PreviousUpNext

15.4.1564  src/lib/x-kit/widget/theme/gui-displaylist.pkg

## gui-displaylist.pkg
#
# Our cross-platform drawing language for the Mythryl widget set.
#
# Draw_Op is intended to be the cross-platform-portable
# subset of windowsystem_to_xserver::x::Op                                                                      # windowsystem_to_xserver       is from   src/lib/x-kit/xclient/src/window/windowsystem-to-xserver.pkg
#
# The intent is that guiboss_to_guishim should define a
# rendering model which is highly compatible with X
# (Mythryl's prime target) but able to be supported
# with reasonable effort on other platforms.

# Compiled by:
#     src/lib/x-kit/widget/xkit-widget.sublib

stipulate
    package r64 =  rgb;                                                                                         # rgb                           is from   src/lib/x-kit/xclient/src/color/rgb.pkg
    package g2d =  geometry2d;                                                                                  # geometry2d                    is from   src/lib/std/2d/geometry2d.pkg
    package mtx =  rw_matrix;                                                                                   # rw_matrix                     is from   src/lib/std/src/rw-matrix.pkg
    package r8  =  rgb8;                                                                                        # rgb8                          is from   src/lib/x-kit/xclient/src/color/rgb8.pkg
    package pp  =  standard_prettyprinter;                                                                      # standard_prettyprinter        is from   src/lib/prettyprint/big/src/standard-prettyprinter.pkg
