aboutsummaryrefslogtreecommitdiff
path: root/render.f90
diff options
context:
space:
mode:
authorJeffrey Armstrong <jeff@approximatrix.com>2020-04-24 21:47:09 -0400
committerJeffrey Armstrong <jeff@approximatrix.com>2020-04-24 21:47:09 -0400
commiteb8d9bc74a0624dbc98ffb75268a3ba57bd43b40 (patch)
tree04e77c082b1c87778f06fe53798db6bb284f834c /render.f90
downloadLR-87-eb8d9bc74a0624dbc98ffb75268a3ba57bd43b40.zip
LR-87-eb8d9bc74a0624dbc98ffb75268a3ba57bd43b40.tar.gz
Initial code commit
Diffstat (limited to 'render.f90')
-rw-r--r--render.f90173
1 files changed, 173 insertions, 0 deletions
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