PreviousUpNext

15.4.1637  src/lib/x-kit/xclient/src/window/pen-old.pkg

## pen-old.pkg
#
#  "A pen is similar to the graphics context provided by xlib.
#   The principal differences are that pens are immutable, do
#   not specify a font, and can specify clipping rectangles and
#   dashlists (which are handled separately in the X protocol)."
#           -- p16 http://mythryl.org/pub/exene/1993-lib.ps
#              (John H Reppy's 1993 eXene library manual.)

# Compiled by:
#     src/lib/x-kit/xclient/xclient-internals.sublib



# Support for symbolic names for pen component values.

stipulate
    package rc  =  range_check;                                 # range_check           is from   src/lib/std/2d/range-check.pkg
    package dt  =  draw_types_old;                              # draw_types_old        is from   src/lib/x-kit/xclient/src/window/draw-types-old.pkg
    package xt  =  xtypes;                                      # xtypes                is from   src/lib/x-kit/xclient/src/wire/xtypes.pkg
    package v2w =  value_to_wire;                               # value_to_wire         is from   src/lib/x-kit/xclient/src/wire/value-to-wire.pkg
    package g2d =  geometry2d;                                  # geometry2d            is from   src/lib/std/2d/geometry2d.pkg
    package rwv =  rw_vector;                                   # rw_vector             is from   src/lib/std/src/rw-vector.pkg
    package vec =  vector;                                      # vector                is from   src/lib/std/src/vector.pkg
herein


    package pen_old {

        include package   geometry2d;                                   # geometry2d            is from   src/lib/std/2d/geometry2d.pkg

        exception BAD_PEN_TRAIT;

        # These are the properties
        # distinguishing one pen from
        # another:
        #
        package p {
            #
            Pen_Trait
              = FUNCTION    xt::Graphics_Op
              | PLANE_MASK  xt::Plane_Mask
              | FOREGROUND  rgb8::Rgb8
              | BACKGROUND  rgb8::Rgb8
              | LINE_WIDTH  Int
              | LINE_STYLE_SOLID
              | LINE_STYLE_ON_OFF_DASH
              | LINE_STYLE_DOUBLE_DASH
              | CAP_STYLE_NOT_LAST
              | CAP_STYLE_BUTT
              | CAP_STYLE_ROUND
              | CAP_STYLE_PROJECTING
              | JOIN_STYLE_MITER
              | JOIN_STYLE_ROUND
              | JOIN_STYLE_BEVEL
              | FILL_STYLE_SOLID
              | FILL_STYLE_TILED
              | FILL_STYLE_STIPPLED
              | FILL_STYLE_OPAQUE_STIPPLED
              | FILL_RULE_EVEN_ODD
              | FILL_RULE_WINDING
              | ARC_MODE_CHORD
              | ARC_MODE_PIE_SLICE
              | CLIP_BY_CHILDREN
              | INCLUDE_INFERIORS
              #
              | RO_PIXMAP   dt::Ro_Pixmap
              | STIPPLE     dt::Ro_Pixmap
              | CLIP_MASK   dt::Ro_Pixmap
              | CLIP_MASK_NONE
              | CLIP_MASK_UNSORTED_BOXES  List( Box )
              | CLIP_MASK_YSORTED_BOXES   List( Box )
              | CLIP_MASK_YXSORTED_BOXES  List( Box )
              | CLIP_MASK_YXBANDED_BOXES  List( Box )
              | CLIP_ORIGIN       Point
              #
              | STIPPLE_ORIGIN    Point
              #
              | DASH_OFFSET       Int
              | DASH_FIXED        Int
              | DASH_LIST         List(Int)
              ;
        };

        stipulate

            include package   pen_guts;                         # pen_guts              is from   src/lib/x-kit/xclient/src/window/pen-guts.pkg


            fun check_list chkfn l
                =
                {   apply (\\ x = { chkfn x; ();})
                          l;
                    l;
                };

            fun check_item chkfn
                =
                \\ v =  if (chkfn v)   v;
                        else           raise exception BAD_PEN_TRAIT;
                        fi;

            check_card16 =  unt::from_int  o  (check_item  rc::valid16);
            check_card8  =  unt::from_int  o  (check_item  rc::valid8);

            check_point  =  check_item  g2d::valid_point;
            check_box    =  check_item  g2d::valid_box;

            check_boxes  =  check_list  check_box;
            check_card8s =  check_list  check_card8;


            # Map a pen trait to its slot and representation 
            #
            fun trait_to_rep (p::FUNCTION xt::OP_COPY)
                    =>
                    (0, IS_DEFAULT);

                trait_to_rep (p::FUNCTION gr_op)
                    =>
                    (0, IS_WIRE (v2w::graph_op_to_wire  gr_op));

                trait_to_rep (p::PLANE_MASK (xt::PLANEMASK mask))
                    =>
                    (1, IS_WIRE mask);

                trait_to_rep (p::FOREGROUND rgb8)
                    =>
                    {   i = rgb8::rgb8_to_int  rgb8;

                        i == 0   ??   (2, IS_DEFAULT)
                                 ::   (2, IS_WIRE (unt::from_int i));
                    };

                trait_to_rep (p::BACKGROUND rgb8)
                    =>
                    {   i = rgb8::rgb8_to_int  rgb8;

                        i == 1   ??   (3, IS_DEFAULT)
                                 ::   (3, IS_WIRE (unt::from_int i));
                    };
                
                trait_to_rep (p::LINE_WIDTH 0 ) => (4, IS_DEFAULT);
                trait_to_rep (p::LINE_WIDTH wd) => (4, IS_WIRE (check_card16 wd));

                trait_to_rep (p::LINE_STYLE_SOLID      ) => (5, IS_DEFAULT);
                trait_to_rep (p::LINE_STYLE_ON_OFF_DASH) => (5, IS_WIRE 0u1);
                trait_to_rep (p::LINE_STYLE_DOUBLE_DASH) => (5, IS_WIRE 0u2);

                trait_to_rep (p::CAP_STYLE_NOT_LAST  ) => (6, IS_WIRE 0u0);
                trait_to_rep (p::CAP_STYLE_BUTT      ) => (6, IS_DEFAULT);
                trait_to_rep (p::CAP_STYLE_ROUND     ) => (6, IS_WIRE 0u2);
                trait_to_rep (p::CAP_STYLE_PROJECTING) => (6, IS_WIRE 0u3);

                trait_to_rep (p::JOIN_STYLE_MITER) => (7, IS_DEFAULT);
                trait_to_rep (p::JOIN_STYLE_ROUND) => (7, IS_WIRE 0u1);
                trait_to_rep (p::JOIN_STYLE_BEVEL) => (7, IS_WIRE 0u2);

                trait_to_rep (p::FILL_STYLE_SOLID          ) => (8, IS_DEFAULT);
                trait_to_rep (p::FILL_STYLE_TILED          ) => (8, IS_WIRE 0u1);
                trait_to_rep (p::FILL_STYLE_STIPPLED       ) => (8, IS_WIRE 0u2);
                trait_to_rep (p::FILL_STYLE_OPAQUE_STIPPLED) => (8, IS_WIRE 0u3);

                trait_to_rep (p::FILL_RULE_EVEN_ODD) => (9, IS_DEFAULT);
                trait_to_rep (p::FILL_RULE_WINDING ) => (9, IS_WIRE 0u1);

                trait_to_rep (p::RO_PIXMAP (dt::RO_PIXMAP ({ pixmap_id, ... }: dt::Rw_Pixmap))) => (10, IS_PIXMAP pixmap_id);
                trait_to_rep (p::STIPPLE   (dt::RO_PIXMAP ({ pixmap_id, ... }: dt::Rw_Pixmap))) => (11, IS_PIXMAP pixmap_id);

                trait_to_rep (p::STIPPLE_ORIGIN pt) => (12, IS_POINT (check_point pt));

                trait_to_rep (p::CLIP_BY_CHILDREN ) => (13, IS_DEFAULT);
                trait_to_rep (p::INCLUDE_INFERIORS) => (13, IS_WIRE 0u1);

                trait_to_rep (p::CLIP_ORIGIN ({ col=>0, row=>0 } )) => (14, IS_DEFAULT);
                trait_to_rep (p::CLIP_ORIGIN pt)                    => (14, IS_POINT (check_point pt));

                trait_to_rep (p::CLIP_MASK_NONE) => (15, IS_DEFAULT);
                trait_to_rep (p::CLIP_MASK (dt::RO_PIXMAP ({ pixmap_id, ... }: dt::Rw_Pixmap))) => (15, IS_PIXMAP pixmap_id);

                trait_to_rep (p::CLIP_MASK_UNSORTED_BOXES r) => (15, IS_BOXES (xt::UNSORTED_ORDER, check_boxes r));
                trait_to_rep (p::CLIP_MASK_YSORTED_BOXES  r) => (15, IS_BOXES (xt::YSORTED_ORDER,  check_boxes r));
                trait_to_rep (p::CLIP_MASK_YXSORTED_BOXES r) => (15, IS_BOXES (xt::YXSORTED_ORDER, check_boxes r));
                trait_to_rep (p::CLIP_MASK_YXBANDED_BOXES r) => (15, IS_BOXES (xt::YXBANDED_ORDER, check_boxes r));

                trait_to_rep (p::DASH_OFFSET 0)      => (16, IS_DEFAULT);
                trait_to_rep (p::DASH_OFFSET n)      => (16, IS_WIRE (check_card16 n));

                trait_to_rep (p::DASH_FIXED     4)   => (17, IS_DEFAULT);
                trait_to_rep (p::DASH_FIXED     n)   => (17, IS_WIRE (check_card8 n));
                trait_to_rep (p::DASH_LIST dashes)   => (17, IS_DASHES (check_card8s dashes));

                trait_to_rep (p::ARC_MODE_CHORD    ) => (18, IS_WIRE 0u0);
                trait_to_rep (p::ARC_MODE_PIE_SLICE) => (18, IS_DEFAULT);
            end;

            # Extract the non-default value mask
            # from a rw_vector of pen-guts:
            #
            fun extract_mask  vec
                =
                loop (0u0, 0, 0u1)
                where 

                    fun loop (m, i, b)
                        =
                        if (i < pen_slot_count)
                            #
                            case (rwv::get (vec, i))
                                #
                                IS_DEFAULT =>   loop (m, i+1, unt::(<<) (b, 0u1));
                                _          =>   loop (unt::bitwise_or (m, b), i+1, unt::(<<) (b, 0u1));
                            esac;
                        else
                            m;
                        fi;
                end;

            # Make a pen from a rw_vector of initial values
            # and a list of new values 
            #
            fun make_pen' (vec, trait_list)
                =
                {   fun update (slot, rep)
                        =
                        rwv::set (vec, slot, rep);

                    apply (\\ trait = update (trait_to_rep  trait))
                          trait_list;

                    { traits  =>  vec::from_fn (pen_slot_count, \\ i = rwv::get (vec, i)),
                      bitmask =>  extract_mask vec
                    }
                    : Pen
                    ;
                };

        herein

            default_pen
                =
                pen_guts::default_pen;


            # Create a new drawing context
            # from a list of pen traits:
            #
            fun make_pen  traits
                =
                make_pen' (rwv::make_rw_vector (pen_slot_count, IS_DEFAULT),  traits);


            # Create a new pen from an existing
            # pen by functional update:
            #
            fun clone_pen ({ traits, ... }: Pen,  new_traits)
                =
                make_pen' (rwv::from_fn (pen_slot_count, \\ i = vec::get (traits, i)), new_traits);

        end;    # stipulate
    };          # package pen 

end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext