ftraster.c revision 766b822f4c1cc84cc11545b63be87108d0954b48
1a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/***************************************************************************/ 2a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* */ 3a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* ftraster.c */ 4a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* */ 5a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* The FreeType glyph rasterizer (body). */ 6a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* */ 7b66efefdcde552e4880896aa961a0b9a583762d2Werner Lemberg/* Copyright 1996-2001, 2002, 2003, 2005, 2007, 2008, 2009 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 520d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg#define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> 530d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg 54766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg#include <string.h> /* for memset */ 550d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg 56f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#include "ftmisc.h" 57f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#include "ftimage.h" 58f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg 59f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#else /* !_STANDALONE_ */ 60a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 6119ed8afe60bbc5becf0fbbe3987a91b35a36aad4David Turner#include <ft2build.h> 628d3a401fa808a8c70bd6a9ce17d5a840fb0ae2dbDavid Turner#include "ftraster.h" 6319ed8afe60bbc5becf0fbbe3987a91b35a36aad4David Turner#include FT_INTERNAL_CALC_H /* for FT_MulDiv only */ 64a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 650d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg#include "rastpic.h" 660d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg 67f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#endif /* !_STANDALONE_ */ 68f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg 69a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 70a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 71a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 72a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* A simple technical note on how the raster works */ 73a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* ----------------------------------------------- */ 74a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 75a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Converting an outline into a bitmap is achieved in several steps: */ 76a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 77a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* 1 - Decomposing the outline into successive `profiles'. Each */ 78a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile is simply an array of scanline intersections on a given */ 79a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* dimension. A profile's main attributes are */ 80a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 818262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* o its scanline position boundaries, i.e. `Ymin' and `Ymax' */ 82a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 83a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* o an array of intersection coordinates for each scanline */ 848262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* between `Ymin' and `Ymax' */ 85a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 86a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* o a direction, indicating whether it was built going `up' or */ 878262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* `down', as this is very important for filling rules */ 888262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* */ 898262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* o its drop-out mode */ 90a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 91a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* 2 - Sweeping the target map's scanlines in order to compute segment */ 92a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* `spans' which are then filled. Additionally, this pass */ 93a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* performs drop-out control. */ 94a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 95a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The outline data is parsed during step 1 only. The profiles are */ 96a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* built from the bottom of the render pool, used as a stack. The */ 97a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* following graphics shows the profile list under construction: */ 98a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 998262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* __________________________________________________________ _ _ */ 1008262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* | | | | | */ 1018262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* | profile | coordinates for | profile | coordinates for |--> */ 1028262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* | 1 | profile 1 | 2 | profile 2 |--> */ 1038262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* |_________|_________________|_________|_________________|__ _ _ */ 104a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1058262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* ^ ^ */ 1068262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* | | */ 1078262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* start of render pool top */ 108a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 109a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The top of the profile stack is kept in the `top' variable. */ 110a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 111a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* As you can see, a profile record is pushed on top of the render */ 112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* pool, which is then followed by its coordinates/intersections. If */ 113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* a change of direction is detected in the outline, a new profile is */ 114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* generated until the end of the outline. */ 115a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 116a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Note that when all profiles have been generated, the function */ 117a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Finalize_Profile_Table() is used to record, for each profile, its */ 118a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* bottom-most scanline as well as the scanline above its upmost */ 119a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* boundary. These positions are called `y-turns' because they (sort */ 120a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* of) correspond to local extrema. They are stored in a sorted list */ 121a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* built from the top of the render pool as a downwards stack: */ 122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 123a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* _ _ _______________________________________ */ 124a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* | | */ 125a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <--| sorted list of | */ 126a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <--| extrema scanlines | */ 127a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* _ _ __________________|____________________| */ 128a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 129a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* ^ ^ */ 130a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* | | */ 131a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxBuff sizeBuff = end of pool */ 132a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This list is later used during the sweep phase in order to */ 134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* optimize performance (see technical note on the sweep below). */ 135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 136a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Of course, the raster detects whether the two stacks collide and */ 1376e87ed9f04f7914e15f9284b0b762b730222c399Werner Lemberg /* handles the situation properly. */ 138a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 141a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 142a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 143a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 144a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 145a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** CONFIGURATION MACROS **/ 146a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 147a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 148a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 149a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 150a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* define DEBUG_RASTER if you want to compile a debugging version */ 151766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg/* #define DEBUG_RASTER */ 152a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 153766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* define FT_RASTER_OPTION_ANTI_ALIASING if you want to support */ 154766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* 5-levels anti-aliasing */ 155766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg/* #define FT_RASTER_OPTION_ANTI_ALIASING */ 156a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 157a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The size of the two-lines intermediate bitmap used */ 158a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* for anti-aliasing, in bytes. */ 159a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RASTER_GRAY_LINES 2048 160a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 161a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 162a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 163a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 164a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 165a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** OTHER MACROS (do not change) **/ 166a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 167a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 168a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 169a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 172a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 173a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 174a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* messages during execution. */ 175a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 176a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#undef FT_COMPONENT 177a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FT_COMPONENT trace_raster 178a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 179a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 180a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef _STANDALONE_ 181a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 182a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 183a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This macro is used to indicate that a function parameter is unused. */ 184a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Its purpose is simply to reduce compiler warnings. Note also that */ 185a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* simply defining it as `(void)x' doesn't avoid warnings with certain */ 186a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* ANSI compilers (e.g. LCC). */ 187a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FT_UNUSED( x ) (x) = (x) 188a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 189a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Disable the tracing mechanism for simplicity -- developers can */ 190a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* activate it easily by redefining these two macros. */ 191a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FT_ERROR 192f47acf2b5fcd9d6c9dc58809ef8ecf1b1e0b46adWerner Lemberg#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ 193a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 194a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 195a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FT_TRACE 196f47acf2b5fcd9d6c9dc58809ef8ecf1b1e0b46adWerner Lemberg#define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ 197f47acf2b5fcd9d6c9dc58809ef8ecf1b1e0b46adWerner Lemberg#define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ 198f47acf2b5fcd9d6c9dc58809ef8ecf1b1e0b46adWerner Lemberg#define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ 199a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 200a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 201a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_None 0 202a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Not_Ini -1 203a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Overflow -2 204a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Neg_Height -3 205a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Invalid -4 206a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Unsupported -5 207a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2080d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg#define ft_memset memset 2090d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg 2100d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \ 2110d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_reset_, raster_set_mode_, \ 2120d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_render_, raster_done_ ) \ 2130d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg const FT_Raster_Funcs class_ = \ 2140d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg { \ 2150d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg glyph_format_, \ 2160d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_new_, \ 2170d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_reset_, \ 2180d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_set_mode_, \ 2190d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_render_, \ 2200d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_done_ \ 2210d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg }; 2228262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg 2238262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg#else /* !_STANDALONE_ */ 224a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 225a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2261f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#include FT_INTERNAL_OBJECTS_H 2271f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#include FT_INTERNAL_DEBUG_H /* for FT_TRACE() and FT_ERROR() */ 228a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2291f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#include "rasterrs.h" 2301f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg 2311f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_None Raster_Err_Ok 2321f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized 2331f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Overflow Raster_Err_Raster_Overflow 2341f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height 2351f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Invalid Raster_Err_Invalid_Outline 2361f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph 237a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 238a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2398262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg#endif /* !_STANDALONE_ */ 240a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 241a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 242e459d742e6236df43f542b8c29dfdcf05d69716cDavid Turner#ifndef FT_MEM_SET 243d15bc0d13a163995e1ca11925349bd64d1c33617David Turner#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) 244c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg#endif 245c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg 246f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#ifndef FT_MEM_ZERO 247f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) 248f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#endif 249c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg 250a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ 251a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* typically a small value and the result of a*b is known to fit into */ 252a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* 32 bits. */ 253a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) 254a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 255a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ 256a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* for clipping computations. It simply uses the FT_MulDiv() function */ 257a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* defined in `ftcalc.h'. */ 258a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define SMulDiv FT_MulDiv 259a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 260a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The rasterizer is a very general purpose component; please leave */ 261a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the following redefinitions there (you never know your target */ 262a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* environment). */ 263a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 264a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef TRUE 265a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define TRUE 1 266a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 267a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 268a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FALSE 269a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FALSE 0 270a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 271a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 272a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef NULL 273a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define NULL (void*)0 274a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 275a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 276a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef SUCCESS 277a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define SUCCESS 0 278a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 279a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 280a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FAILURE 281a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FAILURE 1 282a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 283a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 284a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 285a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define MaxBezier 32 /* The maximum number of stacked Bezier curves. */ 286a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Setting this constant to more than 32 is a */ 287a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* pure waste of space. */ 288a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 289a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Pixel_Bits 6 /* fractional bits of *input* coordinates */ 290a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 291a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 292a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 293a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 294a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 295a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** SIMPLE TYPE DECLARATIONS **/ 296a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 297a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 298a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 299a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 300a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef int Int; 301a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef unsigned int UInt; 302a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef short Short; 303a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef unsigned short UShort, *PUShort; 304a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef long Long, *PLong; 305a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef unsigned long ULong; 306a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 307a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef unsigned char Byte, *PByte; 308a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef char Bool; 309a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 310fefd8742928491a9da356cc1c37f434c76d73514Werner Lemberg 311fefd8742928491a9da356cc1c37f434c76d73514Werner Lemberg typedef union Alignment_ 3128530a228889128adfd446514928f36663ed20f04David Turner { 3138530a228889128adfd446514928f36663ed20f04David Turner long l; 3148530a228889128adfd446514928f36663ed20f04David Turner void* p; 3158530a228889128adfd446514928f36663ed20f04David Turner void (*f)(void); 3168530a228889128adfd446514928f36663ed20f04David Turner 3178530a228889128adfd446514928f36663ed20f04David Turner } Alignment, *PAlignment; 3188530a228889128adfd446514928f36663ed20f04David Turner 319fefd8742928491a9da356cc1c37f434c76d73514Werner Lemberg 320a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef struct TPoint_ 321a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 322a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x; 323a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y; 324a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 325a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } TPoint; 326a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 327a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 32842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* values for the `flags' bit field */ 32972271140434028186a49a5dc5925f0727559e46fWerner Lemberg#define Flow_Up 0x8 33072271140434028186a49a5dc5925f0727559e46fWerner Lemberg#define Overshoot_Top 0x10 33172271140434028186a49a5dc5925f0727559e46fWerner Lemberg#define Overshoot_Bottom 0x20 332a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 333a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 334a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* States of each line, arc, and profile */ 335a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef enum TStates_ 336a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3379ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Unknown_State, 3389ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Ascending_State, 3399ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Descending_State, 3409ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Flat_State 341a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 342a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } TStates; 343a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 344a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 345a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef struct TProfile_ TProfile; 346a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef TProfile* PProfile; 347a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 348a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner struct TProfile_ 349a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 35042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg FT_F26Dot6 X; /* current coordinate during sweep */ 35142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg PProfile link; /* link to next profile (various purposes) */ 35242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg PLong offset; /* start of profile's data in render pool */ 35372271140434028186a49a5dc5925f0727559e46fWerner Lemberg unsigned flags; /* Bit 0-2: drop-out mode */ 35472271140434028186a49a5dc5925f0727559e46fWerner Lemberg /* Bit 3: profile orientation (up/down) */ 35572271140434028186a49a5dc5925f0727559e46fWerner Lemberg /* Bit 4: is top profile? */ 35672271140434028186a49a5dc5925f0727559e46fWerner Lemberg /* Bit 5: is bottom profile? */ 35742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg long height; /* profile's height in scanlines */ 35842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg long start; /* profile's starting scanline */ 35942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 36042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg unsigned countL; /* number of lines to step before this */ 36142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* profile becomes drawable */ 36242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 36342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg PProfile next; /* next profile in same contour, used */ 36442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* during drop-out control */ 365a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner }; 366a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 367a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef PProfile TProfileList; 368a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef PProfile* PProfileList; 369a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 370a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 371a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Simple record used to implement a stack of bands, required */ 372a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* by the sub-banding mechanism */ 373a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef struct TBand_ 374a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 375a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short y_min; /* band's minimum */ 376a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short y_max; /* band's maximum */ 377a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 378a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } TBand; 379a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 380a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 381a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define AlignProfileSize \ 382fefd8742928491a9da356cc1c37f434c76d73514Werner Lemberg ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( long ) ) 383a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 384a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 385f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#ifdef FT_STATIC_RASTER 386a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 387a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 388a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_ARGS /* void */ 389a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_ARG /* void */ 390a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 391a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_VARS /* void */ 392a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_VAR /* void */ 393a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 394f47acf2b5fcd9d6c9dc58809ef8ecf1b1e0b46adWerner Lemberg#define FT_UNUSED_RASTER do { } while ( 0 ) 395a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 396a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3978262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg#else /* !FT_STATIC_RASTER */ 398a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 399a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4008a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define RAS_ARGS PWorker worker, 4018a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define RAS_ARG PWorker worker 402a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4038a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define RAS_VARS worker, 4048a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define RAS_VAR worker 405a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4068a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define FT_UNUSED_RASTER FT_UNUSED( worker ) 407a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 408a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4098262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg#endif /* !FT_STATIC_RASTER */ 410a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 411a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 412174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg typedef struct TWorker_ TWorker, *PWorker; 413a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 414a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 415a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* prototypes used for sweep function dispatch */ 41652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg typedef void 41752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Function_Sweep_Init( RAS_ARGS Short* min, 41852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Short* max ); 419a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 42052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg typedef void 42152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Function_Sweep_Span( RAS_ARGS Short y, 42252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 42352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 42452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 42552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ); 426a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 42752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg typedef void 42852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Function_Sweep_Step( RAS_ARG ); 429a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 430a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 431a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* NOTE: These operations are only valid on 2's complement processors */ 432a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 433a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FLOOR( x ) ( (x) & -ras.precision ) 434a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) 435a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define TRUNC( x ) ( (signed long)(x) >> ras.precision_bits ) 436a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) 437a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define SCALED( x ) ( ( (x) << ras.scale_shift ) - ras.precision_half ) 438a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 43942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg#define IS_BOTTOM_OVERSHOOT( x ) ( CEILING( x ) - x >= ras.precision_half ) 44042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg#define IS_TOP_OVERSHOOT( x ) ( x - FLOOR( x ) >= ras.precision_half ) 44142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 4428262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* The most used variables are positioned at the top of the structure. */ 4438262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* Thus, their offset can be coded with less opcodes, resulting in a */ 4448262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* smaller executable. */ 445a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4468a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner struct TWorker_ 447a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 4488262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision_bits; /* precision related variables */ 4498262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision; 4508262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision_half; 4518262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Long precision_mask; 4528262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision_shift; 4538262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision_step; 4548262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision_jitter; 4558262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg 4568262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int scale_shift; /* == precision_shift for bitmaps */ 457a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* == precision_shift+1 for pixmaps */ 458a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4598262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PLong buff; /* The profiles buffer */ 4608262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PLong sizeBuff; /* Render pool size */ 4618262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PLong maxBuff; /* Profiles buffer size */ 4628262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PLong top; /* Current cursor in buffer */ 463a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4648262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg FT_Error error; 465a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4668262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int numTurns; /* number of Y-turns in outline */ 467a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4688262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg TPoint* arc; /* current Bezier arc pointer */ 469a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4708262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg UShort bWidth; /* target bitmap width */ 4718262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PByte bTarget; /* target bitmap buffer */ 4728262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PByte gTarget; /* target pixmap buffer */ 473a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4748262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Long lastX, lastY; 4758262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Long minY, maxY; 476a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4778262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg UShort num_Profs; /* current number of profiles */ 478a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4798262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Bool fresh; /* signals a fresh new profile which */ 48090c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg /* `start' field must be completed */ 4818262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Bool joint; /* signals that the last arc ended */ 482a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* exactly on a scanline. Allows */ 483a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* removal of doublets */ 4848262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PProfile cProfile; /* current profile */ 4858262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PProfile fProfile; /* head of linked list of profiles */ 4868262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PProfile gProfile; /* contour's first profile in case */ 487a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* of impact */ 488a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4898262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg TStates state; /* rendering state */ 490a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 491a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Bitmap target; /* description of target bit/pixmap */ 492a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Outline outline; 493a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4948262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Long traceOfs; /* current offset in target bitmap */ 4958262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Long traceG; /* current offset in target pixmap */ 496a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4978262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Short traceIncr; /* sweep's increment in target bitmap */ 498a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4998262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Short gray_min_x; /* current min x during gray rendering */ 5008262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Short gray_max_x; /* current max x during gray rendering */ 501a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 502a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* dispatch variables */ 503a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 504a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Init* Proc_Sweep_Init; 505a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Span* Proc_Sweep_Span; 506a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Span* Proc_Sweep_Drop; 507a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Step* Proc_Sweep_Step; 508a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5098262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Byte dropOutControl; /* current drop_out control method */ 510a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5118262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Bool second_pass; /* indicates whether a horizontal pass */ 512a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* should be performed to control */ 513a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* drop-out accurately when calling */ 514a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Render_Glyph. Note that there is */ 515a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* no horizontal pass during gray */ 516a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* rendering. */ 517a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5188262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ 519a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5208262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg TBand band_stack[16]; /* band stack used for sub-banding */ 5218262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int band_top; /* band stack top */ 522a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 523a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 524a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5258262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Byte* grays; 526a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5278262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Byte gray_lines[RASTER_GRAY_LINES]; 528a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Intermediate table used to render the */ 529a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* graylevels pixmaps. */ 530a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* gray_lines is a buffer holding two */ 531a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* monochrome scanlines */ 532a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5338262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Short gray_width; /* width in bytes of one monochrome */ 534a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* intermediate scanline of gray_lines. */ 535a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Each gray pixel takes 2 bits long there */ 536a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 537a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The gray_lines must hold 2 lines, thus with size */ 538a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* in bytes of at least `gray_width*2'. */ 539a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 540a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif /* FT_RASTER_ANTI_ALIASING */ 541a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5428a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner }; 543a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 544a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 545174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg typedef struct TRaster_ 5468a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner { 5478262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg char* buffer; 5488262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg long buffer_size; 5498262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg void* memory; 5508262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PWorker worker; 5518262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Byte grays[5]; 5528262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Short gray_width; 553a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5548a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner } TRaster, *PRaster; 555a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 556f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#ifdef FT_STATIC_RASTER 557a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 558174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg static TWorker cur_ras; 559a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define ras cur_ras 560a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5618262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg#else /* !FT_STATIC_RASTER */ 562a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5638a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define ras (*worker) 564a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5658262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg#endif /* !FT_STATIC_RASTER */ 566a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 567a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 56839c91ad444ac05cc45b54ff48d2d5b70dde01904Werner Lemberg#ifdef FT_RASTER_OPTION_ANTI_ALIASING 56939c91ad444ac05cc45b54ff48d2d5b70dde01904Werner Lemberg 570766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* A lookup table used to quickly count set bits in four gray 2x2 */ 571766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* cells. The values of the table have been produced with the */ 572766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* following code: */ 573766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* */ 574766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* for ( i = 0; i < 256; i++ ) */ 575766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* { */ 576766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* l = 0; */ 577766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* j = i; */ 578766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* */ 579766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* for ( c = 0; c < 4; c++ ) */ 580766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* { */ 581766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* l <<= 4; */ 582766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* */ 583766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* if ( j & 0x80 ) l++; */ 584766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* if ( j & 0x40 ) l++; */ 585766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* */ 586766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* j = ( j << 2 ) & 0xFF; */ 587766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* } */ 588766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* printf( "0x%04X", l ); */ 589766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* } */ 590766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg /* */ 591766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 592766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg static const short count_table[256] = 593174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg { 594766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x0000, 0x0001, 0x0001, 0x0002, 0x0010, 0x0011, 0x0011, 0x0012, 595766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x0010, 0x0011, 0x0011, 0x0012, 0x0020, 0x0021, 0x0021, 0x0022, 596766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, 597766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, 598766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x0100, 0x0101, 0x0101, 0x0102, 0x0110, 0x0111, 0x0111, 0x0112, 599766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x0110, 0x0111, 0x0111, 0x0112, 0x0120, 0x0121, 0x0121, 0x0122, 600766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x0200, 0x0201, 0x0201, 0x0202, 0x0210, 0x0211, 0x0211, 0x0212, 601766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x0210, 0x0211, 0x0211, 0x0212, 0x0220, 0x0221, 0x0221, 0x0222, 602766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, 603766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, 604766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, 605766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, 606766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, 607766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, 608766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, 609766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, 610766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1000, 0x1001, 0x1001, 0x1002, 0x1010, 0x1011, 0x1011, 0x1012, 611766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1010, 0x1011, 0x1011, 0x1012, 0x1020, 0x1021, 0x1021, 0x1022, 612766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, 613766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, 614766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1100, 0x1101, 0x1101, 0x1102, 0x1110, 0x1111, 0x1111, 0x1112, 615766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1110, 0x1111, 0x1111, 0x1112, 0x1120, 0x1121, 0x1121, 0x1122, 616766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1200, 0x1201, 0x1201, 0x1202, 0x1210, 0x1211, 0x1211, 0x1212, 617766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x1210, 0x1211, 0x1211, 0x1212, 0x1220, 0x1221, 0x1221, 0x1222, 618766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x2000, 0x2001, 0x2001, 0x2002, 0x2010, 0x2011, 0x2011, 0x2012, 619766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x2010, 0x2011, 0x2011, 0x2012, 0x2020, 0x2021, 0x2021, 0x2022, 620766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, 621766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, 622766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x2100, 0x2101, 0x2101, 0x2102, 0x2110, 0x2111, 0x2111, 0x2112, 623766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x2110, 0x2111, 0x2111, 0x2112, 0x2120, 0x2121, 0x2121, 0x2122, 624766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x2200, 0x2201, 0x2201, 0x2202, 0x2210, 0x2211, 0x2211, 0x2212, 625766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 0x2210, 0x2211, 0x2211, 0x2212, 0x2220, 0x2221, 0x2221, 0x2222 626cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg }; 62738d1002b8ab6057a54d3483bc0a6f3808d44794dDavid Turner 62839c91ad444ac05cc45b54ff48d2d5b70dde01904Werner Lemberg#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ 62939c91ad444ac05cc45b54ff48d2d5b70dde01904Werner Lemberg 63038d1002b8ab6057a54d3483bc0a6f3808d44794dDavid Turner 63138d1002b8ab6057a54d3483bc0a6f3808d44794dDavid Turner 632a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 633a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 634a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 635a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** PROFILES COMPUTATION **/ 636a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 637a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 638a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 639a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 640a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 641a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 642a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 643a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 644a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Set_High_Precision */ 645a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 646a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 647174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Set precision variables according to param flag. */ 648a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 649a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 650a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* High :: Set to True for high precision (typically for ppem < 18), */ 651a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* false otherwise. */ 652a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 65352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 65452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Set_High_Precision( RAS_ARGS Int High ) 655a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 656a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( High ) 657a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 6580409ef32686188c1947298e0fca9fbeadd23c1c3Werner Lemberg ras.precision_bits = 12; 6590409ef32686188c1947298e0fca9fbeadd23c1c3Werner Lemberg ras.precision_step = 256; 6600409ef32686188c1947298e0fca9fbeadd23c1c3Werner Lemberg ras.precision_jitter = 50; 661a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 662a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 663a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 664a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_bits = 6; 665a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_step = 32; 666a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_jitter = 2; 667a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 668a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 669a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); 670a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 67168e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg ras.precision = 1 << ras.precision_bits; 672a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_half = ras.precision / 2; 673a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_shift = ras.precision_bits - Pixel_Bits; 674a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_mask = -ras.precision; 675a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 676a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 677a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 678a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 679a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 680a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 681a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* New_Profile */ 682a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 683a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 684174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Create a new profile in the render pool. */ 685a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 686a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 68742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* aState :: The state/orientation of the new profile. */ 68842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* */ 68942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* overshoot :: Whether the profile's unrounded start position */ 69042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* differs by at least a half pixel. */ 691a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 692a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 693a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ 694a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 695a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 69652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 69742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg New_Profile( RAS_ARGS TStates aState, 69842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg Bool overshoot ) 699a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 700a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !ras.fProfile ) 701a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 702a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile = (PProfile)ras.top; 703a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fProfile = ras.cProfile; 704a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top += AlignProfileSize; 705a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 706a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 707a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.top >= ras.maxBuff ) 708a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 709a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Overflow; 710a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 711a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 712a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 71342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->flags = 0; 71442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->start = 0; 71542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->height = 0; 71642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->offset = ras.top; 71742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->link = (PProfile)0; 71842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->next = (PProfile)0; 71972271140434028186a49a5dc5925f0727559e46fWerner Lemberg ras.cProfile->flags = ras.dropOutControl; 72042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 721a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( aState ) 722a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 7239ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Ascending_State: 72490c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg ras.cProfile->flags |= Flow_Up; 72542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( overshoot ) 72642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->flags |= Overshoot_Bottom; 72742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 728a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE6(( "New ascending profile = %lx\n", (long)ras.cProfile )); 729a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 730a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 7319ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Descending_State: 73242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( overshoot ) 73342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->flags |= Overshoot_Top; 734a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE6(( "New descending profile = %lx\n", (long)ras.cProfile )); 735a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 736a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 737a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 738858abbedc0c156965aba830bfc2072a3c21144cfWerner Lemberg FT_ERROR(( "New_Profile: invalid profile direction\n" )); 739a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Invalid; 740a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 741a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 742a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 743a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !ras.gProfile ) 744a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gProfile = ras.cProfile; 745a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 746a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.state = aState; 747a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = TRUE; 748a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 749a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 750a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 751a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 752a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 753a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 754a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 755a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 756a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 757a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* End_Profile */ 758a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 759a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 760174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Finalize the current profile. */ 761a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 76242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* <Input> */ 76342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* overshoot :: Whether the profile's unrounded end position differs */ 76442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* by at least a half pixel. */ 76542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* */ 766a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 767a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ 768a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 76952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 77042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg End_Profile( RAS_ARGS Bool overshoot ) 771a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 772a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long h; 773a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile oldProfile; 774a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 775a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 776914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg h = (Long)( ras.top - ras.cProfile->offset ); 777a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 778a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( h < 0 ) 779a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 780858abbedc0c156965aba830bfc2072a3c21144cfWerner Lemberg FT_ERROR(( "End_Profile: negative height encountered\n" )); 781a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Neg_Height; 782a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 783a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 784a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 785a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( h > 0 ) 786a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 787a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE6(( "Ending profile %lx, start = %ld, height = %ld\n", 788a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (long)ras.cProfile, ras.cProfile->start, h )); 789a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 790a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->height = h; 79142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( overshoot ) 79242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg { 79342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( ras.cProfile->flags & Flow_Up ) 79442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->flags |= Overshoot_Top; 79542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg else 79642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->flags |= Overshoot_Bottom; 79742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg } 798a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 79942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg oldProfile = ras.cProfile; 80042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile = (PProfile)ras.top; 80142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 80242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.top += AlignProfileSize; 803a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 804a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->height = 0; 805a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->offset = ras.top; 80642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 80742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg oldProfile->next = ras.cProfile; 808a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.num_Profs++; 809a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 810a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 811a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.top >= ras.maxBuff ) 812a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 813a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE1(( "overflow in End_Profile\n" )); 814a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Overflow; 815a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 816a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 817a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 818a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 819a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 820a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 821a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 822a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 823a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 824a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 825a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 826a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 827a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Insert_Y_Turn */ 828a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 829a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 830174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Insert a salient into the sorted list placed on top of the render */ 831a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* pool. */ 832a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 833a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 834a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* New y scanline position. */ 835a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 836a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 837a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow. */ 838a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 83952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 84052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Insert_Y_Turn( RAS_ARGS Int y ) 841a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 84251daa4feb18fce52a3c5d40bd6c9969203ec6b28Werner Lemberg PLong y_turns; 84351daa4feb18fce52a3c5d40bd6c9969203ec6b28Werner Lemberg Int y2, n; 844a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 845a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 846a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n = ras.numTurns - 1; 847a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_turns = ras.sizeBuff - ras.numTurns; 848a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 849a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* look for first y value that is <= */ 850a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( n >= 0 && y < y_turns[n] ) 851a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n--; 852a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 853a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* if it is <, simply insert it, ignore if == */ 854a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( n >= 0 && y > y_turns[n] ) 855a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( n >= 0 ) 856a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 85768e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg y2 = (Int)y_turns[n]; 858a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_turns[n] = y; 859a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = y2; 860a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n--; 861a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 862a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 863a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( n < 0 ) 864a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 86551daa4feb18fce52a3c5d40bd6c9969203ec6b28Werner Lemberg ras.maxBuff--; 866a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.maxBuff <= ras.top ) 867a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 868a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Overflow; 869a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 870a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 871a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.numTurns++; 872a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.sizeBuff[-ras.numTurns] = y; 873a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 874a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 875a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 876a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 877a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 878a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 879a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 880a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 881a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 882a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Finalize_Profile_Table */ 883a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 884a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 885174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Adjust all links in the profiles list. */ 886a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 887a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 888a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow. */ 889a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 89052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 89152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Finalize_Profile_Table( RAS_ARG ) 892a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 893a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int bottom, top; 894a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner UShort n; 895a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile p; 896a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 897a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 898a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n = ras.num_Profs; 899b66efefdcde552e4880896aa961a0b9a583762d2Werner Lemberg p = ras.fProfile; 900a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 901b66efefdcde552e4880896aa961a0b9a583762d2Werner Lemberg if ( n > 1 && p ) 902a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 903a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( n > 0 ) 904a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 905a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( n > 1 ) 906a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->link = (PProfile)( p->offset + p->height ); 907a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 908a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->link = NULL; 909a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 91090c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg if ( p->flags & Flow_Up ) 91190c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg { 91290c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg bottom = (Int)p->start; 91390c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg top = (Int)( p->start + p->height - 1 ); 91490c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg } 91590c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg else 916a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 91768e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg bottom = (Int)( p->start - p->height + 1 ); 91868e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg top = (Int)p->start; 919a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->start = bottom; 920a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->offset += p->height - 1; 921a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 922a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 92390c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg if ( Insert_Y_Turn( RAS_VARS bottom ) || 92490c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg Insert_Y_Turn( RAS_VARS top + 1 ) ) 925a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 926a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 927a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p = p->link; 928a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n--; 929a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 930a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 931a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 932a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fProfile = NULL; 933a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 934a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 935a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 936a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 937a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 938a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 939a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 940a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 941a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Split_Conic */ 942a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 943a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 944174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */ 945a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* stack. */ 946a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 947a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 948a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* None (subdivided Bezier is taken from the top of the stack). */ 949a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 950a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Note> */ 951a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This routine is the `beef' of this component. It is _the_ inner */ 952a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* loop that should be optimized to hell to get the best performance. */ 953a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 95452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 95552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Split_Conic( TPoint* base ) 956a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 957a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long a, b; 958a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 959a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 960a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].x = base[2].x; 961a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].x; 962a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner a = base[3].x = ( base[2].x + b ) / 2; 963a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].x = ( base[0].x + b ) / 2; 964a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].x = ( a + b ) / 2; 965a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 966a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].y = base[2].y; 967a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].y; 968a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner a = base[3].y = ( base[2].y + b ) / 2; 969a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].y = ( base[0].y + b ) / 2; 970a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].y = ( a + b ) / 2; 971a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 972a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* hand optimized. gcc doesn't seem to be too good at common */ 973a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* expression substitution and instruction scheduling ;-) */ 974a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 975a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 976a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 977a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 978a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 979a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 980a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Split_Cubic */ 981a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 982a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 983174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */ 984a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Bezier stack. */ 985a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 986a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Note> */ 987a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This routine is the `beef' of the component. It is one of _the_ */ 988a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* inner loops that should be optimized like hell to get the best */ 989a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* performance. */ 990a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 99152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 99252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Split_Cubic( TPoint* base ) 993a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 994a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long a, b, c, d; 995a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 996a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 997a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[6].x = base[3].x; 998a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = base[1].x; 999a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner d = base[2].x; 1000a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[1].x = a = ( base[0].x + c + 1 ) >> 1; 1001a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[5].x = b = ( base[3].x + d + 1 ) >> 1; 1002a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = ( c + d + 1 ) >> 1; 1003a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].x = a = ( a + c + 1 ) >> 1; 1004a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].x = b = ( b + c + 1 ) >> 1; 1005a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[3].x = ( a + b + 1 ) >> 1; 1006a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1007a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[6].y = base[3].y; 1008a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = base[1].y; 1009a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner d = base[2].y; 1010a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[1].y = a = ( base[0].y + c + 1 ) >> 1; 1011a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[5].y = b = ( base[3].y + d + 1 ) >> 1; 1012a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = ( c + d + 1 ) >> 1; 1013a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].y = a = ( a + c + 1 ) >> 1; 1014a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].y = b = ( b + c + 1 ) >> 1; 1015a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[3].y = ( a + b + 1 ) >> 1; 1016a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1017a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1018a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1019a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1020a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1021a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1022a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Line_Up */ 1023a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1024a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1025174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an ascending line segment and store */ 1026a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* them in the render pool. */ 1027a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1028a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1029a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x1 :: The x-coordinate of the segment's start point. */ 1030a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1031a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y1 :: The y-coordinate of the segment's start point. */ 1032a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1033a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x2 :: The x-coordinate of the segment's end point. */ 1034a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1035a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y2 :: The y-coordinate of the segment's end point. */ 1036a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1037a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 1038a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1039a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 1040a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1041a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1042a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 1043a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 104452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 104552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Line_Up( RAS_ARGS Long x1, 104652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y1, 104752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x2, 104852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y2, 104952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 105052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 1051a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1052a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long Dx, Dy; 1053a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */ 1054a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long Ix, Rx, Ax; 1055a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1056a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PLong top; 1057a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1058a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1059a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dx = x2 - x1; 1060a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dy = y2 - y1; 1061a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1062a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Dy <= 0 || y2 < miny || y1 > maxy ) 1063a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1064a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1065a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 < miny ) 1066a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1067a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Take care: miny-y1 can be a very large value; we use */ 1068a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* a slow MulDiv function to avoid clipping bugs */ 1069a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 += SMulDiv( Dx, miny - y1, Dy ); 107073861976779a754cc9b808760cc8e6cf98d52549Werner Lemberg e1 = (Int)TRUNC( miny ); 1071a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner f1 = 0; 1072a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1073a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1074a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 107568e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg e1 = (Int)TRUNC( y1 ); 107668e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg f1 = (Int)FRAC( y1 ); 1077a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1078a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1079a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 > maxy ) 1080a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1081a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ 108268e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg e2 = (Int)TRUNC( maxy ); 1083a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner f2 = 0; 1084a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1085a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1086a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 108768e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg e2 = (Int)TRUNC( y2 ); 108868e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg f2 = (Int)FRAC( y2 ); 1089a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1090a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1091a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( f1 > 0 ) 1092a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1093a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 ) 1094a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1095a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1096a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1097a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 += FMulDiv( Dx, ras.precision - f1, Dy ); 1098a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 += 1; 1099a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1100a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1101a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1102a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.joint ) 1103a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1104a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top--; 1105a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 1106a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1107a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 11088edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner ras.joint = (char)( f2 == 0 ); 1109a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1110a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.fresh ) 1111a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = e1; 1113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = FALSE; 1114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1115a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1116a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner size = e2 - e1 + 1; 1117a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.top + size >= ras.maxBuff ) 1118a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1119a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Overflow; 1120a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1121a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1123a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Dx > 0 ) 1124a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1125a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ix = ( ras.precision * Dx ) / Dy; 1126a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Rx = ( ras.precision * Dx ) % Dy; 1127a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dx = 1; 1128a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1129a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1130a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1131a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ix = -( ( ras.precision * -Dx ) / Dy ); 1132a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Rx = ( ras.precision * -Dx ) % Dy; 1133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dx = -1; 1134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1136a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ax = -Dy; 1137a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner top = ras.top; 1138a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( size > 0 ) 1140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1141a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *top++ = x1; 1142a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1143a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 += Ix; 1144a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ax += Rx; 1145a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Ax >= 0 ) 1146a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1147a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ax -= Dy; 1148a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 += Dx; 1149a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1150a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner size--; 1151a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1152a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1153a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = top; 1154a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1155a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1156a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1157a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1158a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1159a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1160a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1161a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Line_Down */ 1162a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1163a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1164174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an descending line segment and store */ 1165174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* them in the render pool. */ 1166a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1167a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1168a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x1 :: The x-coordinate of the segment's start point. */ 1169a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y1 :: The y-coordinate of the segment's start point. */ 1171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1172a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x2 :: The x-coordinate of the segment's end point. */ 1173a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1174a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y2 :: The y-coordinate of the segment's end point. */ 1175a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1176a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 1177a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1178a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 1179a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1180a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1181a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 1182a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 118352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 118452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Line_Down( RAS_ARGS Long x1, 118552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y1, 118652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x2, 118752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y2, 118852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 118952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 1190a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1191a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Bool result, fresh; 1192a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1193a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1194a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner fresh = ras.fresh; 1195a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1196a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); 1197a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1198a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( fresh && !ras.fresh ) 1199a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = -ras.cProfile->start; 1200a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1201a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return result; 1202a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1203a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1204a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1205a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* A function type describing the functions used to split Bezier arcs */ 1206a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef void (*TSplitter)( TPoint* base ); 1207a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1208a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1209a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1210a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1211a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1212a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Bezier_Up */ 1213a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1214a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1215174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an ascending Bezier arc and store */ 1216a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* them in the render pool. */ 1217a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1218a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1219a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* degree :: The degree of the Bezier arc (either 2 or 3). */ 1220a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1221a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* splitter :: The function to split Bezier arcs. */ 1222a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1223a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 1224a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1225a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 1226a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1227a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1228a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 1229a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 123052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 123152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Bezier_Up( RAS_ARGS Int degree, 123252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg TSplitter splitter, 123352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 123452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 1235a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1236a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y1, y2, e, e2, e0; 1237a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short f1; 1238a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1239a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TPoint* arc; 1240a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TPoint* start_arc; 1241a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1242a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PLong top; 1243a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1244a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1245a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc = ras.arc; 1246a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = arc[degree].y; 1247a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = arc[0].y; 1248a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner top = ras.top; 1249a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1250a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 < miny || y1 > maxy ) 1251a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fin; 1252a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1253a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = FLOOR( y2 ); 1254a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1255a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 > maxy ) 1256a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = maxy; 1257a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1258a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e0 = miny; 1259a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1260a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 < miny ) 1261a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e = miny; 1262a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1263a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1264a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e = CEILING( y1 ); 1265914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg f1 = (Short)( FRAC( y1 ) ); 1266a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e0 = e; 1267a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1268a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( f1 == 0 ) 1269a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1270a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.joint ) 1271a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1272a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner top--; 1273a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 1274a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1275a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1276a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *top++ = arc[degree].x; 1277a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1278a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e += ras.precision; 1279a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1280a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1281a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1282a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.fresh ) 1283a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1284a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = TRUNC( e0 ); 1285a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = FALSE; 1286a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1287a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1288a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 < e ) 1289a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fin; 1290a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1291a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) 1292a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1293a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = top; 1294a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Overflow; 1295a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1296a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1297a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1298a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner start_arc = arc; 1299a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1300a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( arc >= start_arc && e <= e2 ) 1301a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1302a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 1303a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1304a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = arc[0].y; 1305a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1306a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 > e ) 1307a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1308a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = arc[degree].y; 1309a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 - y1 >= ras.precision_step ) 1310a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1311a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner splitter( arc ); 1312a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc += degree; 1313a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1314a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1315a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1316cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x, 1317a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e - y1, y2 - y1 ); 1318a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc -= degree; 1319a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e += ras.precision; 1320a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1321a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1322a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1323a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1324a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 == e ) 1325a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1326a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = TRUE; 1327a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *top++ = arc[0].x; 1328a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1329a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e += ras.precision; 1330a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1331a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc -= degree; 1332a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1333a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1334a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1335a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fin: 1336a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = top; 1337a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc -= degree; 1338a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1339a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1340a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1341a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1342a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1343a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1344a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1345a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Bezier_Down */ 1346a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1347a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1348174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an descending Bezier arc and store */ 1349a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* them in the render pool. */ 1350a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1351a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1352a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* degree :: The degree of the Bezier arc (either 2 or 3). */ 1353a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1354a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* splitter :: The function to split Bezier arcs. */ 1355a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1356a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 1357a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1358a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 1359a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1360a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1361a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 1362a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 136352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 136452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Bezier_Down( RAS_ARGS Int degree, 136552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg TSplitter splitter, 136652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 136752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 1368a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1369a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TPoint* arc = ras.arc; 1370a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Bool result, fresh; 1371a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1372a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1373a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[0].y = -arc[0].y; 1374a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[1].y = -arc[1].y; 1375a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[2].y = -arc[2].y; 1376a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( degree > 2 ) 1377a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[3].y = -arc[3].y; 1378a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1379a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner fresh = ras.fresh; 1380a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1381a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny ); 1382a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1383a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( fresh && !ras.fresh ) 1384a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = -ras.cProfile->start; 1385a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1386a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[0].y = -arc[0].y; 1387a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return result; 1388a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1389a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1390a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1391a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1392a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1393a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1394a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Line_To */ 1395a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1396a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1397174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Inject a new line segment and adjust the Profiles list. */ 1398a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1399a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1400a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x :: The x-coordinate of the segment's end point (its start point */ 1401ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* is stored in `lastX'). */ 1402a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1403a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y :: The y-coordinate of the segment's end point (its start point */ 1404ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* is stored in `lastY'). */ 1405a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1406a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1407a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1408a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 1409a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 141052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 141152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Line_To( RAS_ARGS Long x, 141252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y ) 1413a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1414a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* First, detect a change of direction */ 1415a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1416a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( ras.state ) 1417a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 14189ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Unknown_State: 1419a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y > ras.lastY ) 1420a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 142142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( New_Profile( RAS_VARS Ascending_State, 142242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) 1423a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1424a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1425a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1426a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1427a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y < ras.lastY ) 142842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( New_Profile( RAS_VARS Descending_State, 142942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg IS_TOP_OVERSHOOT( ras.lastY ) ) ) 1430a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1431a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1432a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1433a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 14349ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Ascending_State: 1435a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y < ras.lastY ) 1436a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 143742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) || 143842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg New_Profile( RAS_VARS Descending_State, 143942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg IS_TOP_OVERSHOOT( ras.lastY ) ) ) 1440a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1441a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1442a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1443a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 14449ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Descending_State: 1445a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y > ras.lastY ) 1446a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 144742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) || 144842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg New_Profile( RAS_VARS Ascending_State, 144942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) 1450a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1451a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1452a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1453a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1454a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 1455a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ; 1456a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1457a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1458a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Then compute the lines */ 1459a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1460a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( ras.state ) 1461a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 14629ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Ascending_State: 1463a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, 146442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x, y, ras.minY, ras.maxY ) ) 1465a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1466a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1467a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 14689ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Descending_State: 1469a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, 147042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x, y, ras.minY, ras.maxY ) ) 1471a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1472a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1473a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1474a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 1475a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ; 1476a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1477a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1478a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = x; 1479a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = y; 1480a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1481a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1482a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1483a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1484a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1485a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1486a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1487a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1488a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Conic_To */ 1489a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1490a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1491174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Inject a new conic arc and adjust the profile list. */ 1492a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1493a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1494a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cx :: The x-coordinate of the arc's new control point. */ 1495a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1496a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cy :: The y-coordinate of the arc's new control point. */ 1497a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1498a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x :: The x-coordinate of the arc's end point (its start point is */ 1499ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastX'). */ 1500a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1501a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y :: The y-coordinate of the arc's end point (its start point is */ 1502ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastY'). */ 1503a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1504a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1505a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1506a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 1507a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 150852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 150952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Conic_To( RAS_ARGS Long cx, 151052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cy, 151152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x, 151252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y ) 1513a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1514a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y1, y2, y3, x3, ymin, ymax; 1515a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TStates state_bez; 1516a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1517a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1518a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc = ras.arcs; 1519a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[2].x = ras.lastX; 1520a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[2].y = ras.lastY; 1521cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[1].x = cx; 1522cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[1].y = cy; 1523cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[0].x = x; 1524cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[0].y = y; 1525a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1526a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner do 1527a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1528a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = ras.arc[2].y; 1529a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = ras.arc[1].y; 1530a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y3 = ras.arc[0].y; 1531a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x3 = ras.arc[0].x; 1532a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1533a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first, categorize the Bezier arc */ 1534a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1535a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 <= y3 ) 1536a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1537a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin = y1; 1538a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax = y3; 1539a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1540a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1541a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1542a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin = y3; 1543a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax = y1; 1544a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1545a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1546a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 < ymin || y2 > ymax ) 1547a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1548a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc has no given direction, split it! */ 1549a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Split_Conic( ras.arc ); 1550a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc += 2; 1551a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1552a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else if ( y1 == y3 ) 1553a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1554a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc is flat, ignore it and pop it from the Bezier stack */ 1555a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc -= 2; 1556a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1557a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1558a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1559a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the arc is y-monotonous, either ascending or descending */ 1560a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* detect a change of direction */ 15619ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg state_bez = y1 < y3 ? Ascending_State : Descending_State; 1562a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.state != state_bez ) 1563a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 156442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) 156542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg : IS_TOP_OVERSHOOT( y1 ); 156642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 156742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 1568a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* finalize current profile if any */ 1569cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg if ( ras.state != Unknown_State && 157042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg End_Profile( RAS_VARS o ) ) 1571a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1572a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1573a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* create a new profile */ 157442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( New_Profile( RAS_VARS state_bez, o ) ) 1575a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1576a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1577a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1578a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* now call the appropriate routine */ 15799ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( state_bez == Ascending_State ) 1580a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1581a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) 1582a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1583a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1584a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1585a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) 1586a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1587a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1588a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1589a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } while ( ras.arc >= ras.arcs ); 1590a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1591a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = x3; 1592a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = y3; 1593a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1594a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1595a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1596a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fail: 1597a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1598a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1599a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1600a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1601a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1602a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1603a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1604a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Cubic_To */ 1605a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1606a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1607174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Inject a new cubic arc and adjust the profile list. */ 1608a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1609a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1610a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cx1 :: The x-coordinate of the arc's first new control point. */ 1611a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1612a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cy1 :: The y-coordinate of the arc's first new control point. */ 1613a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1614a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cx2 :: The x-coordinate of the arc's second new control point. */ 1615a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1616a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cy2 :: The y-coordinate of the arc's second new control point. */ 1617a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1618a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x :: The x-coordinate of the arc's end point (its start point is */ 1619ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastX'). */ 1620a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1621a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y :: The y-coordinate of the arc's end point (its start point is */ 1622ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastY'). */ 1623a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1624a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1625a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1626a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 1627a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 162852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 162952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Cubic_To( RAS_ARGS Long cx1, 163052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cy1, 163152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cx2, 163252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cy2, 163352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x, 163452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y ) 1635a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1636a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2; 1637a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TStates state_bez; 1638a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1639a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1640a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc = ras.arcs; 1641a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[3].x = ras.lastX; 1642a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[3].y = ras.lastY; 1643cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[2].x = cx1; 1644cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[2].y = cy1; 1645cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[1].x = cx2; 1646cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[1].y = cy2; 1647cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[0].x = x; 1648cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[0].y = y; 1649a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1650a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner do 1651a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1652a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = ras.arc[3].y; 1653a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = ras.arc[2].y; 1654a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y3 = ras.arc[1].y; 1655a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y4 = ras.arc[0].y; 1656a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x4 = ras.arc[0].x; 1657a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1658a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first, categorize the Bezier arc */ 1659a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1660a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 <= y4 ) 1661a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1662a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin1 = y1; 1663a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax1 = y4; 1664a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1665a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1666a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1667a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin1 = y4; 1668a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax1 = y1; 1669a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1670a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1671a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 <= y3 ) 1672a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1673a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin2 = y2; 1674a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax2 = y3; 1675a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1676a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1677a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1678a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin2 = y3; 1679a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax2 = y2; 1680a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1681a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1682a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ymin2 < ymin1 || ymax2 > ymax1 ) 1683a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1684a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc has no given direction, split it! */ 1685a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Split_Cubic( ras.arc ); 1686a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc += 3; 1687a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1688a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else if ( y1 == y4 ) 1689a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1690a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc is flat, ignore it and pop it from the Bezier stack */ 1691a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc -= 3; 1692a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1693a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1694a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 16959ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State; 1696a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1697a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* detect a change of direction */ 1698a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.state != state_bez ) 1699a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 170042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg Bool o = state_bez == Ascending_State ? IS_BOTTOM_OVERSHOOT( y1 ) 170142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg : IS_TOP_OVERSHOOT( y1 ); 170242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 170342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 170442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* finalize current profile if any */ 1705cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg if ( ras.state != Unknown_State && 170642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg End_Profile( RAS_VARS o ) ) 1707a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1708a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 170942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( New_Profile( RAS_VARS state_bez, o ) ) 1710a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1711a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1712a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1713a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* compute intersections */ 17149ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( state_bez == Ascending_State ) 1715a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1716a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) 1717a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1718a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1719a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1720a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) 1721a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1722a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1723a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1724a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } while ( ras.arc >= ras.arcs ); 1725a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1726a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = x4; 1727a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = y4; 1728a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1729a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1730a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1731a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fail: 1732a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1733a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1734a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1735a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1736a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#undef SWAP_ 1737a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define SWAP_( x, y ) do \ 1738a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { \ 1739a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long swap = x; \ 1740a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner \ 1741a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner \ 1742a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = y; \ 1743a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = swap; \ 1744a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } while ( 0 ) 1745a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1746a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1747a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1748a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1749a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1750a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Decompose_Curve */ 1751a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1752a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1753174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Scan the outline arrays in order to emit individual segments and */ 1754a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Beziers by calling Line_To() and Bezier_To(). It handles all */ 1755a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* weird cases, like when the first point is off the curve, or when */ 1756a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* there are simply no `on' points in the contour! */ 1757a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1758a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1759a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first :: The index of the first point in the contour. */ 1760a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1761a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* last :: The index of the last point in the contour. */ 1762a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1763a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* flipped :: If set, flip the direction of the curve. */ 1764a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1765a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1766a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on error. */ 1767a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 176852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 176952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Decompose_Curve( RAS_ARGS UShort first, 177052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg UShort last, 177152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg int flipped ) 1772a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1773a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_last; 1774a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_control; 1775a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_start; 1776a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1777a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector* points; 1778a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector* point; 1779a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector* limit; 1780a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner char* tags; 1781a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 17828edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner unsigned tag; /* current point's state */ 1783a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1784a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1785a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner points = ras.outline.points; 1786a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner limit = points + last; 1787a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1788a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.x = SCALED( points[first].x ); 1789a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.y = SCALED( points[first].y ); 1790a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_last.x = SCALED( points[last].x ); 1791a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_last.y = SCALED( points[last].y ); 1792a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1793a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1794a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1795a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( v_start.x, v_start.y ); 1796a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( v_last.x, v_last.y ); 1797a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1798a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1799a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control = v_start; 1800a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1801a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point = points + first; 1802cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg tags = ras.outline.tags + first; 180372271140434028186a49a5dc5925f0727559e46fWerner Lemberg 180472271140434028186a49a5dc5925f0727559e46fWerner Lemberg /* set scan mode if necessary */ 180572271140434028186a49a5dc5925f0727559e46fWerner Lemberg if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE ) 180672271140434028186a49a5dc5925f0727559e46fWerner Lemberg ras.dropOutControl = (Byte)tags[0] >> 5; 180772271140434028186a49a5dc5925f0727559e46fWerner Lemberg 180872271140434028186a49a5dc5925f0727559e46fWerner Lemberg tag = FT_CURVE_TAG( tags[0] ); 1809a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1810a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* A contour cannot start with a cubic control point! */ 1811b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag == FT_CURVE_TAG_CUBIC ) 1812a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Invalid_Outline; 1813a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1814a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* check first point to determine origin */ 1815b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag == FT_CURVE_TAG_CONIC ) 1816a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1817a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first point is conic control. Yes, this happens. */ 1818b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON ) 1819a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1820a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* start at last point if it is on the curve */ 1821a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start = v_last; 1822a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner limit--; 1823a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1824a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1825a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1826a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* if both first and last points are conic, */ 1827a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* start at their middle and record its position */ 1828a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* for closure */ 1829a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.x = ( v_start.x + v_last.x ) / 2; 1830a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.y = ( v_start.y + v_last.y ) / 2; 1831a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1832a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_last = v_start; 1833a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1834a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point--; 1835a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags--; 1836a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1837a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1838a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = v_start.x; 1839a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = v_start.y; 1840a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1841a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( point < limit ) 1842a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1843a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point++; 1844a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags++; 1845a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1846a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tag = FT_CURVE_TAG( tags[0] ); 1847a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1848a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( tag ) 1849a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1850b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner case FT_CURVE_TAG_ON: /* emit a single line_to */ 1851a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1852a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x, y; 1853a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1854a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1855a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = SCALED( point->x ); 1856a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = SCALED( point->y ); 1857a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1858a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x, y ); 1859a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1860a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_To( RAS_VARS x, y ) ) 1861a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1862a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner continue; 1863a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1864a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1865b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner case FT_CURVE_TAG_CONIC: /* consume conic arcs */ 1866a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.x = SCALED( point[0].x ); 1867a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.y = SCALED( point[0].y ); 1868a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1869a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1870a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( v_control.x, v_control.y ); 1871a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1872a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Do_Conic: 1873a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( point < limit ) 1874a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1875a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_middle; 1876a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x, y; 1877a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1878a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1879a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point++; 1880a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags++; 1881a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tag = FT_CURVE_TAG( tags[0] ); 1882a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1883a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = SCALED( point[0].x ); 1884a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = SCALED( point[0].y ); 1885a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1886a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1887a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x, y ); 1888a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1889b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag == FT_CURVE_TAG_ON ) 1890a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1891a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) ) 1892a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1893a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner continue; 1894a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1895a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1896b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag != FT_CURVE_TAG_CONIC ) 1897a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Invalid_Outline; 1898a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1899a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_middle.x = ( v_control.x + x ) / 2; 1900a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_middle.y = ( v_control.y + y ) / 2; 1901a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1902a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Conic_To( RAS_VARS v_control.x, v_control.y, 1903a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_middle.x, v_middle.y ) ) 1904a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1905a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1906a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.x = x; 1907a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.y = y; 1908a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1909a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Do_Conic; 1910a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1911a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1912a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Conic_To( RAS_VARS v_control.x, v_control.y, 1913a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.x, v_start.y ) ) 1914a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1915a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1916a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Close; 1917a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1918b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner default: /* FT_CURVE_TAG_CUBIC */ 1919a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1920a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x1, y1, x2, y2, x3, y3; 1921a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1922a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1923a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( point + 1 > limit || 1924b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) 1925a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Invalid_Outline; 1926a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1927a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point += 2; 1928a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags += 2; 1929a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1930a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 = SCALED( point[-2].x ); 1931a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = SCALED( point[-2].y ); 1932a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x2 = SCALED( point[-1].x ); 1933a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = SCALED( point[-1].y ); 1934a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x3 = SCALED( point[ 0].x ); 1935a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y3 = SCALED( point[ 0].y ); 1936a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1937a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1938a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1939a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x1, y1 ); 1940a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x2, y2 ); 1941a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x3, y3 ); 1942a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1943a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1944a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( point <= limit ) 1945a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1946a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) ) 1947a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1948a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner continue; 1949a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1950a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1951a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) ) 1952a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1953a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Close; 1954a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1955a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1956a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1957a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1958a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* close the contour with a line segment */ 1959a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_To( RAS_VARS v_start.x, v_start.y ) ) 1960a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1961a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1962a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Close: 1963a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1964a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1965a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Invalid_Outline: 1966a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Invalid; 1967a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1968a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fail: 1969a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1970a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1971a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1972a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1973a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1974a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1975a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1976a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Convert_Glyph */ 1977a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1978a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1979174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Convert a glyph into a series of segments and arcs and make a */ 1980a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profiles list with them. */ 1981a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1982a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1983a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* flipped :: If set, flip the direction of curve. */ 1984a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1985a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1986a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE if any error was encountered during */ 1987a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* rendering. */ 1988a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 198952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 199052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Convert_Glyph( RAS_ARGS int flipped ) 1991a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 19928edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner int i; 19938edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner unsigned start; 1994a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1995a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile lastProfile; 1996a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1997a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1998a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fProfile = NULL; 1999a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 2000a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = FALSE; 2001a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2002a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.maxBuff = ras.sizeBuff - AlignProfileSize; 2003a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2004a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.numTurns = 0; 2005a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2006a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile = (PProfile)ras.top; 2007a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->offset = ras.top; 2008a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.num_Profs = 0; 2009a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2010a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner start = 0; 2011a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2012a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner for ( i = 0; i < ras.outline.n_contours; i++ ) 2013a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 201442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg Bool o; 201542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 201642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 20179ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg ras.state = Unknown_State; 2018a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gProfile = NULL; 2019a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 20208eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg if ( Decompose_Curve( RAS_VARS (unsigned short)start, 202142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.outline.contours[i], 202242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg flipped ) ) 2023a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 2024a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2025a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner start = ras.outline.contours[i] + 1; 2026a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2027cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg /* we must now check whether the extreme arcs join or not */ 2028a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( FRAC( ras.lastY ) == 0 && 2029a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY >= ras.minY && 2030a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY <= ras.maxY ) 203142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( ras.gProfile && 203242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ( ras.gProfile->flags & Flow_Up ) == 203342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ( ras.cProfile->flags & Flow_Up ) ) 2034a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top--; 2035a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Note that ras.gProfile can be nil if the contour was too small */ 2036a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* to be drawn. */ 2037a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2038a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner lastProfile = ras.cProfile; 203942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( ras.cProfile->flags & Flow_Up ) 204042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg o = IS_TOP_OVERSHOOT( ras.lastY ); 204142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg else 204242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg o = IS_BOTTOM_OVERSHOOT( ras.lastY ); 204342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( End_Profile( RAS_VARS o ) ) 2044a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 2045a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2046a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* close the `next profile in contour' linked list */ 2047a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.gProfile ) 2048a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner lastProfile->next = ras.gProfile; 2049a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2050a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2051a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Finalize_Profile_Table( RAS_VAR ) ) 2052a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 2053a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 20548edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE ); 2055a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2056a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2057a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2058a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2059a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2060a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 2061a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** SCAN-LINE SWEEPS AND DRAWING **/ 2062a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 2063a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2064a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2065a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2066a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2067a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2068a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2069a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Init_Linked */ 2070a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2071a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Initializes an empty linked list. */ 2072a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 207352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 207452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Init_Linked( TProfileList* l ) 2075a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2076a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *l = NULL; 2077a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2078a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2079a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2080a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2081a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2082a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* InsNew */ 2083a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2084a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Inserts a new profile in a linked list. */ 2085a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 208652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 208752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg InsNew( PProfileList list, 208852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile profile ) 2089a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2090a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile *old, current; 2091a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x; 2092a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2093a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2094a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 2095a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2096a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = profile->X; 2097a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2098a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( current ) 2099a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2100a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x < current->X ) 2101a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2102a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = ¤t->link; 2103a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2104a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2105a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2106a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner profile->link = current; 2107a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *old = profile; 2108a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2109a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2110a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2111a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* DelOld */ 2114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2115a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Removes an old profile from a linked list. */ 2116a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 211752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 211852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg DelOld( PProfileList list, 211952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile profile ) 2120a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2121a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile *old, current; 2122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2123a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2124a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 2125a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2126a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2127a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( current ) 2128a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2129a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( current == profile ) 2130a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2131a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *old = current->link; 2132a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = ¤t->link; 2136a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2137a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2138a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* we should never get there, unless the profile was not part of */ 2140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the list. */ 2141a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2142a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2143a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2144a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2145a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2146a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Sort */ 2147a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2148a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Sorts a trace list. In 95%, the list is already sorted. We need */ 2149a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* an algorithm which is fast in this case. Bubble sort is enough */ 2150a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* and simple. */ 2151a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 215252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 215352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Sort( PProfileList list ) 2154a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2155a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile *old, current, next; 2156a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2157a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2158a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* First, set the new X coordinate of each profile */ 2159ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current = *list; 2160ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner while ( current ) 2161ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner { 2162ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current->X = *current->offset; 216390c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg current->offset += current->flags & Flow_Up ? 1 : -1; 2164ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current->height--; 2165ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current = current->link; 2166ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner } 2167a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2168a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Then sort them */ 2169a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 2170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2172a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !current ) 2173a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2174a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2175a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner next = current->link; 2176a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2177a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( next ) 2178a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2179a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( current->X <= next->X ) 2180a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2181a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = ¤t->link; 2182a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2183a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2184a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !current ) 2185a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2186a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2187a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2188a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2189a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *old = next; 2190a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current->link = next->link; 2191a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner next->link = current; 2192a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2193a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 2194a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2195a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2196a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2197a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner next = current->link; 2198a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2199a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2200a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2201a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2202a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2203a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2204a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Vertical Sweep Procedure Set */ 2205a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2206a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* These four routines are used during the vertical black/white sweep */ 2207a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* phase by the generic Draw_Sweep() function. */ 2208a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2209a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2210a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 221152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 221252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Init( RAS_ARGS Short* min, 221352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Short* max ) 2214a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2215a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long pitch = ras.target.pitch; 2216a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2217a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( max ); 2218a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2219a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2220a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceIncr = (Short)-pitch; 2221a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs = -*min * pitch; 2222a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( pitch > 0 ) 2223a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs += ( ras.target.rows - 1 ) * pitch; 2224a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2225a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_min_x = 0; 2226a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_max_x = 0; 2227a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2228a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2229a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 223052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 223152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Span( RAS_ARGS Short y, 223252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 223352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 223452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 223552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2236a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2237a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long e1, e2; 22388edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner int c1, c2; 2239a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte f1, f2; 2240a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte* target; 2241a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2242a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( y ); 2243a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( left ); 2244a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( right ); 2245a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2246a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2247a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Drop-out control */ 2248a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2249a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = TRUNC( CEILING( x1 ) ); 2250a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2251a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x2 - x1 - ras.precision <= ras.precision_jitter ) 2252a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = e1; 2253a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2254a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = TRUNC( FLOOR( x2 ) ); 2255a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2256a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 >= 0 && e1 < ras.bWidth ) 2257a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2258a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 < 0 ) 2259a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = 0; 2260a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 >= ras.bWidth ) 2261a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = ras.bWidth - 1; 2262a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2263a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c1 = (Short)( e1 >> 3 ); 2264a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2 = (Short)( e2 >> 3 ); 2265a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22668edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); 22678edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); 2268a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22695df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.gray_min_x > c1 ) 22705df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.gray_min_x = (short)c1; 22715df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.gray_max_x < c2 ) 22725df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.gray_max_x = (short)c2; 2273a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2274a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner target = ras.bTarget + ras.traceOfs + c1; 2275a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2 -= c1; 2276a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2277a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( c2 > 0 ) 2278a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2279a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner target[0] |= f1; 2280a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 228194ffae5239631a18b8b5a39674c0afa8a992410eWerner Lemberg /* memset() is slower than the following code on many platforms. */ 2282a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This is due to the fact that, in the vast majority of cases, */ 2283a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the span length in bytes is relatively small. */ 2284a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2--; 2285a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( c2 > 0 ) 2286a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2287a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *(++target) = 0xFF; 2288a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2--; 2289a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2290a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner target[1] |= f2; 2291a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2292a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2293a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *target |= ( f1 & f2 ); 2294a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2295a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2296a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2297a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 229852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 229952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Drop( RAS_ARGS Short y, 230052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 230152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 230252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 230352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2304a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 23055df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg Long e1, e2, pxl; 2306a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short c1, f1; 2307a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2308a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2309a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Drop-out control */ 2310a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23115df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* e2 x2 x1 e1 */ 23125df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* */ 23135df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* ^ | */ 23145df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | | */ 23155df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* +-------------+---------------------+------------+ */ 23165df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | | */ 23175df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | v */ 23185df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* */ 23195df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* pixel contour contour pixel */ 23205df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* center center */ 23215df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 23225df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* drop-out mode scan conversion rules (as defined in OpenType) */ 23235df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* --------------------------------------------------------------- */ 23245df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 0 1, 2, 3 */ 23255df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 1 1, 2, 4 */ 23265df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 2 1, 2 */ 23275df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 3 same as mode 2 */ 23285df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 4 1, 2, 5 */ 23295df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 5 1, 2, 6 */ 23305df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 6, 7 same as mode 2 */ 23315df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 23325df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = CEILING( x1 ); 23335df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e2 = FLOOR ( x2 ); 23345df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e1; 2335a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2336a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 > e2 ) 2337a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 233872271140434028186a49a5dc5925f0727559e46fWerner Lemberg Int dropOutControl = left->flags & 7; 233972271140434028186a49a5dc5925f0727559e46fWerner Lemberg 234072271140434028186a49a5dc5925f0727559e46fWerner Lemberg 2341a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 + ras.precision ) 2342a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 234372271140434028186a49a5dc5925f0727559e46fWerner Lemberg switch ( dropOutControl ) 2344a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 23455df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 0: /* simple drop-outs including stubs */ 23465df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 2347a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2348a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23495df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 4: /* smart drop-outs including stubs */ 23502f2b780e00235356ffcf1e8f98e19f3bb1910ed2Werner Lemberg pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2351a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2352a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23535df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 1: /* simple drop-outs excluding stubs */ 23545df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 5: /* smart drop-outs excluding stubs */ 2355a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23565df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* Drop-out Control Rules #4 and #6 */ 23575df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 235842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* The specification neither provides an exact definition */ 235942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* of a `stub' nor gives exact rules to exclude them. */ 2360a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 236142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* Here the constraints we use to recognize a stub. */ 2362a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2363a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* upper stub: */ 2364a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2365a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Left and P_Right are in the same contour */ 2366a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Right is the successor of P_Left in that contour */ 2367a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - y is the top of P_Left and P_Right */ 2368a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2369a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* lower stub: */ 2370a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2371a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Left and P_Right are in the same contour */ 2372a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Left is the successor of P_Right in that contour */ 2373a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - y is the bottom of P_Left */ 2374a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 237542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* We draw a stub if the following constraints are met. */ 237642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* */ 237742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* - for an upper or lower stub, there is top or bottom */ 237842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* overshoot, respectively */ 237942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* - the covered interval is greater or equal to a half */ 238042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* pixel */ 238142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 238242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* upper stub test */ 238342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( left->next == right && 238442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg left->height <= 0 && 238542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg !( left->flags & Overshoot_Top && 238642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x2 - x1 >= ras.precision_half ) ) 238742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg return; 2388a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 238942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* lower stub test */ 239042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( right->next == left && 239142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg left->start == y && 239242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg !( left->flags & Overshoot_Bottom && 239342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x2 - x1 >= ras.precision_half ) ) 239442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg return; 2395a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 239672271140434028186a49a5dc5925f0727559e46fWerner Lemberg if ( dropOutControl == 1 ) 23975df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 23985df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 23992f2b780e00235356ffcf1e8f98e19f3bb1910ed2Werner Lemberg pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 24005df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg break; 2401a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24025df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg default: /* modes 2, 3, 6, 7 */ 24035df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg return; /* no drop-out control */ 24045df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg } 2405a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24065df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* check that the other pixel isn't set */ 24075df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = pxl == e1 ? e2 : e1; 2408a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24095df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( e1 ); 2410a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24115df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg c1 = (Short)( e1 >> 3 ); 24125df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg f1 = (Short)( e1 & 7 ); 2413a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24145df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( e1 >= 0 && e1 < ras.bWidth && 24155df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) 24165df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg return; 2417a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2418a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2419a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2420a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2421a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24225df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( pxl ); 2423a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2424a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 >= 0 && e1 < ras.bWidth ) 2425a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2426a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c1 = (Short)( e1 >> 3 ); 2427914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg f1 = (Short)( e1 & 7 ); 2428a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24295df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.gray_min_x > c1 ) 24305df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.gray_min_x = c1; 24315df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.gray_max_x < c1 ) 24325df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.gray_max_x = c1; 2433a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2434a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); 2435a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2436a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2437a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2438a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 243952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 244052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Step( RAS_ARG ) 2441a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2442a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs += ras.traceIncr; 2443a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2444a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2445a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2446a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /***********************************************************************/ 2447a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2448a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Horizontal Sweep Procedure Set */ 2449a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2450a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* These four routines are used during the horizontal black/white */ 2451a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* sweep phase by the generic Draw_Sweep() function. */ 2452a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2453a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /***********************************************************************/ 2454a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 245552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 245652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Init( RAS_ARGS Short* min, 245752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Short* max ) 2458a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2459a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* nothing, really */ 2460f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg FT_UNUSED_RASTER; 2461a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( min ); 2462a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( max ); 2463a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2464a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2465a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 246652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 246752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Span( RAS_ARGS Short y, 246852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 246952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 247052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 247152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2472a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2473a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long e1, e2; 2474a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte bits; 2475a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte f1; 2476a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2477a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( left ); 2478a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( right ); 2479a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2480a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2481a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x2 - x1 < ras.precision ) 2482a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2483a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = CEILING( x1 ); 2484a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = FLOOR ( x2 ); 2485a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2486a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 ) 2487a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2488a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits = ras.bTarget + ( y >> 3 ); 2489a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2490a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2491a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = TRUNC( e1 ); 2492a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2493a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 >= 0 && e1 < ras.target.rows ) 2494a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2495a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte p; 2496a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2497a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2498a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p = bits - e1*ras.target.pitch; 2499a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.target.pitch > 0 ) 2500a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p += ( ras.target.rows - 1 ) * ras.target.pitch; 2501a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2502a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p[0] |= f1; 2503a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2504a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2505a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2506a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2507a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2508a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 250952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 251052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Drop( RAS_ARGS Short y, 251152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 251252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 251352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 251452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2515a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 25165df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg Long e1, e2, pxl; 2517a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte bits; 2518a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte f1; 2519a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2520a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2521a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* During the horizontal sweep, we only take care of drop-outs */ 2522a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25235df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* e1 + <-- pixel center */ 25245df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 25255df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* x1 ---+--> <-- contour */ 25265df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 25275df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 25285df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* x2 <--+--- <-- contour */ 25295df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 25305df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 25315df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* e2 + <-- pixel center */ 25325df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 25335df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = CEILING( x1 ); 25345df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e2 = FLOOR ( x2 ); 25355df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e1; 2536a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2537a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 > e2 ) 2538a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 253972271140434028186a49a5dc5925f0727559e46fWerner Lemberg Int dropOutControl = left->flags & 7; 254072271140434028186a49a5dc5925f0727559e46fWerner Lemberg 254172271140434028186a49a5dc5925f0727559e46fWerner Lemberg 2542a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 + ras.precision ) 2543a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 254472271140434028186a49a5dc5925f0727559e46fWerner Lemberg switch ( dropOutControl ) 2545a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 25465df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 0: /* simple drop-outs including stubs */ 25475df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 2548a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2549a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25505df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 4: /* smart drop-outs including stubs */ 25512f2b780e00235356ffcf1e8f98e19f3bb1910ed2Werner Lemberg pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2552a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2553a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25545df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 1: /* simple drop-outs excluding stubs */ 25555df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 5: /* smart drop-outs excluding stubs */ 25565df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* see Vertical_Sweep_Drop for details */ 2557a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2558a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* rightmost stub test */ 255942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( left->next == right && 256042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg left->height <= 0 && 256142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg !( left->flags & Overshoot_Top && 256242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x2 - x1 >= ras.precision_half ) ) 2563a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2564a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2565a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* leftmost stub test */ 256642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( right->next == left && 256742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg left->start == y && 256842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg !( left->flags & Overshoot_Bottom && 256942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x2 - x1 >= ras.precision_half ) ) 2570a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2571a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 257272271140434028186a49a5dc5925f0727559e46fWerner Lemberg if ( dropOutControl == 1 ) 25735df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 25745df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 25752f2b780e00235356ffcf1e8f98e19f3bb1910ed2Werner Lemberg pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 25765df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg break; 2577a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25785df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg default: /* modes 2, 3, 6, 7 */ 25795df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg return; /* no drop-out control */ 25805df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg } 2581a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25825df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* check that the other pixel isn't set */ 25835df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = pxl == e1 ? e2 : e1; 2584a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25855df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( e1 ); 2586a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25875df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg bits = ras.bTarget + ( y >> 3 ); 25885df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2589a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25905df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg bits -= e1 * ras.target.pitch; 25915df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.target.pitch > 0 ) 25925df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg bits += ( ras.target.rows - 1 ) * ras.target.pitch; 2593a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25945df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( e1 >= 0 && 25955df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 < ras.target.rows && 25965df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg *bits & f1 ) 25975df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg return; 2598a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2599a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2600a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2601a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2602a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2603a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits = ras.bTarget + ( y >> 3 ); 2604a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2605a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 26065df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( pxl ); 2607a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2608a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 >= 0 && e1 < ras.target.rows ) 2609a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2610a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits -= e1 * ras.target.pitch; 2611a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.target.pitch > 0 ) 2612a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits += ( ras.target.rows - 1 ) * ras.target.pitch; 2613a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2614a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits[0] |= f1; 2615a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2616a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2617a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2618a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 261952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 262052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Step( RAS_ARG ) 2621a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2622a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Nothing, really */ 2623f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg FT_UNUSED_RASTER; 2624a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2625a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2626a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2627a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 2628a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2629a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2630a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2631a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2632a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Vertical Gray Sweep Procedure Set */ 2633a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2634a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* These two routines are used during the vertical gray-levels sweep */ 2635a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* phase by the generic Draw_Sweep() function. */ 2636a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2637a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* NOTES */ 2638a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2639a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - The target pixmap's width *must* be a multiple of 4. */ 2640a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2641a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - You have to use the function Vertical_Sweep_Span() for the gray */ 2642a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* span call. */ 2643a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2644a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2645a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 264652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 264752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Gray_Sweep_Init( RAS_ARGS Short* min, 264852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Short* max ) 2649a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2650a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long pitch, byte_len; 2651a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2652a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2653a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *min = *min & -2; 2654a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *max = ( *max + 3 ) & -2; 2655a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2656a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs = 0; 2657a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pitch = ras.target.pitch; 2658a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner byte_len = -pitch; 2659a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceIncr = (Short)byte_len; 2660a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceG = ( *min / 2 ) * byte_len; 2661a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2662a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( pitch > 0 ) 2663a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2664a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceG += ( ras.target.rows - 1 ) * pitch; 2665a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner byte_len = -byte_len; 2666a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2667a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2668a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_min_x = (Short)byte_len; 2669a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_max_x = -(Short)byte_len; 2670a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2671a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2672a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 267352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 267452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Gray_Sweep_Step( RAS_ARG ) 2675a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2676766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg Int c1, c2; 2677766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg PByte pix, bit, bit2; 2678766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg short* count = (short*)count_table; 2679766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg Byte* grays; 2680a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2681a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2682a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs += ras.gray_width; 2683a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2684a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.traceOfs > ras.gray_width ) 2685a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2686a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix = ras.gTarget + ras.traceG + ras.gray_min_x * 4; 2687a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner grays = ras.grays; 2688a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2689a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.gray_max_x >= 0 ) 2690a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2691174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg Long last_pixel = ras.target.width - 1; 2692174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg Int last_cell = last_pixel >> 2; 2693174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg Int last_bit = last_pixel & 3; 2694174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg Bool over = 0; 2695a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2696a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2697a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.gray_max_x >= last_cell && last_bit != 3 ) 2698a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2699a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_max_x = last_cell - 1; 2700a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner over = 1; 2701a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2702a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2703a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.gray_min_x < 0 ) 2704a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_min_x = 0; 2705a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2706174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg bit = ras.bTarget + ras.gray_min_x; 2707174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg bit2 = bit + ras.gray_width; 2708a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2709a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c1 = ras.gray_max_x - ras.gray_min_x; 2710a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2711a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( c1 >= 0 ) 2712a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2713a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2 = count[*bit] + count[*bit2]; 2714a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2715a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( c2 ) 2716a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2717a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[0] = grays[(c2 >> 12) & 0x000F]; 2718a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[1] = grays[(c2 >> 8 ) & 0x000F]; 2719a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[2] = grays[(c2 >> 4 ) & 0x000F]; 2720a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[3] = grays[ c2 & 0x000F]; 2721a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2722a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *bit = 0; 2723a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *bit2 = 0; 2724a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2725a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2726a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bit++; 2727a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bit2++; 2728a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix += 4; 2729a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c1--; 2730a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2731a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2732a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( over ) 2733a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2734a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2 = count[*bit] + count[*bit2]; 2735a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( c2 ) 2736a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2737a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( last_bit ) 2738a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2739a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner case 2: 2740a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[2] = grays[(c2 >> 4 ) & 0x000F]; 2741a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner case 1: 2742a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[1] = grays[(c2 >> 8 ) & 0x000F]; 2743a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 2744a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pix[0] = grays[(c2 >> 12) & 0x000F]; 2745a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2746a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2747a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *bit = 0; 2748a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *bit2 = 0; 2749a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2750a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2751a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2752a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2753a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs = 0; 2754a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceG += ras.traceIncr; 2755a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2756a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_min_x = 32000; 2757a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gray_max_x = -32000; 2758a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2759a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2760a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2761a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 276252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 276352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Gray_Sweep_Span( RAS_ARGS Short y, 276452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 276552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 276652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 276752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2768a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2769a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* nothing, really */ 2770f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg FT_UNUSED_RASTER; 2771a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( y ); 2772a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( x1 ); 2773a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( x2 ); 2774a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( left ); 2775a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( right ); 2776a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2777a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2778a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 277952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 278052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Gray_Sweep_Drop( RAS_ARGS Short y, 278152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 278252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 278352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 278452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2785a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2786a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long e1, e2; 2787a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte pixel; 2788a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte color; 2789a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2790a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2791a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* During the horizontal sweep, we only take care of drop-outs */ 27925df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 2793a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = CEILING( x1 ); 2794a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = FLOOR ( x2 ); 2795a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2796a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 > e2 ) 2797a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 279872271140434028186a49a5dc5925f0727559e46fWerner Lemberg Int dropOutControl = left->flags & 7; 279972271140434028186a49a5dc5925f0727559e46fWerner Lemberg 280072271140434028186a49a5dc5925f0727559e46fWerner Lemberg 2801a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 + ras.precision ) 2802a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 280372271140434028186a49a5dc5925f0727559e46fWerner Lemberg switch ( dropOutControl ) 2804a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 28055df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 0: /* simple drop-outs including stubs */ 2806a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = e2; 2807a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2808a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 28095df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 4: /* smart drop-outs including stubs */ 28102f2b780e00235356ffcf1e8f98e19f3bb1910ed2Werner Lemberg e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2811a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2812a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 28135df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 1: /* simple drop-outs excluding stubs */ 28145df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 5: /* smart drop-outs excluding stubs */ 28155df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* see Vertical_Sweep_Drop for details */ 2816a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2817a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* rightmost stub test */ 2818a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( left->next == right && left->height <= 0 ) 2819a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2820a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2821a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* leftmost stub test */ 2822a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( right->next == left && left->start == y ) 2823a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2824a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 282572271140434028186a49a5dc5925f0727559e46fWerner Lemberg if ( dropOutControl == 1 ) 2826a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = e2; 2827a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 28282f2b780e00235356ffcf1e8f98e19f3bb1910ed2Werner Lemberg e1 = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2829a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2830a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2831a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 28325df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg default: /* modes 2, 3, 6, 7 */ 28335df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg return; /* no drop-out control */ 2834a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2835a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2836a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2837a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2838a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2839a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2840a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 >= 0 ) 2841a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2842a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x2 - x1 >= ras.precision_half ) 2843a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner color = ras.grays[2]; 2844a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2845a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner color = ras.grays[1]; 2846a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2847a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = TRUNC( e1 ) / 2; 2848a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 < ras.target.rows ) 2849a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2850a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pixel = ras.gTarget - e1 * ras.target.pitch + y / 2; 2851a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.target.pitch > 0 ) 2852a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pixel += ( ras.target.rows - 1 ) * ras.target.pitch; 2853a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2854a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( pixel[0] == ras.grays[0] ) 2855a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pixel[0] = color; 2856a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2857a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2858a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2859a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2860a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2861a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif /* FT_RASTER_OPTION_ANTI_ALIASING */ 2862a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2863a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2864a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2865a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2866a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Generic Sweep Drawing routine */ 2867a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2868a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2869a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 287052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 287152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Draw_Sweep( RAS_ARG ) 2872a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2873a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short y, y_change, y_height; 2874a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2875a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile P, Q, P_Left, P_Right; 2876a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2877a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short min_Y, max_Y, top, bottom, dropouts; 2878a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2879a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x1, x2, xs, e1, e2; 2880a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 28813c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg TProfileList waiting; 2882a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TProfileList draw_left, draw_right; 2883a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2884a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2885174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* initialize empty linked lists */ 2886a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 28873c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg Init_Linked( &waiting ); 2888a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2889a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Init_Linked( &draw_left ); 2890a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Init_Linked( &draw_right ); 2891a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2892a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first, compute min and max Y */ 2893a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2894a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = ras.fProfile; 2895a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner max_Y = (Short)TRUNC( ras.minY ); 2896a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner min_Y = (Short)TRUNC( ras.maxY ); 2897a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2898a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2899a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2900a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 2901a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2902a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bottom = (Short)P->start; 2903914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg top = (Short)( P->start + P->height - 1 ); 2904a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 29055df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( min_Y > bottom ) 29065df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg min_Y = bottom; 29075df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( max_Y < top ) 29085df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg max_Y = top; 2909a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2910a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P->X = 0; 29113c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg InsNew( &waiting, P ); 2912a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2913a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 2914a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2915a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2916174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* check the Y-turns */ 2917a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.numTurns == 0 ) 2918a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2919a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Invalid; 2920a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 2921a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2922a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2923174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* now initialize the sweep */ 2924a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2925a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); 2926a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2927174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* then compute the distance of each profile from min_Y */ 2928a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 29293c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg P = waiting; 2930a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2931a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2932a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2933914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg P->countL = (UShort)( P->start - min_Y ); 2934a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = P->link; 2935a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2936a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2937174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* let's go */ 2938a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2939a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = min_Y; 2940a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_height = 0; 2941a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2942cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg if ( ras.numTurns > 0 && 2943a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.sizeBuff[-ras.numTurns] == min_Y ) 2944a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.numTurns--; 2945a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2946a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( ras.numTurns > 0 ) 2947a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2948174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* check waiting list for new activations */ 2949a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 29503c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg P = waiting; 2951a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2952a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2953a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2954a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 2955a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P->countL -= y_height; 2956a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P->countL == 0 ) 2957a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 29583c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg DelOld( &waiting, P ); 2959a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 296090c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg if ( P->flags & Flow_Up ) 2961a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner InsNew( &draw_left, P ); 296290c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg else 2963a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner InsNew( &draw_right, P ); 2964a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2965a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2966a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 2967a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2968a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2969174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* sort the drawing lists */ 2970a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2971a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_left ); 2972a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_right ); 2973a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2974a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_change = (Short)ras.sizeBuff[-ras.numTurns--]; 29758eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg y_height = (Short)( y_change - y ); 2976a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2977a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( y < y_change ) 2978a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2979174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* let's trace */ 2980a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2981a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner dropouts = 0; 2982a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2983a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = draw_left; 2984a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = draw_right; 2985a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2986a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P_Left ) 2987a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2988a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 = P_Left ->X; 2989a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x2 = P_Right->X; 2990a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2991a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x1 > x2 ) 2992a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2993a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner xs = x1; 2994a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 = x2; 2995a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x2 = xs; 2996a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2997a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 299871b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg e1 = FLOOR( x1 ); 299971b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg e2 = CEILING( x2 ); 3000a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 300171b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg if ( x2 - x1 <= ras.precision && 300271b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg e1 != x1 && e2 != x2 ) 300371b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg { 3004ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg if ( e1 > e2 || e2 == e1 + ras.precision ) 3005a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 300672271140434028186a49a5dc5925f0727559e46fWerner Lemberg Int dropOutControl = P_Left->flags & 7; 300772271140434028186a49a5dc5925f0727559e46fWerner Lemberg 300872271140434028186a49a5dc5925f0727559e46fWerner Lemberg 300972271140434028186a49a5dc5925f0727559e46fWerner Lemberg if ( dropOutControl != 2 ) 3010ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg { 3011174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* a drop-out was detected */ 3012a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3013ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg P_Left ->X = x1; 3014ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg P_Right->X = x2; 3015a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3016ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg /* mark profile for drop-out processing */ 3017ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg P_Left->countL = 1; 3018ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg dropouts++; 3019ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg } 3020a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3021a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Skip_To_Next; 3022a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3023a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3024a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3025a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right ); 3026a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3027a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Skip_To_Next: 3028a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3029a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = P_Left->link; 3030a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = P_Right->link; 3031a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3032a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3033174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* handle drop-outs _after_ the span drawing -- */ 3034174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* drop-out processing has been moved out of the loop */ 3035174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* for performance tuning */ 3036a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( dropouts > 0 ) 3037a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Scan_DropOuts; 3038a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3039a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Next_Line: 3040a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3041a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step( RAS_VAR ); 3042a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3043a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y++; 3044a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3045a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y < y_change ) 3046a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3047a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_left ); 3048a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_right ); 3049a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3050a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3051a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3052174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* now finalize the profiles that need it */ 3053a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3054a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = draw_left; 3055a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 3056a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3057a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 3058a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P->height == 0 ) 3059a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner DelOld( &draw_left, P ); 3060a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 3061a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3062a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3063a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = draw_right; 3064a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 3065a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3066a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 3067a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P->height == 0 ) 3068a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner DelOld( &draw_right, P ); 3069a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 3070a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3071a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3072a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3073174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* for gray-scaling, flush the bitmap scanline cache */ 3074a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( y <= max_Y ) 3075a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3076a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step( RAS_VAR ); 3077a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y++; 3078a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3079a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3080a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 3081a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3082a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Scan_DropOuts: 3083a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3084a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = draw_left; 3085a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = draw_right; 3086a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3087a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P_Left ) 3088a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3089a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P_Left->countL ) 3090a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3091a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left->countL = 0; 3092a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#if 0 3093a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner dropouts--; /* -- this is useful when debugging only */ 3094a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 3095a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop( RAS_VARS y, 3096a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left->X, 3097a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right->X, 3098a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left, 3099a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right ); 3100a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3101a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3102a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = P_Left->link; 3103a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = P_Right->link; 3104a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3105a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3106a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Next_Line; 3107a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3108a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3109a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3110a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 3111a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 3113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Render_Single_Pass */ 3114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3115a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 3116174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Perform one sweep with sub-banding. */ 3117a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3118a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 3119a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* flipped :: If set, flip the direction of the outline. */ 3120a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3121a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 3122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Renderer error code. */ 3123a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 312452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 312552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Render_Single_Pass( RAS_ARGS Bool flipped ) 3126a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3127a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short i, j, k; 3128a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3129a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3130a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( ras.band_top >= 0 ) 3131a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3132a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision; 3133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision; 3134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = ras.buff; 3136a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3137a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_None; 3138a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Convert_Glyph( RAS_VARS flipped ) ) 3140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3141a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.error != Raster_Err_Overflow ) 3142a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 3143a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3144a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_None; 3145a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3146a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* sub-banding */ 3147a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3148a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef DEBUG_RASTER 3149a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) ); 3150a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 3151a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3152a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner i = ras.band_stack[ras.band_top].y_min; 3153a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner j = ras.band_stack[ras.band_top].y_max; 3154a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 31558eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg k = (Short)( ( i + j ) / 2 ); 3156a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3157a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.band_top >= 7 || k < i ) 3158a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3159a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3160a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_Invalid; 3161a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3162a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return ras.error; 3163a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3164a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3165a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[ras.band_top + 1].y_min = k; 3166a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[ras.band_top + 1].y_max = j; 3167a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 31688eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg ras.band_stack[ras.band_top].y_max = (Short)( k - 1 ); 3169a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top++; 3171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3172a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 3173a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3174a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.fProfile ) 3175a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Draw_Sweep( RAS_VAR ) ) 3176a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return ras.error; 3177a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top--; 3178a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3179a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3180a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3181a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 3182a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3183a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3184a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3185a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 3186a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3187a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 3188a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Render_Glyph */ 3189a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3190a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 3191174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Render a glyph in a bitmap. Sub-banding if needed. */ 3192a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3193a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 3194a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* FreeType error code. 0 means success. */ 3195a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3196bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner FT_LOCAL_DEF( FT_Error ) 319752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Render_Glyph( RAS_ARG ) 3198a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3199a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Error error; 3200a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3201a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3202a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Set_High_Precision( RAS_VARS ras.outline.flags & 320342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg FT_OUTLINE_HIGH_PRECISION ); 32045df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.scale_shift = ras.precision_shift; 32055df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 32065df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) 32075df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 2; 32085df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 32095df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg { 32105df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) 32115df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 4; 32125df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 32135df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 0; 32145df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 32155df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) 32165df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl += 1; 32175df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg } 32185df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 32195df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.second_pass = (FT_Byte)( !( ras.outline.flags & 32205df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg FT_OUTLINE_SINGLE_PASS ) ); 3221a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3222a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Vertical Sweep */ 3223a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init = Vertical_Sweep_Init; 3224a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span = Vertical_Sweep_Span; 3225a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; 3226a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step = Vertical_Sweep_Step; 3227a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3228a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3229a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_min = 0; 32308eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg ras.band_stack[0].y_max = (short)( ras.target.rows - 1 ); 3231a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 32328edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner ras.bWidth = (unsigned short)ras.target.width; 3233a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bTarget = (Byte*)ras.target.buffer; 3234a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3235a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) 3236a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3237a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3238a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Horizontal Sweep */ 3239ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg if ( ras.second_pass && ras.dropOutControl != 2 ) 3240a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3241a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init = Horizontal_Sweep_Init; 3242a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span = Horizontal_Sweep_Span; 3243a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; 3244a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step = Horizontal_Sweep_Step; 3245a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3246a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3247a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_min = 0; 32488eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg ras.band_stack[0].y_max = (short)( ras.target.width - 1 ); 3249a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3250a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) 3251a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3252a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3253a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3254f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg return Raster_Err_None; 3255a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3256a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3257a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3258a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 3259a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3260a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 3261a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3262a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 3263a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Render_Gray_Glyph */ 3264a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3265a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 3266174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Render a glyph with grayscaling. Sub-banding if needed. */ 3267a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3268a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 3269a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* FreeType error code. 0 means success. */ 3270a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 3271bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner FT_LOCAL_DEF( FT_Error ) 327252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Render_Gray_Glyph( RAS_ARG ) 3273a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3274a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long pixel_width; 3275a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Error error; 3276a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3277a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3278a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Set_High_Precision( RAS_VARS ras.outline.flags & 327942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg FT_OUTLINE_HIGH_PRECISION ); 32805df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.scale_shift = ras.precision_shift + 1; 32815df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 32825df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) 32835df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 2; 32845df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 32855df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg { 32865df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) 32875df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 4; 32885df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 32895df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 0; 32905df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 32915df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) 32925df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl += 1; 32935df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg } 32945df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 32955df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.second_pass = !( ras.outline.flags & FT_OUTLINE_SINGLE_PASS ); 3296a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3297a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Vertical Sweep */ 3298a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3299a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3300a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_min = 0; 3301a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_max = 2 * ras.target.rows - 1; 3302a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3303a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bWidth = ras.gray_width; 3304a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner pixel_width = 2 * ( ( ras.target.width + 3 ) >> 2 ); 3305a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3306a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.bWidth > pixel_width ) 3307a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bWidth = pixel_width; 3308a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3309a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bWidth = ras.bWidth * 8; 3310a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bTarget = (Byte*)ras.gray_lines; 3311a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gTarget = (Byte*)ras.target.buffer; 3312a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3313a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init = Vertical_Gray_Sweep_Init; 3314a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span = Vertical_Sweep_Span; 3315a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; 3316a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step = Vertical_Gray_Sweep_Step; 3317a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3318a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner error = Render_Single_Pass( RAS_VARS 0 ); 3319a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( error ) 3320a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3321a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3322a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Horizontal Sweep */ 3323ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg if ( ras.second_pass && ras.dropOutControl != 2 ) 3324a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3325a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init = Horizontal_Sweep_Init; 3326a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span = Horizontal_Gray_Sweep_Span; 3327a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop = Horizontal_Gray_Sweep_Drop; 3328a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step = Horizontal_Sweep_Step; 3329a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3330a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3331a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_min = 0; 3332a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_max = ras.target.width * 2 - 1; 3333a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3334a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner error = Render_Single_Pass( RAS_VARS 1 ); 3335a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( error ) 3336a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3337a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3338a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3339f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg return Raster_Err_None; 3340a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3341a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3342bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner#else /* !FT_RASTER_OPTION_ANTI_ALIASING */ 3343a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3344bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner FT_LOCAL_DEF( FT_Error ) 3345bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner Render_Gray_Glyph( RAS_ARG ) 3346a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3347a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED_RASTER; 3348a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3349f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg return Raster_Err_Unsupported; 3350a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3351a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3352bc82f1bbefa90c649a9ad2c28938d55b4acbf380David Turner#endif /* !FT_RASTER_OPTION_ANTI_ALIASING */ 3353a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3354a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 335552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 33568a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner ft_black_init( PRaster raster ) 3357a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3358a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 335938d1002b8ab6057a54d3483bc0a6f3808d44794dDavid Turner FT_UInt n; 3360a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 33614ea0a7f0b65c026420f39cabdc146b943c74e2c5Werner Lemberg 3362a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* set default 5-levels gray palette */ 3363a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner for ( n = 0; n < 5; n++ ) 3364a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner raster->grays[n] = n * 255 / 4; 3365a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 33668a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->gray_width = RASTER_GRAY_LINES / 2; 3367eca1f2790578ce8e9907ef3373ab69b7816b3093Werner Lemberg#else 3368eca1f2790578ce8e9907ef3373ab69b7816b3093Werner Lemberg FT_UNUSED( raster ); 3369a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 3370a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3371a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3372a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3373a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ 3374a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /**** a static object. *****/ 3375a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3376a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3377a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef _STANDALONE_ 3378a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3379a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 338052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 3381174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg ft_black_new( void* memory, 338252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_Raster *araster ) 3383a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 33848a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner static TRaster the_raster; 3385a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3386a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3387f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg *araster = (FT_Raster)&the_raster; 3388b3d5e9cf03dce78e606b79c81cb1f29ce06555d5Werner Lemberg FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); 3389a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ft_black_init( &the_raster ); 3390a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3391a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return 0; 3392a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3393a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3394a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 339552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 339652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg ft_black_done( FT_Raster raster ) 3397a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3398a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* nothing */ 3399f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg FT_UNUSED( raster ); 3400a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3401a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3402a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3403a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#else /* _STANDALONE_ */ 3404a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3405a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 340652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 34078a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner ft_black_new( FT_Memory memory, 34088a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner PRaster *araster ) 3409a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 34108a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner FT_Error error; 34118a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner PRaster raster; 3412a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3413a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3414a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *araster = 0; 3415e459d742e6236df43f542b8c29dfdcf05d69716cDavid Turner if ( !FT_NEW( raster ) ) 3416a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3417a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner raster->memory = memory; 3418a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ft_black_init( raster ); 3419a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3420a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *araster = raster; 3421a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3422a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3423a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3424a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3425a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3426a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 342752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 34288a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner ft_black_done( PRaster raster ) 3429a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3430a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Memory memory = (FT_Memory)raster->memory; 3431e459d742e6236df43f542b8c29dfdcf05d69716cDavid Turner FT_FREE( raster ); 3432a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3433a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3434a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3435a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif /* _STANDALONE_ */ 3436a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3437a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 343852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 3439174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg ft_black_reset( PRaster raster, 3440174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg char* pool_base, 3441174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg long pool_size ) 3442a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 34438a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner if ( raster ) 3444a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 34458a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner if ( pool_base && pool_size >= (long)sizeof(TWorker) + 2048 ) 34468a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner { 34478a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner PWorker worker = (PWorker)pool_base; 34488a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner 34494ea0a7f0b65c026420f39cabdc146b943c74e2c5Werner Lemberg 34504ea0a7f0b65c026420f39cabdc146b943c74e2c5Werner Lemberg raster->buffer = pool_base + ( (sizeof ( *worker ) + 7 ) & ~7 ); 34514ea0a7f0b65c026420f39cabdc146b943c74e2c5Werner Lemberg raster->buffer_size = ( ( pool_base + pool_size ) - 34524ea0a7f0b65c026420f39cabdc146b943c74e2c5Werner Lemberg (char*)raster->buffer ) / sizeof ( Long ); 34538a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->worker = worker; 34548a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner } 34558a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner else 34568a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner { 34578a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->buffer = NULL; 34588a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->buffer_size = 0; 34598a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->worker = NULL; 34608a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner } 3461a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3462a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3463a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3464a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 346552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 3466174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg ft_black_set_mode( PRaster raster, 3467174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg unsigned long mode, 3468174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg const char* palette ) 3469a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3470a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 3471a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3472a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( mode == FT_MAKE_TAG( 'p', 'a', 'l', '5' ) ) 3473a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3474a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* set 5-levels gray palette */ 34758a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->grays[0] = palette[0]; 34768a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->grays[1] = palette[1]; 34778a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->grays[2] = palette[2]; 34788a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->grays[3] = palette[3]; 34798a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner raster->grays[4] = palette[4]; 3480a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3481a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3482a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#else 3483a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3484a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( raster ); 3485a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( mode ); 3486a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( palette ); 3487a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3488a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 3489a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3490a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3491a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 349252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 34938a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner ft_black_render( PRaster raster, 3494fa420250c59414e432243feffb70be68654b8c27Werner Lemberg const FT_Raster_Params* params ) 3495a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 34968ae1dceb94effa59a307c0b778b37483f808f3d4Werner Lemberg const FT_Outline* outline = (const FT_Outline*)params->source; 34978ae1dceb94effa59a307c0b778b37483f808f3d4Werner Lemberg const FT_Bitmap* target_map = params->target; 34988a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner PWorker worker; 3499a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3500a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 35018a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner if ( !raster || !raster->buffer || !raster->buffer_size ) 3502a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return Raster_Err_Not_Ini; 3503a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 35041ddd1b768dc3821e275e97c9391e54a14a8dc136Werner Lemberg if ( !outline ) 35051ddd1b768dc3821e275e97c9391e54a14a8dc136Werner Lemberg return Raster_Err_Invalid; 35061ddd1b768dc3821e275e97c9391e54a14a8dc136Werner Lemberg 3507a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* return immediately if the outline is empty */ 3508a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( outline->n_points == 0 || outline->n_contours <= 0 ) 3509a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return Raster_Err_None; 3510a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 35111ddd1b768dc3821e275e97c9391e54a14a8dc136Werner Lemberg if ( !outline->contours || !outline->points ) 3512a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return Raster_Err_Invalid; 3513a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3514c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( outline->n_points != 3515c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg outline->contours[outline->n_contours - 1] + 1 ) 3516a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return Raster_Err_Invalid; 3517a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 35188a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner worker = raster->worker; 35198a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner 3520a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this version of the raster does not support direct rendering, sorry */ 3521b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( params->flags & FT_RASTER_FLAG_DIRECT ) 3522a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return Raster_Err_Unsupported; 3523a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3524c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( !target_map ) 3525c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg return Raster_Err_Invalid; 3526c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg 3527c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg /* nothing to do */ 3528c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( !target_map->width || !target_map->rows ) 3529c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg return Raster_Err_None; 3530c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg 3531c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( !target_map->buffer ) 35321eb9a43aa14e02b56d981bae334e6e24c63298f7David Turner return Raster_Err_Invalid; 35331eb9a43aa14e02b56d981bae334e6e24c63298f7David Turner 35345df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.outline = *outline; 35355df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.target = *target_map; 3536a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 35375df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg worker->buff = (PLong) raster->buffer; 35385df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg worker->sizeBuff = worker->buff + 35395df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg raster->buffer_size / sizeof ( Long ); 35408a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#ifdef FT_RASTER_OPTION_ANTI_ALIASING 35415df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg worker->grays = raster->grays; 35425df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg worker->gray_width = raster->gray_width; 3543766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg 3544766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg FT_MEM_ZERO( worker->gray_lines, worker->gray_width * 2 ); 35458a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#endif 35468a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner 3547cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg return ( params->flags & FT_RASTER_FLAG_AA ) 3548cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ? Render_Gray_Glyph( RAS_VAR ) 3549cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg : Render_Glyph( RAS_VAR ); 3550a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3551a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3552a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 35530d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg FT_DEFINE_RASTER_FUNCS( ft_standard_raster, 3554b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner FT_GLYPH_FORMAT_OUTLINE, 3555a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (FT_Raster_New_Func) ft_black_new, 3556a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (FT_Raster_Reset_Func) ft_black_reset, 3557a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (FT_Raster_Set_Mode_Func)ft_black_set_mode, 3558a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (FT_Raster_Render_Func) ft_black_render, 3559a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner (FT_Raster_Done_Func) ft_black_done 3560056095096fdce9084e23116f7825784a2ad5e677Oran Agra ) 3561a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3562a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3563a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* END */ 3564