1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* ftraster.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* The FreeType glyph rasterizer (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Copyright 1996-2003, 2005, 2007-2013 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This file can be compiled without the rest of the FreeType engine, by */ 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* defining the _STANDALONE_ macro when compiling it. You also need to */ 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* directory. Typically, you should do something like */ 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - copy `src/raster/ftraster.c' (this file) to your current directory */ 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' */ 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to your current directory */ 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */ 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cc -c -D_STANDALONE_ ftraster.c */ 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The renderer can be initialized with a call to */ 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `ft_standard_raster.raster_new'; a bitmap can be generated */ 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* with a call to `ft_standard_raster.raster_render'. */ 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* See the comments and documentation in the file `ftimage.h' for more */ 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* details on how the raster works. */ 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This is a rewrite of the FreeType 1.x scan-line converter */ 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _STANDALONE_ 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <string.h> /* for memset */ 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftmisc.h" 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftimage.h" 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !_STANDALONE_ */ 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/ft2build.h" 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftraster.h" 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftcalc.h" /* for FT_MulDiv and FT_MulDiv_No_Round */ 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "rastpic.h" 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !_STANDALONE_ */ 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A simple technical note on how the raster works */ 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ----------------------------------------------- */ 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Converting an outline into a bitmap is achieved in several steps: */ 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 1 - Decomposing the outline into successive `profiles'. Each */ 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* profile is simply an array of scanline intersections on a given */ 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* dimension. A profile's main attributes are */ 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* o its scanline position boundaries, i.e. `Ymin' and `Ymax' */ 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* o an array of intersection coordinates for each scanline */ 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* between `Ymin' and `Ymax' */ 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* o a direction, indicating whether it was built going `up' or */ 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `down', as this is very important for filling rules */ 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* o its drop-out mode */ 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 2 - Sweeping the target map's scanlines in order to compute segment */ 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `spans' which are then filled. Additionally, this pass */ 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* performs drop-out control. */ 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The outline data is parsed during step 1 only. The profiles are */ 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* built from the bottom of the render pool, used as a stack. The */ 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* following graphics shows the profile list under construction: */ 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* __________________________________________________________ _ _ */ 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | | | | | */ 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | profile | coordinates for | profile | coordinates for |--> */ 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | 1 | profile 1 | 2 | profile 2 |--> */ 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* |_________|_________________|_________|_________________|__ _ _ */ 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ^ ^ */ 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | | */ 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start of render pool top */ 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The top of the profile stack is kept in the `top' variable. */ 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* As you can see, a profile record is pushed on top of the render */ 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* pool, which is then followed by its coordinates/intersections. If */ 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* a change of direction is detected in the outline, a new profile is */ 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* generated until the end of the outline. */ 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note that when all profiles have been generated, the function */ 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Finalize_Profile_Table() is used to record, for each profile, its */ 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* bottom-most scanline as well as the scanline above its upmost */ 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* boundary. These positions are called `y-turns' because they (sort */ 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* of) correspond to local extrema. They are stored in a sorted list */ 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* built from the top of the render pool as a downwards stack: */ 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* _ _ _______________________________________ */ 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | | */ 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <--| sorted list of | */ 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <--| extrema scanlines | */ 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* _ _ __________________|____________________| */ 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ^ ^ */ 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | | */ 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* maxBuff sizeBuff = end of pool */ 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This list is later used during the sweep phase in order to */ 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* optimize performance (see technical note on the sweep below). */ 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Of course, the raster detects whether the two stacks collide and */ 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* handles the situation properly. */ 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** **/ 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** CONFIGURATION MACROS **/ 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** **/ 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* define DEBUG_RASTER if you want to compile a debugging version */ 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* #define DEBUG_RASTER */ 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */ 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 5-levels anti-aliasing */ 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* #define FT_RASTER_OPTION_ANTI_ALIASING */ 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The size of the two-lines intermediate bitmap used */ 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for anti-aliasing, in bytes. */ 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RASTER_GRAY_LINES 2048 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** **/ 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** OTHER MACROS (do not change) **/ 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** **/ 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_raster 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _STANDALONE_ 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Auxiliary macros for token concatenation. */ 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_ERR_XCAT( x, y ) x ## y 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This macro is used to indicate that a function parameter is unused. */ 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Its purpose is simply to reduce compiler warnings. Note also that */ 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* simply defining it as `(void)x' doesn't avoid warnings with certain */ 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ANSI compilers (e.g. LCC). */ 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_UNUSED( x ) (x) = (x) 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Disable the tracing mechanism for simplicity -- developers can */ 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* activate it easily by redefining these macros. */ 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_ERROR 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_TRACE 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_THROW 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_THROW( e ) FT_ERR_CAT( Raster_Err_, e ) 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_None 0 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_Not_Ini -1 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_Overflow -2 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_Neg_Height -3 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_Invalid -4 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_Unsupported -5 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ft_memset memset 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \ 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_reset_, raster_set_mode_, \ 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_render_, raster_done_ ) \ 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Raster_Funcs class_ = \ 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { \ 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_format_, \ 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_new_, \ 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_reset_, \ 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_set_mode_, \ 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_render_, \ 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_done_ \ 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !_STANDALONE_ */ 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftobjs.h" 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../include/freetype/internal/ftdebug.h" /* for FT_TRACE, FT_ERROR, and FT_THROW */ 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "rasterrs.h" 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_None FT_Err_Ok 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_Overflow Raster_Err_Raster_Overflow 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_Invalid Raster_Err_Invalid_Outline 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !_STANDALONE_ */ 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_MEM_SET 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_MEM_ZERO 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* typically a small value and the result of a*b is known to fit into */ 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 32 bits. */ 260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ 263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for clipping computations. It simply uses the FT_MulDiv() function */ 264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* defined in `ftcalc.h'. */ 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SMulDiv FT_MulDiv 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SMulDiv_No_Round FT_MulDiv_No_Round 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The rasterizer is a very general purpose component; please leave */ 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the following redefinitions there (you never know your target */ 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* environment). */ 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef TRUE 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TRUE 1 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FALSE 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FALSE 0 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef NULL 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define NULL (void*)0 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef SUCCESS 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SUCCESS 0 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FAILURE 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FAILURE 1 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MaxBezier 32 /* The maximum number of stacked Bezier curves. */ 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Setting this constant to more than 32 is a */ 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* pure waste of space. */ 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Pixel_Bits 6 /* fractional bits of *input* coordinates */ 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** **/ 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** SIMPLE TYPE DECLARATIONS **/ 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** **/ 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef int Int; 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef unsigned int UInt; 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef short Short; 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef unsigned short UShort, *PUShort; 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef long Long, *PLong; 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef unsigned long ULong; 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef unsigned char Byte, *PByte; 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef char Bool; 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef union Alignment_ 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov long l; 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* p; 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void (*f)(void); 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } Alignment, *PAlignment; 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct TPoint_ 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long x; 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long y; 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } TPoint; 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* values for the `flags' bit field */ 337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Flow_Up 0x8 338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Overshoot_Top 0x10 339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Overshoot_Bottom 0x20 340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* States of each line, arc, and profile */ 343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef enum TStates_ 344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Unknown_State, 346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Ascending_State, 347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Descending_State, 348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Flat_State 349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } TStates; 351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct TProfile_ TProfile; 354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef TProfile* PProfile; 355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov struct TProfile_ 357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 X; /* current coordinate during sweep */ 359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile link; /* link to next profile (various purposes) */ 360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PLong offset; /* start of profile's data in render pool */ 361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned flags; /* Bit 0-2: drop-out mode */ 362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Bit 3: profile orientation (up/down) */ 363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Bit 4: is top profile? */ 364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Bit 5: is bottom profile? */ 365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov long height; /* profile's height in scanlines */ 366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov long start; /* profile's starting scanline */ 367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned countL; /* number of lines to step before this */ 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* profile becomes drawable */ 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile next; /* next profile in same contour, used */ 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* during drop-out control */ 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef PProfile TProfileList; 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef PProfile* PProfileList; 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Simple record used to implement a stack of bands, required */ 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* by the sub-banding mechanism */ 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct black_TBand_ 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short y_min; /* band's minimum */ 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short y_max; /* band's maximum */ 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } black_TBand; 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define AlignProfileSize \ 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) ) 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef RAS_ARG 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef RAS_ARGS 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef RAS_VAR 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef RAS_VARS 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_STATIC_RASTER 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_ARGS /* void */ 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_ARG /* void */ 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_VARS /* void */ 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_VAR /* void */ 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_UNUSED_RASTER do { } while ( 0 ) 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !FT_STATIC_RASTER */ 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_ARGS black_PWorker worker, 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_ARG black_PWorker worker 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_VARS worker, 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_VAR worker 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_UNUSED_RASTER FT_UNUSED( worker ) 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !FT_STATIC_RASTER */ 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct black_TWorker_ black_TWorker, *black_PWorker; 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* prototypes used for sweep function dispatch */ 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef void 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Function_Sweep_Init( RAS_ARGS Short* min, 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short* max ); 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef void 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Function_Sweep_Span( RAS_ARGS Short y, 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x1, 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x2, 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile left, 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile right ); 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef void 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Function_Sweep_Step( RAS_ARG ); 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NOTE: These operations are only valid on 2's complement processors */ 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FLOOR 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CEILING 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef TRUNC 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef SCALED 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FLOOR( x ) ( (x) & -ras.precision ) 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TRUNC( x ) ( (Long)(x) >> ras.precision_bits ) 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SCALED( x ) ( ( (ULong)(x) << ras.scale_shift ) - ras.precision_half ) 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define IS_BOTTOM_OVERSHOOT( x ) \ 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (Bool)( CEILING( x ) - x >= ras.precision_half ) 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define IS_TOP_OVERSHOOT( x ) \ 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (Bool)( x - FLOOR( x ) >= ras.precision_half ) 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The most used variables are positioned at the top of the structure. */ 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Thus, their offset can be coded with less opcodes, resulting in a */ 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* smaller executable. */ 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov struct black_TWorker_ 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int precision_bits; /* precision related variables */ 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int precision; 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int precision_half; 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int precision_shift; 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int precision_step; 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int precision_jitter; 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int scale_shift; /* == precision_shift for bitmaps */ 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* == precision_shift+1 for pixmaps */ 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PLong buff; /* The profiles buffer */ 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PLong sizeBuff; /* Render pool size */ 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PLong maxBuff; /* Profiles buffer size */ 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PLong top; /* Current cursor in buffer */ 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int numTurns; /* number of Y-turns in outline */ 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPoint* arc; /* current Bezier arc pointer */ 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov UShort bWidth; /* target bitmap width */ 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PByte bTarget; /* target bitmap buffer */ 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PByte gTarget; /* target pixmap buffer */ 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long lastX, lastY; 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long minY, maxY; 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov UShort num_Profs; /* current number of profiles */ 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bool fresh; /* signals a fresh new profile which */ 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `start' field must be completed */ 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bool joint; /* signals that the last arc ended */ 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* exactly on a scanline. Allows */ 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* removal of doublets */ 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile cProfile; /* current profile */ 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile fProfile; /* head of linked list of profiles */ 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile gProfile; /* contour's first profile in case */ 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* of impact */ 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TStates state; /* rendering state */ 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap target; /* description of target bit/pixmap */ 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline outline; 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long traceOfs; /* current offset in target bitmap */ 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long traceG; /* current offset in target pixmap */ 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short traceIncr; /* sweep's increment in target bitmap */ 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short gray_min_x; /* current min x during gray rendering */ 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short gray_max_x; /* current max x during gray rendering */ 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* dispatch variables */ 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Function_Sweep_Init* Proc_Sweep_Init; 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Function_Sweep_Span* Proc_Sweep_Span; 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Function_Sweep_Span* Proc_Sweep_Drop; 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Function_Sweep_Step* Proc_Sweep_Step; 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Byte dropOutControl; /* current drop_out control method */ 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bool second_pass; /* indicates whether a horizontal pass */ 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* should be performed to control */ 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* drop-out accurately when calling */ 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Render_Glyph. Note that there is */ 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* no horizontal pass during gray */ 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* rendering. */ 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov black_TBand band_stack[16]; /* band stack used for sub-banding */ 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int band_top; /* band stack top */ 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_RASTER_OPTION_ANTI_ALIASING 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Byte* grays; 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Byte gray_lines[RASTER_GRAY_LINES]; 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Intermediate table used to render the */ 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* graylevels pixmaps. */ 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* gray_lines is a buffer holding two */ 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* monochrome scanlines */ 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short gray_width; /* width in bytes of one monochrome */ 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* intermediate scanline of gray_lines. */ 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Each gray pixel takes 2 bits long there */ 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The gray_lines must hold 2 lines, thus with size */ 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in bytes of at least `gray_width*2'. */ 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_RASTER_ANTI_ALIASING */ 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct black_TRaster_ 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* buffer; 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov long buffer_size; 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* memory; 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov black_PWorker worker; 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Byte grays[5]; 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short gray_width; 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } black_TRaster, *black_PRaster; 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_STATIC_RASTER 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static black_TWorker cur_ras; 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ras cur_ras 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !FT_STATIC_RASTER */ 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ras (*worker) 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !FT_STATIC_RASTER */ 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_RASTER_OPTION_ANTI_ALIASING 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A lookup table used to quickly count set bits in four gray 2x2 */ 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cells. The values of the table have been produced with the */ 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* following code: */ 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for ( i = 0; i < 256; i++ ) */ 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* { */ 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* l = 0; */ 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* j = i; */ 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for ( c = 0; c < 4; c++ ) */ 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* { */ 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* l <<= 4; */ 600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if ( j & 0x80 ) l++; */ 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if ( j & 0x40 ) l++; */ 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* j = ( j << 2 ) & 0xFF; */ 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* } */ 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* printf( "0x%04X", l ); */ 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* } */ 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const short count_table[256] = 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012, 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022, 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212, 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222, 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012, 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022, 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212, 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** **/ 653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** PROFILES COMPUTATION **/ 654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** **/ 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Set_High_Precision */ 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Set precision variables according to param flag. */ 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* High :: Set to True for high precision (typically for ppem < 24), */ 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* false otherwise. */ 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Set_High_Precision( RAS_ARGS Int High ) 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * `precision_step' is used in `Bezier_Up' to decide when to split a 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * given y-monotonous Bezier arc that crosses a scanline before 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * approximating it as a straight segment. The default value of 32 (for 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * low accuracy) corresponds to 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 32 / 64 == 0.5 pixels , 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * while for the high accuracy case we have 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 256/ (1 << 12) = 0.0625 pixels . 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * `precision_jitter' is an epsilon threshold used in 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * `Vertical_Sweep_Span' to deal with small imperfections in the Bezier 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * decomposition (after all, we are working with approximations only); 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * it avoids switching on additional pixels which would cause artifacts 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * otherwise. 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * The value of `precision_jitter' has been determined heuristically. 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( High ) 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.precision_bits = 12; 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.precision_step = 256; 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.precision_jitter = 30; 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.precision_bits = 6; 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.precision_step = 32; 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.precision_jitter = 2; 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.precision = 1 << ras.precision_bits; 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.precision_half = ras.precision / 2; 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.precision_shift = ras.precision_bits - Pixel_Bits; 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* New_Profile */ 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Create a new profile in the render pool. */ 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* aState :: The state/orientation of the new profile. */ 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* overshoot :: Whether the profile's unrounded start position */ 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* differs by at least a half pixel. */ 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* profile. */ 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov New_Profile( RAS_ARGS TStates aState, 737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bool overshoot ) 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !ras.fProfile ) 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile = (PProfile)ras.top; 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.fProfile = ras.cProfile; 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.top += AlignProfileSize; 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.top >= ras.maxBuff ) 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = FT_THROW( Overflow ); 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->flags = 0; 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->start = 0; 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->height = 0; 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->offset = ras.top; 756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->link = (PProfile)0; 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->next = (PProfile)0; 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->flags = ras.dropOutControl; 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( aState ) 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case Ascending_State: 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->flags |= Flow_Up; 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( overshoot ) 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->flags |= Overshoot_Bottom; 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE6(( "New ascending profile = %p\n", ras.cProfile )); 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case Descending_State: 771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( overshoot ) 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->flags |= Overshoot_Top; 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE6(( "New descending profile = %p\n", ras.cProfile )); 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "New_Profile: invalid profile direction\n" )); 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = FT_THROW( Invalid ); 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !ras.gProfile ) 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gProfile = ras.cProfile; 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.state = aState; 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.fresh = TRUE; 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.joint = FALSE; 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* End_Profile */ 797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Finalize the current profile. */ 800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* overshoot :: Whether the profile's unrounded end position differs */ 803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* by at least a half pixel. */ 804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ 807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov End_Profile( RAS_ARGS Bool overshoot ) 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long h; 812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov h = (Long)( ras.top - ras.cProfile->offset ); 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( h < 0 ) 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERROR(( "End_Profile: negative height encountered\n" )); 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = FT_THROW( Neg_Height ); 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( h > 0 ) 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile oldProfile; 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE6(( "Ending profile %p, start = %ld, height = %ld\n", 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile, ras.cProfile->start, h )); 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->height = h; 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( overshoot ) 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.cProfile->flags & Flow_Up ) 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->flags |= Overshoot_Top; 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->flags |= Overshoot_Bottom; 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov oldProfile = ras.cProfile; 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile = (PProfile)ras.top; 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.top += AlignProfileSize; 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->height = 0; 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->offset = ras.top; 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov oldProfile->next = ras.cProfile; 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.num_Profs++; 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.top >= ras.maxBuff ) 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE1(( "overflow in End_Profile\n" )); 855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = FT_THROW( Overflow ); 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.joint = FALSE; 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Insert_Y_Turn */ 869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Insert a salient into the sorted list placed on top of the render */ 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* pool. */ 873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* New y scanline position. */ 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success. FAILURE in case of overflow. */ 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Insert_Y_Turn( RAS_ARGS Int y ) 882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PLong y_turns; 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int n; 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n = ras.numTurns - 1; 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_turns = ras.sizeBuff - ras.numTurns; 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* look for first y value that is <= */ 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( n >= 0 && y < y_turns[n] ) 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n--; 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if it is <, simply insert it, ignore if == */ 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( n >= 0 && y > y_turns[n] ) 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( n >= 0 ) 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int y2 = (Int)y_turns[n]; 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_turns[n] = y; 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = y2; 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n--; 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( n < 0 ) 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.maxBuff--; 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.maxBuff <= ras.top ) 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = FT_THROW( Overflow ); 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.numTurns++; 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.sizeBuff[-ras.numTurns] = y; 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Finalize_Profile_Table */ 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Adjust all links in the profiles list. */ 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success. FAILURE in case of overflow. */ 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Finalize_Profile_Table( RAS_ARG ) 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov UShort n; 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile p; 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n = ras.num_Profs; 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = ras.fProfile; 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( n > 1 && p ) 944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( n > 0 ) 946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int bottom, top; 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( n > 1 ) 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p->link = (PProfile)( p->offset + p->height ); 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p->link = NULL; 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( p->flags & Flow_Up ) 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bottom = (Int)p->start; 958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top = (Int)( p->start + p->height - 1 ); 959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bottom = (Int)( p->start - p->height + 1 ); 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top = (Int)p->start; 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p->start = bottom; 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p->offset += p->height - 1; 966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Insert_Y_Turn( RAS_VARS bottom ) || 969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Insert_Y_Turn( RAS_VARS top + 1 ) ) 970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = p->link; 973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov n--; 974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.fProfile = NULL; 978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Split_Conic */ 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */ 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stack. */ 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* None (subdivided Bezier is taken from the top of the stack). */ 994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Note> */ 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This routine is the `beef' of this component. It is _the_ inner */ 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* loop that should be optimized to hell to get the best performance. */ 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Split_Conic( TPoint* base ) 1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long a, b; 1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[4].x = base[2].x; 1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov b = base[1].x; 1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a = base[3].x = ( base[2].x + b ) / 2; 1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov b = base[1].x = ( base[0].x + b ) / 2; 1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[2].x = ( a + b ) / 2; 1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[4].y = base[2].y; 1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov b = base[1].y; 1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a = base[3].y = ( base[2].y + b ) / 2; 1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov b = base[1].y = ( base[0].y + b ) / 2; 1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[2].y = ( a + b ) / 2; 1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* hand optimized. gcc doesn't seem to be too good at common */ 1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* expression substitution and instruction scheduling ;-) */ 1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Split_Cubic */ 1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */ 1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Bezier stack. */ 1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Note> */ 1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This routine is the `beef' of the component. It is one of _the_ */ 1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* inner loops that should be optimized like hell to get the best */ 1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* performance. */ 1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Split_Cubic( TPoint* base ) 1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long a, b, c, d; 1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[6].x = base[3].x; 1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c = base[1].x; 1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov d = base[2].x; 1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[1].x = a = ( base[0].x + c + 1 ) >> 1; 1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[5].x = b = ( base[3].x + d + 1 ) >> 1; 1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c = ( c + d + 1 ) >> 1; 1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[2].x = a = ( a + c + 1 ) >> 1; 1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[4].x = b = ( b + c + 1 ) >> 1; 1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[3].x = ( a + b + 1 ) >> 1; 1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[6].y = base[3].y; 1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c = base[1].y; 1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov d = base[2].y; 1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[1].y = a = ( base[0].y + c + 1 ) >> 1; 1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[5].y = b = ( base[3].y + d + 1 ) >> 1; 1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c = ( c + d + 1 ) >> 1; 1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[2].y = a = ( a + c + 1 ) >> 1; 1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[4].y = b = ( b + c + 1 ) >> 1; 1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[3].y = ( a + b + 1 ) >> 1; 1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Line_Up */ 1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Compute the x-coordinates of an ascending line segment and store */ 1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* them in the render pool. */ 1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* x1 :: The x-coordinate of the segment's start point. */ 1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* y1 :: The y-coordinate of the segment's start point. */ 1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* x2 :: The x-coordinate of the segment's end point. */ 1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* y2 :: The y-coordinate of the segment's end point. */ 1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* miny :: A lower vertical clipping bound value. */ 1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* maxy :: An upper vertical clipping bound value. */ 1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success, FAILURE on render pool overflow. */ 1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Line_Up( RAS_ARGS Long x1, 1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long y1, 1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long x2, 1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long y2, 1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long miny, 1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long maxy ) 1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long Dx, Dy; 1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */ 1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long Ix, Rx, Ax; 1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PLong top; 1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Dx = x2 - x1; 1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Dy = y2 - y1; 1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Dy <= 0 || y2 < miny || y1 > maxy ) 1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y1 < miny ) 1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Take care: miny-y1 can be a very large value; we use */ 1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* a slow MulDiv function to avoid clipping bugs */ 1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x1 += SMulDiv( Dx, miny - y1, Dy ); 1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = (Int)TRUNC( miny ); 1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f1 = 0; 1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = (Int)TRUNC( y1 ); 1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f1 = (Int)FRAC( y1 ); 1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y2 > maxy ) 1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ 1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = (Int)TRUNC( maxy ); 1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f2 = 0; 1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = (Int)TRUNC( y2 ); 1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f2 = (Int)FRAC( y2 ); 1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( f1 > 0 ) 1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 == e2 ) 1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x1 += SMulDiv( Dx, ras.precision - f1, Dy ); 1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 += 1; 1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.joint ) 1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.top--; 1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.joint = FALSE; 1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.joint = (char)( f2 == 0 ); 1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.fresh ) 1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->start = e1; 1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.fresh = FALSE; 1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size = e2 - e1 + 1; 1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.top + size >= ras.maxBuff ) 1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = FT_THROW( Overflow ); 1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Dx > 0 ) 1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Ix = SMulDiv_No_Round( ras.precision, Dx, Dy ); 1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Rx = ( ras.precision * Dx ) % Dy; 1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Dx = 1; 1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Ix = -SMulDiv_No_Round( ras.precision, -Dx, Dy ); 1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Rx = ( ras.precision * -Dx ) % Dy; 1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Dx = -1; 1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Ax = -Dy; 1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top = ras.top; 1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( size > 0 ) 1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *top++ = x1; 1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x1 += Ix; 1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Ax += Rx; 1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Ax >= 0 ) 1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Ax -= Dy; 1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x1 += Dx; 1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov size--; 1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.top = top; 1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Line_Down */ 1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Compute the x-coordinates of an descending line segment and store */ 1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* them in the render pool. */ 1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* x1 :: The x-coordinate of the segment's start point. */ 1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* y1 :: The y-coordinate of the segment's start point. */ 1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* x2 :: The x-coordinate of the segment's end point. */ 1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* y2 :: The y-coordinate of the segment's end point. */ 1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* miny :: A lower vertical clipping bound value. */ 1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* maxy :: An upper vertical clipping bound value. */ 1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success, FAILURE on render pool overflow. */ 1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Line_Down( RAS_ARGS Long x1, 1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long y1, 1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long x2, 1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long y2, 1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long miny, 1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long maxy ) 1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bool result, fresh; 1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fresh = ras.fresh; 1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); 1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( fresh && !ras.fresh ) 1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->start = -ras.cProfile->start; 1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A function type describing the functions used to split Bezier arcs */ 1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef void (*TSplitter)( TPoint* base ); 1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Bezier_Up */ 1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Compute the x-coordinates of an ascending Bezier arc and store */ 1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* them in the render pool. */ 1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* degree :: The degree of the Bezier arc (either 2 or 3). */ 1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* splitter :: The function to split Bezier arcs. */ 1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* miny :: A lower vertical clipping bound value. */ 1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* maxy :: An upper vertical clipping bound value. */ 1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success, FAILURE on render pool overflow. */ 1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bezier_Up( RAS_ARGS Int degree, 1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TSplitter splitter, 1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long miny, 1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long maxy ) 1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long y1, y2, e, e2, e0; 1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short f1; 1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPoint* arc; 1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPoint* start_arc; 1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PLong top; 1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc = ras.arc; 1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y1 = arc[degree].y; 1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y2 = arc[0].y; 1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top = ras.top; 1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y2 < miny || y1 > maxy ) 1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fin; 1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = FLOOR( y2 ); 1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e2 > maxy ) 1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = maxy; 1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e0 = miny; 1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y1 < miny ) 1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e = miny; 1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e = CEILING( y1 ); 1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f1 = (Short)( FRAC( y1 ) ); 1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e0 = e; 1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( f1 == 0 ) 1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.joint ) 1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top--; 1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.joint = FALSE; 1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *top++ = arc[degree].x; 1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e += ras.precision; 1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.fresh ) 1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->start = TRUNC( e0 ); 1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.fresh = FALSE; 1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e2 < e ) 1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fin; 1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) 1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.top = top; 1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = FT_THROW( Overflow ); 1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start_arc = arc; 1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( arc >= start_arc && e <= e2 ) 1346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.joint = FALSE; 1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y2 = arc[0].y; 1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y2 > e ) 1352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y1 = arc[degree].y; 1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y2 - y1 >= ras.precision_step ) 1355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov splitter( arc ); 1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc += degree; 1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x, 1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e - y1, y2 - y1 ); 1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc -= degree; 1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e += ras.precision; 1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y2 == e ) 1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.joint = TRUE; 1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *top++ = arc[0].x; 1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e += ras.precision; 1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc -= degree; 1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fin: 1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.top = top; 1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc -= degree; 1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Bezier_Down */ 1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Compute the x-coordinates of an descending Bezier arc and store */ 1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* them in the render pool. */ 1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* degree :: The degree of the Bezier arc (either 2 or 3). */ 1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* splitter :: The function to split Bezier arcs. */ 1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* miny :: A lower vertical clipping bound value. */ 1402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* maxy :: An upper vertical clipping bound value. */ 1404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success, FAILURE on render pool overflow. */ 1407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 1409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bezier_Down( RAS_ARGS Int degree, 1410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TSplitter splitter, 1411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long miny, 1412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long maxy ) 1413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPoint* arc = ras.arc; 1415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bool result, fresh; 1416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[0].y = -arc[0].y; 1419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[1].y = -arc[1].y; 1420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[2].y = -arc[2].y; 1421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( degree > 2 ) 1422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[3].y = -arc[3].y; 1423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fresh = ras.fresh; 1425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny ); 1427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( fresh && !ras.fresh ) 1429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->start = -ras.cProfile->start; 1430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[0].y = -arc[0].y; 1432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return result; 1433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Line_To */ 1440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Inject a new line segment and adjust the Profiles list. */ 1443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* x :: The x-coordinate of the segment's end point (its start point */ 1446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is stored in `lastX'). */ 1447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* y :: The y-coordinate of the segment's end point (its start point */ 1449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* is stored in `lastY'). */ 1450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* profile. */ 1454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 1456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Line_To( RAS_ARGS Long x, 1457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long y ) 1458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* First, detect a change of direction */ 1460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( ras.state ) 1462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case Unknown_State: 1464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y > ras.lastY ) 1465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( New_Profile( RAS_VARS Ascending_State, 1467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) 1468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 1469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y < ras.lastY ) 1473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( New_Profile( RAS_VARS Descending_State, 1474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov IS_TOP_OVERSHOOT( ras.lastY ) ) ) 1475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 1476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case Ascending_State: 1480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y < ras.lastY ) 1481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) || 1483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov New_Profile( RAS_VARS Descending_State, 1484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov IS_TOP_OVERSHOOT( ras.lastY ) ) ) 1485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 1486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case Descending_State: 1490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y > ras.lastY ) 1491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) || 1493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov New_Profile( RAS_VARS Ascending_State, 1494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) 1495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 1496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 1500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ; 1501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Then compute the lines */ 1504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( ras.state ) 1506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case Ascending_State: 1508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, 1509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x, y, ras.minY, ras.maxY ) ) 1510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 1511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case Descending_State: 1514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, 1515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x, y, ras.minY, ras.maxY ) ) 1516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 1517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 1518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 1520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ; 1521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.lastX = x; 1524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.lastY = y; 1525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 1527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Conic_To */ 1534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Inject a new conic arc and adjust the profile list. */ 1537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cx :: The x-coordinate of the arc's new control point. */ 1540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cy :: The y-coordinate of the arc's new control point. */ 1542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* x :: The x-coordinate of the arc's end point (its start point is */ 1544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stored in `lastX'). */ 1545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* y :: The y-coordinate of the arc's end point (its start point is */ 1547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stored in `lastY'). */ 1548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* profile. */ 1552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 1554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Conic_To( RAS_ARGS Long cx, 1555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long cy, 1556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long x, 1557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long y ) 1558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long y1, y2, y3, x3, ymin, ymax; 1560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TStates state_bez; 1561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc = ras.arcs; 1564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[2].x = ras.lastX; 1565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[2].y = ras.lastY; 1566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[1].x = cx; 1567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[1].y = cy; 1568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[0].x = x; 1569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[0].y = y; 1570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do 1572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y1 = ras.arc[2].y; 1574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y2 = ras.arc[1].y; 1575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y3 = ras.arc[0].y; 1576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x3 = ras.arc[0].x; 1577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first, categorize the Bezier arc */ 1579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y1 <= y3 ) 1581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymin = y1; 1583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymax = y3; 1584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymin = y3; 1588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymax = y1; 1589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y2 < ymin || y2 > ymax ) 1592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this arc has no given direction, split it! */ 1594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Split_Conic( ras.arc ); 1595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc += 2; 1596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( y1 == y3 ) 1598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this arc is flat, ignore it and pop it from the Bezier stack */ 1600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc -= 2; 1601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the arc is y-monotonous, either ascending or descending */ 1605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* detect a change of direction */ 1606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov state_bez = y1 < y3 ? Ascending_State : Descending_State; 1607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.state != state_bez ) 1608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) 1610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : IS_TOP_OVERSHOOT( y1 ); 1611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* finalize current profile if any */ 1614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.state != Unknown_State && 1615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov End_Profile( RAS_VARS o ) ) 1616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* create a new profile */ 1619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( New_Profile( RAS_VARS state_bez, o ) ) 1620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now call the appropriate routine */ 1624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( state_bez == Ascending_State ) 1625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) 1627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) 1631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while ( ras.arc >= ras.arcs ); 1635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.lastX = x3; 1637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.lastY = y3; 1638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 1640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 1642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 1643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Cubic_To */ 1650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Inject a new cubic arc and adjust the profile list. */ 1653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cx1 :: The x-coordinate of the arc's first new control point. */ 1656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cy1 :: The y-coordinate of the arc's first new control point. */ 1658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cx2 :: The x-coordinate of the arc's second new control point. */ 1660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cy2 :: The y-coordinate of the arc's second new control point. */ 1662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* x :: The x-coordinate of the arc's end point (its start point is */ 1664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stored in `lastX'). */ 1665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* y :: The y-coordinate of the arc's end point (its start point is */ 1667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* stored in `lastY'). */ 1668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* profile. */ 1672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 1674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Cubic_To( RAS_ARGS Long cx1, 1675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long cy1, 1676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long cx2, 1677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long cy2, 1678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long x, 1679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long y ) 1680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2; 1682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TStates state_bez; 1683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc = ras.arcs; 1686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[3].x = ras.lastX; 1687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[3].y = ras.lastY; 1688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[2].x = cx1; 1689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[2].y = cy1; 1690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[1].x = cx2; 1691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[1].y = cy2; 1692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[0].x = x; 1693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc[0].y = y; 1694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do 1696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y1 = ras.arc[3].y; 1698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y2 = ras.arc[2].y; 1699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y3 = ras.arc[1].y; 1700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y4 = ras.arc[0].y; 1701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x4 = ras.arc[0].x; 1702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first, categorize the Bezier arc */ 1704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y1 <= y4 ) 1706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymin1 = y1; 1708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymax1 = y4; 1709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymin1 = y4; 1713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymax1 = y1; 1714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y2 <= y3 ) 1717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymin2 = y2; 1719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymax2 = y3; 1720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymin2 = y3; 1724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ymax2 = y2; 1725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ymin2 < ymin1 || ymax2 > ymax1 ) 1728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this arc has no given direction, split it! */ 1730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Split_Cubic( ras.arc ); 1731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc += 3; 1732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( y1 == y4 ) 1734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this arc is flat, ignore it and pop it from the Bezier stack */ 1736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.arc -= 3; 1737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State; 1741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* detect a change of direction */ 1743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.state != state_bez ) 1744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) 1746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : IS_TOP_OVERSHOOT( y1 ); 1747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* finalize current profile if any */ 1750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.state != Unknown_State && 1751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov End_Profile( RAS_VARS o ) ) 1752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( New_Profile( RAS_VARS state_bez, o ) ) 1755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compute intersections */ 1759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( state_bez == Ascending_State ) 1760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) 1762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) 1766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while ( ras.arc >= ras.arcs ); 1770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.lastX = x4; 1772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.lastY = y4; 1773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 1775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 1777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 1778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef SWAP_ 1782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SWAP_( x, y ) do \ 1783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { \ 1784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long swap = x; \ 1785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov \ 1786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov \ 1787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = y; \ 1788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = swap; \ 1789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while ( 0 ) 1790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Decompose_Curve */ 1796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Scan the outline arrays in order to emit individual segments and */ 1799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Beziers by calling Line_To() and Bezier_To(). It handles all */ 1800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* weird cases, like when the first point is off the curve, or when */ 1801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* there are simply no `on' points in the contour! */ 1802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first :: The index of the first point in the contour. */ 1805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* last :: The index of the last point in the contour. */ 1807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* flipped :: If set, flip the direction of the curve. */ 1809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success, FAILURE on error. */ 1812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 1814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Decompose_Curve( RAS_ARGS UShort first, 1815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov UShort last, 1816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int flipped ) 1817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector v_last; 1819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector v_control; 1820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector v_start; 1821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* points; 1823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* point; 1824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* limit; 1825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* tags; 1826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned tag; /* current point's state */ 1828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov points = ras.outline.points; 1831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = points + last; 1832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.x = SCALED( points[first].x ); 1834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.y = SCALED( points[first].y ); 1835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_last.x = SCALED( points[last].x ); 1836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_last.y = SCALED( points[last].y ); 1837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( flipped ) 1839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SWAP_( v_start.x, v_start.y ); 1841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SWAP_( v_last.x, v_last.y ); 1842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control = v_start; 1845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point = points + first; 1847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tags = ras.outline.tags + first; 1848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set scan mode if necessary */ 1850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE ) 1851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.dropOutControl = (Byte)tags[0] >> 5; 1852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tag = FT_CURVE_TAG( tags[0] ); 1854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A contour cannot start with a cubic control point! */ 1856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag == FT_CURVE_TAG_CUBIC ) 1857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Invalid_Outline; 1858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check first point to determine origin */ 1860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag == FT_CURVE_TAG_CONIC ) 1861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first point is conic control. Yes, this happens. */ 1863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON ) 1864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start at last point if it is on the curve */ 1866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start = v_last; 1867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit--; 1868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if both first and last points are conic, */ 1872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start at their middle and record its position */ 1873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for closure */ 1874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.x = ( v_start.x + v_last.x ) / 2; 1875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.y = ( v_start.y + v_last.y ) / 2; 1876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_last = v_start; 1878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point--; 1880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tags--; 1881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.lastX = v_start.x; 1884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.lastY = v_start.y; 1885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( point < limit ) 1887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point++; 1889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tags++; 1890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tag = FT_CURVE_TAG( tags[0] ); 1892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( tag ) 1894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case FT_CURVE_TAG_ON: /* emit a single line_to */ 1896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long x, y; 1898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = SCALED( point->x ); 1901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = SCALED( point->y ); 1902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( flipped ) 1903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SWAP_( x, y ); 1904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Line_To( RAS_VARS x, y ) ) 1906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case FT_CURVE_TAG_CONIC: /* consume conic arcs */ 1911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control.x = SCALED( point[0].x ); 1912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control.y = SCALED( point[0].y ); 1913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( flipped ) 1915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SWAP_( v_control.x, v_control.y ); 1916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Do_Conic: 1918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( point < limit ) 1919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector v_middle; 1921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long x, y; 1922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point++; 1925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tags++; 1926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tag = FT_CURVE_TAG( tags[0] ); 1927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = SCALED( point[0].x ); 1929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = SCALED( point[0].y ); 1930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( flipped ) 1932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SWAP_( x, y ); 1933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag == FT_CURVE_TAG_ON ) 1935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) ) 1937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag != FT_CURVE_TAG_CONIC ) 1942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Invalid_Outline; 1943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_middle.x = ( v_control.x + x ) / 2; 1945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_middle.y = ( v_control.y + y ) / 2; 1946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Conic_To( RAS_VARS v_control.x, v_control.y, 1948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_middle.x, v_middle.y ) ) 1949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control.x = x; 1952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control.y = y; 1953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Do_Conic; 1955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Conic_To( RAS_VARS v_control.x, v_control.y, 1958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.x, v_start.y ) ) 1959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Close; 1962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: /* FT_CURVE_TAG_CUBIC */ 1964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long x1, y1, x2, y2, x3, y3; 1966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( point + 1 > limit || 1969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) 1970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Invalid_Outline; 1971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point += 2; 1973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tags += 2; 1974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x1 = SCALED( point[-2].x ); 1976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y1 = SCALED( point[-2].y ); 1977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x2 = SCALED( point[-1].x ); 1978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y2 = SCALED( point[-1].y ); 1979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( flipped ) 1981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SWAP_( x1, y1 ); 1983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SWAP_( x2, y2 ); 1984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( point <= limit ) 1987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x3 = SCALED( point[0].x ); 1989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y3 = SCALED( point[0].y ); 1990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( flipped ) 1992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov SWAP_( x3, y3 ); 1993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) ) 1995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 1996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) ) 2000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 2001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Close; 2002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* close the contour with a line segment */ 2007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Line_To( RAS_VARS v_start.x, v_start.y ) ) 2008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Fail; 2009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Close: 2011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 2012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Invalid_Outline: 2014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = FT_THROW( Invalid ); 2015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Fail: 2017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 2018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 2024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Convert_Glyph */ 2025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 2027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Convert a glyph into a series of segments and arcs and make a */ 2028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* profiles list with them. */ 2029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 2031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* flipped :: If set, flip the direction of curve. */ 2032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 2034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* SUCCESS on success, FAILURE if any error was encountered during */ 2035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* rendering. */ 2036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 2038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Convert_Glyph( RAS_ARGS int flipped ) 2039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int i; 2041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned start; 2042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.fProfile = NULL; 2045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.joint = FALSE; 2046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.fresh = FALSE; 2047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.maxBuff = ras.sizeBuff - AlignProfileSize; 2049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.numTurns = 0; 2051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile = (PProfile)ras.top; 2053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cProfile->offset = ras.top; 2054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.num_Profs = 0; 2055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = 0; 2057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( i = 0; i < ras.outline.n_contours; i++ ) 2059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile lastProfile; 2061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bool o; 2062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.state = Unknown_State; 2065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gProfile = NULL; 2066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Decompose_Curve( RAS_VARS (unsigned short)start, 2068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.outline.contours[i], 2069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov flipped ) ) 2070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 2071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov start = ras.outline.contours[i] + 1; 2073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we must now check whether the extreme arcs join or not */ 2075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FRAC( ras.lastY ) == 0 && 2076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.lastY >= ras.minY && 2077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.lastY <= ras.maxY ) 2078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.gProfile && 2079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( ras.gProfile->flags & Flow_Up ) == 2080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( ras.cProfile->flags & Flow_Up ) ) 2081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.top--; 2082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note that ras.gProfile can be nil if the contour was too small */ 2083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to be drawn. */ 2084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lastProfile = ras.cProfile; 2086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.cProfile->flags & Flow_Up ) 2087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov o = IS_TOP_OVERSHOOT( ras.lastY ); 2088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov o = IS_BOTTOM_OVERSHOOT( ras.lastY ); 2090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( End_Profile( RAS_VARS o ) ) 2091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 2092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* close the `next profile in contour' linked list */ 2094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.gProfile ) 2095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov lastProfile->next = ras.gProfile; 2096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Finalize_Profile_Table( RAS_VAR ) ) 2099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 2100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE ); 2102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** **/ 2108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** SCAN-LINE SWEEPS AND DRAWING **/ 2109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /** **/ 2110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Init_Linked */ 2117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Initializes an empty linked list. */ 2119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Init_Linked( TProfileList* l ) 2122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *l = NULL; 2124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* InsNew */ 2130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Inserts a new profile in a linked list. */ 2132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov InsNew( PProfileList list, 2135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile profile ) 2136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile *old, current; 2138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long x; 2139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old = list; 2142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current = *old; 2143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = profile->X; 2144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( current ) 2146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x < current->X ) 2148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old = ¤t->link; 2150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current = *old; 2151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov profile->link = current; 2154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *old = profile; 2155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* DelOld */ 2161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Removes an old profile from a linked list. */ 2163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DelOld( PProfileList list, 2166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile profile ) 2167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile *old, current; 2169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old = list; 2172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current = *old; 2173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( current ) 2175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( current == profile ) 2177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *old = current->link; 2179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old = ¤t->link; 2183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current = *old; 2184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we should never get there, unless the profile was not part of */ 2187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the list. */ 2188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Sort */ 2194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Sorts a trace list. In 95%, the list is already sorted. We need */ 2196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* an algorithm which is fast in this case. Bubble sort is enough */ 2197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* and simple. */ 2198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Sort( PProfileList list ) 2201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile *old, current, next; 2203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* First, set the new X coordinate of each profile */ 2206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current = *list; 2207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( current ) 2208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->X = *current->offset; 2210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->offset += current->flags & Flow_Up ? 1 : -1; 2211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->height--; 2212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current = current->link; 2213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Then sort them */ 2216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old = list; 2217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current = *old; 2218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !current ) 2220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov next = current->link; 2223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( next ) 2225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( current->X <= next->X ) 2227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old = ¤t->link; 2229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current = *old; 2230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !current ) 2232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *old = next; 2237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current->link = next->link; 2238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov next->link = current; 2239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov old = list; 2241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov current = *old; 2242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov next = current->link; 2245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Vertical Sweep Procedure Set */ 2252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* These four routines are used during the vertical black/white sweep */ 2254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* phase by the generic Draw_Sweep() function. */ 2255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Vertical_Sweep_Init( RAS_ARGS Short* min, 2260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short* max ) 2261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long pitch = ras.target.pitch; 2263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( max ); 2265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.traceIncr = (Short)-pitch; 2268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.traceOfs = -*min * pitch; 2269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pitch > 0 ) 2270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.traceOfs += ( ras.target.rows - 1 ) * pitch; 2271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_min_x = 0; 2273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_max_x = 0; 2274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Vertical_Sweep_Span( RAS_ARGS Short y, 2279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x1, 2280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x2, 2281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile left, 2282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile right ) 2283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long e1, e2; 2285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Byte* target; 2286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( y ); 2288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( left ); 2289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( right ); 2290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Drop-out control */ 2293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = TRUNC( CEILING( x1 ) ); 2295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x2 - x1 - ras.precision <= ras.precision_jitter ) 2297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = e1; 2298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = TRUNC( FLOOR( x2 ) ); 2300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e2 >= 0 && e1 < ras.bWidth ) 2302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int c1, c2; 2304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Byte f1, f2; 2305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 < 0 ) 2308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = 0; 2309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e2 >= ras.bWidth ) 2310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = ras.bWidth - 1; 2311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c1 = (Short)( e1 >> 3 ); 2313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c2 = (Short)( e2 >> 3 ); 2314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); 2316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); 2317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.gray_min_x > c1 ) 2319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_min_x = (short)c1; 2320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.gray_max_x < c2 ) 2321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_max_x = (short)c2; 2322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov target = ras.bTarget + ras.traceOfs + c1; 2324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c2 -= c1; 2325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( c2 > 0 ) 2327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov target[0] |= f1; 2329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* memset() is slower than the following code on many platforms. */ 2331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This is due to the fact that, in the vast majority of cases, */ 2332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the span length in bytes is relatively small. */ 2333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c2--; 2334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( c2 > 0 ) 2335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *(++target) = 0xFF; 2337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c2--; 2338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov target[1] |= f2; 2340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *target |= ( f1 & f2 ); 2343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Vertical_Sweep_Drop( RAS_ARGS Short y, 2349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x1, 2350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x2, 2351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile left, 2352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile right ) 2353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long e1, e2, pxl; 2355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short c1, f1; 2356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Drop-out control */ 2359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* e2 x2 x1 e1 */ 2361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ^ | */ 2363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | | */ 2364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* +-------------+---------------------+------------+ */ 2365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | | */ 2366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | v */ 2367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* pixel contour contour pixel */ 2369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* center center */ 2370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* drop-out mode scan conversion rules (as defined in OpenType) */ 2372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* --------------------------------------------------------------- */ 2373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 0 1, 2, 3 */ 2374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 1 1, 2, 4 */ 2375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 2 1, 2 */ 2376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 3 same as mode 2 */ 2377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 4 1, 2, 5 */ 2378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 5 1, 2, 6 */ 2379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* 6, 7 same as mode 2 */ 2380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = CEILING( x1 ); 2382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = FLOOR ( x2 ); 2383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = e1; 2384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 > e2 ) 2386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int dropOutControl = left->flags & 7; 2388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 == e2 + ras.precision ) 2391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( dropOutControl ) 2393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 0: /* simple drop-outs including stubs */ 2395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = e2; 2396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 4: /* smart drop-outs including stubs */ 2399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: /* simple drop-outs excluding stubs */ 2403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 5: /* smart drop-outs excluding stubs */ 2404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Drop-out Control Rules #4 and #6 */ 2406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The specification neither provides an exact definition */ 2408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* of a `stub' nor gives exact rules to exclude them. */ 2409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Here the constraints we use to recognize a stub. */ 2411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* upper stub: */ 2413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - P_Left and P_Right are in the same contour */ 2415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - P_Right is the successor of P_Left in that contour */ 2416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - y is the top of P_Left and P_Right */ 2417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* lower stub: */ 2419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - P_Left and P_Right are in the same contour */ 2421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - P_Left is the successor of P_Right in that contour */ 2422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - y is the bottom of P_Left */ 2423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We draw a stub if the following constraints are met. */ 2425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - for an upper or lower stub, there is top or bottom */ 2427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* overshoot, respectively */ 2428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - the covered interval is greater or equal to a half */ 2429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* pixel */ 2430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* upper stub test */ 2432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( left->next == right && 2433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov left->height <= 0 && 2434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !( left->flags & Overshoot_Top && 2435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x2 - x1 >= ras.precision_half ) ) 2436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* lower stub test */ 2439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( right->next == left && 2440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov left->start == y && 2441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !( left->flags & Overshoot_Bottom && 2442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x2 - x1 >= ras.precision_half ) ) 2443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dropOutControl == 1 ) 2446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = e2; 2447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: /* modes 2, 3, 6, 7 */ 2452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; /* no drop-out control */ 2453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* undocumented but confirmed: If the drop-out would result in a */ 2456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* pixel outside of the bounding box, use the pixel inside of the */ 2457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* bounding box instead */ 2458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pxl < 0 ) 2459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = e1; 2460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( TRUNC( pxl ) >= ras.bWidth ) 2461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = e2; 2462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that the other pixel isn't set */ 2464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = pxl == e1 ? e2 : e1; 2465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = TRUNC( e1 ); 2467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c1 = (Short)( e1 >> 3 ); 2469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f1 = (Short)( e1 & 7 ); 2470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 >= 0 && e1 < ras.bWidth && 2472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) 2473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = TRUNC( pxl ); 2480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 >= 0 && e1 < ras.bWidth ) 2482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c1 = (Short)( e1 >> 3 ); 2484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f1 = (Short)( e1 & 7 ); 2485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.gray_min_x > c1 ) 2487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_min_x = c1; 2488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.gray_max_x < c1 ) 2489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_max_x = c1; 2490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); 2492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Vertical_Sweep_Step( RAS_ARG ) 2498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.traceOfs += ras.traceIncr; 2500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***********************************************************************/ 2504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Horizontal Sweep Procedure Set */ 2506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* These four routines are used during the horizontal black/white */ 2508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* sweep phase by the generic Draw_Sweep() function. */ 2509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /***********************************************************************/ 2511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Horizontal_Sweep_Init( RAS_ARGS Short* min, 2514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short* max ) 2515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* nothing, really */ 2517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED_RASTER; 2518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( min ); 2519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( max ); 2520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Horizontal_Sweep_Span( RAS_ARGS Short y, 2525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x1, 2526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x2, 2527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile left, 2528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile right ) 2529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( left ); 2531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( right ); 2532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x2 - x1 < ras.precision ) 2535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long e1, e2; 2537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = CEILING( x1 ); 2540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = FLOOR ( x2 ); 2541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 == e2 ) 2543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Byte f1; 2545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PByte bits; 2546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bits = ras.bTarget + ( y >> 3 ); 2549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = TRUNC( e1 ); 2552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 >= 0 && e1 < ras.target.rows ) 2554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PByte p; 2556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = bits - e1 * ras.target.pitch; 2559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.target.pitch > 0 ) 2560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p += ( ras.target.rows - 1 ) * ras.target.pitch; 2561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p[0] |= f1; 2563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Horizontal_Sweep_Drop( RAS_ARGS Short y, 2571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x1, 2572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x2, 2573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile left, 2574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile right ) 2575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long e1, e2, pxl; 2577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PByte bits; 2578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Byte f1; 2579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* During the horizontal sweep, we only take care of drop-outs */ 2582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* e1 + <-- pixel center */ 2584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | */ 2585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* x1 ---+--> <-- contour */ 2586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | */ 2587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | */ 2588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* x2 <--+--- <-- contour */ 2589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | */ 2590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* | */ 2591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* e2 + <-- pixel center */ 2592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = CEILING( x1 ); 2594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = FLOOR ( x2 ); 2595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = e1; 2596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 > e2 ) 2598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int dropOutControl = left->flags & 7; 2600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 == e2 + ras.precision ) 2603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( dropOutControl ) 2605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 0: /* simple drop-outs including stubs */ 2607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = e2; 2608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 4: /* smart drop-outs including stubs */ 2611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: /* simple drop-outs excluding stubs */ 2615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 5: /* smart drop-outs excluding stubs */ 2616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* see Vertical_Sweep_Drop for details */ 2617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* rightmost stub test */ 2619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( left->next == right && 2620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov left->height <= 0 && 2621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !( left->flags & Overshoot_Top && 2622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x2 - x1 >= ras.precision_half ) ) 2623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* leftmost stub test */ 2626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( right->next == left && 2627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov left->start == y && 2628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov !( left->flags & Overshoot_Bottom && 2629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x2 - x1 >= ras.precision_half ) ) 2630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dropOutControl == 1 ) 2633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = e2; 2634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: /* modes 2, 3, 6, 7 */ 2639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; /* no drop-out control */ 2640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* undocumented but confirmed: If the drop-out would result in a */ 2643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* pixel outside of the bounding box, use the pixel inside of the */ 2644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* bounding box instead */ 2645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pxl < 0 ) 2646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = e1; 2647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( TRUNC( pxl ) >= ras.target.rows ) 2648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pxl = e2; 2649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check that the other pixel isn't set */ 2651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = pxl == e1 ? e2 : e1; 2652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = TRUNC( e1 ); 2654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bits = ras.bTarget + ( y >> 3 ); 2656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bits -= e1 * ras.target.pitch; 2659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.target.pitch > 0 ) 2660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bits += ( ras.target.rows - 1 ) * ras.target.pitch; 2661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 >= 0 && 2663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 < ras.target.rows && 2664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *bits & f1 ) 2665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bits = ras.bTarget + ( y >> 3 ); 2672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = TRUNC( pxl ); 2675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 >= 0 && e1 < ras.target.rows ) 2677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bits -= e1 * ras.target.pitch; 2679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.target.pitch > 0 ) 2680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bits += ( ras.target.rows - 1 ) * ras.target.pitch; 2681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bits[0] |= f1; 2683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Horizontal_Sweep_Step( RAS_ARG ) 2689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Nothing, really */ 2691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED_RASTER; 2692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_RASTER_OPTION_ANTI_ALIASING 2696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Vertical Gray Sweep Procedure Set */ 2701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* These two routines are used during the vertical gray-levels sweep */ 2703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* phase by the generic Draw_Sweep() function. */ 2704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* NOTES */ 2706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - The target pixmap's width *must* be a multiple of 4. */ 2708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - You have to use the function Vertical_Sweep_Span() for the gray */ 2710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* span call. */ 2711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, 2716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short* max ) 2717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long pitch, byte_len; 2719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *min = *min & -2; 2722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *max = ( *max + 3 ) & -2; 2723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.traceOfs = 0; 2725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pitch = ras.target.pitch; 2726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov byte_len = -pitch; 2727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.traceIncr = (Short)byte_len; 2728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.traceG = ( *min / 2 ) * byte_len; 2729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pitch > 0 ) 2731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.traceG += ( ras.target.rows - 1 ) * pitch; 2733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov byte_len = -byte_len; 2734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_min_x = (Short)byte_len; 2737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_max_x = -(Short)byte_len; 2738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Vertical_Gray_Sweep_Step( RAS_ARG ) 2743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov short* count = (short*)count_table; 2745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Byte* grays; 2746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.traceOfs += ras.gray_width; 2749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.traceOfs > ras.gray_width ) 2751ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PByte pix; 2753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; 2756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov grays = ras.grays; 2757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.gray_max_x >= 0 ) 2759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long last_pixel = ras.target.width - 1; 2761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int last_cell = last_pixel >> 2; 2762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int last_bit = last_pixel & 3; 2763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Bool over = 0; 2764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int c1, c2; 2766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PByte bit, bit2; 2767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.gray_max_x >= last_cell && last_bit != 3 ) 2770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_max_x = last_cell - 1; 2772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov over = 1; 2773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.gray_min_x < 0 ) 2776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_min_x = 0; 2777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bit = ras.bTarget + ras.gray_min_x; 2779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bit2 = bit + ras.gray_width; 2780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c1 = ras.gray_max_x - ras.gray_min_x; 2782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( c1 >= 0 ) 2784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c2 = count[*bit] + count[*bit2]; 2786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( c2 ) 2788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pix[0] = grays[(c2 >> 12) & 0x000F]; 2790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pix[1] = grays[(c2 >> 8 ) & 0x000F]; 2791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pix[2] = grays[(c2 >> 4 ) & 0x000F]; 2792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pix[3] = grays[ c2 & 0x000F]; 2793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *bit = 0; 2795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *bit2 = 0; 2796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bit++; 2799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bit2++; 2800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pix += 4; 2801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c1--; 2802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( over ) 2805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c2 = count[*bit] + count[*bit2]; 2807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( c2 ) 2808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( last_bit ) 2810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 2: 2812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pix[2] = grays[(c2 >> 4 ) & 0x000F]; 2813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: 2814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pix[1] = grays[(c2 >> 8 ) & 0x000F]; 2815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 2816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pix[0] = grays[(c2 >> 12) & 0x000F]; 2817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *bit = 0; 2820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *bit2 = 0; 2821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.traceOfs = 0; 2826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.traceG += ras.traceIncr; 2827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_min_x = 32000; 2829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_max_x = -32000; 2830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, 2836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x1, 2837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x2, 2838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile left, 2839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile right ) 2840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* nothing, really */ 2842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED_RASTER; 2843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( y ); 2844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( x1 ); 2845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( x2 ); 2846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( left ); 2847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( right ); 2848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, 2853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x1, 2854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_F26Dot6 x2, 2855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile left, 2856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile right ) 2857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long e1, e2; 2859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PByte pixel; 2860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* During the horizontal sweep, we only take care of drop-outs */ 2863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = CEILING( x1 ); 2865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = FLOOR ( x2 ); 2866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 > e2 ) 2868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int dropOutControl = left->flags & 7; 2870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 == e2 + ras.precision ) 2873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( dropOutControl ) 2875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 0: /* simple drop-outs including stubs */ 2877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = e2; 2878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 4: /* smart drop-outs including stubs */ 2881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: /* simple drop-outs excluding stubs */ 2885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 5: /* smart drop-outs excluding stubs */ 2886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* see Vertical_Sweep_Drop for details */ 2887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* rightmost stub test */ 2889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( left->next == right && left->height <= 0 ) 2890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* leftmost stub test */ 2893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( right->next == left && left->start == y ) 2894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dropOutControl == 1 ) 2897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = e2; 2898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 2902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: /* modes 2, 3, 6, 7 */ 2904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; /* no drop-out control */ 2905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 2909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 >= 0 ) 2912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Byte color; 2914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x2 - x1 >= ras.precision_half ) 2917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov color = ras.grays[2]; 2918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov color = ras.grays[1]; 2920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = TRUNC( e1 ) / 2; 2922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 < ras.target.rows ) 2923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; 2925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.target.pitch > 0 ) 2926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pixel += ( ras.target.rows - 1 ) * ras.target.pitch; 2927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pixel[0] == ras.grays[0] ) 2929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pixel[0] = color; 2930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ 2936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Generic Sweep Drawing routine */ 2941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 2942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 2943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static Bool 2945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Draw_Sweep( RAS_ARG ) 2946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short y, y_change, y_height; 2948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PProfile P, Q, P_Left, P_Right; 2950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short min_Y, max_Y, top, bottom, dropouts; 2952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long x1, x2, xs, e1, e2; 2954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TProfileList waiting; 2956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TProfileList draw_left, draw_right; 2957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* initialize empty linked lists */ 2960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Init_Linked( &waiting ); 2962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Init_Linked( &draw_left ); 2964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Init_Linked( &draw_right ); 2965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first, compute min and max Y */ 2967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P = ras.fProfile; 2969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_Y = (Short)TRUNC( ras.minY ); 2970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min_Y = (Short)TRUNC( ras.maxY ); 2971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( P ) 2973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Q = P->link; 2975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bottom = (Short)P->start; 2977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top = (Short)( P->start + P->height - 1 ); 2978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( min_Y > bottom ) 2980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min_Y = bottom; 2981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( max_Y < top ) 2982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_Y = top; 2983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P->X = 0; 2985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov InsNew( &waiting, P ); 2986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P = Q; 2988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check the Y-turns */ 2991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.numTurns == 0 ) 2992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = FT_THROW( Invalid ); 2994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 2995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now initialize the sweep */ 2998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); 3000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* then compute the distance of each profile from min_Y */ 3002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P = waiting; 3004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( P ) 3006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P->countL = (UShort)( P->start - min_Y ); 3008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P = P->link; 3009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* let's go */ 3012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = min_Y; 3014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_height = 0; 3015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.numTurns > 0 && 3017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.sizeBuff[-ras.numTurns] == min_Y ) 3018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.numTurns--; 3019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( ras.numTurns > 0 ) 3021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check waiting list for new activations */ 3023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P = waiting; 3025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( P ) 3027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Q = P->link; 3029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P->countL -= y_height; 3030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( P->countL == 0 ) 3031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DelOld( &waiting, P ); 3033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( P->flags & Flow_Up ) 3035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov InsNew( &draw_left, P ); 3036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov InsNew( &draw_right, P ); 3038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P = Q; 3041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* sort the drawing lists */ 3044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Sort( &draw_left ); 3046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Sort( &draw_right ); 3047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_change = (Short)ras.sizeBuff[-ras.numTurns--]; 3049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y_height = (Short)( y_change - y ); 3050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( y < y_change ) 3052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* let's trace */ 3054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dropouts = 0; 3056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Left = draw_left; 3058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Right = draw_right; 3059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( P_Left ) 3061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x1 = P_Left ->X; 3063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x2 = P_Right->X; 3064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x1 > x2 ) 3066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov xs = x1; 3068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x1 = x2; 3069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x2 = xs; 3070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 = FLOOR( x1 ); 3073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e2 = CEILING( x2 ); 3074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x2 - x1 <= ras.precision && 3076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov e1 != x1 && e2 != x2 ) 3077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( e1 > e2 || e2 == e1 + ras.precision ) 3079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Int dropOutControl = P_Left->flags & 7; 3081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dropOutControl != 2 ) 3084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* a drop-out was detected */ 3086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Left ->X = x1; 3088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Right->X = x2; 3089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* mark profile for drop-out processing */ 3091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Left->countL = 1; 3092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dropouts++; 3093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Skip_To_Next; 3096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right ); 3100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Skip_To_Next: 3102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Left = P_Left->link; 3104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Right = P_Right->link; 3105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* handle drop-outs _after_ the span drawing -- */ 3108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* drop-out processing has been moved out of the loop */ 3109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for performance tuning */ 3110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dropouts > 0 ) 3111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Scan_DropOuts; 3112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Next_Line: 3114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Step( RAS_VAR ); 3116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y++; 3118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y < y_change ) 3120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Sort( &draw_left ); 3122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Sort( &draw_right ); 3123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* now finalize the profiles that need it */ 3127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P = draw_left; 3129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( P ) 3130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Q = P->link; 3132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( P->height == 0 ) 3133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DelOld( &draw_left, P ); 3134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P = Q; 3135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P = draw_right; 3138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( P ) 3139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Q = P->link; 3141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( P->height == 0 ) 3142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov DelOld( &draw_right, P ); 3143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P = Q; 3144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for gray-scaling, flush the bitmap scanline cache */ 3148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( y <= max_Y ) 3149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Step( RAS_VAR ); 3151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y++; 3152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 3155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Scan_DropOuts: 3157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Left = draw_left; 3159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Right = draw_right; 3160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( P_Left ) 3162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( P_Left->countL ) 3164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Left->countL = 0; 3166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if 0 3167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dropouts--; /* -- this is useful when debugging only */ 3168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 3169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Drop( RAS_VARS y, 3170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Left->X, 3171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Right->X, 3172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Left, 3173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Right ); 3174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Left = P_Left->link; 3177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov P_Right = P_Right->link; 3178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Next_Line; 3181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 3185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 3187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Render_Single_Pass */ 3188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 3190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Perform one sweep with sub-banding. */ 3191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 3193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* flipped :: If set, flip the direction of the outline. */ 3194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 3196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Renderer error code. */ 3197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 3199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Render_Single_Pass( RAS_ARGS Bool flipped ) 3200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Short i, j, k; 3202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( ras.band_top >= 0 ) 3205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision; 3207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision; 3208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.top = ras.buff; 3210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = Raster_Err_None; 3212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Convert_Glyph( RAS_VARS flipped ) ) 3214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.error != Raster_Err_Overflow ) 3216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FAILURE; 3217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = Raster_Err_None; 3219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* sub-banding */ 3221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef DEBUG_RASTER 3223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) ); 3224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 3225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov i = ras.band_stack[ras.band_top].y_min; 3227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov j = ras.band_stack[ras.band_top].y_max; 3228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov k = (Short)( ( i + j ) / 2 ); 3230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.band_top >= 7 || k < i ) 3232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_top = 0; 3234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.error = FT_THROW( Invalid ); 3235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ras.error; 3237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_stack[ras.band_top + 1].y_min = k; 3240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_stack[ras.band_top + 1].y_max = j; 3241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_stack[ras.band_top].y_max = (Short)( k - 1 ); 3243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_top++; 3245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.fProfile ) 3249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( Draw_Sweep( RAS_VAR ) ) 3250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ras.error; 3251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_top--; 3252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return SUCCESS; 3256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 3260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 3262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Render_Glyph */ 3263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 3265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Render a glyph in a bitmap. Sub-banding if needed. */ 3266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 3268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 3269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 3271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Render_Glyph( RAS_ARG ) 3272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 3274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Set_High_Precision( RAS_VARS ras.outline.flags & 3277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_OUTLINE_HIGH_PRECISION ); 3278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.scale_shift = ras.precision_shift; 3279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) 3281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.dropOutControl = 2; 3282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) 3285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.dropOutControl = 4; 3286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.dropOutControl = 0; 3288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) 3290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.dropOutControl += 1; 3291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.second_pass = (FT_Byte)( !( ras.outline.flags & 3294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_OUTLINE_SINGLE_PASS ) ); 3295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Vertical Sweep */ 3297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Init = Vertical_Sweep_Init; 3298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Span = Vertical_Sweep_Span; 3299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; 3300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Step = Vertical_Sweep_Step; 3301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_top = 0; 3303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_stack[0].y_min = 0; 3304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_stack[0].y_max = (short)( ras.target.rows - 1 ); 3305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.bWidth = (unsigned short)ras.target.width; 3307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.bTarget = (Byte*)ras.target.buffer; 3308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) 3310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 3311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Horizontal Sweep */ 3313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.second_pass && ras.dropOutControl != 2 ) 3314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Init = Horizontal_Sweep_Init; 3316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Span = Horizontal_Sweep_Span; 3317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; 3318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Step = Horizontal_Sweep_Step; 3319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_top = 0; 3321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_stack[0].y_min = 0; 3322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_stack[0].y_max = (short)( ras.target.width - 1 ); 3323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) 3325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 3326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return Raster_Err_None; 3329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_RASTER_OPTION_ANTI_ALIASING 3333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 3335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 3337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Render_Gray_Glyph */ 3338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 3340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Render a glyph with grayscaling. Sub-banding if needed. */ 3341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 3343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FreeType error code. 0 means success. */ 3344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 3345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 3346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Render_Gray_Glyph( RAS_ARG ) 3347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Long pixel_width; 3349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 3350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Set_High_Precision( RAS_VARS ras.outline.flags & 3353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_OUTLINE_HIGH_PRECISION ); 3354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.scale_shift = ras.precision_shift + 1; 3355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) 3357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.dropOutControl = 2; 3358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) 3361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.dropOutControl = 4; 3362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.dropOutControl = 0; 3364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) 3366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.dropOutControl += 1; 3367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); 3370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Vertical Sweep */ 3372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_top = 0; 3374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_stack[0].y_min = 0; 3375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_stack[0].y_max = 2 * ras.target.rows - 1; 3376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.bWidth = ras.gray_width; 3378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); 3379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.bWidth > pixel_width ) 3381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.bWidth = pixel_width; 3382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.bWidth = ras.bWidth * 8; 3384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.bTarget = (Byte*)ras.gray_lines; 3385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gTarget = (Byte*)ras.target.buffer; 3386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; 3388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Span = Vertical_Sweep_Span; 3389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; 3390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; 3391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = Render_Single_Pass( RAS_VARS 0 ); 3393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 3394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 3395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Horizontal Sweep */ 3397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.second_pass && ras.dropOutControl != 2 ) 3398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Init = Horizontal_Sweep_Init; 3400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; 3401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; 3402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.Proc_Sweep_Step = Horizontal_Sweep_Step; 3403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_top = 0; 3405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_stack[0].y_min = 0; 3406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_stack[0].y_max = ras.target.width * 2 - 1; 3407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = Render_Single_Pass( RAS_VARS 1 ); 3409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 3410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 3411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return Raster_Err_None; 3414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !FT_RASTER_OPTION_ANTI_ALIASING */ 3417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_LOCAL_DEF( FT_Error ) 3419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Render_Gray_Glyph( RAS_ARG ) 3420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED_RASTER; 3422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unsupported ); 3424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */ 3427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 3430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_black_init( black_PRaster raster ) 3431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_RASTER_OPTION_ANTI_ALIASING 3433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UInt n; 3434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set default 5-levels gray palette */ 3437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < 5; n++ ) 3438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->grays[n] = n * 255 / 4; 3439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->gray_width = RASTER_GRAY_LINES / 2; 3441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 3442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( raster ); 3443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 3444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ 3448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** a static object. *****/ 3449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _STANDALONE_ 3452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 3455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_black_new( void* memory, 3456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Raster *araster ) 3457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static black_TRaster the_raster; 3459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( memory ); 3460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *araster = (FT_Raster)&the_raster; 3463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); 3464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_black_init( &the_raster ); 3465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 3467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 3471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_black_done( FT_Raster raster ) 3472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* nothing */ 3474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( raster ); 3475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !_STANDALONE_ */ 3479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 3482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_black_new( FT_Memory memory, 3483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov black_PRaster *araster ) 3484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 3486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov black_PRaster raster = NULL; 3487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *araster = 0; 3490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_NEW( raster ) ) 3491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->memory = memory; 3493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_black_init( raster ); 3494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *araster = raster; 3496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 3499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 3503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_black_done( black_PRaster raster ) 3504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = (FT_Memory)raster->memory; 3506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( raster ); 3509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !_STANDALONE_ */ 3513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 3516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_black_reset( black_PRaster raster, 3517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* pool_base, 3518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov long pool_size ) 3519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( raster ) 3521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( pool_base && pool_size >= (long)sizeof ( black_TWorker ) + 2048 ) 3523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov black_PWorker worker = (black_PWorker)pool_base; 3525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->buffer = pool_base + ( ( sizeof ( *worker ) + 7 ) & ~7 ); 3528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->buffer_size = (long)( pool_base + pool_size - 3529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (char*)raster->buffer ); 3530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->worker = worker; 3531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 3533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->buffer = NULL; 3535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->buffer_size = 0; 3536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->worker = NULL; 3537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 3543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_black_set_mode( black_PRaster raster, 3544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned long mode, 3545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* palette ) 3546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_RASTER_OPTION_ANTI_ALIASING 3548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) 3550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set 5-levels gray palette */ 3552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->grays[0] = palette[0]; 3553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->grays[1] = palette[1]; 3554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->grays[2] = palette[2]; 3555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->grays[3] = palette[3]; 3556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->grays[4] = palette[4]; 3557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 3560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( raster ); 3562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( mode ); 3563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( palette ); 3564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 3566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 3570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_black_render( black_PRaster raster, 3571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Raster_Params* params ) 3572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 3573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Outline* outline = (const FT_Outline*)params->source; 3574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Bitmap* target_map = params->target; 3575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov black_PWorker worker; 3576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !raster || !raster->buffer || !raster->buffer_size ) 3579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Not_Ini ); 3580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !outline ) 3582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid ); 3583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* return immediately if the outline is empty */ 3585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( outline->n_points == 0 || outline->n_contours <= 0 ) 3586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return Raster_Err_None; 3587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !outline->contours || !outline->points ) 3589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid ); 3590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( outline->n_points != 3592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outline->contours[outline->n_contours - 1] + 1 ) 3593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid ); 3594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov worker = raster->worker; 3596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this version of the raster does not support direct rendering, sorry */ 3598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( params->flags & FT_RASTER_FLAG_DIRECT ) 3599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Unsupported ); 3600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !target_map ) 3602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid ); 3603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* nothing to do */ 3605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !target_map->width || !target_map->rows ) 3606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return Raster_Err_None; 3607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !target_map->buffer ) 3609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid ); 3610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.outline = *outline; 3612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.target = *target_map; 3613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov worker->buff = (PLong) raster->buffer; 3615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov worker->sizeBuff = worker->buff + 3616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->buffer_size / sizeof ( Long ); 3617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_RASTER_OPTION_ANTI_ALIASING 3618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov worker->grays = raster->grays; 3619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov worker->gray_width = raster->gray_width; 3620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 ); 3622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 3623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return ( params->flags & FT_RASTER_FLAG_AA ) 3625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ? Render_Gray_Glyph( RAS_VAR ) 3626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov : Render_Glyph( RAS_VAR ); 3627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 3628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_DEFINE_RASTER_FUNCS( ft_standard_raster, 3631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GLYPH_FORMAT_OUTLINE, 3632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Raster_New_Func) ft_black_new, 3633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Raster_Reset_Func) ft_black_reset, 3634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Raster_Set_Mode_Func)ft_black_set_mode, 3635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Raster_Render_Func) ft_black_render, 3636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Raster_Done_Func) ft_black_done 3637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ) 3638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 3640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 3641