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. --- render.f90 | 113 ++++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 94 insertions(+), 19 deletions(-) (limited to 'render.f90') 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