R3 Graphics as an Extension
We need the main graphics sub-system to be accessible to community developers for porting, support, and extensions. Currently, this system is directly linked into the R3 core and has dependencies on R3 implementation. Moving this code out to the host environment and removing any dependencies will make the objective possible.
The main problem is that the graphics code has deeper access to R3 internals than it really needs. This design choice was made early on and is mostly the result of implementation based on the delect function for interpreting dialects like draw, effect, and richtext.
However, it's possible to redesign this part of the code to make use of command datatypes rather than an delect dialect. This gives developers access to all of the graphics functions at the host and extensions levels.
Graphics has a few main parts:
- The top level windowing and compositing functions.
- A small number of utility functions.
- The GOB content dialects like draw and effect.
When a GOB needs to be rendered, the OS_Show_Gob function is called in the graphics subsystem. This function calls Compose_Gob to render the graphics of the window, and as part of its operation it will call Draw_Gob to interpret the draw dialect.
The dialect is interpreted by calling Reb_Dialect a callback into the REBOL library. This function handles the complex interpretation of the draw dialect, properly handling optional arguments, restacking arguments by datatype, allowing unbounded argument sequences, and handling word lookup.
The Reb_Dialect function returns a dialect word number and a block of arguments.
Moving this part to it's own page...
Step 1 - Hosted Extensions
The host can add resident extensions during boot by calling this function:
REBAPI int Reb_Extend(REBYTE *spec, int (*call)(int, RXIFRM *))
The spec is UTF-8 REBOL source for the extension module as described in Making Extensions. The call is the extension function dispatcher function, RX_Call. The RX_Init and RX_Quit functions are not used.
Multiple extensions can be added by calling this function for each.
Note that the extension is only cataloged, not initialized at this time.
The hosted extension is initialized in one of three ways:
- On boot, if it specifies a boot priority in its module header, it is automatically initialized according to that priority. Higher priorities are initialized first.
- Within the host boot script by calling the import function. This allows the host to control when the extension is added.
- Within user programs via the import function. This allows an extension to remain uninitialized until it is needed.
Note that the import function must be modified to allow delayed module creation.
Step 2 - Graphics Commands
Each of the dialected graphics commands must be converted to a command function. This isn't difficult, but it does create a problem with commands that have indefinite arguments. It may be necessary to provide a few variations in such functions for the required number of arguments.