herein

    package gui_displaylist {
        #
        Put_Text =   TO_LEFT_OF_POINT
                 |  TO_RIGHT_OF_POINT                                                                           # Default.
                 |  CENTERED_ON_POINT
                 ;

        Draw_Op
          = POINTS              List( g2d::Point )                                                              # Unaffected by LINE_THICKNESS; use 360 degree FILLED_ARCS for fat points.
          | PATH                List( g2d::Point )                                                              # Draws a sequence of line segments connecting given points.
          | POLYGON             List( g2d::Point )                                                              # Like PATH, but additionally draws a line segment connectings last point back to first point.
          | FILLED_POLYGON      List( g2d::Point )
          | LINES               List( g2d::Line  )
          | BOXES               List( g2d::Box   )
          | FILLED_BOXES        List( g2d::Box   )
          | ARCS                List( g2d::Arc   )                                                              # NB: ARCS can draw circles and X-Y oriented ellipses (and parts thereof).  For other ellipses see ellipse.pkg below.
          | FILLED_ARCS         List( g2d::Arc   )
          #
          | TEXT                (g2d::Point, String)    
          #
          | IMAGE               { from_box:     Null_Or( g2d::Box ),                                            # Take this subrectangle (default: all)
                                  from:         mtx::Rw_Matrix( r8::Rgb8 ),                                     # from this pixel array
                                  to_point:     g2d::Point                                                      # and write it to this point in window.
                                }
          | COPY_BOX            { to_point:     g2d::Point,                                                     # So terminal widgets can scroll text up, etc. Contents of screen area in given box are copied to given point.
                                  from_box:     g2d::Box
                                }
          | COPY_FROM_RW_PIXMAP { from_id:      Id,                                                             # 'from_id' should be guiboss_to_rw_pixmap.id for some gtg::Guiboss_To_Rw_Pixmap value obtained via guiboss_to_guishim.make_rw_pixmap.
                                  to_point:     g2d::Point,
                                  from_box:     g2d::Box
                                }
          #
          | COLOR          (r64::Rgb,     List(Draw_Op))
          | LINE_THICKNESS (Int,          List(Draw_Op))                                                        # Affects lines and arcs.  A thickness of zero draws the fastest, thinnest lines supported by host.  Use thickness 1 for pretty lines and joints.
          | PUT_TEXT       (Put_Text,     List(Draw_Op))
          | CLIP_TO        (g2d::Box,     List(Draw_Op))
          | FONT           (List(String), List(Draw_Op))                                                        # X fontnames like "fixed" or "-misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1" -- see Note[1] or (eg) /usr/share/fonts/X11/misc/fonts.alias
          #                                                                                                     # TEXTs will be drawn in first font in FONT list which is found on X server. The best fonts are optional, hence the list: put best-first, most-common last.
          #
          ;                                                                                                     # Additional drawing support is provided by higher-level packages which generate Draw_Op-level results, for example:
                                                                                                                #     src/lib/x-kit/draw/ellipse.pkg
                                                                                                                #     src/lib/x-kit/draw/beta2-spline.pkg

        Gui_Displaylist =  List( Draw_Op );


        fun find_all_points_in_gui_displaylist (d: Gui_Displaylist)                                             # Used mainly to generate pointlists to be handed to g2d::bounding_box or g2d::convex_hull, for mouseclick hit-testing etc via g2d::point_in_polygon.
            =
            do_ops (d, [])
            where
                fun do_box  (box: g2d::Box)  =  g2d::box::to_points  box;
                fun do_line (point1, point2) =  [ point1, point2 ];

                fun do_arc ({ row, col, high, wide, ... }: g2d::Arc)                                            # 
                    =
                    do_box  { row, col, high, wide };                                                           # XXX QUERO FIXME is this anywhere close to sane?

                fun do_image  { to_point as { row, col }:       g2d::Point,
                                from_box:                       Null_Or( g2d::Box ),
                                from:                           mtx::Rw_Matrix( r8::Rgb8 )
                              }
                    =
                    {   my (high, wide)
                            =
                            case  from_box
                                #
                                NULL                    =>  (mtx::rowscols from);
                                THE { high, wide, ... } =>  (high, wide);
                            esac;
                        #
                        do_box { row, col, high, wide };
                    };

                fun do_boxes (boxes)         =  list::cat (map do_box  boxes);
                fun do_lines (lines)         =  list::cat (map do_line lines);
                fun do_arcs  (arcs)          =  list::cat (map do_arc  arcs);

                fun do_copybox { to_point: g2d::Point, from_box: g2d::Box }
                    =
                    {   from_box -> { row, col, high, wide };
                        to_box = { row => to_point.row, col => to_point.col, high, wide };
                        do_boxes [ from_box, to_box ];
                    };

                fun do_copy_from_rw_pixmap { to_point as { row, col }: g2d::Point, from_box as { high, wide, ... }: g2d::Box, from_id: Id }
                    =
                    do_boxes [ { row, col, high, wide } ];

                fun do_ops ([],        result) =>  result;
                    do_ops (op ! rest, result) =>  do_ops (rest, do_op op @ result);
                end
                also
                fun do_op (POINTS                p) =>  p;
                    do_op (PATH                  p) =>  p;
                    do_op (POLYGON               p) =>  p;
                    do_op (FILLED_POLYGON        p) =>  p;
                    #
                    do_op (LINES                 l) =>  do_lines l;
                    do_op (BOXES                 b) =>  do_boxes b;
                    do_op (FILLED_BOXES          b) =>  do_boxes b;
                    do_op (ARCS                  a) =>  do_arcs  a;
                    do_op (FILLED_ARCS           a) =>  do_arcs  a;
                    #
                    do_op (TEXT           (p, _  )) =>  [ p ];                                                  # XXX SUCKO FIXME  We should really compute the bounding box for the string here.
                    do_op (IMAGE                 a) =>  do_image a;
                    do_op (COPY_BOX              a) =>  do_copybox a;
                    do_op (COPY_FROM_RW_PIXMAP   a) =>  do_copy_from_rw_pixmap a;
                    #
                    do_op (FONT           (_, ops)) =>                 (do_ops (ops, []));
                    do_op (COLOR          (_, ops)) =>                 (do_ops (ops, []));
                    do_op (LINE_THICKNESS (_, ops)) =>                 (do_ops (ops, []));
                    do_op (PUT_TEXT       (_, ops)) =>                 (do_ops (ops, []));
                    do_op (CLIP_TO      (box, ops)) =>  (do_box box) @ (do_ops (ops, []));
                end;
            end;


        # Sample call looks like:
        #
        #     fg = pp::prettyprint_to_string [] {. gd::prettyprint_gui_displaylist #pp displaylist; };
        #     print ("\narrowbutton: foreground:\n" + fg + "\n");
        #
        fun prettyprint_gui_displaylist
              # 
              (pp: pp::Prettyprinter)
              (gd: Gui_Displaylist)
            =
            pp::listx pp do_op "" gd
            where
                fun point_to_string { row, col } = sprintf "{ row => %d, col => %d }" row col;
                fun  line_to_string  (p1, p2)     = sprintf "(%s, %s)" (point_to_string p1) (point_to_string p2);
                fun   box_to_string  { row, col, high, wide }  = sprintf "{ row => %d, col => %d, high => %d, wide => %d }" row col high wide;
                fun   arc_to_string  { row, col, high, wide, start_angle, fill_angle }  = sprintf "{ row => %d, col => %d, high => %d, wide => %d, start_angle => %f, fill_angle => %f }" row col high wide start_angle fill_angle;

                fun do_op (POINTS                p) =>  pp::listx pp (\\ pt = pp.lit (point_to_string pt))  "POINTS"         p;
                    do_op (PATH                  p) =>  pp::listx pp (\\ pt = pp.lit (point_to_string pt))  "PATH"           p;
                    do_op (POLYGON               p) =>  pp::listx pp (\\ pt = pp.lit (point_to_string pt))  "POLYGON"        p;
                    do_op (FILLED_POLYGON        p) =>  pp::listx pp (\\ pt = pp.lit (point_to_string pt))  "FILLED_POLYGON" p;
                    #
                    do_op (LINES                 l) =>  pp::listx pp (\\ pt = pp.lit (line_to_string pt))   "LINES"          l;
                    do_op (BOXES                 b) =>  pp::listx pp (\\ pt = pp.lit ( box_to_string pt))   "BOXES"          b;
                    do_op (FILLED_BOXES          b) =>  pp::listx pp (\\ pt = pp.lit ( box_to_string pt))   "FILLED_BOXES"   b;
                    do_op (ARCS                  a) =>  pp::listx pp (\\ pt = pp.lit ( arc_to_string pt))   "ARCS"           a;
                    do_op (FILLED_ARCS           a) =>  pp::listx pp (\\ pt = pp.lit ( arc_to_string pt))   "FILLED_ARCS"    a;
                    #
                    do_op (TEXT             (p, t)) =>  pp.lit (sprintf "(TEXT (%s,\"%s\"))" (point_to_string p) t);
                    do_op (IMAGE                 a) =>  pp.lit "<IMAGE>";
                    do_op (COPY_BOX              r) =>  pp.lit (sprintf "(COPY_BOX { to_point => %s, from_box => %s }" (point_to_string r.to_point) (box_to_string r.from_box));
                    do_op (COPY_FROM_RW_PIXMAP   r) =>  pp.lit (sprintf "(COPY_FROM_RW_PIXMAP { to_point => %s, from_box => %s, from_id }" (point_to_string r.to_point) (box_to_string r.from_box));
                    #
                    do_op (FONT           (_, ops)) =>  pp::listx pp do_op  "FONT"           ops;
                    do_op (COLOR          (_, ops)) =>  pp::listx pp do_op  "COLOR"          ops;
                    do_op (LINE_THICKNESS (_, ops)) =>  pp::listx pp do_op  "LINE_THICKNESS" ops;
                    do_op (PUT_TEXT       (_, ops)) =>  pp::listx pp do_op  "PUT_TEXT"       ops;
                    do_op (CLIP_TO      (box, ops)) =>  pp::listx pp do_op  "CLIP_TO"        ops;
                end;
            end;

    };
end;


###########################################################################################
# Note[1]
# As of X11R7.5 standard short fontnames include:
#
#    fixed        -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1
#    variable     -*-helvetica-bold-r-normal-*-*-120-*-*-*-*-iso8859-1
#    5x7          -misc-fixed-medium-r-normal--7-70-75-75-c-50-iso8859-1
#    5x8          -misc-fixed-medium-r-normal--8-80-75-75-c-50-iso8859-1
#    6x9          -misc-fixed-medium-r-normal--9-90-75-75-c-60-iso8859-1
#    6x10         -misc-fixed-medium-r-normal--10-100-75-75-c-60-iso8859-1
#    6x12         -misc-fixed-medium-r-semicondensed--12-110-75-75-c-60-iso8859-1
#    6x13         -misc-fixed-medium-r-semicondensed--13-120-75-75-c-60-iso8859-1
#    6x13bold     -misc-fixed-bold-r-semicondensed--13-120-75-75-c-60-iso8859-1
#    7x13         -misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-1
#    7x13bold     -misc-fixed-bold-r-normal--13-120-75-75-c-70-iso8859-1
#    7x13euro     -misc-fixed-medium-r-normal--13-120-75-75-c-70-iso8859-15
#    7x13eurobold -misc-fixed-bold-r-normal--13-120-75-75-c-70-iso8859-15
#    7x14         -misc-fixed-medium-r-normal--14-130-75-75-c-70-iso8859-1
#    7x14bold     -misc-fixed-bold-r-normal--14-130-75-75-c-70-iso8859-1
#    8x13         -misc-fixed-medium-r-normal--13-120-75-75-c-80-iso8859-1
#    8x13bold     -misc-fixed-bold-r-normal--13-120-75-75-c-80-iso8859-1
#    8x16         -sony-fixed-medium-r-normal--16-120-100-100-c-80-iso8859-1
#    9x15         -misc-fixed-medium-r-normal--15-140-75-75-c-90-iso8859-1
#    9x15bold     -misc-fixed-bold-r-normal--15-140-75-75-c-90-iso8859-1
#    10x20        -misc-fixed-medium-r-normal--20-200-75-75-c-100-iso8859-1
#    12x24        -sony-fixed-medium-r-normal--24-170-100-100-c-120-iso8859-1
#    ...   


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext