⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ftraster.c

📁 Qt/Embedded是一个多平台的C++图形用户界面应用程序框架
💻 C
📖 第 1 页 / 共 5 页
字号:
                                    /* exactly on a scanline.  Allows    */                                    /* removal of doublets               */    PProfile  cur_prof;             /* current profile                   */    PProfile  start_prof;           /* head of linked list of profiles   */    PProfile  first_prof;           /* contour's first profile in case   */                                    /* of impact                         */    TDirection  state;              /* rendering state */    FT_Bitmap target;          /* description of target bit/pixmap */    int       trace_bit;            /* current offset in target bitmap    */    int       trace_pix;            /* current offset in target pixmap    */    int       trace_incr;           /* sweep's increment in target bitmap */    /* dispatch variables */    Raster_Render     render;    int       scale_shift;      /* == 0  for bitmaps           */                                /* == 1  for 5-levels pixmaps  */                                /* == 2  for 17-levels pixmaps */    int       scale_delta;      /* ras.precision_half for bitmaps */                                /* 0 for pixmaps                  */    char      dropout_mode;     /* current drop_out control method */    char      second_pass;      /* indicates whether 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.                  */    char      flipped;          /* this flag is set during the rendering to */                                /* indicate the second pass.                */    TBand     band_stack[16];   /* band stack used for sub-banding */    int       band_top;         /* band stack top                  */    TPoint    arcs[2 * MaxBezier + 1];  /* The Bezier stack */  };#ifdef DEBUG_RASTER  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    Pset                                                               */  /*                                                                       */  /* <Description>                                                         */  /*    Used for debugging only.  Plots a point in VRAM during rendering   */  /*    (not afterwards).                                                  */  /*                                                                       */  /* <Note>                                                                */  /*    This procedure relies on the value of cProfile->start, which may   */  /*    not be set when Pset() is called sometimes.  This will usually     */  /*    result in a dot plotted on the first screen scanline (far away     */  /*    from its original position).                                       */  /*                                                                       */  /*    This `feature' reflects nothing wrong in the current               */  /*    implementation, and the bitmap is rendered correctly, so don't     */  /*    panic if you see `flying' dots in debugging mode.                  */  /*                                                                       */  static  void  Pset( RAS_ARG )  {    long  o;    long  x;    x = ras.cursor[-1];    switch ( ras.cur_prof->flow )    {    case FT_Flow_Up:      o = Vio_ScanLineWidth *         ( ras.cursor - ras.cur_prof->offset + ras.cur_prof->start ) +         ( x / (PRECISION * 8) );      break;    case FT_Flow_Down:      o = Vio_ScanLineWidth *         ( ras.cur_prof->start - ras.cursor + ras.cur_prof->offset ) +         ( x / (PRECISION * 8) );      break;    }    if ( o > 0 )      Vio[o] |= (unsigned)0x80 >> ( (x/PRECISION) & 7 );  }  static  void  Clear_Band( RAS_ARG_ TScan  y1,                             TScan  y2 )  {    MEM_Set( Vio + y1*Vio_ScanLineWidth, (y2-y1+1)*Vio_ScanLineWidth, 0 );  }#endif /* DEBUG_RASTER */  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    Set_High_Precision                                                 */  /*                                                                       */  /* <Description>                                                         */  /*    Sets precision variables according to the parameter flag.          */  /*                                                                       */  /* <Input>                                                               */  /*    High :: Set to True for high precision (typically for ppem < 18),  */  /*    false otherwise.                                                   */  /*                                                                       */  static  void  Set_High_Precision( RAS_ARG_  char  High )  {#ifdef FT_RASTER_CONSTANT_PRECISION    (void)High;    (void)&ras;#else    if ( High )    {      ras.precision_bits   = 10;      ras.precision_step   = 128;      ras.precision_jitter = 24;    }    else    {      ras.precision_bits   = 6;      ras.precision_step   = 32;      ras.precision_jitter = 2;    }    ras.precision       = 1L << ras.precision_bits;    ras.precision_half  = ras.precision / 2;    ras.precision_shift = ras.precision_bits - INPUT_BITS;    ras.precision_mask  = -ras.precision;#endif  }  /*************************************************************************/  /*                                                                       */  /* A simple technical note on how the raster works:                      */  /*                                                                       */  /*   Converting an outline into a bitmap is achieved in several steps    */  /*   which are:                                                          */  /*                                                                       */  /*   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 wether is 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.  Additionaly, 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                                   cursor      */  /*                                                                       */  /*   The top of the profile stack is kept in the `cursor' 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 `extrema' 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 |                     */  /*      _ _ __________________|____________________|                     */  /*                                                                       */  /*                            ^                    ^                     */  /*                            |                    |                     */  /*                       pool_limit        end of render 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.                                    */  /*                                                                       */  /*************************************************************************/  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    New_Profile                                                        */  /*                                                                       */  /* <Description>                                                         */  /*    Creates a new Profile in the render pool.                          */  /*                                                                       */  /* <Input>                                                               */  /*    aState :: The state/orientation of the new profile.                */  /*                                                                       */  /* <Return>                                                              */  /*    SUCCESS or FAILURE.                                                */  /*                                                                       */  static  TResult  New_Profile( RAS_ARG_ TDirection  direction )  {    if ( ras.start_prof == NULL )    {      ras.cur_prof   = (PProfile)ras.cursor; /* current profile          */      ras.start_prof = ras.cur_prof;         /* first profile in pool    */      ras.cursor    += AlignProfileSize;     /* record profile in buffer */    }    /* check for overflow */    if ( ras.cursor >= ras.pool_limit )    {      ras.error = ErrRaster_Overflow;      return FAILURE;    }    /* record profile direction */    switch ( direction )    {    case Ascending:      ras.cur_prof->flow = Flow_Up;      break;    case Descending:      ras.cur_prof->flow = Flow_Down;      break;    default:      ras.error = ErrRaster_Invalid_Map;      return FAILURE;    }    /* initialize a few fields */    {      PProfile  cur = ras.cur_prof;      cur->start  = 0;            /* current start scanline          */      cur->height = 0;            /* current height                  */      cur->offset = ras.cursor;   /* address of first coordinate     */      cur->link   = (PProfile)0;  /* link to next profile in pool    */      cur->next   = (PProfile)0;  /* link to next profile in contour */    }    /* record the first profile in a contour */    if ( ras.first_prof == NULL )      ras.first_prof = ras.cur_prof;    ras.state  = direction;    ras.fresh  = TRUE;       /* this profile has no coordinates yet */    ras.joint  = FALSE;    return SUCCESS;  }  /*************************************************************************/  /*                                                                       */  /* <Function>                                                            */  /*    End_Profile                                                        */  /*                                                                       */  /* <Description>                                                         */  /*    Finalizes the current Profile and computes its height.  If it is   */  /*    not 0, the profile's fields are updated and a new profile is       */  /*    pushed on top of its coordinates.  Otherwise the current profile   */  /*    is kept and the recording of intersections is restarted.           */  /*                                                                       */  /* <Return>                                                              */  /*    SUCCESS or FAILURE.                                                */  /*                                                                       */  static  TResult  End_Profile( RAS_ARG )  {    int  h;    h = ras.cursor - ras.cur_prof->offset;    if ( h < 0 )    {      /* This error should _never_ occur unless the raster is buggy */      ras.error = ErrRaster_Negative_Height;      return FAILURE;    }    if ( h > 0 )    {      PProfile  old, new;      /* record scanline height in current profile, create a new one */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -