diff options
Diffstat (limited to 'Build/source/libs/freetype/freetype-1.5/docs/bitmaps.txt')
-rw-r--r-- | Build/source/libs/freetype/freetype-1.5/docs/bitmaps.txt | 770 |
1 files changed, 0 insertions, 770 deletions
diff --git a/Build/source/libs/freetype/freetype-1.5/docs/bitmaps.txt b/Build/source/libs/freetype/freetype-1.5/docs/bitmaps.txt deleted file mode 100644 index 79ed2ddbea9..00000000000 --- a/Build/source/libs/freetype/freetype-1.5/docs/bitmaps.txt +++ /dev/null @@ -1,770 +0,0 @@ - - Bitmap and Pixmap generation with FreeType - ------------------------------------------ - - Table of Contents - - - Introduction - - I. The rasterizer component - - II. Bitmap & pixmap descriptors - - III. Rendering an outline - - IV. Anti-aliasing palette and other concerns - - Conclusion - - - -Introduction ------------- - - This document describes the steps that are needed to render a - glyph outline into a bitmap or a pixmap with the FreeType library. - It contains several important details needed to generate bitmaps - correctly in all situations, including if an outline has been - transformed or translated. - - --------------------------------------------------------------------- - - -I. The rasterizer component ---------------------------- - - In FreeType, the component in charge of performing bitmap and - pixmap rendering is called the `rasterizer'. Generation is - performed through a traditional process called `scan-line - conversion', but exhibits certain properties: - - - The rasterizer doesn't allocate bitmaps: - - In fact, it is only able to render an outline into an existing - bitmap or pixmap, which is passed to one of its rendering - functions. This means that the target bitmap/pixmap must be set - up correctly by the caller to achieve desired results. Setting - up bitmap and pixmap descriptors is explained in section II. - - - It is able to render anti-aliased pixmaps directly: - - This is unlike other graphics packages, which render to a - `large' bitmap which is then filtered down. Putting the - anti-aliasing logic within the rasterizer improves performance - and reduces memory usage, as well as lets us use better - algorithms which couldn't work in a `two-phase' process. - - The rasterizer is located in the files `ttraster.h' and - `ttraster.c'. - - The format of outlines isn't important for most developers and - won't be discussed here. However, a few conventions must be - explained regarding the vector outlines: - - - 1. Units - - All point coordinates within an outline are stored in 32-bit - fractional pixel values, using the 26.6 fixed float format - (which uses 26 bits for the integer part, and 6 bits for the - fractional part). The following table gives some examples of - real versus 26.6 coordinates: - - ----------------------------------------- - real real coord 26.6 coord - coord. * 2^6 - ----------------------------------------- - 0 0*64 = 0.0 0 - 2.4 2.4*64 = 153.6 154 - 3 3*64 = 192.0 192 - -1.7 -1.7*64 = -108.8 -109 - - As you can see, conversion is relatively simple -- basically a - multiplication by 64. - - In order to differentiate coordinates expressed in real or 26.6 - systems, we'll use in the following lines brackets (`[' and `]') - for real coordinates, and simple parentheses (`(' and `)') for - fractional coordinates so that - - [1.0,2.5] equals (64,160) - - [0,0] equals (0,0) - - [-2,3] equals (-128,192) - - - 2. Orientation - - The rasterizer uses the traditional convention of an X axis - oriented from left to right, and of a Y axis oriented from - bottom to top. - - ^ Y - | - | - | - -*-----> X - | - - You've probably already used it at school when doing math :-) - - Though the orientation of bitmap lines has the opposite - direction on nearly all graphics systems, the former convention - is the _right_ one when it comes to vector graphics. The reason - is simply that for managing angles and vector cross-products - resp. orientations in complex algorithms, a single convention, - used in math as well as computing alike solves many headaches. - - And due to education, most people expect a 45 degrees angle to - be in the top right quadrant, at coordinate (1,1). - - - 3. Pixels and the grid - - In a vector outline, a point is immaterial and has no size or - width, just like in usual geometry. A `pixel' is an element of - a computer image called a `map' (like a bitmap or a pixmap). - - The FreeType rasterizer follows the convention defined by the - TrueType specification regarding pixel placement: - - - The map can be seen as a `grid' placed in the vector plane. - The grid lines are set on integer real coordinates (i.e., on - multiples of 64 in 26.6 fractional notation). - - Each pixel is one `cell' of the grid, and can be `lit' with - any color. Hence, each pixel has a width and a height of - [1.0] units, (i.e., 64 fixed float units). - - ^ Y - | - | The pixel grid with two - | points (not pixels!) - +-----+-----+-----+-----+-----+ at coordinates [0,0] - | | | | | | and [2,2]. - | | | | | | - | | | | |[2,2]| - +-----+-----+-----+-----@-----+ The pixels are the - | | |11111|22222| | grid's cells, and this - | | |11111|22222| | example show the four - | | |11111|22222| | pixels enclosed within - +-----+-----+-----+-----+-----+ the rectangle delimited - | | |33333|44444| | by these two points. - | | |33333|44444| | - | | |33333|44444| | - --+-----+-----@-----+-----+-----+----> X - | | |[0,0]| | | - | | | | | | Note that the numbering - | | | | | | of pixels isn't - +-----+-----+-----+-----+-----+ meaningful here, it's - | | | | | | only used to distinguish - | | | | | | them. - | | | | | | - +-----+-----+-----+-----+-----+ - | - | - - - The `center' of each pixel is always located on a - `half-integer' coordinate, i.e., at -1.5, -0.5, 0.5, 1.5, etc. - - - When drawing a shape, the rasterizer only `lits' a pixel when - its center is placed _within_ the shape. This is important - because an outline point may not be necessarily be on a grid - line. - - - When a pixel center falls on the shape, the pixel is lit too. - - For example, the following graphics show the `lit' pixels - corresponding to the rectangle enclosed by the points: - - [-0.2, 0] and [2.4, 2.7] - - - ^ Y As one can see, the - | newest pixels `1' - | and `2' are now lit, - | because its centers - +-----+-----+-----+-----+--[2.4,2.7] are located at - | | |11111|22222| @ | coordinates - | . | . |11.11|22.22| . | [0.5,2.5] and - | | |11111|22222| | [1.5,2.5], - +-----+-----+-----+-----+-----+ respectively. - | | |33333|44444| | - | . | . |33.33|44.44| . | Note that pixel - | | |33333|44444| | centers are - +-----+-----+-----+-----+-----+ represented with a - | | |55555|66666| | dot in the graphics. - | . | . |55.55|66.66| . | - | | |55555|66666| | - --+-----+----@+-----+-----+-----+----> X - | | [-0.2,0] | | | - | . | . | . | . | . | - | | | | | | Note also that pixel - +-----+-----+-----+-----+-----+ numbering is still - | | | | | | meaningless there. - | . | . | . | . | . | - | | | | | | - +-----+-----+-----+-----+-----+ - | - | - - - 4. Drop-out control - - Sometimes, a stroke is too thin to even contain a single pixel - center. This results in `lost continuity' in the resulting - bitmap, i.e., some unpleasant `holes' or `breaks' in the - rendered shape, which are called a `drop-out'. - - Because a glyph representation uses curves (Bezier arcs), this - case is not easily controllable during the `hinting' of glyph - outlines by the font driver, which means that the rasterizer - must be able to correct these `artefacts'. - - This processing is called `drop-out control', and can be - performed in several modes, defined by the TrueType - specification, and which details do not belong to this document. - However, the important idea is that, in _some_ cases, a pixel - may be lit even if its center isn't part of the shape. - - This case is relatively rare, but is mentioned because it has - consequences of the rendering of maps. More precisely, in the - way an outline's extent is computed (see below). - - --------------------------------------------------------------------- - - -II. Bitmap and pixmap descriptors ---------------------------------- - - The Freetype rasterizer only supports bitmaps and 8-bit pixmaps. - In order to render an outline, a map descriptor must be sent to - its rendering functions, along with a vectorial outline. - - - 1. Bitmap properties - - This section explains how to set up a bitmap descriptor, and how - vector coordinates in the outline plane relate to pixel - positions within the bitmap buffer. - - A bitmap's `raw data' is made of a simple bit buffer where each - bit corresponds to a monochrome pixel. For the sake of - simplicity, the FreeType rasterizer uses the following - conventions to store bitmaps in a buffer: - - - The value 0 is used for `unlit' pixels, usually the - `background' when rendering text. Hence 1 is used for `lit'. - - - Lines are padded to 8 bits, i.e. bytes. A bitmap row thus - takes an integral number of bytes in its buffer. No further - alignment is required. - - (Some systems compress bitmaps by _not_ padding bit rows to - byte boundaries. It is not possible to render into such a - bitmap buffer with FreeType.) - - - In a bitmap buffer byte, the left-most pixel is represented by - the most significant bit (i.e., 0x80). - - The opposite convention is not supported by the FreeType - rasterizer, though it may possibly be implemented too if this - ever comes useful (ask the developers -- for now, nobody did). - - - Increasing offsets within a row correspond to right-most - positions in the bitmap (i.e., byte 1 contains the - 8 bits/pixels that are located on the right of the - 8 bits/pixels of byte 0). - - - A bitmap can be oriented in two ways: - - o If increasing row addresses within the buffer correspond to - lower vertical lines, the bitmap is said to go `down'. This - is, for example, the case of nearly all video RAMs. - - o If increasing row addresses within the buffer correspond to - higher vertical lines, the bitmap is said to go `up'. This - is the case, for example, for OS/2 bitmaps. - - The `direction' of a bitmap is called `flow' to avoid any - confusion. In both cases, the rasterizer ALWAYS matches the - vector coordinate (0,0) with the lower-left corner of the - *lower-left* pixel in the bitmap. - - The following graphics illustrate these ideas: - - - - Y ^ - | A `down-flow' bitmap. - +--+--+--+--+--+--+--+--+ On the left is each - | | | | | | | | | row's number and its - 0: 0 | | | | | | | | | offset in the bitmap - +--+--+--+--+--+--+--+--+ buffer (where `w' is - | | | | | | | | | the width, in bytes, - 1: w | | | | | | | | | of a single bitmap - +--+--+--+--+--+--+--+--+ row). Note that the - | | | | | | | | | origin is located at - 2: 2*w | | | | | | | | | the lower left, i.e., - +--+--+--+--+--+--+--+--+ near the leftmost bit - | | | | | | | | | of the last bitmap - 3: 3*w | | | | | | | | | row. - -@--+--+--+--+--+--+--+-----> X - |[0,0] - - - - Y ^ - | An `up-flow' bitmap. - +--+--+--+--+--+--+--+--+ On the left is each - | | | | | | | | | row's number and its - 3: 3*w | | | | | | | | | offset in the bitmap - +--+--+--+--+--+--+--+--+ buffer (where `w' is - | | | | | | | | | the width, in bytes, - 2: 2*w | | | | | | | | | of a single bitmap - +--+--+--+--+--+--+--+--+ row). Note that the - | | | | | | | | | origin is located at - 1: w | | | | | | | | | the lower left, i.e., - +--+--+--+--+--+--+--+--+ near the first bit in - | | | | | | | | | the buffer. - 0: 0 | | | | | | | | | The first buffer bit - -@--+--+--+--+--+--+--+-----> X corresponds to the - |[0,0] rectangle [0,0]-[1,1] - in the vector plane. - - - 2. Bitmap descriptors - - Now that you understand all these details, a bitmap can be - described to the rasterizer engine through a map, which - structure must be set up by client application: - - struct TT_Raster_Map_ - { - int rows; /* number of rows */ - int cols; /* number of columns (bytes) per row */ - int width; /* number of pixels per line */ - int flow; /* bitmap orientation */ - - void* bitmap; /* bit/pixmap buffer */ - long size; /* bit/pixmap size in bytes */ - }; - typedef struct TT_Raster_Map_ TT_Raster_Map; - - where the fields stand for: - - rows: - The number of rows within the bitmap buffer. - - cols: - The number of columns, i.e. bytes per row within the - buffer. It corresponds to the `w' value used in the above - graphics. - - width: - The number of pixels (i.e. bits) per row in the buffer. The - rasterizer always clips its rendering to the bit width - specified in this field, even if the `cols' fields - corresponds to a larger width. - - flow: - The bitmap flow. Use the constants TT_Flow_Up and - TT_Flow_Down exclusively for this field. - - bitmap: - A typeless pointer to the bit buffer. - - size: - The total size of the bit buffer in bytes. This is not used - directly by the rasterizer, so applications can use it. - - Note that the `cols' field should always be bigger than the - value of `width' multiplied by 8. The rasterizer clips the - generated bitmap to the `width' first bits in a row. - - Note also that it is of course allowed to create, for example, a - Windows or X11 bitmap through a normal system-specific API call, - using a TT_Raster_Map that describes it to the rasterizer. It - is thus possible to draw directly into such OS specific - structures. - - - IMPORTANT: ***************************************************** - - When rendering a bitmap, the rasterizer always OR-es the shape - on the target bitmap. It is thus possible to draw several - shapes into a single surface which successive calls to the - render functions. - - **************************************************************** - - - 3. Pixmap properties - - The rasterizer only supports 8-bit pixmaps, where one pixel is - represented by a single byte. They must conform to the - following rules: - - - A 5-entries palette is used to generate an outline's pixmap in - the buffer. They correspond to: - - palette[0] -> background - palette[1] -> `light' - palette[2] -> `medium' - palette[3] -> `dark' - palette[4] -> foreground - - where the terms `light', `medium', and `dark' correspond to - intermediate values between the first (background) and last - (foreground) entry. - - The upcoming FreeType 2.0 will feature an additional - anti-aliasing logic with a 17-entries palette. - - - Lines are padded to 32 bits, i.e. 4 bytes. A pixmap row thus - takes a multiple of 4 bytes in its buffer. - - - Increasing offsets within a row correspond to right-most - positions in the bitmap (i.e., byte/pixel 1 is to the right of - byte/pixel 0). - - - A pixmap can be oriented in two ways, following the same rules - as a bitmap regarding its flow. - - - IMPORTANT: ***************************************************** - - In order to improve performance when rendering large outlines - with anti-aliasing, the rasterizer draws pixels in runs of - 4-bytes ONLY when at least one of their `colour' isn't 0 - (background). - - This means that you should ALWAYS CLEAR the pixmap buffer before - calling the rendering function, you may otherwise experience - ugly artefacts, which are possibly left from a previous - rendering! - - In general, it is not possible to do colour compositing with the - FreeType rasterizer (compositing is if you want to superpose a - transparent coloured layer on top of an image). This is mainly - due to the fact that: - - - There are too many pixel formats to support. - - - There is not a single portable way to do it anyway. - - - It really is a graphics processing question, not one that - should be solved by a text rendering engine. - - **************************************************************** - - - 4. Pixmap descriptors - - Pixmaps use the same descriptor structure as bitmaps, with a few - differences in interpretation: - - - The `cols' field is used to indicate the number of _bytes_ in - a pixmap row. It must thus be a multiple of 4! - - - The rasterizer clips the outline to the first `width' - pixels/width within each buffer row. - - As usual, it should be possible to use a system-specific pixmap - and render directly into it, as long as you set up a descriptor - for it. - - -------------------------------------------------------------------------- - - -III. Rendering an outline -------------------------- - - Now that you understand how the rasterizer sees the target bitmaps - and pixmaps it renders to, this section will explain how the - rendering eventually happen. - - - 1. Outline coordinates and extents - - Let's first consider the case where we're rendering text - directly into a huge single bitmap. To do that, we simply - translate each glyph outline before calling the rasterizer. - Here the roadmap: - - - Vectorial coordinates [0,0] are mapped to the lower left - `corner' (in the grid) of the lower left pixel in the bitmap - (whatever its flow is). - - - When the glyph loader returns an outline, the latter is placed - so that the coordinate [0,0] corresponds to the current cursor - position. - - This means that: - - - If we use our own cursor (cx,cy) within the bitmap during text - rendering, we must translate the outline to its position - before rendering it, e.g. with - - TT_Translate_Outline( outline, cx, cy ) - - (and the cursor position must be incremented after rendering - each glyph). - - - Before translation (i.e., when it is returned by the glyph - loader), the glyph outline doesn't necessarily lie on any of - the coordinate axes, nor is it limited to the first quadrant - (i.e., x>0 and y>0 is not true in general). - - Its extent can be computed with the function - TT_Get_Outline_BBox(), which returns the minimum and maximum - values of its X and Y point coordinates (in 26.6 format, of - course). - - - 2. Computing an outline's dimensions in pixels - - In many cases, however, it is much better to render individual - glyph bitmaps, then cache them with appropriate metrics in order - to render text much more quickly at a given point size. - - To be able to render the smallest possible bitmap, the exact - outline's extent dimensions in pixel are required. Again a - roadmap: - - - Get the outline's bounding box in vector coordinates: - - Simply call the TT_Get_Outline_BBox() function which will - return the values of xMin, yMin, xMax, and yMax in vector - (i.e. fractional) coordinates. - - - Grid-fit the bounding box: - - Because of the way pixels are lit in the bitmaps relative to - the position of their `centers' within the shape (see - section I), it is necessary to align the values of xMin, xMax, - yMin, and yMax to the pixel grid in order to compute the width - and height of the resulting bitmap. This can be done with: - - xMin = FLOOR ( xMin ); with FLOOR(x) == (x & -64) - xMax = CEILING( xMax ); CEILING(x) == ((x+63) & -64) - yMin = FLOOR ( yMin ); - yMax = CEILING( yMax ); - - The extents in pixels can then be simply computed as: - - pixel_width = (xMax - xMin) / 64; - pixel_height = (yMax - yMin) / 64; - - Note that because of drop-out control, and because the - bounding box computed currently includes all Bezier control - points from the outline, the bitmap may be slightly larger - than necessary in some cases. - - Some improvements are planned for FreeType 2.0; for now, you - should consider that finding the `exact' bitmap bounding box - requires to scan all `borders' to detect null columns or rows. - However, the values are right in most cases. - - NOTE: It seems that in some *rare* cases, which relate to - weird drop-out control situations, the above dimensions - are not enough to store all bits from the outline (there - are one or more bits `cut' on the edge). - - This being hard to study (it only appears in very poorly - hinted fonts), we leave this problem to FreeType 2.0. - - - Create/setup a bitmap with the computed dimensions. DON'T - FORGET TO CLEAR ITS BUFFER TOO! - - - Translate the outline to stick within the bitmap space. This - is done easily by translating it by (-xMin,-yMin), where you - should ALWAYS USE THE GRID-FITTED VALUES computed above for - xMin and yMin: - - TT_Translate_Outline( outline, -xMin, -yMin ); - - - IMPORTANT: *************************************************** - - For technical reasons, you should never translate a HINTED - outline by a non-integer vector (i.e., a vector which - coordinates aren't multiples of 64)! This would CERTAINLY - completely RUIN the delicate HINTING of the glyph, and will - result probably in pure GARBAGE at small point sizes. - - Of course, if you're not interested in hinting, like when - displaying rotated text, you can ignore this rule and - translate to any position freely. - - ************************************************************** - - - Render the bitmap (or pixmap). - - DON'T FORGET TO STORE THE GRID-FITTED xMin and yMin WITH THE - BITMAP! This will allow you later to place it correctly - relative to your cursor position. - - - Here's some example pseudo code: - - { - ... load the glyph ... - - TT_Outline outline; - TT_BBox bbox; - TT_Raster_Map bitmap; - - - /* get the outline */ - TT_Get_Glyph_Outline( glyph, &outline ); - - /* compute its extent */ - TT_Get_Outline_BBox( &outline, &bbox ); - - /* Grid-fit it */ - bbox.xMin &= -64; - bbox.xMax = ( bbox.xMax + 63 ) & -64; - bbox.yMin &= -64; - bbox.yMax = ( bbox.yMax + 63 ) & -64; - - /* compute pixel dimensions */ - width = (bbox.xMax - bbox.xMin) / 64; - height = (bbox.yMax - bbox.yMin) / 64; - - /* set up bitmap */ - bitmap.rows = height; - bitmap.width = width; - bitmap.cols = (width + 7) / 8; - bitmap.size = bitmap.rows * bitmap.cols; - bitmap.bitmap = malloc( bitmap.size ); - if ( !bitmap.bitmap ) - return error_memory... - - /* clear the bitmap buffer! */ - memset( bitmap.bitmap, 0, bitmap.size ); - - /* translate outline */ - TT_Translate_Outline( &outline, -bbox.xMin, -bbox.yMin ); - - /* render it within the bitmap */ - TT_Get_Outline_Bitmap( engine, &outline, &bitmap ); - - /* We're done; don't forget to save bbox.xMin and */ - /* bbox.yMin to adjust the bitmap position when */ - /* rendering text with it */ - - ... - } - - - 3. The case of transformed/rotated glyphs: - - You may want to apply a transformation other than a translation - to your glyph outlines before rendering them. For example, a - simple slant to synthesize italics, or a slight rotation. - - In all cases, it is possible to render individual glyph bitmaps. - Just make sure to follow the same process AFTER you have - transformed you outline! - - DON'T FORGET THAT YOU NEED TO RE-COMPUTE THE BBOX TO GET THE - CORRECT PIXEL DIMENSIONS AFTER A TRANSFORMATION. - - --------------------------------------------------------------------- - - -IV. Anti-aliasing palette and other concerns - - When rendering pixmaps, using the TT_Get_Outline_Pixmap() or - TT_Get_Glyph_Pixmap() functions, the rasterizer uses a 5-entries - palette of 8-bit deep `colors'. - - By default, this palette is set to ( 0, 1, 2, 3, 4 ), but one can - change it to suit your needs with TT_Set_Raster_Palette(). - - While in bitmap mode, it simply OR-es the pixel values to the - target bitmap that has been passed to TT_Get_Outline_Bitmap(). - - For pixmaps it simply writes directly the palette entries - corresponding to the `color' of the `lit' pixels it has computed. - This means that it is NOT POSSIBLE to render text in a single - pixmap with multiple calls to TT_Get_Outline_Pixmaps() within the - same target! - - The reason is that `gray' pixels of two distinct outlines are not - `added' when they overlap (the operation called 'compositing'), as - it could be expected by applications. - - The following graphic shows this effect when rendering two - overlapping anti-aliased shapes: - - - *** *** - .** .** - ** **. **. ** - .*. .*.. .*..*. - .*. + .*. = ---> ..*. - .*. ** | .*. ** - ** | ** - **. | **. - *** | *** - | - - missing black pixel after second - rendering... - - - There is no simple way to perform a composition within the - rasterizer. This would not be portable; moreover, it would be - extremely slow if it is too general. This operation is thus left - to client applications which can use their own system-specific API - for transparently blitting the glyph pixmaps into a surface to - form text. - - NOTE: - - If your system doesn't support transparent/alpha blits, you can - still have a look at the source file `freetype/test/display.c'. - It uses a large pixmap, with a special palette trick to render all - text quickly, then convert everything to `real' colors for - display. - - --------------------------------------------------------------------- - - -Conclusion ----------- - - We've seen how the FreeType rasterizer sees bitmaps through - descriptors, as well as the mapping which exists between the - vector coordinate space and the pixel position space. - - You should now be able to render outlines into bitmaps and pixmaps - while applying transformations like translation, slanting, or - rotation. Don't forget a few rules, however: - - - Always clear the bitmap/pixmap buffer before rendering (unless - you want to render several glyphs in a single _bitmap_; it won't - work on a pixmap). - - - A pixmap `cols' field, i.e. the size in bytes of each rows, must - be a multiple of 4. - - - Never translate a hinted outline by a non-integer vector if you - want to preserve the hints (i.e., the vector's coordinates must - be multiples of 64). - - - Finally, don't expect the rasterizer to composite transparent - `grays' for you in a single target pixmap through multiple - calls. - - ---- end of bitmaps.txt --- |