GLYPH
. We should briefly explain GLYPH
here. The type is defined by
typedef struct { char *bits; struct { int ascent; int descent; int leftSideBearing; int rightSideBearing; int advanceX; int advanceY; } metrics; void *pFontCacheInfo; unsigned long bpp; } GLYPH;
bits
is a pointer to the bitmap data. The
bitmap is organized in lines, starting with the uppermost line.
Each bitmap pixel is usually represented by one bit. If the width of
the
bitmap is not an integer multiple of 8, the lines are padded with
zeros, so that each line starts at a byte boundary. Note that the
bitmap has no margins taken into account. The bitmap occupies the
minimum area the character needs to be painted.
The bitmap pointer may also be
the NULL
-pointer. In this case, the glyph contains no foreground
pixels. The metrics of the corresponding glyph should be valid,
though. Typically, this appears for the space character as well as in
situations where an undefined or unencoded character had been substituted by
the .notdef
-character within the rastering functions.
Note that the pixmap
-entry which has been present in version 0.3-beta,
has been removed with version 0.4-beta. See the discussion on the X11-interface
in for an explanation of this.
The struct metrics
contains metric information that is needed
to position the character and to describe the character origin
with respect to the bitmap. The members in detail:
metrics.ascent
: describes how many lines the bitmap
ranges above the line metrics.descent
: describes how many lines the bitmap
ranges below the line ascent
descent
is the
total height of the bitmap, the number of lines.
metrics.leftSideBearing
: The amount of spacing between
the origin of a character and the x-coordinate of its leftmost
painted pixel. One could also name it ``left margin'' of the
character.
metrics.rightSideBearing
: The horizontal difference between
the origin of a character and the x-coordinate of its rightmost
painted pixel. This definition stands in contrast to some other
interpretations of the right side bearing, where it is assumed as the
difference between the glyph's width and its right most pixel.
metrics.advanceX
: The amount of position increment in
horizontal direction after this character
bitmap (or string bitmap) has been placed. It is almost always
larger than the bitmap width because most characters contain a
certain amount of margins. Note that this value is not suitable for internal
computations of character positions since it contains the horizontal
escapement rounded to the pixel grid. Using this value for such computations
leads to accumulating positioning errors.
metrics.advanceY
: The amount of position increment in
vertical direction after this character
bitmap (or string bitmap) has been placed. Upper direction counts positive.
rightSideBearing
and leftSideBearing
and the values
metrics.leftSideBearing
, metrics.descent
,
metrics.rightSideBearing
and metrics.ascent
effectively describe
the bounding box of the glyph.
The entry pFontCacheInfo
is not currently used but will
probably later when font caching is really
implemented. Moreover, there's a certain chance that some other
entry will be added in future releases.
The member bpp
is used to store the depth of the bitmap. For
true bitmaps, it is always 1. See for an
explanation.
There are three basic functions which produce pointer to glyph objects. In order to generate the glyph for a single character you would use the function
GLYPH *T1_SetChar( int FontID, char charcode, float size, T1_TMATRIX *transform)
FontID
is a valid identification
number of a font. It can range from 0 to
The second argument charcode
determines the character that will
be rasterized.
As mentioned earlier, the encoding mechanism is used for
accessing the output character. This means, if 'A'
is given as
the character code, the machine representation of 'A'
is used
as an index into the current encoding vector. In this encoding vector,
the characters' name is looked up. Encoding vectors may be changed by
the user (see ).
The parameter size
is interpreted in Postscript's bigpoint-unit
(bp). By default,
1 bp equals one device pixel.
transform
specifies the transformation that will be applied to the
character before rastering. If this pointer is NULL
, no transformation
is used. Otherwise it should point to a valid t1lib-transformation matrix.
Please refer to for information on how to easily create
T1_TMATRIX
matrices.
Hinting is only performed if the transformation is a pure rotation and if the
the angle is one of 0, 90, 180 or 270 degrees. Otherwise font level and
character level hinting information is ignored.
Bitmaps of transformed characters are never saved in cache memory since I assume that they are rarely needed. The overhead to manage transformed characters in cache would be overkill and would significantly increase memory consuming. Anyhow, this would only work for some dedicated transformations.
T1_SetChar()
in fact does some more things than simply
rastering the specified character:
Some words concerning memory management: The memory used by
the GLYPH
-structure is static in this function. The memory
required for the bitmap is also allocated by the function itself.
This means, the user doesn't need to free any memory by
himself. Every time T1_SetChar()
is called, it starts by giving the
memory needed for the last generated glyph free or respectively
setting metric values to 0. Thus, do not free the
returned glyph pointer since later T1_SetChar()
will free
memory that is no more allocated and probably used for some other purpose.
If you really like to free the memory, set the pointer to NULL
afterwards.
If an error occurs at some point, T1_SetChar()
returns a
NULL-pointer to the user.
Frequently it is advantageous to raster a series of characters at once. This has the advantage that internal accuracy may be used and the overhead for the user is minimal. For such cases, the function
GLYPH *T1_SetString( int FontID, char *string, int len, long spaceoff, int modflag, float size, T1_TMATRIX *transform)
T1_SetChar()
. The
same as said above applies to the arguments FontID
,
size
and transform
. But a few additional arguments are
needed here.
string
is a series of bytes representing the indices into the current
encoding vector.
The len
-parameter is needed because we cannot imply that string
is always an object like a string in C. For example, the Computer
Modern Roman fonts contain the uppercase Greek Gamma () at
position 0 in their internal encoding. In a string to be typeset the
value 0 is thus a valid value and deserves no special
treatment. Hence, we cannot not use the C-function strlen()
to
compute the length of the string. However, since in most usual encodings
the special value 0 is not encoded (``.notdef
''), it makes
sense to switch between
standard situations and non-standard situations:
string
is a string conforming with C-semantics,
len
can be set to 0. Then, the length of the string is
internally computed.
string
contains one or more control characters which make
processing impossible, the len
-value must be specified
explicitly.
The spaceoff
parameter is important for word processing
purposes. The value specified here is interpreted as an offset to the
space width used during rastering. It is interpreted in charspace
units, i.e., bp. Every time a space character is requested,
this amount of horizontal escapement is added to the natural
spacewidth of the current font. Note that the space character itself
is actually not rastered. All requests to the character with the
charactername ``
space
'' are caught by t1lib and converted
to a simple horizontal escapement. For computation of the resulting
spacewidth, the width of the space-character is taken from the
AFM data and merged with the specified offset, which may also be
negative.5
The modflag
argument may be used to specify some option to the
rastering function. It is generally 0 or an OR'ed combination of the following
names:
T1_KERNING
: As the name implies, this argument
determines that pairwise kerning information from the AFM file is to be taken
into account during string rastering. Not specifying T1_KERNING
means: ``omit kerning''. It is generally
recommended to use kerning information since this improves the optical
appearance. However, many lower quality fonts do not have kerning
information. With t1lib V. 0.4-beta, kerning information is accessible
much faster than before because it is based on char codes rather than on
characternames.
T1_RIGHT_TO_LEFT
: Setting this flag will invert the writing
direction. In Right-To-Left mode the escapement in writing direction
(left) is inserted before placing the character with the result that the
character laps over to the left side. This principle is kept for all
characters in the string. Note that metrics of fonts that are intended for
Right-To-Left typesetting have the same meaning as for fonts intended
for standard (Left-To-Right) typesetting.
T1_UNDERLINE
: The string to be rastered is to be underlined
according to the line specifications of the current font.
T1_OVERLINE
: The string to be rastered is to be over lined.
T1_OVERSTRIKE
: Same here for overstriking.
modflag
argument is a replacement of the kerning
argument from pre-0.7 versions of t1lib.
Concerning glyph-memory considerations, the same applies as said under
the description of T1_SetChar()
: Never free a pointer to memory
which was returned by T1_SetString()
. Or, alternatively, if freeing
the pointer cannot be avoided set it to NULL after freeing it.6
There are two generic ways how a string-glyph can be produced. The first is to
take the paths of all characters needed, concatenate them, insert space and
kerning amounts as needed and raster the resulting whole path. This will yield
the best results since the average position accuracy of the pixels will be
optimal. This applies especially for rotated strings. The drawback is, that
every character must be rastered every time it is needed. There is no way to
access the bitmap data of a character inside a rastered string separate from
others. And the caching of string-glyphs at this programming level doesn't
make any sense. So this principle takes significantly longer than
concatenating bitmaps from a cache area. However, it is done when the
specified rotation angle is not equal to or when even further
transformation are to be applied. This condition should limit the total
number of situations when this happens to an amount we can easily bear.
If the transform
-argument is NULL
we know transformations or
rotation should not be applied and another approach is used. We are then able
to construct the resulting bitmap by adjusting already existent bitmaps into
proper positions. If a character does not already exist in the cache, it is
generated just the way T1_SetChar()
works. The calculation of the
character-bitmap positions in the output bitmap is done with
char space-precision. Nonetheless, there may be differences in the output
compared with output of the above method. These are caused by the fact that
rounding to pixel accuracy has already been achieved when generating the
character bitmap. Thus, the output of the above principle should always be
better since the positions of the black pixels are rounded with respect to the
whole string, and not with respect to a single character glyph. On the other
hand, concatenating character glyphs takes significantly less time than
rastering a complete string. Theoretically, differences of up to two pixels
horizontal shift may appear in the output of the two principles. You can
check the effect by running the program xglyph
. Specify a string of
enough length and raster it at angle . Then specify a very small
angle from 0 different, say,
, and raster the string again with
the new setting. You might find that the representation of the string is a
little different now.
The third function that creates a glyph object is
GLYPH* T1_SetRect( int FontID, float size, float width, float height, T1_TMATRIX *transform)
\vrule
would be appropriate, or, for equations in
mathematical typesetting.
First, the argument FontID
identifies a valid font. At this time, it is
not obvious why a valid font is required in order to create a rectangular
glyph. The reason is, that some of the parameters that are associated to a
particular font are also relevant for creating rectangles in the context of
that font. Hence, specifying a font identifier in this case is a means of
stating ``draw a rectangle that visually fits to the style of the font
FontID
''. Aside from this, I assume that each application that uses
t1lib deals with at least one font so that the FontID
parameter actually does not hurt.
The size of the rectangle is to be specified in charspace units by means of
the parameters width
and height
, and is moreover subject to
scaling through the parameter size
. By definition, the typographical
fundamental area of a font, known as the em-square, is just as high and
as wide as the design size of the font. In charspace units, this rectangle
exactly maps to a
grid. Or alternatively spoken, one
charspace unit is 0.001bp (Big Point). For example, in order to draw an
em-square for some font at 13 points, the correct parameters are
size
,
width
and
height
. If absolute physical dimensions are desired,
the scaling explicitly must be calculated by the user. For instance, in order to
produce a
square we find
size
is assumed to be
The parameter transform
is a pointer to a t1lib transformation
matrix. If it is NULL
, the current transformation of the font in
question is used. Depending on the kind of actual transformation, the
rectangle might also image as a nonrectangular shape. This happens, if the
current font is slanted, then the rectangle will be skewed.
Glyphs produced by the rectangle function are never cached because there is
no means in doing so. With respect to memory management, the same applies as
for T1_SetChar()
and T1_SetString()
. Since rectangles rarely are
used to produce normal text flow, the glyphs produced by the rectangle
function do not cause any escapement.
If two glyphs with arbitrary orientation exist,
GLYPH *T1_ConcatGlyphs( GLYPH *glyph1, GLYPH *glyph2, int x_off, int y_off, int modflag)
NULL
.
bpp
-values. If antialiased and
non-antialiased glyphs are to be concatenated, have a look at
x_off
and y_off
describe the modflag
argument is used to specify the direction in which the two glyphs are to be
concatenated. That is, only the bit T1_LEFT_TO_RIGHT
/
T1_RIGHT_TO_LEFT
is respected by this function.
If problems occur, NULL
is returned.
It is generally not recommended to produce large glyphs with this function
because the char space precision in placing the character bitmaps is lost. For
example, three times rounding up an advance by 0.3 pixels accumulates to 1
pixel position error. A similar effect shows up when two rotated and underlined
glyphs are concatenated with this function. There might be a slight shift in the
baseline at the point where the two glyphs touch.
A dilemma occurs, if two antialiased bitmaps have distinct background
colors. Then, it is not clear what the transparent color
is. T1_ConcatGlyphs()
always assumes the current background color
to be transparent.
There is one more function that generates pointers to glyphs:
GLYPH *T1_CopyGlyph(GLYPH *glyph)
T1_CopyGlyph()
may be used
to copy the glyph to another area which is then completely under user's
control. This function simply does the following:
bpp
into account (see glyph.bits
.
Return value is the pointer to the allocated glyph-structure. If something
goes wrong, NULL is returned to indicate an error. A glyph pointer,
returned by a call to this function should be freed by a call to
T1_FreeGlyph()
(see ).