< prev index next >

src/java.desktop/share/native/libfreetype/src/raster/ftraster.c

Print this page

        

*** 1,53 **** ! /***************************************************************************/ ! /* */ ! /* ftraster.c */ ! /* */ ! /* The FreeType glyph rasterizer (body). */ ! /* */ ! /* Copyright 1996-2018 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 file can be compiled without the rest of the FreeType engine, by */ ! /* defining the STANDALONE_ macro when compiling it. You also need to */ ! /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ ! /* directory. Typically, you should do something like */ ! /* */ ! /* - copy `src/raster/ftraster.c' (this file) to your current directory */ ! /* */ ! /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your */ ! /* current directory */ ! /* */ ! /* - compile `ftraster' with the STANDALONE_ macro defined, as in */ ! /* */ ! /* cc -c -DSTANDALONE_ ftraster.c */ ! /* */ ! /* The renderer can be initialized with a call to */ ! /* `ft_standard_raster.raster_new'; a bitmap can be generated */ ! /* with a call to `ft_standard_raster.raster_render'. */ ! /* */ ! /* See the comments and documentation in the file `ftimage.h' for more */ ! /* details on how the raster works. */ ! /* */ ! /*************************************************************************/ ! /*************************************************************************/ ! /* */ ! /* This is a rewrite of the FreeType 1.x scan-line converter */ ! /* */ ! /*************************************************************************/ #ifdef STANDALONE_ /* The size in bytes of the render pool used by the scan-line converter */ /* to do all of its work. */ --- 1,53 ---- ! /**************************************************************************** ! * ! * ftraster.c ! * ! * The FreeType glyph rasterizer (body). ! * ! * Copyright (C) 1996-2019 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 file can be compiled without the rest of the FreeType engine, by ! * defining the STANDALONE_ macro when compiling it. You also need to ! * put the files `ftimage.h' and `ftmisc.h' into the $(incdir) ! * directory. Typically, you should do something like ! * ! * - copy `src/raster/ftraster.c' (this file) to your current directory ! * ! * - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your ! * current directory ! * ! * - compile `ftraster' with the STANDALONE_ macro defined, as in ! * ! * cc -c -DSTANDALONE_ ftraster.c ! * ! * The renderer can be initialized with a call to ! * `ft_standard_raster.raster_new'; a bitmap can be generated ! * with a call to `ft_standard_raster.raster_render'. ! * ! * See the comments and documentation in the file `ftimage.h' for more ! * details on how the raster works. ! * ! */ ! /************************************************************************** ! * ! * This is a rewrite of the FreeType 1.x scan-line converter ! * ! */ #ifdef STANDALONE_ /* The size in bytes of the render pool used by the scan-line converter */ /* to do all of its work. */
*** 63,148 **** #else /* !STANDALONE_ */ #include <ft2build.h> #include "ftraster.h" #include FT_INTERNAL_CALC_H /* for FT_MulDiv and FT_MulDiv_No_Round */ ! ! #include "rastpic.h" #endif /* !STANDALONE_ */ ! /*************************************************************************/ ! /* */ ! /* 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 */ ! /* */ ! /* o its drop-out mode */ ! /* */ ! /* 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 properly. */ ! /* */ ! /*************************************************************************/ /*************************************************************************/ /*************************************************************************/ /** **/ --- 63,147 ---- #else /* !STANDALONE_ */ #include <ft2build.h> #include "ftraster.h" #include FT_INTERNAL_CALC_H /* for FT_MulDiv and FT_MulDiv_No_Round */ ! #include FT_OUTLINE_H /* for FT_Outline_Get_CBox */ #endif /* !STANDALONE_ */ ! /************************************************************************** ! * ! * 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 ! * ! * o its drop-out mode ! * ! * 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 properly. ! * ! */ /*************************************************************************/ /*************************************************************************/ /** **/
*** 161,178 **** /** 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_ /* Auxiliary macros for token concatenation. */ --- 160,177 ---- /** 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 raster #ifdef STANDALONE_ /* Auxiliary macros for token concatenation. */
*** 450,462 **** #define FLOOR( x ) ( (x) & -ras.precision ) #define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) #define TRUNC( x ) ( (Long)(x) >> ras.precision_bits ) #define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) ! #define SCALED( x ) ( ( (x) < 0 ? -( -(x) << ras.scale_shift ) \ ! : ( (x) << ras.scale_shift ) ) \ ! - ras.precision_half ) #define IS_BOTTOM_OVERSHOOT( x ) \ (Bool)( CEILING( x ) - x >= ras.precision_half ) #define IS_TOP_OVERSHOOT( x ) \ (Bool)( x - FLOOR( x ) >= ras.precision_half ) --- 449,461 ---- #define FLOOR( x ) ( (x) & -ras.precision ) #define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) #define TRUNC( x ) ( (Long)(x) >> ras.precision_bits ) #define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) ! ! /* scale and shift grid to pixel centers */ ! #define SCALED( x ) ( (x) * ras.precision_scale - ras.precision_half ) #define IS_BOTTOM_OVERSHOOT( x ) \ (Bool)( CEILING( x ) - x >= ras.precision_half ) #define IS_TOP_OVERSHOOT( x ) \ (Bool)( x - FLOOR( x ) >= ras.precision_half )
*** 474,490 **** struct black_TWorker_ { Int precision_bits; /* precision related variables */ Int precision; Int precision_half; ! 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 */ --- 473,486 ---- struct black_TWorker_ { Int precision_bits; /* precision related variables */ Int precision; Int precision_half; ! Int precision_scale; Int precision_step; Int precision_jitter; PLong buff; /* The profiles buffer */ PLong sizeBuff; /* Render pool size */ PLong maxBuff; /* Profiles buffer size */ PLong top; /* Current cursor in buffer */
*** 493,504 **** 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; Long minY, maxY; UShort num_Profs; /* current number of profiles */ --- 489,499 ---- Int numTurns; /* number of Y-turns in outline */ TPoint* arc; /* current Bezier arc pointer */ UShort bWidth; /* target bitmap width */ ! PByte bOrigin; /* target bitmap bottom-left origin */ Long lastX, lastY; Long minY, maxY; UShort num_Profs; /* current number of profiles */
*** 517,528 **** 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 */ /* dispatch variables */ Function_Sweep_Init* Proc_Sweep_Init; --- 512,521 ----
*** 570,591 **** /** **/ /*************************************************************************/ /*************************************************************************/ ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Set_High_Precision */ ! /* */ ! /* <Description> */ ! /* Set precision variables according to param flag. */ ! /* */ ! /* <Input> */ ! /* High :: Set to True for high precision (typically for ppem < 24), */ ! /* false otherwise. */ ! /* */ static void Set_High_Precision( RAS_ARGS Int High ) { /* * `precision_step' is used in `Bezier_Up' to decide when to split a --- 563,585 ---- /** **/ /*************************************************************************/ /*************************************************************************/ ! /************************************************************************** ! * ! * @Function: ! * Set_High_Precision ! * ! * @Description: ! * Set precision variables according to param flag. ! * ! * @Input: ! * High :: ! * Set to True for high precision (typically for ppem < 24), ! * false otherwise. ! */ static void Set_High_Precision( RAS_ARGS Int High ) { /* * `precision_step' is used in `Bezier_Up' to decide when to split a
*** 623,655 **** } FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); ras.precision = 1 << ras.precision_bits; ! ras.precision_half = ras.precision / 2; ! ras.precision_shift = ras.precision_bits - Pixel_Bits; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* New_Profile */ ! /* */ ! /* <Description> */ ! /* Create a new profile in the render pool. */ ! /* */ ! /* <Input> */ ! /* aState :: The state/orientation of the new profile. */ ! /* */ ! /* overshoot :: Whether the profile's unrounded start position */ ! /* differs by at least a half pixel. */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ ! /* profile. */ ! /* */ static Bool New_Profile( RAS_ARGS TStates aState, Bool overshoot ) { if ( !ras.fProfile ) --- 617,651 ---- } FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); ras.precision = 1 << ras.precision_bits; ! ras.precision_half = ras.precision >> 1; ! ras.precision_scale = ras.precision >> Pixel_Bits; } ! /************************************************************************** ! * ! * @Function: ! * New_Profile ! * ! * @Description: ! * Create a new profile in the render pool. ! * ! * @Input: ! * aState :: ! * The state/orientation of the new profile. ! * ! * overshoot :: ! * Whether the profile's unrounded start position ! * differs by at least a half pixel. ! * ! * @Return: ! * SUCCESS on success. FAILURE in case of overflow or of incoherent ! * profile. ! */ static Bool New_Profile( RAS_ARGS TStates aState, Bool overshoot ) { if ( !ras.fProfile )
*** 704,728 **** return SUCCESS; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* End_Profile */ ! /* */ ! /* <Description> */ ! /* Finalize the current profile. */ ! /* */ ! /* <Input> */ ! /* overshoot :: Whether the profile's unrounded end position differs */ ! /* by at least a half pixel. */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ ! /* */ static Bool End_Profile( RAS_ARGS Bool overshoot ) { Long h; --- 700,725 ---- return SUCCESS; } ! /************************************************************************** ! * ! * @Function: ! * End_Profile ! * ! * @Description: ! * Finalize the current profile. ! * ! * @Input: ! * overshoot :: ! * Whether the profile's unrounded end position differs ! * by at least a half pixel. ! * ! * @Return: ! * SUCCESS on success. FAILURE in case of overflow or incoherency. ! */ static Bool End_Profile( RAS_ARGS Bool overshoot ) { Long h;
*** 776,800 **** return SUCCESS; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Insert_Y_Turn */ ! /* */ ! /* <Description> */ ! /* Insert a salient into the sorted list placed on top of the render */ ! /* pool. */ ! /* */ ! /* <Input> */ ! /* New y scanline position. */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success. FAILURE in case of overflow. */ ! /* */ static Bool Insert_Y_Turn( RAS_ARGS Int y ) { PLong y_turns; Int n; --- 773,797 ---- return SUCCESS; } ! /************************************************************************** ! * ! * @Function: ! * Insert_Y_Turn ! * ! * @Description: ! * Insert a salient into the sorted list placed on top of the render ! * pool. ! * ! * @Input: ! * New y scanline position. ! * ! * @Return: ! * SUCCESS on success. FAILURE in case of overflow. ! */ static Bool Insert_Y_Turn( RAS_ARGS Int y ) { PLong y_turns; Int n;
*** 832,852 **** return SUCCESS; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Finalize_Profile_Table */ ! /* */ ! /* <Description> */ ! /* Adjust all links in the profiles list. */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success. FAILURE in case of overflow. */ ! /* */ static Bool Finalize_Profile_Table( RAS_ARG ) { UShort n; PProfile p; --- 829,849 ---- return SUCCESS; } ! /************************************************************************** ! * ! * @Function: ! * Finalize_Profile_Table ! * ! * @Description: ! * Adjust all links in the profiles list. ! * ! * @Return: ! * SUCCESS on success. FAILURE in case of overflow. ! */ static Bool Finalize_Profile_Table( RAS_ARG ) { UShort n; PProfile p;
*** 892,917 **** return SUCCESS; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Split_Conic */ ! /* */ ! /* <Description> */ ! /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */ ! /* stack. */ ! /* */ ! /* <Input> */ ! /* None (subdivided Bezier is taken from the top of the stack). */ ! /* */ ! /* <Note> */ ! /* This routine is the `beef' of this component. It is _the_ inner */ ! /* loop that should be optimized to hell to get the best performance. */ ! /* */ static void Split_Conic( TPoint* base ) { Long a, b; --- 889,914 ---- return SUCCESS; } ! /************************************************************************** ! * ! * @Function: ! * Split_Conic ! * ! * @Description: ! * Subdivide one conic Bezier into two joint sub-arcs in the Bezier ! * stack. ! * ! * @Input: ! * None (subdivided Bezier is taken from the top of the stack). ! * ! * @Note: ! * This routine is the `beef' of this component. It is _the_ inner ! * loop that should be optimized to hell to get the best performance. ! */ static void Split_Conic( TPoint* base ) { Long a, b;
*** 931,954 **** /* hand optimized. gcc doesn't seem to be too good at common */ /* expression substitution and instruction scheduling ;-) */ } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Split_Cubic */ ! /* */ ! /* <Description> */ ! /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */ ! /* Bezier stack. */ ! /* */ ! /* <Note> */ ! /* This routine is the `beef' of the component. It is one of _the_ */ ! /* inner loops that should be optimized like hell to get the best */ ! /* performance. */ ! /* */ static void Split_Cubic( TPoint* base ) { Long a, b, c, d; --- 928,951 ---- /* hand optimized. gcc doesn't seem to be too good at common */ /* expression substitution and instruction scheduling ;-) */ } ! /************************************************************************** ! * ! * @Function: ! * Split_Cubic ! * ! * @Description: ! * Subdivide a third-order Bezier arc into two joint sub-arcs in the ! * Bezier stack. ! * ! * @Note: ! * This routine is the `beef' of the component. It is one of _the_ ! * inner loops that should be optimized like hell to get the best ! * performance. ! */ static void Split_Cubic( TPoint* base ) { Long a, b, c, d;
*** 973,1007 **** base[4].y = b = ( b + c + 1 ) >> 1; base[3].y = ( a + b + 1 ) >> 1; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Line_Up */ ! /* */ ! /* <Description> */ ! /* Compute the x-coordinates of an ascending line segment and store */ ! /* them in the render pool. */ ! /* */ ! /* <Input> */ ! /* x1 :: The x-coordinate of the segment's start point. */ ! /* */ ! /* y1 :: The y-coordinate of the segment's start point. */ ! /* */ ! /* x2 :: The x-coordinate of the segment's end point. */ ! /* */ ! /* y2 :: The y-coordinate of the segment's end point. */ ! /* */ ! /* miny :: A lower vertical clipping bound value. */ ! /* */ ! /* maxy :: An upper vertical clipping bound value. */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success, FAILURE on render pool overflow. */ ! /* */ static Bool Line_Up( RAS_ARGS Long x1, Long y1, Long x2, Long y2, --- 970,1010 ---- base[4].y = b = ( b + c + 1 ) >> 1; base[3].y = ( a + b + 1 ) >> 1; } ! /************************************************************************** ! * ! * @Function: ! * Line_Up ! * ! * @Description: ! * Compute the x-coordinates of an ascending line segment and store ! * them in the render pool. ! * ! * @Input: ! * x1 :: ! * The x-coordinate of the segment's start point. ! * ! * y1 :: ! * The y-coordinate of the segment's start point. ! * ! * x2 :: ! * The x-coordinate of the segment's end point. ! * ! * y2 :: ! * The y-coordinate of the segment's end point. ! * ! * miny :: ! * A lower vertical clipping bound value. ! * ! * maxy :: ! * An upper vertical clipping bound value. ! * ! * @Return: ! * SUCCESS on success, FAILURE on render pool overflow. ! */ static Bool Line_Up( RAS_ARGS Long x1, Long y1, Long x2, Long y2,
*** 1112,1146 **** ras.top = top; return SUCCESS; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Line_Down */ ! /* */ ! /* <Description> */ ! /* Compute the x-coordinates of an descending line segment and store */ ! /* them in the render pool. */ ! /* */ ! /* <Input> */ ! /* x1 :: The x-coordinate of the segment's start point. */ ! /* */ ! /* y1 :: The y-coordinate of the segment's start point. */ ! /* */ ! /* x2 :: The x-coordinate of the segment's end point. */ ! /* */ ! /* y2 :: The y-coordinate of the segment's end point. */ ! /* */ ! /* miny :: A lower vertical clipping bound value. */ ! /* */ ! /* maxy :: An upper vertical clipping bound value. */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success, FAILURE on render pool overflow. */ ! /* */ static Bool Line_Down( RAS_ARGS Long x1, Long y1, Long x2, Long y2, --- 1115,1155 ---- ras.top = top; return SUCCESS; } ! /************************************************************************** ! * ! * @Function: ! * Line_Down ! * ! * @Description: ! * Compute the x-coordinates of an descending line segment and store ! * them in the render pool. ! * ! * @Input: ! * x1 :: ! * The x-coordinate of the segment's start point. ! * ! * y1 :: ! * The y-coordinate of the segment's start point. ! * ! * x2 :: ! * The x-coordinate of the segment's end point. ! * ! * y2 :: ! * The y-coordinate of the segment's end point. ! * ! * miny :: ! * A lower vertical clipping bound value. ! * ! * maxy :: ! * An upper vertical clipping bound value. ! * ! * @Return: ! * SUCCESS on success, FAILURE on render pool overflow. ! */ static Bool Line_Down( RAS_ARGS Long x1, Long y1, Long x2, Long y2,
*** 1163,1193 **** /* A function type describing the functions used to split Bezier arcs */ typedef void (*TSplitter)( TPoint* base ); ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Bezier_Up */ ! /* */ ! /* <Description> */ ! /* Compute the x-coordinates of an ascending Bezier arc and store */ ! /* them in the render pool. */ ! /* */ ! /* <Input> */ ! /* degree :: The degree of the Bezier arc (either 2 or 3). */ ! /* */ ! /* splitter :: The function to split Bezier arcs. */ ! /* */ ! /* miny :: A lower vertical clipping bound value. */ ! /* */ ! /* maxy :: An upper vertical clipping bound value. */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success, FAILURE on render pool overflow. */ ! /* */ static Bool Bezier_Up( RAS_ARGS Int degree, TSplitter splitter, Long miny, Long maxy ) --- 1172,1206 ---- /* A function type describing the functions used to split Bezier arcs */ typedef void (*TSplitter)( TPoint* base ); ! /************************************************************************** ! * ! * @Function: ! * Bezier_Up ! * ! * @Description: ! * Compute the x-coordinates of an ascending Bezier arc and store ! * them in the render pool. ! * ! * @Input: ! * degree :: ! * The degree of the Bezier arc (either 2 or 3). ! * ! * splitter :: ! * The function to split Bezier arcs. ! * ! * miny :: ! * A lower vertical clipping bound value. ! * ! * maxy :: ! * An upper vertical clipping bound value. ! * ! * @Return: ! * SUCCESS on success, FAILURE on render pool overflow. ! */ static Bool Bezier_Up( RAS_ARGS Int degree, TSplitter splitter, Long miny, Long maxy )
*** 1296,1326 **** ras.arc -= degree; return SUCCESS; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Bezier_Down */ ! /* */ ! /* <Description> */ ! /* Compute the x-coordinates of an descending Bezier arc and store */ ! /* them in the render pool. */ ! /* */ ! /* <Input> */ ! /* degree :: The degree of the Bezier arc (either 2 or 3). */ ! /* */ ! /* splitter :: The function to split Bezier arcs. */ ! /* */ ! /* miny :: A lower vertical clipping bound value. */ ! /* */ ! /* maxy :: An upper vertical clipping bound value. */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success, FAILURE on render pool overflow. */ ! /* */ static Bool Bezier_Down( RAS_ARGS Int degree, TSplitter splitter, Long miny, Long maxy ) --- 1309,1343 ---- ras.arc -= degree; return SUCCESS; } ! /************************************************************************** ! * ! * @Function: ! * Bezier_Down ! * ! * @Description: ! * Compute the x-coordinates of an descending Bezier arc and store ! * them in the render pool. ! * ! * @Input: ! * degree :: ! * The degree of the Bezier arc (either 2 or 3). ! * ! * splitter :: ! * The function to split Bezier arcs. ! * ! * miny :: ! * A lower vertical clipping bound value. ! * ! * maxy :: ! * An upper vertical clipping bound value. ! * ! * @Return: ! * SUCCESS on success, FAILURE on render pool overflow. ! */ static Bool Bezier_Down( RAS_ARGS Int degree, TSplitter splitter, Long miny, Long maxy )
*** 1345,1373 **** arc[0].y = -arc[0].y; return result; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Line_To */ ! /* */ ! /* <Description> */ ! /* Inject a new line segment and adjust the Profiles list. */ ! /* */ ! /* <Input> */ ! /* x :: The x-coordinate of the segment's end point (its start point */ ! /* is stored in `lastX'). */ ! /* */ ! /* y :: The y-coordinate of the segment's end point (its start point */ ! /* is stored in `lastY'). */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ ! /* profile. */ ! /* */ static Bool Line_To( RAS_ARGS Long x, Long y ) { /* First, detect a change of direction */ --- 1362,1392 ---- arc[0].y = -arc[0].y; return result; } ! /************************************************************************** ! * ! * @Function: ! * Line_To ! * ! * @Description: ! * Inject a new line segment and adjust the Profiles list. ! * ! * @Input: ! * x :: ! * The x-coordinate of the segment's end point (its start point ! * is stored in `lastX'). ! * ! * y :: ! * The y-coordinate of the segment's end point (its start point ! * is stored in `lastY'). ! * ! * @Return: ! * SUCCESS on success, FAILURE on render pool overflow or incorrect ! * profile. ! */ static Bool Line_To( RAS_ARGS Long x, Long y ) { /* First, detect a change of direction */
*** 1439,1471 **** return SUCCESS; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Conic_To */ ! /* */ ! /* <Description> */ ! /* Inject a new conic arc and adjust the profile list. */ ! /* */ ! /* <Input> */ ! /* cx :: The x-coordinate of the arc's new control point. */ ! /* */ ! /* cy :: The y-coordinate of the arc's new control point. */ ! /* */ ! /* x :: The x-coordinate of the arc's end point (its start point is */ ! /* stored in `lastX'). */ ! /* */ ! /* y :: The y-coordinate of the arc's end point (its start point is */ ! /* stored in `lastY'). */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ ! /* profile. */ ! /* */ static Bool Conic_To( RAS_ARGS Long cx, Long cy, Long x, Long y ) --- 1458,1494 ---- return SUCCESS; } ! /************************************************************************** ! * ! * @Function: ! * Conic_To ! * ! * @Description: ! * Inject a new conic arc and adjust the profile list. ! * ! * @Input: ! * cx :: ! * The x-coordinate of the arc's new control point. ! * ! * cy :: ! * The y-coordinate of the arc's new control point. ! * ! * x :: ! * The x-coordinate of the arc's end point (its start point is ! * stored in `lastX'). ! * ! * y :: ! * The y-coordinate of the arc's end point (its start point is ! * stored in `lastY'). ! * ! * @Return: ! * SUCCESS on success, FAILURE on render pool overflow or incorrect ! * profile. ! */ static Bool Conic_To( RAS_ARGS Long cx, Long cy, Long x, Long y )
*** 1556,1592 **** Fail: return FAILURE; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Cubic_To */ ! /* */ ! /* <Description> */ ! /* Inject a new cubic arc and adjust the profile list. */ ! /* */ ! /* <Input> */ ! /* cx1 :: The x-coordinate of the arc's first new control point. */ ! /* */ ! /* cy1 :: The y-coordinate of the arc's first new control point. */ ! /* */ ! /* cx2 :: The x-coordinate of the arc's second new control point. */ ! /* */ ! /* cy2 :: The y-coordinate of the arc's second new control point. */ ! /* */ ! /* x :: The x-coordinate of the arc's end point (its start point is */ ! /* stored in `lastX'). */ ! /* */ ! /* y :: The y-coordinate of the arc's end point (its start point is */ ! /* stored in `lastY'). */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ ! /* profile. */ ! /* */ static Bool Cubic_To( RAS_ARGS Long cx1, Long cy1, Long cx2, Long cy2, --- 1579,1621 ---- Fail: return FAILURE; } ! /************************************************************************** ! * ! * @Function: ! * Cubic_To ! * ! * @Description: ! * Inject a new cubic arc and adjust the profile list. ! * ! * @Input: ! * cx1 :: ! * The x-coordinate of the arc's first new control point. ! * ! * cy1 :: ! * The y-coordinate of the arc's first new control point. ! * ! * cx2 :: ! * The x-coordinate of the arc's second new control point. ! * ! * cy2 :: ! * The y-coordinate of the arc's second new control point. ! * ! * x :: ! * The x-coordinate of the arc's end point (its start point is ! * stored in `lastX'). ! * ! * y :: ! * The y-coordinate of the arc's end point (its start point is ! * stored in `lastY'). ! * ! * @Return: ! * SUCCESS on success, FAILURE on render pool overflow or incorrect ! * profile. ! */ static Bool Cubic_To( RAS_ARGS Long cx1, Long cy1, Long cx2, Long cy2,
*** 1703,1733 **** x = y; \ y = swap; \ } while ( 0 ) ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Decompose_Curve */ ! /* */ ! /* <Description> */ ! /* Scan the outline arrays in order to emit individual segments and */ ! /* Beziers by calling Line_To() and Bezier_To(). It handles all */ ! /* weird cases, like when the first point is off the curve, or when */ ! /* there are simply no `on' points in the contour! */ ! /* */ ! /* <Input> */ ! /* first :: The index of the first point in the contour. */ ! /* */ ! /* last :: The index of the last point in the contour. */ ! /* */ ! /* flipped :: If set, flip the direction of the curve. */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success, FAILURE on error. */ ! /* */ static Bool Decompose_Curve( RAS_ARGS UShort first, UShort last, Int flipped ) { --- 1732,1765 ---- x = y; \ y = swap; \ } while ( 0 ) ! /************************************************************************** ! * ! * @Function: ! * Decompose_Curve ! * ! * @Description: ! * Scan the outline arrays in order to emit individual segments and ! * Beziers by calling Line_To() and Bezier_To(). It handles all ! * weird cases, like when the first point is off the curve, or when ! * there are simply no `on' points in the contour! ! * ! * @Input: ! * first :: ! * The index of the first point in the contour. ! * ! * last :: ! * The index of the last point in the contour. ! * ! * flipped :: ! * If set, flip the direction of the curve. ! * ! * @Return: ! * SUCCESS on success, FAILURE on error. ! */ static Bool Decompose_Curve( RAS_ARGS UShort first, UShort last, Int flipped ) {
*** 1932,1957 **** Fail: return FAILURE; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Convert_Glyph */ ! /* */ ! /* <Description> */ ! /* Convert a glyph into a series of segments and arcs and make a */ ! /* profiles list with them. */ ! /* */ ! /* <Input> */ ! /* flipped :: If set, flip the direction of curve. */ ! /* */ ! /* <Return> */ ! /* SUCCESS on success, FAILURE if any error was encountered during */ ! /* rendering. */ ! /* */ static Bool Convert_Glyph( RAS_ARGS Int flipped ) { Int i; UInt start; --- 1964,1990 ---- Fail: return FAILURE; } ! /************************************************************************** ! * ! * @Function: ! * Convert_Glyph ! * ! * @Description: ! * Convert a glyph into a series of segments and arcs and make a ! * profiles list with them. ! * ! * @Input: ! * flipped :: ! * If set, flip the direction of curve. ! * ! * @Return: ! * SUCCESS on success, FAILURE if any error was encountered during ! * rendering. ! */ static Bool Convert_Glyph( RAS_ARGS Int flipped ) { Int i; UInt start;
*** 2026,2054 **** /** **/ /*************************************************************************/ /*************************************************************************/ ! /*************************************************************************/ ! /* */ ! /* Init_Linked */ ! /* */ ! /* Initializes an empty linked list. */ ! /* */ static void Init_Linked( TProfileList* l ) { *l = NULL; } ! /*************************************************************************/ ! /* */ ! /* InsNew */ ! /* */ ! /* Inserts a new profile in a linked list. */ ! /* */ static void InsNew( PProfileList list, PProfile profile ) { PProfile *old, current; --- 2059,2087 ---- /** **/ /*************************************************************************/ /*************************************************************************/ ! /************************************************************************** ! * ! * Init_Linked ! * ! * Initializes an empty linked list. ! */ static void Init_Linked( TProfileList* l ) { *l = NULL; } ! /************************************************************************** ! * ! * InsNew ! * ! * Inserts a new profile in a linked list. ! */ static void InsNew( PProfileList list, PProfile profile ) { PProfile *old, current;
*** 2070,2085 **** profile->link = current; *old = profile; } ! /*************************************************************************/ ! /* */ ! /* DelOld */ ! /* */ ! /* Removes an old profile from a linked list. */ ! /* */ static void DelOld( PProfileList list, PProfile profile ) { PProfile *old, current; --- 2103,2118 ---- profile->link = current; *old = profile; } ! /************************************************************************** ! * ! * DelOld ! * ! * Removes an old profile from a linked list. ! */ static void DelOld( PProfileList list, PProfile profile ) { PProfile *old, current;
*** 2103,2120 **** /* we should never get there, unless the profile was not part of */ /* the list. */ } ! /*************************************************************************/ ! /* */ ! /* Sort */ ! /* */ ! /* Sorts a trace list. In 95%, the list is already sorted. We need */ ! /* an algorithm which is fast in this case. Bubble sort is enough */ ! /* and simple. */ ! /* */ static void Sort( PProfileList list ) { PProfile *old, current, next; --- 2136,2153 ---- /* we should never get there, unless the profile was not part of */ /* the list. */ } ! /************************************************************************** ! * ! * Sort ! * ! * Sorts a trace list. In 95%, the list is already sorted. We need ! * an algorithm which is fast in this case. Bubble sort is enough ! * and simple. ! */ static void Sort( PProfileList list ) { PProfile *old, current, next;
*** 2161,2178 **** next = current->link; } } ! /*************************************************************************/ ! /* */ ! /* Vertical Sweep Procedure Set */ ! /* */ ! /* These four routines are used during the vertical black/white sweep */ ! /* phase by the generic Draw_Sweep() function. */ ! /* */ ! /*************************************************************************/ static void Vertical_Sweep_Init( RAS_ARGS Short* min, Short* max ) { --- 2194,2211 ---- next = current->link; } } ! /************************************************************************** ! * ! * Vertical Sweep Procedure Set ! * ! * These four routines are used during the vertical black/white sweep ! * phase by the generic Draw_Sweep() function. ! * ! */ static void Vertical_Sweep_Init( RAS_ARGS Short* min, Short* max ) {
*** 2181,2192 **** FT_UNUSED( max ); ras.traceIncr = (Short)-pitch; ras.traceOfs = -*min * pitch; - if ( pitch > 0 ) - ras.traceOfs += (Long)( ras.target.rows - 1 ) * pitch; } static void Vertical_Sweep_Span( RAS_ARGS Short y, --- 2214,2223 ----
*** 2213,2229 **** x2 / (double)ras.precision, dropOutControl )); /* Drop-out control */ ! e1 = TRUNC( CEILING( x1 ) ); if ( dropOutControl != 2 && ! x2 - x1 - ras.precision <= ras.precision_jitter ) e2 = e1; ! else ! e2 = TRUNC( FLOOR( x2 ) ); if ( e2 >= 0 && e1 < ras.bWidth ) { Int c1, c2; Byte f1, f2; --- 2244,2265 ---- x2 / (double)ras.precision, dropOutControl )); /* Drop-out control */ ! e1 = CEILING( x1 ); ! e2 = FLOOR( x2 ); + /* take care of the special case where both the left */ + /* and right contour lie exactly on pixel centers */ if ( dropOutControl != 2 && ! x2 - x1 - ras.precision <= ras.precision_jitter && ! e1 != x1 && e2 != x2 ) e2 = e1; ! ! e1 = TRUNC( e1 ); ! e2 = TRUNC( e2 ); if ( e2 >= 0 && e1 < ras.bWidth ) { Int c1, c2; Byte f1, f2;
*** 2240,2265 **** c2 = (Short)( e2 >> 3 ); f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); ! target = ras.bTarget + ras.traceOfs + c1; c2 -= c1; if ( c2 > 0 ) { target[0] |= f1; /* memset() is slower than the following code on many platforms. */ /* This is due to the fact that, in the vast majority of cases, */ /* the span length in bytes is relatively small. */ ! c2--; ! while ( c2 > 0 ) ! { *(++target) = 0xFF; ! c2--; ! } target[1] |= f2; } else *target |= ( f1 & f2 ); } --- 2276,2298 ---- c2 = (Short)( e2 >> 3 ); f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); ! target = ras.bOrigin + ras.traceOfs + c1; c2 -= c1; if ( c2 > 0 ) { target[0] |= f1; /* memset() is slower than the following code on many platforms. */ /* This is due to the fact that, in the vast majority of cases, */ /* the span length in bytes is relatively small. */ ! while ( --c2 > 0 ) *(++target) = 0xFF; ! target[1] |= f2; } else *target |= ( f1 & f2 ); }
*** 2398,2408 **** c1 = (Short)( e1 >> 3 ); f1 = (Short)( e1 & 7 ); if ( e1 >= 0 && e1 < ras.bWidth && ! ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) goto Exit; } else goto Exit; } --- 2431,2441 ---- c1 = (Short)( e1 >> 3 ); f1 = (Short)( e1 & 7 ); if ( e1 >= 0 && e1 < ras.bWidth && ! ras.bOrigin[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) goto Exit; } else goto Exit; }
*** 2414,2424 **** FT_TRACE7(( " -> x=%d (drop-out)", e1 )); c1 = (Short)( e1 >> 3 ); f1 = (Short)( e1 & 7 ); ! ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); } Exit: FT_TRACE7(( "\n" )); } --- 2447,2457 ---- FT_TRACE7(( " -> x=%d (drop-out)", e1 )); c1 = (Short)( e1 >> 3 ); f1 = (Short)( e1 & 7 ); ! ras.bOrigin[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); } Exit: FT_TRACE7(( "\n" )); }
*** 2429,2446 **** { ras.traceOfs += ras.traceIncr; } ! /***********************************************************************/ ! /* */ ! /* Horizontal Sweep Procedure Set */ ! /* */ ! /* These four routines are used during the horizontal black/white */ ! /* sweep phase by the generic Draw_Sweep() function. */ ! /* */ ! /***********************************************************************/ static void Horizontal_Sweep_Init( RAS_ARGS Short* min, Short* max ) { --- 2462,2479 ---- { ras.traceOfs += ras.traceIncr; } ! /************************************************************************ ! * ! * Horizontal Sweep Procedure Set ! * ! * These four routines are used during the horizontal black/white ! * sweep phase by the generic Draw_Sweep() function. ! * ! */ static void Horizontal_Sweep_Init( RAS_ARGS Short* min, Short* max ) {
*** 2481,2503 **** if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) { Byte f1; PByte bits; - PByte p; FT_TRACE7(( " -> y=%d (drop-out)", e1 )); ! bits = ras.bTarget + ( y >> 3 ); f1 = (Byte)( 0x80 >> ( y & 7 ) ); - p = bits - e1 * ras.target.pitch; ! if ( ras.target.pitch > 0 ) ! p += (Long)( ras.target.rows - 1 ) * ras.target.pitch; ! ! p[0] |= f1; } } FT_TRACE7(( "\n" )); } --- 2514,2531 ---- if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) { Byte f1; PByte bits; FT_TRACE7(( " -> y=%d (drop-out)", e1 )); ! bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch; f1 = (Byte)( 0x80 >> ( y & 7 ) ); ! bits[0] |= f1; } } FT_TRACE7(( "\n" )); }
*** 2595,2611 **** /* check that the other pixel isn't set */ e1 = ( pxl == e1 ) ? e2 : e1; e1 = TRUNC( e1 ); ! bits = ras.bTarget + ( y >> 3 ); f1 = (Byte)( 0x80 >> ( y & 7 ) ); - bits -= e1 * ras.target.pitch; - if ( ras.target.pitch > 0 ) - bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; - if ( e1 >= 0 && (ULong)e1 < ras.target.rows && *bits & f1 ) goto Exit; } --- 2623,2635 ---- /* check that the other pixel isn't set */ e1 = ( pxl == e1 ) ? e2 : e1; e1 = TRUNC( e1 ); ! bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch; f1 = (Byte)( 0x80 >> ( y & 7 ) ); if ( e1 >= 0 && (ULong)e1 < ras.target.rows && *bits & f1 ) goto Exit; }
*** 2617,2632 **** if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) { FT_TRACE7(( " -> y=%d (drop-out)", e1 )); ! bits = ras.bTarget + ( y >> 3 ); f1 = (Byte)( 0x80 >> ( y & 7 ) ); - bits -= e1 * ras.target.pitch; - - if ( ras.target.pitch > 0 ) - bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; bits[0] |= f1; } Exit: --- 2641,2652 ---- if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) { FT_TRACE7(( " -> y=%d (drop-out)", e1 )); ! bits = ras.bOrigin + ( y >> 3 ) - e1 * ras.target.pitch; f1 = (Byte)( 0x80 >> ( y & 7 ) ); bits[0] |= f1; } Exit:
*** 2640,2654 **** /* Nothing, really */ FT_UNUSED_RASTER; } ! /*************************************************************************/ ! /* */ ! /* Generic Sweep Drawing routine */ ! /* */ ! /*************************************************************************/ static Bool Draw_Sweep( RAS_ARG ) { Short y, y_change, y_height; --- 2660,2674 ---- /* Nothing, really */ FT_UNUSED_RASTER; } ! /************************************************************************** ! * ! * Generic Sweep Drawing routine ! * ! */ static Bool Draw_Sweep( RAS_ARG ) { Short y, y_change, y_height;
*** 2886,2909 **** goto Next_Line; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Render_Single_Pass */ ! /* */ ! /* <Description> */ ! /* Perform one sweep with sub-banding. */ ! /* */ ! /* <Input> */ ! /* flipped :: If set, flip the direction of the outline. */ ! /* */ ! /* <Return> */ ! /* Renderer error code. */ ! /* */ static int Render_Single_Pass( RAS_ARGS Bool flipped ) { Short i, j, k; --- 2906,3018 ---- goto Next_Line; } ! #ifdef STANDALONE_ ! ! /************************************************************************** ! * ! * The following functions should only compile in stand-alone mode, ! * i.e., when building this component without the rest of FreeType. ! * ! */ ! ! /************************************************************************** ! * ! * @Function: ! * FT_Outline_Get_CBox ! * ! * @Description: ! * Return an outline's `control box'. The control box encloses all ! * the outline's points, including Bézier control points. Though it ! * coincides with the exact bounding box for most glyphs, it can be ! * slightly larger in some situations (like when rotating an outline ! * that contains Bézier outside arcs). ! * ! * Computing the control box is very fast, while getting the bounding ! * box can take much more time as it needs to walk over all segments ! * and arcs in the outline. To get the latter, you can use the ! * `ftbbox' component, which is dedicated to this single task. ! * ! * @Input: ! * outline :: ! * A pointer to the source outline descriptor. ! * ! * @Output: ! * acbox :: ! * The outline's control box. ! * ! * @Note: ! * See @FT_Glyph_Get_CBox for a discussion of tricky fonts. ! */ ! ! static void ! FT_Outline_Get_CBox( const FT_Outline* outline, ! FT_BBox *acbox ) ! { ! Long xMin, yMin, xMax, yMax; ! ! ! if ( outline && acbox ) ! { ! if ( outline->n_points == 0 ) ! { ! xMin = 0; ! yMin = 0; ! xMax = 0; ! yMax = 0; ! } ! else ! { ! FT_Vector* vec = outline->points; ! FT_Vector* limit = vec + outline->n_points; ! ! ! xMin = xMax = vec->x; ! yMin = yMax = vec->y; ! vec++; ! ! for ( ; vec < limit; vec++ ) ! { ! Long x, y; ! ! ! x = vec->x; ! if ( x < xMin ) xMin = x; ! if ( x > xMax ) xMax = x; ! ! y = vec->y; ! if ( y < yMin ) yMin = y; ! if ( y > yMax ) yMax = y; ! } ! } ! acbox->xMin = xMin; ! acbox->xMax = xMax; ! acbox->yMin = yMin; ! acbox->yMax = yMax; ! } ! } ! ! #endif /* STANDALONE_ */ ! ! ! /************************************************************************** ! * ! * @Function: ! * Render_Single_Pass ! * ! * @Description: ! * Perform one sweep with sub-banding. ! * ! * @Input: ! * flipped :: ! * If set, flip the direction of the outline. ! * ! * @Return: ! * Renderer error code. ! */ static int Render_Single_Pass( RAS_ARGS Bool flipped ) { Short i, j, k;
*** 2961,2990 **** return SUCCESS; } ! /*************************************************************************/ ! /* */ ! /* <Function> */ ! /* Render_Glyph */ ! /* */ ! /* <Description> */ ! /* Render a glyph in a bitmap. Sub-banding if needed. */ ! /* */ ! /* <Return> */ ! /* FreeType error code. 0 means success. */ ! /* */ static FT_Error Render_Glyph( RAS_ARG ) { FT_Error error; Set_High_Precision( RAS_VARS ras.outline.flags & FT_OUTLINE_HIGH_PRECISION ); - ras.scale_shift = ras.precision_shift; if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) ras.dropOutControl = 2; else { --- 3070,3098 ---- return SUCCESS; } ! /************************************************************************** ! * ! * @Function: ! * Render_Glyph ! * ! * @Description: ! * Render a glyph in a bitmap. Sub-banding if needed. ! * ! * @Return: ! * FreeType error code. 0 means success. ! */ static FT_Error Render_Glyph( RAS_ARG ) { FT_Error error; Set_High_Precision( RAS_VARS ras.outline.flags & FT_OUTLINE_HIGH_PRECISION ); if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) ras.dropOutControl = 2; else {
*** 3011,3021 **** ras.band_top = 0; ras.band_stack[0].y_min = 0; ras.band_stack[0].y_max = (Short)( ras.target.rows - 1 ); ras.bWidth = (UShort)ras.target.width; ! ras.bTarget = (Byte*)ras.target.buffer; if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) return error; /* Horizontal Sweep */ --- 3119,3132 ---- ras.band_top = 0; ras.band_stack[0].y_min = 0; ras.band_stack[0].y_max = (Short)( ras.target.rows - 1 ); ras.bWidth = (UShort)ras.target.width; ! ras.bOrigin = (Byte*)ras.target.buffer; ! ! if ( ras.target.pitch > 0 ) ! ras.bOrigin += (Long)( ras.target.rows - 1 ) * ras.target.pitch; if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) return error; /* Horizontal Sweep */
*** 3183,3206 **** return Raster_Err_None; if ( !target_map->buffer ) return FT_THROW( Invalid ); - /* reject too large outline coordinates */ - { - FT_Vector* vec = outline->points; - FT_Vector* limit = vec + outline->n_points; - - - for ( ; vec < limit; vec++ ) - { - if ( vec->x < -0x1000000L || vec->x > 0x1000000L || - vec->y < -0x1000000L || vec->y > 0x1000000L ) - return FT_THROW( Invalid ); - } - } - ras.outline = *outline; ras.target = *target_map; worker->buff = buffer; worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */ --- 3294,3303 ----
< prev index next >