From ac37668c0765703a2d76edac0d1d8b8f55be4e56 Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Thu, 14 May 2020 08:31:44 -0400 Subject: Renderer class now has optional arguments for drawing text to indicate list items, headings, etc. Dumb renderer now draws headings a bit nicer. --- dumb_render.f90 | 102 +++++++++++++++++++++++++++++++++++++++++++---- gemini-windows.prj | 3 ++ main.F90 | 5 +++ render.f90 | 113 ++++++++++++++++++++++++++++++++++++++++++++--------- 4 files changed, 197 insertions(+), 26 deletions(-) diff --git a/dumb_render.f90 b/dumb_render.f90 index 93897ed..3834e5c 100644 --- a/dumb_render.f90 +++ b/dumb_render.f90 @@ -27,6 +27,8 @@ implicit none integer, parameter::width = 79 integer, parameter::height = 24 + character, parameter::bullet_character = '-' + type, extends(renderer) :: dumb_renderer integer::link_index @@ -46,14 +48,14 @@ implicit none procedure :: draw_porportional => dumb_text_draw - procedure :: preformatted_width => dumb_text_width - procedure :: preformatted_height => dumb_text_height + procedure :: preformatted_width => dumb_simple_width + procedure :: preformatted_height => dumb_simple_height procedure :: is_preformatted_visible => dumb_text_visible - procedure :: draw_preformatted => dumb_text_draw + procedure :: draw_preformatted => dumb_simple_draw procedure :: link_width => dumb_link_width - procedure :: link_height => dumb_text_height + procedure :: link_height => dumb_simple_height procedure :: is_link_visible => dumb_text_visible procedure :: draw_link => dumb_link_draw @@ -122,28 +124,66 @@ contains end function store_link - function dumb_text_width(self, text) + function dumb_text_width(self, text, heading, list_item) implicit none class(dumb_renderer)::self character(*), intent(in)::text + integer, optional::heading + logical, optional::list_item integer::dumb_text_width dumb_text_width = len_trim(text) + if(present(list_item)) then + if(list_item) then + dumb_text_width = dumb_text_width + 3 + end if + end if + end function dumb_text_width - function dumb_text_height(self, text) + function dumb_text_height(self, text, heading, list_item) implicit none class(dumb_renderer)::self character(*), intent(in)::text + integer, optional::heading + logical, optional::list_item integer::dumb_text_height dumb_text_height = 1 + if(present(heading)) then + if(heading > 0) then + dumb_text_height = 2 + end if + end if + end function dumb_text_height + function dumb_simple_width(self, text) + implicit none + + class(dumb_renderer)::self + character(*), intent(in)::text + integer::dumb_simple_width + + dumb_simple_width = len_trim(text) + + end function dumb_simple_width + + function dumb_simple_height(self, text) + implicit none + + class(dumb_renderer)::self + character(*), intent(in)::text + integer::dumb_simple_height + + dumb_simple_height = 1 + + end function dumb_simple_height + function dumb_text_visible(self, text) implicit none @@ -157,7 +197,7 @@ contains end function dumb_text_visible - subroutine dumb_text_draw(self, text) + subroutine dumb_simple_draw(self, text) implicit none class(dumb_renderer)::self @@ -177,6 +217,54 @@ contains write(*, formatting) text(1:limit_x) end if + end subroutine dumb_simple_draw + + subroutine dumb_text_draw(self, text, heading, list_item) + implicit none + + class(dumb_renderer)::self + character(*), intent(in)::text + integer, optional::heading + logical, optional::list_item + integer::limit_x + character(5)::formatting + character(self%max_width)::heading_line + + ! Put a bullet for list items + if(present(list_item)) then + if(list_item) then + write(*, '(1X, A1, 1X)', advance='no') bullet_character + end if + end if + + limit_x = min(len_trim(text), self%max_width) + if(limit_x == 0) then + write(*,*) " " + else + if(limit_x < 10) then + write(formatting, '(A2, I1, A1)') '(A', limit_x, ')' + else + write(formatting, '(A2, I2, A1)') '(A', limit_x, ')' + end if + + write(*, formatting) text(1:limit_x) + end if + + ! For headings, plop a second line as an underline + if(present(heading)) then + if(heading > 0) then + if(limit_x > 0) then + if(heading == 1) then + heading_line = repeat("=", limit_x) + else + heading_line = repeat("-", limit_x) + end if + write(*, formatting) heading_line(1:limit_x) + else + write(*,*) " " + end if + end if + end if end subroutine dumb_text_draw diff --git a/gemini-windows.prj b/gemini-windows.prj index 2491864..05c7a2e 100644 --- a/gemini-windows.prj +++ b/gemini-windows.prj @@ -29,6 +29,9 @@ }], "Name":"+gemini-windows (lr87.exe)", "Files":[{ + "filename":".\\ag_render.f90", + "enabled":"0" + },{ "filename":".\\dumb_render.f90", "enabled":"1" },{ diff --git a/main.F90 b/main.F90 index c313b5f..8fff5de 100644 --- a/main.F90 +++ b/main.F90 @@ -22,7 +22,11 @@ program gemini use request + use dumb_render +!use ag_render, only: appgraphics_renderer +use render + use gemini_protocol use layout use file_handling @@ -38,6 +42,7 @@ implicit none character(1024)::current_url, input type(connection)::conn type(dumb_renderer)::r + !type(appgraphics_renderer)::r logical::running logical::loaded diff --git a/render.f90 b/render.f90 index 387d897..96ec610 100644 --- a/render.f90 +++ b/render.f90 @@ -52,21 +52,21 @@ implicit none procedure(calculate_visibility), deferred::is_text_visible procedure(draw_text), deferred::draw_porportional - procedure(calculate_width), deferred::preformatted_width - procedure(calculate_height), deferred::preformatted_height + procedure(calculate_simple_width), deferred::preformatted_width + procedure(calculate_simple_height), deferred::preformatted_height procedure(calculate_visibility), deferred::is_preformatted_visible - procedure(draw_text), deferred::draw_preformatted + procedure(draw_simple_text), deferred::draw_preformatted - procedure(calculate_width), deferred::link_width - procedure(calculate_height), deferred::link_height + procedure(calculate_simple_width), deferred::link_width + procedure(calculate_simple_height), deferred::link_height procedure(calculate_visibility), deferred::is_link_visible procedure(draw_link), deferred::draw_link procedure(request_input), deferred::request_input - procedure(draw_text), deferred::draw_error + procedure(draw_simple_text), deferred::draw_error - procedure(draw_text), deferred::report_status + procedure(draw_simple_text), deferred::report_status procedure(request_action), deferred::request_action @@ -94,31 +94,63 @@ implicit none end interface abstract interface - function calculate_width(self, text) + function calculate_width(self, text, heading, list_item) import::renderer class(renderer)::self character(*), intent(in)::text + integer, optional::heading + logical, optional::list_item integer::calculate_width end function calculate_width end interface abstract interface - function calculate_height(self, text) + function calculate_height(self, text, heading, list_item) import::renderer class(renderer)::self character(*), intent(in)::text + integer, optional::heading + logical, optional::list_item integer::calculate_height end function calculate_height end interface abstract interface - subroutine draw_text(self, text) + subroutine draw_text(self, text, heading, list_item) import::renderer class(renderer)::self character(*), intent(in)::text + integer, optional::heading + logical, optional::list_item end subroutine draw_text end interface + abstract interface + function calculate_simple_width(self, text) + import::renderer + class(renderer)::self + character(*), intent(in)::text + integer::calculate_simple_width + end function calculate_simple_width + end interface + + abstract interface + function calculate_simple_height(self, text) + import::renderer + class(renderer)::self + character(*), intent(in)::text + integer::calculate_simple_height + end function calculate_simple_height + end interface + + abstract interface + subroutine draw_simple_text(self, text) + import::renderer + class(renderer)::self + character(*), intent(in)::text + end subroutine draw_simple_text + end interface + abstract interface function calculate_visibility(self, text) import::renderer @@ -193,12 +225,14 @@ contains end function type_supported - function width_of_line(r, text, startpos, endpos) + function width_of_line(r, text, startpos, endpos, heading_level, list_item) implicit none class(renderer)::r character(*), intent(in)::text integer, intent(in)::startpos, endpos + integer, intent(in)::heading_level + logical, intent(in)::list_item integer::width_of_line integer::my_start, my_end @@ -216,17 +250,21 @@ contains if(my_end <= my_start) then width_of_line = 0 else - width_of_line = r%text_width(text(my_start:my_end)) + width_of_line = r%text_width(text(my_start:my_end), & + heading=heading_level, & + list_item=list_item) end if end function width_of_line - function wrap_line(r, text, startpos) result(endpos) + function wrap_line(r, text, startpos, heading_level, list_item) result(endpos) implicit none class(renderer)::r character(*), intent(in)::text integer, intent(in)::startpos + integer, intent(in)::heading_level + logical, intent(in)::list_item integer::endpos integer::my_start integer::w @@ -237,7 +275,7 @@ contains end if endpos = len_trim(text) - w = width_of_line(r, text, my_start, endpos) + w = width_of_line(r, text, my_start, endpos, heading_level, list_item) do while(w > r%max_width) endpos = endpos - 1 @@ -245,7 +283,7 @@ contains endpos = endpos - 1 end do - w = width_of_line(r, text, my_start, endpos) + w = width_of_line(r, text, my_start, endpos, heading_level, list_item) end do end function wrap_line @@ -257,27 +295,64 @@ contains character(*)::text integer::startpos, endpos + integer::heading_level + logical::list_item if(len_trim(text) == 0) then + if(r%is_text_visible(" ")) then call r%draw_porportional("") end if r%y = r%y + r%text_height(" ") + else + startpos = 1 - endpos = wrap_line(r, text, startpos) + + ! Check for headings first + heading_level = 0 + do while(text(startpos:startpos) == '#') + heading_level = heading_level + 1 + startpos = startpos + 1 + end do + + ! Or a list item + list_item = .FALSE. + if(heading_level == 0) then + list_item = (text(1:1) == '*') + if(list_item) then + startpos = startpos + 1 + end if + end if + + ! If either occurred, advance past whitespace + if(heading_level > 0 .or. list_item) then + do while(text(startpos:startpos) == ' ' .or. text(startpos:startpos) == char(9)) + startpos = startpos + 1 + end do + end if + + endpos = wrap_line(r, text, startpos, heading_level, list_item) do while(endpos > startpos) if(r%is_text_visible(text(startpos:endpos))) then - call r%draw_porportional(text(startpos:endpos)) + call r%draw_porportional(text(startpos:endpos), & + heading=heading_level, & + list_item=list_item) end if - r%y = r%y + r%text_height(text(startpos:endpos)) + r%y = r%y + r%text_height(text(startpos:endpos), & + heading=heading_level, & + list_item=list_item) ! Advance string positions startpos = endpos+1 do while(text(startpos:startpos) == ' ') startpos = startpos + 1 end do - endpos = wrap_line(r, text, startpos) + + ! Do not mark as a list item for subsequent lines + list_item = .FALSE. + + endpos = wrap_line(r, text, startpos, heading_level, list_item) end do end if -- cgit v1.2.3