1a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/***************************************************************************/ 2a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* */ 3a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* ftraster.c */ 4a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* */ 5a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* The FreeType glyph rasterizer (body). */ 6a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* */ 70a0c22569deab933df21127e75db5c81f724f292Werner Lemberg/* Copyright 1996-2018 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 */ 219d0b76d7f6e87b68ee739688be693f28094b23bfWerner 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 /* */ 27392cf22f8a5a281b8ebc56bf932e66da78f66410Werner Lemberg /* - copy `include/freetype/ftimage.h' and `src/raster/ftmisc.h' to your */ 28392cf22f8a5a281b8ebc56bf932e66da78f66410Werner Lemberg /* current directory */ 29f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* */ 309d0b76d7f6e87b68ee739688be693f28094b23bfWerner Lemberg /* - compile `ftraster' with the STANDALONE_ macro defined, as in */ 31f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg /* */ 329d0b76d7f6e87b68ee739688be693f28094b23bfWerner Lemberg /* cc -c -DSTANDALONE_ 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 509d0b76d7f6e87b68ee739688be693f28094b23bfWerner Lemberg#ifdef STANDALONE_ 51f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg 524d1f7af17b4b0966d5ed7fab215fc855fe459345Werner Lemberg /* The size in bytes of the render pool used by the scan-line converter */ 534d1f7af17b4b0966d5ed7fab215fc855fe459345Werner Lemberg /* to do all of its work. */ 544d1f7af17b4b0966d5ed7fab215fc855fe459345Werner Lemberg#define FT_RENDER_POOL_SIZE 16384L 554d1f7af17b4b0966d5ed7fab215fc855fe459345Werner Lemberg 560d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg#define FT_CONFIG_STANDARD_LIBRARY_H <stdlib.h> 570d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg 58766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg#include <string.h> /* for memset */ 590d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg 60f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#include "ftmisc.h" 61f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#include "ftimage.h" 62f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg 639d0b76d7f6e87b68ee739688be693f28094b23bfWerner Lemberg#else /* !STANDALONE_ */ 64a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 6519ed8afe60bbc5becf0fbbe3987a91b35a36aad4David Turner#include <ft2build.h> 668d3a401fa808a8c70bd6a9ce17d5a840fb0ae2dbDavid Turner#include "ftraster.h" 67495bd3cc4f54f5f4604709391a716fcd0c033277Werner Lemberg#include FT_INTERNAL_CALC_H /* for FT_MulDiv and FT_MulDiv_No_Round */ 68a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 690d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg#include "rastpic.h" 700d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg 719d0b76d7f6e87b68ee739688be693f28094b23bfWerner Lemberg#endif /* !STANDALONE_ */ 72f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg 73a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 74a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 75a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 76a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* A simple technical note on how the raster works */ 77a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* ----------------------------------------------- */ 78a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 79a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Converting an outline into a bitmap is achieved in several steps: */ 80a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 81a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* 1 - Decomposing the outline into successive `profiles'. Each */ 82a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile is simply an array of scanline intersections on a given */ 83a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* dimension. A profile's main attributes are */ 84a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 858262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* o its scanline position boundaries, i.e. `Ymin' and `Ymax' */ 86a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 87a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* o an array of intersection coordinates for each scanline */ 888262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* between `Ymin' and `Ymax' */ 89a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 90a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* o a direction, indicating whether it was built going `up' or */ 918262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* `down', as this is very important for filling rules */ 928262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* */ 938262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* o its drop-out mode */ 94a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 95a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* 2 - Sweeping the target map's scanlines in order to compute segment */ 96a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* `spans' which are then filled. Additionally, this pass */ 97a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* performs drop-out control. */ 98a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 99a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The outline data is parsed during step 1 only. The profiles are */ 100a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* built from the bottom of the render pool, used as a stack. The */ 101a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* following graphics shows the profile list under construction: */ 102a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1038262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* __________________________________________________________ _ _ */ 1048262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* | | | | | */ 1058262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* | profile | coordinates for | profile | coordinates for |--> */ 1068262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* | 1 | profile 1 | 2 | profile 2 |--> */ 1078262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* |_________|_________________|_________|_________________|__ _ _ */ 108a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1098262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* ^ ^ */ 1108262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* | | */ 1118262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* start of render pool top */ 112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The top of the profile stack is kept in the `top' variable. */ 114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 115a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* As you can see, a profile record is pushed on top of the render */ 116a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* pool, which is then followed by its coordinates/intersections. If */ 117a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* a change of direction is detected in the outline, a new profile is */ 118a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* generated until the end of the outline. */ 119a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 120a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Note that when all profiles have been generated, the function */ 121a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Finalize_Profile_Table() is used to record, for each profile, its */ 122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* bottom-most scanline as well as the scanline above its upmost */ 123a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* boundary. These positions are called `y-turns' because they (sort */ 124a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* of) correspond to local extrema. They are stored in a sorted list */ 125a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* built from the top of the render pool as a downwards stack: */ 126a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 127a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* _ _ _______________________________________ */ 128a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* | | */ 129a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <--| sorted list of | */ 130a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <--| extrema scanlines | */ 131a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* _ _ __________________|____________________| */ 132a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* ^ ^ */ 134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* | | */ 135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxBuff sizeBuff = end of pool */ 136a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 137a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This list is later used during the sweep phase in order to */ 138a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* optimize performance (see technical note on the sweep below). */ 139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Of course, the raster detects whether the two stacks collide and */ 1416e87ed9f04f7914e15f9284b0b762b730222c399Werner Lemberg /* handles the situation properly. */ 142a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 143a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 144a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 145a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 146a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 147a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 148a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 149a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** CONFIGURATION MACROS **/ 150a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 151a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 152a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 153a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 154a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* define DEBUG_RASTER if you want to compile a debugging version */ 155766b822f4c1cc84cc11545b63be87108d0954b48Werner Lemberg/* #define DEBUG_RASTER */ 156a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 157a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 158a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 159a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 160a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 161a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** OTHER MACROS (do not change) **/ 162a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 163a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 164a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 165a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 166a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 167a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 168a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 169a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* messages during execution. */ 171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 172a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#undef FT_COMPONENT 173a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FT_COMPONENT trace_raster 174a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 175a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1769d0b76d7f6e87b68ee739688be693f28094b23bfWerner Lemberg#ifdef STANDALONE_ 177a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 178059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg /* Auxiliary macros for token concatenation. */ 179059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg#define FT_ERR_XCAT( x, y ) x ## y 180059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) 181a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 182a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This macro is used to indicate that a function parameter is unused. */ 183a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Its purpose is simply to reduce compiler warnings. Note also that */ 184a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* simply defining it as `(void)x' doesn't avoid warnings with certain */ 185a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* ANSI compilers (e.g. LCC). */ 186a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FT_UNUSED( x ) (x) = (x) 187a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 188a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Disable the tracing mechanism for simplicity -- developers can */ 189059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg /* activate it easily by redefining these macros. */ 190a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FT_ERROR 191f47acf2b5fcd9d6c9dc58809ef8ecf1b1e0b46adWerner Lemberg#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ 192a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 193a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 194a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FT_TRACE 195f47acf2b5fcd9d6c9dc58809ef8ecf1b1e0b46adWerner Lemberg#define FT_TRACE( x ) do { } while ( 0 ) /* nothing */ 196f47acf2b5fcd9d6c9dc58809ef8ecf1b1e0b46adWerner Lemberg#define FT_TRACE1( x ) do { } while ( 0 ) /* nothing */ 197f47acf2b5fcd9d6c9dc58809ef8ecf1b1e0b46adWerner Lemberg#define FT_TRACE6( x ) do { } while ( 0 ) /* nothing */ 198d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */ 199a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 200a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 201059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg#ifndef FT_THROW 202059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg#define FT_THROW( e ) FT_ERR_CAT( Raster_Err_, e ) 203059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg#endif 204059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg 205a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_None 0 206a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Not_Ini -1 207a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Overflow -2 208a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Neg_Height -3 209a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Invalid -4 210a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Raster_Err_Unsupported -5 211a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2120d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg#define ft_memset memset 2130d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg 2140d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, raster_new_, \ 2150d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_reset_, raster_set_mode_, \ 2160d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_render_, raster_done_ ) \ 2170d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg const FT_Raster_Funcs class_ = \ 2180d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg { \ 2190d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg glyph_format_, \ 2200d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_new_, \ 2210d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_reset_, \ 2220d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_set_mode_, \ 2230d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_render_, \ 2240d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg raster_done_ \ 2250d02317fb2a6f46e568cefc1132273cdd1bc80b7Werner Lemberg }; 2268262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg 2279d0b76d7f6e87b68ee739688be693f28094b23bfWerner Lemberg#else /* !STANDALONE_ */ 228a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 229a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2301f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#include FT_INTERNAL_OBJECTS_H 231059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg#include FT_INTERNAL_DEBUG_H /* for FT_TRACE, FT_ERROR, and FT_THROW */ 232a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2331f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#include "rasterrs.h" 2341f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg 235e3c9301581a450fae5db73a3b94b10ed6a0aeb5eWerner Lemberg#define Raster_Err_None FT_Err_Ok 2361f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Not_Ini Raster_Err_Raster_Uninitialized 2371f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Overflow Raster_Err_Raster_Overflow 2381f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Neg_Height Raster_Err_Raster_Negative_Height 2391f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Invalid Raster_Err_Invalid_Outline 2401f7f0e87e58168b2e739e2622db0ee06e0c9acccWerner Lemberg#define Raster_Err_Unsupported Raster_Err_Cannot_Render_Glyph 241a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 242a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2439d0b76d7f6e87b68ee739688be693f28094b23bfWerner Lemberg#endif /* !STANDALONE_ */ 244a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 245a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 246e459d742e6236df43f542b8c29dfdcf05d69716cDavid Turner#ifndef FT_MEM_SET 247d15bc0d13a163995e1ca11925349bd64d1c33617David Turner#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) 248c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg#endif 249c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg 250f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#ifndef FT_MEM_ZERO 251f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) 252f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#endif 253c3b21608699a72698d382ad44c5f9fd6946ce43cWerner Lemberg 25445cad2e5e15c08b682e87b5636cccfc941b3fe7dWerner Lemberg#ifndef FT_ZERO 25545cad2e5e15c08b682e87b5636cccfc941b3fe7dWerner Lemberg#define FT_ZERO( p ) FT_MEM_ZERO( p, sizeof ( *(p) ) ) 25645cad2e5e15c08b682e87b5636cccfc941b3fe7dWerner Lemberg#endif 25745cad2e5e15c08b682e87b5636cccfc941b3fe7dWerner Lemberg 258a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* FMulDiv means `Fast MulDiv'; it is used in case where `b' is */ 259a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* typically a small value and the result of a*b is known to fit into */ 260a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* 32 bits. */ 261a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FMulDiv( a, b, c ) ( (a) * (b) / (c) ) 262a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 263a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* On the other hand, SMulDiv means `Slow MulDiv', and is used typically */ 264a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* for clipping computations. It simply uses the FT_MulDiv() function */ 265a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* defined in `ftcalc.h'. */ 266495bd3cc4f54f5f4604709391a716fcd0c033277Werner Lemberg#define SMulDiv FT_MulDiv 267495bd3cc4f54f5f4604709391a716fcd0c033277Werner Lemberg#define SMulDiv_No_Round FT_MulDiv_No_Round 268a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 269a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* The rasterizer is a very general purpose component; please leave */ 270a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the following redefinitions there (you never know your target */ 271a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* environment). */ 272a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 273a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef TRUE 274a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define TRUE 1 275a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 276a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 277a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FALSE 278a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FALSE 0 279a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 280a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 281a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef NULL 282a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define NULL (void*)0 283a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 284a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 285a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef SUCCESS 286a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define SUCCESS 0 287a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 288a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 289a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifndef FAILURE 290a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FAILURE 1 291a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 292a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 293a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 294a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define MaxBezier 32 /* The maximum number of stacked Bezier curves. */ 295a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Setting this constant to more than 32 is a */ 296a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* pure waste of space. */ 297a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 298a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define Pixel_Bits 6 /* fractional bits of *input* coordinates */ 299a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 300a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 301a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 302a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 303a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 304a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** SIMPLE TYPE DECLARATIONS **/ 305a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 306a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 307a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 308a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 309a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef int Int; 310a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef unsigned int UInt; 311a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef short Short; 312a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef unsigned short UShort, *PUShort; 313a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef long Long, *PLong; 314073a0e2901e931d457f205d870ee77eb0ed763cbWerner Lemberg typedef unsigned long ULong; 315a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 316a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef unsigned char Byte, *PByte; 317a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef char Bool; 318a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 319fefd8742928491a9da356cc1c37f434c76d73514Werner Lemberg 320fefd8742928491a9da356cc1c37f434c76d73514Werner Lemberg typedef union Alignment_ 3218530a228889128adfd446514928f36663ed20f04David Turner { 322a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg Long l; 3238530a228889128adfd446514928f36663ed20f04David Turner void* p; 3248530a228889128adfd446514928f36663ed20f04David Turner void (*f)(void); 3258530a228889128adfd446514928f36663ed20f04David Turner 3268530a228889128adfd446514928f36663ed20f04David Turner } Alignment, *PAlignment; 3278530a228889128adfd446514928f36663ed20f04David Turner 328fefd8742928491a9da356cc1c37f434c76d73514Werner Lemberg 329a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef struct TPoint_ 330a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 331a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x; 332a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y; 333a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 334a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } TPoint; 335a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 336a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 33742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* values for the `flags' bit field */ 338ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg#define Flow_Up 0x08U 339ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg#define Overshoot_Top 0x10U 340ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg#define Overshoot_Bottom 0x20U 341a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 342a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 343a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* States of each line, arc, and profile */ 344a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef enum TStates_ 345a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3469ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Unknown_State, 3479ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Ascending_State, 3489ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Descending_State, 3499ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg Flat_State 350a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 351a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } TStates; 352a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 353a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 354a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef struct TProfile_ TProfile; 355a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef TProfile* PProfile; 356a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 357a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner struct TProfile_ 358a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 35942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg FT_F26Dot6 X; /* current coordinate during sweep */ 36042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg PProfile link; /* link to next profile (various purposes) */ 36142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg PLong offset; /* start of profile's data in render pool */ 362ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg UShort flags; /* Bit 0-2: drop-out mode */ 36372271140434028186a49a5dc5925f0727559e46fWerner Lemberg /* Bit 3: profile orientation (up/down) */ 36472271140434028186a49a5dc5925f0727559e46fWerner Lemberg /* Bit 4: is top profile? */ 36572271140434028186a49a5dc5925f0727559e46fWerner Lemberg /* Bit 5: is bottom profile? */ 366a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg Long height; /* profile's height in scanlines */ 367a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg Long start; /* profile's starting scanline */ 36842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 369ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg Int countL; /* number of lines to step before this */ 37042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* profile becomes drawable */ 37142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 37242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg PProfile next; /* next profile in same contour, used */ 37342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* during drop-out control */ 374a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner }; 375a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 376a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef PProfile TProfileList; 377a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef PProfile* PProfileList; 378a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 379a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 380a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Simple record used to implement a stack of bands, required */ 381a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* by the sub-banding mechanism */ 382126405adde4caf69ea6eacf478ce805f6635f42aVinnie Falco typedef struct black_TBand_ 383a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 384a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short y_min; /* band's minimum */ 385a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short y_max; /* band's maximum */ 386a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 387126405adde4caf69ea6eacf478ce805f6635f42aVinnie Falco } black_TBand; 388a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 389a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 390a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define AlignProfileSize \ 391a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg ( ( sizeof ( TProfile ) + sizeof ( Alignment ) - 1 ) / sizeof ( Long ) ) 392a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 393a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 39495111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco#undef RAS_ARG 39595111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco#undef RAS_ARGS 39695111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco#undef RAS_VAR 39795111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco#undef RAS_VARS 39895111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco 399f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#ifdef FT_STATIC_RASTER 400a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 401a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 402a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_ARGS /* void */ 403a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_ARG /* void */ 404a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 405a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_VARS /* void */ 406a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define RAS_VAR /* void */ 407a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 408f47acf2b5fcd9d6c9dc58809ef8ecf1b1e0b46adWerner Lemberg#define FT_UNUSED_RASTER do { } while ( 0 ) 409a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 410a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4118262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg#else /* !FT_STATIC_RASTER */ 412a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 413a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 414d55f16df11121ef4d5af8dfa0d7670d0bb0e238fVinnie Falco#define RAS_ARGS black_PWorker worker, 415d55f16df11121ef4d5af8dfa0d7670d0bb0e238fVinnie Falco#define RAS_ARG black_PWorker worker 416a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4178a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define RAS_VARS worker, 4188a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define RAS_VAR worker 419a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4208a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define FT_UNUSED_RASTER FT_UNUSED( worker ) 421a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 422a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4238262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg#endif /* !FT_STATIC_RASTER */ 424a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 425a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 426d55f16df11121ef4d5af8dfa0d7670d0bb0e238fVinnie Falco typedef struct black_TWorker_ black_TWorker, *black_PWorker; 427a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 428a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 429a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* prototypes used for sweep function dispatch */ 43052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg typedef void 43152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Function_Sweep_Init( RAS_ARGS Short* min, 43252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Short* max ); 433a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 43452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg typedef void 43552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Function_Sweep_Span( RAS_ARGS Short y, 43652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 43752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 43852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 43952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ); 440a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 44152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg typedef void 44252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Function_Sweep_Step( RAS_ARG ); 443a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 444a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 445a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* NOTE: These operations are only valid on 2's complement processors */ 4465ccebc4e1eb71e5ee82a88edb9cd553e08fc69b9Vinnie Falco#undef FLOOR 4475ccebc4e1eb71e5ee82a88edb9cd553e08fc69b9Vinnie Falco#undef CEILING 4485ccebc4e1eb71e5ee82a88edb9cd553e08fc69b9Vinnie Falco#undef TRUNC 4495ccebc4e1eb71e5ee82a88edb9cd553e08fc69b9Vinnie Falco#undef SCALED 450a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 451a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FLOOR( x ) ( (x) & -ras.precision ) 452a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define CEILING( x ) ( ( (x) + ras.precision - 1 ) & -ras.precision ) 453073a0e2901e931d457f205d870ee77eb0ed763cbWerner Lemberg#define TRUNC( x ) ( (Long)(x) >> ras.precision_bits ) 454a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define FRAC( x ) ( (x) & ( ras.precision - 1 ) ) 4556343ba22a36ab264fa061cab3b87662d5b7b7114Werner Lemberg#define SCALED( x ) ( ( (x) < 0 ? -( -(x) << ras.scale_shift ) \ 4566343ba22a36ab264fa061cab3b87662d5b7b7114Werner Lemberg : ( (x) << ras.scale_shift ) ) \ 4576343ba22a36ab264fa061cab3b87662d5b7b7114Werner Lemberg - ras.precision_half ) 458a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 459c06889eb2c42b40d9ef557b03c9b57d6057e0f12Werner Lemberg#define IS_BOTTOM_OVERSHOOT( x ) \ 460c06889eb2c42b40d9ef557b03c9b57d6057e0f12Werner Lemberg (Bool)( CEILING( x ) - x >= ras.precision_half ) 461c06889eb2c42b40d9ef557b03c9b57d6057e0f12Werner Lemberg#define IS_TOP_OVERSHOOT( x ) \ 462c06889eb2c42b40d9ef557b03c9b57d6057e0f12Werner Lemberg (Bool)( x - FLOOR( x ) >= ras.precision_half ) 46342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 46472a0653142420a060296ed261406ea61342fae8bAlexei Podtelezhnikov (Алексей Подтележников)#if FT_RENDER_POOL_SIZE > 2048 46572a0653142420a060296ed261406ea61342fae8bAlexei Podtelezhnikov (Алексей Подтележников)#define FT_MAX_BLACK_POOL ( FT_RENDER_POOL_SIZE / sizeof ( Long ) ) 4663e1f7bc506652bbeb89632733430a72a92dde2cdAlexei Podtelezhnikov (Алексей Подтележников)#else 46772a0653142420a060296ed261406ea61342fae8bAlexei Podtelezhnikov (Алексей Подтележников)#define FT_MAX_BLACK_POOL ( 2048 / sizeof ( Long ) ) 46872a0653142420a060296ed261406ea61342fae8bAlexei Podtelezhnikov (Алексей Подтележников)#endif 46972a0653142420a060296ed261406ea61342fae8bAlexei Podtelezhnikov (Алексей Подтележников) 4708262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* The most used variables are positioned at the top of the structure. */ 4718262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* Thus, their offset can be coded with less opcodes, resulting in a */ 4728262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg /* smaller executable. */ 473a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 474d55f16df11121ef4d5af8dfa0d7670d0bb0e238fVinnie Falco struct black_TWorker_ 475a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 4768262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision_bits; /* precision related variables */ 4778262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision; 4788262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision_half; 4798262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision_shift; 4808262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision_step; 4818262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int precision_jitter; 4828262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg 4838262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int scale_shift; /* == precision_shift for bitmaps */ 484a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* == precision_shift+1 for pixmaps */ 485a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4868262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PLong buff; /* The profiles buffer */ 4878262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PLong sizeBuff; /* Render pool size */ 4888262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PLong maxBuff; /* Profiles buffer size */ 4898262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PLong top; /* Current cursor in buffer */ 490a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4918262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg FT_Error error; 492a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4938262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Int numTurns; /* number of Y-turns in outline */ 494a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4958262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg TPoint* arc; /* current Bezier arc pointer */ 496a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 4978262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg UShort bWidth; /* target bitmap width */ 4988262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PByte bTarget; /* target bitmap buffer */ 4998262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PByte gTarget; /* target pixmap buffer */ 500a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5018262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Long lastX, lastY; 5028262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Long minY, maxY; 503a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5048262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg UShort num_Profs; /* current number of profiles */ 505a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5068262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Bool fresh; /* signals a fresh new profile which */ 50790c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg /* `start' field must be completed */ 5088262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Bool joint; /* signals that the last arc ended */ 509a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* exactly on a scanline. Allows */ 510a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* removal of doublets */ 5118262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PProfile cProfile; /* current profile */ 5128262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PProfile fProfile; /* head of linked list of profiles */ 5138262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg PProfile gProfile; /* contour's first profile in case */ 514a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* of impact */ 515a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5168262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg TStates state; /* rendering state */ 517a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 518a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Bitmap target; /* description of target bit/pixmap */ 519a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Outline outline; 520a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5218262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Long traceOfs; /* current offset in target bitmap */ 5228262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Long traceG; /* current offset in target pixmap */ 523a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5248262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Short traceIncr; /* sweep's increment in target bitmap */ 525a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 526a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* dispatch variables */ 527a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 528a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Init* Proc_Sweep_Init; 529a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Span* Proc_Sweep_Span; 530a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Span* Proc_Sweep_Drop; 531a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Function_Sweep_Step* Proc_Sweep_Step; 532a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5338262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Byte dropOutControl; /* current drop_out control method */ 534a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5358262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg Bool second_pass; /* indicates whether a horizontal pass */ 536a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* should be performed to control */ 537a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* drop-out accurately when calling */ 5388dc863587440d0a1d2eec2a7973a8eda99d2767dBehdad Esfahbod /* Render_Glyph. */ 539a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5408262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg TPoint arcs[3 * MaxBezier + 1]; /* The Bezier stack */ 541a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 542126405adde4caf69ea6eacf478ce805f6635f42aVinnie Falco black_TBand band_stack[16]; /* band stack used for sub-banding */ 543126405adde4caf69ea6eacf478ce805f6635f42aVinnie Falco Int band_top; /* band stack top */ 544a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5458a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner }; 546a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 547a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 54895111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco typedef struct black_TRaster_ 5498a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner { 550d55f16df11121ef4d5af8dfa0d7670d0bb0e238fVinnie Falco void* memory; 551a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 55295111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco } black_TRaster, *black_PRaster; 553a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 554f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg#ifdef FT_STATIC_RASTER 555a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 556d55f16df11121ef4d5af8dfa0d7670d0bb0e238fVinnie Falco static black_TWorker cur_ras; 557a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define ras cur_ras 558a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5598262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg#else /* !FT_STATIC_RASTER */ 560a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5618a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner#define ras (*worker) 562a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 5638262213192704679677edfd6f1b89c94b8de8f3bWerner Lemberg#endif /* !FT_STATIC_RASTER */ 564a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 565a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 566a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 567a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 568a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 569a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** PROFILES COMPUTATION **/ 570a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 571a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 572a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 573a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 574a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 575a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 576a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 577a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 578a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Set_High_Precision */ 579a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 580a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 581174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Set precision variables according to param flag. */ 582a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 583a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 584762bf19ab7416a40c8c3cf553bd4f02eec45c3b2Werner Lemberg /* High :: Set to True for high precision (typically for ppem < 24), */ 585a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* false otherwise. */ 586a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 58752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 58852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Set_High_Precision( RAS_ARGS Int High ) 589a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 590c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg /* 591c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * `precision_step' is used in `Bezier_Up' to decide when to split a 592c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * given y-monotonous Bezier arc that crosses a scanline before 593c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * approximating it as a straight segment. The default value of 32 (for 594c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * low accuracy) corresponds to 595c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * 596d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg * 32 / 64 == 0.5 pixels, 597c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * 598c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * while for the high accuracy case we have 599c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * 600d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg * 256 / (1 << 12) = 0.0625 pixels. 601c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * 602c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * `precision_jitter' is an epsilon threshold used in 603c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * `Vertical_Sweep_Span' to deal with small imperfections in the Bezier 604c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * decomposition (after all, we are working with approximations only); 605c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * it avoids switching on additional pixels which would cause artifacts 606c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * otherwise. 607c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * 608c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * The value of `precision_jitter' has been determined heuristically. 609c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg * 610c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg */ 611c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg 612a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( High ) 613a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 6140409ef32686188c1947298e0fca9fbeadd23c1c3Werner Lemberg ras.precision_bits = 12; 6150409ef32686188c1947298e0fca9fbeadd23c1c3Werner Lemberg ras.precision_step = 256; 616c02485cb725f94ea0487351596adc1e3ef8d1ae6Werner Lemberg ras.precision_jitter = 30; 617a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 618a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 619a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 620a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_bits = 6; 621a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_step = 32; 622a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_jitter = 2; 623a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 624a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 625a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE6(( "Set_High_Precision(%s)\n", High ? "true" : "false" )); 626a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 62768e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg ras.precision = 1 << ras.precision_bits; 628a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_half = ras.precision / 2; 629a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.precision_shift = ras.precision_bits - Pixel_Bits; 630a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 631a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 632a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 633a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 634a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 635a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 636a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* New_Profile */ 637a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 638a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 639174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Create a new profile in the render pool. */ 640a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 641a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 64242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* aState :: The state/orientation of the new profile. */ 64342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* */ 64442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* overshoot :: Whether the profile's unrounded start position */ 64542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* differs by at least a half pixel. */ 646a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 647a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 648a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow or of incoherent */ 649a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 650a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 65152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 65242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg New_Profile( RAS_ARGS TStates aState, 65342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg Bool overshoot ) 654a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 655a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !ras.fProfile ) 656a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 657a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile = (PProfile)ras.top; 658a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fProfile = ras.cProfile; 659a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top += AlignProfileSize; 660a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 661a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 662a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.top >= ras.maxBuff ) 663a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 664059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg ras.error = FT_THROW( Overflow ); 665a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 666a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 667a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 66842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->flags = 0; 66942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->start = 0; 67042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->height = 0; 67142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->offset = ras.top; 67242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->link = (PProfile)0; 67342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->next = (PProfile)0; 67472271140434028186a49a5dc5925f0727559e46fWerner Lemberg ras.cProfile->flags = ras.dropOutControl; 67542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 676a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( aState ) 677a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 6789ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Ascending_State: 67990c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg ras.cProfile->flags |= Flow_Up; 68042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( overshoot ) 68142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->flags |= Overshoot_Bottom; 68242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 683d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE6(( " new ascending profile = %p\n", ras.cProfile )); 684a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 685a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 6869ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Descending_State: 68742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( overshoot ) 68842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->flags |= Overshoot_Top; 689d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE6(( " new descending profile = %p\n", ras.cProfile )); 690a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 691a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 692a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 693858abbedc0c156965aba830bfc2072a3c21144cfWerner Lemberg FT_ERROR(( "New_Profile: invalid profile direction\n" )); 694059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg ras.error = FT_THROW( Invalid ); 695a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 696a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 697a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 698a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !ras.gProfile ) 699a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gProfile = ras.cProfile; 700a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 701a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.state = aState; 702a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = TRUE; 703a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 704a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 705a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 706a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 707a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 708a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 709a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 710a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 711a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 712a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* End_Profile */ 713a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 714a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 715174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Finalize the current profile. */ 716a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 71742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* <Input> */ 71842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* overshoot :: Whether the profile's unrounded end position differs */ 71942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* by at least a half pixel. */ 72042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* */ 721a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 722a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow or incoherency. */ 723a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 72452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 72542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg End_Profile( RAS_ARGS Bool overshoot ) 726a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 727dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg Long h; 728a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 729a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 730914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg h = (Long)( ras.top - ras.cProfile->offset ); 731a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 732a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( h < 0 ) 733a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 734858abbedc0c156965aba830bfc2072a3c21144cfWerner Lemberg FT_ERROR(( "End_Profile: negative height encountered\n" )); 735059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg ras.error = FT_THROW( Neg_Height ); 736a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 737a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 738a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 739a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( h > 0 ) 740a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 741dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg PProfile oldProfile; 742dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg 743dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg 744d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE6(( " ending profile %p, start = %ld, height = %ld\n", 74546c371c2c7398d25fa614065c28a27ebb4b5d489Suzuki, Toshiya (鈴木俊哉) ras.cProfile, ras.cProfile->start, h )); 746a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 747a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->height = h; 74842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( overshoot ) 74942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg { 75042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( ras.cProfile->flags & Flow_Up ) 75142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->flags |= Overshoot_Top; 75242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg else 75342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile->flags |= Overshoot_Bottom; 75442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg } 755a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 75642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg oldProfile = ras.cProfile; 75742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.cProfile = (PProfile)ras.top; 75842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 75942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ras.top += AlignProfileSize; 760a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 761a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->height = 0; 762a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->offset = ras.top; 76342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 76442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg oldProfile->next = ras.cProfile; 765a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.num_Profs++; 766a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 767a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 768a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.top >= ras.maxBuff ) 769a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 770a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_TRACE1(( "overflow in End_Profile\n" )); 771059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg ras.error = FT_THROW( Overflow ); 772a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 773a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 774a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 775a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 776a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 777a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 778a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 779a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 780a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 781a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 782a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 783a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 784a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Insert_Y_Turn */ 785a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 786a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 787174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Insert a salient into the sorted list placed on top of the render */ 788a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* pool. */ 789a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 790a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 791a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* New y scanline position. */ 792a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 793a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 794a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow. */ 795a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 79652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 79752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Insert_Y_Turn( RAS_ARGS Int y ) 798a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 79951daa4feb18fce52a3c5d40bd6c9969203ec6b28Werner Lemberg PLong y_turns; 800dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg Int n; 801a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 802a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 803a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n = ras.numTurns - 1; 804a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_turns = ras.sizeBuff - ras.numTurns; 805a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 806a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* look for first y value that is <= */ 807a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( n >= 0 && y < y_turns[n] ) 808a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n--; 809a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 810a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* if it is <, simply insert it, ignore if == */ 811a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( n >= 0 && y > y_turns[n] ) 8125a6dc87240905f0e55568678e0fbf93a51242051Alexei Podtelezhnikov (Алексей Подтележников) do 813a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 814dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg Int y2 = (Int)y_turns[n]; 815dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg 816dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg 817a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_turns[n] = y; 818a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = y2; 8195a6dc87240905f0e55568678e0fbf93a51242051Alexei Podtelezhnikov (Алексей Подтележников) } while ( --n >= 0 ); 820a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 821a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( n < 0 ) 822a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 82351daa4feb18fce52a3c5d40bd6c9969203ec6b28Werner Lemberg ras.maxBuff--; 824a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.maxBuff <= ras.top ) 825a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 826059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg ras.error = FT_THROW( Overflow ); 827a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 828a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 829a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.numTurns++; 830a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.sizeBuff[-ras.numTurns] = y; 831a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 832a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 833a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 834a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 835a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 836a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 837a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 838a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 839a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 840a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Finalize_Profile_Table */ 841a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 842a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 843174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Adjust all links in the profiles list. */ 844a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 845a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 846a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success. FAILURE in case of overflow. */ 847a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 84852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 84952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Finalize_Profile_Table( RAS_ARG ) 850a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 851a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner UShort n; 852a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile p; 853a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 854a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 855a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner n = ras.num_Profs; 856b66efefdcde552e4880896aa961a0b9a583762d2Werner Lemberg p = ras.fProfile; 857a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 858b66efefdcde552e4880896aa961a0b9a583762d2Werner Lemberg if ( n > 1 && p ) 859a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 8605a6dc87240905f0e55568678e0fbf93a51242051Alexei Podtelezhnikov (Алексей Подтележников) do 861a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 862dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg Int bottom, top; 863dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg 864dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg 865a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( n > 1 ) 866a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->link = (PProfile)( p->offset + p->height ); 867a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 868a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->link = NULL; 869a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 87090c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg if ( p->flags & Flow_Up ) 87190c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg { 87290c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg bottom = (Int)p->start; 87390c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg top = (Int)( p->start + p->height - 1 ); 87490c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg } 87590c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg else 876a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 87768e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg bottom = (Int)( p->start - p->height + 1 ); 87868e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg top = (Int)p->start; 879a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->start = bottom; 880a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p->offset += p->height - 1; 881a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 882a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 88390c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg if ( Insert_Y_Turn( RAS_VARS bottom ) || 88490c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg Insert_Y_Turn( RAS_VARS top + 1 ) ) 885a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 886a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 887a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p = p->link; 8885a6dc87240905f0e55568678e0fbf93a51242051Alexei Podtelezhnikov (Алексей Подтележников) } while ( --n ); 889a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 890a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 891a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fProfile = NULL; 892a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 893a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 894a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 895a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 896a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 897a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 898a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 899a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 900a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Split_Conic */ 901a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 902a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 903174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Subdivide one conic Bezier into two joint sub-arcs in the Bezier */ 904a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* stack. */ 905a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 906a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 907a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* None (subdivided Bezier is taken from the top of the stack). */ 908a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 909a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Note> */ 910a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This routine is the `beef' of this component. It is _the_ inner */ 911a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* loop that should be optimized to hell to get the best performance. */ 912a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 91352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 91452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Split_Conic( TPoint* base ) 915a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 916a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long a, b; 917a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 918a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 919a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].x = base[2].x; 920a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].x; 921a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner a = base[3].x = ( base[2].x + b ) / 2; 922a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].x = ( base[0].x + b ) / 2; 923a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].x = ( a + b ) / 2; 924a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 925a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].y = base[2].y; 926a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].y; 927a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner a = base[3].y = ( base[2].y + b ) / 2; 928a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner b = base[1].y = ( base[0].y + b ) / 2; 929a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].y = ( a + b ) / 2; 930a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 931a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* hand optimized. gcc doesn't seem to be too good at common */ 932a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* expression substitution and instruction scheduling ;-) */ 933a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 934a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 935a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 936a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 937a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 938a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 939a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Split_Cubic */ 940a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 941a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 942174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Subdivide a third-order Bezier arc into two joint sub-arcs in the */ 943a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Bezier stack. */ 944a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 945a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Note> */ 946a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This routine is the `beef' of the component. It is one of _the_ */ 947a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* inner loops that should be optimized like hell to get the best */ 948a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* performance. */ 949a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 95052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 95152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Split_Cubic( TPoint* base ) 952a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 953a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long a, b, c, d; 954a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 955a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 956a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[6].x = base[3].x; 957a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = base[1].x; 958a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner d = base[2].x; 959a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[1].x = a = ( base[0].x + c + 1 ) >> 1; 960a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[5].x = b = ( base[3].x + d + 1 ) >> 1; 961a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = ( c + d + 1 ) >> 1; 962a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].x = a = ( a + c + 1 ) >> 1; 963a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].x = b = ( b + c + 1 ) >> 1; 964a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[3].x = ( a + b + 1 ) >> 1; 965a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 966a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[6].y = base[3].y; 967a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = base[1].y; 968a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner d = base[2].y; 969a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[1].y = a = ( base[0].y + c + 1 ) >> 1; 970a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[5].y = b = ( base[3].y + d + 1 ) >> 1; 971a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c = ( c + d + 1 ) >> 1; 972a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[2].y = a = ( a + c + 1 ) >> 1; 973a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[4].y = b = ( b + c + 1 ) >> 1; 974a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner base[3].y = ( a + b + 1 ) >> 1; 975a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 976a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 977a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 978a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 979a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 980a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 981a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Line_Up */ 982a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 983a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 984174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an ascending line segment and store */ 985a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* them in the render pool. */ 986a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 987a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 988a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x1 :: The x-coordinate of the segment's start point. */ 989a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 990a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y1 :: The y-coordinate of the segment's start point. */ 991a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 992a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x2 :: The x-coordinate of the segment's end point. */ 993a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 994a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y2 :: The y-coordinate of the segment's end point. */ 995a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 996a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 997a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 998a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 999a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1000a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1001a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 1002a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 100352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 100452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Line_Up( RAS_ARGS Long x1, 100552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y1, 100652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x2, 100752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y2, 100852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 100952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 1010a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1011a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long Dx, Dy; 1012a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Int e1, e2, f1, f2, size; /* XXX: is `Short' sufficient? */ 1013a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long Ix, Rx, Ax; 1014a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1015a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PLong top; 1016a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1017a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1018a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dx = x2 - x1; 1019a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dy = y2 - y1; 1020a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1021a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Dy <= 0 || y2 < miny || y1 > maxy ) 1022a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1023a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1024a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 < miny ) 1025a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1026a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Take care: miny-y1 can be a very large value; we use */ 1027a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* a slow MulDiv function to avoid clipping bugs */ 1028a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 += SMulDiv( Dx, miny - y1, Dy ); 102973861976779a754cc9b808760cc8e6cf98d52549Werner Lemberg e1 = (Int)TRUNC( miny ); 1030a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner f1 = 0; 1031a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1032a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1033a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 103468e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg e1 = (Int)TRUNC( y1 ); 103568e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg f1 = (Int)FRAC( y1 ); 1036a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1037a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1038a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 > maxy ) 1039a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1040a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x2 += FMulDiv( Dx, maxy - y2, Dy ); UNNECESSARY */ 104168e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg e2 = (Int)TRUNC( maxy ); 1042a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner f2 = 0; 1043a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1044a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1045a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 104668e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg e2 = (Int)TRUNC( y2 ); 104768e9f927105b22ec6952a5bc929cfabfc6b7e810Werner Lemberg f2 = (Int)FRAC( y2 ); 1048a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1049a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1050a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( f1 > 0 ) 1051a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1052a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 ) 1053a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1054a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1055a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1056f0987abdc24b136100656f49ecfe3997869cd93dWerner Lemberg x1 += SMulDiv( Dx, ras.precision - f1, Dy ); 1057a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 += 1; 1058a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1059a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1060a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1061a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.joint ) 1062a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1063a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top--; 1064a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 1065a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1066a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 10678edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner ras.joint = (char)( f2 == 0 ); 1068a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1069a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.fresh ) 1070a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1071a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = e1; 1072a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = FALSE; 1073a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1074a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1075a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner size = e2 - e1 + 1; 1076a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.top + size >= ras.maxBuff ) 1077a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1078059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg ras.error = FT_THROW( Overflow ); 1079a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1080a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1081a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1082a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Dx > 0 ) 1083a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1084495bd3cc4f54f5f4604709391a716fcd0c033277Werner Lemberg Ix = SMulDiv_No_Round( ras.precision, Dx, Dy ); 1085a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Rx = ( ras.precision * Dx ) % Dy; 1086a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dx = 1; 1087a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1088a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1089a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1090495bd3cc4f54f5f4604709391a716fcd0c033277Werner Lemberg Ix = -SMulDiv_No_Round( ras.precision, -Dx, Dy ); 1091495bd3cc4f54f5f4604709391a716fcd0c033277Werner Lemberg Rx = ( ras.precision * -Dx ) % Dy; 1092a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Dx = -1; 1093a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1094a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1095a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ax = -Dy; 1096a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner top = ras.top; 1097a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1098a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( size > 0 ) 1099a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1100a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *top++ = x1; 1101a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1102a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 += Ix; 1103a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ax += Rx; 1104a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Ax >= 0 ) 1105a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1106a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Ax -= Dy; 1107a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 += Dx; 1108a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1109a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner size--; 1110a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1111a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = top; 1113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1115a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1116a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1117a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1118a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1119a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1120a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Line_Down */ 1121a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1123174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an descending line segment and store */ 1124174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* them in the render pool. */ 1125a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1126a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1127a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x1 :: The x-coordinate of the segment's start point. */ 1128a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1129a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y1 :: The y-coordinate of the segment's start point. */ 1130a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1131a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x2 :: The x-coordinate of the segment's end point. */ 1132a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y2 :: The y-coordinate of the segment's end point. */ 1134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 1136a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1137a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 1138a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 1141a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 114252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 114352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Line_Down( RAS_ARGS Long x1, 114452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y1, 114552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x2, 114652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y2, 114752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 114852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 1149a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1150a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Bool result, fresh; 1151a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1152a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1153a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner fresh = ras.fresh; 1154a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1155a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner result = Line_Up( RAS_VARS x1, -y1, x2, -y2, -maxy, -miny ); 1156a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1157a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( fresh && !ras.fresh ) 1158a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = -ras.cProfile->start; 1159a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1160a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return result; 1161a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1162a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1163a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1164a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* A function type describing the functions used to split Bezier arcs */ 1165a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner typedef void (*TSplitter)( TPoint* base ); 1166a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1167a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1168a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1169a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Bezier_Up */ 1172a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1173a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1174174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an ascending Bezier arc and store */ 1175a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* them in the render pool. */ 1176a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1177a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1178a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* degree :: The degree of the Bezier arc (either 2 or 3). */ 1179a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1180a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* splitter :: The function to split Bezier arcs. */ 1181a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1182a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 1183a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1184a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 1185a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1186a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1187a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 1188a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 118952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 119052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Bezier_Up( RAS_ARGS Int degree, 119152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg TSplitter splitter, 119252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 119352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 1194a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1195a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y1, y2, e, e2, e0; 1196a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short f1; 1197a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1198a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TPoint* arc; 1199a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TPoint* start_arc; 1200a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1201a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PLong top; 1202a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1203a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1204a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc = ras.arc; 1205a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = arc[degree].y; 1206a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = arc[0].y; 1207a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner top = ras.top; 1208a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1209a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 < miny || y1 > maxy ) 1210a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fin; 1211a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1212a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = FLOOR( y2 ); 1213a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1214a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 > maxy ) 1215a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = maxy; 1216a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1217a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e0 = miny; 1218a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1219a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 < miny ) 1220a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e = miny; 1221a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1222a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1223a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e = CEILING( y1 ); 1224914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg f1 = (Short)( FRAC( y1 ) ); 1225a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e0 = e; 1226a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1227a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( f1 == 0 ) 1228a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1229a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.joint ) 1230a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1231a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner top--; 1232a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 1233a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1234a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1235a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *top++ = arc[degree].x; 1236a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1237a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e += ras.precision; 1238a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1239a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1240a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1241a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.fresh ) 1242a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1243a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = TRUNC( e0 ); 1244a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = FALSE; 1245a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1246a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1247a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 < e ) 1248a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fin; 1249a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1250a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ( top + TRUNC( e2 - e ) + 1 ) >= ras.maxBuff ) 1251a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1252a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = top; 1253059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg ras.error = FT_THROW( Overflow ); 1254a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1255a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1256a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1257a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner start_arc = arc; 1258a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 12595a6dc87240905f0e55568678e0fbf93a51242051Alexei Podtelezhnikov (Алексей Подтележников) do 1260a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1261a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 1262a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1263a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = arc[0].y; 1264a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1265a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 > e ) 1266a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1267a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = arc[degree].y; 1268a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 - y1 >= ras.precision_step ) 1269a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1270a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner splitter( arc ); 1271a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc += degree; 1272a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1273a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1274a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1275cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg *top++ = arc[degree].x + FMulDiv( arc[0].x - arc[degree].x, 1276a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e - y1, y2 - y1 ); 1277a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc -= degree; 1278a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e += ras.precision; 1279a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1280a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1281a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1282a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1283a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 == e ) 1284a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1285a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = TRUE; 1286a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *top++ = arc[0].x; 1287a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1288a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e += ras.precision; 1289a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1290a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc -= degree; 1291a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 12925a6dc87240905f0e55568678e0fbf93a51242051Alexei Podtelezhnikov (Алексей Подтележников) } while ( arc >= start_arc && e <= e2 ); 1293a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1294a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fin: 1295a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = top; 1296a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc -= degree; 1297a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1298a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1299a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1300a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1301a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1302a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1303a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1304a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Bezier_Down */ 1305a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1306a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1307174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Compute the x-coordinates of an descending Bezier arc and store */ 1308a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* them in the render pool. */ 1309a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1310a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1311a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* degree :: The degree of the Bezier arc (either 2 or 3). */ 1312a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1313a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* splitter :: The function to split Bezier arcs. */ 1314a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1315a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* miny :: A lower vertical clipping bound value. */ 1316a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1317a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* maxy :: An upper vertical clipping bound value. */ 1318a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1319a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1320a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow. */ 1321a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 132252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 132352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Bezier_Down( RAS_ARGS Int degree, 132452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg TSplitter splitter, 132552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long miny, 132652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long maxy ) 1327a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1328a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TPoint* arc = ras.arc; 1329a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Bool result, fresh; 1330a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1331a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1332a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[0].y = -arc[0].y; 1333a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[1].y = -arc[1].y; 1334a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[2].y = -arc[2].y; 1335a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( degree > 2 ) 1336a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[3].y = -arc[3].y; 1337a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1338a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner fresh = ras.fresh; 1339a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1340a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner result = Bezier_Up( RAS_VARS degree, splitter, -maxy, -miny ); 1341a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1342a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( fresh && !ras.fresh ) 1343a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->start = -ras.cProfile->start; 1344a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1345a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner arc[0].y = -arc[0].y; 1346a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return result; 1347a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1348a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1349a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1350a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1351a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1352a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1353a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Line_To */ 1354a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1355a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1356174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Inject a new line segment and adjust the Profiles list. */ 1357a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1358a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1359a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x :: The x-coordinate of the segment's end point (its start point */ 1360ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* is stored in `lastX'). */ 1361a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1362a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y :: The y-coordinate of the segment's end point (its start point */ 1363ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* is stored in `lastY'). */ 1364a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1365a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1366a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1367a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 1368a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 136952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 137052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Line_To( RAS_ARGS Long x, 137152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y ) 1372a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1373a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* First, detect a change of direction */ 1374a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1375a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( ras.state ) 1376a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 13779ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Unknown_State: 1378a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y > ras.lastY ) 1379a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 138042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( New_Profile( RAS_VARS Ascending_State, 138142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) 1382a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1383a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1384a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1385a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1386a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y < ras.lastY ) 138742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( New_Profile( RAS_VARS Descending_State, 138842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg IS_TOP_OVERSHOOT( ras.lastY ) ) ) 1389a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1390a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1391a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1392a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 13939ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Ascending_State: 1394a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y < ras.lastY ) 1395a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 139642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( End_Profile( RAS_VARS IS_TOP_OVERSHOOT( ras.lastY ) ) || 139742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg New_Profile( RAS_VARS Descending_State, 139842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg IS_TOP_OVERSHOOT( ras.lastY ) ) ) 1399a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1400a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1401a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1402a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 14039ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Descending_State: 1404a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y > ras.lastY ) 1405a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 140642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( End_Profile( RAS_VARS IS_BOTTOM_OVERSHOOT( ras.lastY ) ) || 140742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg New_Profile( RAS_VARS Ascending_State, 140842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg IS_BOTTOM_OVERSHOOT( ras.lastY ) ) ) 1409a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1410a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1411a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1412a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1413a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 1414a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ; 1415a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1416a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1417a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Then compute the lines */ 1418a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1419a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( ras.state ) 1420a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 14219ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Ascending_State: 1422a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_Up( RAS_VARS ras.lastX, ras.lastY, 142342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x, y, ras.minY, ras.maxY ) ) 1424a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1425a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1426a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 14279ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg case Descending_State: 1428a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_Down( RAS_VARS ras.lastX, ras.lastY, 142942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x, y, ras.minY, ras.maxY ) ) 1430a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1431a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 1432a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1433a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner default: 1434a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ; 1435a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1436a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1437a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = x; 1438a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = y; 1439a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1440a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1441a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1442a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1443a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1444a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1445a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1446a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1447a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Conic_To */ 1448a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1449a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1450174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Inject a new conic arc and adjust the profile list. */ 1451a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1452a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1453a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cx :: The x-coordinate of the arc's new control point. */ 1454a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1455a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cy :: The y-coordinate of the arc's new control point. */ 1456a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1457a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x :: The x-coordinate of the arc's end point (its start point is */ 1458ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastX'). */ 1459a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1460a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y :: The y-coordinate of the arc's end point (its start point is */ 1461ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastY'). */ 1462a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1463a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1464a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1465a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 1466a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 146752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 146852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Conic_To( RAS_ARGS Long cx, 146952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cy, 147052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x, 147152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y ) 1472a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1473a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y1, y2, y3, x3, ymin, ymax; 1474a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TStates state_bez; 1475a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1476a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1477a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc = ras.arcs; 1478a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[2].x = ras.lastX; 1479a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[2].y = ras.lastY; 1480cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[1].x = cx; 1481cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[1].y = cy; 1482cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[0].x = x; 1483cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[0].y = y; 1484a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1485a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner do 1486a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1487a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = ras.arc[2].y; 1488a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = ras.arc[1].y; 1489a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y3 = ras.arc[0].y; 1490a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x3 = ras.arc[0].x; 1491a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1492a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first, categorize the Bezier arc */ 1493a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1494a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 <= y3 ) 1495a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1496a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin = y1; 1497a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax = y3; 1498a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1499a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1500a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1501a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin = y3; 1502a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax = y1; 1503a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1504a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1505a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 < ymin || y2 > ymax ) 1506a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1507a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc has no given direction, split it! */ 1508a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Split_Conic( ras.arc ); 1509a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc += 2; 1510a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1511a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else if ( y1 == y3 ) 1512a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1513a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc is flat, ignore it and pop it from the Bezier stack */ 1514a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc -= 2; 1515a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1516a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1517a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1518a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the arc is y-monotonous, either ascending or descending */ 1519a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* detect a change of direction */ 15209ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg state_bez = y1 < y3 ? Ascending_State : Descending_State; 1521a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.state != state_bez ) 1522a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 152337c72f66a56887ec25f4f541337b00e8ba69b9eeWerner Lemberg Bool o = ( state_bez == Ascending_State ) 152437c72f66a56887ec25f4f541337b00e8ba69b9eeWerner Lemberg ? IS_BOTTOM_OVERSHOOT( y1 ) 152537c72f66a56887ec25f4f541337b00e8ba69b9eeWerner Lemberg : IS_TOP_OVERSHOOT( y1 ); 152642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 152742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 1528a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* finalize current profile if any */ 1529cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg if ( ras.state != Unknown_State && 153042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg End_Profile( RAS_VARS o ) ) 1531a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1532a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1533a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* create a new profile */ 153442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( New_Profile( RAS_VARS state_bez, o ) ) 1535a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1536a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1537a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1538a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* now call the appropriate routine */ 15399ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( state_bez == Ascending_State ) 1540a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1541a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Up( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) 1542a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1543a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1544a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1545a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Down( RAS_VARS 2, Split_Conic, ras.minY, ras.maxY ) ) 1546a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1547a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1548a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1549a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } while ( ras.arc >= ras.arcs ); 1550a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1551a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = x3; 1552a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = y3; 1553a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1554a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1555a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1556a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fail: 1557a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1558a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1559a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1560a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1561a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1562a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1563a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1564a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Cubic_To */ 1565a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1566a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1567174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Inject a new cubic arc and adjust the profile list. */ 1568a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1569a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1570a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cx1 :: The x-coordinate of the arc's first new control point. */ 1571a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1572a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cy1 :: The y-coordinate of the arc's first new control point. */ 1573a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1574a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cx2 :: The x-coordinate of the arc's second new control point. */ 1575a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1576a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* cy2 :: The y-coordinate of the arc's second new control point. */ 1577a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1578a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* x :: The x-coordinate of the arc's end point (its start point is */ 1579ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastX'). */ 1580a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1581a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* y :: The y-coordinate of the arc's end point (its start point is */ 1582ce235eaf099765b1a868ce27fef4e83171767e11Werner Lemberg /* stored in `lastY'). */ 1583a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1584a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1585a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on render pool overflow or incorrect */ 1586a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profile. */ 1587a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 158852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 158952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Cubic_To( RAS_ARGS Long cx1, 159052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cy1, 159152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cx2, 159252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long cy2, 159352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long x, 159452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Long y ) 1595a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1596a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long y1, y2, y3, y4, x4, ymin1, ymax1, ymin2, ymax2; 1597a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TStates state_bez; 1598a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1599a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1600a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc = ras.arcs; 1601a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[3].x = ras.lastX; 1602a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc[3].y = ras.lastY; 1603cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[2].x = cx1; 1604cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[2].y = cy1; 1605cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[1].x = cx2; 1606cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[1].y = cy2; 1607cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[0].x = x; 1608cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg ras.arc[0].y = y; 1609a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1610a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner do 1611a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1612a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = ras.arc[3].y; 1613a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = ras.arc[2].y; 1614a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y3 = ras.arc[1].y; 1615a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y4 = ras.arc[0].y; 1616a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x4 = ras.arc[0].x; 1617a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1618a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first, categorize the Bezier arc */ 1619a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1620a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y1 <= y4 ) 1621a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1622a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin1 = y1; 1623a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax1 = y4; 1624a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1625a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1626a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1627a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin1 = y4; 1628a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax1 = y1; 1629a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1630a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1631a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y2 <= y3 ) 1632a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1633a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin2 = y2; 1634a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax2 = y3; 1635a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1636a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1637a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1638a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymin2 = y3; 1639a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ymax2 = y2; 1640a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1641a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1642a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ymin2 < ymin1 || ymax2 > ymax1 ) 1643a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1644a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc has no given direction, split it! */ 1645a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Split_Cubic( ras.arc ); 1646a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc += 3; 1647a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1648a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else if ( y1 == y4 ) 1649a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1650a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this arc is flat, ignore it and pop it from the Bezier stack */ 1651a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.arc -= 3; 1652a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1653a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1654a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 16559ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg state_bez = ( y1 <= y4 ) ? Ascending_State : Descending_State; 1656a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1657a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* detect a change of direction */ 1658a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.state != state_bez ) 1659a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 166037c72f66a56887ec25f4f541337b00e8ba69b9eeWerner Lemberg Bool o = ( state_bez == Ascending_State ) 166137c72f66a56887ec25f4f541337b00e8ba69b9eeWerner Lemberg ? IS_BOTTOM_OVERSHOOT( y1 ) 166237c72f66a56887ec25f4f541337b00e8ba69b9eeWerner Lemberg : IS_TOP_OVERSHOOT( y1 ); 166342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 166442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 166542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* finalize current profile if any */ 1666cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg if ( ras.state != Unknown_State && 166742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg End_Profile( RAS_VARS o ) ) 1668a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1669a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 167042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( New_Profile( RAS_VARS state_bez, o ) ) 1671a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1672a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1673a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1674a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* compute intersections */ 16759ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg if ( state_bez == Ascending_State ) 1676a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1677a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Up( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) 1678a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1679a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1680a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1681a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Bezier_Down( RAS_VARS 3, Split_Cubic, ras.minY, ras.maxY ) ) 1682a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1683a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1684a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1685a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } while ( ras.arc >= ras.arcs ); 1686a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1687a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = x4; 1688a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = y4; 1689a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1690a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1691a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1692a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fail: 1693a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1694a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1695a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1696a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1697a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#undef SWAP_ 1698a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#define SWAP_( x, y ) do \ 1699a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { \ 1700a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long swap = x; \ 1701a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner \ 1702a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner \ 1703a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = y; \ 1704a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = swap; \ 1705a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } while ( 0 ) 1706a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1707a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1708a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1709a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1710a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1711a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Decompose_Curve */ 1712a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1713a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1714174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Scan the outline arrays in order to emit individual segments and */ 1715a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Beziers by calling Line_To() and Bezier_To(). It handles all */ 1716a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* weird cases, like when the first point is off the curve, or when */ 1717a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* there are simply no `on' points in the contour! */ 1718a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1719a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1720a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first :: The index of the first point in the contour. */ 1721a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1722a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* last :: The index of the last point in the contour. */ 1723a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1724a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* flipped :: If set, flip the direction of the curve. */ 1725a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1726a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1727a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE on error. */ 1728a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 172952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 173052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Decompose_Curve( RAS_ARGS UShort first, 173152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg UShort last, 1732a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg Int flipped ) 1733a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1734a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_last; 1735a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_control; 1736a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_start; 1737a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1738a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector* points; 1739a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector* point; 1740a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector* limit; 1741a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner char* tags; 1742a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1743a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg UInt tag; /* current point's state */ 1744a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1745a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1746a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner points = ras.outline.points; 1747a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner limit = points + last; 1748a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1749a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.x = SCALED( points[first].x ); 1750a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.y = SCALED( points[first].y ); 1751a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_last.x = SCALED( points[last].x ); 1752a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_last.y = SCALED( points[last].y ); 1753a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1754a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1755a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1756a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( v_start.x, v_start.y ); 1757a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( v_last.x, v_last.y ); 1758a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1759a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1760a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control = v_start; 1761a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1762a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point = points + first; 1763cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg tags = ras.outline.tags + first; 176472271140434028186a49a5dc5925f0727559e46fWerner Lemberg 176572271140434028186a49a5dc5925f0727559e46fWerner Lemberg /* set scan mode if necessary */ 176672271140434028186a49a5dc5925f0727559e46fWerner Lemberg if ( tags[0] & FT_CURVE_TAG_HAS_SCANMODE ) 176772271140434028186a49a5dc5925f0727559e46fWerner Lemberg ras.dropOutControl = (Byte)tags[0] >> 5; 176872271140434028186a49a5dc5925f0727559e46fWerner Lemberg 176972271140434028186a49a5dc5925f0727559e46fWerner Lemberg tag = FT_CURVE_TAG( tags[0] ); 1770a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1771a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* A contour cannot start with a cubic control point! */ 1772b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag == FT_CURVE_TAG_CUBIC ) 1773a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Invalid_Outline; 1774a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1775a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* check first point to determine origin */ 1776b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag == FT_CURVE_TAG_CONIC ) 1777a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1778a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first point is conic control. Yes, this happens. */ 1779b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( FT_CURVE_TAG( ras.outline.tags[last] ) == FT_CURVE_TAG_ON ) 1780a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1781a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* start at last point if it is on the curve */ 1782a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start = v_last; 1783a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner limit--; 1784a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1785a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 1786a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1787a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* if both first and last points are conic, */ 1788a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* start at their middle and record its position */ 1789a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* for closure */ 1790a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.x = ( v_start.x + v_last.x ) / 2; 1791a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.y = ( v_start.y + v_last.y ) / 2; 1792a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 17937be2a94a50109773459414687151d70a99a1b6bdSean McBride /* v_last = v_start; */ 1794a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1795a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point--; 1796a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags--; 1797a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1798a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1799a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastX = v_start.x; 1800a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY = v_start.y; 1801a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1802a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( point < limit ) 1803a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1804a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point++; 1805a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags++; 1806a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1807a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tag = FT_CURVE_TAG( tags[0] ); 1808a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1809a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner switch ( tag ) 1810a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1811b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner case FT_CURVE_TAG_ON: /* emit a single line_to */ 1812a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1813a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x, y; 1814a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1815a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1816a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = SCALED( point->x ); 1817a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = SCALED( point->y ); 1818a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1819a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x, y ); 1820a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1821a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_To( RAS_VARS x, y ) ) 1822a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1823a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner continue; 1824a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1825a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1826b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner case FT_CURVE_TAG_CONIC: /* consume conic arcs */ 1827a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.x = SCALED( point[0].x ); 1828a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.y = SCALED( point[0].y ); 1829a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1830a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1831a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( v_control.x, v_control.y ); 1832a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1833a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Do_Conic: 1834a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( point < limit ) 1835a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1836a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Vector v_middle; 1837a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x, y; 1838a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1839a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1840a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point++; 1841a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags++; 1842a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tag = FT_CURVE_TAG( tags[0] ); 1843a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1844a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = SCALED( point[0].x ); 1845a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = SCALED( point[0].y ); 1846a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1847a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1848a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x, y ); 1849a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1850b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag == FT_CURVE_TAG_ON ) 1851a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1852a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Conic_To( RAS_VARS v_control.x, v_control.y, x, y ) ) 1853a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1854a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner continue; 1855a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1856a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1857b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( tag != FT_CURVE_TAG_CONIC ) 1858a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Invalid_Outline; 1859a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1860a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_middle.x = ( v_control.x + x ) / 2; 1861a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_middle.y = ( v_control.y + y ) / 2; 1862a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1863a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Conic_To( RAS_VARS v_control.x, v_control.y, 1864a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_middle.x, v_middle.y ) ) 1865a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1866a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1867a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.x = x; 1868a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_control.y = y; 1869a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1870a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Do_Conic; 1871a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1872a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1873a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Conic_To( RAS_VARS v_control.x, v_control.y, 1874a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner v_start.x, v_start.y ) ) 1875a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1876a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1877a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Close; 1878a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1879b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner default: /* FT_CURVE_TAG_CUBIC */ 1880a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1881a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x1, y1, x2, y2, x3, y3; 1882a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1883a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1884a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( point + 1 > limit || 1885b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) 1886a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Invalid_Outline; 1887a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1888a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner point += 2; 1889a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner tags += 2; 1890a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1891a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 = SCALED( point[-2].x ); 1892a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y1 = SCALED( point[-2].y ); 1893a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x2 = SCALED( point[-1].x ); 1894a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y2 = SCALED( point[-1].y ); 1895a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1896a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( flipped ) 1897a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1898a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x1, y1 ); 1899a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner SWAP_( x2, y2 ); 1900a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1901a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1902a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( point <= limit ) 1903a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1904c9de9cbd56caea5ceeab8d984e71441803c41aefYuriy Kaminskiy x3 = SCALED( point[0].x ); 1905c9de9cbd56caea5ceeab8d984e71441803c41aefYuriy Kaminskiy y3 = SCALED( point[0].y ); 1906c9de9cbd56caea5ceeab8d984e71441803c41aefYuriy Kaminskiy 1907c9de9cbd56caea5ceeab8d984e71441803c41aefYuriy Kaminskiy if ( flipped ) 1908c9de9cbd56caea5ceeab8d984e71441803c41aefYuriy Kaminskiy SWAP_( x3, y3 ); 1909c9de9cbd56caea5ceeab8d984e71441803c41aefYuriy Kaminskiy 1910a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Cubic_To( RAS_VARS x1, y1, x2, y2, x3, y3 ) ) 1911a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1912a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner continue; 1913a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1914a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1915a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Cubic_To( RAS_VARS x1, y1, x2, y2, v_start.x, v_start.y ) ) 1916a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1917a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Close; 1918a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1919a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1920a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1921a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1922a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* close the contour with a line segment */ 1923a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Line_To( RAS_VARS v_start.x, v_start.y ) ) 1924a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Fail; 1925a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1926a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Close: 1927a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 1928a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1929a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Invalid_Outline: 1930059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg ras.error = FT_THROW( Invalid ); 1931a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1932a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Fail: 1933a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1934a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 1935a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1936a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1937a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 1938a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1939a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 1940a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Convert_Glyph */ 1941a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1942a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 1943174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Convert a glyph into a series of segments and arcs and make a */ 1944a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* profiles list with them. */ 1945a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1946a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 1947a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* flipped :: If set, flip the direction of curve. */ 1948a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 1949a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 1950a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* SUCCESS on success, FAILURE if any error was encountered during */ 1951a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* rendering. */ 1952a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 195352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 1954a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg Convert_Glyph( RAS_ARGS Int flipped ) 1955a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1956a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg Int i; 1957a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg UInt start; 1958a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1959a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1960a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fProfile = NULL; 1961a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.joint = FALSE; 1962a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.fresh = FALSE; 1963a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1964a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.maxBuff = ras.sizeBuff - AlignProfileSize; 1965a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1966a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.numTurns = 0; 1967a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1968a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile = (PProfile)ras.top; 1969a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.cProfile->offset = ras.top; 1970a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.num_Profs = 0; 1971a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1972a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner start = 0; 1973a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1974a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner for ( i = 0; i < ras.outline.n_contours; i++ ) 1975a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 1976dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg PProfile lastProfile; 1977dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg Bool o; 197842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 197942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 19809ca7a157273201e4e40168e7b239e12bb813f9a7Werner Lemberg ras.state = Unknown_State; 1981a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.gProfile = NULL; 1982a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1983ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg if ( Decompose_Curve( RAS_VARS (UShort)start, 1984ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg (UShort)ras.outline.contours[i], 198542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg flipped ) ) 1986a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 1987a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1988ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg start = (UShort)ras.outline.contours[i] + 1; 1989a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 1990cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg /* we must now check whether the extreme arcs join or not */ 1991a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( FRAC( ras.lastY ) == 0 && 1992a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY >= ras.minY && 1993a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.lastY <= ras.maxY ) 199442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( ras.gProfile && 199542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ( ras.gProfile->flags & Flow_Up ) == 199642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg ( ras.cProfile->flags & Flow_Up ) ) 1997a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top--; 1998a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Note that ras.gProfile can be nil if the contour was too small */ 1999a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* to be drawn. */ 2000a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2001a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner lastProfile = ras.cProfile; 2002c242fe41ec634af32845cd17bcd1a0ee2653feb9Behdad Esfahbod if ( ras.top != ras.cProfile->offset && 2003c242fe41ec634af32845cd17bcd1a0ee2653feb9Behdad Esfahbod ( ras.cProfile->flags & Flow_Up ) ) 200442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg o = IS_TOP_OVERSHOOT( ras.lastY ); 200542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg else 200642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg o = IS_BOTTOM_OVERSHOOT( ras.lastY ); 200742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( End_Profile( RAS_VARS o ) ) 2008a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 2009a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2010a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* close the `next profile in contour' linked list */ 2011a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.gProfile ) 2012a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner lastProfile->next = ras.gProfile; 2013a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2014a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2015a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Finalize_Profile_Table( RAS_VAR ) ) 2016a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 2017a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 20188edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner return (Bool)( ras.top < ras.maxBuff ? SUCCESS : FAILURE ); 2019a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2020a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2021a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2022a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2023a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2024a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 2025a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** SCAN-LINE SWEEPS AND DRAWING **/ 2026a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /** **/ 2027a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2028a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2029a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2030a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2031a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2032a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2033a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Init_Linked */ 2034a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2035a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Initializes an empty linked list. */ 2036a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 203752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 203852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Init_Linked( TProfileList* l ) 2039a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2040a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *l = NULL; 2041a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2042a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2043a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2044a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2045a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2046a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* InsNew */ 2047a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2048a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Inserts a new profile in a linked list. */ 2049a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 205052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 205152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg InsNew( PProfileList list, 205252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile profile ) 2053a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2054a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile *old, current; 2055a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x; 2056a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2057a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2058a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 2059a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2060a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x = profile->X; 2061a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2062a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( current ) 2063a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2064a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x < current->X ) 2065a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2066a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = ¤t->link; 2067a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2068a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2069a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2070a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner profile->link = current; 2071a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *old = profile; 2072a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2073a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2074a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2075a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2076a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2077a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* DelOld */ 2078a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2079a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Removes an old profile from a linked list. */ 2080a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 208152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 208252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg DelOld( PProfileList list, 208352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile profile ) 2084a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2085a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile *old, current; 2086a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2087a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2088a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 2089a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2090a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2091a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( current ) 2092a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2093a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( current == profile ) 2094a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2095a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *old = current->link; 2096a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2097a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2098a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2099a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = ¤t->link; 2100a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2101a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2102a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2103a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* we should never get there, unless the profile was not part of */ 2104a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the list. */ 2105a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2106a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2107a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2108a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2109a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2110a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Sort */ 2111a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Sorts a trace list. In 95%, the list is already sorted. We need */ 2113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* an algorithm which is fast in this case. Bubble sort is enough */ 2114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* and simple. */ 2115a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 211652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 211752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Sort( PProfileList list ) 2118a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2119a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile *old, current, next; 2120a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2121a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* First, set the new X coordinate of each profile */ 2123ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current = *list; 2124ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner while ( current ) 2125ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner { 2126ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current->X = *current->offset; 212752aad9dfc6568b7eafefead5b49bad7e61f7938cWerner Lemberg current->offset += ( current->flags & Flow_Up ) ? 1 : -1; 2128ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current->height--; 2129ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner current = current->link; 2130ea5a981c7d000b11cf29dd7f1a9cf96defdff059David Turner } 2131a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2132a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Then sort them */ 2133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 2134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2136a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !current ) 2137a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2138a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner next = current->link; 2140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2141a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( next ) 2142a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2143a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( current->X <= next->X ) 2144a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2145a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = ¤t->link; 2146a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2147a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2148a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( !current ) 2149a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return; 2150a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2151a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2152a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2153a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *old = next; 2154a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current->link = next->link; 2155a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner next->link = current; 2156a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2157a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner old = list; 2158a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner current = *old; 2159a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2160a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2161a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner next = current->link; 2162a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2163a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2164a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2165a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2166a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2167a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2168a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Vertical Sweep Procedure Set */ 2169a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* These four routines are used during the vertical black/white sweep */ 2171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* phase by the generic Draw_Sweep() function. */ 2172a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2173a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2174a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 217552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 217652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Init( RAS_ARGS Short* min, 217752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Short* max ) 2178a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2179a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long pitch = ras.target.pitch; 2180a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2181a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( max ); 2182a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2183a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2184a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceIncr = (Short)-pitch; 2185a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs = -*min * pitch; 2186a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( pitch > 0 ) 2187ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg ras.traceOfs += (Long)( ras.target.rows - 1 ) * pitch; 2188a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2189a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2190a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 219152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 219252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Span( RAS_ARGS Short y, 219352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 219452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 219552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 219652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2197a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2198a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long e1, e2; 2199a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte* target; 2200a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2201f193637f63738eb451a6a23be70d763e78bc0c11Werner Lemberg Int dropOutControl = left->flags & 7; 2202f193637f63738eb451a6a23be70d763e78bc0c11Werner Lemberg 2203a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( y ); 2204a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( left ); 2205a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( right ); 2206a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2207a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2208d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg /* in high-precision mode, we need 12 digits after the comma to */ 2209d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg /* represent multiples of 1/(1<<12) = 1/4096 */ 2210d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( " y=%d x=[%.12f;%.12f], drop-out=%d", 2211d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg y, 2212d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg x1 / (double)ras.precision, 2213d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg x2 / (double)ras.precision, 2214d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg dropOutControl )); 2215d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2216a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Drop-out control */ 2217a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2218a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = TRUNC( CEILING( x1 ) ); 2219a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2220426f0e0453f172dc411783356834fb6f01ef6cd7Werner Lemberg if ( dropOutControl != 2 && 2221426f0e0453f172dc411783356834fb6f01ef6cd7Werner Lemberg x2 - x1 - ras.precision <= ras.precision_jitter ) 2222a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = e1; 2223a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2224a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = TRUNC( FLOOR( x2 ) ); 2225a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2226a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 >= 0 && e1 < ras.bWidth ) 2227a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2228a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg Int c1, c2; 2229dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg Byte f1, f2; 2230dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg 2231dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg 2232a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 < 0 ) 2233a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = 0; 2234a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e2 >= ras.bWidth ) 2235a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = ras.bWidth - 1; 2236a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2237d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( " -> x=[%d;%d]", e1, e2 )); 2238d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2239a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c1 = (Short)( e1 >> 3 ); 2240a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2 = (Short)( e2 >> 3 ); 2241a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22428edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner f1 = (Byte) ( 0xFF >> ( e1 & 7 ) ); 22438edbcabce1b3756fb1921f85901dcce944bdf1e7David Turner f2 = (Byte) ~( 0x7F >> ( e2 & 7 ) ); 2244a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2245a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner target = ras.bTarget + ras.traceOfs + c1; 2246a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2 -= c1; 2247a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2248a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( c2 > 0 ) 2249a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2250a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner target[0] |= f1; 2251a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 225294ffae5239631a18b8b5a39674c0afa8a992410eWerner Lemberg /* memset() is slower than the following code on many platforms. */ 2253a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* This is due to the fact that, in the vast majority of cases, */ 2254a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* the span length in bytes is relatively small. */ 2255a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2--; 2256a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( c2 > 0 ) 2257a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2258a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *(++target) = 0xFF; 2259a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c2--; 2260a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2261a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner target[1] |= f2; 2262a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2263a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2264a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *target |= ( f1 & f2 ); 2265a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2266d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2267d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( "\n" )); 2268a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2269a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2270a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 227152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 227252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Drop( RAS_ARGS Short y, 227352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 227452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 227552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 227652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2277a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 22785df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg Long e1, e2, pxl; 2279a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short c1, f1; 2280a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2281a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2282d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( " y=%d x=[%.12f;%.12f]", 2283d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg y, 2284d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg x1 / (double)ras.precision, 2285d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg x2 / (double)ras.precision )); 2286d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2287a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Drop-out control */ 2288a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 22895df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* e2 x2 x1 e1 */ 22905df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* */ 22915df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* ^ | */ 22925df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | | */ 22935df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* +-------------+---------------------+------------+ */ 22945df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | | */ 22955df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | v */ 22965df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* */ 22975df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* pixel contour contour pixel */ 22985df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* center center */ 22995df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 23005df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* drop-out mode scan conversion rules (as defined in OpenType) */ 23015df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* --------------------------------------------------------------- */ 23025df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 0 1, 2, 3 */ 23035df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 1 1, 2, 4 */ 23045df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 2 1, 2 */ 23055df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 3 same as mode 2 */ 23065df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 4 1, 2, 5 */ 23075df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 5 1, 2, 6 */ 23085df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* 6, 7 same as mode 2 */ 23095df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 23105df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = CEILING( x1 ); 23115df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e2 = FLOOR ( x2 ); 23125df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e1; 2313a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2314a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 > e2 ) 2315a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 231672271140434028186a49a5dc5925f0727559e46fWerner Lemberg Int dropOutControl = left->flags & 7; 231772271140434028186a49a5dc5925f0727559e46fWerner Lemberg 231872271140434028186a49a5dc5925f0727559e46fWerner Lemberg 2319d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( ", drop-out=%d", dropOutControl )); 2320d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2321a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 + ras.precision ) 2322a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 232372271140434028186a49a5dc5925f0727559e46fWerner Lemberg switch ( dropOutControl ) 2324a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 23255df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 0: /* simple drop-outs including stubs */ 23265df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 2327a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2328a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23295df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 4: /* smart drop-outs including stubs */ 23302f2b780e00235356ffcf1e8f98e19f3bb1910ed2Werner Lemberg pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2331a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2332a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23335df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 1: /* simple drop-outs excluding stubs */ 23345df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 5: /* smart drop-outs excluding stubs */ 2335a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23365df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* Drop-out Control Rules #4 and #6 */ 23375df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 233842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* The specification neither provides an exact definition */ 233942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* of a `stub' nor gives exact rules to exclude them. */ 2340a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 234142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* Here the constraints we use to recognize a stub. */ 2342a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2343a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* upper stub: */ 2344a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2345a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Left and P_Right are in the same contour */ 2346a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Right is the successor of P_Left in that contour */ 2347a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - y is the top of P_Left and P_Right */ 2348a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2349a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* lower stub: */ 2350a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2351a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Left and P_Right are in the same contour */ 2352a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - P_Left is the successor of P_Right in that contour */ 2353a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* - y is the bottom of P_Left */ 2354a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 235542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* We draw a stub if the following constraints are met. */ 235642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* */ 235742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* - for an upper or lower stub, there is top or bottom */ 235842206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* overshoot, respectively */ 235942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* - the covered interval is greater or equal to a half */ 236042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* pixel */ 236142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg 236242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* upper stub test */ 236342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( left->next == right && 236442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg left->height <= 0 && 236542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg !( left->flags & Overshoot_Top && 236642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x2 - x1 >= ras.precision_half ) ) 2367d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg goto Exit; 2368a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 236942206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg /* lower stub test */ 237042206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( right->next == left && 237142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg left->start == y && 237242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg !( left->flags & Overshoot_Bottom && 237342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x2 - x1 >= ras.precision_half ) ) 2374d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg goto Exit; 2375a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 237672271140434028186a49a5dc5925f0727559e46fWerner Lemberg if ( dropOutControl == 1 ) 23775df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 23785df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 23792f2b780e00235356ffcf1e8f98e19f3bb1910ed2Werner Lemberg pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 23805df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg break; 2381a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23825df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg default: /* modes 2, 3, 6, 7 */ 2383d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg goto Exit; /* no drop-out control */ 23845df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg } 2385a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 238629bc310563d4c8c728adfa78e18af9e4d3c89116Werner Lemberg /* undocumented but confirmed: If the drop-out would result in a */ 23870039d0120e08bdcbe88dac66f65003d3ed5251b4Werner Lemberg /* pixel outside of the bounding box, use the pixel inside of the */ 23880039d0120e08bdcbe88dac66f65003d3ed5251b4Werner Lemberg /* bounding box instead */ 238929bc310563d4c8c728adfa78e18af9e4d3c89116Werner Lemberg if ( pxl < 0 ) 239029bc310563d4c8c728adfa78e18af9e4d3c89116Werner Lemberg pxl = e1; 23910039d0120e08bdcbe88dac66f65003d3ed5251b4Werner Lemberg else if ( TRUNC( pxl ) >= ras.bWidth ) 23920039d0120e08bdcbe88dac66f65003d3ed5251b4Werner Lemberg pxl = e2; 239329bc310563d4c8c728adfa78e18af9e4d3c89116Werner Lemberg 23945df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* check that the other pixel isn't set */ 239537c72f66a56887ec25f4f541337b00e8ba69b9eeWerner Lemberg e1 = ( pxl == e1 ) ? e2 : e1; 2396a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23975df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( e1 ); 2398a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 23995df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg c1 = (Short)( e1 >> 3 ); 24005df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg f1 = (Short)( e1 & 7 ); 2401a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24025df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( e1 >= 0 && e1 < ras.bWidth && 24035df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.bTarget[ras.traceOfs + c1] & ( 0x80 >> f1 ) ) 2404d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg goto Exit; 2405a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2406a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2407d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg goto Exit; 2408a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2409a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 24105df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( pxl ); 2411a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2412a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 >= 0 && e1 < ras.bWidth ) 2413a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2414d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( " -> x=%d (drop-out)", e1 )); 2415d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2416a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner c1 = (Short)( e1 >> 3 ); 2417914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg f1 = (Short)( e1 & 7 ); 2418a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2419a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bTarget[ras.traceOfs + c1] |= (char)( 0x80 >> f1 ); 2420a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2421d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2422d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg Exit: 2423d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( "\n" )); 2424a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2425a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2426a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 242752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 242852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Vertical_Sweep_Step( RAS_ARG ) 2429a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2430a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.traceOfs += ras.traceIncr; 2431a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2432a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2433a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2434a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /***********************************************************************/ 2435a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2436a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Horizontal Sweep Procedure Set */ 2437a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2438a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* These four routines are used during the horizontal black/white */ 2439a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* sweep phase by the generic Draw_Sweep() function. */ 2440a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2441a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /***********************************************************************/ 2442a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 244352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 244452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Init( RAS_ARGS Short* min, 244552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Short* max ) 2446a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2447a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* nothing, really */ 2448f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg FT_UNUSED_RASTER; 2449a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( min ); 2450a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( max ); 2451a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2452a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2453a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 245452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 245552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Span( RAS_ARGS Short y, 245652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 245752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 245852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 245952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2460a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2461a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( left ); 2462a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( right ); 2463a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2464a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2465a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x2 - x1 < ras.precision ) 2466a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2467dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg Long e1, e2; 2468dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg 2469dc624ca4dcac1cbfb6870414e6aaedba43aeb9eeWerner Lemberg 2470d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( " x=%d y=[%.12f;%.12f]", 2471d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg y, 2472d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg x1 / (double)ras.precision, 2473d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg x2 / (double)ras.precision )); 2474d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2475a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = CEILING( x1 ); 2476a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e2 = FLOOR ( x2 ); 2477a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2478a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 ) 2479a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2480a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner e1 = TRUNC( e1 ); 2481a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2482b3500af717010137046ec4076d1e1c0641e33727Werner Lemberg if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) 2483a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2484d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg Byte f1; 2485d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg PByte bits; 2486a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte p; 2487a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2488a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2489d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( " -> y=%d (drop-out)", e1 )); 2490d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2491d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg bits = ras.bTarget + ( y >> 3 ); 2492d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2493d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg p = bits - e1 * ras.target.pitch; 2494d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2495a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.target.pitch > 0 ) 2496ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg p += (Long)( ras.target.rows - 1 ) * ras.target.pitch; 2497a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2498a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner p[0] |= f1; 2499a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2500a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2501d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2502d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( "\n" )); 2503a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2504a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2505a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2506a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 250752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 250852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Drop( RAS_ARGS Short y, 250952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x1, 251052005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_F26Dot6 x2, 251152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile left, 251252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg PProfile right ) 2513a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 25145df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg Long e1, e2, pxl; 2515a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PByte bits; 2516a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Byte f1; 2517a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2518a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2519d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( " x=%d y=[%.12f;%.12f]", 2520d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg y, 2521d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg x1 / (double)ras.precision, 2522d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg x2 / (double)ras.precision )); 2523d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2524a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* During the horizontal sweep, we only take care of drop-outs */ 2525a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25265df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* e1 + <-- pixel center */ 25275df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 25285df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* x1 ---+--> <-- contour */ 25295df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 25305df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 25315df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* x2 <--+--- <-- contour */ 25325df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 25335df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* | */ 25345df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* e2 + <-- pixel center */ 25355df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 25365df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = CEILING( x1 ); 25375df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e2 = FLOOR ( x2 ); 25385df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e1; 2539a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2540a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 > e2 ) 2541a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 254272271140434028186a49a5dc5925f0727559e46fWerner Lemberg Int dropOutControl = left->flags & 7; 254372271140434028186a49a5dc5925f0727559e46fWerner Lemberg 254472271140434028186a49a5dc5925f0727559e46fWerner Lemberg 2545d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( ", dropout=%d", dropOutControl )); 2546d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2547a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( e1 == e2 + ras.precision ) 2548a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 254972271140434028186a49a5dc5925f0727559e46fWerner Lemberg switch ( dropOutControl ) 2550a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 25515df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 0: /* simple drop-outs including stubs */ 25525df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 2553a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2554a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25555df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 4: /* smart drop-outs including stubs */ 25562f2b780e00235356ffcf1e8f98e19f3bb1910ed2Werner Lemberg pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 2557a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner break; 2558a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25595df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 1: /* simple drop-outs excluding stubs */ 25605df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg case 5: /* smart drop-outs excluding stubs */ 25615df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* see Vertical_Sweep_Drop for details */ 2562a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2563a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* rightmost stub test */ 256442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( left->next == right && 256542206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg left->height <= 0 && 256642206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg !( left->flags & Overshoot_Top && 256742206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x2 - x1 >= ras.precision_half ) ) 2568d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg goto Exit; 2569a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2570a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* leftmost stub test */ 257142206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg if ( right->next == left && 257242206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg left->start == y && 257342206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg !( left->flags & Overshoot_Bottom && 257442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg x2 - x1 >= ras.precision_half ) ) 2575d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg goto Exit; 2576a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 257772271140434028186a49a5dc5925f0727559e46fWerner Lemberg if ( dropOutControl == 1 ) 25785df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg pxl = e2; 25795df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 25802f2b780e00235356ffcf1e8f98e19f3bb1910ed2Werner Lemberg pxl = FLOOR( ( x1 + x2 - 1 ) / 2 + ras.precision_half ); 25815df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg break; 2582a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25835df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg default: /* modes 2, 3, 6, 7 */ 2584d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg goto Exit; /* no drop-out control */ 25855df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg } 2586a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25870039d0120e08bdcbe88dac66f65003d3ed5251b4Werner Lemberg /* undocumented but confirmed: If the drop-out would result in a */ 25880039d0120e08bdcbe88dac66f65003d3ed5251b4Werner Lemberg /* pixel outside of the bounding box, use the pixel inside of the */ 25890039d0120e08bdcbe88dac66f65003d3ed5251b4Werner Lemberg /* bounding box instead */ 259029bc310563d4c8c728adfa78e18af9e4d3c89116Werner Lemberg if ( pxl < 0 ) 259129bc310563d4c8c728adfa78e18af9e4d3c89116Werner Lemberg pxl = e1; 2592b3500af717010137046ec4076d1e1c0641e33727Werner Lemberg else if ( (ULong)( TRUNC( pxl ) ) >= ras.target.rows ) 25930039d0120e08bdcbe88dac66f65003d3ed5251b4Werner Lemberg pxl = e2; 259429bc310563d4c8c728adfa78e18af9e4d3c89116Werner Lemberg 25955df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg /* check that the other pixel isn't set */ 259637c72f66a56887ec25f4f541337b00e8ba69b9eeWerner Lemberg e1 = ( pxl == e1 ) ? e2 : e1; 2597a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 25985df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( e1 ); 2599a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 26005df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg bits = ras.bTarget + ( y >> 3 ); 26015df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2602a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 26035df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg bits -= e1 * ras.target.pitch; 26045df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.target.pitch > 0 ) 2605ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; 2606a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2607b3500af717010137046ec4076d1e1c0641e33727Werner Lemberg if ( e1 >= 0 && 2608b3500af717010137046ec4076d1e1c0641e33727Werner Lemberg (ULong)e1 < ras.target.rows && 2609b3500af717010137046ec4076d1e1c0641e33727Werner Lemberg *bits & f1 ) 2610d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg goto Exit; 2611a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2612a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2613d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg goto Exit; 2614a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2615a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 26165df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg e1 = TRUNC( pxl ); 2617a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2618b3500af717010137046ec4076d1e1c0641e33727Werner Lemberg if ( e1 >= 0 && (ULong)e1 < ras.target.rows ) 2619a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2620d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( " -> y=%d (drop-out)", e1 )); 2621d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2622d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg bits = ras.bTarget + ( y >> 3 ); 2623d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg f1 = (Byte)( 0x80 >> ( y & 7 ) ); 2624a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits -= e1 * ras.target.pitch; 2625d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2626a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.target.pitch > 0 ) 2627ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg bits += (Long)( ras.target.rows - 1 ) * ras.target.pitch; 2628a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2629a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bits[0] |= f1; 2630a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2631d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 2632d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg Exit: 2633d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( "\n" )); 2634a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2635a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2636a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 263752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 263852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Horizontal_Sweep_Step( RAS_ARG ) 2639a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2640a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Nothing, really */ 2641f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg FT_UNUSED_RASTER; 2642a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2643a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2644a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2645a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2646a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2647a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Generic Sweep Drawing routine */ 2648a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2649a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2650a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 265152005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static Bool 265252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Draw_Sweep( RAS_ARG ) 2653a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2654a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short y, y_change, y_height; 2655a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2656a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner PProfile P, Q, P_Left, P_Right; 2657a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2658a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short min_Y, max_Y, top, bottom, dropouts; 2659a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2660a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Long x1, x2, xs, e1, e2; 2661a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 26623c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg TProfileList waiting; 2663a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner TProfileList draw_left, draw_right; 2664a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2665a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2666174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* initialize empty linked lists */ 2667a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 26683c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg Init_Linked( &waiting ); 2669a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2670a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Init_Linked( &draw_left ); 2671a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Init_Linked( &draw_right ); 2672a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2673a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* first, compute min and max Y */ 2674a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2675a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = ras.fProfile; 2676a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner max_Y = (Short)TRUNC( ras.minY ); 2677a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner min_Y = (Short)TRUNC( ras.maxY ); 2678a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2679a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2680a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2681a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 2682a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2683a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner bottom = (Short)P->start; 2684914b289f1623b1030b66537d3b3ce4b652e4606cWerner Lemberg top = (Short)( P->start + P->height - 1 ); 2685a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 26865df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( min_Y > bottom ) 26875df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg min_Y = bottom; 26885df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( max_Y < top ) 26895df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg max_Y = top; 2690a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2691a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P->X = 0; 26923c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg InsNew( &waiting, P ); 2693a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2694a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 2695a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2696a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2697174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* check the Y-turns */ 2698a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.numTurns == 0 ) 2699a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2700059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg ras.error = FT_THROW( Invalid ); 2701a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 2702a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2703a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2704174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* now initialize the sweep */ 2705a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2706a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init( RAS_VARS &min_Y, &max_Y ); 2707a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2708174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* then compute the distance of each profile from min_Y */ 2709a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 27103c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg P = waiting; 2711a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2712a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2713a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2714ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg P->countL = P->start - min_Y; 2715a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = P->link; 2716a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2717a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2718174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* let's go */ 2719a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2720a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y = min_Y; 2721a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_height = 0; 2722a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2723cbdba615115b0f07984130d9420ee7299ab0a3ccWerner Lemberg if ( ras.numTurns > 0 && 2724a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.sizeBuff[-ras.numTurns] == min_Y ) 2725a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.numTurns--; 2726a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2727a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( ras.numTurns > 0 ) 2728a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2729174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* check waiting list for new activations */ 2730a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 27313c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg P = waiting; 2732a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2733a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2734a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2735a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 2736a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P->countL -= y_height; 2737a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P->countL == 0 ) 2738a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 27393c403e4c17fa68a8a7992fa347fda312e1bae2a0Werner Lemberg DelOld( &waiting, P ); 2740a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 274190c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg if ( P->flags & Flow_Up ) 2742a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner InsNew( &draw_left, P ); 274390c699af0cb6e40ba96f43e80433818c83d2560fWerner Lemberg else 2744a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner InsNew( &draw_right, P ); 2745a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2746a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2747a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 2748a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2749a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2750174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* sort the drawing lists */ 2751a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2752a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_left ); 2753a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_right ); 2754a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2755a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y_change = (Short)ras.sizeBuff[-ras.numTurns--]; 27568eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg y_height = (Short)( y_change - y ); 2757a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2758a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( y < y_change ) 2759a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2760174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* let's trace */ 2761a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2762a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner dropouts = 0; 2763a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2764a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = draw_left; 2765a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = draw_right; 2766a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2767a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P_Left ) 2768a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2769a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 = P_Left ->X; 2770a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x2 = P_Right->X; 2771a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2772a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( x1 > x2 ) 2773a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2774a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner xs = x1; 2775a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x1 = x2; 2776a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner x2 = xs; 2777a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2778a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 277971b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg e1 = FLOOR( x1 ); 278071b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg e2 = CEILING( x2 ); 2781a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 278271b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg if ( x2 - x1 <= ras.precision && 278371b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg e1 != x1 && e2 != x2 ) 278471b8f3f2ed06ce2a437b31e34c75e6aeab781640Werner Lemberg { 2785ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg if ( e1 > e2 || e2 == e1 + ras.precision ) 2786a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 278772271140434028186a49a5dc5925f0727559e46fWerner Lemberg Int dropOutControl = P_Left->flags & 7; 278872271140434028186a49a5dc5925f0727559e46fWerner Lemberg 278972271140434028186a49a5dc5925f0727559e46fWerner Lemberg 279072271140434028186a49a5dc5925f0727559e46fWerner Lemberg if ( dropOutControl != 2 ) 2791ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg { 2792174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* a drop-out was detected */ 2793a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2794ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg P_Left ->X = x1; 2795ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg P_Right->X = x2; 2796a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2797ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg /* mark profile for drop-out processing */ 2798ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg P_Left->countL = 1; 2799ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg dropouts++; 2800ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg } 2801a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2802a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Skip_To_Next; 2803a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2804a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2805a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2806a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span( RAS_VARS y, x1, x2, P_Left, P_Right ); 2807a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2808a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Skip_To_Next: 2809a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2810a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = P_Left->link; 2811a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = P_Right->link; 2812a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2813a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2814174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* handle drop-outs _after_ the span drawing -- */ 2815174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* drop-out processing has been moved out of the loop */ 2816174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* for performance tuning */ 2817a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( dropouts > 0 ) 2818a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Scan_DropOuts; 2819a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2820a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Next_Line: 2821a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2822a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step( RAS_VAR ); 2823a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2824a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y++; 2825a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2826a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( y < y_change ) 2827a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2828a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_left ); 2829a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Sort( &draw_right ); 2830a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2831a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2832a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2833174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* now finalize the profiles that need it */ 2834a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2835a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = draw_left; 2836a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2837a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2838a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 2839a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P->height == 0 ) 2840a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner DelOld( &draw_left, P ); 2841a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 2842a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2843a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2844a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = draw_right; 2845a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P ) 2846a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2847a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Q = P->link; 2848a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P->height == 0 ) 2849a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner DelOld( &draw_right, P ); 2850a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P = Q; 2851a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2852a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2853a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2854174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* for gray-scaling, flush the bitmap scanline cache */ 2855a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( y <= max_Y ) 2856a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2857a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step( RAS_VAR ); 2858a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner y++; 2859a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2860a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2861a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 2862a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2863a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Scan_DropOuts: 2864a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2865a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = draw_left; 2866a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = draw_right; 2867a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2868a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( P_Left ) 2869a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2870a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( P_Left->countL ) 2871a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2872a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left->countL = 0; 2873a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#if 0 2874a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner dropouts--; /* -- this is useful when debugging only */ 2875a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 2876a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop( RAS_VARS y, 2877a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left->X, 2878a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right->X, 2879a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left, 2880a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right ); 2881a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2882a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2883a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Left = P_Left->link; 2884a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner P_Right = P_Right->link; 2885a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2886a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2887a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner goto Next_Line; 2888a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2889a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2890a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2891a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2892a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2893a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 2894a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Render_Single_Pass */ 2895a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2896a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 2897174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Perform one sweep with sub-banding. */ 2898a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2899a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Input> */ 2900a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* flipped :: If set, flip the direction of the outline. */ 2901a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2902a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 2903a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Renderer error code. */ 2904a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 290552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 290652005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Render_Single_Pass( RAS_ARGS Bool flipped ) 2907a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2908a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Short i, j, k; 2909a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2910a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2911a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner while ( ras.band_top >= 0 ) 2912a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2913a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.maxY = (Long)ras.band_stack[ras.band_top].y_max * ras.precision; 2914a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.minY = (Long)ras.band_stack[ras.band_top].y_min * ras.precision; 2915a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2916a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.top = ras.buff; 2917a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2918a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_None; 2919a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2920a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Convert_Glyph( RAS_VARS flipped ) ) 2921a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2922a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.error != Raster_Err_Overflow ) 2923a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return FAILURE; 2924a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2925a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.error = Raster_Err_None; 2926a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2927a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* sub-banding */ 2928a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2929a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#ifdef DEBUG_RASTER 2930a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ClearBand( RAS_VARS TRUNC( ras.minY ), TRUNC( ras.maxY ) ); 2931a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner#endif 2932a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2933a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner i = ras.band_stack[ras.band_top].y_min; 2934a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner j = ras.band_stack[ras.band_top].y_max; 2935a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 29368eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg k = (Short)( ( i + j ) / 2 ); 2937a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2938a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.band_top >= 7 || k < i ) 2939a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2940a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 2941059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg ras.error = FT_THROW( Invalid ); 2942a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2943a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return ras.error; 2944a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2945a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2946a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[ras.band_top + 1].y_min = k; 2947a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[ras.band_top + 1].y_max = j; 2948a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 29498eb0353fec1494ab7d9fe9bb91a5954449ab30c1Werner Lemberg ras.band_stack[ras.band_top].y_max = (Short)( k - 1 ); 2950a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2951a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top++; 2952a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2953a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner else 2954a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2955a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ras.fProfile ) 2956a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( Draw_Sweep( RAS_VAR ) ) 2957a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return ras.error; 2958a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top--; 2959a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2960a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2961a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2962a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return SUCCESS; 2963a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 2964a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2965a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2966a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /*************************************************************************/ 2967a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2968a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Function> */ 2969a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Render_Glyph */ 2970a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2971a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Description> */ 2972174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg /* Render a glyph in a bitmap. Sub-banding if needed. */ 2973a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2974a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* <Return> */ 2975a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* FreeType error code. 0 means success. */ 2976a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* */ 2977851e815127d47e85a575e1be7ff8cc265d5d7e79Werner Lemberg static FT_Error 297852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg Render_Glyph( RAS_ARG ) 2979a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 2980a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Error error; 2981a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2982a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 2983a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner Set_High_Precision( RAS_VARS ras.outline.flags & 298442206ad86aac3c3c344fcd9730d80165514584c9Werner Lemberg FT_OUTLINE_HIGH_PRECISION ); 29855df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.scale_shift = ras.precision_shift; 29865df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 29875df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.outline.flags & FT_OUTLINE_IGNORE_DROPOUTS ) 29885df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 2; 29895df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 29905df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg { 29915df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( ras.outline.flags & FT_OUTLINE_SMART_DROPOUTS ) 29925df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 4; 29935df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg else 29945df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl = 0; 29955df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 29965df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg if ( !( ras.outline.flags & FT_OUTLINE_INCLUDE_STUBS ) ) 29975df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.dropOutControl += 1; 29985df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg } 29995df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg 3000ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg ras.second_pass = (Bool)( !( ras.outline.flags & 3001ca96fe01fa7687d43c062f5d48cf8fa919170be4Werner Lemberg FT_OUTLINE_SINGLE_PASS ) ); 3002a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3003a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Vertical Sweep */ 3004d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( "Vertical pass (ftraster)\n" )); 3005d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 3006a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init = Vertical_Sweep_Init; 3007a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span = Vertical_Sweep_Span; 3008a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop = Vertical_Sweep_Drop; 3009a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step = Vertical_Sweep_Step; 3010a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3011a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3012a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_min = 0; 3013a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg ras.band_stack[0].y_max = (Short)( ras.target.rows - 1 ); 3014a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3015a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg ras.bWidth = (UShort)ras.target.width; 3016a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.bTarget = (Byte*)ras.target.buffer; 3017a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3018a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ( error = Render_Single_Pass( RAS_VARS 0 ) ) != 0 ) 3019a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3020a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3021a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* Horizontal Sweep */ 3022ce8853af8158368eae51b14c89dc3b79f48ce8ceWerner Lemberg if ( ras.second_pass && ras.dropOutControl != 2 ) 3023a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3024d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg FT_TRACE7(( "Horizontal pass (ftraster)\n" )); 3025d1ade6d11a1e31253180a19a2e0c6c1af0a8563fWerner Lemberg 3026a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Init = Horizontal_Sweep_Init; 3027a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Span = Horizontal_Sweep_Span; 3028a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Drop = Horizontal_Sweep_Drop; 3029a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.Proc_Sweep_Step = Horizontal_Sweep_Step; 3030a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3031a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_top = 0; 3032a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ras.band_stack[0].y_min = 0; 3033a974e9acdf9c436a8520dd883179ae19d93a1c17Werner Lemberg ras.band_stack[0].y_max = (Short)( ras.target.width - 1 ); 3034a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3035a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( ( error = Render_Single_Pass( RAS_VARS 1 ) ) != 0 ) 3036a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3037a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3038a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3039f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg return Raster_Err_None; 3040a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3041a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3042a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 304352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 304495111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco ft_black_init( black_PRaster raster ) 3045a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3046eca1f2790578ce8e9907ef3373ab69b7816b3093Werner Lemberg FT_UNUSED( raster ); 3047a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3048a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3049a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3050a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /**** RASTER OBJECT CREATION: In standalone mode, we simply use *****/ 3051a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /**** a static object. *****/ 3052a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3053a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 30549d0b76d7f6e87b68ee739688be693f28094b23bfWerner Lemberg#ifdef STANDALONE_ 3055a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3056a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 305752005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 3058174b8de3283c921d8bddf48325fe42ba7330a930Werner Lemberg ft_black_new( void* memory, 305952005c304229e2bfc54c0d406944d125d4849920Werner Lemberg FT_Raster *araster ) 3060a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 306195111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco static black_TRaster the_raster; 306212cf031644ddd2531fa315e948aad24499adb251Werner Lemberg FT_UNUSED( memory ); 3063a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3064a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3065f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg *araster = (FT_Raster)&the_raster; 306645cad2e5e15c08b682e87b5636cccfc941b3fe7dWerner Lemberg FT_ZERO( &the_raster ); 3067a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ft_black_init( &the_raster ); 3068a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3069a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return 0; 3070a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3071a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3072a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 307352005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 307452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg ft_black_done( FT_Raster raster ) 3075a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3076a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* nothing */ 3077f9fccbee8b265a7576b358191e940299ebe60827Werner Lemberg FT_UNUSED( raster ); 3078a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3079a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3080a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 30819d0b76d7f6e87b68ee739688be693f28094b23bfWerner Lemberg#else /* !STANDALONE_ */ 3082a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3083a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 308452005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 308595111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco ft_black_new( FT_Memory memory, 308695111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco black_PRaster *araster ) 3087a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 308895111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco FT_Error error; 308995111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco black_PRaster raster = NULL; 3090a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3091a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3092a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *araster = 0; 3093e459d742e6236df43f542b8c29dfdcf05d69716cDavid Turner if ( !FT_NEW( raster ) ) 3094a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3095a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner raster->memory = memory; 3096a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner ft_black_init( raster ); 3097a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3098a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner *araster = raster; 3099a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3100a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3101a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return error; 3102a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3103a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3104a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 310552005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 310695111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco ft_black_done( black_PRaster raster ) 3107a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3108a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_Memory memory = (FT_Memory)raster->memory; 310995111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco 311095111433853850345e4c3103b3bdf28a525ebb92Vinnie Falco 3111e459d742e6236df43f542b8c29dfdcf05d69716cDavid Turner FT_FREE( raster ); 3112a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3113a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3114a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 31159d0b76d7f6e87b68ee739688be693f28094b23bfWerner Lemberg#endif /* !STANDALONE_ */ 3116a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3117a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 311852005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static void 3119e9181aba2c5594f5fedba649170c6e8efbabdea2Werner Lemberg ft_black_reset( FT_Raster raster, 3120e9181aba2c5594f5fedba649170c6e8efbabdea2Werner Lemberg PByte pool_base, 3121e9181aba2c5594f5fedba649170c6e8efbabdea2Werner Lemberg ULong pool_size ) 3122a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3123a773c3041e024975241d110989f617f032c4b7e3Behdad Esfahbod FT_UNUSED( raster ); 3124a773c3041e024975241d110989f617f032c4b7e3Behdad Esfahbod FT_UNUSED( pool_base ); 3125a773c3041e024975241d110989f617f032c4b7e3Behdad Esfahbod FT_UNUSED( pool_size ); 3126a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3127a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3128a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 31293e86711ebf6efdea405f8f35bc34baf737b744dfWerner Lemberg static int 3130e9181aba2c5594f5fedba649170c6e8efbabdea2Werner Lemberg ft_black_set_mode( FT_Raster raster, 3131e9181aba2c5594f5fedba649170c6e8efbabdea2Werner Lemberg ULong mode, 3132e9181aba2c5594f5fedba649170c6e8efbabdea2Werner Lemberg void* args ) 3133a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 3134a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( raster ); 3135a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner FT_UNUSED( mode ); 3136e9181aba2c5594f5fedba649170c6e8efbabdea2Werner Lemberg FT_UNUSED( args ); 3137a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 31383e86711ebf6efdea405f8f35bc34baf737b744dfWerner Lemberg return 0; 3139a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3140a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3141a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 314252005c304229e2bfc54c0d406944d125d4849920Werner Lemberg static int 3143e9181aba2c5594f5fedba649170c6e8efbabdea2Werner Lemberg ft_black_render( FT_Raster raster, 3144fa420250c59414e432243feffb70be68654b8c27Werner Lemberg const FT_Raster_Params* params ) 3145a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner { 31468ae1dceb94effa59a307c0b778b37483f808f3d4Werner Lemberg const FT_Outline* outline = (const FT_Outline*)params->source; 31478ae1dceb94effa59a307c0b778b37483f808f3d4Werner Lemberg const FT_Bitmap* target_map = params->target; 3148a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3149a773c3041e024975241d110989f617f032c4b7e3Behdad Esfahbod black_TWorker worker[1]; 3150a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 315172a0653142420a060296ed261406ea61342fae8bAlexei Podtelezhnikov (Алексей Подтележников) Long buffer[FT_MAX_BLACK_POOL]; 3152a773c3041e024975241d110989f617f032c4b7e3Behdad Esfahbod 3153a773c3041e024975241d110989f617f032c4b7e3Behdad Esfahbod 3154a773c3041e024975241d110989f617f032c4b7e3Behdad Esfahbod if ( !raster ) 3155059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg return FT_THROW( Not_Ini ); 3156a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 31571ddd1b768dc3821e275e97c9391e54a14a8dc136Werner Lemberg if ( !outline ) 3158059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg return FT_THROW( Invalid ); 31591ddd1b768dc3821e275e97c9391e54a14a8dc136Werner Lemberg 3160a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* return immediately if the outline is empty */ 3161a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner if ( outline->n_points == 0 || outline->n_contours <= 0 ) 3162a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner return Raster_Err_None; 3163a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 31641ddd1b768dc3821e275e97c9391e54a14a8dc136Werner Lemberg if ( !outline->contours || !outline->points ) 3165059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg return FT_THROW( Invalid ); 3166a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3167c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( outline->n_points != 3168c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg outline->contours[outline->n_contours - 1] + 1 ) 3169059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg return FT_THROW( Invalid ); 3170a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3171a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner /* this version of the raster does not support direct rendering, sorry */ 3172b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner if ( params->flags & FT_RASTER_FLAG_DIRECT ) 3173059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg return FT_THROW( Unsupported ); 3174a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3175264b5e46c0d166c11360eb6c29edf2c178bb87c7Behdad Esfahbod if ( params->flags & FT_RASTER_FLAG_AA ) 3176264b5e46c0d166c11360eb6c29edf2c178bb87c7Behdad Esfahbod return FT_THROW( Unsupported ); 3177264b5e46c0d166c11360eb6c29edf2c178bb87c7Behdad Esfahbod 3178c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( !target_map ) 3179059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg return FT_THROW( Invalid ); 3180c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg 3181c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg /* nothing to do */ 3182c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( !target_map->width || !target_map->rows ) 3183c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg return Raster_Err_None; 3184c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg 3185c938131856e288d7dd5d9e7c0437d0097b2ccc0cWerner Lemberg if ( !target_map->buffer ) 3186059bc335ce42220b222763379e89d0cbf2b949ebWerner Lemberg return FT_THROW( Invalid ); 31871eb9a43aa14e02b56d981bae334e6e24c63298f7David Turner 318831f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg /* reject too large outline coordinates */ 318931f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg { 319031f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg FT_Vector* vec = outline->points; 319131f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg FT_Vector* limit = vec + outline->n_points; 319231f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg 319331f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg 319431f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg for ( ; vec < limit; vec++ ) 319531f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg { 319631f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg if ( vec->x < -0x1000000L || vec->x > 0x1000000L || 319731f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg vec->y < -0x1000000L || vec->y > 0x1000000L ) 319831f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg return FT_THROW( Invalid ); 319931f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg } 320031f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg } 320131f2dc19462774dd4e5b55f80cafcee07077e744Werner Lemberg 32025df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.outline = *outline; 32035df5dbb722cf008b3f617448d8d28fde4d725556Werner Lemberg ras.target = *target_map; 3204a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3205a773c3041e024975241d110989f617f032c4b7e3Behdad Esfahbod worker->buff = buffer; 3206a773c3041e024975241d110989f617f032c4b7e3Behdad Esfahbod worker->sizeBuff = (&buffer)[1]; /* Points to right after buffer. */ 32078a2c7f8fb804f3b74ea062f1c367b78d12c5b3f2David Turner 32088dc863587440d0a1d2eec2a7973a8eda99d2767dBehdad Esfahbod return Render_Glyph( RAS_VAR ); 3209a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner } 3210a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3211a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 32124d1f7af17b4b0966d5ed7fab215fc855fe459345Werner Lemberg FT_DEFINE_RASTER_FUNCS( 32134d1f7af17b4b0966d5ed7fab215fc855fe459345Werner Lemberg ft_standard_raster, 32144d1f7af17b4b0966d5ed7fab215fc855fe459345Werner Lemberg 3215b08fe2dc7af972a61f4e6bcadd7bb522861faec5David Turner FT_GLYPH_FORMAT_OUTLINE, 32164d1f7af17b4b0966d5ed7fab215fc855fe459345Werner Lemberg 3217c95b7652d8db19530c91e80d23c288bbf27f1b72Werner Lemberg (FT_Raster_New_Func) ft_black_new, /* raster_new */ 3218c95b7652d8db19530c91e80d23c288bbf27f1b72Werner Lemberg (FT_Raster_Reset_Func) ft_black_reset, /* raster_reset */ 3219c95b7652d8db19530c91e80d23c288bbf27f1b72Werner Lemberg (FT_Raster_Set_Mode_Func)ft_black_set_mode, /* raster_set_mode */ 3220c95b7652d8db19530c91e80d23c288bbf27f1b72Werner Lemberg (FT_Raster_Render_Func) ft_black_render, /* raster_render */ 3221c95b7652d8db19530c91e80d23c288bbf27f1b72Werner Lemberg (FT_Raster_Done_Func) ft_black_done /* raster_done */ 3222c95b7652d8db19530c91e80d23c288bbf27f1b72Werner Lemberg ) 3223a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3224a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner 3225a4e2894e03de65c5e0cd14b11b6fa30b14ed6769David Turner/* END */ 3226