Drawing Text From Different Fonts on the Same Line
Different type styles within a font family can have different widths. For
example, bold and italic styles of a family are always wider than the roman style
for a given point size. When you display or print several type styles on a
single line, you must keep track of the width of the line to avoid having characters
displayed or printed on top of one another.
You can use two functions to retrieve the width (or extent) of text in the
current font. The
GetTabbedTextExtent function computes the width and height of a character string. If the string
contains one or more tab characters, the width of the string is based upon a
specified array of tab-stop positions. The
GetTextExtentPoint32 function computes the width and height of a line of text.
When necessary, Windows synthesizes a font by changing the character bitmaps.
To synthesize a character in a bold font, Windows draws the character twice:
once at the starting point, and again one pixel to the right of the starting
point. To synthesize a character in an italic font, Windows draws two rows of
pixels at the bottom of the character cell, moves the starting point one pixel to
the right, draws the next two rows, and continues until the character has been
drawn. By shifting pixels, each character appears to be sheared to the right. The
amount of shear is a function of the height of the character.
One way to write a line of text that contains multiple fonts is to use the
GetTextExtentPoint32 function after each call to
TextOut and add the length to a current position. The following example writes the
line "This is a sample string." using bold characters for "This is a", switches
to italic characters for "sample", then returns to bold characters for "string."
After printing all the strings, it restores the system default characters.
int XIncrement;
int YStart;
TEXTMETRIC tm;
HFONT hfntDefault, hfntItalic, hfntBold;
SIZE sz;
LPSTR lpszString1 = "This is a ";
LPSTR lpszString2 = "sample ";
LPSTR lpszString3 = "string.";
/* Create a bold and an italic logical font. */
hfntItalic = MyCreateFont();
hfntBold = MyCreateFont();
/* Select the bold font and draw the first string */
/* beginning at the specified point (XIncrement, YStart). */
XIncrement = 10;
YStart = 50;
hfntDefault = SelectObject(hdc, hfntBold);
TextOut(hdc, XIncrement, YStart, lpszString1,
lstrlen(lpszString1));
/*
* Compute the length of the first string and add
* this value to the x-increment that is used for the
* text-output operation.
*/
GetTextExtentPoint32(hdc, lpszString1,
lstrlen(lpszString1), &sz);
XIncrement += sz.cx;
/*
* Retrieve the overhang value from the TEXTMETRIC
* structure and subtract it from the x-increment.
* (This is only necessary for non-TrueType raster
* fonts.)
*/
GetTextMetrics(hdc, &tm);
XIncrement -= tm.tmOverhang;
/*
* Select an italic font and draw the second string
* beginning at the point (XIncrement, YStart).
*/
hfntBold = SelectObject(hdc, hfntItalic);
GetTextMetrics(hdc, &tm);
XIncrement -= tm.tmOverhang;
TextOut(hdc, XIncrement, YStart, lpszString2,
lstrlen(lpszString2));
/*
* Compute the length of the second string and add
* this value to the x-increment that is used for the
* text-output operation.
*/
GetTextExtentPoint32(hdc, lpszString2, lstrlen(lpszString2), &sz);
XIncrement += sz.cx;
/*
* Reselect the bold font and draw the third string
* beginning at the point (XIncrement, YStart).
*/
SelectObject(hdc, hfntBold);
TextOut(hdc, XIncrement - tm.tmOverhang, YStart, lpszString3,
lstrlen(lpszString3));
/* Reselect the original font. */
SelectObject(hdc, hfntDefault);
/* Delete the bold and italic fonts. */
DeleteObject(hfntItalic);
DeleteObject(hfntBold);
In this example, the
GetTextExtentPoint32 function initializes the members of a
SIZE structure with the length and height of the specified string. The
GetTextMetrics function retrieves the overhang for the current font. Because the overhang is
zero if the font is a TrueType font, the overhang value does not change the
string placement. For raster fonts, however, it is important to use the overhang
value.
The overhang is subtracted from the bold string once, to bring subsequent
characters closer to the end of the string if the font is a raster font. Because
overhang affects both the beginning and end of the italic string in a raster
font, the glyphs start at the right of the specified location and end at the left
of the endpoint of the last character cell. (The
GetTextExtentPoint32 function retrieves the extent of the character cells, not the extent of the
glyphs.) To account for the overhang in the raster italic string, the example
subtracts the overhang before placing the string and subtracts it again before
placing subsequent characters.
The
SetTextJustification function adds extra space to the break characters in a line of text. You can
use the
GetTextExtentPoint function to determine the extent of a string, then subtract that extent from
the total amount of space the line should occupy, and use the
SetTextJustification function to distribute the extra space among the break characters in the
string. The
SetTextCharacterExtra function adds extra space to every character cell in the selected font,
including the break character. (You can use the
GetTextCharacterExtra function to determine the current amount of extra space being added to the
character cells; the default setting is zero.)
You can place characters with greater precision by using the
GetCharWidth32 or
GetCharABCWidths function to retrieve the widths of individual characters in a font. The
GetCharABCWidths function is more accurate than the
GetCharWidth32 function, but only when it is used with TrueType fonts; when you use
GetCharABCWidths with non-TrueType fonts, it retrieves the same information as
GetCharWidth32.
ABC spacing also allows an application to perform very accurate text
alignment. For example, when the application right aligns a raster roman font without
using ABC spacing, the advance width is calculated as the character width. This
means the white space to the right of the glyph in the bitmap is aligned, not
the glyph itself. By using ABC widths, applications have more flexibility in the
placement and removal of white space when aligning text, because they have
information that allows them to finely control intercharacter spacing.
- Software for developers
-
Delphi Components
.Net Components
Software for Android Developers
- More information resources
-
MegaDetailed.Net
Unix Manual Pages
Delphi Examples
- Databases for Amazon shops developers
-
Amazon Categories Database
Browse Nodes Database