Binghamton University EngiNet State University of New York EngiNet Thomas J. Watson School of Engineering and Applied Science WARNING All rights reserved. No Part of this video lecture series may be reproduced in any form or by any electronic or mechanical means, including the use of information storage and retrieval systems, without written approval from the copyright owner. 2007 The Research Foundation of the State University of New York CS 460/560 Computer Graphics Professor Richard Eckert Scan Converting Text Attributes of Output Primitives February 19, 2007 1
Text and Characters Very important output primitive Many pictures require text Two general techniques used Bitmapped (raster) Stroked (outline) Bitmapped Characters Each character represented (stored) as a 2-D array Each element corresponds to a pixel in a rectangular character cell Simplest: each element is a bit (1=pixel on, 0=pixel off) 00111000 01101100 11000110 11000110 11111110 11000110 11000110 00000000 Stroked Characters Each character represented (stored) as a series of line segments sometimes as more complex primitives Parameters needed to draw each stroke endpoint coordinates for line segments Characteristics of Bitmapped Characters Each character in set requires same amount of memory to store Characters can only be scaled by integer scaling factors --> "Blocky" appearance Difficult to rotate characters by arbitrary angles Fast (BitBLT) Characteristics of Stroked Characters Number of stokes (storage space) depends on complexity of character Each stroke must be scan converted ==> more time to display Easily scaled and rotated arbitrarily just transform each stroke Example Character-Display Algorithms See CS-460/560 Notes Web Pages: Links to: An illustration of how to display bitmapped characters An illustration of how to display stroked characters 2
Algorithm for Bitmapped Characters--an Example 1. Define bitmap for the letter--e.g. T int t[7][7] = { {0,0,0,0,0,0,0}, {0,1,1,1,1,1,0}, {0,0,0,1,0,0,0}, {0,0,0,1,0,0,0}, {0,0,0,1,0,0,0}, {0,0,0,1,0,0,0}, {0,0,0,0,0,0,0}}; // bitmap for T [Could have a file with the bitmap descriptions of each character in the character set to be displayed] Not the most efficient way of doing it Could have used individual bits Algorithm would be more complex Bitmapped Character Algorithm, Continued 2. Define a function to display bitmap letter[][] at pixel coordinates (x,y) disp_letter (int x, int y, int letter[7][7]) { int i,j; for (i=0; i<7; i++) for (j=0; j<7; j++) if (letter[i][j] == 1) Setpixel(x+j,y+i); // plot from bitmap} 3. Call the function, passing desired bitmap disp_letter (50,100,t); // draw a 'T' at (50,100) Algorithm for Stroked Characters 1. Define a character (CH) type: typedef struct tagch { int n; POINT * pts; } CH; pts is an array of stroke endpoint vertices n is the number of vertices Stroked Character Algorithm, Continued 2. Define generic display-character function Strokes are specified in variable c (type CH) Display at pixel coordinates (xx,yy): disp_char (int xx, int yy, CH c) { int i, n_strokes; n_strokes=c.n/2; // n points ==> n/2 strokes for (i=0; i<n_strokes; i++) } line(xx+c.pts[2*i].x,yy+c.pts[2*i].y, xx+c.pts[2*i+1].x, yy+c.pts[2*i+1].y); Stroked Character Algorithm, Continued 3. Define the character's CH structure The following could be for an 'F': POINT p[6]; CH f; p[0].x=0; p[0].y=0; p[1].x=0; p[1].y=10; p[2].x=0; p[2].y=0; p[3].x=10; p[3].y=0; p[4].x=0; p[4].y=5; p[5].x=6; p[5].y=5; f.n = 6; f.pts = p; [Descriptions of each character in the character set could be stored in a file] Stroked Character Algorithm, Continued 4. Call the character-display function, passing it the desired character (CH) disp_char (50,100,f); // draw F at (50,100) 3
OpenGLCharacter Functions Only low-level support in basic OpenGL library Explicitly define characters as bitmaps Display by mapping selected sequence of bitmaps to adjacent positions in frame buffer (BitBLTing) OpenGL GLUT Text Support Some predefined character sets in GLUT: 1. GLUT Bitmapped: Display with glutbitmapcharacter(font, ch); font: constant type face to be used GLUT_BITMAP_8_BY_15 (fixed-width) GLUT_BITMAP_TIMES_ROMAN_10 (variable width) Others are available ch: ASCII code of character Position with glrasterposition2i(x,y); Example: glrasterposition2i(20,10); glutbitmapcharacter(glut_bitmap_8_15, A ); x coordinate is incremented by width of character after display 2. GLUT Stroked Characters: glutstrokecharacter(font, ch); Font: GLUT_STROKE_ROMAN (proportional spacing) GLUT_STROKE_MONO_ROMAN (constant spacing) Ch: ASCII code of character Size & position determined by specifying transformation operations We ll see these later Character Fonts in Windows FONT--Typeface, style, size of characters in a character set Three kinds of Windows Fonts Stock Fonts Logical or GDI Fonts Device Fonts Windows Stock Fonts Built into Windows Always available Windows Logical or GDI Fonts Defined in separate font resource files on disk.fon file (Stroke or Raster).fot/.ttf file (TrueType) Specific instance must be created 4
Windows Stroke Fonts Consist of line/curve segments Continuously scalable Slow to draw Legibility not too good Windows Raster Fonts Bitmaps so: Scaling by non-integer factors difficult Fast to display Legibility very good Windows TrueType Fonts Windows TrueType Fonts Rasterized stroke fonts so: Stored as strokes with hints to convert to bitmap Conversion called rasterization Continuously scalable Fast to display Legibility very good Combine best of both stroke and raster fonts Device Fonts Native to output device e.g., built-in printer fonts Postscript Using Windows Stock Fonts Like stock pens, brushes Accessed with: GetStockObject(font_name); Returns a handle to a font Use by selecting into DC with SelectObject(): Or -- CDC::SelectStockObject(font_name); 5
Using Windows Logical Fonts Instantiate a CFont object Use CFont::CreateFont(14 params!!) Specify characteristics Interpolates data from font file --> new sizes, bold, rotated, etc. Select CFont object into the DC Called logical since determined by program logic not just file contents See online help Windows Text Metrics CreateFont () may not give you exactly what you ask for Can use CDC::GetTextMetrics() to find out font details Gives lots of information in a TEXTMETRIC structure Commonly used to determine font size can be used to set line spacing, caret size, sizes of buttons, etc. Windows Text Metrics Computer Graphics Attributes Line and Text Attributes Fonts in Windows Area Fill Boundary/Flood Fill Algorithms Scanline Polygon Fill Algorithm Attributes How primitives are to be displayed Most systems use modal attributes Values in effect until changed Text Attributes Font (typeface) Character set with particular design style Display style underlined, italic, boldface, outlined, strikeout, spacing, etc. Color Size (width, height)--specified in points Point = 1/72 inch 6
Text Attributes, continued Orientation--how much character is rotated Escapement--orientation of line between first & last character in a string Color Width Line Attributes Style--solid, dotted, dashed, etc. Can be specified by giving a pattern array e.g., pat[]={1,1,1,1,1,1,0,0} Repeat this pattern on entire line: i th pixel along line: if (pat[i%8]==1) SetPixel(x,y) In Windows, use a pen (CPen) Area Fill Important for any closed output primitive Polygons, Circles, Ellipses, etc. Attributes: fill color fill pattern 2 Types of area fill algorithms: Boundary/Flood Fill Algorithms Scanline Algorithms Area Fill Algorithms See CS-460/560 Notes Web Page Link to: Week 5-BC: Area Fill Algorithms URL: http://www.cs.binghamton.edu/~reckert/460 /fillalgs.htm Boundary/Flood Fill Algorithms Determine which points are inside from pixel color information e.g., interior color, boundary color, fill color, current pixel color Color the ones that are inside. Scanline Algorithms Examine horizontal scanlines spanning area Find intersection points between current scanline and borders Color pixels along the scanline between alternate pairs of intersection points Especially useful for filling polygons polygon intersection point calculations are very simple Use vertical and horizontal coherence to get new intersection points from old rapidly 7
Boundary/Flood Fill Algorithms Determine which points are inside from pixel color information e.g., interior color, boundary color, fill color, current pixel color Color the ones that are inside. Connected Area Boundary Fill Algorithm For arbitrary closed areas Input: Boundary Color (BC), Fill Color (FC) (x,y) coordinates of seed point known to be inside Define a recursive BndFill(x,y,BC,FC) function: If pixel (x,y) not set to BC or FC, then set to FC Call BndFill() for neighboring points To be able to implement this, need an inquire function e.g., Windows GetPixel(x,y) returns color of pixel at (x,y) The BndFill() Function BndFill(x,y,BC,FC) { color = GetPixel(x,y) if ( (color!= BC) && (color!= FC) ) { SetPixel(x,y,FC); BndFill(x+1,y,BC,FC); BndFill(x,y+1,BC,FC); BndFill(x-1,y,BC,FC); BndFill(x,y-1,BC,FC); } } This would be called by code like: BndFill(50,100,5,8); // 5,8 are colors Windows GDI: colors are COLORREFs RGB() macro could be used As given, only works with 4-connected regions Boundary must be of a single color Could have multiple interior colors 8
Flood Fill Algorithm A variation Boundary Fill Fill area identified by the interior color instead of boundary color Good for single colored area with multicolor border Ups & Downs of Boundary / Flood Fill Big Up: Can be used for arbitrary areas! BUT-- Deep Recursion so: Uses enormous amounts of stack space (Adjust stack size before building in Windows!) Also very slow since: Extensive pushing/popping of stack Pixels may be visited more than once GetPixel() & SetPixel() called for each pixel 2 accesses to frame buffer for each pixel plotted Adjusting Stack Size in VC++ Project on Main Menu Properties Configuration Properties Linker System Stack Reserve Size: perhaps 10000000 Stack Commit Size: perhaps 8000000 Scanline Polygon Fill Algorithm Look at individual scan lines Compute intersection points with polygon edges Fill between alternate pairs of intersection points More specifically: For each scanline spanning the polygon: Find intersection points with all edges the current scanline cuts Sort intersection points by increasing x Turn on all pixels between alternate pairs of intersection points But-- There may be a problem with intersection points that are polygon vertices 9
Preprocessing non-max/min intersection points Vertex intersection points that are not local max or min must be preprocessed! Move lower endpoint of upper edge up by one pixel i.e., y <-- y + 1 What about x? m =? y/? x, so?x = (1/m) *? y But? y = 1, so: x <-- x + 1/m Preprocessing Active Edge A polygon edge intersected by the current scanline As polygon is scanned, edges will become active and inactive. Criterion for activating an edge: ysl = ymin of the edge (Here ysl = y of current scanline) Criterion for deactivating an edge: ysl = ymax of the edge Vertical & Horizontal Coherence Moving from one scanline to next: y = y + 1 If edge remains active, new intersection point coordinates will be: ynew = yold + 1 xnew = xold + 1/m (1/m = inverse slope of edge) Scanline Polygon Fill Algorithm Input List of polygon vertices (xi,yi) 10
Scanline Polygon Fill Algorithm Data Structures 1. Edge table: For each edge: edge #, ymin, ymax, x, 1/m 2. Activation Table: (y, edge number activated at y) Provides edge(s) activated for each new scanline Constructed by doing a "bin" or "bucket" sort 3. Active Edge List (AEL): Active edge numbers sorted on x A dynamic data structure Bin Sort for Activation Table 1 3 0 0 2 2 4 Scanline Polygon Fill Algorithm 1. Set up edge table from vertex list; determine range of scanlines spanning polygon (miny, maxy ) 2. Preprocess edges with nonlocal max/min endpoints 3. Set up activation table (bin sort) 4. For eachscanline spanned by polygon: Add new active edges to AEL using activation table Sort active edge list on x Fill between alternate pairs of points (x,y) in order of sorted active edges For each edge e in active edge list: If (y!=ymax [e]) Compute & store new x (x+=1/m) Else Delete edge e from the active edge list Scanline Polygon Fill Algorithm Example Scanline Poly Fill Alg. (with example Data) 11