Text and font

xiaoxiao2021-03-06  47

The display text is the primary issue to be solved by this book. Now let's study how various effective fonts and font size in Microsoft Windows and how to adjust text.

Windows 3.1 issued TrueType makers and users have greatly enhanced the ability to handle text in flexible way. TrueType is an outline font technology, developed by Apple Computer and Microsoft, and supports many font manufacturers. Since the TrueType font can continuously zoom, and can be applied to the video display and a printer, it is now possible to real Wysiwyg (What You see what you get: WYOWY). TrueType is also convenient to make "wonderful" fonts, such as rotating letters, letters of internal padding patterns or use them for cropping areas, in this chapter I will show them.

Simple text output

Let's first look at the Windows for the text output, the device content attribute that affects the text, and various functions provided by the standby font.

Text output function

I have used the most common text output function in many models:

Textout (HDC, XStart, Ystart, Pstring, ICOUNT); Parameters XStart and Ystart are the starting point of the logical seating string. Typically, this is the upper left corner of the first letter started by Windows. Textout needs to point to the indicator of the string and the length of the string, and this function cannot recognize the string terminating with NULL.

The meaning of the XStart and YStart parameters of the Textout function can be changed by the setTextAlign. TA_LEFT, TA_RIGHT and TA_CENTER flags affect how to locate strings in the horizontal direction using XStart. The preset value is TA_LEFT. If TA_RIGHT is specified in the SetTextAlign function, the next Textout call will position the last character of the string in XStart, if TA_Center is specified, the center of the string is located in XStart.

Similarly, TA_TOP, TA_BOTTOM and TA_BASELINE flags affect the vertical position of the string. TA_TOP is a preset value that means that the letter of the letters of the string is located in YSTART, which means that the string is above YStart. You can use a TA_BASELINE to locate strings to enable the baseline in YSTART. The baseline is a line such as lowercase letters P, Q, Y and other letters.

If you use the TA_UPDATECP flag call setTextAlign, Windows ignores the XStart and YStart parameters of Textout, and uses the location of the other letter set by MoveToex, LineTo, or change the current location. The TA_UPDATECP flag also enables the TextOut to update the current location to the end of the string (TA_LEFT) or the beginning of the string (TA_RIGHT). This is very useful when using multiple Textout calls to display a line of text. When the horizontal position is ta_center, after the Textout call, the current location is constant.

You should still remember that when a series of Sysmets in Chapter 4 displays a few columns, you need to call a Textout for each column, and its replacement is a TabbedTextout Verifier:

TabbedTextOut (HDC, XStart, Ystart, Pstring, ICOUNT, INUMTABS, PITABSTOPS, XTaborigin); if the text string contains embedded hop character ('/ t' or 0x09), TabbedTextout will be based on the integer array passed to it. Extension the hop bit character is spaced.

The top five parameters of TabbedTextOut are the same as TextOut. The sixth parameter is the number of hopping spacers, and the seventh is a hop-bit interval array in primary. For example, if the average font width is 8 primitives, and you want every 5 fifth fifth to add a hopping interval, this array will contain 40, 80, 120, and push it in the increment order. If the sixth and seventh parameters are 0 or NULL, the hopping interval is set by the 10 average font width. If the sixth parameter is 1, the seventh parameter points to an integer, indicating a multiple of the hopping interval repeats (for example, if the sixth parameter is 1, and the seventh parameter points to the value of 30 variables, The hopping interval is set at 30, 60, 90 .... The last parameter gives a logical X coordinate starting from the hopping interval, which may differ from the starting position of the string.

Another advanced text output function is extTextout (the header EXT means it is extended):

EXTTEXTOUT (HDC, XStart, YSTART, IOPTIONS, & Rect, PString, Icount, PXDistance); The fifth parameter is a indicator of the rectangular structure. When IOPTIONS is set to ETO_CLIPPED, the structure is a tailor-cut rectangle, and it is set to Eto_opaque in IOptions. This structure is a background rectangle filled with current background colors. These two options you can use or not.

The last parameter is an integer array, which specifies the interval between consecutive fonts in the string. Program can be used to narrow the character pitch or wide, because sometimes adjusts a single text in a narrower column. This parameter can be set to NULL to use the demonstrated character spacing.

The advanced function used to write text is DrawText. We first encountered it in the third chapter to discuss the Hellowin program, it does not specify the starting position of the seat, but defines the area where you want to display text through the Rect structure. :

DrawText (HDC, PString, Icount, & Rect, IFORMAT); Like other text Output, DrawText needs to point to the length of the string and the length of the string. However, if the strings ending with NULL are used in DrawText, ICOUNT can be set to -1, and Windows automatically calculates the length of the string.

When IFORMAT is set to 0, Windows interprets text as a series of rows separated by Carriage Return ('/ R' or 0x0D) or LineFeed fonts ('/ n' or 0x0a). The text starts from the upper left corner of the rectangle, the Carriage Return font or the LineFeed character is interpreted as a wrap character, so Windows will end the current line. The new line starts from the left side of the rectangle, and the height of the flyer is voided below the upper line (there is no external interval). Any words containing letters should be displayed on the right or lower on the bottom of the cut rectangle.

You can change the DrawText's instructions using the iFormat parameter, and iformat consists of one or more flags. The DT_LEFT flag (preset value) specifies the left aligned row, DT_right specifies the row to the right alignment, and the DT_Center specifies the rows located in the left and right side of the rectangle. Because the value of DT_LEFT is 0, if only the left alignment is required, it is not necessary to include the identification word.

If you do not want to interpret the Carriage Return nail or the LineFeed character to a wrap character, you can include identifying the word Dt_SingLine. Then, Windows interprets the Carriage Return font and the LineFeed character as the displayable character, not the control character. When using DT_SINGLINE, the row can also be specified as the top end (DT_TOP), the bottom (DT_BOTTOM) or the middle (DT_VCETER, V. V.). When you display multiple lines, Windows usually only wraps at the Carriage Return nail or the LineFeed character. However, if the length of the line exceeds the width of the rectangle, you can use the DT_WordBreak flag, which makes Windows in the end of the row. For a single line or multi-line text, Windows intercepts the text part of the rectangle, you can use DT_noClip to skip this operation, this flag has accelerated the speed of the function. When Windows determines how many line spacing of multi-line text, it usually uses a font height without an external pitch. If you want to add external spacing in the line spacing, you can use the flag DT_ExternalLleading.

If the text contains a hopping character ('/ t' or 0x09), you need to include flag DT_EXPANDTABS. In the case, the hopping interval is set to the position of every eight characters. By using the flag DT_TABSTOP, you can specify a different hopping interval, in which case the level of the iFormat contains the value of each new hopping interval. But I suggest you avoid using DT_TABSTOP because IFORMAT's high tunnel is also used for other flags.

The problem with the DT_TABSTOP flag can be solved by the new version of DrawTextex, which contains an extra parameter:

DrawTextex (HDC, Pstring, Icount, & Rect, IFORMAT, & DrawTextParams); The last parameter is the indicator of the DrawTextParams structure, which is defined as follows:

typedef struct tagDRAWTEXTPARAMS {UINT cbSize; // size of structureint iTabLength; // size of each tab stopint iLeftMargin; // left marginint iRightMargin; // right marginUINT uiLengthDrawn; // receives number of characters processed} DRAWTEXTPARAMS, * LPDRAWTEXTPARAMS; intermediate The three fields are increments in average font.

Text device content properties

In addition to the sertextalign discussed above, several other device content properties have also affected the text. Under the components of the components, the text color is black, but you can change by the following narrative:

SetTextColor (HDC, RGBCOLOR); uses the color of the brush and the color of the painting brush, Windows converts RGBCOLOR value to solid color, you can get the color of the current text by calling GetTextColor.

Windows displays text in the rectangular background area, which may color according to the settings of the background mode, or not do it. you can use it

SetBKMode (HDC, Imode); Change the background mode, where the value of IMODE is Opaque or Transparent. The background pattern is Opaque, which means that Windows uses background colors to fill rectangles. you can use it

Setbkcolor (HDC, RGBColor); to change the background color. The value of RGBColor is converted to a solid value. The complex background is white. If the two lines are too close, one of the background rectangles will cover another text. For this reason, I usually want to have a background pattern in the background. In the case of the background mode for Transparent, Windows will ignore the background color, nor colored in the rectangular background area. Windows also uses background mode and background color pairs and dotted gaps and shadows in the shadow brush, just like the fifth chapter.

Many Windows programs specify white_brush as Windows to scribe the brush on the window background, and the brush is specified in the window category structure. However, you may want you to keep the window background with the user consistent with the system color set in "Console". In this case, you can specify this method of background color in the WNDCLASS structure:

WNDCLASS.HBRBACKGROUND = color_window 1; When you want to write text in the display area, you can use the current system color setting text color and background color:

SetTextColor (HDC, GetSysColor); setBkcolor (HDC, GetSysColor (Color_Window)); Finish these, you can make your program vary with system color changes:

Case WM_SYSCOLORCHANGE: INVALIDATERECT (HWND, NULL, TRUE); Break; Another device content attribute that affects text is a character spacing. Its preset is 0, indicating that Windows does not add any space between the characters, but you can use the following function inserted space:

SetTextCharacterextra (HDC, IEXTRA); Parameters iptra are logical units, and Windows converts them to the closest icon, which can be 0. If you take IEXTRA to negative (you want to crush the characteristics), Windows accepts the absolute value of this value - that is, you can't make the value of IEXTRA less than 0. You can get the current character spacing by calling GetTextCharacterextra, and Windows converts the icon spacing into logical units before returning to this value.

Use spare fonts

When you call textOut, TabbedTextOut, ExtTextOut, DrawText, or DrawTexTex written text, Windows uses the fonts currently selected in the device content. The font defines specific words and sizes. The easiest way to display text with different fonts is to use the spare fonts provided by Windows, however, its range is very limited.

You can call the following in the form of the code to get a code of a spare font:

HFONT = getStockObject (ifont); where IFONT is one of several identification words. You can then select the font to the device content:

SelectObject (HDC, HFONT); You can also use only one step:

SelectObject (HDC, GetStockObject (ifont)); the font selected in the content of the components is referred to as a system font, and can be identified by the system_font parameter of GetStockObject. This is the restrued ANSI character set font. Specify system_fixed_font in GetStockObject (I am using it in the previous few programs of this book), you can get the ascending font code, this font is compatible with the system font before Windows 3.0. This is very convenient when you want all fonts.

The spare font OEM_FIXED_FONT is also known as the terminal font, which is the font used in the MS-DOS command prompt window, which includes a character set with the original IBM-PC extension character set. Windows uses defult_gui_font in the text of the window title column, functional table and dialog. When you select the new font to the device content, you must use the GetTextMetrics to calculate the height and average width of the font. If you choose a reconciling font, it must be noted that the average width of the font is just a average, and some of the characters are wider than it or narrower than it. Behind this chapter, you'll learn how to determine the total width of the string consisting of different width fonts.

Although getStockObject does provide the easiest way to access different fonts, you can't fully control the fonts provided by Windows. Soon, you will see a method of specifying font words and sizes.

Font background

The remaining parts of this chapter are dedicated to handling different fonts. But before you contact these specific programming, there is a deep understanding of the basic knowledge of Windows using fonts.

Font type

Windows supports two types of fonts, the so-called "GDI font" and "equipment font". The GDI font is stored in the file of the hard disk, and the device font is the output device. For example, the typographic machine has a built-in device font set.

There are three styles of GDI fonts: dot matrix fonts, stroke fonts and trueType fonts.

Each of the characters of the dot matrix is ​​stored in the form of a dot matrix pattern, each with a specific aspect ratio and a character size. Windows can produce larger characters by GDI docking fonts by simply replicating rows or columns of the primary. However, it can only be magnified by integer multiplication and cannot exceed certain limits. For this reason, the GDI dot matrix font is also called "unpretable" font. They cannot be randomly enlarged or narrow. The main advantage of the dot matrix font is that the display performance (fast display speed) and readability (because it is manually designed, so clearly).

The font is identified by the font name, the font name of the dot matrix font is:

SYSTEM (for system_font)

FIXEDSYS (for system_fixed_font)

TERMINAL (for OEM_FIXED_FONT)

Courier

MS Serif

MS SANS Serif (for default_gui_font)

Small fonts

There are only several sizes of each dot matrix (no more than 6). The Courier font is a wide font and the shape is similar to the fonts played with the typewriter. "Serif" refers to the font letter string to turn a small bend at the end. The "Sans Serif" font is not a font of the Serff class. In earlier versions of Windows, MS (Microsoft) Serif and MS Sans Serif fonts are called TMS RMN (refer to Times Roman) and Helv (similar to Helvetica). Small Fonts is designed for display of small characters.

Before Windows3.1, in addition to the GDI font, Windows provided by Windows only pen-drawn fonts. The stroke font is a series of line segments defined in the way of "connecting nodes". The stroke font can be scaled continuously, which means that the same font can be used for a graphic output device having any resolution, and the font can enlarge or shrink to any size . However, its performance is not good, the readability of the small font is also very thin, and the big font is very thin because the stroke is a single straight line. The stroke font is sometimes referred to as a plotter font because they are particularly suitable for the plotting machine, but is not suitable for other occasions. The words of the stroke font include: Modern, Roman and Script.

For GDI dot matrix fonts and GDI stroke fonts, Windows can "synthesize" bold, slope, spline and deletion deletion, without having to store fonts for each property. For example, for the slope, Windows only needs to move the upper right of the character to the right. Next is TrueType, I will discuss it in the remaining parts of this chapter.

TrueType font

The single-character of the TrueType font is defined by the outline of the fill line and the profile of the curve. Windows can zoom the TrueType font by changing the coordinates of the defined profile.

When the model starts using a specific size TrueType font, Windows "Point Cancet" font. That is to say that Windows scales the "prompt" included in the TrueType font file to scale the coordinates of each of the characters. These tips can compensate for errors, avoiding the synthetic fonts (for example, in certain fonts, the two vertical should be as wide, but blindly zoom the fonts may cause one of the vertical elements than the other Vertical. With a prompt to avoid these phenomena). Then, the synthetic contour of each of the characters is used to establish a dot matrix map of the character, and these dot matrix are stored in the memory for future use.

Initially, Windows used 13 TrueType fonts, and their font names are as follows:

Courier New

Courier New Bold

Courier New Italic

Courier New Bold Italic

Times New Roman

Times New Roman Bold

Times New Roman Italic

Times New Roman Bold Italic

Arial

Arial Bold

Arial italic

Arial Bold Italic

Symbol

In the new Windows version, this list is longer. In particular, I will use the Lucida Sans Unicode font, which includes some alphabets used in other parts of the world.

The three main characters are similar to the dot matrix font, and Courier New is a wide font. It looks like a font output by typewriter. Times New Roman is a replica of Times fonts, which is originally designed to be "Times of London" and is used in many printed materials. It has good readability. Arial is a replica of Helvetica fonts and is a SANS Serif font. The Symbol font contains a handwritten symbol set.

Attribute or style

In the list of TrueType fonts, you will notice that Courier, Times New Roman and Arial bold and bertlast are separate fonts with their own font names, which is consistent with traditional panels. However, computer users believe that bold and slope are only special "attributes". Windows uses a method for defining a dot matrix naming, listing, and selection. But for the TrueType font, it is more inclined to use traditional naming methods.

This conflict has not fully resolved in Windows. In short, you can select fonts through naming or specific properties. However, when processing the font, the application requires a list of fonts in the system, just as you expect, this dual processing makes the problem complicated.

Point value

In the traditional layout, you can specify the font with the font name and size, and the size of the font is represented in units. It is very close to 1/72 inches - they are very close, so it is usually defined in the computer to be 1/72 inches. The point value is usually described as the height of the alphabet (exclaimed symbol) to the bottom end of the letter, for example, the total height of the letter "BQ". This is a simple way to consider the font size, but it is usually not very accurate.

The point value of the font is actually the concept of the typographic design rather than the metric concept. The size of the font in the specific font may be greater than or smaller than the size indicated by its point value. In traditional layouts, you use points to specify the size of the font, in the computer typography, there are other methods to determine the actual size of the character. Interval and spacing

In Chapter 4 we mentioned that we can use this card several times by calling GetTextMetrics to get the current selection in the device content. Figure 4-3 shows the vertical size of the font in the FontMetric structure.

The other field of the TextMetric structure is TMExternalleading, the word "Leading" from the typographic worker inserted by the metal block, which is used to create a gap between two lines. The TMInternalLleading value is related to the space preserved for the pronunciation symbol, and TMExternalLleading indicates the additional space left between the continuous lines of the character. Program writers can use or ignore external intervals.

When we say that a font is 8 or 12 points, it refers to the height of the interior interval. A pronunciation symbol on a big write letter occupies the spacing of the partition. Thus, the TemTmetriC structure of the TemHeight value actually guides points rather than the point value of the font. The point value of the font can be obtained by TmHeight minus TMINTERNALLEADING.

Logical inch problem

As we discussed in Chapter 5 The Windows 98 defines the system font as 10 points of fonts with 12-point row. According to the "small font" or "big font" in the "display attribute" dialogue, the TmHeight value of the font is 16 or 20, and TemHeight minus the value of 13 or 16 in the TMInternalleAding. In this way, the selection of the font means that "small font" is 96dpi, select "Large Font", which is 120dpi.

You can use the Logpixelsx or Logpixelsy parameter to call getDeviceCaps to get the device resolution. Therefore, the measure distance of 96 or 120 in the screen may be referred to as "logical inches". If you measuring the screen and calculate the icon, you may find that the logical inch is better than the actual inches, why?

On paper, 14 8 points per inch is convenient to read. If you are handling or writing an application in a textbook, you may want to display a clear 8-point pattern on the display, but if you use the actual size of the video display, there is not enough indicia to clearly display the word element. Even if the display has sufficient resolution, there will be a problem with 8 o'clock on the screen. When people read printers on the paper, the distance between the eyes and the text is usually one foot, and this distance is usually two feet when using the video display.

Logic inch is effectively enlarged to the screen, which can show a clear font for small to 8 points. Moreover, the minimum display size of 640 inch is equal to about 6.5 inches per inch 96 points. This is precisely the width of the text of the text of 8.5-inch wide sheets of paper. Thus, logical inches also uses the screen width to display text as much as possible.

You may still remember that in Chapter 5, Windows NT is different. In Windows NT, the LogPixelsx (number of digits per inch) obtained from getDeviceCaps is not equal to the HorzRES value (number of images) divided by the HORZSIZE value (mm number) and multiplied by 25.4. Similarly, Logpixelsy, Vertres, and Vertsize are inconsistent. Windows uses Horzres, Horzsize, Vertres and Vertsize values ​​when calculating the window and offset ranges for different mapping. However, the program that shows text is best not to use the assumed display resolution based on Logpixelsx and LogPixelsy, which is more consistent with Windows 98.

So, under Windows NT, when the text is displayed at a specific point value, it may not use the mapping mode provided by Windows, and the program defines its own mapping mode based on the number of logical status as the Windows 98. I am calling this mapping method for text is a "logical twips" mapping method. You can set the following:

SetmapMode (HDC, MM_anisotropic); SetWindowExtex (HDC, 1440, 1440, NULL); SetViewPortext (HDC, GetDeviceCaps (HDC, Logpixelsx), GetDeviceCaps (HDC, Logpixelsy), NULL; use this mapping mode setting, you can 20 times more of the point value to specify the font size, for example, a 12-point word 240. Note that the MM_TWIPS mapping mode is different, the Y value grows down in the screen, which is very convenient to display the continuous line of the text.

Keep in mind that the difference between logical inch and actual inters is only exists on the display. On the printing device, GDI and ruler are completely consistent.

Logical font

Since we have clarified the concept of logical inch and logical units, then we will now discuss logical fonts.

The logical font is a GDI object, and its code is stored in a variable in the HFONT type, and the logical font is a description of the font. As with the logical brush and logical painting, it is an abstract object, only when the application call SelectObject When it is selected into the device content, it becomes a real object. For example, for a logical brush, you can specify any color for the brush, but when you select the brush to select the device content, Windows convert it to a valid color in the device. Only at this time, Windows knows the color of the device.

Establishment and selection of logical fonts

You can create logical fonts through call CREATEFONT or CREATEFONTIIRECT. The CreateFontIndirect function accepts an indicator pointing to the LogFont structure, which has 14 columns. The CreateFont is accepted 14 parameters that are the same as 14 fields of the LogFont structure. They are only two functions of establishing logical fonts (I mention this because there are many functions for other font operations in Windows). Because it is difficult to remember 14 columns, it rarely uses CREATEFONT. Therefore, I mainly discuss CREATEFONTINDIRECT.

There are three basic ways to define the fields in the logfont structure to call CREATEFONTINDIRECT:

You can simply set the field of the LogFont structure to the font feature required. In this case, when calling SelectObject, Windows uses the "Font Mapping" algorithm to select the font that matches these features from the device. Since this depends on the effective font on the video display and the press, the result may be considerable to your requirements. You can list all fonts on your device and choose from it, and even display them with the dialogue. I will discuss the font listed in this chapter. However, they are now not usually used because the third method can also be enumerated. You can use a simple method and call the Choosefont. I have discussed this letter in Chapter 11 that can use the logfont structure to build fonts. In this chapter, I use the first and third methods.

Below is a program for establishing, selecting, and deleting logical fonts:

Establish logical fonts by calling CREATEFONT or CREATEFONTINDIRECT, these functions return to the logical font code of the HFONT type. Use SelectObject to select the logical font to the device content, Windows selects the true fonts that are most matching with the logical font. Use GetTextMetrics (and other functions that may be used) to determine the size and characteristics of the true font. After the font is selected into the device content, you can use these information to properly set the spacing of the text. After using the logical font, call the deleteObject to delete the logical font, when the font is selected to be valid, do not delete the font, and do not delete the standby font. GetTextFacery enables programs to determine the font names currently selected: GetTextFace (HDC, SizeOf (Szfacename) / sizeof (tchar), szfacename); detailed font information can be obtained from GetTextMetrics:

GetTextMetrics (HDC, & TextMetric); where TextMetric is a variable of the TextMetric type, which has 20 columns.

I will discuss the field of the Logfont and TextMetric structures later. These two structures have some similar fields, so they are easily confused. Now you only need to remember, logfont is used to define logical fonts, while TextMetric is used to obtain font information in the content of the device.

PickFont program

You can define a number of fields of the LogFont structure using the PickFont shown in the program 17-1. This program establishes a logical font and the characteristics of the real font after the logic font is selected into the device content. This is a convenient program, through which we can understand the way logical fonts are mapped to real fonts.

Program 17-1 pickfontpickfont.c / * ----------------------------------------- ----------------------------------- Pickfont.c - Create Logical Font (C) Charles Petzold, 1998 -------------------------------------------------- ------------------------- * /

#include #include "resource.h"

// Structure shared between main window and dialog boxtypedef struct {int iDevice, iMapMode; BOOL fMatchAspect; BOOL fAdvGraphics; LOGFONT lf; TEXTMETRIC tm; TCHAR szFaceName [LF_FULLFACESIZE];} DLGPARAMS; // Formatting for BCHAR fields of TEXTMETRIC structure # ifdef UNICODE #define bcharform text ("0x% 04x") # Else # Define Bcharform text ("0x% 02x") # ENDIF

// Global VariableshWnd HDLG; tchar szappname [] = text ("pickfont");

// Forward declarations of functionsLRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); BOOL CALLBACK DlgProc (HWND, UINT, WPARAM, LPARAM); void SetLogFontFromFields (HWND hdlg, DLGPARAMS * pdp); void SetFieldsFromTextMetric (HWND hdlg, DLGPARAMS * pdp); void MySetMapMode (HDC hdc, int iMapMode); int WINAPI WinMain (hINSTANCE hInstance, hINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; (! RegisterClass (& wndclass)) if {MessageBox (NULL, TEXT ( "! This program requires Windows NT"), szAppName, MB_ICONERROR); return 0; } hWnd = CREATEWINDOW (Szappname, Text ("Pi ckFont: Create Logical Font "), WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd); while (GetMessage (& msg, NULL, 0 , 0) {if (hdlg == 0 ||! Isdialogmessage (hdlg, & msg)) {TranslateMessage (& MSG); DispatchMessage (& MSG);}} Return Msg.wParam;

LResult Callback WndProc (HWND HWND, UINT MESSAGE, WPARAM WPARAM, LPARAM LPARAM) {static dlgparams dp; static tchar sztext [] = text ("/ x41 / x42 / x43 / x44 / x45") Text ("/ x61 / x62 / X63 / x64 / x65 ")

TEXT ("/ xc0 / xc1 / xc2 / xc3 / xc4 / xc5") Text ("/ xe0 / xe1 / xe2 / xe3 / xe4 / xe5") #ifdef unicodetext ("/ x0390 / x0391 / x0392 / x0393 / x0394 / X0395 ") TEXT (" / x03b0 / x03b1 / x03b2 / x03b3 / x03b4 / x03b5 ") Text (" / x0410 / x0411 / x0412 / x0413 / x0414 / x0415 ") Text (" / x0430 / x0431 / x0432 / x0433 / x0434 / x0435 ") TEXT (" / x5000 / x5001 / x5002 / x5003 / x5004 ") #endif; HDC hdc; PAINTSTRUCT ps; RECT rect; switch (message) {case WM_CREATE: dp.iDevice = IDM_DEVICE_SCREEN; hdlg = CreateDialogParam (( (LPCREATESTRUCT) lParam) -> hInstance, szAppName, hwnd, DlgProc, (LPARAM) & dp); return 0; case WM_SETFOCUS: SetFocus (hdlg); return 0; case WM_COMMAND: switch (LOWORD (wParam)) {case IDM_DEVICE_SCREEN: case IDM_DEVICE_PRINTER: CheckMenuItem (GetMenu (hwnd), dp.iDevice, MF_UNCHECKED); dp.iDevice = LOWORD (wParam); CheckMenuItem (GetMenu (hwnd), dp.iDevice, MF_CHECKED); SendMessage (hwnd, WM_COMMAND, IDOK, 0); Return 0;} Break;

Case WM_Paint: HDC = BeginPaint (HWND, & PS);

// set Graphics Mode So Escapement Works in WINDOWS NT

SetgraphicsMode (HDC, DP.FADVGRAPHICS? GM_ADVANCED: GM_COMPATIBLE);

// set the mapping mode and the mapper flag

MySetMapMode (HDC, DP.Imapmode); SetMapPerflags (HDC, DP.FMATchaspect);

// Find the point to begin drawing text

GetClientRect (HDLG, & Rect); Rect.Bottom = 1; DPTOLP (HDC, (PPOINT) & Rect, 2);

// Create and SELECT The font; Display Text

SelectObject (HDC, CreateFontIndirect (& DP.LF)); Textout (HDC, Rect.left, Rect.Bottom, Sztext, Lstrlen (Sztext);

DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))); EndPaint (hwnd, & ps); return 0; case WM_DESTROY: PostQuitMessage (0); return 0;} return DefWindowProc (hwnd, message, wParam, lParam);} BOOL CALLBACK DlgProc (HWND hdlg, UINT message, WPARAM wParam, LPARAM lParam) {static DLGPARAMS * pdp; static PRINTDLG pd = {sizeof (PRINTDLG)}; HDC hdcDevice; hFONT hFont; switch (message) {case WM_INITDIALOG: // Save pointer to Dialog-parameters structure in wndproc

PDP = (DLGPARAMS *) LPARAM;

SendDlgItemMessage (hdlg, IDC_LF_FACENAME, EM_LIMITTEXT, LF_FACESIZE - 1, 0); CheckRadioButton (hdlg, IDC_OUT_DEFAULT, IDC_OUT_OUTLINE, IDC_OUT_DEFAULT); CheckRadioButton (hdlg, IDC_DEFAULT_QUALITY, IDC_PROOF_QUALITY, IDC_DEFAULT_QUALITY); CheckRadioButton (hdlg, IDC_DEFAULT_PITCH, IDC_VARIABLE_PITCH, IDC_DEFAULT_PITCH); CheckRadioButton ( hdlg, IDC_FF_DONTCARE, IDC_FF_DECORATIVE, IDC_FF_DONTCARE); CheckRadioButton (hdlg, IDC_MM_TEXT, IDC_MM_LOGTWIPS, IDC_MM_TEXT); SendMessage (hdlg, WM_COMMAND, IDOK, 0); // fall throughcase WM_SETFOCUS: SetFocus (GetDlgItem (hdlg, IDC_LF_HEIGHT)); return FALSE;

Case WM_COMMAND: Switch (WPARAM) {CASE IDC_CHARSET_HELP: MessageBox (HDLG, Text ("0 = ANSI / N") Text ("1 = default / n") Text ("2 = Symbol / N") Text "128 = Shift JIS (Japanese) / N") Text ("129 = hangul (korean) / n") text ("130 = johab (korean) / N") text ("134 = GB 2312) / n ") Text (" 136 = Chinese Big 5 / N ") Text (" 177 = hebrew / n ") text (" 178 = arabic / n ") Text (" 161 = GREEK / N ") Text ("162 = TURKISH / N") Text ("163 = Vietnamese / N") Text ("204 = Russian / N") Text ("222 = THAI / N") Text ("238 = East European / N") TEXT ("255 = OEM"), SZAPPNAME, MB_OK | MB_ICONICONFORMATION; RETURN TRUE; // Thase Radio Buttons Set The LfoutPrecision Field

Case IDC_OUT_DEFAULT: PDP-> LF.LfoutPrecision = OUT_DEFAULT_PRECIS; RETURN TRUE

Case IDC_Out_String: PDP-> LF.LfoutPrecision = OUT_STRING_PRECIS; RETURN TRUE

Case IDC_OUT_CHARACTER: PDP-> LF.LfoutPrecision = OUT_CHARACTER_PRECIS; RETURN TRUE

Case IDC_OUT_STROKE: PDP-> LF.LFoutPrecision = OUT_STROKE_PRECIS; RETURN TRUE

Case IDC_OUT_TT: PDP-> LF.LfoutPrecision = OUT_TT_PRECIS; RETURN TRUE;

Case IDC_Out_Device: PDP-> lf.lfoutPrecision = OUT_DEVICE_PRECIS; RETURN TRUE;

Case IDC_OUT_RASTER: PDP-> LF.LfoutPrecision = OUT_RASTER_PRECIS; RETURN TRUE

CASE IDC_OUT_TT_ONLY: PDP-> LF.LfoutPrecision = OUT_TT_ONLY_PRECIS; RETURN TRUE

Case IDC_out_outline: PDP-> LF.LFoutPrecision = OUT_OUTLINE_PRECIS; RETURN TRUE

// THEE RADIO Buttons Set The LFquality Field

Case IDC_DEFAULT_QUALITY: PDP-> LF.LFQuality = default_quality; return true; case idc_draft_quality: PDP-> lf.lfquality = Draft_quality; return true;

Case IDC_Proof_quality: PDP-> LF.LFQUALITY = Proof_quality; Return True;

// THEE RADIO Buttons Set The Lower Nibble // of The LFPITCHANDFAMILY FIELD

Case IDC_DEFAULT_PITCH: PDP-> lf.lfpitchandFamily = (0xF0 & PDP-> LF.LFPITCHANDFAMILY) | default_pitch; return true;

Case IDC_FIXED_PITCH: PDP-> LF.LFPITCHANDFAMILY = (0xF0 & PDP-> LF.LFPITCHANDFAMILY) | fixed_pitch; return true;

Case IDC_VARIABLE_PITCH: PDP-> LF.LFPITCHANDFAMILY = (0xF0 & PDP-> LF.LFPITCHANDFAMILY) | Variable_pitch; return true;

// Thase Six Radio Buttons Set The Upper Nibble // of The LFPITCHFAMILY FIELD

Case IDC_FF_DONTCARE: PDP-> LF.LFPITCHANDFAMILY = (0x0f & pdp-> lf.lfpitchandfamily) | ff_dontcare; return true;

Case IDC_FF_ROMAN: PDP-> LF.LFPITCHANDFAMILY = (0x0f & PDP-> LF.LFPITCHANDFAMILY) | FF_ROMAN; RETURN TRUE

Case IDC_FF_SWISS: PDP-> LF.LFPITCHANDFAMILY = (0x0f & PDP-> LF.LFPITCHANDFAMILY) | ff_swiss; return true;

Case IDC_FF_MODERN: PDP-> LF.LFPITCHANDFAMILY = (0x0F & PDP-> LF.LFPITCHANDFAMILY) | FF_MODERN; RETURN TRUE

Case IDC_FF_Script: PDP-> LF.LFPITCHANDFAMILY = (0x0f & PDP-> LF.LFPITCHANDFAMILY) | ff_script; return;

Case IDC_FF_DECORATIVE: PDP-> LF.LFPITCHANDFAMILY = (0x0F & PDP-> LF.LFPITCHANDFAMILY) | FF_DECORATIVE; RETURN TRUE

// mapping mode:

case IDC_MM_TEXT: case IDC_MM_LOMETRIC: case IDC_MM_HIMETRIC: case IDC_MM_LOENGLISH: case IDC_MM_HIENGLISH: case IDC_MM_TWIPS: case IDC_MM_LOGTWIPS: pdp-> iMapMode = LOWORD (wParam); return TRUE; // OK button pressed // --------- ------------

Case IDok: // Get Logfont Structure

SetLogFontFromfireDs (HDLG, PDP);

// SET MATCH-Aspect and Advanced Graphics Flags

PDP-> FMATCHASPECT = ISDLGBUTTONCHECKED (HDLG, IDC_MATCH_ASPECT); PDP-> Fadvgraphics = IsdlGButtonChecked (HDLG, IDC_ADV_GRAPHICS);

// Get Information Context

if (pdp-> iDevice == IDM_DEVICE_SCREEN) {hdcDevice = CreateIC (TEXT ( "DISPLAY"), NULL, NULL, NULL);} else {pd.hwndOwner = hdlg; pd.Flags = PD_RETURNDEFAULT | PD_RETURNIC; pd.hDevNames = NULL; pd.hdevmode = null;

Printdlg (& PD);

HDCDevice = pd.hdc;} // set the mapping mode and the mapper flag

MySetMapMode (HDCDevice, PDP-> ImapMode); SetMapPerflags (HDCDevice, PDP-> Fmatchaspect);

// Create Font and SELECT IT IC

HFONT = CREATEFONTINDIRECT (& PDP-> LF); SelectObject (HDCDevice, HFONT);

// Get the text metrics and face name

GetTextMetrics (HDCDevice, & PDP-> TM); GetTextFace (HDCDEVICE, LF_FULLFACESIZE, PDP-> SZFACENAME); deletedc (HDCDevice); deleteObject (hfont);

// Update Dialog Fields and Invalidate Main Window

SetFieldsFromTextMetric (hdlg, pdp); InvalidateRect (GetParent (hdlg), NULL, TRUE); return TRUE;} break;} return FALSE;} void SetLogFontFromFields (HWND hdlg, DLGPARAMS * pdp) {pdp-> lf.lfHeight = GetDlgItemInt ( hdlg, IDC_LF_HEIGHT, NULL, TRUE); pdp-> lf.lfWidth = GetDlgItemInt (hdlg, IDC_LF_WIDTH, NULL, TRUE); pdp-> lf.lfEscapement = GetDlgItemInt (hdlg, IDC_LF_ESCAPE, NULL, TRUE); pdp-> lf. lfOrientation = GetDlgItemInt (hdlg, IDC_LF_ORIENT, NULL, TRUE); pdp-> lf.lfWeight = GetDlgItemInt (hdlg, IDC_LF_WEIGHT, NULL, TRUE); pdp-> lf.lfCharSet = GetDlgItemInt (hdlg, IDC_LF_CHARSET, NULL, FALSE); pdp -> lf.lfItalic = IsDlgButtonChecked (hdlg, IDC_LF_ITALIC) == BST_CHECKED; pdp-> lf.lfUnderline = IsDlgButtonChecked (hdlg, IDC_LF_UNDER) == BST_CHECKED; pdp-> lf.lfStrikeOut = IsDlgButtonChecked (hdlg, IDC_LF_STRIKE) == BST_CHECKED; Getdlgitemtext (HDLG, IDC_LF_FFCENAME, PDP-> LF.LFFACENAME, LF_FACESIZE);} void setfieldsfromtextMetric (hwnd hdlg, dlgparams * pdp) {tchar szbuffer [10]; tchar * szyes = text ("yes"); TCHAR * SZNO = TEXT ("NO"); tchar * szfamily [] = {Text ("Don't Know"), Text ("Roman"), Text ("Swiss"), Text ("Modern"), Text ("Script"), Text ("Decorative"), Text ("Undefined")}

SetDlgItemInt (hdlg, IDC_TM_HEIGHT, pdp-> tm.tmHeight, TRUE); SetDlgItemInt (hdlg, IDC_TM_ASCENT, pdp-> tm.tmAscent, TRUE); SetDlgItemInt (hdlg, IDC_TM_DESCENT, pdp-> tm.tmDescent, TRUE); SetDlgItemInt ( hdlg, IDC_TM_INTLEAD, pdp-> tm.tmInternalLeading, TRUE); SetDlgItemInt (hdlg, IDC_TM_EXTLEAD, pdp-> tm.tmExternalLeading, TRUE); SetDlgItemInt (hdlg, IDC_TM_AVECHAR, pdp-> tm.tmAveCharWidth, TRUE); SetDlgItemInt (hdlg, IDC_TM_MAXCHAR, pdp-> tm.tmMaxCharWidth, TRUE); SetDlgItemInt (hdlg, IDC_TM_WEIGHT, pdp-> tm.tmWeight, TRUE); SetDlgItemInt (hdlg, IDC_TM_OVERHANG, pdp-> tm.tmOverhang, TRUE); SetDlgItemInt (hdlg, IDC_TM_DIGASPX, pdp-> tm.tmDigitizedAspectX, TRUE); SetDlgItemInt (hdlg, IDC_TM_DIGASPY, pdp-> tm.tmDigitizedAspectY, TRUE); wsprintf (szBuffer, BCHARFORM, pdp-> tm.tmFirstChar); SetDlgItemText (hdlg, IDC_TM_FIRSTCHAR, szBuffer);

WSPrintf (szbuffer, bcharform, pdp-> tm.tmlastchar); setdlgitemtext (hdlg, idc_tm_lastchar, szbuffer);

WSPrintf (szbuffer, bcharform, pdp-> tm.tmdefaultchar); setdlgitemtext (HDLG, IDC_TM_DEFCHAR, SZBUFFER);

WSPrintf (szbuffer, bcharform, pdp-> tm.tmbreakchar); setdlgitemtext (HDLG, IDC_TM_BREAKCHAR, SZBUFFER);

SetDlgItemText (hdlg, IDC_TM_ITALIC, pdp-> tm.tmItalic szYes: szNo?); SetDlgItemText? (Hdlg, IDC_TM_UNDER, pdp-> tm.tmUnderlined szYes:? SzNo); SetDlgItemText (hdlg, IDC_TM_STRUCK, pdp-> tm.tmStruckOut szYes : szno);

Setdlgitem text (HDLG, IDC_TM_VARIABLE, TMPF_FIXED_PITCH & PDP-> TM.TMPITCHFAMILY? SZYES: SZNO);

Setdlgitem text (HDLG, IDC_TM_Vector, TMPF_VECTOR & PDP-> TM.TMPITCHANDFAMILY? SZYES: SZNO);

Setdlgitem text (HDLG, IDC_TM_TRUETYPE, TMPF_TRUETYPE & PDP-> TM.TMPITCHFAMILY? SZYES: SZNO);

SetDlgItem Text (hdlg, IDC_TM_DEVICE, TMPF_DEVICE & pdp-> tm.tmPitchAndFamily szYes: szNo?); SetDlgItem Text (hdlg, IDC_TM_FAMILY, szFamily [min (6, pdp-> tm.tmPitchAndFamily >> 4)]);

Setdlgitemint (HDLG, IDC_TM_CHARSET, PDP-> TM.TMCHARSET, FALSE); setdlgitemtext (HDLG, IDC_TM_FACENAME, PDP-> SZFACENAME);}

void MySetMapMode (HDC hdc, int iMapMode) {switch (iMapMode) {case IDC_MM_TEXT: SetMapMode (hdc, MM_TEXT); break; case IDC_MM_LOMETRIC: SetMapMode (hdc, MM_LOMETRIC); break; case IDC_MM_HIMETRIC: SetMapMode (hdc, MM_HIMETRIC); break ; case IDC_MM_LOENGLISH: SetMapMode (hdc, MM_LOENGLISH); break; case IDC_MM_HIENGLISH: SetMapMode (hdc, MM_HIENGLISH); break; case IDC_MM_TWIPS: SetMapMode (hdc, MM_TWIPS); break; case IDC_MM_LOGTWIPS: SetMapMode (hdc, MM_ANISOTROPIC); SetWindowExtEx (hdc , 1440, 1440, NULL); SetViewportExtEx (hdc, GetDeviceCaps (hdc, LOGPIXELSX), GetDeviceCaps (hdc, LOGPIXELSY), NULL); break;.}} PICKFONT.RC // Microsoft Developer Studio generated resource script # include "resource. H "#include" afxres.h "

/// DialogPICKFONT DIALOG DISCARDABLE 0, 0, 348, 308STYLE WS_CHILD | WS_VISIBLE | WS_BORDERFONT 8, "MS Sans Serif" BEGINLTEXT "& Height:", IDC_STATIC, 8,10,44,8EDITTEXT IDC_LF_HEIGHT, 64,8,24,12, ES_AUTOHSCROLLLTEXT "& Width", IDC_STATIC, 8,26,44,8EDITTEXT IDC_LF_WIDTH, 64,24,24,12, ES_AUTOHSCROLLLTEXT "Escapement:", IDC_STATIC, 8,42,44,8EDITTEXT IDC_LF_ESCAPE, 64,40,24,12, ES_AUTOHSCROLLLTEXT "Orientation:", IDC_STATIC, 8,58,44,8EDITTEXT IDC_LF_ORIENT, 64,56,24,12, ES_AUTOHSCROLLLTEXT "Weight:", IDC_STATIC, 8,74,44,8EDITTEXT IDC_LF_WEIGHT, 64,74,24,12, ES_AUTOHSCROLLGROUPBOX "Mapping Mode", IDC_STATIC, 97,3,96,90, WS_GROUPCONTROL "Text", IDC_MM_TEXT, "Button", BS_AUTORADIOBUTTON, 104,13,56,8CONTROL "Low Metric", IDC_MM_LOMETRIC, "Button", BS_AUTORADIOBUTTON, 104, 24,56,8CONTROL High Metric ", IDC_MM_HIMETRIC," Button ", BS_AUTORADIOBUTTON, 104,35,56,8CONTROL" Low English ", IDC_MM_LOENGLISH," Button ", BS_AUTORADIOBUTTON, 104,46,56,8CONTROL" High English ", IDC_MM_HIENGLISH , "Button", BS_AUTORADIOBUTTON, 104, 57, 56, 8Control "twips", IDC _MM_TWIPS, "Button", BS_AUTORADIOBUTTON, 104,68,56,8CONTROL "Logical Twips", IDC_MM_LOGTWIPS, "Button", BS_AUTORADIOBUTTON, 104,79,64,8CONTROL "Italic", IDC_LF_ITALIC, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 8 , 90,48,12CONTROL "Underline", IDC_LF_UNDER, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 8,104,48,12CONTROL "Strike Out", IDC_LF_STRIKE, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 8,118,48,12CONTROL "Match Aspect", IDC_MATCH_ASPECT, "Button", BS_AUTOCHECKBOX | WS_TABSTOP, 60, 104, 62, 8Control "Adv Grfx Mode"

"?": |, IDC_ADV_GRAPHICS, "Button", BS_AUTOCHECKBOX WS_TABSTOP, 60,118,62,8LTEXT "Character Set", IDC_STATIC, 8,137,46,8EDITTEXT IDC_LF_CHARSET, 58,135,24,12, ES_AUTOHSCROLLPUSHBUTTON, IDC_CHARSET_HELP, 90,135,14,14GROUPBOX " Quality ", IDC_STATIC, 132,98,62,48, WS_GROUPCONTROL" Default ", IDC_DEFAULT_QUALITY," Button ", BS_AUTORADIOBUTTON, 136,110,40,8CONTROL" Draft ", IDC_DRAFT_QUALITY," Button ", BS_AUTORADIOBUTTON, 136,122,40,8CONTROL" Proof ", IDC_PROOF_QUALITY," Button ", BS_AUTORADIOBUTTON, 136,134,40,8LTEXT" Face Name: ", IDC_STATIC, 8,154,44,8EDITTEXT IDC_LF_FACENAME, 58,152,136,12, ES_AUTOHSCROLLGROUPBOX" Output Precision ", IDC_STATIC, 8,166,118,133, WS_GROUPCONTROL" OUT_DEFAULT_PRECIS ", IDC_OUT_DEFAULT , "Button", BS_AUTORADIOBUTTON, 12,178,112,8CONTROL "OUT_STRING_PRECIS", IDC_OUT_STRING, "Button", BS_AUTORADIOBUTTON, 12,191,112,8CONTROL "OUT_CHARACTER_PRECIS", IDC_OUT_CHARACTER, "Button", BS_AUTORADIOBUTTON, 12,204,112,8CONTROL "OUT_STROKE_PRECIS", IDC_OUT_STROKE, "Button", BS_AUTORADIOBUTTON, 12, 217, 112, 8Control "OUT_TT_PRECIS" , IDC_OUT_TT, "Button", BS_AUTORADIOBUTTON, 12,230,112,8CONTROL "OUT_DEVICE_PRECIS", IDC_OUT_DEVICE, "Button", BS_AUTORADIOBUTTON, 12,243,112,8CONTROL "OUT_RASTER_PRECIS", IDC_OUT_RASTER, "Button", BS_AUTORADIOBUTTON, 12,256,112,8CONTROL "OUT_TT_ONLY_PRECIS", IDC_OUT_TT_ONLY, "Button ", BS_AUTORADIOBUTTON, 12,269,112,8CONTROL" OUT_OUTLINE_PRECIS ", IDC_OUT_OUTLINE," Button ", BS_AUTORADIOBUTTON, 12,282,112,8GROUPBOX" Pitch ", IDC_STATIC, 132,166,62,50, WS_GROUPCONTROL" Default ", IDC_DEFAULT_PITCH," Button "

, BS_AUTORADIOBUTTON, 137,176,52,8CONTROL "Fixed", IDC_FIXED_PITCH, "Button", BS_AUTORADIOBUTTON, 137,189,52,8CONTROL "Variable", IDC_VARIABLE_PITCH, "Button", BS_AUTORADIOBUTTON, 137,203,52,8GROUPBOX "Family", IDC_STATIC, 132,218, 62,82, WS_GROUPCONTROL "Do not Care", IDC_FF_DONTCARE, "Button", BS_AUTORADIOBUTTON, 137,229,52,8CONTROL "Roman", IDC_FF_ROMAN, "Button", BS_AUTORADIOBUTTON, 137,241,52,8CONTROL "Swiss", IDC_FF_SWISS, "Button ", BS_AUTORADIOBUTTON, 137,253,52,8CONTROL" Modern ", IDC_FF_MODERN," Button ", BS_AUTORADIOBUTTON, 137,265,52,8CONTROL" Script ", IDC_FF_SCRIPT," Button ", BS_AUTORADIOBUTTON, 137,277,52,8CONTROL" Decorative ", IDC_FF_DECORATIVE," Button ", BS_AUTORADIOBUTTON, 137,289,52,8DEFPUSHBUTTON" OK ", IDOK, 247,286,50,14GROUPBOX" Text Metrics ", IDC_STATIC, 201,2,140,272, WS_GROUPLTEXT" Height: ", IDC_STATIC, 207,12,64,8LTEXT" 0 " , IDC_TM_HEIGHT, 281, 12, 44, 8LText "Ascent:", IDC_STATIC, 207, 22, 64, 8LText "0", IDC_TM_ASCENT, 281, 22, 44, 8LText "Descent:", IDC_STATIC, 207, 32, 64, 8LTEXT "0", IDC_TM_DESCENT, 281, 32, 44, 8LText "Internal" Leading: ", IDC_STATIC, 207, 42, 64, 8LText" 0 ", IDC_TM_INTLEAD, 281, 42, 44, 8LTEXT" External Leading: ", IDC_STATIC, 207, 52, 64, 8LText" 0 ", IDC_TM_EXTLEAD, 281, 52 44, 8LText "Ave Char Width:", IDC_STATIC, 207, 62, 64, 8LText "0", IDC_TM_AVECHAR, 281, 62, 44, 8LText "Max Char Width:", IDC_STATIC, 207, 72, 64, 8LText " 0 ", IDC_TM_MAXCHAR, 281, 72, 44, 8LText" Weight: ", IDC_STATIC, 207, 82, 64, 8LText" 0 ", IDC_TM_Weight, 281, 82, 44, 8lText" Overhang: ", IDC_STATIC, 207, 92, 64, 8LText "0"

, IDC_TM_OVERHANG, 281,92,44,8LTEXT "Digitized Aspect X:", IDC_STATIC, 207,102,64,8LTEXT "0", IDC_TM_DIGASPX, 281,102,44,8LTEXT "Digitized Aspect Y:", IDC_STATIC, 207,112,64,8LTEXT " 0 ", IDC_TM_DIGASPY, 281, 112, 44, 8LText" First Char: ", IDC_STATIC, 207, 122, 64, 8LText" 0 ", IDC_TM_Firstchar, 281, 122, 44, 8lText" Last Char: ", IDC_STATIC, 207, 132, 64, 8LText" 0 " , IDC_TM_LASTCHAR, 281,132,44,8LTEXT "Default Char:", IDC_STATIC, 207,142,64,8LTEXT "0", IDC_TM_DEFCHAR, 281,142,44,8LTEXT "Break Char:", IDC_STATIC, 207,152,64,8LTEXT "0", IDC_TM_BREAKCHAR 281, 152, 44, 8LText "Italic?", IDC_STATIC, 207, 162, 64, 8LText "0", IDC_TM_ITALIC, 281, 162, 44, 8LTEXT "underlined?", IDC_STATIC, 207, 172, 64, 8LText "0", IDC_TM_UNDER, 281, 172, 44 , 8LTEXT "Struck Out?", IDC_STATIC, 207,182,64,8LTEXT "0", IDC_TM_STRUCK, 281,182,44,8LTEXT "Variable Pitch?", IDC_STATIC, 207,192,64,8LTEXT "0", IDC_TM_VARIABLE, 281,192,44,8LTEXT "VECTOR FONT?", IDC_STATIC, 207, 202, 64, 8LText "0", IDC_TM_Vector, 281, 202, 44, 8LTEXT "TrueType Font?", IDC_STATIC, 207, 212, 64, 8LText "0", IDC_TM_TRueType, 2 81,212,44,8LTEXT "Device Font?", IDC_STATIC, 207,222,64,8LTEXT "0", IDC_TM_DEVICE, 281,222,44,8LTEXT "Family:", IDC_STATIC, 207,232,64,8LTEXT "0", IDC_TM_FAMILY, 281,232,44 8LText "Character set:", IDC_STATIC, 207, 242, 64, 8LText "0", IDC_TM_CHARSET, 281, 242, 44, 8LText "0", IDC_TM_FACENAME, 207, 262, 128, and 8

/// MenuPICKFONT MENU DISCARDABLE BEGINPOPUP "& Device" BEGINMENUITEM "& Screen", IDM_DEVICE_SCREEN, CHECKEDMENUITEM "& Printer", IDM_DEVICE_PRINTERENDENDRESOURCE.H // Microsoft Developer Studio generated include file.// Used by PickFont.rc

#define IDC_LF_HEIGHT 1000 # define IDC_LF_WIDTH 1001 # define IDC_LF_ESCAPE 1002 # define IDC_LF_ORIENT 1003 # define IDC_LF_WEIGHT 1004 # define IDC_MM_TEXT 1005 # define IDC_MM_LOMETRIC 1006 # define IDC_MM_HIMETRIC 1007 # define IDC_MM_LOENGLISH 1008 # define IDC_MM_HIENGLISH 1009 # define IDC_MM_TWIPS 1010 # define IDC_MM_LOGTWIPS 1011 # define IDC_LF_ITALIC 1012 # define IDC_LF_UNDER 1013 # define IDC_LF_STRIKE 1014 # define IDC_MATCH_ASPECT 1015 # define IDC_ADV_GRAPHICS 1016 # define IDC_LF_CHARSET 1017 # define IDC_CHARSET_HELP 1018 # define IDC_DEFAULT_QUALITY 1019 # define IDC_DRAFT_QUALITY 1020 # define IDC_PROOF_QUALITY 1021 # define IDC_LF_FACENAME 1022 # define IDC_OUT_DEFAULT 1023 # define IDC_OUT_STRING 1024 #define IDC_OUT_CHARACTER 1025 # define IDC_OUT_STROKE 1026 # define IDC_OUT_TT 1027 # define IDC_OUT_DEVICE 1028 # define IDC_OUT_RASTER 1029 # define IDC_OUT_TT_ONLY 1030 # define IDC_OUT_OUTLINE 1031 # define IDC_DEFAULT_PITCH 1032 # define IDC_FIXED_PITCH 1033 # define IDC_VARIABLE_PITCH 1034 # define IDC_FF_DONTCARE 1035 # define IDC_FF_ROMAN 1036 # define IDC_FF_SWISS 1037 # define IDC_FF_MODERN 1038 # define IDC_FF_SCRIPT 1039 # define IDC_FF_DECORATIVE 1040 # define IDC_TM_HEIGHT 1041 # define IDC_TM_ASCENT 1042 # define IDC_TM_DESCENT 1043 # define IDC_TM_INTLEAD 1044 # define IDC_TM_EXTLEAD 1045 # define IDC_TM_AVECHAR 1046 # define IDC_TM_MAXCHAR 1047 # define IDC_TM_WEIGHT 1048 #define IDC_TM_OVERHANG 1049 # define IDC_TM_DIGASPX 1050 # define IDC_TM_DIGASPY 1051 # define IDC_TM_FIRSTCHAR 1052 # define IDC_TM_LASTCHAR 1053 # define IDC_TM_DEFCHAR 1054 # define IDC_TM_BREAKCHAR 1055 # define IDC_TM_ITALIC 1056 # define IDC_TM_UNDER 1057 # define IDC_TM_STRUCK 1058 # define IDC_TM_VARIABLE 1059 # define IDC_TM_VECTOR 1060 # define IDC_TM_TRUETYPE 1061 # Define IDC_TM_Device 1062 # define IDC_TM_FAMILY 1063 # Defin

E IDC_TM_CHARSET 1064 # Define IDC_TM_FACENAME 1065 # define idm_device_screen 40001 # define IDM_Device_printer 40002 Figure 17-1 shows a typical PickFont screen display. The PICKFONT left half shows a non-modular dialog, through it, you can choose most of the fields of logical font structures. The right half of the dialog box shows the results of the GetTextMetrics after the font is selected. The lower part of the dialogue, the program uses this font to display a string. Since the non-modular dialogue is very large, it is best to perform this program at 1024 × 768 or more display size. Figure 17-1 Typical PICKFONT screen display (Unicode version under Windows NT)

Non-modular dialogues also contain options for non-logical font structures, which are mapping methods including "logical twips", "Match Aspect" option (Change Windows matching logical fonts with real fonts) and "Adv GRTX Mode Setting up the advanced graphics mode in Windows NT). I will discuss this later.

From the "Device" menu, you can select the internal printing machine instead of the video display. In this case, PickFont selects the logical font into the printing machine device content and displays the TextMetric structure from the printer. Then, the logical font is selected in the window device content to display the sample string. Therefore, the text displayed by the program may use fonts (screen fonts) different from the font (printing font) described by the TextMetric field.

Most logic of the PICKFont program is in handling the necessary actions of the dialogue, so I will not discuss the working mode of the program, only explain the principles of establishing and selecting logical fonts.

Logical font structure

You can call createFont to create a logical font, which is a function of 14 parameters. General, define a structure of a logfont type

Logfont LF; then define the field of this structure is more easier. After completing, you can use the indicator to call this structure call CREATEFONTINDIRECT:

HFont = CreatFontIndirect (& lf); You don't have to set each field of the logfont structure. If the logical font structure is defined as a static variable, all the fields will initialize 0, 0 is generally a preset value. Then, you can use this structure directly without the change, CreateFontIndirect will return to the code of the font. When you select the font to the device content, you will get a reasonable font. You can fill the logfont structure according to your needs, clear or blurred, and Windows will match your requirements with a real font.

When I discuss each field in the LogFont structure, you may want to test them with a PickFont program. Don't forget to press Enter or "OK" buttons when you want to use any of the columns you entered.

The first two fields of the LogFont structure are logical units, so they rely on the current setting of the mapping method:

Lfheight This is the hopes height of the desired character represented by logical unit. You can set the LFHEIGHT to use the memory size, or set it to a positive or negative number according to the meaning of the field represented. If the LFHEIGHT is set to positive, you want this value to represent the height of the internal interval (not external interval). In fact, the required font line spacing is LFHEIGHT. If the LFHEIGHT is set to a negative value, Windows will use its absolute value as a font height consistent with the point value. This is a very important difference: if you want a font of a specific point value, you can convert the point value to a logical unit and set the LFHEIGHT field to the negative number of the value. If LFHEIGHT is a positive value, the TemHeight field of the TextMetric structure is approximately this value (sometimes tiny deviation, possibly due to rounding errors). If LFHEIGHT is a negative value, it is roughly matched to the TemTMeTRC structure that does not include the TextMetric structure that does not include the TMInternalLleading field. Lfwidth is the character's desired width of the logical unit. In most cases, this value can be set to 0, so that Windows is only selected according to the height selective font. The use of a non-zero value to the dot matrix font does not work too much, but for the TrueType font, you can easily use it to get a wider or narrower than normal fonts. This field corresponds to the TMAVECHARWIDTH field of the TextMetric structure. To use the LFWidth field correctly, first set the LogFont structure with the LFWidth field to 0, establish a logical font, and select it into the device content, then call GetTextMetrics. Get the TMAVECHARWIDTH field, the size of its value can be adjusted, and then the second font is established using the adjusted LFWIDTHTMAVHARWIDTH value. The next two fields specify the "shift angle" and "direction" of the text. In theory, LFESCAPEMENT enables strings to write at a certain angle (but the baseline of each character is still parallel to the horizontal axis), while the LirtInt is tilted with a single character. But these two fields are not so effective, even now they can only work well in the case: using the TuReType font, perform Windows NT and first use the cm_advanced flag to set the call setgraphicsmode. By selecting the "Adv Grfx Mode" verified, you can complete the final needs in PickFont. When verifying these fields in the PickFont, you should pay attention to the unit is very common, rotate counterclockwise. It's easy to enter a value to disappear! Therefore, use the value between 0 to -600 or 3000 to 3600.

LFESCAPEMENT This is a very angle measurement of counterclockwise from the horizontal direction. It specifies the way to place the continuous font of the string when writing text. Table 17-1 provides several examples: Table 17-1

The placement of the value font is from left to right (internal) 900 up 1800 from right to left 2700

In Windows 98, this value sets the shift angle and direction of TrueType text. In Windows NT, this value is usually set, in addition to calling SETGRAPHICSMODE with the GM_ADVANCED parameter, it works as described in the file.

Lirtation This is a very angle measurement measured from the horizontal direction, which affects the appearance of a single character. Table 17-2 provides several examples: Table 17-2

Value font appearance 0 Normal (internal) 900 to right inclined 90 degree 1800 reverse 2700 to incline 90 degrees

This field is generally not a function, unless the TrueType font is used under Windows NT, and the image mode is set to GM_ADVANCED, in this case it works as described in the file. The remaining 10 columns are as follows:

LfWeight This field allows you to specify bold. Wingdi.h header file defines a set of values ​​that can be used in this field (see Table 17-3). Table 17-3

Value of identification word 0 FW_DONTCARE 100 FW_THIN 200 FW_EXTRALIGHT or FW_ULTRALIGHT 300 FW_LIGHT 400 FW_NORMAL or FW_REGULAR 500 FW_MEDIUM 600 FW_SEMIBOLD or FW_DEMIBOLD 700 FW_BOLD 800 FW_EXTRABOLD or FW_ULTRABOLD 900 FW_HEAVY or FW_BLACK

In fact, it is perfect than any of the previously used values. You can use 0 or 400 for standard characters, use 700 to bold.

Lfitalic is specified in a non-zero value. Windows can synthesize the hemure on the GDI dot matrix font. That is, Windows only moves several line fifth dot mapping to mimic the hem. For TrueType fonts, Windows uses a true slope or font. LFunderLine When a non-zero value, it specifies the bottom line, which is synthesized in the GDI font. That is, Windows GDI is only the bottom line including each character line of spaces. LFSTRIKEOUT In a non-zero value, it should have a line on a line. This is also synthesized by GDI font. Lfcharset This is the value of a bit set of the specified font font set. I will discuss this field in more detail in the next section "Flections and Unicode". In PickFont, you can press the button with the question mark to get the character set list. Note that the LFcharset field is the only field that does not need zero to represent the preset value. The zero value is equivalent to the ANSI_CHARSET, ANSI fonts are used in the United States and Western Europe. The DEFAULT_CHARSET code is equal to 1, indicating the franchise set on the machine executed.

LfoutPrecision It specifies how Windows is a way to match the desired font size and characteristics of the actual font. This is a complex field, which is generally rarely used. Check out the files on the logfont structure to get more detailed information. Note that you can use the OUT_TT_ONLY_PRECIS flag to ensure that the TrueType font is obtained. The LFClipPrecision This field specifies how the character is cut when a part of the character is located outside the cut zone. This field is not used frequently, and the PICKFONT has not used it. LFQUALITY This is an instruction to Windows, and is instructions that match the desired font matching the actual font. It actually only makes sense to the dot matrix, does not affect the TrueType font. The Draft_Quality flag indicates that the GDI zoom dot matrix is ​​required to get the desired size; the Proof_quality flag indicates that there is no need to zoom. The proof_quality font is the most beautiful, but they may be smaller than the desired. DEFAULT_QUALITY (or 0) can also be used in this field. The LFPITCHANDFAMILY is composed of two parts. You can use the bit or operator symbol to combine two identifier words for this field. The lowest two-bit specified font is widened (ie, the width of all the fonts is equal) or widened (see Table 17-4). Table 17-4

Value Identification Word 0 Default_pitch 1 fixed_pitch 2 variable_pitch

The upper half of the bit group specifies the word system series (see Table 17-5).

Table 17-5

Value identification word 0x00 fw_dontcare 0x10 ff_roman (widening, serif) 0x20 ff_swiss (widening, non-serif) 0x30 ff_modern (wide) 0x40 FF_Script (Imitation handwriting) 0x50 ff_decoAdayAmeLFFCename This is about words (such as Courier, Arial or Times New Roman) The actual text name. This field is a bit group array of width LF_FaceSize (or 32). There are two ways if you want to get the slope or bold font of TrueType. Use the full font name (such as Times New Roman Italic) in the LFFACename field, or you can use the basic name (ie Times New Roman) and set the LFITALIC field. Font mapping algorithm

After setting the logical font structure, call CREATEFONTINDIRECT to get the logical font code. When the call SelectObject selects the logical font to the device content, Windows looks for the actual font that is closest to the desired font. It uses "font mapping algorithm". Some columns of the structure are more important than other fields.

The best way to understand the font mapping is to spend some time trial PickFont. Here are a few guidelines:

Lfcharset is very important. If you specify OEM_CHARSET (255), you will get some stroke font or terminal font because they are the only fonts using OEM character sets. However, with the appearance of TrueType "Big Fonts" (in Chapter 6 section), a single TrueType font can map to different font sets including OEM font sets. You need to use Symbol_Charset (2) to get Symbol fonts or WINGDINGS fonts. The Fixed_PITCH pitch value of the LFPITCHANDFAMILY field is important because you actually tell Windows do not want to process wide fonts. The LFFACename field is important because you specify the words of the required font. If the LFFACename is set to NULL and set the group value to a value other than ff_dontcare in the LFPITCHANDFAMILY field, because the font series is specified, the field is also important. For the dot matrix font, Windows will try to match the LFheight value, even if you need to increase the size of the smaller font. The high level of the actual font is always less than or equal to the required font, unless there is no smaller font to meet your requirements. For strokes or TrueType fonts, Windows simply scales fonts to the required height. You can prevent Windows zoom dot matrix by setting LFQuality to Proof_quality. Do you can tell Windows's font high without font. If the LFHEIGHT and LFWEIGHT values ​​that are not coordinated for the display of the display, Windows can be mapped to the dot matrix fonts designed for the display or other aspect ratio. This is a technique that gets fine or crude fonts (of course, it is unnecessary to the TrueType font). In general, you may want to avoid changing fonts for another device. You can do it in the PickFont by clicking the Nuclear Acquisition with "Match Aspect". If you select a verification block, PickFont uses the True parameter call setmapperflags. Font information

On the right side of the Afro-modal dialogue in the PickFont is information obtained from the GetTextMetrics function after the font is selected (note, "the" Device "function table that can be used in PickFont indicates that the device is the screen or the inner stamping machine. Because The valid font on the printer may be different, so the results may also be different). At the bottom of the list in the PickFont is the valid font name obtained from the GetTextFace. In addition to numerical aspect ratio, all size values ​​replicated to the TextMetric structure are represented in logical units. The field of the TextMetric structure is as follows:

The characteristic height of the temheight logical unit. It approximates the value of the LFHEIGHT field specified in the logfont structure, if the value is positive, it represents the line spacing, rather than point value. If the LFHEIGHT field of the logfont structure is negative, the TMHEIGHT field minus the TminternalLleading field should be approximately equal to the absolute value of the LFHEIGHT field. The character line of the TMASCENT logical unit is vertically large. The radioclass below the TMDESCENT logic unit is vertical. TminternalLleading is included in the Temheight value, which is usually occupied by some uppercase letters. Also, the point value of the font can be calculated using the TMHEIGHT value to reduce the TminternalLleading value. TmexternalLleading Tmheight is recommended, and the design of the font is recommended for continuous lines of the text. The average width of lowercase letters in the TmaveCharWidth font. The maximum width of the character of the TMMaxCharWidth logical unit. This value is the same as TmaveCharwidth for a wide range. TMWEIGHT font weight, range from 0 to 999. In fact, this field is 400 is a standard font, 700 is bold. TMOVERHANG Windows adds an additional width (logical unit) that is added to the dot matrix font font when synthetic hemure or bold. When the dot matrix is ​​obliquely, the TmaveCharWidth value remains the same because the slopelated string is equal to the total width of the same normal string. To bold the font, Windows must increase the width of each of the characters slightly. For bold, the TmaveCharWidth value is less than the TMOVERHANG value, which is equal to the TMAVHARWIDTH value of the same font without a bold. TmdigitizedAspectX and TMDigitizedaSpectY fonts suitable aspect ratio. They are the same as the value obtained from getDeviceCaps using Logpixelsx and Logpixelsy identification words. The character code of the first character in the TMFirstChar font. The character code of the last character of the TmLastChar font. This value may be greater than 255 if the TextMetric structure is obtained by calling GetTextMetricsw (Wide Bright Version). TMDEFAULTCHAR Windows is used to display the character code of the characters in the font, usually a rectangle. TMBREAKCHAR When adjusting text, Windows and your program are used to determine the single-word disconnection. If you don't have to have some strange things (such as EBCDic fonts), it is 32- blank font. Tmitalic is a non-zero value for the italic word. TMunderLined is a non-zero value for the bottom line font. TMSTRUCKOUT is a non-zero value for the delete line font. The TmpitchandFamily low four-bit element is a flag indicating some of the characteristics of the font, which is pointed out by the identification word defined in WingDi.h (see Table 17-6). Table 17-6

Value identification word 0x01 TMPF_FIXED_PITCH 0X02 TMPF_VECTOR 0X04 TMPF_TRUETYPE 0X08 TMPF_DEVICE

Regardless of the name of the TMPF_FIXED_PITCH flag, if the font font is widened, the lowest bit is 1. The second lowest bit element (TMPF_Vector) is 1 for the trueType font and fonts using other scalable contour techniques (such as PostScript font) to 1. The TMPF_Device flag represents the device font (ie the font built into the printer), not based on the font of GDI. The fourth high bit element of this field represents the word system and is the same as the value used in the LogFont's LFPITCHANDFAMILY field.

TMCharset character set identification word. Flections and Unicode

I discussed the concept of a Windows font set in Chapter 6, where we have to deal with internationalization issues related to keyboards. In the LogFont and TextMetric structure, the desired font (or actual font) is represented by the value of a single bit group between 0 and 255. The character identification word defined in Wingdi.h is shown below:

#define ANSI_CHARSET 0 # define DEFAULT_CHARSET 1 # define SYMBOL_CHARSET 2 # define MAC_CHARSET 77 # define SHIFTJIS_CHARSET 128 # define HANGEUL_CHARSET 129 # define HANGUL_CHARSET 129 #define JOHAB_CHARSET 130 # define GB2312_CHARSET 134 # define CHINESEBIG5_CHARSET 136 # define GREEK_CHARSET 161 # define TURKISH_CHARSET 162 # define VIETNAMESE_CHARSET 163 # define HEBREW_CHARSET 177 # define ARABIC_CHARSET 178 # define BALTIC_CHARSET 186 # define RUSSIAN_CHARSET 204 # define THAI_CHARSET similar 222 # define EASTEUROPE_CHARSET 238 # define concepts OEM_CHARSET 255 character set and the page table, but the specific character sets for Windows, and typically It is less than or equal to 255.

As with all the books of this book, you can compile PickFont with a defined Unicode identifier, or you can compile it without Unicode recognition. As usual, two versions of the programs on this book are located in the debug and release directory, respectively.

Note that PickFont's strings displayed at the bottom of its window are longer in the UNICODE version. In two versions, the character code of the string is 0x40 to 0x45, 0x60 to 0x65. Regardless of which character set (except Symbol_Charset), these character code displays the top five uppercases and lowercase letters (ie A to E and A to E) of the Latin alphabet.

When performing a non-Unicode version of the PICKFONT, the next 12 word-character code 0xc0 to 0xc5 and 0xE0 to 0xE5 will depend on the selected character set. For ansi_charset, this character code corresponds to the plus-bounce version of uppercase and lowercase letters A. For Greek_Charset, these code correspond to the letters of the Greek alphabet. For Russian_Charset, the letter corresponding to the Slavic alphabet. Note that when you choose a character set, the font may change because the dot matrix font may not have these characters, but the trueType font may have. You may remember that most TrueType fonts are "BIG FONTS" and include several different font sets of letters. If you execute the Far East version of Windows, these characters will be interpreted as a dual-bit tuft font and will be displayed in blocks instead of by alphabet. When performing the Unicode version of PickFont under Windows NT, the code 0xc0 to 0xc5 and 0xE0 to 0xE5 are usually uppercase and lowercase letters A plus-bounce version (except Symbol_Charset), which defines these codes in Unicode. The program also shows the character code of 0x0390 to 0x0395 and 0x03B0 to 0x03B5. Since they are defined in Unicode, these code always correspond to the letters of the Greek alphabet. Similarly, the units of 0x0410 to 0x0415 and 0x0430 to 0x0415 and 0x0430 to 0x0435 are displayed, which correspond to the letters of the Slavic alphabet. However, these fonts cannot exist in the internal definition font, you must choose Greek_Charset or Russian_Charset to get them. In this case, the character set id in the logfont structure does not change the actual character set; the character set is always Unicode. The character set ID indicates the character from the desired character set.

Now select Hebrew_Charset (Code 177). Hebrew alphabet is not included in Windows usual BIG FONTS, so the job system selects Lucida Sans Unicode, which you can verify in the lower right corner of the non-modular dialogue.

PickFont also shows the character code of 0x5000 to 0x5004, which corresponds to part of Chinese, Japanese, and North Korea. If you perform Windows's Far East version, or download the free Unicode font than the Lucida Sans Unicode, you can see it. BitStream Cyberbit is such a font, you can find from http://www.bitstream.com/products/world/cyberbits. (Lucida Sans Unicode is approximately 300K, while BitStream Cyberbit is about 13m). If you have this font, when you need a font that is not supported by Lucida Sans Unicode, Windows selects it, these fonts such as Shiftjis_Charset (Japanese), Hangul_Charset, Johab_Charset (Korean), GB2312_Charset (Simplified Chinese) or Chinesebig5_charset (Traditional Chinese).

There is a program that will allow you to view all letters of the Unicode font.

EZFont system

The TrueType font system (based on traditional typography) provides a strong foundation for Windows. However, some Windows font selection functions are based on older technologies, so that the dot matrix font on the screen must approach the printing machine device font. The next section will tell the font to enumerate the display of all valid fonts on the display or printer. However, "Choosefont" dialogue (discussed later) does significantly eliminate the necessity of the program. Because standard TrueType fonts can be used on any system, and these fonts can be used for display and printers, so that the program is not necessary when selecting a TrueType font or in the absence of information, there is no need. Reform the font. The program requires simplicity and explicitly select the TrueType font existing in the system (of course, unless the user deliberately deletes them). This approach is as simple as one of the 13 fonts listed in the 13 fonts in Chapter 17 . I called this method to make EZFONT ("Simple Font"), and the program 17-2 lists its two files.

Co-style 17-2 EZFONTEZFONT.H / * ----------------------------------------- ---------------------------------- EZFONT.H Header File --------- -------------------------------------------------- --------------- * /

HFONT EZCREATEFONT (HDC HDC, Tchar * Szfacename, Id Ideciptheight, int IDeciptwidth, I AtTributes, Bool Flogres);

#define ez_attr_bold 1 # define eZ_attr_italic 2 # define eZ_attr_underline 4 # define eZ_attr_strikeout 8EZFONT.C / * -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------------------------- EZFONT.C - - Easy Font Creation (C) Charles Petzold, 1998 --------------------------------------- ------------------------------------- * /

#include #include #include "ezfont.h"

HFONT EzCreateFont (HDC hdc, TCHAR * szFaceName, int iDeciPtHeight, int iDeciPtWidth, int iAttributes, BOOL fLogRes) {FLOAT cxDpi, cyDpi; HFONT hFont; LOGFONT lf; POINT pt; TEXTMETRIC tm; SaveDC (hdc); SetGraphicsMode (hdc, GM_ADVANCED ); ModifyWorldTransform (HDC, NULL, MWT_IDENTITY); SetViewportorgex (HDC, 0, 0, NULL); SetWindoWorgex (HDC, 0, 0, NULL); if (flogres) {cxdpi = (float) getDeviceCaps (HDC, LogPixelsx); cyDpi = (FLOAT) GetDeviceCaps (hdc, LOGPIXELSY);} else {cxDpi = (FLOAT) (25.4 * GetDeviceCaps (hdc, HORZRES) / GetDeviceCaps (hdc, HORZSIZE)); cyDpi = (FLOAT) (25.4 * GetDeviceCaps (hdc, Vertres) / getDeviceCaps (HDC, VERTSIZE));} Pt.x = (int)); pt.y = (int) (IdeCIPTHEIGHT * CYDPI / 72); DPTOLP (HDC, & PT, 1) ; lf.lfheight = - (int) (FABS (Pt.y) / 10.0 0.5); lf.lfwidth = 0; lf.lFescape, = 0; lf.lForientation = 0; lf.lfweight = IATTRIBUTES & EZ_ATTR_BOLD? 700: 0; lf.lfitalic = IATTRIBUTES & EZ_ATTR_ITALIC? 1: 0; lf.lfunderline = IATTRIBUTES & EZ_ATT ? R_UNDERLINE 1: 0; lf.lfStrikeOut = iAttributes & EZ_ATTR_STRIKEOUT 1: 0; lf.lfCharSet = DEFAULT_CHARSET; lf.lfOutPrecision = 0; lf.lfClipPrecision = 0; lf.lfQuality = 0; lf.lfPitchAndFamily = 0; lstrcpy (? lf.lfFaceName, szFaceName); hFont = CreateFontIndirect (& lf); if (iDeciPtWidth = 0) {hFont = (hFONT) SelectObject (hdc, hFont);! GetTextMetrics (hdc, & tm); DeleteObject (SelectObject (hdc, hFont)) ; lf.lfWidth = (int) (TM.X) / FABS (Pt.y) 0.5); HFONT = CREATEFONTINDIRECT (& lf);} restoredc (HDC, -1); Return Hfont; EZFONT.C has only one letter, called EzcreateFont, as shown below:

HFONT = EzcreateFont (HDC, SzFacename, Ideciptheight, IdecipTwidth, IAATTRIBUTES, FLOGRES); The font can be selected into the device content by calling SelectObject, then call GetTextMetrics or GetOutLineTextMetrics to determine the actual size of the font size in the logic. Before the final termination, you should call DeleteObject to delete any created fonts. The SZFACENAME parameter can be any TrueType font name. The closer the font you selected, the greater the chance where the font exists in the system.

The third parameter pointed out the desired point value, but its unit is one tenth point. Therefore, if the desired point value is one or two, the value should be 125.

The fourth parameter is usually set to zero or is the same as the third parameter. However, a wider or narrower TRUETYPE font can be established by setting this field to a different value. It describes the width of the font with a point unit, sometimes called "EM-WIDTH)". Do not confuse it with the average width of the font character or something similar. In the past typography technology, the width and height of uppercase letters M are equal. Thus, the concept of "EM-Square" is produced, which is the origin of full-wide measurement. When the full width of the font is equal to the full height of the font (the point value of the font), the character width is the width set by the font designer. Wide or narrow full width values ​​can produce finer or wider characters.

You can set the IATTRIBUTES parameter to the following definition value in ezfont.h:

EZ_ATTR_BOLDEZ_ATTR_ITALIC EZ_ATTR_UNDERLINEEZ_ATTR_STRIKEOUT You can use EZ_ATTR_BOLD or EZ_ATTR_ITALIC or the style as part of the full TRUETYPE font name.

Finally, we set the parameter flogres to the logical value True to indicate that the font point value is consistent with the "logical resolution" of the device, where "logical resolution" is a return value using the Logpixelsx and LogPixelsy parameters of the GetDeviceCaps. In addition, based on the residential size of the resolution is calculated from Horzres, Horzsize, Vertres, and Vertsize. This is only different for video displays under Windows NT.

The ezcreatefont function starts only some of the adjustments for Windows NT. That is, call SetGraphicsMode and ModifyWorldTransform, which does not work in Windows 98. Because Windows NT's global conversion should have a function of modifying the font visual size, the global conversion setting is set to a preset value before calculating the font size - no conversion.

EzcreateFont basically sets the field of the logfont structure and calls CREATEFONTINDIRECT, CREATEFONTINDIRECT back the code. The main task of the ezcreateFont function is to convert the point value of the font to the logical unit required by the LFHEIGHT field of the LogFont structure. In fact, the point value is first converted to the device unit (the icint), and then converted to a logical unit. To complete the first step, the function is used with getDeviceCaps. The conversion from the icon to logic seems to simply call DPTOLP ("From Device Point to Logical Point"). However, in order to make DPTOLP conversion normally, the same mapping mode must be valid when using the created font display text. This means that the mapping method should be set before the call ezcreatefont function. In most cases, only one mapping method is drawn in a specific area of ​​the window, so this requirement is not a problem.

The EZTEST program shown in the formula 17-3 did not strictly test the EZFONT file. This process uses the above EZTest file, as well as the FONTDEMO file to use after this book. Program 17-3 eztesteztest.c / * ----------------------------------------- --------------------------------- Eztest.c - test of ezfont (c) Charles Petzold, 1998 - -------------------------------------------------- ----------------------- * /

#include #include "ezfont.h"

Tchar szappname [] = text ("eztest"); tchar sztitle [] = text ("eztest: test of ezfont);

Void PainTroutine (HWND HWND, HDC HDC, INT CXAREA, INT CYAREA) {HFONT HFONT; INT Y, IPOINTSIZE; LogFont LF; Tchar Szbuffer [100]; TextMetric TM;

// set logical twips mapping mode

Setmapmode (HDC, MM_anisotropic); SetWindowExtex (HDC, 1440, 1440, NULL); SetViewPortextex (HDC, GetDeviceCaps (HDC, Logpixelsx), GetDeviceCaps (HDC, Logpixelsy), NULL;

// Try Some Fonts

y = 0; for (iPointSize = 80; iPointSize <= 120; iPointSize ) {HFONT = EzcreateFont (HDC, Text ("Times New Roman"), iPointSize, 0, 0, True;

GetObject (HFONT, SIZEOF (Logfont), & lf;

SelectObject (HDC, HFONT); GetTextMetrics (HDC, & TM); Textout (HDC, 0, Y, SZBuffer, WSPrintf (Szbuffer, Text ("Times New Roman Font of% i.% I Points,") Text ("LF. Lfheight =% i, tm.tmheight =% I "), iPointSize / 10, iPointSize% 10, LF.LFHEIGHT, TM.TMHT));

DeleteObject (SelectObject (HDC, getStockObject); y = tm.tmheight;}} fontdemo.c / * ----------------------- -------------------------------------------------- --Fontdemo.c - Font Demonstration Shell Program (c) Charles Petzold, 1998 ---------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------- * /

#include #include "../eztest//ezfont.h"#include" ../eztest//resource.h"extern void PainTroutine (HWND, HDC, INT, INT); LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);

Hinstance hinst;

Extern tchar szappname []; extern tchar sztitle [];

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {TCHAR szResource [] = TEXT ( "FontDemo"); HWND hwnd; MSG msg; WNDCLASS wndclass; hInst = hInstance; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = szResource; wndclass.lpszClassName = szAppName; (! RegisterClass (& wndclass)) if {MessageBox ( "! This program requires Windows NT" NULL, TEXT (), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd); while (GetMessage (& msg, NULL , 0, 0) {TranslateMessage (& MSG); DispatchMessage (& MS g);} return msg.wparam;}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static DOCINFO di = {sizeof (DOCINFO), TEXT ( "Font Demo: Printing")}; static int cxClient, cyClient; static PRINTDLG pd = {sizeof (PRINTDLG)}; Bool Fsuccess; HDC HDC, HDCPRN; INT CXPAGE, CYPAGE; PAINTSTRUCT PS; Switch (Message) {Case WM_COMMAND: Switch (WPARAM) {CASE IDM_PRINT: // Get Printer DC

Pd.hwndowner = hwnd; pd.flags = pd_returndc | PD_NOPAGENUMS | PD_NOSELECTION;

IF (! PrintDLG (& PD)) Return 0;

IF (NULL == (HDCPRN = PD.HDC)) {MessageBox (HWND, Text ("Cannot Obtain Printer DC"), Szappname, MB_ICONEXCLAMATION | MB_OK; RETURN 0;} // Get Size Of Printable Area of ​​Page

CXPAGE = getDeviceCaps (HDCPRN, HORZRES); cypage = getDeviceCaps (HDCPRN, Vertres);

Fsuccess = false;

// do the printer page

SetCursor (LoadCursor (NULL, IDC_WAIT); showcursor (TRUE);

IF (STARTDOC (HDCPRN, & DI)> 0) && (hwnd, hdcprn, cxpage, cypage); if (endpage (hdcprn)> 0) {fsuccess = true; Enddoc HDCPRN);}} deletedc (HDCPRN);

Showcursor (False); SetCursor (LoadCursor (NULL, IDC_ARROW);

IF (! fsuccess) MessageBox (HWnd, Text ("Error Encountered During Printing", Szappname, MB_ICONEXCLAMATION | MB_OK; RETURN 0;

case IDM_ABOUT: MessageBox (hwnd, TEXT ( "Font Demonstration Program / n") TEXT ( "(c) Charles Petzold, 1998"), szAppName, MB_ICONINFORMATION | MB_OK); return 0;} break; case WM_SIZE: cxClient = LOWORD ( lParam); cyClient = HIWORD (lParam); return 0; case WM_PAINT: hdc = BeginPaint (hwnd, & ps); PaintRoutine (hwnd, hdc, cxClient, cyClient); EndPaint (hwnd, & ps); return 0; case WM_DESTROY: PostQuitMessage (0); Return 0; Return DefWindowProc (HWND, Message, WParam, LPARAM);} fontdemo.rc // Microsoft Developer Studio generated resource script. # Include "resource.h" #include "afxres.h" /// MenuFONTDEMO MENU DISCARDABLE BEGINPOPUP "& File" BEGINMENUITEM "& Print ...", IDM_PRINTENDPOPUP "& Help" BEGINMENUITEM "& About ...", IDM_ABOUTENDENDRESOURCE.H // Microsoft Developer Studio generated include file.// Used by FontDemo.rc

#define IDM_Print 40001 # Define IDM_ABOUT 40002EzTest.c PainTroutine in the PainTroutine in the mapping mode to Logical TWIPS, then build the Times New Roman font from 8:00 to 12 (interval 0.1). When this program is performed for the first time, its output may make you confused. Many lines of lines use a font using a size, and the TextMetric function also reports these fonts with the same height. All this is the result of the dottion processing. The icon on the display is discontinuous, it cannot display each possible font size. However, the FontDemo shell program is different from the font of the print output. Here you will find that the font size is more accurate.

Font rotation

You may have experimented in PickFont, and the LogFont structure of the LogFont structure can rotate the TrueType text. If you carefully think about it, this will not cause more difficulties, because the formula surrounding the original rotating seat is open.

Although EzcreateFont cannot specify the rotation angle of the font, it is very easy to adjust when the Fontrot is displayed. The program 17-4 shows the Fontrot.c file, which also requires the EZFont file and FONTDEMO file displayed above.

Program 17-4 fontrotfontrot.c / * ----------------------------------------- ---------------------------------- Fontrot.c - Rotated Fonts (c) Charles Petzold, 1998- -------------------------------------------------- -------------------------- * / # include #include "../eztest/ezfont.h"tchar Szappname [] = text ("fontrot"); tchar sztitle [] = text ("fontrot: Rotated Fonts);

Void PainTroutine (hwnd hwnd, hdc hdc, int cxarea, int customa) {static tchar szstring [] = text ("rotation"); hfont hfont; int i; logfont lf;

HFONT = EzcreateFont (HDC, Text ("Times New Roman"), 540, 0, 0, True; GetObject (HFont, SizeOf (Logfont), & lf); deleteObject (HFONT);

SetBKMode (HDC, Transparent); SetTextAlign (HDC, TA_BASELINE); SetViewportorgex (HDC, Cxarea / 2, Cyarea / 2, NULL);

For (i = 0; i <12; i ) {lf.lfescapeent = lf.lForientation = i * 300; SelectObject (HDC, CreateFontIndirect (& lf));

Textout (HDC, 0, 0, Szstring, Lstrlen (Szstring)); deleteObject (SelectObject (hdc, getstockObject);}}}}}} fontrot call ezcreateFont is just a LogFont structure associated with 54 Times New Roman font. Then, the font is deleted. In the Forward circle, for every 30 degrees, the new font is created and the text is displayed. The results are shown in Figure 17-2.

Figure 17-2 Screen of Fontrot

If you are interested in graphics rotation and other linear conversions, and you know that your program will be restricted in Windows NT, you can use the XForm matrix and the number of symbols.

Font enumeration

The font enumeration is a program that acquires all the valid font lists of the device from the GDI. Program can be selected or displayed in the dialogue selection. I will briefly introduce the following list, then display the method of using the Choosefont function, Choosefont reduces the necessity of the font enumeration in the application.

Formula

In the early days of Windows, the font enumeration needs to use the enumfonts function:

Enumfonts (HDC, PDATA); programs can list all fonts (set the second parameter null) or only list specific words. The third parameter is to list the Callback function; the fourth parameter is the optional information passed to the function. GDI calls a callback in the system, which will pass the LogFont and TextMetric structure of the definition font and some flag indicating the font type to it. EnumfontFamilies Functures are a Volumes of TrueType fonts under Windows 3.1:

EnumfontFamilies (HDC, SZFACENAME, ENUMPROC, PDATA); When ENUMFONTFAMIL is usually called, the second parameter is set to NULL. Call an EnumProccallback function for each word system (for example, Times New Roman). Then, the application uses the font name and different Callback functions to call EnumFontFamilies again. GDI is called the second Callback library for each font (such as Times New Roman Italic) in the word system. For non-TrueType fonts, pass the EnumlogFont structure to the Callback function (it is composed of "full name" field and "full name" field, "type" field, "Italic" or " Bold ") and TextMetriC structure, pass the NewTextMetriC structure for the TrueType font. The NewTextMetric structure adds four fields to the information in the TextMetric structure.

EnumfontFamiliesex is recommended for use in Windows 32-bit versions:

EnumfontFamiliex (HDC, & logfont, enumproc, pdata, dwflags); the second parameter is an indicator of the LogFont structure, where the LFCharset and the LFFCENAME field indicate the font information to be listed. The Callback function is available in the Enumlogfontex and NewTextMetricEx structures.

"Choosefont" dialogue

In the eleventh chapter, the general dialogue of choosefont is slightly introduced. Now, we discuss the font enumeration, you need to learn more about the internal working principle of the Choosefont function. The Choosefont is getting a representation of the Choosefont structure to be used as its unique parameters and displays a dialog that lists all fonts. Using the return value from Choosefont, the LogFont structure (part of the choosefont structure) can establish a logical font.

The CHOSFONT shown in the program 17-5 shows the method of using the Choosefont function and shows the field of the LogFont structure defined by the letter. The program also shows the same string displayed in the PICKFont.

Co-style 17-5 ChosFontChosFont.c / * ----------------------------------------- ------------------------------------ CHOSFONT.C - Choosefont Demo (C) Charles Petzold, 1998 -------------------------------------------------- --------------------------- * /

#include #include "resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "ChosFont"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; if (RegisterClass (& wndclass)!) {MessageBox (NULL, TEXT ( "This program requires Windows ! NT "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT (" ChooseFont "), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, ICMDSHOW); UpdateWindow (HWND); While (GetMessage (& MSG, NULL, 0 , 0) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wparam;}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static CHOOSEFONT cf; static int cyChar; static LOGFONT if; static TCHAR szText [] = TEXT ( "/ x41 / x42 / x43 / x44 / x45") Text ("/ x61 / x62 / x63 / x64 / x65") Text ("/ xc0 / xc1 / xc2 / xc3 / xc4 / xc5") TEXT ("/ XE0 / XE1 / XE2 / XE3 / XE4 / XE5") # IFDEF UnicodeText ("/ X0390 / X0391 / X0392 / X0393 / X0394 / X0395") Text ("/ x03b0 / x03b1 / x03b2 / x03b3 / x03b4 / x03b5") Text ("/ x0410 / x0411 / x0412 / x0413 / x0414 / x0415 ") TEXT (" / x0430 / x0434 / x0432 / x0433 / x0434 / x0435 ") TEXT (" / x5000 / x5004 ") #ENDIF; HDC HDC; Int Y; PaintStruct PS; Tchar Szbuffer [64 ]; TEXTMETRIC tm; switch (message) {case WM_CREATE: // Get text heightcyChar = HIWORD (GetDialogBaseUnits ()); // Initialize the LOGFONT structureGetObject (GetStockObject (SYSTEM_FONT), sizeof (lf), & lf); // Initialize the CHOOSEFONT structurecf.lStructSize = sizeof (CHOOSEFONT); cf.hwndOwner = hwnd; cf.hDC = NULL; cf.lpLogFont = & lf; cf.iPointSize = 0; cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_E Ffects; cf.rgbcolors = 0; cf.lcustdata = 0; cf.lpfnhook = null; cf.lpTemplatename = null; cf.hinstance = null; cf.lpszstyle = null; cf.nfonttype = 0; cf.nsizemin = 0; Cf.nsizemax = 0; Return 0; Case WM_COMMAND: Switch (WPARAM)) {CASE IDM_FONT: IF (Choosefont (& CF)) InvalidateRect (hwnd, null, true); return 0;} return 0;

Case WM_Paint: HDC = BeginPaint (HWND, & PS);

// Display sample text Using SELECTED FONT

SelectObject (hdc, CreateFontIndirect (& lf)); GetTextMetrics (hdc, & tm); SetTextColor (hdc, cf.rgbColors); TextOut (hdc, 0, y = tm.tmExternalLeading, szText, lstrlen (szText)); // Display LOGFONT Structure Fields Using System Font

DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))); SetTextColor (hdc, 0); TextOut (hdc, 0, y = tm.tmHeight, szBuffer, wsprintf (szBuffer, TEXT ( "lfHeight =% i"), lf .lfheight));

Textout (HDC, 0, Y = cychar, szbuffer, wsprintf (szbuffer, text ("lfwidth =% i"), lf.lfwidth); Textout (HDC, 0, Y = cychar, szbuffer, WSPrintf (Szbuffer, Text ("LFESCAPEMENT =% I"), LF.LFESCAPEMENT); Textout (HDC, 0, Y = cychar, szbuffer, wsprintf (szbuffer, text ("LirtIntation =% I"), LF.LForientation);

Textout (HDC, 0, Y = cychar, szbuffer, wsprintf (szbuffer, text ("lfweight =% i"), lf.lfweight);

Textout (HDC, 0, Y = cychar, szbuffer, wsprintf (szbuffer, text ("lfertalic =% i"), lf.lfitalic);

Textout (HDC, 0, Y = cychar, szbuffer, wsprintf (szbuffer, text ("lfunderline =% i"), lf.lfunderline));

Textout (HDC, 0, Y = cychar, szbuffer, wsprintf (szbuffer, text ("lfstrikeout =% i"), lf.lfstrikeout);

Textout (HDC, 0, Y = cychar, szbuffer, wsprintf (szbuffer, text ("lfcharset =% i"), lf.lfcharset);

Textout (HDC, 0, Y = cychar, szbuffer, wsprintf (szbuffer, text ("lfoutprecision =% i"), lf.lfoutPrecision);

Textout (HDC, 0, Y = cychar, szbuffer, wsprintf (szbuffer, text ("LFClipPrecision =% I"), LF.LFCLIPPRecision);

Textout (HDC, 0, Y = cychar, szbuffer, wsprintf (szbuffer, text ("lfquality =% i"), lf.lfquality); Textout (HDC, 0, Y = cychar, szbuffer, WSPrintf (Szbuffer, Text ("LFPITCHANDFAMILY = 0x% 02x"), LF.LFPITCHANDFAMILY);

Textout (HDC, 0, Y = cychar, szbuffer, wsprintf (szbuffer, text ("lfffactename =% s"), lf.lffacename);

EndPaint (hwnd, & ps); return 0; case WM_DESTROY:. PostQuitMessage (0); return 0;} return DefWindowProc (hwnd, message, wParam, lParam);} CHOSFONT.RC // Microsoft Developer Studio generated resource script # include " Resource.h "#include" afxres.h "

////////////////////Wwm_fontendresource.h // Microsoft Developer Studio generated include file./ used by chosfont.rc

#DEfine IDM_Font 40001 Like a general dialog, the CHOSEFont structure of the FLAGS fields lists many options. Chosfont specified CF_INITLOGFONTSTRUCT flags make Windows to initialize the selection of the dialogue according to the LogFont structure passed to the Choosefont structure. You can use the flag to specify as long as the TrueType font (CF_TTONLY) is listed or as long as the fixed wide font (cf_fixedpitchly) or unsigned font (CF_Scriptsonly). It is also possible to display the screen font (CF_Screenfonts), the print font (CF_PrinterFonts), or both (CF_BOTH). In the latter two cases, the HDC field of the Choosefont structure must be the content of the printing machine. Chosfont program uses the CF_SCREENFONTS flag.

The CF_EFFECTS flag (the third flag used by the CHOSFONT) The forced dialogue includes a verification block for the bottom line and the delete line and allows you to select the color of the text. It is not difficult to transform the text in the program code, you can try it.

Note that the "Script" field displayed by Choosefont in the "Font" dialog box. It allows the user to choose a character set for special fonts, and the appropriate font set ID is back in the logfont structure.

The ChooseFont function calculates the LFHEIGHT field using logical inch from point values. For example, assuming that you have "small fonts" from the "Show Properties" dialog box. This means that getDeviceCaps and parameter logpixelsyssy transmitted back 96 with the content of the video display device. If you use Choosefont to select a 72-point Times Roman font, it is actually a font that you want to have a 1 inches. When choosefont is back, the LFHEIGHT field of the LogFont structure is equal to -96 (pay attention to the negative), which means the point value of the font is equal to 96 primitives, or 1 logic inch.

The above is probably what we want to know. However, remember the following: If a metric mapping method is set under Windows NT, the logical coordinates are inconsistent with the actual size of the font. For example, if you paint a ruler by writing a text based on the metrics map, it will find that it does not match the font. The graphic should be drawn using the Logical TWIPS mapping method described above to consistent with the font size. If you want to use any non-MM_TEXT mapping, make sure that the mapping method is not set when the font is selected in the device content and display text. Otherwise, GDI will think that the LFHEIGHT field of the logfont structure is a logic host. The LFHEIGHT field of the LogFont structure set by Choosefont is always a primitive, and it is only available for the video display. When you build a font for the contents of the printer device, you must adjust the LFHEIGHT value. The HDC field using the Choosefont function is only for the printing machine fonts listed in the dialogue. This device content code does not affect the LFHEIGHT value. Fortunately, the Choosefont structure includes an iPointSize field that provides the size of the selected fonts in very a very minute. No matter what device content and mapping method, this field can be converted to a logic size and used for the LFHEIGHT field. You can find a suitable program code in ezfont.c, you can simplify it as needed.

Another program using choosefont is Unichars, which allows you to view all the fonts of a font, which is especially useful for studying the Lucida Sans Unicode fonts (demonstration display fonts) or BitStream Cyberbit. Unichars always uses the Textoutw function to display the font of the font, so you can execute it in Windows NT or Windows 98.

Cheng 17-6 unicharsunichars.c / * ----------------------------------------- --------------------------------- Unichars.c - Displays 16-bit Character Codes (c) Charles Petzold 1998 ------------------------------------------------ ----------------------------- * /

#include #include "resource.h"

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "UniChars"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName; if (RegisterClass (& wndclass)!) {MessageBox (NULL, TEXT ( "This program requies Windows ! NT "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT (" Unicode Characters "), WS_OVERLAPPEDWINDOW | WS_VSCROLL, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, icmdshow); UpdateWindow (hwnd); while (getm Essage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wparam;}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static CHOOSEFONT cf; static int iPage; static LOGFONT lf; HDC hdc; int cxChar, cyChar, x, y, i, cxLabels; PAINTSTRUCT ps; SIZE size TCHAR SZBUFFER [8]; TextMetric TM; Wchar CH;

Switch (Message) {case wm_create: hdc = getdc (hwnd); lf.lfheight = - getDevicecaps (hdc, logpixelsy) / 6; // 12 PointslstrcPy (Lucida Sans Unicode "); ReleaseDC ( HWND, HDC);

cf.lStructSize = sizeof (CHOOSEFONT); cf.hwndOwner = hwnd; cf.lpLogFont = & lf; cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS; SetScrollRange (hwnd, SB_VERT, 0, 255, FALSE); SetScrollPos (hwnd, SB_VERT, iPage, True); Return 0;

case WM_COMMAND: switch (LOWORD (wParam)) {case IDM_FONT: if (ChooseFont (& cf)) InvalidateRect (hwnd, NULL, TRUE); return 0;} return 0; case WM_VSCROLL: switch (LOWORD (wParam)) {case SB_LINEUP : iPage - = 1; break; case SB_LINEDOWN: iPage = 1; break; case SB_PAGEUP: iPage - = 16; break; case SB_PAGEDOWN: iPage = 16; break; case SB_THUMBPOSITION: iPage = HIWORD (wParam); break;

DEFAULT: RETURN 0;

ipage = max (0, min (iPage, 255));

Setscrollpos (HWND, SB_VERT, IPAGE, TRUE); InvalidateERECT (HWND, NULL, TRUE); RETURN 0;

Case WM_Paint: HDC = BeginPaint (HWND, & PS);

SelectObject (HDC, CREATEFONTINDIRECT (& LF));

GetTextMetrics (HDC, & TM); cxchar = tm.tmmaxcharwidth; cychar = tm.tmheight tm.tmexternalleading;

Cxlabels = 0;

For (i = 0; I <16; i ) {WSPrintf (Szbuffer, Text ("000% 1x:"), I); GetTextExtentPoint (HDC, SZBuffer, 7, & size);

Cxlabels = max (cxlabels, size.cx);

For (y = 0; y <16; y ) {wsprintf (szbuffer, text ("% 03x_:"), 16 * ipage y); TextOut (HDC, 0, Y * cychar, szbuffer, 7);

For (x = 0; x <16; x ) {ch = (wchar) (256 * ipage 16 * y x); TextOutw (HDC, X * CxChar CXLabels, Y * cychar, & ch, 1);} }

DeleteObject (SELECTOBJECT (HDC, getStockObject); EndPaint (HWND, & PS); Return 0;

case WM_DESTROY:. PostQuitMessage (0); return 0;} return DefWindowProc (hwnd, message, wParam, lParam);} UNICHARS.RC // Microsoft Developer Studio generated resource script # include "resource.h" #include "afxres.h "/// Menuunichars Menu Discardable BeginMenuItem" & Font! ", IDM_FontendResource.h // Microsoft Developer Studio generated include file.// used by unichars.rc

#define IDM_FONT 40001 Paragraph Format

After having the ability to select and establish logic fonts, you can handle text formats. This program includes one of the four ways to lay each line in the page: left alignment, alignment to the right, center or dispersion alignment - that is, one end from the margin to the other, the text spacing is equal. For the first three ways, you can use a DRAWTEXT function with the DT_WordBreak parameter, but this method has limitations. For example, you cannot determine which portion of the text will exactly in the rectangle. DrawText is very convenient for some simple tasks, but for more complex formatting tasks, you may use Textout.

Simple text format

The most useful one of the text is GetTextExtentPoint32 (this version of this function displays some changes in the early version of the Windows). The function derives the width and height of the string according to the current font selected in the device content:

GetTextExtentPoint32 (HDC, PString, ICOUNT, & SIZE); The text width and height of the logical unit are back in the CX and CY fields of the Size structure. I use an example of a line of text, assume you selecting a font to select the device content, now you want to write text:

Tchar * sztext [] = text ("Hello, How Are you?"); You want the text to start from the vertical coordinate YStart, the page distance is set by the coordinate XLEFT and XRIGHT. Your task is to calculate the XStart value of the horizontal seat starting at the beginning of the text.

If the text is displayed in a wide font, then this task is quite easy, but it is usually not the case. First you get the text width of the string:

GetTextExtentPoint32 (HDC, Sztext, Lstrlen (Sztext), & size); if size.cx is big, this line is too long, and cannot be placed within the margin. We assume that it can put it.

To align the text to the left, just set the XStart to equally equally, then write into text:

Textout (HDC, XStart, Ystart, Sztext, Lstrlen (sztext); this is easy. Now you can add Size.cy to YSTART to write a line of words.

To align the words to the right, calculate xstart with the following formula:

XStart = Xright - size.cx; 中文 字 Use the following formula:

XStart = (xleft xright - size.cx) / 2; now started a difficult task - disperse the alignment in the left and right pages. The distance between the margins is (XRight-Xleft). If not adjusted, the text width is Size.cx. Both differences

XRight - Xleft - size.cx must be averaged at the three space character of the string. This sounds hate, but it is not too bad. You can call SetTextJustification (HDC, XRight - Xleft - size.cx, 3). The second parameter is the amount of space that needs to be allocated in the string internal space character. The third parameter is the number of space character, here is 3. Now put the XStart settings with XLEFT, write text with Textout:

Textout (HDC, XStart, Ystart, Sztext, Lstrlen (sztext)); text will be aligned between XLEFT and XRight margins.

Whenever a call setTextJustification, if the amount of space cannot be allocated in the space character, it will accumulate an error value. This will affect the rear of the getTextExtentPoint32 call. Every time you start a new line, you must pass the call.

SetTextJustification (HDC, 0, 0); to clear the error value.

Use paragraph

If you have processed the entire paragraph, you must start from the beginning and scan the string to look for a spacemaker. Whenever you touch a space (or other fifth that can be used to disconnect a row), you need to call GetTextExtentPoint32 to determine if the text can be placed between the left and right margins. When the text exceeds the allowed space, it is necessary to return a blank. Now you have been able to determine the string of a row. If you want to disperse the row, call setTextJustification and TextOut, clear the error value, and continue the next line.

The first paragraph of the "The Adventures Of Huckleberry Finn" in Mark Twain is shown in Justify11. You can select the desired font from the dialogue, or you can use the function table option to change the alignment mode (left alignment, align, mediate or disperse). Figure 17-3 is a typical Justify1 screen display.

Program 17-7 Justify1Justify1.c / * ----------------------------------------- -------------------------------- Justify1.c - Justified Type Program # 1 (c) Charles Petzold, 1998 -------------------------------------------------- ------------------------- * /

#include #include "resource.h"

LResult Callback WndProc (HWND, UINT, WPARAM, LPARAM); Tchar Szappname [] = Text ("Justify1");

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass. lpszClassName = szAppName; if {MessageBox (NULL, TEXT ( "This program requires Windows NT!"), szAppName, MB_ICONERROR); return 0;} (RegisterClass (& wndclass)!) hwnd = CreateWindow (szAppName, TEXT ( "Justified Type # 1 "), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd); while (GetMessage (& msg, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wpaham;}

Void Drawruler (HDC HDC, Rect * PRC) {Static IRulesize [16] = {360, 72, 144, 72, 216, 72, 144, 72, 288, 72, 144, 72, 216, 72, 144, 72}; INT I, J; Point PTClient; Savedc (HDC) ; // Set Logical Twips mapping modeSetMapMode (hdc, MM_ANISOTROPIC); SetWindowExtEx (hdc, 1440, 1440, NULL); SetViewportExtEx (hdc, GetDeviceCaps (hdc, LOGPIXELSX), GetDeviceCaps (hdc, LOGPIXELSY), NULL); // Move the Origin to a Half Inch from Upper LeftSetWindoWorgeX (HDC, -720, -720, NULL); // Find the right margin (quarter incrom Right) PTClient.x = prc-> Right; ptclient.y = prc-> bottom DPTOLP (HDC, & PTClient, 1); PTClient.x - = 360; // Draw The Rulesmovetoex (HDC, 0, -360, NULL); LINETO (HDC, PTClient.x, -360); MoveToex (HDC, -360 , 0, NULL; LINETO (HDC, -360, Ptclient.y); for (i = 0, j = 0; i <= ptclient.x; i = 1440/16, j ) {MoveToex (HDC, I , -360, null; lineto (HDC, I, -360 - Irulesize [j% 16]);} for (i = 0, j = 0; i <= ptclient.y; i = 1440/16, j ) {MoveToex (HDC, -360, I, NULL); LINETO (HDC, -360 - i Rulesize [J% 16], I);} Restoredc (HDC, -1);} Void Justify (HDC HDC, PTSTR PTEXT, RECT * PRC, IALIGN) {INT XStart, YSPACHARS; PTSTR PBEGIN, PEND; SIZE Size; ystart = prc-> top; do // for each text line {cspacechars = 0; // INITIALIZE NUMBER OF SPACES in linewhile (* ptext == ') // Skip over Leading spacsptext ;

Pbegin = PText; // set pointer to char at beginning of linedo // untric the line is known {pend = ptext; // set pointer to char at End of line

// Skip to next space While (* ptext! = '/ 0' && * ptext ! = ');

IF (* ptext == '/ 0') Break; // after each space Encountered, Calculate Extents

CSPacechars ; GettextExtentPoint32 (HDC, Pbegin, PTEXT - PBEGIN - 1, & size);} while (size.cx <(prc-> right - prc-> left); cspacechars ---; // discount last space at End of LineWhile (* (PEND - 1) == ') // Eliminate Trailing Spaces {Pend-; cspacechars--;

// if end of text and no space character character, set pend to endif (* ptext == '/ 0' || cspacechars <= 0) pend = ptext;

GetTextExtentPoint32 (hdc, pBegin, pEnd - pBegin, & size); switch (iAlign) // use alignment for xStart {case IDM_ALIGN_LEFT: xStart = prc-> left; break; case IDM_ALIGN_RIGHT: xStart = prc-> right - size.cx; Break; case IDM_ALIGN_CENTER: XStart = (Prc-> Right Prc-> Left - size.cx) / 2; Break; Case IDM_Align_Justified: IF (* Ptext! = '/ 0' && Cspacechars> 0) SetTextJustification (HDC, PRC -> Right-Prc-> Left - size.cx, cspacechars; xstart = prc-> left; break;} // display the texttextout (HDC, XStart, Ystart, Pbegin, Pend - Pbegin);

// prepare for next line

SetTextJustification (HDC, 0, 0); YSTART = Size.cy; PText = Pend;} While (* Ptext && Ystart bottom - size.cy);}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static CHOOSEFONT cf; static DOCINFO di = {sizeof (DOCINFO), TEXT ( "Justify1: Printing")}; static int iAlign = IDM_ALIGN_LEFT; static LOGFONT lf static printdlg pd; static tchar sztext [] = {text ("You Don't Know About Me, without you") Text ("Have Read A Book by the name of /" the ") Text (" Adventures of Tom Sawyer , / "but that") text ("" "" "" ") Text (" MR. Mark Twain, And He Told The Truth, ") Text (" Mainly. There Was Things Which He " Text ("STRETCHED, But Mainly He Told The TEXT (" That is nothing. I Never seen anybody ") Text (" But Lied, One Time or Another, WITHOUT ") Text (" IT WAS Aunt Polly, Or the widow, or ") Text (" Maybe Mary. Aunt Polly - Tom's Aunt ") Text (" Polly, She Is - and Mary, and The Widow) Text ("Douglas, Is All Told About in That Book ") Text (" - WHICH IS MOSTLY a TRUE BOOK; ") Text (" Some Stretcher, As I SaiD BEFORE. ")}; Bool Fsuccess; HDC hdc, hdcPrn; HMENU hMenu; int iSavePointSize; PAINTSTRUCT ps; RECT rect; switch (message) {case WM_CREATE: // Initialize the CHOOSEFONT structureGetObject (GetStockObject (SYSTEM_FONT), sizeof (lf), & lf);

cf.lStructSize = sizeof (CHOOSEFONT); cf.hwndOwner = hwnd; cf.hDC = NULL; cf.lpLogFont = & lf; cf.iPointSize = 0; cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_EFFECTS; cf.rgbColors = 0; cf .lcustdata = 0; cf.lpfnhook = null; cf.lptemplatename = null; cf.hinstance = null; cf.lpszstyle = null; cf.nfonttype = 0; cf.nsizemin = 0; cf.nsizemax = 0; Return 0; Case WM_COMMAND: HMENU = GetMenu (hwnd); switch (wparam) {copy idm_file_print: // Get Printer DC

Pd.lstructSize = sizeof (PrintDLG); pd.hwndowner = hwnd; pd.flags = pd_returndc | PD_nopagenums | PD_NOSELECTION;

IF (! PrintDLG (& PD)) Return 0;

IF (NULL == (HDCPRN = PD.HDC)) {MessageBox (HWND, Text ("Cannot Obtain Printer DC"), SZAPPNAME, MB_ICONEXCLAMATION | MB_OK; RETURN 0;} // set margins of 1 inch

Rect.Left = getDeviceCaps (HDCPRN, Logpixelsx) -getDeviceCaps (HDCPRN, PhysicalOffsetx);

rect.top = GetDeviceCaps (hdcPrn, LOGPIXELSY) GetDeviceCaps (hdcPrn, PHYSICALOFFSETY); rect.right = GetDeviceCaps (hdcPrn, PHYSICALWIDTH) -GetDeviceCaps (hdcPrn, LOGPIXELSX) -GetDeviceCaps (hdcPrn, PHYSICALOFFSETX); rect.bottom = GetDeviceCaps (hdcPrn, PHYSICALHEIGHT - GetDeviceCaps (HDCPRN, Logpixelsy) -GetDeviceCaps (HDCPRN, PhysicalOffSetys);

// Display Text on Printer

SetCursor (LoadCursor (NULL, IDC_WAIT); showcursor (TRUE);

Fsuccess = false; if (StartDoc (HDCPRN, & DI)> 0) && (STARTPAGE (HDCPRN)> 0)) {// select font using adjusted Lfheight

IsavePointSize = lf.lfheight; lf.lfheight = - (GetDeviceCaps (HDCPRN, Logpixelsy) * cf.ipointsize / 720;

SelectObject (HDCPRN, CreateFontIndirect (& lf)); lf.lfheight = isavepointsize; // set text color setTextColor (HDCPRN, CF.RGBCOLORS); // Display Text

Justify (HDCPRN, Sztext, & Rect, IAlign);

IF (EndPage (HDCPRN)> 0) {fsuccess = true; enddoc (hdcprn);}} showcursor (false); setcursor (loadcursor (null, idc_arrow);

Deletedc (HDCPRN);

IF (! fsuccess) MessageBox ("Could Not Print Text", Szappname, MB_ICONEXCLAMATION | MB_OK; RETURN 0;

case IDM_FONT: if (ChooseFont (& cf)) InvalidateRect (hwnd, NULL, TRUE); return 0; case IDM_ALIGN_LEFT: case IDM_ALIGN_RIGHT: case IDM_ALIGN_CENTER: case IDM_ALIGN_JUSTIFIED: CheckMenuItem (hMenu, iAlign, MF_UNCHECKED); iAlign = LOWORD (wParam); Checkmenuitem (HMENU, IALIGN, MF_CHECKED); InvalIdateRect (hwnd, null, true); return 0;} return 0;

case WM_PAINT: hdc = BeginPaint (hwnd, & ps); GetClientRect (hwnd, & rect); DrawRuler (hdc, & rect); rect.left = GetDeviceCaps (hdc, LOGPIXELSX) / 2; rect.top = GetDeviceCaps (hdc, LOGPIXELSY ) / 2; Rect.right - = getDeviceCaps (HDC, Logpixelsx) / 4;

SelectObject (hdc, CreateFontIndirect (& lf)); SetTextColor (hdc, cf.rgbColors); Justify (hdc, szText, & rect, iAlign); DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))); EndPaint (hwnd, & ps); return 0; case WM_DESTROY:. PostQuitMessage (0); return 0;} return DefWindowProc (hwnd, message, wParam, lParam);} JUSTIFY1.RC // Microsoft Developer Studio generated resource script # include "resource.h" #include " AfXRES.H "

/// MenuJUSTIFY1 MENU DISCARDABLE BEGIN POPUP "& File" BEGINMENUITEM "& Print", IDM_FILE_PRINTENDPOPUP "& Font" BEGINMENUITEM "& Font ...", IDM_FONTENDPOPUP "& Align" BEGINMENUITEM "& Left", IDM_ALIGN_LEFT, CHECKEDMENUITEM "& Right", IDM_ALIGN_RIGHTMENUITEM "& Centered", IDM_ALIGN_CENTERMENUITEM "& Justified", IDM_ALIGN_JUSTIFIEDENDENDRESOURCE.H // Microsoft Developer Studio generated include file.// Used by Justify1.rc # define IDM_FILE_PRINT 40001 # define IDM_FONT 40002 # define IDM_ALIGN_LEFT 40003 # define IDM_ALIGN_RIGHT 40004 # define IDM_ALIGN_CENTER 40005 # define IDM_ALIGN_JUSTIFIED 40006JUSTIFY1 in the display area The upper and left sides showed a ruler (of course, the unit is logical inch). The ruler is drawn from the Drawruler. A rectangular structure defines the area that is dispersed to the word.

A large amount of work involving formatting in writing is implemented by the Justify letter. A blank started by the letter and use GetTextExtentPoint32 to measure each line. When the length of the line exceeds the width of the display area, Justify1 is transmitted back to the previous space and reaches the line to the Linefeed. According to the value of the IALIGN constant, the alignment of the line is: Aligned to the right, align, center or disperse alignment.

JustiFy1 is not perfect. For example, it does not have a problem of dealing with the link. In addition, when each line is less than two words, the way to be aligned will invalid. Even if we solve this problem, it is not a particularly difficult problem. When a single word is too long, the program does not work properly when it is in the left and right edges. Of course, when we use a variety of fonts (like the Windows documents to be easily made in the program), the situation will be more complicated. No one has claimed that this process is easy, it is just more than we work more than we personally.

Figure 17-3 Typical Justify1 screen display

Print output preview

Some fonts are not for use on the screen, these fonts are used for printing. Usually in this case, the screen's screen preview must be precisely fitted with the format of the print output. It is not enough to show the same font, size and character format. It is a shortcut to use TrueType. Also need to disconnect each of the paragraphs in the same position. This is the difficult point in Wysiwyg.

Justify1 contains a "Print" option, but this option is only set on the page, left, and right side. In this way, formatting is completely independent of the screen display. Here is an interesting practice: Change a few stroke code in Justify1, so that the screens and printers logic are logically rectangular in accordance with a 6-inch format. The method is to change the definition of Rect.right in the WM_Paint and "Print" command processing. In the WM_PAINT process, the corresponding description is:

Rect.right = Rect.Left 6 * getDeviceCaps (HDC, Logpixelsx); in the "Print" command processing program, the corresponding description is:

Rect.right = Rect.LEFT 6 * getDeviceCaps (HDCPRN, Logpixelsx); if a TrueType font is selected, the Linefeed situation on the screen should be the same as the printing machine. But the actual situation is not the case. Even if the two devices use the same fonts with the same point value, different display resolutions and match errors will appear in different places in different displays in the same formatted rectangle. Obviously, there is a need for a more highly method of making a printout preview on the screen.

Justify2 demonstrates this method of this approach to the JUSTIFY2 shown. The program code in Justify2 is based on the TTJUST ("TrueType Justify") written by Microsoft, and the program is based on the Justify1 program in front of this book. In order to show the complexity added in this program, the first chapter in "moby-dick" in Herman Melville replaces the number of Mark TWAIN novels.

Program 17-8 Justify2justify2.c / * ----------------------------------------- ------------------------------------ Justify2.c - Justified Type Program # 2 (c) Charles Petzold, 1998 --------------------------------- ------------------------------ * /

#include #include "resource.h"

#define outwidth 6 // width of formatted Output in inches # define lastchar 127 // Last Character Code Used in Text

LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM); TCHAR szAppName [] = TEXT ( "Justify2"); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {HWND hwnd; MSG msg; WNDCLASS wndclass ; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor ( NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = szAppName; wndclass.lpszClassName = szAppName;! if (RegisterClass (& wndclass)) {MessageBox (NULL, TEXT ( "This program requires Windows NT ! "), szAppName, MB_ICONERROR); return 0;} hwnd = CreateWindow (szAppName, TEXT (" Justified Type # 2 "), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow ( HWND, ICMDSHOW; UpdateWindow (hwnd); while (GetMessage (& MSG, NULL, 0, 0) {TranslateMessage (& MSG); DispatchMessage (& MSG);} return msg.wparam;}

Void Drawruler (HDC HDC, Rect * PRC) {Static IRulesize [16] = {360, 72, 144, 72, 216, 72, 144, 72, 288, 72, 144, 72, 216, 72, 144, 72}; INT I, J; Point Ptclient; SaveDC (HDC) ; // Set Logical Twips mapping modeSetMapMode (hdc, MM_ANISOTROPIC); SetWindowExtEx (hdc, 1440, 1440, NULL); SetViewportExtEx (hdc, GetDeviceCaps (hdc, LOGPIXELSX), GetDeviceCaps (hdc, LOGPIXELSY), NULL); // Move the Origin to a Half Inch from Upper LeftSetWindoWorgeX (HDC, -720, -720, NULL); // Find the right margin (quarter incrom Right) PTClient.x = prc-> Right; ptclient.y = prc-> bottom DPTOLP (HDC, & PTClient, 1); PTClient.x - = 360; // Draw The Rulersmovetoex (HDC, 0, -36 0, NULL); LINETO (HDC, Outwidth * 1440, -36 0); MoveToex (HDC, -360, 0, null; LineTo (HDC, -360, PTClient.y); for (i = 0, j = 0; i <= ptclient.x && i <= Outwidth * 1440; i = 1440/16 , J ) {MoveToex (HDC, I, -360, NULL); LINETO (HDC, I, -360 - Irulesize [J% 16]);} for (i = 0, j = 0; i <= ptclient.y ; i = 1440/16, J ) {MoveToex (HDC, -360, I, NU LL); LINETO (HDC, -360 - Irulesize [J% 16], I);} Restoredc (HDC, -1);} / * ------------------ -------------------------------------------------- ------- GetCharDesignWidths: Gets Character Widths for Font As Large As Theoriginal Design Size -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------------------------------------------- * /

UINT GETCHARDESIGNWIDTHS (HDC HDC, UINT UFIRST, UINT ULAST, INT * PIWIDTHS) {HFONT HFONT, HFONTDESIGN; LOGFONT LF; OUTLINETEXTMETRIC OTM

HFONT = GetCurrentObject (HDC, Obj_Font); GetObject (HFont, SizeOf (Logfont), & lf);

// Get outline text metrics (we'll only be using a field that is // independent of the DC the font is selected into) otm.otmSize = sizeof (OUTLINETEXTMETRIC); GetOutlineTextMetrics (hdc, sizeof (OUTLINETEXTMETRIC), & otm);

// Create a new font based on the design sizelf.lfheight = - (int) otm.otmemsquare; lf.lfwidth = 0; hfontdesign = createfontIndirect (& lf);

// select the font 通 t DC and get the character widths

Savedc (HDC); SetMapMode (HDC, MM_Text); SelectObject (HDC, HFONTDESIGN);

GetCharWidth (HDC, Ufirst, ULAST, PIWIDTHS); SelectObject (HDC, HFONT); Restoredc (HDC, -1);

// clean UpdeleteObject (hfontdesign); return otm.otmemsquare;}

/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------- GetscaledWidths: Gets floating point character widths for selectedfont size -------------- -------------------------------------------------- ------------ * /

Void getScaledWidths (HDC HDC, Double * pdwidths) {Double DScale; HFONT HFONT; INT AIDesignWidths [Lastchar 1]; INT i; logfont lf; uint uemquare;

// Call Function Above

uEMSquare = GetCharDesignWidths (hdc, 0, LASTCHAR, aiDesignWidths); // Get LOGFONT for current font in device contexthFont = GetCurrentObject (hdc, OBJ_FONT); GetObject (hFont, sizeof (LOGFONT), & lf); // Scale the widths and store As floating point value; -LF.LFHEIGHT / (Double) uemquare; for (i = 0; i <= lastchaar; i ) pdwidths [i] = dscale * AIDesignWidths [i];}

/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- -------------------------------------------------- ------------ * /

Double gettextextentfloat (double * pdwidths, ptstr pstext, int icount) {double dwidth = 0; INT i; for (i = 0; i

Return dwidth;}

/ * ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ---------------------------- Justify: based on design units for screen / printer compatibility ----------- -------------------------------------------------- ---------------- * /

Void Justify (HDC HDC, PTSTR PTEXT, Rect * PRC, IALIGN) {Double Dwidth, Adwidths [Lastchar 1]; Int XStart, YStart, Cspacechars; PTSTR PBEGIN, PEND; SIZE SIZE

// Fill The AdWidths Array with floating point character widths

GetscaledWidths (HDC, AdWidths); YSTART = prc-> top; do // for each text line {cspacechars = 0; // initialize number of spaces in line

While (* ptext == ') // Skip over letting spacesptext ;

Pbegin = PText; // set pointer to char at beginning of linedo // untric the line is known {pend = ptext; // set pointer to char at End of line

// Skip to next space While (* ptext! = '/ 0' && * ptext ! = ');

IF (* PTEXT == '/ 0') Break;

// after Each Space Encountered, Calculate Extents

Cspacechars ; dwidth = gettextextentfloat (Adwidths, Pbegin, PTEXT - PBEGIN - 1);} while (dwidth <(double) (PRC-> Right - PRC-> Left); cspacechars--; // discount last space at End of LINEWHILE (* (PEND - 1) == ') // Eliminate Trailing Spaces {Pend-; cspacechars--;

// if end of text and no space character character, set pend to endif (* ptext == '/ 0' || cspacechars <= 0) pend = ptext;

// Now get integer extents

GetTextExtentPoint32 (hdc, pBegin, pEnd - pBegin, & size); switch (iAlign) // use alignment for xStart {case IDM_ALIGN_LEFT: xStart = prc-> left; break; case IDM_ALIGN_RIGHT: xStart = prc-> right - size.cx; Break; case IDM_ALIGN_CENTER: XStart = (Prc-> Right Prc-> Left - size.cx) / 2; Break; Case IDM_Align_Justified: IF (* Ptext! = '/ 0' && Cspacechars> 0) SetTextJustification (HDC, PRC -> Right - Prc-> Left - size.cx, cspacechars; xstart = prc-> left; break;} // display the texttextout (HDC, XStart, Ystart, Pbegin, Pend - Pbegin);

// prepare for next line

SetTextJustification (HDC, 0, 0); YSTART = Size.cy; PText = Pend;} While (* Ptext && Ystart bottom - size.cy);}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) {static CHOOSEFONT cf; static DOCINFO di = {sizeof (DOCINFO), TEXT ( "Justify2: Printing")}; static int iAlign = IDM_ALIGN_LEFT; static LOGFONT lf static printdlg pd; static tchar sztext [] = {text ("Call Me ishmael. Some Years Ago - Never") Text ("Mind How long Pregrasly - Having Little") Text ("OR no Money in My PURSE, And nothing ") Text (" Thought I Watery Part of The World. IT IS ") Text (" See The Watery Part of The World. IT I Watery Part of The World. .. ") Text (" A Way I have of driving off the spleen, ") Text (" I Find Myself Growing Grim About The ") Text (" Mouth; WHENEVER IS A DAMP, DRIZZLY) TEXT (" november in my soul; whenever I find ") TEXT (" myself involuntarily pausing before ") TEXT (" coffin warehouses, and bringing up the ") TEXT (" rear of every funeral I meet; and ") TEXT (" especially whenever my HYPOS GET Such AN ") Text (" UPP ER Hand of Me, That It Requires A ") Text (" from Delibelely Stepping Into Text ("Street, And Methodicalware") Text ("People's Hats Off - TEXT ("High Time to Get To Sea As Soon As I") Text ("CAN. THIS My Substitution for Pistol") Text ("And Ball. With a Philosophical Flourish) Text (" Cato throws himself upon his sword; i ") Text (" QuietLy Take To The Ship. There IS ") Text (" Nothing Surprising In this. If the ") Text ("

Knew IT, Almost All Men In Their Degree, ") Text (" Same Feelings Towards the Ocean with ") Text (" ME. ")}; Bool Fsuccess; HDC hdc, hdcPrn; hMENU hMenu; int iSavePointSize; PAINTSTRUCT ps; RECT rect; switch (message) {case WM_CREATE: // Initialize the CHOOSEFONT structurehdc = GetDC (hwnd); lf.lfHeight = - GetDeviceCaps (hdc, LOGPIXELSY) / 6; Lf.lfoutPrecision = OUT_TT_ONLY_PRECIS; LSTRCPY (LF.Lffacename, Text ("Times New Roman"); ReleaseDC (HWND, HDC);

Cf.lstructSize = sizeof (choosefont); cf.hwndowner = hwnd; cf.hdc = null; cf.lplogfont = & lf; cf.ipointsize = 120;

// set flags for trueType Only!

cf.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_TTONLY | CF_EFFECTS; cf.rgbColors = 0; cf.lCustData = 0; cf.lpfnHook = NULL; cf.lpTemplateName = NULL; cf.hInstance = NULL; cf.lpszStyle = NULL; cf. NFONTTYPE = 0; cf.nsizemin = 0; cf.nsizemax = 0; return 0;

Case WM_COMMAND: HMENU = GetMenu (hwnd); switch (wparam) {copy idm_file_print: // Get Printer DC

Pd.lstructSize = sizeof (PrintDLG); pd.hwndowner = hwnd; pd.flags = pd_returndc | PD_nopagenums | PD_NOSELECTION;

IF (! PrintDLG (& PD)) Return 0;

IF (NULL == (HDCPRN = PD.HDC)) {MessageBox (HWND, Text ("Cannot Obtain Printer DC"), Szappname, MB_ICONEXCLAMATION | MB_OK; RETURN 0;} // set margins for Outwidth Inches Wide

rect.left = (GetDeviceCaps (hdcPrn, PHYSICALWIDTH) -GetDeviceCaps (hdcPrn, LOGPIXELSX) * OUTWIDTH) / 2 - GetDeviceCaps (hdcPrn, PHYSICALOFFSETX); rect.right = rect.left GetDeviceCaps (hdcPrn, LOGPIXELSX) * OUTWIDTH;

// set margins of 1 inch Top and bottomRect.top = getDevicecaps (hdcprn, logpixelsy) -getDevicecaps (hdcprn, physicaloffset);

Rect.bottom = getDeviceCaps (HDCPRN, PhysicalHeight) - GetDeviceCaps (HDCPRN, Logpixelsy) -GetDeviceCaps (HDCPRN, PhysicalOffSety);

// Display Text on Printer

SetCursor (LoadCursor (NULL, IDC_WAIT); showcursor (TRUE);

Fsuccess = false;

IF (STARTDOC (HDCPRN, & DI)> 0) && (STARTPAGE (HDCPRN)> 0)) {// select font using adjusted lfheight

IsavePointSize = lf.lfheight; lf.lfheight = - (GetDeviceCaps (HDCPRN, Logpixelsy) * cf.ipointsize / 720;

SelectObject (HDCPRN, CREATEFONTINDIRECT (& LF)); lf.lfheight = isavepointsize;

// set text color

SetTextColor (HDCPRN, CF.RGBCOLORS); // Display Text

Justify (HDCPRN, Sztext, & Rect, IAlign);

IF (EndPage (HDCPRN)> 0) {fsuccess = true; enddoc (hdcprn);}} showcursor (false); setcursor (loadcursor (null, idc_arrow);

Deletedc (HDCPRN);

if MessageBox (hwnd, TEXT ( "Could not print text"), szAppName, MB_ICONEXCLAMATION | MB_OK); return 0; case IDM_FONT (fSuccess!): if (ChooseFont (& cf)) InvalidateRect (hwnd, NULL, TRUE); return 0 ; case IDM_ALIGN_LEFT: case IDM_ALIGN_RIGHT: case IDM_ALIGN_CENTER: case IDM_ALIGN_JUSTIFIED: CheckMenuItem (hMenu, iAlign, MF_UNCHECKED); iAlign = LOWORD (wParam); CheckMenuItem (hMenu, iAlign, MF_CHECKED); InvalidateRect (hwnd, NULL, TRUE); return 0; } return 0;

case WM_PAINT: hdc = BeginPaint (hwnd, & ps); GetClientRect (hwnd, & rect); DrawRuler (hdc, & rect); rect.left = GetDeviceCaps (hdc, LOGPIXELSX) / 2; rect.top = GetDeviceCaps (hdc, LOGPIXELSY ) / 2; rect.right = rect.left OUTWIDTH * GetDeviceCaps (hdc, LOGPIXELSX); SelectObject (hdc, CreateFontIndirect (& lf)); SetTextColor (hdc, cf.rgbColors); Justify (hdc, szText, & rect, iAlign) ; DeleteObject (SelectObject (hdc, GetStockObject (SYSTEM_FONT))); EndPaint (hwnd, & ps); return 0; case WM_DESTROY: PostQuitMessage (0); return 0;} return DefWindowProc (hwnd, message, wParam, lParam);} JUSTIFY2 .Rc // Microsoft Developer Studio Generated Resource Script. # Include "resource.h" #include "afxres.h"

/// MenuJUSTIFY2 MENU DISCARDABLE BEGIN POPUP "& File" BEGINMENUITEM "& Print", IDM_FILE_PRINTENDPOPUP "& Font" BEGINMENUITEM "& Font ...", IDM_FONTENDPOPUP "& Align" BEGINMENUITEM "& Left", IDM_ALIGN_LEFT, CHECKEDMENUITEM "& Right", IDM_ALIGN_RIGHTMENUITEM "& Centered", IDM_ALIGN_CENTERMENUITEM "& Justified", IDM_ALIGN_JUSTIFIEDENDENDITRESOPER.H // Microsoft Developer Studio Generated Include File./ USED BY JUSTIFY2.RC

#define IDM_FILE_PRINT 40001 # define IDM_FONT 40002 # define IDM_ALIGN_LEFT 40003 # define IDM_ALIGN_RIGHT 40004 # define IDM_ALIGN_CENTER 40005 # define IDM_ALIGN_JUSTIFIED 40006JUSTIFY2 only use TrueType fonts. In its GetCharDesignWidths card, the program uses the GetOutlineTextMetrics to get a message on a surface, that is, OutlineTextMetric's OtMemSquare field.

The TrueType font is designed in the mesh of trans-square (as I said "EM" means a width of a square type, and m is equivalent to the size of the font point value in the width). All the characters of any particular TrueType font is designed in the same grid, although these flms usually have different widths. The OutlineTextMetriC structure of the OTMEMSQUARE field gives this all-in-one size of any particular font. You will find that for most TrueType fonts, OtMemSquare columns are equal to 2048, which means that the font is designed on 2048 × 2048 grid. The key is that a LogFont structure can be set for the specific TrueType font name that you want to use, and its LFHEIGHT field is equal to the negative number of OtMemSquare values. After the font is created and the device content is selected, you can call GetCharWidth. This function provides the width of a single cell in the font in a logical unit. Usually, since these fonts are scaled to different font size, the character width is not accurate. However, use the font based on OTMEMSQUARE size, which is always independent of any device content.

The GetCharDesignWidths in this manner gets the original character design width and stores them in an array of integers. Justify2 Program uses only ASCII characters in their own text, so this array does not need to be large. The GetScaledWidths in the GetScaledWidths transitions these integer stem widths into floating point widths based on the actual point value of the font in the device logic. GettextExtentFloat functions use these floating point widths to calculate the width of the entire string. This is a new Justify function to calculate the operation of the text line width.

Interesting thing

According to the profile indicates that the font font provides the possibility of combining the font to other graphics technology. We discussed the way to rotate fonts. Here you tell some other techniques. Before proceeding, you can first understand two important preparatory knowledge: drawing paths and extension brushes.

GDI drawing path

The drawing path is a collection of straight lines and curves stored in GDI. The drawing path is published in the 32-bit version of Windows. The drawing path looks similar to the area, we really convert the drawing path to the area and use the drawing path to cut. But then we will find that the difference is different.

To define a drawing path, you can simply call

BeginPath (HDC); after the call, any line (e.g., straight line, arc, and bezer curve) stored as the drawing path in the GDI, not displayed on the device content. The drawing path is often composed of a line up. To make a joint line, you should use Lineto, POLYLINETO, and Bezierto, these functions are from the current location. If you use MoveToex to change your current location, or call other drawings, or calls the window / view of the current location to change, you create a new sub-draw path in the entire drawing path. Therefore, the drawing path contains one or more sub-drawing paths, each of which is a series of links.

Each of the drawing paths can be open or closed. The first point of the first link of the closed sub-drawing path is the same as the last point of the last junction line, and the sub-draw path ends through the call closefigure. If necessary, Closefigure will use a linear blockage plot path. Subsequent line functions will start a new child drawing path. Finally, the drawing path is defined by the following call:

Endpath (HDC); At this time, then one of the following five functions:

Strokepath (HDC); FillPath (HDC); strokeAndfillPath (HDC); HRGN = Pathtoregion (HDC); SelectClipPath (HDC, ICOMBINE); each of these functions will be cleared after the drawing path definition is completed. Strokepath uses the current brush to draw the drawing path. You may be curious: What are the points on the plot path? Why can't you skip these drawing path fragmentation? I will tell you the reason later.

The other four functions close to any open drawing path with straight lines. FillPath uses the current drawing drawing path in accordance with the current multilateral fill mode. StrokeAndfillPath completes these two work. You can also convert the drawing path to the area or use the drawing path for a tailorway. The ICOMBINE parameter is one of the RGN_ series constants used in the CombinerGN-like, which points out the way the drawing path is combined with the current tailor area.

When used to fill or cut, the drawing path is more flexible than the drawing area, because the drawing area can only be defined by the rectangle, elliptical and polygon; the drawing path can be defined by the Bezier curve, at least in Windows NT can also be arc The line consists. In GDI, the storage path and the storage of the area are completely different. The drawing path is a collection of straight lines and curve definitions; while the drawing area (usual) is a collection of scan lines.

Extension brush

When calling strokepath, draw the drawing path using the current brush. In Chapter 4 discusses the Createpen function used to establish a brush object. With the publishing of the drawing path, Windows also supports an extension pen-written call called ExtCreatepen. This letter reveals its establishment of drawing paths and uses drawing paths to be useful than drawing path lines. The EXTCREATEPEN is as follows:

HPEN = Extcreatepen (iStyle, iWidth, & lbrush, 0, null); you can use this letter to draw line segments normally, but in this case Windows 98 does not support some features. Even when used to display the drawing path, Windows 98 still does not support some functions, which is why the last two parameters of the above functions are set to 0 and NULL.

For ExtCreatepen's first parameters, you can use all styles discussed in Createpen in Chapter 4. You can use PS_GEOMETRIC to additionally combine these styles (where the iWidth parameter represents line width and can be converted), or uses PS_COSMETIC (where the iWidth parameter must be 1). In Windows 98, a brush in a dotted or point line style must be PS_COSMETIC, and this limit is canceled in Windows NT.

A parameter of Createpen represents color; the corresponding parameters of EXTCREATEPEN do not only represent color, which also colors the PS_GEOMETRIC brush inside. This painting can even be defined through a dot matrix.

When drawing a wide line segment, we may pay attention to the appearance of the line segment endpoint. When connecting a straight line or curve, it may also pay attention to the appearance of the nodes between the line segments. When the brush is established by Createpen, these endpoints and connectors are typically circular; we can choose when using ExtCreatepen to build a brush. (In fact, in Windows 98, we can choose when using the brush as a drawing path; more flexible in Windows NT). The endpoint of the wide line can be defined using the following brush style in ExtCreatepen:

PS_ENDCAP_ROUNDPS_ENDCAP_SQUAREPS_ENDCAP_FLAT "Square" styles and "FLAT" styles are: the former stretches the line to half wide. Similar to the endpoint, the connection between the midline segment of the drawing path can be set by the following style: PS_JOIN_ROUNDPS_JOIN_BEVELPS_JOIN_MITER "Bevel" styles cut off; "MITER" styles turn the connection point as an arrow. The endjoin shown in Formula 17-9 is a preferred illustration of this.

Program 17-9 endjoinendjoin.c / * ------------------------------------------- --------------------------------- endjoin.c - ends and joins demo (c) Charles Petzold, 1998 -------------------------------------------------- -------------------------- /

#include Lresult Callback WndProc (HWND, UINT, WPARAM, LPARAM);

int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) {static TCHAR szAppName [] = TEXT ( "EndJoin"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = hInstance; wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); wndclass.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); wndclass.lpszMenuName = NULL; wndclass.lpszClassName = szAppName; if (! RegisterClass (& wndclass)) {MessageBox ( "! This program requires Windows NT" NULL, TEXT (), szAppName, MB_ICONERROR); return 0; } hwnd = CreateWindow (szAppName, TEXT ( "Ends and Joins Demo"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); ShowWindow (hwnd, iCmdShow); UpdateWindow (hwnd); while ( GetMessage (& MSG, NULL, 0, 0)) {TranslateMessage (& MSG); DispatchMessage (& MSG );} Return msg.wParam;} LRESULT CALLBACK WndProc (HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam) {static int iEnd [] = {PS_ENDCAP_ROUND, PS_ENDCAP_SQUARE, PS_ENDCAP_FLAT}; static int iJoin [] = {PS_JOIN_ROUND, PS_JOIN_BEVEL , PS_JOIN_MITER}; static int cxClient, cyClient; HDC hdc; int i; LOGBRUSH ib; PAINTSTRUCT ps; switch (iMsg) {case WM_SIZE: cxClient = LOWORD (lParam); cyClient = HIWORD (lParam); return 0; case WM_PAINT: hdc = BeginPaint (hwnd, & ps); SetMapMode (hdc, MM_ANISOTROPIC); SetWindowExtEx (hdc, 100, 100, NULL); SetViewportExtEx (hdc, cxClient, cyClient, NULL); lb.lbStyle = BS_SOLID; lb.lbColor =

RGB (128, 128, 128); lb.lbhatch = 0; for (i = 0; i <3; i ) {SelectObject (HDC, EXTCREATEPEN (PS_SOLID | PS_GEOMETRIC | IEND [i] | ijoin [i], 10, & lb, 0, null); BeginPath (HDC); MoveToex (HDC, 10 30 * I, 25, NULL); LINETO (HDC, 20 30 * I, 75); Lineto (HDC, 30 30 * i , 25); endpath (HDC); StrokePath (HDC); deleteObject (SelectObject (HDC, getStockObject (black_pen))); MoveToex (HDC, 10 30 * i, 25, null); Lineto (HDC, 20 30 * I, 75); LINETO (HDC, 30 30 * I, 25); EndPaint (HWND, & PS); Return 0; Case WM_DESTROY: PostquitMessage (0); Return 0;} Return DefWindowProc (HWND, IMSG, WPARAM, LPARAM);} Code draws three V-shaped wide line segments using the endpoints and links. The program also uses a spare black painting strokes three in the same line. This makes a wide line with the usual thin lines. The results are shown in Figure 17-4.

Figure 17-4 EndJoin screen display

Now everyone will understand why Windows support strokepath functions: If you draw two straight lines separately, GDI has to use endpoints on each line. Only in the drawing path definition, GDI knows that the line segment is a link between the link and uses the line segment.

Four examples

What is the benefit of this? Carefully consider: The character of the outline font is defined by a range of snaps, which defines the straight lines and turning lines. Thus, the straight lines and curves can be part of the drawing path definition.

Can really! The FONTOUT1 program shown in the formula 17-10 made this.

Program 17-10 fontout1fontout1.c / * ----------------------------------------- ------------------------------------ fontout1.c - using path to outline font (c) Charles Petzold, 1998 --------------------------------- ----------------------------- * /

#include #include "../ezteest/ /ezfont.h"

Tchar szappname [] = text ("fontout1"); tchar sztitle [] = text ("fontout1: using path to outline font);

Void PainTroutine (HWND HWND, HDC HDC, INT CXAREA, INT CYAREA) {static tchar szstring [] = text ("outline"); hfont hfont; size size;

HFONT = EZCREATEFONT (HDC, Text ("Times New Roman"), 1440, 0, 0, True; SelectObject (HDC, HFont); GettextExtentPoint32 (HDC, Szstring, Lstrlen (Szstring), BEGINPATH (HDC); Textout (Cxarea - size.cx) / 2, (cyaarea - size.cy) / 2, szstring, lstrlen (szstring); endpath (hdc); strokepath (hdc); selectObject (HDC, getStockObject (System_Font) DELETEOBJECT (HFONT);} This program and the procedures shown above have used the EZFONT and FONTDEMO files shown in this chapter. The program has established a 144-point TrueType font and calls the GetTexTextentPoint32 function to get the size of the text. Then, the Textout in the calling plot path definition makes the text in the center position in the display area window. Because the call to the TextOUT function is performed in the programs that are surrounded by the drawing path setting command, GDI does not display text immediately. Instead, the program stores the character contour in the drawing path definition.

After the drawing path definition, FONTOUT1 calls strokepath. Because the specified brush is not selected in the device content, GDI only uses the internal definition brush to draw a font outline, as shown in Figures 17-5.

Figure 17-5 Sound of Fontout1

What are we getting now? We have gained the desired outline font, but why are the strings around the rectangle?

Recall, text background mode uses the internal Opaque instead of transparent. This rectangle is the contour of the text block. This clearly shows two steps used when GDI plotted in the internal OPAQUE mode: first draw a rectangle of a pad, then draw a word. The contour of the text block rectangle also becomes part of the drawing path.

Use the ExtCreatepen to draw the contour of the font font other than the internal font pen. The fontout2 shown by the program 17-11 made this show.

Program 17-11 fontout2fontout2.c / * --------------------------------------------------------------------------------------- ------------------------------------ fontout2.c - using path to outline font (c) Charles Petzold, 1998 --------------------------------- ----------------------------- * /

#include #include "../ezteest/ /ezfont.h"

TCHAR SZAPPNAME [] = text ("fontout2"); tchar sztitle [] = text ("fontout2: using path to outline font);

Void PainTroutine (HWND HWND, HDC HDC, INT CXAREA, INT CYAREA) {static tchar szstring [] = text ("outline"); HFONT HFONT; LOGBRUSH LB; SIZE SIZE

hFont = EzCreateFont (hdc, TEXT ( "Times New Roman"), 1440, 0, 0, TRUE); SelectObject (hdc, hFont); SetBkMode (hdc, TRANSPARENT); GetTextExtentPoint32 (hdc, szString, lstrlen (szString), & size BeginPath (HDC); Textout (Cxarea - size.cx) / 2, (cyberea - size.cy) / 2, szstring, lstrlen (szstring)); endpath (hdc); lb.lbstyle = BS_SOLID; Lb.lbcolor = RGB (255, 0, 0); lb.lbhatch = 0;

SelectObject (hdc, ExtCreatePen (PS_GEOMETRIC | PS_DOT, GetDeviceCaps (hdc, LOGPIXELSX) / 24, & lb, 0, NULL)); StrokePath (hdc); DeleteObject (SelectObject (hdc, GetStockObject (BLACK_PEN))); SelectObject (hdc, GetStockObject (System_font); deleteObject (hfont);} This program is previously established (and selecting the device content) a 3-point (1/24-inch) wide red point pen. When executed under Windows NT, the results are shown in Figure 17-6. Windows 98 does not support more than 1 inert-wide non-solid pen, so Windows 98 will draw in solid red pen.

Figure 17-6 Sound of Fontout2

You can also define the padding area using the drawing path. Please create a drawing path with the method shown in the previous two programs, select a padding pattern, then call the FillPath. Another one capable of calling is strokeandfillpath, which draws the outline of the drawing path and fill it with a functions.

StrokeAndfillPath portfral is displayed in Fontfill, 17-12 Fontfill.

Program 17-12 FontfillFontFill.c / * --------------------------------------------------------------------------------------- ---------------------------------- fontfill.c - use path to fill font (c) Charles Petzold 1998 ------------------------------------------------ ----------------------------- * /

#include #include "../ezteest/ /ezfont.h"

TCHAR SZAPPNAME [] = text ("fontfill"); tchar sztitle [] = text ("fontfill: using path to fill font"); Void PainTroutine (HWND HWND, HDC HDC, INT CXAREA, INT Cyarea) {Static Tchar Szstring [ ] = TEXT ("Filling"); hfont hfont; size size;

hFont = EzCreateFont (hdc, TEXT ( "Times New Roman"), 1440, 0, 0, TRUE); SelectObject (hdc, hFont); SetBkMode (hdc, TRANSPARENT); GetTextExtentPoint32 (hdc, szString, lstrlen (szString), & size BeginPath (HDC); Textout (HDC, (Cxarea - size.cx) / 2, (Cyarea - size.cy) / 2, Szstring, Lstrlen (Szstring); Endpath (HDC); SelectObject (HDC, CreateHatchBrush HS_Diagcross, RGB (255, 0, 0))))); SetBkcolor (HDC, RGB (0, 0, 255)); setBkMode (HDC, Opaque);

StrokeAndFillPath (hdc); DeleteObject (SelectObject (hdc, GetStockObject (WHITE_BRUSH))); SelectObject (hdc, GetStockObject (SYSTEM_FONT)); DeleteObject (hFont);} FONTFILL using the default profile brushed drawing path, but using HS_DIAGCROSS style established red Shadow painting. Note The background mode is set to TransParent when the drawing path is created, and it is reset to opaque when populating the drawing path so that it can use the blue background color for the zone pattern. The results are shown in Figure 17-7.

You may want to try a few changes in this system, observe the impact of changes. First, if you turn the first setBkmode call to an annotation, you will get the text of the pattern covered by the pattern instead of the character itself. This is usually not what we actually needs, but it can do this.

In addition, fill characters and when using them, you might want to effectively give up your own Alternate multilateral fill mode. My experience said: If you use the WINDING fill mode, build a TrueType font to avoid strange phenomena (such as "O"), but use Alternate mode to be safer.

Figure 17-7 Screens of Fontfill

Finally, a drawing path can be used, so it is also a TRUETYPE font to define the tailoring area. As shown in the formula 17-13 FontClip.

Program 17-13 FontClipFontClip.c / * ----------------------------------------- -------------------------------- fontclip.c - using path for clipping on font (c) Charles Petzold 1998 ------------------------------------------------ ---------------------------- * /

#include #include "../ezteest/ /ezfont.h"

Tchar Szappname [] = text ("fontclip"); tchar sztitle [] = text ("fontclip: using path for clipping on font);

Void PainTroutine (HWND HWND, INT CYAREA) {Static Tchar Szstring [] = text ("clipping"); hfont hfont; int y, Ioffset; Point Pt [4]; size size; hfont = ezcreatefont HDC, Text ("Times New Roman"), 1200, 0, 0, True; SelectObject (HDC, HFONT);

GetTextExtentPoint32 (HDC, Szstring, Lstrlen (Szstring), & size); BeginPath (HDC); Textout (Cxarea - size.cx) / 2, (Cyarea - size.cy) / 2, Szstring, Lstrlen (Szstring)) Endpath (HDC); // SET Clipping AreaselectClipPath (HDC, RGN_COPY); // Draw Bezier Splinesioffset = (Cxarea Cyarea) / 4; for (Y = -ioffset; Y

Pt [1] .x = cxarea / 3; PT [1] .y = y ioffset;

PT [2] .x = 2 * cxarea / 3; PT [2] .y y - offset;

Pt [3] .x = cxarea; pt [3] .y y;

SelectObject (HDC, Createpen (PS_SOLID, 1, RGB (Rand ()% 256, Rand ()% 256, Rand ()%)); Polybezier (HDC, PT, 4); DeleteObject (SELECTOBJECT (HDC, GetStockObject Black_pen))))))))))));

DeleteObject (SelectObject (HDC, getStockObject (White_brush))); selectObject (hdc, getstockobject); deleteObject (HFONT);} In order to deliberately do not use setbkmode calls to do different effects. The program draws some text in the drawing path bracket, then call SelectClippath. Then use a random color to draw a series of Baizier curves.

If the FontClip program calls setBkmode using the Transparent option, the Bezier curve will be restricted to the interior of the character contour. In the background mode of the inner Opaque option, the cut area is restricted inside the text instead of the inside of the text. As shown in Figure 17-8.

Figure 17-8 FontClip has a screen display

You may want to insert SetBkMode calls in FontClip to observe changes in the Transparent option.

The FontDemo Shell Program allows you to print and display these effects, and even allow you to try some particular effects.

转载请注明原文地址:https://www.9cbs.com/read-54581.html

New Post(0)