[Cairo] Proposed dual-matrix cairo text drawing interface
Bill Spitzak
spitzak at d2.com
Tue Nov 25 13:34:47 PST 2003
> Carl Worth wrote:
> ...describe idea of using two matricies...
Here is my proposal for the two-matrix Cairo text interface. These are all
the calls used by it:
The glyphs are transformed by the concatenation of two matricies, the text
matrix and the font scaling matrix. The text matrix is unrelated to the
current transform, except for the fact that it had to be equal to it at one
time. All measurements are returned in text-matrix units. The purpose of this
is twofold: first it allows both the convienence of using transforms to place
labels without transforming the text itself (like OpenGL), while still
allowing the PostScript feature of scaling an entire drawing. Second, this
will allow the font scaling matrix to be very limited, such that the
y_advance can be forced to be zero in all cases, greatly simplifying the
interface.
Here is a a mockup of the proposed interface (the state parameter is
missing). The "current point" is the last moveto or similar operation.
cairo_set_text_matrix() : Copies the current transform to the text matrix.
Only ABCD need to be stored, the translation is not used. This and grestore
are the only ways to change the text matrix.
cairo_get_text_matrix() : The current transformation matrix is replaced with
a new one such that 0,0 transforms to the current point and ABCD are set
equal to the current text matrix. This is so cairo drawing operations can be
used to draw glyphs. Use gsave/grestore to get the previous transformation
back.
cairo_set_font("name", A,B,D) : "name" selects a font. ABD sets the font
matrix (unsure what order these are in, but they are x and y scaling, and an
oblique factor). The font glyphs are scaled by the concatenation of the text
matrix and the font matrix. Possibly this is split into two calls, one to
set the name and the other to set the matrix. Notice that changing the text
matrix will also rescale the current font. I do not believe a "font object"
is needed or wanted: hashing the names will allow lookup of an internal
object very quickly, and any program that does not know the entire set of
fonts it will ever use ahead of time is pretty much forced to implement such
a hash table anyway. Also this allows easy disposal of font structures when
they are no longer referred to by any graphics contexts.
cairo_draw_utf8(dx,dy, unsigned char* a, int n) : dx,dy is transformed by the
text matrix and added to the current point to produce the origin of the first
glyph. Each subsequent glyph is drawn at a point that is x_advance,0
transformed by the text matrix added to the previous one. Any missing glyphs
are replaced with some visible glyph with a positive x_advance. The bytes
a[0] through a[n-1] are interpreted as UTF-8. The decoder must pretend a[-1]
and a[n] are 0 and not look at them. Any sequence of bytes that is not legal
UTF-8 (including a code using more bytes than necessary!!!) will instead be
converted so each byte renders one glyph of that value (ie in the 128-255
range), which will allow this interface to draw ISO-8859-1 in almost 100% of
all cases.
float cairo_measure_uft8(unsigned char* a, int n) : the x_advance of all the
glyphs is added together and the x is returned. Since the y_advance is zero
it is not returned.
float cairo_draw_glyphs(glyphs*, int n) : draw n glyphs. Each structure
contains a dx,dy distance from the current point in text transform
coordinates and a ucs32 glyph.
float cairo_draw_utf8s(utf8segment*, int n) : equivalent to n calls to
cairo_draw_utf8(). Each structure contains a dx,dy, an unsigned char*
pointer, and a length. I believe this will be more useful for a pango type
system where the original text is utf8, but I may be wrong...
float cairo_ascent(), cairo_descent(); cairo_get_text_extents(glyphs*), etc :
return various measurements of the font. They are all returned in the text
coordinate system, ie they are converted from the raw font information only
by the font transform. Also y_advance is by definition zero and no field
should be provided to return it.
cairo_list_fonts(...) : Some kind of interface to enumerate all the
simple strings that can be passed to cairo_set_font. Any more complex
enumeration can be device-specific.
--
,~,~,~,~ ~ ~ ~ ~
/\_ _|_========___ Bill Spitzak
~~~/\/\\~~~~~~\____________/~~~~~~~~ spitzak at d2.com
More information about the cairo
mailing list