forsyth20121205-174063a80cc13 years agoHistory
3288 lines · 102.6 KB · C
RawDownload
/***************************************************************************//*                                                                         *//*  ftraster.c                                                             *//*                                                                         *//*    The FreeType glyph rasterizer (body).                                *//*                                                                         *//*  Copyright 1996-2001, 2002 by                                           *//*  David Turner, Robert Wilhelm, and Werner Lemberg.                      *//*                                                                         *//*  This file is part of the FreeType project, and may only be used,       *//*  modified, and distributed under the terms of the FreeType project      *//*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     *//*  this file you indicate that you have read the license and              *//*  understand and accept it fully.                                        *//*                                                                         *//***************************************************************************/   /*************************************************************************/  /*                                                                       */  /* This is a rewrite of the FreeType 1.x scan-line converter             */  /*                                                                       */  /*************************************************************************/  #include <ft2build.h>#include "ftraster.h"#include FT_INTERNAL_CALC_H   /* for FT_MulDiv only */    /*************************************************************************/  /*                                                                       */  /* A simple technical note on how the raster works                       */  /* -----------------------------------------------                       */  /*                                                                       */  /*   Converting an outline into a bitmap is achieved in several steps:   */  /*                                                                       */  /*   1 - Decomposing the outline into successive `profiles'.  Each       */  /*       profile is simply an array of scanline intersections on a given */  /*       dimension.  A profile's main attributes are                     */  /*                                                                       */  /*       o its scanline position boundaries, i.e. `Ymin' and `Ymax'.     */  /*                                                                       */  /*       o an array of intersection coordinates for each scanline        */  /*         between `Ymin' and `Ymax'.                                    */  /*                                                                       */  /*       o a direction, indicating whether it was built going `up' or    */  /*         `down', as this is very important for filling rules.          */  /*                                                                       */  /*   2 - Sweeping the target map's scanlines in order to compute segment */  /*       `spans' which are then filled.  Additionally, this pass         */  /*       performs drop-out control.                                      */  /*                                                                       */  /*   The outline data is parsed during step 1 only.  The profiles are    */  /*   built from the bottom of the render pool, used as a stack.  The     */  /*   following graphics shows the profile list under construction:       */  /*                                                                       */  /*     ____________________________________________________________ _ _  */  /*    |         |                   |         |                 |        */  /*    | profile | coordinates for   | profile | coordinates for |-->     */  /*    |    1    |  profile 1        |    2    |  profile 2      |-->     */  /*    |_________|___________________|_________|_________________|__ _ _  */  /*                                                                       */  /*    ^                                                         ^        */  /*    |                                                         |        */  /*  start of render pool                                       top       */  /*                                                                       */  /*   The top of the profile stack is kept in the `top' variable.         */  /*                                                                       */  /*   As you can see, a profile record is pushed on top of the render     */  /*   pool, which is then followed by its coordinates/intersections.  If  */  /*   a change of direction is detected in the outline, a new profile is  */  /*   generated until the end of the outline.                             */  /*                                                                       */  /*   Note that when all profiles have been generated, the function       */  /*   Finalize_Profile_Table() is used to record, for each profile, its   */  /*   bottom-most scanline as well as the scanline above its upmost       */  /*   boundary.  These positions are called `y-turns' because they (sort  */  /*   of) correspond to local extrema.  They are stored in a sorted list  */  /*   built from the top of the render pool as a downwards stack:         */  /*                                                                       */  /*      _ _ _______________________________________                      */  /*                            |                    |                     */  /*                         <--| sorted list of     |                     */  /*                         <--|  extrema scanlines |                     */  /*      _ _ __________________|____________________|                     */  /*                                                                       */  /*                            ^                    ^                     */  /*                            |                    |                     */  /*                         maxBuff           sizeBuff = end of pool      */  /*                                                                       */  /*   This list is later used during the sweep phase in order to          */  /*   optimize performance (see technical note on the sweep below).       */  /*                                                                       */  /*   Of course, the raster detects whether the two stacks collide and    */  /*   handles the situation propertly.                                    */  /*                                                                       */  /*************************************************************************/    /*************************************************************************/  /*************************************************************************/  /**                                                                     **/  /**  CONFIGURATION MACROS                                               **/  /**                                                                     **/  /*************************************************************************/  /*************************************************************************/   /* define DEBUG_RASTER if you want to compile a debugging version */#define xxxDEBUG_RASTER   /* The default render pool size in bytes */#define RASTER_RENDER_POOL  8192   /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */  /* 5-levels anti-aliasing                                                */#ifdef FT_CONFIG_OPTION_5_GRAY_LEVELS#define FT_RASTER_OPTION_ANTI_ALIASING#endif   /* The size of the two-lines intermediate bitmap used */  /* for anti-aliasing, in bytes.                       */#define RASTER_GRAY_LINES  2048    /*************************************************************************/  /*************************************************************************/  /**                                                                     **/  /**  OTHER MACROS (do not change)                                       **/  /**                                                                     **/  /*************************************************************************/  /*************************************************************************/   /*************************************************************************/  /*                                                                       */  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */  /* messages during execution.                                            */  /*                                                                       */#undef  FT_COMPONENT#define FT_COMPONENT  trace_raster  #ifdef _STANDALONE_    /* This macro is used to indicate that a function parameter is unused. */  /* Its purpose is simply to reduce compiler warnings.  Note also that  */  /* simply defining it as `(void)x' doesn't avoid warnings with certain */  /* ANSI compilers (e.g. LCC).                                          */#define FT_UNUSED( x )  (x) = (x)   /* Disable the tracing mechanism for simplicity -- developers can      */  /* activate it easily by redefining these two macros.                  */#ifndef FT_ERROR#define FT_ERROR( x )  do ; while ( 0 )     /* nothing */#endif #ifndef FT_TRACE#define FT_TRACE( x )  do ; while ( 0 )     /* nothing */#endif #define Raster_Err_None          0#define Raster_Err_Not_Ini      -1#define Raster_Err_Overflow     -2#define Raster_Err_Neg_Height   -3#define Raster_Err_Invalid      -4#define Raster_Err_Unsupported  -5  #else /* _STANDALONE_ */  #include FT_INTERNAL_OBJECTS_H#include FT_INTERNAL_DEBUG_H        /* for FT_TRACE() and FT_ERROR() */ #include "rasterrs.h" #define Raster_Err_None         Raster_Err_Ok#define Raster_Err_Not_Ini      Raster_Err_Raster_Uninitialized#define Raster_Err_Overflow     Raster_Err_Raster_Overflow#define Raster_Err_Neg_Height   Raster_Err_Raster_Negative_Height#define Raster_Err_Invalid      Raster_Err_Invalid_Outline#define Raster_Err_Unsupported  Raster_Err_Cannot_Render_Glyph  #endif /* _STANDALONE_ */  #ifndef FT_MEM_SET#define FT_MEM_SET( d, s, c )  ft_memset( d, s, c )#endif    /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is       */  /* typically a small value and the result of a*b is known to fit into */  /* 32 bits.                                                           */#define FMulDiv( a, b, c )  ( (a) * (b) / (c) )   /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */  /* for clipping computations.  It simply uses the FT_MulDiv() function   */  /* defined in `ftcalc.h'.                                                */#define SMulDiv  FT_MulDiv   /* The rasterizer is a very general purpose component; please leave */  /* the following redefinitions there (you never know your target    */  /* environment).                                                    */ #ifndef TRUE#define TRUE   1#endif #ifndef FALSE#define FALSE  0#endif #ifndef NULL#define NULL  (void*)0#endif #ifndef SUCCESS#define SUCCESS  0#endif #ifndef FAILURE#define FAILURE  1#endif  #define MaxBezier  32   /* The maximum number of stacked Bezier curves. */                        /* Setting this constant to more than 32 is a   */                        /* pure waste of space.                         */ #define Pixel_Bits  6   /* fractional bits of *input* coordinates */    /*************************************************************************/  /*************************************************************************/  /**                                                                     **/  /**  SIMPLE TYPE DECLARATIONS                                           **/  /**                                                                     **/  /*************************************************************************/  /*************************************************************************/   typedef int             Int;  typedef unsigned int    UInt;  typedef short           Short;  typedef unsigned short  UShort, *PUShort;  typedef long            Long, *PLong;  typedef unsigned long   ULong;   typedef unsigned char   Byte, *PByte;  typedef char            Bool;   typedef struct  TPoint_  {    Long  x;    Long  y;   } TPoint;    typedef enum  TFlow_  {    Flow_None = 0,    Flow_Up   = 1,    Flow_Down = -1   } TFlow;    /* States of each line, arc, and profile */  typedef enum  TStates_  {    Unknown_State,    Ascending_State,    Descending_State,    Flat_State   } TStates;    typedef struct TProfile_  TProfile;  typedef TProfile*         PProfile;   struct  TProfile_  {    FT_F26Dot6  X;           /* current coordinate during sweep        */    PProfile    link;        /* link to next profile - various purpose */    PLong       offset;      /* start of profile's data in render pool */    int         flow;        /* Profile orientation: Asc/Descending    */    long        height;      /* profile's height in scanlines          */    long        start;       /* profile's starting scanline            */     unsigned    countL;      /* number of lines to step before this    */                             /* profile becomes drawable               */     PProfile    next;        /* next profile in same contour, used     */                             /* during drop-out control                */  };   typedef PProfile   TProfileList;  typedef PProfile*  PProfileList;    /* Simple record used to implement a stack of bands, required */  /* by the sub-banding mechanism                               */  typedef struct  TBand_  {    Short  y_min;   /* band's minimum */    Short  y_max;   /* band's maximum */   } TBand;  #define AlignProfileSize \          ( ( sizeof ( TProfile ) + sizeof ( long ) - 1 ) / sizeof ( long ) )  #ifdef TT_STATIC_RASTER  #define RAS_ARGS       /* void */#define RAS_ARG        /* void */ #define RAS_VARS       /* void */#define RAS_VAR        /* void */ #define FT_UNUSED_RASTER  do ; while ( 0 )  #else /* TT_STATIC_RASTER */  #define RAS_ARGS       TRaster_Instance*  raster,#define RAS_ARG        TRaster_Instance*  raster #define RAS_VARS       raster,#define RAS_VAR        raster #define FT_UNUSED_RASTER  FT_UNUSED( raster )  #endif /* TT_STATIC_RASTER */    typedef struct TRaster_Instance_  TRaster_Instance;    /* prototypes used for sweep function dispatch */  typedef void  Function_Sweep_Init( RAS_ARGS Short*  min,                                Short*  max );   typedef void  Function_Sweep_Span( RAS_ARGS Short       y,                                FT_F26Dot6  x1,                                FT_F26Dot6  x2,                                PProfile    left,                                PProfile    right );   typedef void  Function_Sweep_Step( RAS_ARG );    /* NOTE: These operations are only valid on 2's complement processors */ #define FLOOR( x )    ( (x) & -ras.precision )#define CEILING( x )  ( ( (x) + ras.precision - 1 ) & -ras.precision )#define TRUNC( x )    ( (signed long)(x) >> ras.precision_bits )#define FRAC( x )     ( (x) & ( ras.precision - 1 ) )#define SCALED( x )   ( ( (x) << ras.scale_shift ) - ras.precision_half )   /* Note that I have moved the location of some fields in the */  /* structure to ensure that the most used variables are used */  /* at the top.  Thus, their offset can be coded with less    */  /* opcodes, and it results in a smaller executable.          */   struct  TRaster_Instance_  {    Int       precision_bits;       /* precision related variables         */    Int       precision;    Int       precision_half;    Long      precision_mask;    Int       precision_shift;    Int       precision_step;    Int       precision_jitter;     Int       scale_shift;          /* == precision_shift   for bitmaps    */                                    /* == precision_shift+1 for pixmaps    */     PLong     buff;                 /* The profiles buffer                 */    PLong     sizeBuff;             /* Render pool size                    */    PLong     maxBuff;              /* Profiles buffer size                */    PLong     top;                  /* Current cursor in buffer            */     FT_Error  error;     Int       numTurns;             /* number of Y-turns in outline        */     TPoint*   arc;                  /* current Bezier arc pointer          */     UShort    bWidth;               /* target bitmap width                 */    PByte     bTarget;              /* target bitmap buffer                */    PByte     gTarget;              /* target pixmap buffer                */     Long      lastX, lastY, minY, maxY;     UShort    num_Profs;            /* current number of profiles          */     Bool      fresh;                /* signals a fresh new profile which   */                                    /* 'start' field must be completed     */    Bool      joint;                /* signals that the last arc ended     */                                    /* exactly on a scanline.  Allows      */                                    /* removal of doublets                 */    PProfile  cProfile;             /* current profile                     */    PProfile  fProfile;             /* head of linked list of profiles     */    PProfile  gProfile;             /* contour's first profile in case     */                                    /* of impact                           */     TStates   state;                /* rendering state                     */     FT_Bitmap   target;             /* description of target bit/pixmap    */    FT_Outline  outline;     Long      traceOfs;             /* current offset in target bitmap     */    Long      traceG;               /* current offset in target pixmap     */     Short     traceIncr;            /* sweep's increment in target bitmap  */     Short     gray_min_x;           /* current min x during gray rendering */    Short     gray_max_x;           /* current max x during gray rendering */     /* dispatch variables */     Function_Sweep_Init*  Proc_Sweep_Init;    Function_Sweep_Span*  Proc_Sweep_Span;    Function_Sweep_Span*  Proc_Sweep_Drop;    Function_Sweep_Step*  Proc_Sweep_Step;     Byte      dropOutControl;       /* current drop_out control method     */     Bool      second_pass;          /* indicates wether a horizontal pass  */                                    /* should be performed to control      */                                    /* drop-out accurately when calling    */                                    /* Render_Glyph.  Note that there is   */                                    /* no horizontal pass during gray      */                                    /* rendering.                          */     TPoint    arcs[3 * MaxBezier + 1]; /* The Bezier stack                 */     TBand     band_stack[16];       /* band stack used for sub-banding     */    Int       band_top;             /* band stack top                      */     Int       count_table[256];     /* Look-up table used to quickly count */                                    /* set bits in a gray 2x2 cell         */     void*     memory; #ifdef FT_RASTER_OPTION_ANTI_ALIASING     Byte      grays[5];             /* Palette of gray levels used for     */                                    /* render.                             */     Byte      gray_lines[RASTER_GRAY_LINES];                                /* Intermediate table used to render the   */                                /* graylevels pixmaps.                     */                                /* gray_lines is a buffer holding two      */                                /* monochrome scanlines                    */     Short     gray_width;       /* width in bytes of one monochrome        */                                /* intermediate scanline of gray_lines.    */                                /* Each gray pixel takes 2 bits long there */                        /* The gray_lines must hold 2 lines, thus with size */                       /* in bytes of at least `gray_width*2'.             */ #endif /* FT_RASTER_ANTI_ALIASING */ #if 0    PByte       flags;              /* current flags table                 */    PUShort     outs;               /* current outlines table              */    FT_Vector*  coords;     UShort      nPoints;            /* number of points in current glyph   */    Short       nContours;          /* number of contours in current glyph */#endif   };  #ifdef FT_CONFIG_OPTION_STATIC_RASTER   static TRaster_Instance  cur_ras;#define ras  cur_ras #else #define ras  (*raster) #endif /* FT_CONFIG_OPTION_STATIC_RASTER */

Lines 1–500 of 3288.