ftraster.c revision 174b8de3283c921d8bddf48325fe42ba7330a930
1a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/***************************************************************************/ 2a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* */ 3a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* ftraster.c */ 4a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* */ 5a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* The FreeType glyph rasterizer (body). */ 6a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* */ 7eca1f2790578ce8e9907ef3373ab69b7816b3093Werner Lemberg/* Copyright 1996-2001, 2002, 2003, 2005, 2007, 2008 by */ 8a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* */ 10a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* This file is part of the FreeType project, and may only be used, */ 11a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* modified, and distributed under the terms of the FreeType project */ 12a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* this file you indicate that you have read the license and */ 14a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* understand and accept it fully. */ 15a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* */ 16a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/***************************************************************************/ 17a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 18a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 19a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 20f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* This file can be compiled without the rest of the FreeType engine, by */ 21f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* defining the _STANDALONE_ macro when compiling it. You also need to */ 22f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* put the files `ftimage.h' and `ftmisc.h' into the $(incdir) */ 23f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* directory. Typically, you should do something like */ 24f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* */ 25f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* - copy `src/raster/ftraster.c' (this file) to your current directory */ 26f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* */ 27f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' */ 28f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* to your current directory */ 29f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* */ 30f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* - compile `ftraster' with the _STANDALONE_ macro defined, as in */ 31f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* */ 32f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* cc -c -D_STANDALONE_ ftraster.c */ 33f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* */ 34f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* The renderer can be initialized with a call to */ 35f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* `ft_standard_raster.raster_new'; a bitmap can be generated */ 36f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* with a call to `ft_standard_raster.raster_render'. */ 37f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* */ 38f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* See the comments and documentation in the file `ftimage.h' for more */ 39f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* details on how the raster works. */ 40f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* */ 41f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /*************************************************************************/ 42f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg 43f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg 44f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /*************************************************************************/ 45f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* */ 46a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This is a rewrite of the FreeType 1.x scan-line converter */ 47a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 48a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 49a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 50f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#ifdef _STANDALONE_ 51f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg 52f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#include "ftmisc.h" 53f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#include "ftimage.h" 54f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg 55f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#else /* !_STANDALONE_ */ 56a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5719ed8afe60bbc5becf0fbbe3987a91b35a36aad4David Turner#include <ft2build.h> 588d3a401fa808a8c70bd6a9ce17d5a840fb0ae2dbDavid Turner#include "ftraster.h" 5919ed8afe60bbc5becf0fbbe3987a91b35a36aad4David Turner#include FT_INTERNAL_CALC_H /* for FT_MulDiv only */ 60a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 61f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#endif /* !_STANDALONE_ */ 62f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg 63a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 64a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 65a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 66a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* A simple technical note on how the raster works */ 67a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* ----------------------------------------------- */ 68a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 69a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Converting an outline into a bitmap is achieved in several steps: */ 70a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 71a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* 1 - Decomposing the outline into successive `profiles'. Each */ 72a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile is simply an array of scanline intersections on a given */ 73a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* dimension. A profile's main attributes are */ 74a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 75a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* o its scanline position boundaries, i.e. `Ymin' and `Ymax'. */ 76a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 77a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* o an array of intersection coordinates for each scanline */ 78a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* between `Ymin' and `Ymax'. */ 79a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 80a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* o a direction, indicating whether it was built going `up' or */ 81a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* `down', as this is very important for filling rules. */ 82a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 83a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* 2 - Sweeping the target map's scanlines in order to compute segment */ 84a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* `spans' which are then filled. Additionally, this pass */ 85a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* performs drop-out control. */ 86a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 87a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The outline data is parsed during step 1 only. The profiles are */ 88a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* built from the bottom of the render pool, used as a stack. The */ 89a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* following graphics shows the profile list under construction: */ 90a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 91a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* ____________________________________________________________ _ _ */ 92a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* | | | | | */ 93a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* | profile | coordinates for | profile | coordinates for |--> */ 94a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* | 1 | profile 1 | 2 | profile 2 |--> */ 95a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* |_________|___________________|_________|_________________|__ _ _ */ 96a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 97a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* ^ ^ */ 98a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* | | */ 99a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* start of render pool top */ 100a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 101a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The top of the profile stack is kept in the `top' variable. */ 102a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 103a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* As you can see, a profile record is pushed on top of the render */ 104a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* pool, which is then followed by its coordinates/intersections. If */ 105a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* a change of direction is detected in the outline, a new profile is */ 106a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* generated until the end of the outline. */ 107a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 108a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Note that when all profiles have been generated, the function */ 109a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Finalize_Profile_Table() is used to record, for each profile, its */ 110a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* bottom-most scanline as well as the scanline above its upmost */ 111a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* boundary. These positions are called `y-turns' because they (sort */ 112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* of) correspond to local extrema. They are stored in a sorted list */ 113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* built from the top of the render pool as a downwards stack: */ 114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 115a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* _ _ _______________________________________ */ 116a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* | | */ 117a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <--| sorted list of | */ 118a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <--| extrema scanlines | */ 119a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* _ _ __________________|____________________| */ 120a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 121a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* ^ ^ */ 122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* | | */ 123a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxBuff sizeBuff = end of pool */ 124a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 125a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This list is later used during the sweep phase in order to */ 126a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* optimize performance (see technical note on the sweep below). */ 127a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 128a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Of course, the raster detects whether the two stacks collide and */ 1296e87ed9f04f7914e15f9284b0b762b730222c399Werner Lemberg /* handles the situation properly. */ 130a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 131a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 132a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 136a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 137a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** CONFIGURATION MACROS **/ 138a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 141a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 142a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* define DEBUG_RASTER if you want to compile a debugging version */ 143a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define xxxDEBUG_RASTER 144a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 145a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* undefine FT_RASTER_OPTION_ANTI_ALIASING if you do not want to support */ 146a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* 5-levels anti-aliasing */ 147eca1f2790578ce8e9907ef3373ab69b7816b3093Werner Lemberg#undef FT_RASTER_OPTION_ANTI_ALIASING 148a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 149a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The size of the two-lines intermediate bitmap used */ 150a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* for anti-aliasing, in bytes. */ 151a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RASTER_GRAY_LINES 2048 152a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 153a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 154a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 155a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 156a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 157a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** OTHER MACROS (do not change) **/ 158a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 159a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 160a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 161a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 162a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 163a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 164a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 165a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 166a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* messages during execution. */ 167a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 168a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#undef FT_COMPONENT 169a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FT_COMPONENT trace_raster 170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 172a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef _STANDALONE_ 173a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 174a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 175a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This macro is used to indicate that a function parameter is unused. */ 176a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Its purpose is simply to reduce compiler warnings. Note also that */ 177a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* simply defining it as `(void)x' doesn't avoid warnings with certain */ 178a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* ANSI compilers (e.g. LCC). */ 179a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FT_UNUSED( x ) (x) = (x) 180a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 181a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Disable the tracing mechanism for simplicity -- developers can */ 182a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* activate it easily by redefining these two macros. */ 183a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FT_ERROR 184a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FT_ERROR( x ) do ; while ( 0 ) /* nothing */ 185a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 186a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 187a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FT_TRACE 188f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#define FT_TRACE( x ) do ; while ( 0 ) /* nothing */ 189f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#define FT_TRACE1( x ) do ; while ( 0 ) /* nothing */ 190f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#define FT_TRACE6( x ) do ; while ( 0 ) /* nothing */ 191a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 192a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 193a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_None 0 194a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Not_Ini -1 195a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Overflow -2 196a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Neg_Height -3 197a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Invalid -4 198a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Unsupported -5 199a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 200f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#define ft_memset memset 201a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 202a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#else /* _STANDALONE_ */ 203a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 204a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2051f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#include FT_INTERNAL_OBJECTS_H 2061f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#include FT_INTERNAL_DEBUG_H /* for FT_TRACE() and FT_ERROR() */ 207a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2081f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#include "rasterrs.h" 2091f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg 2101f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_None Raster_Err_Ok 2111f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized 2121f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Overflow Raster_Err_Raster_Overflow 2131f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height 2141f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Invalid Raster_Err_Invalid_Outline 2151f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph 216a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 217a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 218a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif /* _STANDALONE_ */ 219a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 220a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 221e459d742e6236df43f542b8c29dfdcf05d69716cDavid Turner#ifndef FT_MEM_SET 222d15bc0d13a163995e1ca11925349bd64d1c33617David Turner#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) 223c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg#endif 224c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg 225f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#ifndef FT_MEM_ZERO 226f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) 227f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#endif 228c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg 229a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ 230a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* typically a small value and the result of a*b is known to fit into */ 231a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* 32 bits. */ 232a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) 233a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 234a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ 235a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* for clipping computations. It simply uses the FT_MulDiv() function */ 236a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* defined in `ftcalc.h'. */ 237a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define SMulDiv FT_MulDiv 238a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 239a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The rasterizer is a very general purpose component; please leave */ 240a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the following redefinitions there (you never know your target */ 241a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* environment). */ 242a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 243a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef TRUE 244a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define TRUE 1 245a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 246a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 247a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FALSE 248a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FALSE 0 249a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 250a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 251a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef NULL 252a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define NULL (void*)0 253a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 254a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 255a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef SUCCESS 256a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define SUCCESS 0 257a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 258a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 259a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FAILURE 260a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FAILURE 1 261a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 262a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 263a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 264a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define MaxBezier 32 /* The maximum number of stacked Bezier curves. */ 265a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Setting this constant to more than 32 is a */ 266a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* pure waste of space. */ 267a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 268a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Pixel_Bits 6 /* fractional bits of *input* coordinates */ 269a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 270a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 271a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 272a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 273a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 274a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** SIMPLE TYPE DECLARATIONS **/ 275a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 276a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 277a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 278a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 279a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef int Int; 280a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef unsigned int UInt; 281a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef short Short; 282a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef unsigned short UShort, *PUShort; 283a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef long Long, *PLong; 284a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef unsigned long ULong; 285a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 286a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef unsigned char Byte, *PByte; 287a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef char Bool; 288a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 289fefd8742928491a9da356cc1c37f434c76d73514Werner Lemberg 290fefd8742928491a9da356cc1c37f434c76d73514Werner Lemberg typedef union Alignment_ 2918530a228889128adfd446514928f36663ed20f04David Turner { 2928530a228889128adfd446514928f36663ed20f04David Turner long l; 2938530a228889128adfd446514928f36663ed20f04David Turner void* p; 2948530a228889128adfd446514928f36663ed20f04David Turner void (*f)(void); 2958530a228889128adfd446514928f36663ed20f04David Turner 2968530a228889128adfd446514928f36663ed20f04David Turner } Alignment, *PAlignment; 2978530a228889128adfd446514928f36663ed20f04David Turner 298fefd8742928491a9da356cc1c37f434c76d73514Werner Lemberg 299a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef struct TPoint_ 300a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 301a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x; 302a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y; 303a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 304a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } TPoint; 305a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 306a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 307a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef enum TFlow_ 308a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 309a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Flow_None = 0, 310a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Flow_Up = 1, 311a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Flow_Down = -1 312a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 313a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } TFlow; 314a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 315a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 316a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* States of each line, arc, and profile */ 317a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef enum TStates_ 318a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3199ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Unknown_State, 3209ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Ascending_State, 3219ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Descending_State, 3229ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Flat_State 323a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 324a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } TStates; 325a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 326a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 327a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef struct TProfile_ TProfile; 328a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef TProfile* PProfile; 329a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 330a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner struct TProfile_ 331a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 332a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_F26Dot6 X; /* current coordinate during sweep */ 333a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile link; /* link to next profile - various purpose */ 334a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PLong offset; /* start of profile's data in render pool */ 3358edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner int flow; /* Profile orientation: Asc/Descending */ 3368edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner long height; /* profile's height in scanlines */ 3378edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner long start; /* profile's starting scanline */ 338a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3398edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner unsigned countL; /* number of lines to step before this */ 340a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile becomes drawable */ 341a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 342a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile next; /* next profile in same contour, used */ 343a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* during drop-out control */ 344a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner }; 345a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 346a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef PProfile TProfileList; 347a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef PProfile* PProfileList; 348a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 349a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 350a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Simple record used to implement a stack of bands, required */ 351a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* by the sub-banding mechanism */ 352a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef struct TBand_ 353a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 354a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short y_min; /* band's minimum */ 355a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short y_max; /* band's maximum */ 356a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 357a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } TBand; 358a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 359a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 360a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define AlignProfileSize \ 361fefd8742928491a9da356cc1c37f434c76d73514Werner Lemberg ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) ) 362a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 363a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 364f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#ifdef FT_STATIC_RASTER 365a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 366a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 367a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_ARGS /* void */ 368a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_ARG /* void */ 369a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 370a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_VARS /* void */ 371a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_VAR /* void */ 372a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 373a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FT_UNUSED_RASTER do ; while ( 0 ) 374a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 375a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 376f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#else /* FT_STATIC_RASTER */ 377a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 378a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3798a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define RAS_ARGS PWorker worker, 3808a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define RAS_ARG PWorker worker 381a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3828a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define RAS_VARS worker, 3838a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define RAS_VAR worker 384a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3858a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define FT_UNUSED_RASTER FT_UNUSED( worker ) 386a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 387a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 388f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#endif /* FT_STATIC_RASTER */ 389a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 390a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 391174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg typedef struct TWorker_ TWorker, *PWorker; 392a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 393a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 394a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* prototypes used for sweep function dispatch */ 39552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg typedef void 39652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Function_Sweep_Init( RAS_ARGS Short* min, 39752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Short* max ); 398a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 39952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg typedef void 40052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Function_Sweep_Span( RAS_ARGS Short y, 40152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 40252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 40352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 40452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ); 405a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 40652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg typedef void 40752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Function_Sweep_Step( RAS_ARG ); 408a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 409a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 410a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* NOTE: These operations are only valid on 2's complement processors */ 411a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 412a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FLOOR( x ) ( (x) & -ras.precision ) 413a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) 414a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define TRUNC( x ) ( (signed long)(x) >> ras.precision_bits ) 415a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) 416a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define SCALED( x ) ( ( (x) << ras.scale_shift ) - ras.precision_half ) 417a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 418a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Note that I have moved the location of some fields in the */ 419a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* structure to ensure that the most used variables are used */ 420a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* at the top. Thus, their offset can be coded with less */ 421a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* opcodes, and it results in a smaller executable. */ 422a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4238a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner struct TWorker_ 424a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 425a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int precision_bits; /* precision related variables */ 426a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int precision; 427a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int precision_half; 428a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long precision_mask; 429a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int precision_shift; 430a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int precision_step; 431a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int precision_jitter; 432a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 433a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int scale_shift; /* == precision_shift for bitmaps */ 434a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* == precision_shift+1 for pixmaps */ 435a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 436a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PLong buff; /* The profiles buffer */ 437a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PLong sizeBuff; /* Render pool size */ 438a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PLong maxBuff; /* Profiles buffer size */ 439a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PLong top; /* Current cursor in buffer */ 440a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 441a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Error error; 442a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 443a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int numTurns; /* number of Y-turns in outline */ 444a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 445a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TPoint* arc; /* current Bezier arc pointer */ 446a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 447a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner UShort bWidth; /* target bitmap width */ 448a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte bTarget; /* target bitmap buffer */ 449a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte gTarget; /* target pixmap buffer */ 450a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 451a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long lastX, lastY, minY, maxY; 452a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 453a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner UShort num_Profs; /* current number of profiles */ 454a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 455a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Bool fresh; /* signals a fresh new profile which */ 456a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* 'start' field must be completed */ 457a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Bool joint; /* signals that the last arc ended */ 458a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* exactly on a scanline. Allows */ 459a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* removal of doublets */ 460a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile cProfile; /* current profile */ 461a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile fProfile; /* head of linked list of profiles */ 462a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile gProfile; /* contour's first profile in case */ 463a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* of impact */ 464a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 465a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TStates state; /* rendering state */ 466a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 467a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Bitmap target; /* description of target bit/pixmap */ 468a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Outline outline; 469a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 470a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long traceOfs; /* current offset in target bitmap */ 471a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long traceG; /* current offset in target pixmap */ 472a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 473a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short traceIncr; /* sweep's increment in target bitmap */ 474a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 475a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short gray_min_x; /* current min x during gray rendering */ 476a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short gray_max_x; /* current max x during gray rendering */ 477a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 478a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* dispatch variables */ 479a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 480a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Init* Proc_Sweep_Init; 481a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Span* Proc_Sweep_Span; 482a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Span* Proc_Sweep_Drop; 483a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Step* Proc_Sweep_Step; 484a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 485a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte dropOutControl; /* current drop_out control method */ 486a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4876e87ed9f04f7914e15f9284b0b762b730222c399Werner Lemberg Bool second_pass; /* indicates whether a horizontal pass */ 488a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* should be performed to control */ 489a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* drop-out accurately when calling */ 490a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Render_Glyph. Note that there is */ 491a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* no horizontal pass during gray */ 492a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* rendering. */ 493a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 494caf72cd6e5765aa5419f2f3e8e42610181dc82e8David Turner TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ 495a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 496a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TBand band_stack[16]; /* band stack used for sub-banding */ 497a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int band_top; /* band stack top */ 498a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 499a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 500a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5018a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner Byte* grays; 502a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 503a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte gray_lines[RASTER_GRAY_LINES]; 504a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Intermediate table used to render the */ 505a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* graylevels pixmaps. */ 506a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* gray_lines is a buffer holding two */ 507a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* monochrome scanlines */ 508a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 509a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short gray_width; /* width in bytes of one monochrome */ 510a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* intermediate scanline of gray_lines. */ 511a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Each gray pixel takes 2 bits long there */ 512a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 513a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The gray_lines must hold 2 lines, thus with size */ 514a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* in bytes of at least `gray_width*2'. */ 515a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 516a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif /* FT_RASTER_ANTI_ALIASING */ 517a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5188a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner }; 519a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 520a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 521174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg typedef struct TRaster_ 5228a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner { 5238a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner char* buffer; 5248a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner long buffer_size; 5258a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner void* memory; 5268a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner PWorker worker; 5278a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner Byte grays[5]; 5288a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner Short gray_width; 529a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5308a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner } TRaster, *PRaster; 531a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 532f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#ifdef FT_STATIC_RASTER 533a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 534174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg static TWorker cur_ras; 535a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define ras cur_ras 536a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 537a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#else 538a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5398a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define ras (*worker) 540a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 541f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#endif /* FT_STATIC_RASTER */ 542a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 543a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 54439c91ad444ac05cc45b54ff48d2d5b70dde01904Werner Lemberg#ifdef FT_RASTER_OPTION_ANTI_ALIASING 54539c91ad444ac05cc45b54ff48d2d5b70dde01904Werner Lemberg 546174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg static const char count_table[256] = 547174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg { 548174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 0 , 1 , 1 , 2 , 1 , 2 , 2 , 3 , 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4, 549174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, 550174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, 551174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, 552174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, 553174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, 554174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, 555174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, 556174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 1 , 2 , 2 , 3 , 2 , 3 , 3 , 4 , 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5, 557174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, 558174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, 559174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, 560174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 2 , 3 , 3 , 4 , 3 , 4 , 4 , 5 , 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6, 561174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, 562174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 3 , 4 , 4 , 5 , 4 , 5 , 5 , 6 , 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7, 563174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg 4 , 5 , 5 , 6 , 5 , 6 , 6 , 7 , 5 , 6 , 6 , 7 , 6 , 7 , 7 , 8 564174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberga }; 56538d1002b8ab6057a54d3483bc0a6f3808d44794dDavid Turner 56639c91ad444ac05cc45b54ff48d2d5b70dde01904Werner Lemberg#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ 56739c91ad444ac05cc45b54ff48d2d5b70dde01904Werner Lemberg 56838d1002b8ab6057a54d3483bc0a6f3808d44794dDavid Turner 56938d1002b8ab6057a54d3483bc0a6f3808d44794dDavid Turner 570a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 571a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 572a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 573a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** PROFILES COMPUTATION **/ 574a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 575a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 576a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 577a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 578a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 579a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 580a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 581a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 582a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Set_High_Precision */ 583a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 584a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 585174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Set precision variables according to param flag. */ 586a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 587a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 588a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* High :: Set to True for high precision (typically for ppem < 18), */ 589a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* false otherwise. */ 590a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 59152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 59252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Set_High_Precision( RAS_ARGS Int High ) 593a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 594a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( High ) 595a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 596a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_bits = 10; 597a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_step = 128; 598a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_jitter = 24; 599a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 600a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 601a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 602a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_bits = 6; 603a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_step = 32; 604a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_jitter = 2; 605a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 606a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 607a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); 608a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 60968e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg ras.precision = 1 << ras.precision_bits; 610a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_half = ras.precision / 2; 611a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_shift = ras.precision_bits - Pixel_Bits; 612a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_mask = -ras.precision; 613a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 614a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 615a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 616a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 617a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 618a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 619a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* New_Profile */ 620a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 621a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 622174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Create a new profile in the render pool. */ 623a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 624a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 625a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* aState :: The state/orientation of the new profile. */ 626a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 627a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 628a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ 629a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 630a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 63152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 63252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg New_Profile( RAS_ARGS TStates aState ) 633a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 634a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !ras.fProfile ) 635a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 636a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile = (PProfile)ras.top; 637a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fProfile = ras.cProfile; 638a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top += AlignProfileSize; 639a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 640a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 641a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.top >= ras.maxBuff ) 642a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 643a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Overflow; 644a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 645a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 646a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 647a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( aState ) 648a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 6499ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Ascending_State: 650a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->flow = Flow_Up; 651a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile )); 652a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 653a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 6549ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Descending_State: 655a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->flow = Flow_Down; 656a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile )); 657a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 658a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 659a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 660a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_ERROR(( "New_Profile: invalid profile direction!\n" )); 661a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Invalid; 662a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 663a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 664a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 665a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = 0; 666a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->height = 0; 667a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->offset = ras.top; 668a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->link = (PProfile)0; 669a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->next = (PProfile)0; 670a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 671a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !ras.gProfile ) 672a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gProfile = ras.cProfile; 673a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 674a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.state = aState; 675a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = TRUE; 676a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 677a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 678a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 679a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 680a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 681a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 682a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 683a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 684a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 685a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* End_Profile */ 686a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 687a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 688174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Finalize the current profile. */ 689a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 690a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 691a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ 692a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 69352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 69452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg End_Profile( RAS_ARG ) 695a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 696a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long h; 697a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile oldProfile; 698a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 699a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 700914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg h = (Long)( ras.top - ras.cProfile->offset ); 701a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 702a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( h < 0 ) 703a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 704a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_ERROR(( "End_Profile: negative height encountered!\n" )); 705a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Neg_Height; 706a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 707a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 708a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 709a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( h > 0 ) 710a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 711a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n", 712a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (long)ras.cProfile, ras.cProfile->start, h )); 713a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 714a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner oldProfile = ras.cProfile; 715a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->height = h; 716a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile = (PProfile)ras.top; 717a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 718a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top += AlignProfileSize; 719a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 720a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->height = 0; 721a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->offset = ras.top; 722a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner oldProfile->next = ras.cProfile; 723a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.num_Profs++; 724a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 725a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 726a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.top >= ras.maxBuff ) 727a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 728a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE1(( "overflow in End_Profile\n" )); 729a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Overflow; 730a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 731a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 732a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 733a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 734a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 735a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 736a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 737a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 738a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 739a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 740a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 741a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 742a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Insert_Y_Turn */ 743a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 744a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 745174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Insert a salient into the sorted list placed on top of the render */ 746a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* pool. */ 747a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 748a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 749a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* New y scanline position. */ 750a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 751a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 752a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow. */ 753a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 75452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 75552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Insert_Y_Turn( RAS_ARGS Int y ) 756a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 75751daa4feb18fce52a3c5d40bd6c9969203ec6b28Werner Lemberg PLong y_turns; 75851daa4feb18fce52a3c5d40bd6c9969203ec6b28Werner Lemberg Int y2, n; 759a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 760a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 761a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n = ras.numTurns - 1; 762a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_turns = ras.sizeBuff - ras.numTurns; 763a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 764a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* look for first y value that is <= */ 765a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( n >= 0 && y < y_turns[n] ) 766a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n--; 767a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 768a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* if it is <, simply insert it, ignore if == */ 769a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( n >= 0 && y > y_turns[n] ) 770a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( n >= 0 ) 771a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 77268e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg y2 = (Int)y_turns[n]; 773a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_turns[n] = y; 774a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = y2; 775a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n--; 776a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 777a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 778a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( n < 0 ) 779a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 78051daa4feb18fce52a3c5d40bd6c9969203ec6b28Werner Lemberg ras.maxBuff--; 781a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.maxBuff <= ras.top ) 782a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 783a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Overflow; 784a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 785a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 786a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.numTurns++; 787a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.sizeBuff[-ras.numTurns] = y; 788a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 789a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 790a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 791a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 792a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 793a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 794a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 795a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 796a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 797a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Finalize_Profile_Table */ 798a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 799a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 800174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Adjust all links in the profiles list. */ 801a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 802a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 803a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow. */ 804a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 80552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 80652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Finalize_Profile_Table( RAS_ARG ) 807a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 808a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int bottom, top; 809a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner UShort n; 810a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile p; 811a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 812a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 813a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n = ras.num_Profs; 814a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 815a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( n > 1 ) 816a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 817a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p = ras.fProfile; 818a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( n > 0 ) 819a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 820a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( n > 1 ) 821a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->link = (PProfile)( p->offset + p->height ); 822a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 823a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->link = NULL; 824a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 825a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( p->flow ) 826a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 827a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner case Flow_Down: 82868e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg bottom = (Int)( p->start - p->height + 1 ); 82968e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg top = (Int)p->start; 830a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->start = bottom; 831a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->offset += p->height - 1; 832a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 833a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 834a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner case Flow_Up: 835a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 83668e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg bottom = (Int)p->start; 83768e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg top = (Int)( p->start + p->height - 1 ); 838a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 839a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 840a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Insert_Y_Turn( RAS_VARS bottom ) || 841a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Insert_Y_Turn( RAS_VARS top + 1 ) ) 842a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 843a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 844a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p = p->link; 845a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n--; 846a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 847a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 848a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 849a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fProfile = NULL; 850a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 851a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 852a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 853a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 854a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 855a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 856a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 857a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 858a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Split_Conic */ 859a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 860a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 861174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */ 862a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* stack. */ 863a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 864a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 865a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* None (subdivided Bezier is taken from the top of the stack). */ 866a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 867a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Note> */ 868a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This routine is the `beef' of this component. It is _the_ inner */ 869a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* loop that should be optimized to hell to get the best performance. */ 870a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 87152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 87252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Split_Conic( TPoint* base ) 873a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 874a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long a, b; 875a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 876a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 877a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].x = base[2].x; 878a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].x; 879a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner a = base[3].x = ( base[2].x + b ) / 2; 880a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].x = ( base[0].x + b ) / 2; 881a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].x = ( a + b ) / 2; 882a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 883a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].y = base[2].y; 884a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].y; 885a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner a = base[3].y = ( base[2].y + b ) / 2; 886a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].y = ( base[0].y + b ) / 2; 887a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].y = ( a + b ) / 2; 888a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 889a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* hand optimized. gcc doesn't seem to be too good at common */ 890a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* expression substitution and instruction scheduling ;-) */ 891a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 892a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 893a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 894a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 895a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 896a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 897a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Split_Cubic */ 898a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 899a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 900174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */ 901a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Bezier stack. */ 902a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 903a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Note> */ 904a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This routine is the `beef' of the component. It is one of _the_ */ 905a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* inner loops that should be optimized like hell to get the best */ 906a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* performance. */ 907a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 90852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 90952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Split_Cubic( TPoint* base ) 910a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 911a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long a, b, c, d; 912a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 913a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 914a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[6].x = base[3].x; 915a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = base[1].x; 916a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner d = base[2].x; 917a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[1].x = a = ( base[0].x + c + 1 ) >> 1; 918a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[5].x = b = ( base[3].x + d + 1 ) >> 1; 919a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = ( c + d + 1 ) >> 1; 920a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].x = a = ( a + c + 1 ) >> 1; 921a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].x = b = ( b + c + 1 ) >> 1; 922a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[3].x = ( a + b + 1 ) >> 1; 923a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 924a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[6].y = base[3].y; 925a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = base[1].y; 926a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner d = base[2].y; 927a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[1].y = a = ( base[0].y + c + 1 ) >> 1; 928a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[5].y = b = ( base[3].y + d + 1 ) >> 1; 929a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = ( c + d + 1 ) >> 1; 930a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].y = a = ( a + c + 1 ) >> 1; 931a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].y = b = ( b + c + 1 ) >> 1; 932a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[3].y = ( a + b + 1 ) >> 1; 933a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 934a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 935a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 936a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 937a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 938a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 939a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Line_Up */ 940a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 941a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 942174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an ascending line segment and store */ 943a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* them in the render pool. */ 944a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 945a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 946a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x1 :: The x-coordinate of the segment's start point. */ 947a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 948a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y1 :: The y-coordinate of the segment's start point. */ 949a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 950a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x2 :: The x-coordinate of the segment's end point. */ 951a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 952a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y2 :: The y-coordinate of the segment's end point. */ 953a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 954a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 955a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 956a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 957a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 958a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 959a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 960a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 96152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 96252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Line_Up( RAS_ARGS Long x1, 96352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y1, 96452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x2, 96552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y2, 96652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 96752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 968a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 969a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long Dx, Dy; 970a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */ 971a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long Ix, Rx, Ax; 972a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 973a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PLong top; 974a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 975a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 976a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dx = x2 - x1; 977a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dy = y2 - y1; 978a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 979a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Dy <= 0 || y2 < miny || y1 > maxy ) 980a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 981a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 982a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 < miny ) 983a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 984a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Take care: miny-y1 can be a very large value; we use */ 985a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* a slow MulDiv function to avoid clipping bugs */ 986a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 += SMulDiv( Dx, miny - y1, Dy ); 98773861976779a754cc9b808760cc8e6cf98d52549Werner Lemberg e1 = (Int)TRUNC( miny ); 988a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner f1 = 0; 989a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 990a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 991a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 99268e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg e1 = (Int)TRUNC( y1 ); 99368e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg f1 = (Int)FRAC( y1 ); 994a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 995a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 996a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 > maxy ) 997a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 998a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ 99968e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg e2 = (Int)TRUNC( maxy ); 1000a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner f2 = 0; 1001a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1002a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1003a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 100468e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg e2 = (Int)TRUNC( y2 ); 100568e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg f2 = (Int)FRAC( y2 ); 1006a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1007a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1008a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( f1 > 0 ) 1009a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1010a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 ) 1011a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1012a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1013a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1014a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 += FMulDiv( Dx, ras.precision - f1, Dy ); 1015a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 += 1; 1016a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1017a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1018a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1019a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.joint ) 1020a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1021a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top--; 1022a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 1023a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1024a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 10258edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner ras.joint = (char)( f2 == 0 ); 1026a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1027a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.fresh ) 1028a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1029a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = e1; 1030a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = FALSE; 1031a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1032a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1033a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner size = e2 - e1 + 1; 1034a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.top + size >= ras.maxBuff ) 1035a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1036a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Overflow; 1037a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1038a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1039a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1040a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Dx > 0 ) 1041a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1042a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ix = ( ras.precision * Dx ) / Dy; 1043a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Rx = ( ras.precision * Dx ) % Dy; 1044a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dx = 1; 1045a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1046a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1047a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1048a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ix = -( ( ras.precision * -Dx ) / Dy ); 1049a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Rx = ( ras.precision * -Dx ) % Dy; 1050a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dx = -1; 1051a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1052a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1053a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ax = -Dy; 1054a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner top = ras.top; 1055a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1056a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( size > 0 ) 1057a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1058a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *top++ = x1; 1059a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1060a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 += Ix; 1061a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ax += Rx; 1062a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Ax >= 0 ) 1063a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1064a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ax -= Dy; 1065a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 += Dx; 1066a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1067a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner size--; 1068a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1069a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1070a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = top; 1071a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1072a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1073a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1074a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1075a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1076a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1077a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1078a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Line_Down */ 1079a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1080a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1081174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an descending line segment and store */ 1082174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* them in the render pool. */ 1083a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1084a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1085a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x1 :: The x-coordinate of the segment's start point. */ 1086a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1087a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y1 :: The y-coordinate of the segment's start point. */ 1088a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1089a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x2 :: The x-coordinate of the segment's end point. */ 1090a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1091a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y2 :: The y-coordinate of the segment's end point. */ 1092a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1093a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 1094a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1095a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 1096a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1097a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1098a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 1099a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 110052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 110152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Line_Down( RAS_ARGS Long x1, 110252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y1, 110352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x2, 110452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y2, 110552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 110652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 1107a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1108a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Bool result, fresh; 1109a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1110a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1111a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner fresh = ras.fresh; 1112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); 1114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1115a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( fresh && !ras.fresh ) 1116a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = -ras.cProfile->start; 1117a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1118a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return result; 1119a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1120a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1121a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* A function type describing the functions used to split Bezier arcs */ 1123a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef void (*TSplitter)( TPoint* base ); 1124a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1125a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1126a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1127a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1128a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1129a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Bezier_Up */ 1130a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1131a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1132174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an ascending Bezier arc and store */ 1133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* them in the render pool. */ 1134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1136a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* degree :: The degree of the Bezier arc (either 2 or 3). */ 1137a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1138a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* splitter :: The function to split Bezier arcs. */ 1139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 1141a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1142a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 1143a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1144a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1145a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 1146a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 114752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 114852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Bezier_Up( RAS_ARGS Int degree, 114952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg TSplitter splitter, 115052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 115152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 1152a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1153a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y1, y2, e, e2, e0; 1154a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short f1; 1155a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1156a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TPoint* arc; 1157a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TPoint* start_arc; 1158a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1159a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PLong top; 1160a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1161a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1162a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc = ras.arc; 1163a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = arc[degree].y; 1164a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = arc[0].y; 1165a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner top = ras.top; 1166a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1167a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 < miny || y1 > maxy ) 1168a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fin; 1169a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = FLOOR( y2 ); 1171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1172a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 > maxy ) 1173a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = maxy; 1174a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1175a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e0 = miny; 1176a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1177a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 < miny ) 1178a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e = miny; 1179a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1180a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1181a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e = CEILING( y1 ); 1182914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg f1 = (Short)( FRAC( y1 ) ); 1183a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e0 = e; 1184a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1185a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( f1 == 0 ) 1186a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1187a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.joint ) 1188a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1189a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner top--; 1190a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 1191a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1192a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1193a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *top++ = arc[degree].x; 1194a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1195a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e += ras.precision; 1196a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1197a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1198a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1199a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.fresh ) 1200a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1201a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = TRUNC( e0 ); 1202a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = FALSE; 1203a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1204a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1205a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 < e ) 1206a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fin; 1207a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1208a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) 1209a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1210a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = top; 1211a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Overflow; 1212a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1213a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1214a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1215a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner start_arc = arc; 1216a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1217a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( arc >= start_arc && e <= e2 ) 1218a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1219a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 1220a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1221a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = arc[0].y; 1222a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1223a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 > e ) 1224a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1225a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = arc[degree].y; 1226a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 - y1 >= ras.precision_step ) 1227a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1228a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner splitter( arc ); 1229a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc += degree; 1230a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1231a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1232a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1233a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *top++ = arc[degree].x + FMulDiv( arc[0].x-arc[degree].x, 1234a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e - y1, y2 - y1 ); 1235a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc -= degree; 1236a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e += ras.precision; 1237a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1238a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1239a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1240a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1241a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 == e ) 1242a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1243a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = TRUE; 1244a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *top++ = arc[0].x; 1245a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1246a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e += ras.precision; 1247a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1248a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc -= degree; 1249a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1250a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1251a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1252a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fin: 1253a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = top; 1254a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc -= degree; 1255a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1256a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1257a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1258a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1259a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1260a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1261a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1262a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Bezier_Down */ 1263a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1264a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1265174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an descending Bezier arc and store */ 1266a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* them in the render pool. */ 1267a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1268a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1269a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* degree :: The degree of the Bezier arc (either 2 or 3). */ 1270a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1271a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* splitter :: The function to split Bezier arcs. */ 1272a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1273a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 1274a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1275a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 1276a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1277a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1278a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 1279a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 128052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 128152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Bezier_Down( RAS_ARGS Int degree, 128252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg TSplitter splitter, 128352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 128452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 1285a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1286a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TPoint* arc = ras.arc; 1287a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Bool result, fresh; 1288a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1289a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1290a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[0].y = -arc[0].y; 1291a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[1].y = -arc[1].y; 1292a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[2].y = -arc[2].y; 1293a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( degree > 2 ) 1294a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[3].y = -arc[3].y; 1295a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1296a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner fresh = ras.fresh; 1297a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1298a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny ); 1299a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1300a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( fresh && !ras.fresh ) 1301a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = -ras.cProfile->start; 1302a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1303a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[0].y = -arc[0].y; 1304a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return result; 1305a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1306a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1307a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1308a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1309a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1310a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1311a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Line_To */ 1312a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1313a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1314174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Inject a new line segment and adjust the Profiles list. */ 1315a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1316a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1317a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x :: The x-coordinate of the segment's end point (its start point */ 1318ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* is stored in `lastX'). */ 1319a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1320a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y :: The y-coordinate of the segment's end point (its start point */ 1321ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* is stored in `lastY'). */ 1322a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1323a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1324a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1325a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 1326a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 132752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 132852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Line_To( RAS_ARGS Long x, 132952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y ) 1330a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1331a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* First, detect a change of direction */ 1332a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1333a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( ras.state ) 1334a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 13359ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Unknown_State: 1336a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y > ras.lastY ) 1337a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 13389ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( New_Profile( RAS_VARS Ascending_State ) ) 1339a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1340a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1341a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1342a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1343a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y < ras.lastY ) 13449ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( New_Profile( RAS_VARS Descending_State ) ) 1345a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1346a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1347a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1348a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 13499ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Ascending_State: 1350a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y < ras.lastY ) 1351a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 13529ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( End_Profile( RAS_VAR ) || 13539ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg New_Profile( RAS_VARS Descending_State ) ) 1354a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1355a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1356a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1357a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 13589ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Descending_State: 1359a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y > ras.lastY ) 1360a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 13619ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( End_Profile( RAS_VAR ) || 13629ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg New_Profile( RAS_VARS Ascending_State ) ) 1363a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1364a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1365a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1366a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1367a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 1368a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ; 1369a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1370a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1371a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Then compute the lines */ 1372a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1373a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( ras.state ) 1374a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 13759ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Ascending_State: 1376a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, 1377a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x, y, ras.minY, ras.maxY ) ) 1378a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1379a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1380a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 13819ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Descending_State: 1382a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, 1383a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x, y, ras.minY, ras.maxY ) ) 1384a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1385a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1386a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1387a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 1388a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ; 1389a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1390a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1391a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = x; 1392a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = y; 1393a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1394a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1395a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1396a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1397a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1398a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1399a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1400a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1401a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Conic_To */ 1402a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1403a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1404174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Inject a new conic arc and adjust the profile list. */ 1405a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1406a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1407a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cx :: The x-coordinate of the arc's new control point. */ 1408a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1409a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cy :: The y-coordinate of the arc's new control point. */ 1410a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1411a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x :: The x-coordinate of the arc's end point (its start point is */ 1412ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastX'). */ 1413a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1414a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y :: The y-coordinate of the arc's end point (its start point is */ 1415ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastY'). */ 1416a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1417a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1418a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1419a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 1420a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 142152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 142252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Conic_To( RAS_ARGS Long cx, 142352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cy, 142452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x, 142552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y ) 1426a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1427a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y1, y2, y3, x3, ymin, ymax; 1428a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TStates state_bez; 1429a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1430a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1431a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc = ras.arcs; 1432a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[2].x = ras.lastX; 1433a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[2].y = ras.lastY; 1434a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[1].x = cx; ras.arc[1].y = cy; 1435a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[0].x = x; ras.arc[0].y = y; 1436a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1437a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner do 1438a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1439a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = ras.arc[2].y; 1440a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = ras.arc[1].y; 1441a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y3 = ras.arc[0].y; 1442a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x3 = ras.arc[0].x; 1443a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1444a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first, categorize the Bezier arc */ 1445a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1446a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 <= y3 ) 1447a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1448a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin = y1; 1449a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax = y3; 1450a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1451a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1452a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1453a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin = y3; 1454a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax = y1; 1455a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1456a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1457a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 < ymin || y2 > ymax ) 1458a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1459a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc has no given direction, split it! */ 1460a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Split_Conic( ras.arc ); 1461a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc += 2; 1462a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1463a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else if ( y1 == y3 ) 1464a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1465a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc is flat, ignore it and pop it from the Bezier stack */ 1466a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc -= 2; 1467a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1468a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1469a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1470a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the arc is y-monotonous, either ascending or descending */ 1471a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* detect a change of direction */ 14729ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg state_bez = y1 < y3 ? Ascending_State : Descending_State; 1473a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.state != state_bez ) 1474a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1475a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* finalize current profile if any */ 14769ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( ras.state != Unknown_State && 1477a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner End_Profile( RAS_VAR ) ) 1478a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1479a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1480a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* create a new profile */ 1481a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( New_Profile( RAS_VARS state_bez ) ) 1482a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1483a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1484a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1485a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* now call the appropriate routine */ 14869ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( state_bez == Ascending_State ) 1487a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1488a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) 1489a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1490a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1491a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1492a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) 1493a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1494a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1495a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1496a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } while ( ras.arc >= ras.arcs ); 1497a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1498a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = x3; 1499a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = y3; 1500a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1501a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1502a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1503a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fail: 1504a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1505a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1506a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1507a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1508a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1509a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1510a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1511a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Cubic_To */ 1512a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1513a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1514174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Inject a new cubic arc and adjust the profile list. */ 1515a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1516a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1517a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cx1 :: The x-coordinate of the arc's first new control point. */ 1518a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1519a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cy1 :: The y-coordinate of the arc's first new control point. */ 1520a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1521a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cx2 :: The x-coordinate of the arc's second new control point. */ 1522a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1523a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cy2 :: The y-coordinate of the arc's second new control point. */ 1524a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1525a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x :: The x-coordinate of the arc's end point (its start point is */ 1526ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastX'). */ 1527a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1528a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y :: The y-coordinate of the arc's end point (its start point is */ 1529ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastY'). */ 1530a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1531a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1532a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1533a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 1534a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 153552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 153652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Cubic_To( RAS_ARGS Long cx1, 153752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cy1, 153852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cx2, 153952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cy2, 154052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x, 154152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y ) 1542a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1543a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2; 1544a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TStates state_bez; 1545a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1546a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1547a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc = ras.arcs; 1548a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[3].x = ras.lastX; 1549a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[3].y = ras.lastY; 1550a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[2].x = cx1; ras.arc[2].y = cy1; 1551a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[1].x = cx2; ras.arc[1].y = cy2; 1552a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[0].x = x; ras.arc[0].y = y; 1553a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1554a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner do 1555a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1556a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = ras.arc[3].y; 1557a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = ras.arc[2].y; 1558a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y3 = ras.arc[1].y; 1559a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y4 = ras.arc[0].y; 1560a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x4 = ras.arc[0].x; 1561a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1562a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first, categorize the Bezier arc */ 1563a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1564a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 <= y4 ) 1565a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1566a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin1 = y1; 1567a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax1 = y4; 1568a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1569a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1570a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1571a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin1 = y4; 1572a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax1 = y1; 1573a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1574a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1575a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 <= y3 ) 1576a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1577a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin2 = y2; 1578a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax2 = y3; 1579a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1580a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1581a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1582a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin2 = y3; 1583a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax2 = y2; 1584a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1585a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1586a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ymin2 < ymin1 || ymax2 > ymax1 ) 1587a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1588a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc has no given direction, split it! */ 1589a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Split_Cubic( ras.arc ); 1590a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc += 3; 1591a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1592a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else if ( y1 == y4 ) 1593a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1594a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc is flat, ignore it and pop it from the Bezier stack */ 1595a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc -= 3; 1596a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1597a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1598a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 15999ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State; 1600a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1601a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* detect a change of direction */ 1602a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.state != state_bez ) 1603a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 16049ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( ras.state != Unknown_State && 1605a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner End_Profile( RAS_VAR ) ) 1606a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1607a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1608a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( New_Profile( RAS_VARS state_bez ) ) 1609a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1610a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1611a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1612a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* compute intersections */ 16139ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( state_bez == Ascending_State ) 1614a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1615a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) 1616a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1617a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1618a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1619a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) 1620a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1621a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1622a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1623a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } while ( ras.arc >= ras.arcs ); 1624a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1625a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = x4; 1626a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = y4; 1627a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1628a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1629a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1630a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fail: 1631a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1632a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1633a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1634a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1635a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#undef SWAP_ 1636a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define SWAP_( x, y ) do \ 1637a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { \ 1638a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long swap = x; \ 1639a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner \ 1640a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner \ 1641a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = y; \ 1642a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = swap; \ 1643a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } while ( 0 ) 1644a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1645a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1646a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1647a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1648a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1649a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Decompose_Curve */ 1650a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1651a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1652174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Scan the outline arrays in order to emit individual segments and */ 1653a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Beziers by calling Line_To() and Bezier_To(). It handles all */ 1654a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* weird cases, like when the first point is off the curve, or when */ 1655a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* there are simply no `on' points in the contour! */ 1656a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1657a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1658a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first :: The index of the first point in the contour. */ 1659a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1660a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* last :: The index of the last point in the contour. */ 1661a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1662a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* flipped :: If set, flip the direction of the curve. */ 1663a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1664a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1665a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on error. */ 1666a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 166752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 166852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Decompose_Curve( RAS_ARGS UShort first, 166952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg UShort last, 167052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg int flipped ) 1671a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1672a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_last; 1673a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_control; 1674a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_start; 1675a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1676a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector* points; 1677a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector* point; 1678a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector* limit; 1679a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner char* tags; 1680a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 16818edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner unsigned tag; /* current point's state */ 1682a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1683a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1684a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner points = ras.outline.points; 1685a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner limit = points + last; 1686a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1687a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.x = SCALED( points[first].x ); 1688a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.y = SCALED( points[first].y ); 1689a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_last.x = SCALED( points[last].x ); 1690a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_last.y = SCALED( points[last].y ); 1691a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1692a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1693a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1694a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( v_start.x, v_start.y ); 1695a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( v_last.x, v_last.y ); 1696a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1697a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1698a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control = v_start; 1699a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1700a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point = points + first; 1701a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags = ras.outline.tags + first; 1702a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tag = FT_CURVE_TAG( tags[0] ); 1703a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1704a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* A contour cannot start with a cubic control point! */ 1705b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag == FT_CURVE_TAG_CUBIC ) 1706a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Invalid_Outline; 1707a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1708a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* check first point to determine origin */ 1709b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag == FT_CURVE_TAG_CONIC ) 1710a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1711a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first point is conic control. Yes, this happens. */ 1712b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON ) 1713a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1714a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* start at last point if it is on the curve */ 1715a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start = v_last; 1716a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner limit--; 1717a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1718a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1719a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1720a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* if both first and last points are conic, */ 1721a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* start at their middle and record its position */ 1722a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* for closure */ 1723a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.x = ( v_start.x + v_last.x ) / 2; 1724a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.y = ( v_start.y + v_last.y ) / 2; 1725a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1726a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_last = v_start; 1727a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1728a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point--; 1729a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags--; 1730a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1731a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1732a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = v_start.x; 1733a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = v_start.y; 1734a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1735a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( point < limit ) 1736a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1737a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point++; 1738a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags++; 1739a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1740a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tag = FT_CURVE_TAG( tags[0] ); 1741a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1742a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( tag ) 1743a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1744b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner case FT_CURVE_TAG_ON: /* emit a single line_to */ 1745a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1746a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x, y; 1747a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1748a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1749a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = SCALED( point->x ); 1750a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = SCALED( point->y ); 1751a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1752a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x, y ); 1753a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1754a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_To( RAS_VARS x, y ) ) 1755a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1756a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner continue; 1757a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1758a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1759b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner case FT_CURVE_TAG_CONIC: /* consume conic arcs */ 1760a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.x = SCALED( point[0].x ); 1761a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.y = SCALED( point[0].y ); 1762a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1763a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1764a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( v_control.x, v_control.y ); 1765a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1766a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Do_Conic: 1767a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( point < limit ) 1768a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1769a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_middle; 1770a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x, y; 1771a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1772a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1773a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point++; 1774a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags++; 1775a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tag = FT_CURVE_TAG( tags[0] ); 1776a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1777a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = SCALED( point[0].x ); 1778a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = SCALED( point[0].y ); 1779a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1780a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1781a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x, y ); 1782a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1783b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag == FT_CURVE_TAG_ON ) 1784a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1785a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) ) 1786a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1787a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner continue; 1788a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1789a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1790b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag != FT_CURVE_TAG_CONIC ) 1791a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Invalid_Outline; 1792a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1793a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_middle.x = ( v_control.x + x ) / 2; 1794a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_middle.y = ( v_control.y + y ) / 2; 1795a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1796a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Conic_To( RAS_VARS v_control.x, v_control.y, 1797a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_middle.x, v_middle.y ) ) 1798a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1799a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1800a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.x = x; 1801a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.y = y; 1802a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1803a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Do_Conic; 1804a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1805a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1806a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Conic_To( RAS_VARS v_control.x, v_control.y, 1807a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.x, v_start.y ) ) 1808a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1809a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1810a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Close; 1811a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1812b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner default: /* FT_CURVE_TAG_CUBIC */ 1813a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1814a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x1, y1, x2, y2, x3, y3; 1815a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1816a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1817a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( point + 1 > limit || 1818b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) 1819a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Invalid_Outline; 1820a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1821a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point += 2; 1822a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags += 2; 1823a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1824a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 = SCALED( point[-2].x ); 1825a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = SCALED( point[-2].y ); 1826a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x2 = SCALED( point[-1].x ); 1827a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = SCALED( point[-1].y ); 1828a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x3 = SCALED( point[ 0].x ); 1829a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y3 = SCALED( point[ 0].y ); 1830a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1831a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1832a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1833a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x1, y1 ); 1834a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x2, y2 ); 1835a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x3, y3 ); 1836a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1837a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1838a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( point <= limit ) 1839a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1840a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) ) 1841a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1842a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner continue; 1843a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1844a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1845a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) ) 1846a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1847a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Close; 1848a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1849a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1850a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1851a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1852a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* close the contour with a line segment */ 1853a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_To( RAS_VARS v_start.x, v_start.y ) ) 1854a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1855a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1856a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Close: 1857a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1858a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1859a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Invalid_Outline: 1860a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Invalid; 1861a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1862a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fail: 1863a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1864a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1865a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1866a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1867a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1868a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1869a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1870a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Convert_Glyph */ 1871a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1872a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1873174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Convert a glyph into a series of segments and arcs and make a */ 1874a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profiles list with them. */ 1875a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1876a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1877a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* flipped :: If set, flip the direction of curve. */ 1878a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1879a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1880a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE if any error was encountered during */ 1881a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* rendering. */ 1882a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 188352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 188452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Convert_Glyph( RAS_ARGS int flipped ) 1885a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 18868edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner int i; 18878edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner unsigned start; 1888a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1889a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile lastProfile; 1890a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1891a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1892a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fProfile = NULL; 1893a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 1894a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = FALSE; 1895a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1896a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.maxBuff = ras.sizeBuff - AlignProfileSize; 1897a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1898a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.numTurns = 0; 1899a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1900a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile = (PProfile)ras.top; 1901a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->offset = ras.top; 1902a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.num_Profs = 0; 1903a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1904a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner start = 0; 1905a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1906a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner for ( i = 0; i < ras.outline.n_contours; i++ ) 1907a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 19089ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg ras.state = Unknown_State; 1909a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gProfile = NULL; 1910a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 19118eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg if ( Decompose_Curve( RAS_VARS (unsigned short)start, 19128eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg ras.outline.contours[i], 19138eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg flipped ) ) 1914a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1915a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1916a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner start = ras.outline.contours[i] + 1; 1917a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1918a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* We must now see whether the extreme arcs join or not */ 1919a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( FRAC( ras.lastY ) == 0 && 1920a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY >= ras.minY && 1921a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY <= ras.maxY ) 1922a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.gProfile && ras.gProfile->flow == ras.cProfile->flow ) 1923a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top--; 1924a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Note that ras.gProfile can be nil if the contour was too small */ 1925a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* to be drawn. */ 1926a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1927a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner lastProfile = ras.cProfile; 1928a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( End_Profile( RAS_VAR ) ) 1929a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1930a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1931a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* close the `next profile in contour' linked list */ 1932a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.gProfile ) 1933a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner lastProfile->next = ras.gProfile; 1934a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1935a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1936a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Finalize_Profile_Table( RAS_VAR ) ) 1937a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1938a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 19398edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE ); 1940a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1941a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1942a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1943a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1944a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1945a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 1946a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** SCAN-LINE SWEEPS AND DRAWING **/ 1947a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 1948a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1949a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1950a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1951a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1952a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1953a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1954a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Init_Linked */ 1955a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1956a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Initializes an empty linked list. */ 1957a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 195852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 195952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Init_Linked( TProfileList* l ) 1960a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1961a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *l = NULL; 1962a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1963a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1964a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1965a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1966a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1967a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* InsNew */ 1968a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1969a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Inserts a new profile in a linked list. */ 1970a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 197152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 197252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg InsNew( PProfileList list, 197352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile profile ) 1974a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1975a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile *old, current; 1976a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x; 1977a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1978a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1979a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 1980a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 1981a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = profile->X; 1982a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1983a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( current ) 1984a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1985a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x < current->X ) 1986a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1987a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = ¤t->link; 1988a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 1989a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1990a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1991a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner profile->link = current; 1992a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *old = profile; 1993a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1994a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1995a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1996a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1997a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1998a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* DelOld */ 1999a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2000a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Removes an old profile from a linked list. */ 2001a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 200252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 200352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg DelOld( PProfileList list, 200452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile profile ) 2005a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2006a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile *old, current; 2007a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2008a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2009a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 2010a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2011a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2012a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( current ) 2013a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2014a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( current == profile ) 2015a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2016a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *old = current->link; 2017a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2018a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2019a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2020a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = ¤t->link; 2021a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2022a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2023a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2024a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* we should never get there, unless the profile was not part of */ 2025a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the list. */ 2026a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2027a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2028a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2029a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2030a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2031a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Sort */ 2032a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2033a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Sorts a trace list. In 95%, the list is already sorted. We need */ 2034a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* an algorithm which is fast in this case. Bubble sort is enough */ 2035a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* and simple. */ 2036a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 203752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 203852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Sort( PProfileList list ) 2039a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2040a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile *old, current, next; 2041a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2042a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2043a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* First, set the new X coordinate of each profile */ 2044ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current = *list; 2045ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner while ( current ) 2046ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner { 2047ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current->X = *current->offset; 2048ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current->offset += current->flow; 2049ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current->height--; 2050ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current = current->link; 2051ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner } 2052a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2053a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Then sort them */ 2054a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 2055a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2056a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2057a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !current ) 2058a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2059a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2060a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner next = current->link; 2061a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2062a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( next ) 2063a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2064a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( current->X <= next->X ) 2065a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2066a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = ¤t->link; 2067a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2068a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2069a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !current ) 2070a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2071a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2072a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2073a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2074a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *old = next; 2075a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current->link = next->link; 2076a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner next->link = current; 2077a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2078a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 2079a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2080a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2081a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2082a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner next = current->link; 2083a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2084a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2085a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2086a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2087a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2088a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2089a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Vertical Sweep Procedure Set */ 2090a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2091a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* These four routines are used during the vertical black/white sweep */ 2092a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* phase by the generic Draw_Sweep() function. */ 2093a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2094a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2095a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 209652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 209752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Init( RAS_ARGS Short* min, 209852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Short* max ) 2099a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2100a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long pitch = ras.target.pitch; 2101a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2102a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( max ); 2103a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2104a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2105a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceIncr = (Short)-pitch; 2106a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs = -*min * pitch; 2107a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( pitch > 0 ) 2108a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs += ( ras.target.rows - 1 ) * pitch; 2109a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2110a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_min_x = 0; 2111a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_max_x = 0; 2112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 211552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 211652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Span( RAS_ARGS Short y, 211752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 211852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 211952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 212052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2121a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long e1, e2; 21238edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner int c1, c2; 2124a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte f1, f2; 2125a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte* target; 2126a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2127a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( y ); 2128a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( left ); 2129a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( right ); 2130a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2131a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2132a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Drop-out control */ 2133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = TRUNC( CEILING( x1 ) ); 2135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2136a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x2 - x1 - ras.precision <= ras.precision_jitter ) 2137a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = e1; 2138a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = TRUNC( FLOOR( x2 ) ); 2140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2141a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 >= 0 && e1 < ras.bWidth ) 2142a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2143a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 < 0 ) 2144a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = 0; 2145a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 >= ras.bWidth ) 2146a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = ras.bWidth - 1; 2147a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2148a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c1 = (Short)( e1 >> 3 ); 2149a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2 = (Short)( e2 >> 3 ); 2150a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 21518edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); 21528edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); 2153a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 21545df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.gray_min_x > c1 ) 21555df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.gray_min_x = (short)c1; 21565df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.gray_max_x < c2 ) 21575df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.gray_max_x = (short)c2; 2158a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2159a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner target = ras.bTarget + ras.traceOfs + c1; 2160a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2 -= c1; 2161a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2162a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( c2 > 0 ) 2163a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2164a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner target[0] |= f1; 2165a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 216694ffae5239631a18b8b5a39674c0afa8a992410eWerner Lemberg /* memset() is slower than the following code on many platforms. */ 2167a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This is due to the fact that, in the vast majority of cases, */ 2168a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the span length in bytes is relatively small. */ 2169a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2--; 2170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( c2 > 0 ) 2171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2172a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *(++target) = 0xFF; 2173a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2--; 2174a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2175a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner target[1] |= f2; 2176a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2177a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2178a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *target |= ( f1 & f2 ); 2179a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2180a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2181a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2182a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 218352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 218452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Drop( RAS_ARGS Short y, 218552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 218652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 218752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 218852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2189a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 21905df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg Long e1, e2, pxl; 2191a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short c1, f1; 2192a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2193a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2194a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Drop-out control */ 2195a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 21965df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* e2 x2 x1 e1 */ 21975df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* */ 21985df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* ^ | */ 21995df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | | */ 22005df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* +-------------+---------------------+------------+ */ 22015df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | | */ 22025df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | v */ 22035df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* */ 22045df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* pixel contour contour pixel */ 22055df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* center center */ 22065df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 22075df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* drop-out mode scan conversion rules (as defined in OpenType) */ 22085df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* --------------------------------------------------------------- */ 22095df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 0 1, 2, 3 */ 22105df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 1 1, 2, 4 */ 22115df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 2 1, 2 */ 22125df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 3 same as mode 2 */ 22135df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 4 1, 2, 5 */ 22145df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 5 1, 2, 6 */ 22155df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 6, 7 same as mode 2 */ 22165df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 22175df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = CEILING( x1 ); 22185df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e2 = FLOOR ( x2 ); 22195df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e1; 2220a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2221a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 > e2 ) 2222a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2223a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 + ras.precision ) 2224a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2225a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( ras.dropOutControl ) 2226a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 22275df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 0: /* simple drop-outs including stubs */ 22285df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 2229a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2230a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22315df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 4: /* smart drop-outs including stubs */ 22325df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); 2233a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2234a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22355df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 1: /* simple drop-outs excluding stubs */ 22365df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 5: /* smart drop-outs excluding stubs */ 2237a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22385df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* Drop-out Control Rules #4 and #6 */ 22395df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 22405df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* The spec is not very clear regarding those rules. It */ 2241a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* presents a method that is way too costly to implement */ 2242a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* while the general idea seems to get rid of `stubs'. */ 2243a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2244a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Here, we only get rid of stubs recognized if: */ 2245a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2246a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* upper stub: */ 2247a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2248a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Left and P_Right are in the same contour */ 2249a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Right is the successor of P_Left in that contour */ 2250a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - y is the top of P_Left and P_Right */ 2251a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2252a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* lower stub: */ 2253a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2254a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Left and P_Right are in the same contour */ 2255a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Left is the successor of P_Right in that contour */ 2256a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - y is the bottom of P_Left */ 2257a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2258a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2259a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* FIXXXME: uncommenting this line solves the disappearing */ 2260a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* bit problem in the `7' of verdana 10pts, but */ 2261a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* makes a new one in the `C' of arial 14pts */ 2262a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#if 0 2263a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x2 - x1 < ras.precision_half ) 2264a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 2265a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2266a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* upper stub test */ 2267a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( left->next == right && left->height <= 0 ) 2268a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2269a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2270a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* lower stub test */ 2271a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( right->next == left && left->start == y ) 2272a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2273a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2274a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22755df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.dropOutControl == 1 ) 22765df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 22775df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 22785df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); 22795df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg break; 2280a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22815df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg default: /* modes 2, 3, 6, 7 */ 22825df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg return; /* no drop-out control */ 22835df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg } 2284a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22855df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* check that the other pixel isn't set */ 22865df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = pxl == e1 ? e2 : e1; 2287a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22885df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( e1 ); 2289a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22905df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg c1 = (Short)( e1 >> 3 ); 22915df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg f1 = (Short)( e1 & 7 ); 2292a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22935df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( e1 >= 0 && e1 < ras.bWidth && 22945df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) 22955df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg return; 2296a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2297a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2298a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2299a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2300a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23015df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( pxl ); 2302a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2303a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 >= 0 && e1 < ras.bWidth ) 2304a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2305a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c1 = (Short)( e1 >> 3 ); 2306914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg f1 = (Short)( e1 & 7 ); 2307a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23085df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.gray_min_x > c1 ) 23095df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.gray_min_x = c1; 23105df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.gray_max_x < c1 ) 23115df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.gray_max_x = c1; 2312a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2313a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); 2314a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2315a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2316a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2317a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 231852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 231952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Step( RAS_ARG ) 2320a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2321a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs += ras.traceIncr; 2322a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2323a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2324a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2325a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /***********************************************************************/ 2326a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2327a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Horizontal Sweep Procedure Set */ 2328a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2329a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* These four routines are used during the horizontal black/white */ 2330a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* sweep phase by the generic Draw_Sweep() function. */ 2331a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2332a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /***********************************************************************/ 2333a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 233452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 233552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Init( RAS_ARGS Short* min, 233652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Short* max ) 2337a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2338a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* nothing, really */ 2339f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg FT_UNUSED_RASTER; 2340a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( min ); 2341a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( max ); 2342a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2343a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2344a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 234552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 234652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Span( RAS_ARGS Short y, 234752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 234852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 234952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 235052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2351a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2352a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long e1, e2; 2353a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte bits; 2354a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte f1; 2355a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2356a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( left ); 2357a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( right ); 2358a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2359a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2360a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x2 - x1 < ras.precision ) 2361a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2362a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = CEILING( x1 ); 2363a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = FLOOR ( x2 ); 2364a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2365a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 ) 2366a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2367a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits = ras.bTarget + ( y >> 3 ); 2368a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2369a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2370a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = TRUNC( e1 ); 2371a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2372a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 >= 0 && e1 < ras.target.rows ) 2373a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2374a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte p; 2375a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2376a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2377a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p = bits - e1*ras.target.pitch; 2378a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.target.pitch > 0 ) 2379a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p += ( ras.target.rows - 1 ) * ras.target.pitch; 2380a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2381a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p[0] |= f1; 2382a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2383a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2384a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2385a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2386a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2387a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 238852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 238952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Drop( RAS_ARGS Short y, 239052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 239152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 239252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 239352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2394a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 23955df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg Long e1, e2, pxl; 2396a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte bits; 2397a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte f1; 2398a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2399a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2400a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* During the horizontal sweep, we only take care of drop-outs */ 2401a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24025df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* e1 + <-- pixel center */ 24035df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 24045df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* x1 ---+--> <-- contour */ 24055df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 24065df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 24075df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* x2 <--+--- <-- contour */ 24085df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 24095df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 24105df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* e2 + <-- pixel center */ 24115df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 24125df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = CEILING( x1 ); 24135df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e2 = FLOOR ( x2 ); 24145df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e1; 2415a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2416a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 > e2 ) 2417a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2418a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 + ras.precision ) 2419a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2420a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( ras.dropOutControl ) 2421a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 24225df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 0: /* simple drop-outs including stubs */ 24235df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 2424a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2425a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24265df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 4: /* smart drop-outs including stubs */ 24275df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); 2428a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2429a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24305df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 1: /* simple drop-outs excluding stubs */ 24315df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 5: /* smart drop-outs excluding stubs */ 24325df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* see Vertical_Sweep_Drop for details */ 2433a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2434a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* rightmost stub test */ 2435a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( left->next == right && left->height <= 0 ) 2436a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2437a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2438a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* leftmost stub test */ 2439a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( right->next == left && left->start == y ) 2440a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2441a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24425df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.dropOutControl == 1 ) 24435df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 24445df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 24455df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); 24465df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg break; 2447a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24485df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg default: /* modes 2, 3, 6, 7 */ 24495df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg return; /* no drop-out control */ 24505df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg } 2451a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24525df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* check that the other pixel isn't set */ 24535df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = pxl == e1 ? e2 : e1; 2454a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24555df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( e1 ); 2456a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24575df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg bits = ras.bTarget + ( y >> 3 ); 24585df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2459a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24605df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg bits -= e1 * ras.target.pitch; 24615df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.target.pitch > 0 ) 24625df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg bits += ( ras.target.rows - 1 ) * ras.target.pitch; 2463a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24645df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( e1 >= 0 && 24655df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 < ras.target.rows && 24665df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg *bits & f1 ) 24675df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg return; 2468a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2469a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2470a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2471a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2472a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2473a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits = ras.bTarget + ( y >> 3 ); 2474a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2475a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24765df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( pxl ); 2477a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2478a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 >= 0 && e1 < ras.target.rows ) 2479a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2480a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits -= e1 * ras.target.pitch; 2481a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.target.pitch > 0 ) 2482a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits += ( ras.target.rows - 1 ) * ras.target.pitch; 2483a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2484a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits[0] |= f1; 2485a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2486a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2487a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2488a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 248952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 249052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Step( RAS_ARG ) 2491a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2492a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Nothing, really */ 2493f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg FT_UNUSED_RASTER; 2494a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2495a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2496a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2497a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 2498a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2499a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2500a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2501a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2502a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Vertical Gray Sweep Procedure Set */ 2503a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2504a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* These two routines are used during the vertical gray-levels sweep */ 2505a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* phase by the generic Draw_Sweep() function. */ 2506a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2507a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* NOTES */ 2508a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2509a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - The target pixmap's width *must* be a multiple of 4. */ 2510a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2511a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - You have to use the function Vertical_Sweep_Span() for the gray */ 2512a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* span call. */ 2513a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2514a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2515a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 251652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 251752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, 251852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Short* max ) 2519a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2520a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long pitch, byte_len; 2521a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2522a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2523a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *min = *min & -2; 2524a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *max = ( *max + 3 ) & -2; 2525a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2526a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs = 0; 2527a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pitch = ras.target.pitch; 2528a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner byte_len = -pitch; 2529a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceIncr = (Short)byte_len; 2530a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceG = ( *min / 2 ) * byte_len; 2531a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2532a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( pitch > 0 ) 2533a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2534a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceG += ( ras.target.rows - 1 ) * pitch; 2535a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner byte_len = -byte_len; 2536a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2537a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2538a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_min_x = (Short)byte_len; 2539a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_max_x = -(Short)byte_len; 2540a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2541a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2542a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 254352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 254452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Gray_Sweep_Step( RAS_ARG ) 2545a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2546a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int c1, c2; 2547a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte pix, bit, bit2; 254838d1002b8ab6057a54d3483bc0a6f3808d44794dDavid Turner char* count = (char*)count_table; 2549a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte* grays; 2550a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2551a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2552a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs += ras.gray_width; 2553a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2554a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.traceOfs > ras.gray_width ) 2555a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2556a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; 2557a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner grays = ras.grays; 2558a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2559a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.gray_max_x >= 0 ) 2560a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2561174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg Long last_pixel = ras.target.width - 1; 2562174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg Int last_cell = last_pixel >> 2; 2563174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg Int last_bit = last_pixel & 3; 2564174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg Bool over = 0; 2565a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2566a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2567a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.gray_max_x >= last_cell && last_bit != 3 ) 2568a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2569a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_max_x = last_cell - 1; 2570a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner over = 1; 2571a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2572a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2573a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.gray_min_x < 0 ) 2574a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_min_x = 0; 2575a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2576174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg bit = ras.bTarget + ras.gray_min_x; 2577174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg bit2 = bit + ras.gray_width; 2578a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2579a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c1 = ras.gray_max_x - ras.gray_min_x; 2580a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2581a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( c1 >= 0 ) 2582a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2583a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2 = count[*bit] + count[*bit2]; 2584a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2585a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( c2 ) 2586a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2587a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[0] = grays[(c2 >> 12) & 0x000F]; 2588a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[1] = grays[(c2 >> 8 ) & 0x000F]; 2589a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[2] = grays[(c2 >> 4 ) & 0x000F]; 2590a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[3] = grays[ c2 & 0x000F]; 2591a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2592a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *bit = 0; 2593a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *bit2 = 0; 2594a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2595a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2596a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bit++; 2597a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bit2++; 2598a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix += 4; 2599a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c1--; 2600a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2601a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2602a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( over ) 2603a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2604a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2 = count[*bit] + count[*bit2]; 2605a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( c2 ) 2606a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2607a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( last_bit ) 2608a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2609a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner case 2: 2610a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[2] = grays[(c2 >> 4 ) & 0x000F]; 2611a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner case 1: 2612a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[1] = grays[(c2 >> 8 ) & 0x000F]; 2613a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 2614a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[0] = grays[(c2 >> 12) & 0x000F]; 2615a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2616a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2617a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *bit = 0; 2618a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *bit2 = 0; 2619a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2620a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2621a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2622a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2623a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs = 0; 2624a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceG += ras.traceIncr; 2625a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2626a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_min_x = 32000; 2627a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_max_x = -32000; 2628a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2629a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2630a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2631a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 263252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 263352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, 263452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 263552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 263652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 263752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2638a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2639a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* nothing, really */ 2640f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg FT_UNUSED_RASTER; 2641a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( y ); 2642a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( x1 ); 2643a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( x2 ); 2644a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( left ); 2645a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( right ); 2646a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2647a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2648a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 264952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 265052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, 265152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 265252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 265352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 265452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2655a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2656a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long e1, e2; 2657a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte pixel; 2658a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte color; 2659a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2660a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2661a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* During the horizontal sweep, we only take care of drop-outs */ 26625df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 2663a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = CEILING( x1 ); 2664a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = FLOOR ( x2 ); 2665a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2666a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 > e2 ) 2667a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2668a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 + ras.precision ) 2669a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2670a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( ras.dropOutControl ) 2671a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 26725df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 0: /* simple drop-outs including stubs */ 2673a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = e2; 2674a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2675a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 26765df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 4: /* smart drop-outs including stubs */ 26775df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); 2678a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2679a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 26805df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 1: /* simple drop-outs excluding stubs */ 26815df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 5: /* smart drop-outs excluding stubs */ 26825df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* see Vertical_Sweep_Drop for details */ 2683a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2684a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* rightmost stub test */ 2685a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( left->next == right && left->height <= 0 ) 2686a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2687a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2688a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* leftmost stub test */ 2689a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( right->next == left && left->start == y ) 2690a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2691a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 26925df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.dropOutControl == 1 ) 2693a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = e2; 2694a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 26955df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = FLOOR( ( x1 + x2 + 1 ) / 2 + ras.precision_half ); 2696a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2697a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2698a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 26995df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg default: /* modes 2, 3, 6, 7 */ 27005df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg return; /* no drop-out control */ 2701a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2702a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2703a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2704a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2705a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2706a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2707a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 >= 0 ) 2708a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2709a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x2 - x1 >= ras.precision_half ) 2710a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner color = ras.grays[2]; 2711a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2712a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner color = ras.grays[1]; 2713a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2714a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = TRUNC( e1 ) / 2; 2715a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 < ras.target.rows ) 2716a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2717a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; 2718a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.target.pitch > 0 ) 2719a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pixel += ( ras.target.rows - 1 ) * ras.target.pitch; 2720a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2721a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( pixel[0] == ras.grays[0] ) 2722a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pixel[0] = color; 2723a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2724a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2725a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2726a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2727a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2728a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ 2729a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2730a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2731a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2732a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2733a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Generic Sweep Drawing routine */ 2734a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2735a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2736a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 273752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 273852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Draw_Sweep( RAS_ARG ) 2739a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2740a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short y, y_change, y_height; 2741a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2742a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile P, Q, P_Left, P_Right; 2743a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2744a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short min_Y, max_Y, top, bottom, dropouts; 2745a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2746a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x1, x2, xs, e1, e2; 2747a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 27483c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg TProfileList waiting; 2749a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TProfileList draw_left, draw_right; 2750a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2751a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2752174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* initialize empty linked lists */ 2753a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 27543c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg Init_Linked( &waiting ); 2755a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2756a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Init_Linked( &draw_left ); 2757a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Init_Linked( &draw_right ); 2758a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2759a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first, compute min and max Y */ 2760a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2761a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = ras.fProfile; 2762a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner max_Y = (Short)TRUNC( ras.minY ); 2763a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner min_Y = (Short)TRUNC( ras.maxY ); 2764a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2765a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2766a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2767a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 2768a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2769a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bottom = (Short)P->start; 2770914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg top = (Short)( P->start + P->height - 1 ); 2771a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 27725df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( min_Y > bottom ) 27735df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg min_Y = bottom; 27745df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( max_Y < top ) 27755df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg max_Y = top; 2776a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2777a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P->X = 0; 27783c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg InsNew( &waiting, P ); 2779a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2780a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 2781a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2782a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2783174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* check the Y-turns */ 2784a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.numTurns == 0 ) 2785a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2786a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Invalid; 2787a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 2788a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2789a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2790174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* now initialize the sweep */ 2791a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2792a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); 2793a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2794174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* then compute the distance of each profile from min_Y */ 2795a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 27963c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg P = waiting; 2797a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2798a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2799a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2800914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg P->countL = (UShort)( P->start - min_Y ); 2801a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = P->link; 2802a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2803a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2804174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* let's go */ 2805a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2806a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = min_Y; 2807a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_height = 0; 2808a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2809a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.numTurns > 0 && 2810a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.sizeBuff[-ras.numTurns] == min_Y ) 2811a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.numTurns--; 2812a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2813a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( ras.numTurns > 0 ) 2814a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2815174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* check waiting list for new activations */ 2816a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 28173c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg P = waiting; 2818a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2819a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2820a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2821a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 2822a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P->countL -= y_height; 2823a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P->countL == 0 ) 2824a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 28253c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg DelOld( &waiting, P ); 2826a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2827a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( P->flow ) 2828a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2829a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner case Flow_Up: 2830a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner InsNew( &draw_left, P ); 2831a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2832a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2833a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner case Flow_Down: 2834a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner InsNew( &draw_right, P ); 2835a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2836a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2837a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2838a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2839a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 2840a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2841a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2842174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* sort the drawing lists */ 2843a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2844a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_left ); 2845a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_right ); 2846a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2847a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_change = (Short)ras.sizeBuff[-ras.numTurns--]; 28488eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg y_height = (Short)( y_change - y ); 2849a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2850a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( y < y_change ) 2851a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2852174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* let's trace */ 2853a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2854a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner dropouts = 0; 2855a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2856a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = draw_left; 2857a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = draw_right; 2858a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2859a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P_Left ) 2860a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2861a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 = P_Left ->X; 2862a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x2 = P_Right->X; 2863a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2864a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x1 > x2 ) 2865a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2866a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner xs = x1; 2867a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 = x2; 2868a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x2 = xs; 2869a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2870a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 287171b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg e1 = FLOOR( x1 ); 287271b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg e2 = CEILING( x2 ); 2873a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 287471b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg if ( x2 - x1 <= ras.precision && 287571b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg e1 != x1 && e2 != x2 ) 287671b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg { 2877ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg if ( e1 > e2 || e2 == e1 + ras.precision ) 2878a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2879ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg if ( ras.dropOutControl != 2 ) 2880ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg { 2881174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* a drop-out was detected */ 2882a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2883ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg P_Left ->X = x1; 2884ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg P_Right->X = x2; 2885a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2886ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg /* mark profile for drop-out processing */ 2887ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg P_Left->countL = 1; 2888ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg dropouts++; 2889ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg } 2890a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2891a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Skip_To_Next; 2892a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2893a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2894a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2895a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right ); 2896a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2897a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Skip_To_Next: 2898a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2899a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = P_Left->link; 2900a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = P_Right->link; 2901a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2902a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2903174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* handle drop-outs _after_ the span drawing -- */ 2904174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* drop-out processing has been moved out of the loop */ 2905174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* for performance tuning */ 2906a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( dropouts > 0 ) 2907a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Scan_DropOuts; 2908a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2909a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Next_Line: 2910a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2911a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step( RAS_VAR ); 2912a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2913a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y++; 2914a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2915a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y < y_change ) 2916a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2917a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_left ); 2918a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_right ); 2919a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2920a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2921a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2922174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* now finalize the profiles that need it */ 2923a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2924a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = draw_left; 2925a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2926a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2927a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 2928a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P->height == 0 ) 2929a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner DelOld( &draw_left, P ); 2930a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 2931a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2932a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2933a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = draw_right; 2934a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2935a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2936a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 2937a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P->height == 0 ) 2938a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner DelOld( &draw_right, P ); 2939a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 2940a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2941a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2942a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2943174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* for gray-scaling, flush the bitmap scanline cache */ 2944a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( y <= max_Y ) 2945a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2946a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step( RAS_VAR ); 2947a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y++; 2948a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2949a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2950a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 2951a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2952a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Scan_DropOuts: 2953a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2954a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = draw_left; 2955a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = draw_right; 2956a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2957a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P_Left ) 2958a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2959a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P_Left->countL ) 2960a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2961a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left->countL = 0; 2962a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#if 0 2963a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner dropouts--; /* -- this is useful when debugging only */ 2964a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 2965a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop( RAS_VARS y, 2966a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left->X, 2967a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right->X, 2968a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left, 2969a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right ); 2970a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2971a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2972a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = P_Left->link; 2973a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = P_Right->link; 2974a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2975a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2976a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Next_Line; 2977a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2978a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2979a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2980a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2981a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2982a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 2983a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Render_Single_Pass */ 2984a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2985a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 2986174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Perform one sweep with sub-banding. */ 2987a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2988a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 2989a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* flipped :: If set, flip the direction of the outline. */ 2990a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2991a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 2992a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Renderer error code. */ 2993a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 299452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 299552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Render_Single_Pass( RAS_ARGS Bool flipped ) 2996a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2997a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short i, j, k; 2998a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2999a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3000a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( ras.band_top >= 0 ) 3001a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3002a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision; 3003a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision; 3004a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3005a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = ras.buff; 3006a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3007a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_None; 3008a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3009a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Convert_Glyph( RAS_VARS flipped ) ) 3010a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3011a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.error != Raster_Err_Overflow ) 3012a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 3013a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3014a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_None; 3015a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3016a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* sub-banding */ 3017a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3018a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef DEBUG_RASTER 3019a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) ); 3020a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 3021a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3022a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner i = ras.band_stack[ras.band_top].y_min; 3023a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner j = ras.band_stack[ras.band_top].y_max; 3024a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 30258eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg k = (Short)( ( i + j ) / 2 ); 3026a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3027a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.band_top >= 7 || k < i ) 3028a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3029a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3030a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Invalid; 3031a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3032a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return ras.error; 3033a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3034a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3035a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[ras.band_top + 1].y_min = k; 3036a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[ras.band_top + 1].y_max = j; 3037a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 30388eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg ras.band_stack[ras.band_top].y_max = (Short)( k - 1 ); 3039a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3040a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top++; 3041a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3042a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 3043a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3044a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.fProfile ) 3045a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Draw_Sweep( RAS_VAR ) ) 3046a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return ras.error; 3047a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top--; 3048a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3049a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3050a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3051a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 3052a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3053a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3054a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3055a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 3056a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3057a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 3058a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Render_Glyph */ 3059a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3060a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 3061174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Render a glyph in a bitmap. Sub-banding if needed. */ 3062a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3063a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 3064a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* FreeType error code. 0 means success. */ 3065a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3066bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner FT_LOCAL_DEF( FT_Error ) 306752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Render_Glyph( RAS_ARG ) 3068a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3069a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Error error; 3070a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3071a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3072a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Set_High_Precision( RAS_VARS ras.outline.flags & 3073b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner FT_OUTLINE_HIGH_PRECISION ); 30745df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.scale_shift = ras.precision_shift; 30755df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 30765df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) 30775df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 2; 30785df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 30795df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg { 30805df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) 30815df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 4; 30825df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 30835df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 0; 30845df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 30855df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) 30865df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl += 1; 30875df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg } 30885df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 30895df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.second_pass = (FT_Byte)( !( ras.outline.flags & 30905df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg FT_OUTLINE_SINGLE_PASS ) ); 3091a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3092a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Vertical Sweep */ 3093a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init = Vertical_Sweep_Init; 3094a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span = Vertical_Sweep_Span; 3095a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; 3096a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step = Vertical_Sweep_Step; 3097a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3098a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3099a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_min = 0; 31008eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg ras.band_stack[0].y_max = (short)( ras.target.rows - 1 ); 3101a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 31028edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner ras.bWidth = (unsigned short)ras.target.width; 3103a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bTarget = (Byte*)ras.target.buffer; 3104a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3105a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) 3106a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3107a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3108a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Horizontal Sweep */ 3109ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg if ( ras.second_pass && ras.dropOutControl != 2 ) 3110a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3111a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init = Horizontal_Sweep_Init; 3112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span = Horizontal_Sweep_Span; 3113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; 3114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step = Horizontal_Sweep_Step; 3115a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3116a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3117a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_min = 0; 31188eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg ras.band_stack[0].y_max = (short)( ras.target.width - 1 ); 3119a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3120a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) 3121a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3123a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3124f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg return Raster_Err_None; 3125a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3126a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3127a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3128a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 3129a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3130a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 3131a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3132a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 3133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Render_Gray_Glyph */ 3134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 3136174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Render a glyph with grayscaling. Sub-banding if needed. */ 3137a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3138a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 3139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* FreeType error code. 0 means success. */ 3140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3141bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner FT_LOCAL_DEF( FT_Error ) 314252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Render_Gray_Glyph( RAS_ARG ) 3143a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3144a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long pixel_width; 3145a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Error error; 3146a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3147a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3148a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Set_High_Precision( RAS_VARS ras.outline.flags & 3149b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner FT_OUTLINE_HIGH_PRECISION ); 31505df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.scale_shift = ras.precision_shift + 1; 31515df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 31525df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) 31535df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 2; 31545df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 31555df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg { 31565df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) 31575df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 4; 31585df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 31595df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 0; 31605df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 31615df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) 31625df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl += 1; 31635df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg } 31645df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 31655df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); 3166a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3167a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Vertical Sweep */ 3168a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3169a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_min = 0; 3171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_max = 2 * ras.target.rows - 1; 3172a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3173a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bWidth = ras.gray_width; 3174a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); 3175a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3176a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.bWidth > pixel_width ) 3177a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bWidth = pixel_width; 3178a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3179a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bWidth = ras.bWidth * 8; 3180a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bTarget = (Byte*)ras.gray_lines; 3181a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gTarget = (Byte*)ras.target.buffer; 3182a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3183a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; 3184a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span = Vertical_Sweep_Span; 3185a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; 3186a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; 3187a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3188a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner error = Render_Single_Pass( RAS_VARS 0 ); 3189a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( error ) 3190a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3191a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3192a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Horizontal Sweep */ 3193ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg if ( ras.second_pass && ras.dropOutControl != 2 ) 3194a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3195a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init = Horizontal_Sweep_Init; 3196a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; 3197a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; 3198a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step = Horizontal_Sweep_Step; 3199a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3200a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3201a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_min = 0; 3202a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_max = ras.target.width * 2 - 1; 3203a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3204a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner error = Render_Single_Pass( RAS_VARS 1 ); 3205a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( error ) 3206a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3207a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3208a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3209f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg return Raster_Err_None; 3210a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3211a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3212bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner#else /* !FT_RASTER_OPTION_ANTI_ALIASING */ 3213a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3214bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner FT_LOCAL_DEF( FT_Error ) 3215bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner Render_Gray_Glyph( RAS_ARG ) 3216a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3217a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED_RASTER; 3218a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3219f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg return Raster_Err_Unsupported; 3220a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3221a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3222bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */ 3223a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3224a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 322552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 32268a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner ft_black_init( PRaster raster ) 3227a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3228a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 322938d1002b8ab6057a54d3483bc0a6f3808d44794dDavid Turner FT_UInt n; 3230a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 32314ea0a7f0b65c026420f39cabdc146b943c74e2c5Werner Lemberg 3232a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* set default 5-levels gray palette */ 3233a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner for ( n = 0; n < 5; n++ ) 3234a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner raster->grays[n] = n * 255 / 4; 3235a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 32368a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->gray_width = RASTER_GRAY_LINES / 2; 3237a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3238eca1f2790578ce8e9907ef3373ab69b7816b3093Werner Lemberg#else 3239eca1f2790578ce8e9907ef3373ab69b7816b3093Werner Lemberg FT_UNUSED( raster ); 3240a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 3241a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3242a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3243a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3244a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ 3245a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /**** a static object. *****/ 3246a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3247a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3248a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef _STANDALONE_ 3249a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3250a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 325152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 3252174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg ft_black_new( void* memory, 325352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_Raster *araster ) 3254a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 32558a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner static TRaster the_raster; 3256a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3257a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3258f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg *araster = (FT_Raster)&the_raster; 3259b3d5e9cf03dce78e606b79c81cb1f29ce06555d5Werner Lemberg FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); 3260a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ft_black_init( &the_raster ); 3261a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3262a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return 0; 3263a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3264a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3265a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 326652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 326752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg ft_black_done( FT_Raster raster ) 3268a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3269a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* nothing */ 3270f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg FT_UNUSED( raster ); 3271a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3272a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3273a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3274a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#else /* _STANDALONE_ */ 3275a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3276a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 327752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 32788a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner ft_black_new( FT_Memory memory, 32798a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner PRaster *araster ) 3280a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 32818a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner FT_Error error; 32828a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner PRaster raster; 3283a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3284a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3285a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *araster = 0; 3286e459d742e6236df43f542b8c29dfdcf05d69716cDavid Turner if ( !FT_NEW( raster ) ) 3287a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3288a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner raster->memory = memory; 3289a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ft_black_init( raster ); 3290a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3291a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *araster = raster; 3292a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3293a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3294a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3295a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3296a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3297a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 329852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 32998a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner ft_black_done( PRaster raster ) 3300a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3301a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Memory memory = (FT_Memory)raster->memory; 3302e459d742e6236df43f542b8c29dfdcf05d69716cDavid Turner FT_FREE( raster ); 3303a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3304a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3305a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3306a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif /* _STANDALONE_ */ 3307a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3308a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 330952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 3310174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg ft_black_reset( PRaster raster, 3311174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg char* pool_base, 3312174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg long pool_size ) 3313a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 33148a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner if ( raster ) 3315a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 33168a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner if ( pool_base && pool_size >= (long)sizeof(TWorker) + 2048 ) 33178a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner { 33188a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner PWorker worker = (PWorker)pool_base; 33198a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner 33204ea0a7f0b65c026420f39cabdc146b943c74e2c5Werner Lemberg 33214ea0a7f0b65c026420f39cabdc146b943c74e2c5Werner Lemberg raster->buffer = pool_base + ( (sizeof ( *worker ) + 7 ) & ~7 ); 33224ea0a7f0b65c026420f39cabdc146b943c74e2c5Werner Lemberg raster->buffer_size = ( ( pool_base + pool_size ) - 33234ea0a7f0b65c026420f39cabdc146b943c74e2c5Werner Lemberg (char*)raster->buffer ) / sizeof ( Long ); 33248a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->worker = worker; 33258a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner } 33268a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner else 33278a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner { 33288a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->buffer = NULL; 33298a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->buffer_size = 0; 33308a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->worker = NULL; 33318a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner } 3332a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3333a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3334a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3335a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 333652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 3337174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg ft_black_set_mode( PRaster raster, 3338174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg unsigned long mode, 3339174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg const char* palette ) 3340a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3341a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 3342a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3343a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) 3344a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3345a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* set 5-levels gray palette */ 33468a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->grays[0] = palette[0]; 33478a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->grays[1] = palette[1]; 33488a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->grays[2] = palette[2]; 33498a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->grays[3] = palette[3]; 33508a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->grays[4] = palette[4]; 3351a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3352a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3353a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#else 3354a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3355a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( raster ); 3356a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( mode ); 3357a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( palette ); 3358a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3359a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 3360a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3361a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3362a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 336352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 33648a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner ft_black_render( PRaster raster, 3365fa420250c59414e432243feffb70be68654b8c27Werner Lemberg const FT_Raster_Params* params ) 3366a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 33678ae1dceb94effa59a307c0b778b37483f808f3d4Werner Lemberg const FT_Outline* outline = (const FT_Outline*)params->source; 33688ae1dceb94effa59a307c0b778b37483f808f3d4Werner Lemberg const FT_Bitmap* target_map = params->target; 33698a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner PWorker worker; 3370a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3371a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 33728a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner if ( !raster || !raster->buffer || !raster->buffer_size ) 3373a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return Raster_Err_Not_Ini; 3374a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 33751ddd1b768dc3821e275e97c9391e54a14a8dc136Werner Lemberg if ( !outline ) 33761ddd1b768dc3821e275e97c9391e54a14a8dc136Werner Lemberg return Raster_Err_Invalid; 33771ddd1b768dc3821e275e97c9391e54a14a8dc136Werner Lemberg 3378a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* return immediately if the outline is empty */ 3379a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( outline->n_points == 0 || outline->n_contours <= 0 ) 3380a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return Raster_Err_None; 3381a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 33821ddd1b768dc3821e275e97c9391e54a14a8dc136Werner Lemberg if ( !outline->contours || !outline->points ) 3383a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return Raster_Err_Invalid; 3384a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3385c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( outline->n_points != 3386c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg outline->contours[outline->n_contours - 1] + 1 ) 3387a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return Raster_Err_Invalid; 3388a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 33898a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner worker = raster->worker; 33908a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner 3391a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this version of the raster does not support direct rendering, sorry */ 3392b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( params->flags & FT_RASTER_FLAG_DIRECT ) 3393a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return Raster_Err_Unsupported; 3394a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3395c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( !target_map ) 3396c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg return Raster_Err_Invalid; 3397c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg 3398c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg /* nothing to do */ 3399c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( !target_map->width || !target_map->rows ) 3400c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg return Raster_Err_None; 3401c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg 3402c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( !target_map->buffer ) 34031eb9a43aa14e02b56d981bae334e6e24c63298f7David Turner return Raster_Err_Invalid; 34041eb9a43aa14e02b56d981bae334e6e24c63298f7David Turner 34055df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.outline = *outline; 34065df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.target = *target_map; 3407a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 34085df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg worker->buff = (PLong) raster->buffer; 34095df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg worker->sizeBuff = worker->buff + 34105df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg raster->buffer_size / sizeof ( Long ); 34118a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 34125df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg worker->grays = raster->grays; 34135df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg worker->gray_width = raster->gray_width; 34148a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#endif 34158a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner 3416b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner return ( ( params->flags & FT_RASTER_FLAG_AA ) 3417f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg ? Render_Gray_Glyph( RAS_VAR ) 3418f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg : Render_Glyph( RAS_VAR ) ); 3419a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3420a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3421a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3422a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner const FT_Raster_Funcs ft_standard_raster = 3423a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3424b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner FT_GLYPH_FORMAT_OUTLINE, 3425a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (FT_Raster_New_Func) ft_black_new, 3426a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (FT_Raster_Reset_Func) ft_black_reset, 3427a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (FT_Raster_Set_Mode_Func)ft_black_set_mode, 3428a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (FT_Raster_Render_Func) ft_black_render, 3429a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (FT_Raster_Done_Func) ft_black_done 3430a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner }; 3431a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3432a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3433a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* END */ 3434