Check out my first novel, midnight's simulacra!

Notcurses: Difference between revisions

From dankwiki
(→‎Features: link to unicode PSUA-B document)
Line 23: Line 23:
The vast majority of functions draw to <tt>ncplane</tt> objects. A partial order (currently a total order) always exists over the planes. There is always at least one plane, the "standard plane". This plane cannot be resized, deleted, moved relative to the visible area, or reparented. Whenever notcurses updates its idea of the visible area's dimensions, it will resize the standard plane (references to the standard plane are <b>not</b> invalidated). Planes may otherwise be any size (invisible regions will not be rendered, and count only against memory), and can be moved to any position relative to the visible area. All planes, including the standard plane, can be freely moved along the z axis.
The vast majority of functions draw to <tt>ncplane</tt> objects. A partial order (currently a total order) always exists over the planes. There is always at least one plane, the "standard plane". This plane cannot be resized, deleted, moved relative to the visible area, or reparented. Whenever notcurses updates its idea of the visible area's dimensions, it will resize the standard plane (references to the standard plane are <b>not</b> invalidated). Planes may otherwise be any size (invisible regions will not be rendered, and count only against memory), and can be moved to any position relative to the visible area. All planes, including the standard plane, can be freely moved along the z axis.


Every plane, and the notcurses object as a whole, maintains a per-row <i>damage map</i>, one boolean entry per line of the plane. These damage maps are likely to be replaced with [https://github.com/dankamongmen/notcurses/issues/189 O(1) damage detection].
A render operation consists of two logical phases: generation of the rendered scene, and blitting this scene to the terminal (these two phases might actually be interleaved, streaming the output as it is rendered). All ncplanes are locked while generating the frame. Frame generation requires determining an extended grapheme cluster, foreground color, background color, and style for each cell of the physical terminal. Writing the scene requires synthesizing a set of UTF-8-encoded characters and escape codes appropriate for the terminal (relying on terminfo(5)), and writing this sequence to the output **FILE**. If the **renderfp** value was not NULL in the original call to notcurses_init(3), the frame will be written to that **FILE** as well. This write does not affect statistics.


When <tt>notcurses_render()</tt> is called, the visual area is constructed from the top left to the bottom right, row by row and column by column.
Each cell can be rendered in isolation, though synthesis of the stream carries dependencies between cells.


Each row is considered undamaged until proven otherwise. At each column, the character to be emitted (and its styling) is computed. This will require consulting some number of planes (see [[#Transparency/Contrasting|Transparency]] for more information). A damage value is computed as the boolean union over all relevant damage map entries. Relevant entries are those from the toplevel damage map, and the damage maps of all planes which contributed to the output glyph or styling.
Recall that there is a total ordering on the <i>N</i> ncplanes, and that the standard plane always exists, with geometry equal to the physical screen. Each cell of the physical screen is thus intersected by some totally ordered subset of planes <i>P0</i>, <i>P1</i>...<i>Pi</i>, where 0 &lt; <i>i</i> ≤ <i>N</i>. At each cell, rendering starts at the topmost intersecting plane <i>P0</i>. The algorithm descends until either:
 
* it has locked in an extended grapheme cluster, and fore/background colors, or
* all <i>i</i> planes have been examined
 
At each plane <i>P</i>, we consider a cell <i>C</i>. This cell is the intersecting cell, unless that cell has no EGC. In that case, <i>C</i> is the plane's default cell.
 
* If we have not yet determined an EGC, and <i>C</i> has a non-zero EGC, use the EGC and style of <i>C</i>.
* If we have not yet locked in a foreground color, and <i>C</i> is not foreground-transparent, use the foreground color of <i>C</i>. If <i>C</i> is <tt>CELL_ALPHA_OPAQUE</tt>, lock the color in.
* If we have not yet locked in a foreground color, and <i>C</i> is not background-transparent, use the background color of <i>C</i>. If <i>C</i> is <tt>CELL_ALPHA_OPAQUE</tt>, lock the color in.
 
If the algorithm concludes without an EGC, the cell is rendered with no glyph and a default background. If the algorithm concludes without a color locked in, the color as computed thus far is used.


==Unicode==
==Unicode==