25. Fonts

Page 426
  25. Fonts  
   
  In Windows, a font is a collection of characters that have a common design. The terminology that Windows uses to describe fonts is not necessarily the same as that used by a typographer, but we will follow the Windows terminology.  
   
  The typeface of a font refers to the specific design of the characters in the font. For instance. Times New Roman and Arial are two different typefaces. One of the main design features of a typeface is the presence or absence of serifs, which are small lines that are designed to help the eyes make a smooth transition from one character to the next. thus making reading less stressful. Figure 25-1 shows the difference between a serif and a sans serif font.  
   
  0426-01.gif  
   
  Figure 25-1.
Serifs and non serifs
 
   
  The term style refers to the weight and slant of a font. Weights range from thin to black in the following order: thin, extralight, light, normal, medium, semibold, bold, extrabold, heavy, and black.  
   
  The slant of a font is characterized as roman, oblique, or italic. A roman style font has no slant; an oblique style font has a slant that is created simply by sheering the characters in a roman font; an italic style font is one that is designed to be slanted.  
Page 427
   
  To quote the documentation:  
  In Windows, the size of a font is an imprecise value. It can generally be determined by measuring the distance from the bottom of a lowercase ''g" to the top of an adjacent uppercase "M," A font's size is specified in units called points. A point is .013837 of an inch. Following the point system devised by Pierre Simon Fournier, it is common practice to approximate a point as 1/72 inch.  
 
  Font Families  
   
  In Windows, fonts are grouped by family, which is a set of fonts having a common stroke width (width of thick and thin lines making up the characters) and serif characteristics. There are five families in Windows, each identified by a symbolic constant:  
 
  Decorative (FF_DECORATIVE)
Novelty fonts
 
 
  Modern (FF_MODERN)
Monospace fonts
 
 
  Roman (FF_ROMAN)
Proportional fonts with serifs, such as Times New Roman
 
 
  Script (FF_SCRIPT)
Fonts designed to look like handwriting
 
 
  Swiss (FF_SWISS)
Proportional fonts without serifs, such as Arial
 
 
  Dontcare (FF_DONTCARE)
A generic family name, used when information about a font does not exist or does not matter
 
 
  Font Technologies  
   
  In Windows, there are four technologies for rendering fonts on the display or printer: raster (or bitmap), vector (or stroke), TrueType, or OpenType. The difference between these technologies centers on how the glyphs are stored in the font file. (A glyph is the data or commands that define a character.)  
   
  The characters of a raster font are stored as bitmaps. As a result, scaling a raster font generally gives very poor results. The characters of a vector font are stored as line segments. However, vector fonts tend to be drawn more slowly than TrueType and OpenType fonts and appear very thin, since the lines that make up the characters are one-pixel wide.  
   
  TrueType and OpenType characters are stored as line segments and curves, along with hints that are used to adjust the rendering of the characters based on point  
Page 428
   
  size. Hence, these fonts can be scaled up or down without losing their intended appearance. (OpenType fonts allow PostScript character definitions as well as TrueType character definitions.)  
   
  The glyphs for a font are stored in a font-resource file (or just font file). For raster and vector fonts, this data is divided into two parts: a header describing the font's metrics, and the glyph data. These files have extension FON. Each TrueType and OpenType font has two associated files a short header file with extension FOT and the font data with extension TTF.  
 
  Character Sets  
   
  We discussed the ASCII, ANSI, and Unicode character sets earlier in the book. Most Windows fonts use character sets that belong to one of the following groups:  
   
  Windows (ANSI)  
   
  Unicode  
   
  OEM (original equipment manufacturer)  
   
  Symbol  
   
  Vendor-specific  
   
  The OEM character set is usually used for console applications (in a text-based window). Symbol character sets contain special symbolic characters in the upper half (characters 128 255), such as those used in mathematics and the sciences.  
 
  Logical and Physical Fonts  
   
  In order for a particular font to be used in an API function, that font must exist on the user's machine. This presents a potential problem, since we have no way to predict which fonts are installed on a given computer. To deal with this issue, Windows uses the notions of logical and physical fonts.  
   
  Physical fonts can be divided into two types: GDI fonts, which are stored in files on the computer's hard disk, and device fonts, which are internal to (or resident in) a given device.  
   
  An application requests a font by creating a font object using the CreateFont or CreateFontIndirect function. The font attributes that are required by these functions define a logical font. When the logical font is selected into a device context using SelectObject. Windows replaces this logical font by a physical font on the user's system that forms the "closest" match to the logical font.  
   
  To do this, Windows applies a font-mapping algorithm. The process is call font realization. TrueType fonts are simply rendered on the device. Simply put, for non-TrueType fonts, Windows chooses the closest device font by assigning a relative  
Page 429
   
  importance to various font characteristics, the most important of which are (in decreasing order of importance): typeface name, character set, variable versus fixed pitch, family, height, width, weight, slant, underline, and strikeout.  
   
  Font Structures  
   
  There are more than two dozen structures associated with fonts, but two of them stand out. The LOGFONT structure describes a logical font:  
 
  Public Const LF_FACESIZE = 32

Type LOGFONT
    lfHeight As Long
    lfWidth As Long
    lfEscapement As Long
    lfOrientation As Long
    lfWeight As Long
    lfItalic As Byte
    lfUnderline As Byte
    lfStrikeOut As Byte
    lfCharSet As Byte
    lfOutPrecision As Byte
    lfClipPrecision As Byte
    lfQuality As Byte
    lfPitchAndFamily As Byte
    lfFaceName (1 To LF_FACESIZE) As Byte
End Type
 
   
  and the TEXTMETRIC structure describes a physical font:  
 
  Type TEXTMETRIC
    tmHeight As Long
    tmAscent As Long
    tmDescent As Long
    tmInternalLeading As Long
    tmExternalLeading As Long
    tmAveCharWidth As Long
    tmMaxCharWidth As Long
    tmWeight As Long
    tmOverhang As Long
    tmDigitizedAspectX As Long
    tmDigitizedAspectY As Long
    tmFirstChar As Byte
    tmLastChar As Byte
    tmDefaultChar As Byte
    tmBreakChar As Byte
    tmItalic As Byte
    tmUnderlined As Byte
    tmStruckOut As Byte
    tmPitchAndFamily As Byte
    tmCharSet As Byte
End Type
 
Page 430
   
  The CreateFont function is used to create a logical font object. Its parameters mimic the members of a LOGFONT structure.  
 
  Declare Function CreateFont Lib "gdi32" Alias "CreateFontA" ( _
   ByVal nHeight As Long, _
   ByVal nWidth As Long, _
   ByVal nEscapement As Long, _
   ByVal nOrientation As Long, _
   ByVal fnWeight As Long, _
   ByVal fdwItalic As long, _
   ByVal fdwUnderline As Long, _
   ByVal fdwStrikeOut As Long, _
   ByVal fdwCharSet As Long, _
   ByVal fdwOutputPrecision As Long, _
   ByVal fdwClipPrecision As Long, _
   ByVal fdwQuality As Long, _
   ByVal fdwPitchAndFamily As Long, _
   ByVal lpszFace As String _
) As Long
 
   
  The CreateFontIndirect function does essentially the same thing:  
 
  Declare Function CreateFontIndirect Lib "gdi32" Alias "CreateFontIndirectA" ( _
   lpLogFont As LOGFONT _
) As Long
 
   
  We will not go into the details of what all of these structure members mean. (Many of them are fairly evident.)  
   
  Getting the Current Logical/Physical Font  
   
  The GetTextMetrics API function returns a TextMetric structure for the currently realized physical font of a device context. The syntax is:  
 
  BOOL GetTextMetrics(
  HDC hdc,            // handle of device context
  LPTEXTMETRIC 1ptm  // address of text metrics structure
);
 
   
  or, in VB:  
 
  Declare Function GetTextMetrics Lib "gdi32" Alias "GetTextMetricsA" ( _
   ByVal hdc As Long, _
   lpMetrics As TEXTMETRIC _
) As Long
 
   
  To get the logical font that was selected into a device context, we need to proceed a bit more circuitously. The SelectObject function:  
 
  HGDIOBJ SelectObject(
  HDC hdc,          // handle of device context
  HGDIOBJ hgdiobj  // handle of object
);
 
Page 431
   
  returns a handle to the previous object of the specified type that was selected into the device context. Accordingly, we can temporarily select a new font into the device context, just to get the return value of SelectObject. We then immediately restore the original logical font:  
 
  Const SYSTEM_FONT = 13
Dim hCurrentFont As Long
Dim lf As LOGFONT

' Get handle to current font
hCurrentFont = SelectObject(Me.hdc, GetStockObject(SYSTEM_FONT))
' Get current font info
GetObject API hCurrentFont, LenB(lf), lf
' Restore font
SelectObject Me.hdc, hCurrentFont

Debug.Print StrConv(lf.lfFaceName, vbUnicode)
 
 
  Enumerating Fonts  
   
  The EnumFontFamiliesEx function can be used to enumerate the fonts on a system:  
 
  int EnumFontFamiliesEx(
  HDC hdc,              // handle to device context
  LPLOGFONT lpLogfont,  // pointer to logical font information
  FONTENUMPROC lpEnumFontFamExProc,
                        // pointer to callback function
  LPARAM lParam,        // application-supplied data
  DWORD dwFlags        // reserved; must be zero
);
 
   
  This enumeration function uses a callback function, as does EnumWindows, for instance. Thus, we need a function to call EnumFontFamiliesEx:  
 
  Sub EnumFonts()

Dim cFonts As Long
Dim lgFont As LOGFONT

lgFont.lfCharSet = DEFAULT_CHARSET

EnumFontFamiliesEx Me.hdc, lgFont, AddressOf EnumFontFamExProc, cFonts, 0

End Sub
 
   
  By setting the value  
 
  lgFont.lfCharSet = DEFAULT_CHARSET  
   
  the EnumFontFamiliesEx function will enumerate all fonts using all character sets.  
   
  Next, we need the callback function:  
 
  Public Function EnumFontFamExProc(ByVal lpelfe As Long, _
   ByVal lpntme As Long, ByVal FontType As Long, ByRef lParam As Long) As Long
 
 

Page 432
 
  Dim elfe As ENUMLOGFONTEX
Dim sFullName As String

' Get a copy of the structure
CopyMemory elfe, ByVal lpelfe, LenB(elfe)

sFullName = Trim0(StrConv(elfe.elfFullName, vbUnicode))
sFullName = sFullName & "_" & _
   Trim0(StrConv(elfe.elfStyle, vbUnicode)) & "_" & _
   Trim0(Strconv(elfe.elfScript, vbUnicode))

Form1.List1.AddItem sFullName

' Increment font count
lParam = lParam + 1

' Continue with enumeration
EnumFontFamExProc = 1

End Function
 
   
  This will produce the list of fonts shown in Figure 25-2.  
   
  0432-01.gif  
   
  Figure 25-2.
Viewing fonts
 
   
  Finally, to see a sample of the selected font in a picture box (see Figure 25-2), we have the following code, which uses CreateFont to create the selected font object, and SelectObject to select that font into the picture box:  
 
  Private Sub List1_Click()

' Create font and select it into Text1
 
 

Page 433
 
  Dim hFont As Long
Dim v As Variant

If List1.ListIndex = -1 Then Exit Sub

pic.Refresh

' Get the face name
v = Split(List1.List(List1.ListIndex), "_", -1

' Create the logical font
hFont = CreateFont( _
   -MulDiv(14, GetDeviceCaps(hdc, LOGPIXELSY), 72), _
   0, _
   0, _
   0, _
   FW_NORMAL, _
   0, _
   0, _
   0, _
   ANSI_CHARSET, _
   OUT_DEFAULT_PRECIS, _
   CLIP_DEFAULT_PRECIS, _
   DEFAULT_QUALITY, _
   DEFAULT_PITCH, _
   V(0))

' Select into the picture box
SelectObject pic.hdc, hFont

' Draw text in picture box
TextOut pic.hdc, 0, 0, "This is " & List1.List(List1.ListIndex), _
   Len("This is " & List1.List(List1.ListIndex))

' Delete font when done
DeleteObject hFont

End Sub
 


WIN32 API Programming with Visual Basic
Win32 API Programming with Visual Basic
ISBN: 1565926315
EAN: 2147483647
Year: 1999
Pages: 31
Authors: Steven Roman

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net