From eb8d9bc74a0624dbc98ffb75268a3ba57bd43b40 Mon Sep 17 00:00:00 2001 From: Jeffrey Armstrong Date: Fri, 24 Apr 2020 21:47:09 -0400 Subject: Initial code commit --- render.f90 | 173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 render.f90 (limited to 'render.f90') diff --git a/render.f90 b/render.f90 new file mode 100644 index 0000000..2913507 --- /dev/null +++ b/render.f90 @@ -0,0 +1,173 @@ +module render +implicit none + + type, abstract :: renderer + + integer::y + integer::max_width + + contains + + procedure::render_proportional + + procedure(initialize), deferred::initialize + + procedure(calculate_width), deferred::text_width + procedure(calculate_height), deferred::text_height + 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_visibility), deferred::is_preformatted_visible + procedure(draw_text), deferred::draw_preformatted + + end type renderer + + abstract interface + subroutine initialize(self) + import::renderer + class(renderer)::self + end subroutine initialize + end interface + + abstract interface + function calculate_width(self, text) + import::renderer + class(renderer)::self + character(*), intent(in)::text + integer::calculate_width + end function calculate_width + end interface + + abstract interface + function calculate_height(self, text) + import::renderer + class(renderer)::self + character(*), intent(in)::text + integer::calculate_height + end function calculate_height + end interface + + abstract interface + subroutine draw_text(self, text) + import::renderer + class(renderer)::self + character(*), intent(in)::text + end subroutine draw_text + end interface + + abstract interface + function calculate_visibility(self, text) + import::renderer + class(renderer)::self + character(*), intent(in)::text + logical::calculate_visibility + end function calculate_visibility + end interface + +contains + + function width_of_line(r, text, startpos, endpos) + implicit none + + class(renderer)::r + character(*), intent(in)::text + integer, intent(in)::startpos, endpos + integer::width_of_line + + integer::my_start, my_end + + my_end = endpos + if(endpos <= 0) then + my_end = len_trim(text) + end if + + my_start = startpos + if(startpos <= 0) then + my_start = 1 + end if + + if(my_end <= my_start) then + width_of_line = 0 + else + width_of_line = r%text_width(text(my_start:my_end)) + end if + + end function width_of_line + + function wrap_line(r, text, startpos) result(endpos) + implicit none + + class(renderer)::r + character(*), intent(in)::text + integer, intent(in)::startpos + integer::endpos + integer::my_start + integer::w + + my_start = startpos + if(startpos == 0) then + my_start = 1 + end if + + endpos = len_trim(text) + w = width_of_line(r, text, my_start, endpos) + do while(w > r%max_width) + + endpos = endpos - 1 + do while(text(endpos:endpos) /= ' ' .and. text(endpos:endpos) /= '-') + endpos = endpos - 1 + end do + + w = width_of_line(r, text, my_start, endpos) + end do + + end function wrap_line + + subroutine render_proportional(r, text) + implicit none + + class(renderer)::r + character(*)::text + + integer::startpos, endpos + + 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) + do while(endpos > startpos) + if(r%is_text_visible(text(startpos:endpos))) then + call r%draw_porportional(text(startpos:endpos)) + end if + r%y = r%y + r%text_height(text(startpos:endpos)) + + ! Advance string positions + startpos = endpos+1 + do while(text(startpos:startpos) == ' ') + startpos = startpos + 1 + end do + endpos = wrap_line(r, text, startpos) + end do + end if + + end subroutine render_proportional + + subroutine render_preformatted(r, text) + implicit none + + class(renderer)::r + character(*)::text + + if(r%is_preformatted_visible(text)) then + call r%draw_preformatted(text) + end if + r%y = r%y + r%preformatted_height(text) + + end subroutine render_preformatted +end module render -- cgit v1.2.3