The process of drawing can be split into different abstraction layers:
- Application's intent to show some data
- Application-specific layers of transforming its intent into Draw
- Draw commands
- Original geometric primitives and text
- Geometric primitives and text after clipping, blending, stacking - as we see it
- Final pixel map
Layers 4-6 are portable. Layer 3 'Draw' isn't, but it can be.
Use cases:
- Draw as a vector file format: saving/loading images in their original vector form
- Client/server drawing (remote GUI, GUI for other programming languages, etc.)
- Reading (debugging) Draw output, which currently becomes a mess (in Spaces I solve this using a custom
mold implementation)
The main obstacles to portability are only three commands:
text <rtd-object> refers to a full face! object with all of its state, including OS handles.
font <font-object> refers to a font! object, which again has its OS handles, links to faces where it's used, etc.
image <image-object> refers to an image! object, which cannot round-trip in mold/load cycle
As you can see, current Draw implementation is built on a questionable mix of principles, from literal data to things deeply rooted in the program's runtime state. I propose altering its design to make it portable and easy to read.
Rich-text (relates to #124)
- Required facets: text itself, wrapping width, formatting flags block
- Harmful facets: font and color (there's already
font command in Draw, and pen for colors, and font object's color as well: triple redundancy)
- It could be just a
rich-text <position> <optional-width-integer> <optional-flags-block> <text> command.
Fonts
- Font objects don't have much state. Name, size, weight, maybe skew and kerning in future. Color comes into conflict with Draw
pen color, but pen also has options not supported by native text renderers (e.g. pattern pen), so it's a tough situation. mold produces too much info on top of the required facets, which is also unloadable.
- A simpler font representation (e.g. a
map! without any internals) can be a viable option.
- A command like
font <optional-size> <name> seems more limiting than a map (e.g. one can request a font family, or only a font size, but with a single command format it becomes tricky).
Images
- Draw image file format will need the ability to refer to these as file names.
- For remote IPC the best way to transfer these is to compress them first, e.g. as PNG. In principle it's easily doable as a deep block parser that swaps image objects with binary and back.
- It would still be nice to have the quick and dirty option of just molding it and loading back (
mold/all), particularly for local IPC.
The process of drawing can be split into different abstraction layers:
Layers 4-6 are portable. Layer 3 'Draw' isn't, but it can be.
Use cases:
moldimplementation)The main obstacles to portability are only three commands:
text <rtd-object>refers to a fullface!object with all of its state, including OS handles.font <font-object>refers to afont!object, which again has its OS handles, links to faces where it's used, etc.image <image-object>refers to animage!object, which cannot round-trip in mold/load cycleAs you can see, current Draw implementation is built on a questionable mix of principles, from literal data to things deeply rooted in the program's runtime state. I propose altering its design to make it portable and easy to read.
Rich-text (relates to #124)
fontcommand in Draw, andpenfor colors, and font object's color as well: triple redundancy)rich-text <position> <optional-width-integer> <optional-flags-block> <text>command.Fonts
pencolor, butpenalso has options not supported by native text renderers (e.g. pattern pen), so it's a tough situation.moldproduces too much info on top of the required facets, which is also unloadable.map!without any internals) can be a viable option.font <optional-size> <name>seems more limiting than a map (e.g. one can request a font family, or only a font size, but with a single command format it becomes tricky).Images
mold/all), particularly for local IPC.