Software Solution for Engineers and Scientist Episode 8 pptx

90 340 0
Software Solution for Engineers and Scientist Episode 8 pptx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Device context operations belong to two types: those that obtain information and those that set attributes. For example, the GDI function GetTextColor() re - trieves the current text color from the device context, while the function SetTextColor() is used to change the text color attribute. Although these func - tions are sometimes referred to as get- and set-types, the function names do not always start with these words. For example, the SelectObject() function is used to both get and set the attributes of pens, brushes, fonts, and bitmaps. Graphics applications often need to obtain information regarding the device context. For example, a program may need to know the screen resolution or the number of display colors. One of the most useful functions for obtaining informa - tion regarding the capabilities of a device context is GetDeviceCaps(). The call to GetDeviceCaps() requires two parameters: the first one is the handle to the device context, and the second one is an index value that identifies the capability being queried. Table 23.1 lists some of the most useful information returned by this function. Table 23.1 Information Returned by GetDeviceCaps() INDEX MEANING DRIVERVERSION Version number of device driver. TECHNOLOGY Any one of the following: Value Meaning DT_PLOTTER Vector plotter DT_RASDISPLAY Raster display DT_RASPRINTER Raster printer DT_RASCAMERA Raster camera DT_CHARSTREAM Character stream DT_METAFILE Metafile DT_DISPFILE Display file HORZSIZE Width of the physical screen (millimeters). VERTSIZE Height of the physical screen (millimeters). HORZRES Width of the screen (pixels). VERTRES Height of the screen (raster lines). LOGPIXELSX Number of pixels per logical inch along the screen width. LOGPIXELSY Number of pixels per logical inch along the screen height. BITSPIXEL Number of color bits per pixel. PLANES Number of color planes. NUMBRUSHES Number of device-specific brushes. NUMPENS Number of device-specific pens. NUMFONTS Number of device-specific fonts. NUMCOLORS Number of entries in the color table, if the device has a color depth of no more than 8 bits per pixel. Otherwise, –1 is returned. ASPECTX Relative width of a device pixel used for line drawing. ASPECTY Relative height of a device pixel used for line drawing. ASPECTXY Diagonal width of the device pixel. (continues) 604 Chapter 23 Table 23.1 Information Returned by GetDeviceCaps() (continued) INDEX MEANING CLIPCAPS Flag indicating clipping capabilities of the device. Value is 1 if the device can clip to a rectangle. Otherwise, it is 0. SIZEPALETTE Number of entries in the system palette. NUMRESERVED Number of reserved entries in the system palette. COLORRES Actual color resolution of the device, in bits per pixel. PHYSICALWIDTH For printing devices: the width of the physical page, in device units. PHYSICALHEIGHT For printing devices: the height of the physical page, in device units. PHYSICALOFFSETX For printing devices: the distance from the left edge of the physical page to the left edge of the printable area, in device units. PHYSICALOFFSETY For printing devices: the distance from the top edge of the physical page to the top edge of the printable area, in device units. RASTERCAPS Value that indicates the raster capabilities of the device, as follows: Capability Meaning RC_BANDING Requires banding support. RC_BITBLT Capable of transferring bitmaps. RC_BITMAP64 Supports bitmaps larger than 64K. RC_DI_BITMAP Supports SetDIBits() and GetDIBits functions. RC_DIBTODEV Capable of supporting the SetDIBitsToDevice function. RC_FLOODFILL Capable of performing flood fills. RC_PALETTE Palette-based device. RC_SCALING Capable of scaling. RC_STRETCHBLT Capable of performing the StretchBlt function. RC_STRETCHDIB Capable of performing the StretchDIBits function. CURVECAPS Indicates the curve capabilities of the device, as follows: Value Meaning CC_NONE Does not support curves. CC_CIRCLES Device can draw circles. CC_PIE Device can draw pie wedges. CC_CHORD Device can draw chord arcs. CC_ELLIPSES Device can draw ellipses. CC_WIDE Device can draw wide borders. CC_STYLED Device can draw styled borders. CC_WIDESTYLED Device can draw wide and styled borders. CC_INTERIORS Device can draw interiors. CC_ROUNDRECT Device can draw rounded rectangles. (continues) Drawing Lines and Curves 605 Table 23.1 Information Returned by GetDeviceCaps() (continued) INDEX MEANING LINECAPS Indicates the line capabilities of the device, as follows: Value Meaning LC_NONE Does not support lines. LC_POLYLINE Device can draw a polyline. LC_MARKER Device can draw a marker. LC_POLYMARKER Device can draw multiple markers. LC_WIDE Device can draw wide lines. LC_STYLED Device can draw styled lines. LC_WIDESTYLED Device can draw lines that are wide and styled. LC_INTERIORS Device can draw interiors. POLYGONALCAPS Indicates the polygon capabilities of the device, as follows: Value Meaning PC_NONE Does not support polygons. PC_POLYGON Device can draw alternate-fill polygons. PC_RECTANGLE Device can draw rectangles. PC_WINDPOLYGON Device can draw winding-fill polygons. PC_SCANLINE Device can draw a single scanline. PC_WIDE Device can draw wide borders. PC_STYLED Device can draw styled borders. PC_WIDESTYLED Device can draw borders that Are wide and styled. PC_INTERIORS Device can draw interiors. TEXTCAPS Indicates the text capabilities of the device, as follows: Value Meaning TC_OP_CHARACTER Device is capable of character output precision. TC_OP_STROKE Device is capable of stroke output precision. TC_CP_STROKE Device is capable of stroke clip precision. TC_CR_90 Device is capable of 90-degree character rotation. TC_CR_ANY Device is capable of any character rotation. TC_SF_X_YINDEP Device can scale independently in the x- and y-directions. TC_SA_DOUBLE Device is capable of doubled character for scaling. TC_SA_INTEGER Device uses integer multiples only for character scaling. TC_SA_CONTIN Device uses any multiples for exact character scaling. (continues) 606 Chapter 23 Table 23.1 Information Returned by GetDeviceCaps() (continued) VALUE MEANING TC_EA_DOUBLE Device can draw double-weight characters. TC_IA_ABLE Device can italicize. TC_UA_ABLE Device can underline. TC_SO_ABLE Device can draw strikeouts. TC_RA_ABLE Device can draw raster fonts. TC_VA_ABLE Device can draw vector fonts. TC_SCROLLBLT Device cannot scroll using a bit-block transfer. 23.2.2 DC Info Demonstration Program The program named DCI_DEMO, located in the DC Info Demo project folder on the book's on-line software package, shows how to obtain device context information. The menu labeled "DC Info" contains commands for displaying the most used general device context capabilities, the device driver version, as well as the specific line and curve drawing capabilities. Figure 23.1 shows the various menu commands in the DCI_DEMO program. Figure 23.1 Screen Snapshots of the DC Info Program Drawing Lines and Curves 607 The Capabilities command in the DC Info menu displays the device context val - ues for some of the most used elements returned by the GetDeviceCaps() func - tion. To simplify the programming, the data required during processing is stored in a header file named DC_Caps.h, which can be found in the project directory. The header file is formatted as follows: // Header file for DC Info Demo project // Contains array of structures #define LINES ((int) (sizeof DCcaps / sizeof DCcaps [0])) struct { int iIndex ; char *szLabel ; char *szDesc ; } DCcaps [] = { HORZSIZE, "HORZSIZE", "Width (in mm):", VERTSIZE, "VERTSIZE", "Height (in mm):", HORZRES, "HORZRES", "Width (in pixels):", . . . NUMRESERVED, "NUMRESERVED", "Reserved palette entries:", COLORRES, "COLORRES", "Actual color resolution:" }; Each entry in the array of structures contains three elements. The first one (int iIndex) is the index name required in the GetDeviceCaps() call. The two other ele- ments are strings used at display time. Processing takes place in a loop in which the number of iterations is determined by the constant LINES, which is calculated by dividing the number of entries in the structure by the number of elements in each entry. This coding allows us to change the number of entries in the array without having to change the loop. // Obtain and display DC capabilities for(i=0;i<LINES ; i++) { TextOut (hdc, cxChar, cyChar * (1 + i), DCcaps[i].szLabel, strlen (DCcaps[i].szLabel)) ; TextOut (hdc, cxChar + 16 * cxCaps, cyChar * (1 + i), DCcaps[i].szDesc, strlen (DCcaps[i].szDesc)) ; SetTextAlign (hdc, TA_RIGHT | TA_TOP) ; TextOut (hdc, cxChar + 16 * cxCaps + 40 * cxChar, cyChar * (1 + i), szBuffer, wsprintf (szBuffer, "%5d", GetDeviceCaps (hdc, DCcaps[i].iIndex))) ; SetTextAlign (hdc, TA_LEFT | TA_TOP) ; } break; In the previous code fragment, the first TextOut() call displays the szLabel vari - able in the DCcaps structure. The second call to TextOut() displays the szDesc string. The value in the device context is obtained with the GetDeviceCaps() func - 608 Chapter 23 tion that is part of the third call to TextOut(). In this case the iIndex element in the array is used as the second parameter to the call. The wsprintf() function takes care of converting and formatting the integer value returned by GetDeviceCaps() into a displayable string. Obtaining and displaying the driver version is much simpler. The coding is as fol - lows: // Get driver version _itoa(GetDeviceCaps(hdc, DRIVERVERSION), szVersion + 16, 10); // Initialize rectangle structure SetRect (&textRect, // address of structure 2 * cxChar, // x for start cyChar, // y for start cxClient, // x for end cyClient); // y for end DrawText( hdc, szVersion, -1, &textRect, DT_LEFT | DT_WORDBREAK); break; In this case we use the _itoa() function to convert the value returned by GetDeviceCaps() into a string. SetRect() and DrawText() are then used to format and display the string. Obtaining and displaying the curve drawing and line drawing capabilities of the device context requires different processing. These values (see Table 23.1) are re- turned as bit flags associated with an index variable. For example, we make the call to GetDeviceCaps() using the index constant CURVECAPS as the second parameter. The integer returned by the call contains all the bit flags that start with the prefix CC (CurveCaps) in Figure 23.1. Code can then use a bitwise AND to test for one or more of curve drawing capabilities. The following code fragment shows one possible ap - proach for obtaining curve-drawing capabilities: // Get curve drawing capabilities curvecaps = GetDeviceCaps (hdc, CURVECAPS); // Test individual bit flags and change default // string if necessary if (curvecaps & CC_NONE) strncpy(szCurvCaps + 21, strNo, 3); if (curvecaps & CC_CIRCLES) strncpy(szCurvCaps + (26 + 21), strYes, 3); . . . if (curvecaps & CC_ROUNDRECT) strncpy(szCurvCaps + (9 * 26 + 21), strYes, 3); // Initialize rectangle structure SetRect (&textRect, // address of // structure 2 * cxChar, // x for start cyChar, // y for start cxClient, // x for end cyClient); // y for end DrawText( hdc, szCurvCaps, -1, &textRect, Drawing Lines and Curves 609 DT_LEFT | DT_WORDBREAK); break; Each of the if statements in the processing routine tests one of the bit flags re - turned by GetDeviceCaps(). If the bit is set, then a text string containing the words YES or NO is moved into the display string. When all the bits have been ex - amined, the message string named szCurvCaps is displayed in the conventional manner. 23.2.3 Color in the Device Context Monochrome displays are a thing of the past. Virtually all Windows machines have a color display and most of themcango up to 16.7 million displayable colors. In graph - ics programming you will often have to investigate the color capabilities of a device as well as select and manipulate colors. In Windows programming, colors are defined by the relative intensity of the red, green, and blue primary components. Each color value is encoded in 8 bits, therefore, all three primary components require 24 bits. Since no C++ data type is exactly 24 bits, however, the color value in Windows is stored in a type called COLORREF, which contains 32 bits. The resulting encoding is said to be in RGB format, where the letters stand for the red, green, and blue components, respec- tively. Figure 23.2 shows the bit structure of the COLORREF type. Figure 23.2 COLORREF Bitmap Windows provides a macro named RGB, defined in the windows.h header file; it simplifies entering the color values into a data variable of type COLORREF. The macro takes care of inserting the zeros in bits 24 to 31, and in positioning each color in its corresponding field. As the name RGB indicates, the first value corre - sponds to the red primary, the second one to the green, and the third one to the blue. For example, to enter a middle-gray value, in which each of the primary col - ors is set to 128, proceed as follows: COLORREF midGray; // Variable of type COLORREF midGray = RGB(128, 128, 128); The COLORREF data type is also used to encode palette colors. Windows uses the high-order 8 bits to determine if a color value is in explicit RGB, palette-index, or palette-relative format. If the high-order byte is zero, then the color is an ex - 610 Chapter 23 31 24 23 16 15 8 7 0 FORMAT CODE RED 0 for explicit RGB format 1 for palette-index format 2 for palette-relative format GREEN BLUE plicit RGB value; if it is 1 then it is a palette-index value; if it is 2 then the color is a palette-relative value. Using the RGB macro when creating explicit-RGB values en - sures that the high-order byte is set correctly. Obtaining color information from the device context requires careful consider - ation. Note in Table 23.1 that the index constant NUMCOLORS is valid only if the color depth is no more than 8 bits per pixel. The device queried in Figure 23.1 has 16 bits per pixel; therefore, the NUMCOLORS value is set to –1. By the same token, the COLORRES index constant is valid only if the device sets the RC_PALETTE bit. In Figure 23.1 the value of this field is 0. The two most useful constants for obtaining general color depth information are PLANES and BITPIXEL. PLANES returns the number of color planes and BITPIXEL returns the number of bits used in encoding each plane. 23.3 Graphic Objects and GDI Attributes We should first mention that Windows graphics objects are not objects in the ob - ject-oriented sense. Windows graphics objects are pens, brushes, bitmaps, palettes, fonts, paths, and regions. Of these, pens and brushes are the objects most directly re- lated to pixel and line drawing operations. 23.3.1 Pens The pen graphics object determines a line's color, width, and style. Windows uses the pen currently selected in the device context with any of the pen-based drawing func- tions. Three stock pens are defined: BLACK_PEN, WHITE_PEN, and NULL_PEN. The default pen is BLACK_PEN, which draws solid black lines. Applications refer to a pen by means of its handle, which is stored in a variable of type HPEN. The GetStockObject() function is used to obtain a handle to one of the stock pens. The pen must be selected into the device context before it is used, as follows: HPEN aPen; // handle to pen . . . aPen = GetStockObject (WHITE_PEN); SelectObject (hdc, aPen); The two functions can be combined in a single statement, as follows: SelectObject (hdc, GetStockObject (WHITE_PEN)); In this case, no pen handle variable is required. SelectObject() returns the handle to the pen previously installed in the device context. This can be used to save the original pen so that it can be restored later. Drawing applications sometimes require one or more custom pens, which have a particular style, width, and color. Custom pens can be created with the functions CreatePen(), CreatePenIndirect(), and ExtCreatePen(). In the CreatePen() function the pen's style, width, and color are passed as parameters. CreatePenIndirect() uses a structure of type LOGPEN to hold the pen's style, width, and color. ExtCreatePen(), introduced in Windows 95, is the more powerful of the three. The Drawing Lines and Curves 611 iStyle parameter is a combination of pen type, styles, end cap style, and line join at - tributes. The constants used in defining this parameter are listed in Table 23.2. Table 23.2 Values Defined for the ExtCreatePen() iStyle Parameter PEN TYPE DESCRIPTION PS_GEOMETRIC Pen is geometric. PS_COSMETIC Pen is cosmetic. Same as those created with CreatePen() and CreatePenIndirect(). Width must be 1 pixel. Pen Style PS_ALTERNATE Windows NT: Pen sets every other pixel. (cosmetic pens only.) Windows 95: Not supported. PS_SOLID Pen is solid. PS_DASH Pen is dashed. PS_DOT Pen is dotted. PS_DASHDOT Pen has alternating dashes and dots. PS_DASHDOTDOT Pen has alternating dashes and double dots. PS_NULL Pen is invisible. PS_USERSTYLE Windows NT: Pen uses a styling array supplied by the user. Windows 95: Not supported. PS_INSIDEFRAME Pen is solid. Any drawing function that takes a bounding rectangle, the dimensions of the figure are shrunk so that it fits entirely in the bounding rectangle. Geometric pens only. End Cap Style (only in stroked paths) PS_ENDCAP_ROUND End caps are round. PS_ENDCAP_SQUARE End caps are square. PS_ENDCAP_FLAT End caps are flat. Join Style (only in stroked paths) PS_JOIN_BEVEL Joins are beveled. PS_JOIN_MITER Joins are mitered when they are within the current limit set by the SetMiterLimit() function. If it exceeds this limit, the join is beveled. SetMiterLimit() is discussed in Chapter 21. PS_JOIN_ROUND Joins are round. The standard form of the ExtCreatePen() function is as follows: HPEN ExtCreatePen (iStyle, // pen style iWidth, // pen width &aBrush, // pointer to a LOGBRUSH // structure (next section) dwStyleCount,// length of next parameter lpStyle); // dot-dash pattern array 612 Chapter 23 The second parameter to ExtCreatePen() defines the pen's width. If the pen is a geometric pen, then its width is specified in logical units. If it is a cosmetic pen then the width must be set to 1. A geometric pen created with ExtCreatePen() has brush-like attributes. The third parameter is a pointer to LOGBRUSH. The LOGBRUSH structure, described in the following section, is defined as follows: struct tagLOGBRUSH { UINT lbStyle; COLORREF lbColor; LONG lbHatch; } LOGBRUSH If the pen is a cosmetic pen, then the lbStyle member must be BS_SOLID and the lbColor member defines the pen's color. In this case the lbHatch member, which sets a brush's hatch pattern, is ignored. If the pen is geometric, then all three struc - ture members are meaningful and must be used to specify the corresponding at - tributes. The fourth parameter, dwStyleCount, determines the length of the fifth parame- ter. The fifth parameter, lpStyle, is a pointer to an array of doubleword values. The first value in the array is the length of the first dash of a user-defined pen style, the second one is the length of the first space, and so on. If the pen style does not con- tain the PS_USERSTYLE constant, then the fourth parameter must be zero, and the fifth parameter must be NULL. Note that PS_USERSTYLE is supported in Windows NT but not in Windows 95 or later versions. The end cap styles determine the appearance of the line ends. Three constants are defined for round, square, and flat line ends. The end join style determines the appearance of the connecting point of two lines. Both styles are available only for geometric pens. Figure 23.3, on the following page, shows the pen styles and the effects of the different end caps and joins. Note in Figure 23.3 that the difference between square and flat caps is that the square style extends the line by one-half its width. The white lines in the end cap style insert are drawn with the white stock pen, to better show the style's effect. The NULL_PEN style creates a pen that draws with transparent ink, therefore it leaves no mark as it moves on the drawing surface. This style is occasionally used in creating figures that are filled with a particular brush style but have no border. 23.3.2 Brushes The brush object determines the attributes used in filling a solid figure. The outline of these figures is determined by the brush selected in the device context. A brush has a style, color, and hatch pattern. There are several stock brushes: WHITE_BRUSH, LTGRAY_BRUSH, GRAY_BRUSH, DKGRAY_BRUSH, BLACK_BRUSH, and NULL_BRUSH. All stock brushes are solid, that is, they fill the entire enclosed area of the figure. The NULL_BRUSH is used to draw figures without filling the interior. If a solid figure is drawn with the NULL_PEN, then it is filled but has no outline. Drawing Lines and Curves 613 [...]... on a boolean function of two variables: the pen and the background For this reason it is described as a binary raster operation, or ROP2 All four boolean primitives are used in setting the mix mode: AND, OR, NOT, and XOR The function for setting the foreground mix mode is SetROP2() GetROP2() returns the current mix mode in the device context The general form of the SetROP2() function is as follows: Table... Divide -and- Conquer Method of Creating a Bezier Curve In Step 1of Figure 23.10, we see the start node S1, the end node E1, and the attractor A1 We first find a point midway between S1 and A1 and label it P1 Another point midway between A1 and E1 is labeled P2 Points P1 and P2 are joined by a line segment, whose midpoint is labeled P3 In Step 2 we can see two new figures The first one has nodes at S2 and. .. Note that in the array the first and fourth entries are at offset 0 and 3 respectively, and the second and third entries are at offset 1 and 2 If there are other Bezier curves in the array, the first node is not explicit in the data, since it coincides with the end node of the preceding curve Therefore, after the first curve, the following two entries are attractors, and the third entry is the end node... entries are attractors, and the third entry is the end node Table 23.6 shows the sequence of nodes and control points for an array with multiple Bezier curves Drawing Lines and Curves 629 Table 23.6 Nodes and Control Points for the PolyBezier() Function NUMBER 1 2 3 4 5 6 7 8 9 10 OFFSET TYPE 0 1 2 3 4 5 6 7 8 9 Start node of curve 1 First attractor of curve 1 Second attractor of curve 1 End node of curve... both the screen and the inverse of the pen Pixel is a combination of the colors common to both the pen and the screen Pixel is a combination of the colors common to both the pen and the inverse of the screen Pixel is a combination of the screen color and the inverse of the pen color Pixel is a combination of the pen color and the screen color Pixel is a combination of the pen color and the inverse... start node for the first curve is the current pen position, and the current pen position is updated to the end node of the last curve The return value and parameters are the same for both functions In the case of PolyBezierTo() each curve is defined by three points: two control points and the end node Table 23.7, on the following page, shows the sequence of points stored in the points array for PolyBezierTo()... node of Bezier curve pointsArray[5].x = 150; pointsArray[5].y = 150; // Filling array of points for first Bezier spline pointsArray[6].x = 200; pointsArray[6].y = 75; pointsArray[7].x = 280 ; pointsArray[7].y = 190; Drawing Lines and Curves 633 pointsArray [8] .x = 350; pointsArray [8] .y = 150; // Filling array for closed figure pointsArray[9].x = 200; pointsArray[9].y = pointsArray[10].x = 300; pointsArray[10].y... dot by setting five adjacent pixels The demo program displays a pop-up menu, named Line Functions, which has menu commands for exercising LineTo(), PolyLineTo(), PolyLine(), PolyPolyLine(), Arc(), AngleArc(), PolyBezier(), and PolyDraw() Code for implementing PolyDraw() and AngleArc() in software is also included in the demo program Chapter 24 Drawing Solid Figures Chapter Summary In this chapter we... overhead in performing the pixel set and read operations To draw lines and figures by successively calling these functions would be prohibitively time-consuming On the other hand, there are cases in which the programmer must resort to pixel-by-pixel drawing since other higher-level functions are not available There are eleven functions in the Windows API that can be used to draw lines For one of them,... succeeds and FALSE if it fails, but most often the return value is not used by code If the LineTo() function succeeds, the current pen position is reset to the line's end point; therefore, the function can be used to draw a series of connected line segments The following code fragment draws a rectangle using four lines: HPEN bluePen4; // handle for a pen int x, y, i, j; // local variables // Create and . color is an ex - 610 Chapter 23 31 24 23 16 15 8 7 0 FORMAT CODE RED 0 for explicit RGB format 1 for palette-index format 2 for palette-relative format GREEN BLUE plicit RGB value; if it is 1 then. by GetDeviceCaps() into a string. SetRect() and DrawText() are then used to format and display the string. Obtaining and displaying the curve drawing and line drawing capabilities of the device. structure 2 * cxChar, // x for start cyChar, // y for start cxClient, // x for end cyClient); // y for end DrawText( hdc, szCurvCaps, -1, &textRect, Drawing Lines and Curves 609 DT_LEFT | DT_WORDBREAK); break; Each

Ngày đăng: 12/08/2014, 07:22

Từ khóa liên quan

Tài liệu cùng người dùng

Tài liệu liên quan