1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* ftgrays.c */ 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* A new `perfect' anti-aliasing renderer (body). */ 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 7ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann/* Copyright 2000-2015 by */ 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* David Turner, Robert Wilhelm, and Werner Lemberg. */ 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* This file is part of the FreeType project, and may only be used, */ 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* modified, and distributed under the terms of the FreeType project */ 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* license, LICENSE.TXT. By continuing to use, modify, or distribute */ 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* this file you indicate that you have read the license and */ 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* understand and accept it fully. */ 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* */ 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/***************************************************************************/ 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This file can be compiled without the rest of the FreeType engine, by */ 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* defining the _STANDALONE_ macro when compiling it. You also need to */ 22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* put the files `ftgrays.h' and `ftimage.h' into the current */ 23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compilation directory. Typically, you could do something like */ 24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - copy `src/smooth/ftgrays.c' (this file) to your current directory */ 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 27ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */ 28ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* same directory */ 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in */ 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cc -c -D_STANDALONE_ ftgrays.c */ 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The renderer can be initialized with a call to */ 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated */ 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* with a call to `ft_gray_raster.raster_render'. */ 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* See the comments and documentation in the file `ftimage.h' for more */ 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* details on how the raster works. */ 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This is a new anti-aliasing scan-converter for FreeType 2. The */ 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* algorithm used here is _very_ different from the one in the standard */ 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `ftraster' module. Actually, `ftgrays' computes the _exact_ */ 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* coverage of the outline on each pixel cell. */ 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* It is based on ideas that I initially found in Raph Levien's */ 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* excellent LibArt graphics library (see http://www.levien.com/libart */ 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for more information, though the web pages do not tell anything */ 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* about the renderer; you'll have to dive into the source code to */ 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* understand how it works). */ 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note, however, that this is a _very_ different implementation */ 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compared to Raph's. Coverage information is stored in a very */ 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* different way, and I don't use sorted vector paths. Also, it doesn't */ 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* use floating point values. */ 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This renderer has the following advantages: */ 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - It doesn't need an intermediate bitmap. Instead, one can supply a */ 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* callback function that will be called by the renderer to draw gray */ 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* spans on any target surface. You can thus do direct composition on */ 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* any kind of bitmap, provided that you give the renderer the right */ 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* callback. */ 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on */ 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* each pixel cell. */ 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - It performs a single pass on the outline (the `standard' FT2 */ 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* renderer makes two passes). */ 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - It can easily be modified to render to _any_ number of gray levels */ 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* cheaply. */ 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* - For small (< 20) pixel sizes, it is faster than the standard */ 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* renderer. */ 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The macro FT_COMPONENT is used in trace mode. It is an implicit */ 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */ 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* messages during execution. */ 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FT_COMPONENT 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_COMPONENT trace_smooth 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _STANDALONE_ 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 97ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* The size in bytes of the render pool used by the scan-line converter */ 98ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* to do all of its work. */ 99ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define FT_RENDER_POOL_SIZE 16384L 100ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 101ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Auxiliary macros for token concatenation. */ 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_ERR_XCAT( x, y ) x ## y 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_ERR_CAT( x, y ) FT_ERR_XCAT( x, y ) 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FT_BEGIN_STMNT do { 107e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FT_END_STMNT } while ( 0 ) 108e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 109ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define FT_MAX( a, b ) ( (a) > (b) ? (a) : (b) ) 110ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define FT_ABS( a ) ( (a) < 0 ? -(a) : (a) ) 111ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 112ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 113ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann /* 114ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * Approximate sqrt(x*x+y*y) using the `alpha max plus beta min' 115ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * algorithm. We use alpha = 1, beta = 3/8, giving us results with a 116ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann * largest error less than 7% compared to the exact value. 117ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann */ 118ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#define FT_HYPOT( x, y ) \ 119ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ( x = FT_ABS( x ), \ 120ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann y = FT_ABS( y ), \ 121ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann x > y ? x + ( 3 * y >> 3 ) \ 122ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann : y + ( 3 * x >> 3 ) ) 123ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* define this to dump debugging information */ 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* #define FT_DEBUG_LEVEL_TRACE */ 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <stdio.h> 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <stdarg.h> 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <stddef.h> 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <string.h> 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <setjmp.h> 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include <limits.h> 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_UINT_MAX UINT_MAX 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_INT_MAX INT_MAX 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ft_memset memset 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ft_setjmp setjmp 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ft_longjmp longjmp 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ft_jmp_buf jmp_buf 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovtypedef ptrdiff_t FT_PtrDist; 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ErrRaster_Invalid_Mode -2 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ErrRaster_Invalid_Outline -1 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ErrRaster_Invalid_Argument -3 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ErrRaster_Memory_Overflow -4 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_BEGIN_HEADER 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_END_HEADER 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftimage.h" 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftgrays.h" 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This macro is used to indicate that a function parameter is unused. */ 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Its purpose is simply to reduce compiler warnings. Note also that */ 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* simply defining it as `(void)x' doesn't avoid warnings with certain */ 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ANSI compilers (e.g. LCC). */ 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_UNUSED( x ) (x) = (x) 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we only use level 5 & 7 tracing messages; cf. ftdebug.h */ 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Message( const char* fmt, 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ... ) 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov va_list ap; 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov va_start( ap, fmt ); 181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vfprintf( stderr, fmt, ap ); 182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov va_end( ap ); 183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* empty function useful for setting a breakpoint to catch errors */ 187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int 188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Throw( int error, 189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int line, 190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const char* file ) 191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( error ); 193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( line ); 194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( file ); 195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* we don't handle tracing levels in stand-alone mode; */ 201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_TRACE5 202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_TRACE5( varformat ) FT_Message varformat 203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_TRACE7 205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_TRACE7( varformat ) FT_Message varformat 206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_ERROR 208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_ERROR( varformat ) FT_Message varformat 209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_THROW( e ) \ 212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ( FT_Throw( FT_ERR_CAT( ErrRaster, e ), \ 213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov __LINE__, \ 214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov __FILE__ ) | \ 215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_ERR_CAT( ErrRaster, e ) ) 216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !FT_DEBUG_LEVEL_TRACE */ 218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_TRACE5( x ) do { } while ( 0 ) /* nothing */ 220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_TRACE7( x ) do { } while ( 0 ) /* nothing */ 221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_ERROR( x ) do { } while ( 0 ) /* nothing */ 222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_THROW( e ) FT_ERR_CAT( ErrRaster_, e ) 223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !FT_DEBUG_LEVEL_TRACE */ 226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_OUTLINE_FUNCS( class_, \ 229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov move_to_, line_to_, \ 230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov conic_to_, cubic_to_, \ 231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov shift_, delta_ ) \ 232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static const FT_Outline_Funcs class_ = \ 233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { \ 234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov move_to_, \ 235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov line_to_, \ 236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov conic_to_, \ 237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cubic_to_, \ 238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov shift_, \ 239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta_ \ 240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_, \ 243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_new_, raster_reset_, \ 244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_set_mode_, raster_render_, \ 245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_done_ ) \ 246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Raster_Funcs class_ = \ 247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { \ 248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov glyph_format_, \ 249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_new_, \ 250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_reset_, \ 251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_set_mode_, \ 252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_render_, \ 253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster_done_ \ 254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov }; 255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !_STANDALONE_ */ 258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 260e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include <ft2build.h> 261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftgrays.h" 262e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_OBJECTS_H 263e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_INTERNAL_DEBUG_H 264e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#include FT_OUTLINE_H 265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftsmerrs.h" 267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ftspic.h" 269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Smooth_Err_Invalid_Mode Smooth_Err_Cannot_Render_Glyph 271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define Smooth_Err_Memory_Overflow Smooth_Err_Out_Of_Memory 272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ErrRaster_Memory_Overflow Smooth_Err_Out_Of_Memory 273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !_STANDALONE_ */ 276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_MEM_SET 279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_MEM_SET( d, s, c ) ft_memset( d, s, c ) 280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_MEM_ZERO 283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_MEM_ZERO( dest, count ) FT_MEM_SET( dest, 0, count ) 284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* as usual, for the speed hungry :-) */ 287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef RAS_ARG 289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef RAS_ARG_ 290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef RAS_VAR 291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef RAS_VAR_ 292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_STATIC_RASTER 294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_ARG gray_PWorker worker 296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_ARG_ gray_PWorker worker, 297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_VAR worker 299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_VAR_ worker, 300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* FT_STATIC_RASTER */ 302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_ARG /* empty */ 304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_ARG_ /* empty */ 305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_VAR /* empty */ 306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RAS_VAR_ /* empty */ 307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_STATIC_RASTER */ 309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* must be at least 6 bits! */ 312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define PIXEL_BITS 8 313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef FLOOR 315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef CEILING 316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef TRUNC 317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef SCALED 318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ONE_PIXEL ( 1L << PIXEL_BITS ) 320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define TRUNC( x ) ( (TCoord)( (x) >> PIXEL_BITS ) ) 321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SUBPIXELS( x ) ( (TPos)(x) << PIXEL_BITS ) 322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FLOOR( x ) ( (x) & -ONE_PIXEL ) 323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define CEILING( x ) ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL ) 324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ROUND( x ) ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL ) 325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if PIXEL_BITS >= 6 327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define UPSCALE( x ) ( (x) << ( PIXEL_BITS - 6 ) ) 328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define DOWNSCALE( x ) ( (x) >> ( PIXEL_BITS - 6 ) ) 329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define UPSCALE( x ) ( (x) >> ( 6 - PIXEL_BITS ) ) 331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define DOWNSCALE( x ) ( (x) << ( 6 - PIXEL_BITS ) ) 332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 335e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Compute `dividend / divisor' and return both its quotient and */ 336e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* remainder, cast to a specific type. This macro also ensures that */ 337e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* the remainder is always positive. */ 338e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \ 339e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_BEGIN_STMNT \ 340e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (quotient) = (type)( (dividend) / (divisor) ); \ 341e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (remainder) = (type)( (dividend) % (divisor) ); \ 342e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( (remainder) < 0 ) \ 343e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov { \ 344e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (quotient)--; \ 345e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (remainder) += (type)(divisor); \ 346e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } \ 347e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_END_STMNT 348e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 349e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#ifdef __arm__ 350e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* Work around a bug specific to GCC which make the compiler fail to */ 351e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* optimize a division and modulo operation on the same parameters */ 352e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* into a single call to `__aeabi_idivmod'. See */ 353e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* */ 354e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov /* http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 */ 355e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#undef FT_DIV_MOD 356e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \ 357e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_BEGIN_STMNT \ 358e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (quotient) = (type)( (dividend) / (divisor) ); \ 359e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (remainder) = (type)( (dividend) - (quotient) * (divisor) ); \ 360e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( (remainder) < 0 ) \ 361e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov { \ 362e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (quotient)--; \ 363e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (remainder) += (type)(divisor); \ 364e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } \ 365e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_END_STMNT 366e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#endif /* __arm__ */ 367e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 368e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* TYPE DEFINITIONS */ 372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* don't change the following types to FT_Int or FT_Pos, since we might */ 375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* need to define them to "float" or "double" when experimenting with */ 376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* new algorithms */ 377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef long TCoord; /* integer scanline/pixel coordinate */ 379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef long TPos; /* sub-pixel coordinate */ 380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* determine the type used to store cell areas. This normally takes at */ 382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* least PIXEL_BITS*2 + 1 bits. On 16-bit systems, we need to use */ 383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `long' instead of `int', otherwise bad things happen */ 384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if PIXEL_BITS <= 7 386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef int TArea; 388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* PIXEL_BITS >= 8 */ 390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* approximately determine the size of integers using an ANSI-C header */ 392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if FT_UINT_MAX == 0xFFFFU 393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef long TArea; 394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef int TArea; 396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* PIXEL_BITS >= 8 */ 399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* maximum number of gray spans in a call to the span callback */ 402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define FT_MAX_GRAY_SPANS 32 403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct TCell_* PCell; 406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct TCell_ 408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos x; /* same with gray_TWorker.ex */ 410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord cover; /* same with gray_TWorker.cover */ 411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TArea area; 412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PCell next; 413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } TCell; 415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if defined( _MSC_VER ) /* Visual C++ (and Intel C++) */ 418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* We disable the warning `structure was padded due to */ 419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* __declspec(align())' in order to compile cleanly with */ 420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the maximum level of warnings. */ 421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#pragma warning( push ) 422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#pragma warning( disable : 4324 ) 423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* _MSC_VER */ 424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct gray_TWorker_ 426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 427ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ft_jmp_buf jump_buffer; 428ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord ex, ey; 430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos min_ex, max_ex; 431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos min_ey, max_ey; 432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos count_ex, count_ey; 433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TArea area; 435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord cover; 436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int invalid; 437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PCell cells; 439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_PtrDist max_cells; 440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_PtrDist num_cells; 441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos x, y; 443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector bez_stack[32 * 3 + 1]; 445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int lev_stack[32]; 446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline outline; 448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap target; 449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BBox clip_box; 450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Span gray_spans[FT_MAX_GRAY_SPANS]; 452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int num_gray_spans; 453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Raster_Span_Func render_span; 455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* render_span_data; 456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int span_y; 457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int band_size; 459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int band_shoot; 460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* buffer; 462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov long buffer_size; 463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PCell* ycells; 465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos ycount; 466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } gray_TWorker, *gray_PWorker; 468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if defined( _MSC_VER ) 470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#pragma warning( pop ) 471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef FT_STATIC_RASTER 475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define ras (*worker) 476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else 477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static gray_TWorker ras; 478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct gray_TRaster_ 482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* memory; 484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } gray_TRaster, *gray_PRaster; 486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Initialize the cells table. */ 492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_init_cells( RAS_ARG_ void* buffer, 495ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann long byte_size ) 496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.buffer = buffer; 498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.buffer_size = byte_size; 499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.ycells = (PCell*) buffer; 501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cells = NULL; 502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.max_cells = 0; 503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.num_cells = 0; 504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.area = 0; 505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cover = 0; 506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.invalid = 1; 507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Compute the outline bounding box. */ 513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_compute_cbox( RAS_ARG ) 516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline* outline = &ras.outline; 518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* vec = outline->points; 519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* limit = vec + outline->n_points; 520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( outline->n_points <= 0 ) 523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.min_ex = ras.max_ex = 0; 525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.min_ey = ras.max_ey = 0; 526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.min_ex = ras.max_ex = vec->x; 530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.min_ey = ras.max_ey = vec->y; 531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec++; 533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; vec < limit; vec++ ) 535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos x = vec->x; 537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos y = vec->y; 538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x < ras.min_ex ) ras.min_ex = x; 541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x > ras.max_ex ) ras.max_ex = x; 542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y < ras.min_ey ) ras.min_ey = y; 543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y > ras.max_ey ) ras.max_ey = y; 544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* truncate the bounding box to integer pixels */ 547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.min_ex = ras.min_ex >> 6; 548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.min_ey = ras.min_ey >> 6; 549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.max_ex = ( ras.max_ex + 63 ) >> 6; 550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.max_ey = ( ras.max_ey + 63 ) >> 6; 551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Record the current cell in the table. */ 557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static PCell 559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_find_cell( RAS_ARG ) 560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PCell *pcell, cell; 562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos x = ras.ex; 563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x > ras.count_ex ) 566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = ras.count_ex; 567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pcell = &ras.ycells[ras.ey]; 569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell = *pcell; 572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cell == NULL || cell->x > x ) 573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cell->x == x ) 576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov pcell = &cell->next; 579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.num_cells >= ras.max_cells ) 582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ft_longjmp( ras.jump_buffer, 1 ); 583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell = ras.cells + ras.num_cells++; 585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell->x = x; 586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell->area = 0; 587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell->cover = 0; 588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell->next = *pcell; 590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *pcell = cell; 591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cell; 594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_record_cell( RAS_ARG ) 599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 600e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( ras.area | ras.cover ) 601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PCell cell = gray_find_cell( RAS_VAR ); 603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell->area += ras.area; 606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell->cover += ras.cover; 607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Set the current cell to a new position. */ 614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_set_cell( RAS_ARG_ TCoord ex, 617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord ey ) 618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Move the cell pointer to a new position. We set the `invalid' */ 620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* flag to indicate that the cell isn't part of those we're interested */ 621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* in during the render phase. This means that: */ 622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* . the new vertical position must be within min_ey..max_ey-1. */ 624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* . the new horizontal position must be strictly less than max_ex */ 625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Note that if a cell is to the left of the clipping region, it is */ 627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* actually set to the (min_ex-1) horizontal position. */ 628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* All cells that are on the left of the clipping region go to the */ 630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* min_ex - 1 horizontal position. */ 631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ey -= ras.min_ey; 632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ex > ras.max_ex ) 634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ex = ras.max_ex; 635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ex -= ras.min_ex; 637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ex < 0 ) 638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ex = -1; 639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* are we moving to a different cell ? */ 641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ex != ras.ex || ey != ras.ey ) 642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* record the current one if it is valid */ 644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !ras.invalid ) 645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_record_cell( RAS_VAR ); 646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.area = 0; 648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cover = 0; 649e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ras.ex = ex; 650e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov ras.ey = ey; 651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 653ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ras.invalid = ( (unsigned int)ey >= (unsigned int)ras.count_ey || 654ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ex >= ras.count_ex ); 655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Start a new contour at a given cell. */ 661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_start_cell( RAS_ARG_ TCoord ex, 664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord ey ) 665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ex > ras.max_ex ) 667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ex = (TCoord)( ras.max_ex ); 668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ex < ras.min_ex ) 670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ex = (TCoord)( ras.min_ex - 1 ); 671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.area = 0; 673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cover = 0; 674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.ex = ex - ras.min_ex; 675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.ey = ey - ras.min_ey; 676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.invalid = 0; 677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_set_cell( RAS_VAR_ ex, ey ); 679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Render a scanline as one or more cells. */ 685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_scanline( RAS_ARG_ TCoord ey, 688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos x1, 689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord y1, 690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos x2, 691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord y2 ) 692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord ex1, ex2, fx1, fx2, delta, mod; 694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov long p, first, dx; 695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int incr; 696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx = x2 - x1; 699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ex1 = TRUNC( x1 ); 701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ex2 = TRUNC( x2 ); 702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) ); 703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) ); 704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* trivial case. Happens often */ 706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y1 == y2 ) 707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_set_cell( RAS_VAR_ ex2, ey ); 709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* everything is located in a single cell. That is easy! */ 713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ex1 == ex2 ) 715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = y2 - y1; 717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.area += (TArea)(( fx1 + fx2 ) * delta); 718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cover += delta; 719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ok, we'll have to render a run of adjacent cells on the same */ 723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* scanline... */ 724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = ( ONE_PIXEL - fx1 ) * ( y2 - y1 ); 726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = ONE_PIXEL; 727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov incr = 1; 728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dx < 0 ) 730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = fx1 * ( y2 - y1 ); 732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = 0; 733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov incr = -1; 734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx = -dx; 735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 737e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_DIV_MOD( TCoord, p, dx, delta, mod ); 738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.area += (TArea)(( fx1 + first ) * delta); 740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cover += delta; 741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ex1 += incr; 743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_set_cell( RAS_VAR_ ex1, ey ); 744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y1 += delta; 745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ex1 != ex2 ) 747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord lift, rem; 749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 751e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov p = ONE_PIXEL * ( y2 - y1 + delta ); 752e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_DIV_MOD( TCoord, p, dx, lift, rem ); 753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod -= (int)dx; 755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 756ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann do 757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = lift; 759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod += rem; 760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mod >= 0 ) 761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod -= (TCoord)dx; 763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta++; 764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.area += (TArea)(ONE_PIXEL * delta); 767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cover += delta; 768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y1 += delta; 769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ex1 += incr; 770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_set_cell( RAS_VAR_ ex1, ey ); 771ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } while ( ex1 != ex2 ); 772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = y2 - y1; 775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.area += (TArea)(( fx2 + ONE_PIXEL - first ) * delta); 776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cover += delta; 777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Render a given line as a series of scanlines. */ 783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_line( RAS_ARG_ TPos to_x, 786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos to_y ) 787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord ey1, ey2, fy1, fy2, mod; 789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos dx, dy, x, x2; 790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov long p, first; 791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int delta, rem, lift, incr; 792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 794ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ey1 = TRUNC( ras.y ); 795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ey2 = TRUNC( to_y ); /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */ 796ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) ); 797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) ); 798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx = to_x - ras.x; 800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dy = to_y - ras.y; 801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* perform vertical clipping */ 803ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) || 804ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ( ey1 < ras.min_ey && ey2 < ras.min_ey ) ) 805ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann goto End; 806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* everything is on a single scanline */ 808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ey1 == ey2 ) 809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 ); 811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto End; 812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* vertical line - avoid calling gray_render_scanline */ 815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov incr = 1; 816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dx == 0 ) 818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord ex = TRUNC( ras.x ); 820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 ); 821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TArea area; 822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = ONE_PIXEL; 825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dy < 0 ) 826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = 0; 828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov incr = -1; 829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = (int)( first - fy1 ); 832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.area += (TArea)two_fx * delta; 833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cover += delta; 834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ey1 += incr; 835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_set_cell( RAS_VAR_ ex, ey1 ); 837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = (int)( first + first - ONE_PIXEL ); 839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov area = (TArea)two_fx * delta; 840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( ey1 != ey2 ) 841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.area += area; 843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cover += delta; 844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ey1 += incr; 845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_set_cell( RAS_VAR_ ex, ey1 ); 847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = (int)( fy2 - ONE_PIXEL + first ); 850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.area += (TArea)two_fx * delta; 851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cover += delta; 852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto End; 854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* ok, we have to render several scanlines */ 857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = ( ONE_PIXEL - fy1 ) * dx; 858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = ONE_PIXEL; 859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov incr = 1; 860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dy < 0 ) 862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = fy1 * dx; 864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = 0; 865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov incr = -1; 866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dy = -dy; 867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 869e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_DIV_MOD( int, p, dy, delta, mod ); 870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = ras.x + delta; 872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first ); 873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ey1 += incr; 875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); 876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ey1 != ey2 ) 878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = ONE_PIXEL * dx; 880e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_DIV_MOD( int, p, dy, lift, rem ); 881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod -= (int)dy; 882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 883ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann do 884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = lift; 886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod += rem; 887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( mod >= 0 ) 888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov mod -= (int)dy; 890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta++; 891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x2 = x + delta; 894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_scanline( RAS_VAR_ ey1, x, 895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TCoord)( ONE_PIXEL - first ), x2, 896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TCoord)first ); 897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = x2; 898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ey1 += incr; 900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 ); 901ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } while ( ey1 != ey2 ); 902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_scanline( RAS_VAR_ ey1, x, 905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (TCoord)( ONE_PIXEL - first ), to_x, 906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov fy2 ); 907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov End: 909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.x = to_x; 910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.y = to_y; 911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_split_conic( FT_Vector* base ) 916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos a, b; 918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[4].x = base[2].x; 921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov b = base[1].x; 922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a = base[3].x = ( base[2].x + b ) / 2; 923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov b = base[1].x = ( base[0].x + b ) / 2; 924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[2].x = ( a + b ) / 2; 925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[4].y = base[2].y; 927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov b = base[1].y; 928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov a = base[3].y = ( base[2].y + b ) / 2; 929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov b = base[1].y = ( base[0].y + b ) / 2; 930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[2].y = ( a + b ) / 2; 931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_conic( RAS_ARG_ const FT_Vector* control, 936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Vector* to ) 937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos dx, dy; 939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos min, max, y; 940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int top, level; 941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int* levels; 942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* arc; 943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov levels = ras.lev_stack; 946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc = ras.bez_stack; 948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[0].x = UPSCALE( to->x ); 949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[0].y = UPSCALE( to->y ); 950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[1].x = UPSCALE( control->x ); 951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[1].y = UPSCALE( control->y ); 952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[2].x = ras.x; 953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[2].y = ras.y; 954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top = 0; 955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x ); 957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y ); 958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dx < dy ) 959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx = dy; 960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dx < ONE_PIXEL / 4 ) 962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Draw; 963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* short-cut the arc that crosses the current band */ 965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = max = arc[0].y; 966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = arc[1].y; 968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y < min ) min = y; 969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y > max ) max = y; 970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = arc[2].y; 972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y < min ) min = y; 973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y > max ) max = y; 974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) 976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Draw; 977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov level = 0; 979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do 980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx >>= 2; 982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov level++; 983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while ( dx > ONE_PIXEL / 4 ); 984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov levels[0] = level; 986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov do 988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov level = levels[top]; 990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( level > 0 ) 991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_split_conic( arc ); 993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc += 2; 994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top++; 995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov levels[top] = levels[top - 1] = level - 1; 996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Draw: 1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); 1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top--; 1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc -= 2; 1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } while ( top >= 0 ); 1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_split_cubic( FT_Vector* base ) 1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos a, b, c, d; 1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[6].x = base[3].x; 1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c = base[1].x; 1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov d = base[2].x; 1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[1].x = a = ( base[0].x + c ) / 2; 1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[5].x = b = ( base[3].x + d ) / 2; 1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c = ( c + d ) / 2; 1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[2].x = a = ( a + c ) / 2; 1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[4].x = b = ( b + c ) / 2; 1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[3].x = ( a + b ) / 2; 1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[6].y = base[3].y; 1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c = base[1].y; 1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov d = base[2].y; 1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[1].y = a = ( base[0].y + c ) / 2; 1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[5].y = b = ( base[3].y + d ) / 2; 1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov c = ( c + d ) / 2; 1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[2].y = a = ( a + c ) / 2; 1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[4].y = b = ( b + c ) / 2; 1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov base[3].y = ( a + b ) / 2; 1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_cubic( RAS_ARG_ const FT_Vector* control1, 1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Vector* control2, 1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Vector* to ) 1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* arc; 1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos min, max, y; 1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc = ras.bez_stack; 1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[0].x = UPSCALE( to->x ); 1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[0].y = UPSCALE( to->y ); 1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[1].x = UPSCALE( control2->x ); 1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[1].y = UPSCALE( control2->y ); 1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[2].x = UPSCALE( control1->x ); 1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[2].y = UPSCALE( control1->y ); 1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[3].x = ras.x; 1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc[3].y = ras.y; 1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Short-cut the arc that crosses the current band. */ 1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = max = arc[0].y; 1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = arc[1].y; 1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y < min ) 1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = y; 1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y > max ) 1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = y; 1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = arc[2].y; 1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y < min ) 1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = y; 1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y > max ) 1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = y; 1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = arc[3].y; 1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y < min ) 1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = y; 1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y > max ) 1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = y; 1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey ) 1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Draw; 1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for (;;) 1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Decide whether to split or draw. See `Rapid Termination */ 1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */ 1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* F. Hain, at */ 1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */ 1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos dx, dy, dx_, dy_; 1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos dx1, dy1, dx2, dy2; 1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos L, s, s_limit; 1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* dx and dy are x and y components of the P0-P3 chord vector. */ 1093e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov dx = dx_ = arc[3].x - arc[0].x; 1094e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov dy = dy_ = arc[3].y - arc[0].y; 1095e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 1096e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov L = FT_HYPOT( dx_, dy_ ); 1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Avoid possible arithmetic overflow below by splitting. */ 1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( L > 32767 ) 1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Split; 1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */ 1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov s_limit = L * (TPos)( ONE_PIXEL / 6 ); 1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* s is L * the perpendicular distance from P1 to the line P0-P3. */ 1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx1 = arc[1].x - arc[0].x; 1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dy1 = arc[1].y - arc[0].y; 1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov s = FT_ABS( dy * dx1 - dx * dy1 ); 1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( s > s_limit ) 1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Split; 1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* s is L * the perpendicular distance from P2 to the line P0-P3. */ 1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx2 = arc[2].x - arc[0].x; 1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dy2 = arc[2].y - arc[0].y; 1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov s = FT_ABS( dy * dx2 - dx * dy2 ); 1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( s > s_limit ) 1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Split; 1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Split super curvy segments where the off points are so far 1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov from the chord that the angles P0-P1-P3 or P0-P2-P3 become 1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov acute as detected by appropriate dot products. */ 1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 || 1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 ) 1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Split; 1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* No reason to split. */ 1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Draw; 1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Split: 1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_split_cubic( arc ); 1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc += 3; 1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Draw: 1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_line( RAS_VAR_ arc[0].x, arc[0].y ); 1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( arc == ras.bez_stack ) 1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov arc -= 3; 1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_move_to( const FT_Vector* to, 1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_PWorker worker ) 1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos x, y; 1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* record current cell, if any */ 1156e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !ras.invalid ) 1157e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov gray_record_cell( RAS_VAR ); 1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start to a new position */ 1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = UPSCALE( to->x ); 1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = UPSCALE( to->y ); 1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) ); 1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov worker->x = x; 1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov worker->y = y; 1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_line_to( const FT_Vector* to, 1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_PWorker worker ) 1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) ); 1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_conic_to( const FT_Vector* control, 1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Vector* to, 1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_PWorker worker ) 1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_conic( RAS_VAR_ control, to ); 1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_cubic_to( const FT_Vector* control1, 1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Vector* control2, 1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Vector* to, 1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_PWorker worker ) 1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_cubic( RAS_VAR_ control1, control2, to ); 1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_render_span( int y, 1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int count, 1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Span* spans, 1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_PWorker worker ) 1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned char* p; 1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Bitmap* map = &worker->target; 1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first of all, compute the scanline offset */ 1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov p = (unsigned char*)map->buffer - y * map->pitch; 1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( map->pitch >= 0 ) 1214ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann p += ( map->rows - 1 ) * (unsigned int)map->pitch; 1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; count > 0; count--, spans++ ) 1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned char coverage = spans->coverage; 1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( coverage ) 1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* For small-spans it is faster to do it by ourselves than 1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * calling `memset'. This is mainly due to the cost of the 1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov * function call. 1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov */ 1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( spans->len >= 8 ) 1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len ); 1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned char* q = p + spans->x; 1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( spans->len ) 1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 7: *q++ = (unsigned char)coverage; 1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 6: *q++ = (unsigned char)coverage; 1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 5: *q++ = (unsigned char)coverage; 1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 4: *q++ = (unsigned char)coverage; 1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 3: *q++ = (unsigned char)coverage; 1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 2: *q++ = (unsigned char)coverage; 1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case 1: *q = (unsigned char)coverage; 1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: 1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ; 1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_hline( RAS_ARG_ TCoord x, 1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord y, 1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos area, 1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord acount ) 1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int coverage; 1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compute the coverage line's coverage, depending on the */ 1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* outline fill rule */ 1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */ 1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) ); 1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* use range 0..256 */ 1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( coverage < 0 ) 1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov coverage = -coverage; 1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL ) 1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov coverage &= 511; 1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( coverage > 256 ) 1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov coverage = 512 - coverage; 1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( coverage == 256 ) 1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov coverage = 255; 1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* normal non-zero winding rule */ 1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( coverage >= 256 ) 1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov coverage = 255; 1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y += (TCoord)ras.min_ey; 1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x += (TCoord)ras.min_ex; 1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */ 1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( x >= 32767 ) 1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = 32767; 1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FT_Span.y is an integer, so limit our coordinates appropriately */ 1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( y >= FT_INT_MAX ) 1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov y = FT_INT_MAX; 1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( coverage ) 1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Span* span; 1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int count; 1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* see whether we can add this span to the current list */ 1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov count = ras.num_gray_spans; 1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span = ras.gray_spans + count - 1; 1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( count > 0 && 1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.span_y == y && 1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (int)span->x + span->len == (int)x && 1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span->coverage == coverage ) 1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span->len = (unsigned short)( span->len + acount ); 1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS ) 1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.render_span && count > 0 ) 1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.render_span( ras.span_y, count, ras.gray_spans, 1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.render_span_data ); 1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( count > 0 ) 1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int n; 1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE7(( "y = %3d ", ras.span_y )); 1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span = ras.gray_spans; 1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < count; n++, span++ ) 1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE7(( "[%d..%d]:%02x ", 1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span->x, span->x + span->len - 1, span->coverage )); 1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE7(( "\n" )); 1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_DEBUG_LEVEL_TRACE */ 1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.num_gray_spans = 0; 1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.span_y = (int)y; 1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span = ras.gray_spans; 1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span++; 1346e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* add a gray span to the current list */ 1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span->x = (short)x; 1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span->len = (unsigned short)acount; 1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span->coverage = (unsigned char)coverage; 1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.num_gray_spans++; 1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* to be called while in the debugger -- */ 1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this function causes a compiler warning since it is unused otherwise */ 1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_dump_cells( RAS_ARG ) 1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int yindex; 1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( yindex = 0; yindex < ras.ycount; yindex++ ) 1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PCell cell; 1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( "%3d:", yindex ); 1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next ) 1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area ); 1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov printf( "\n" ); 1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_DEBUG_LEVEL_TRACE */ 1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_sweep( RAS_ARG_ const FT_Bitmap* target ) 1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int yindex; 1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( target ); 1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.num_cells == 0 ) 1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return; 1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.num_gray_spans = 0; 1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE7(( "gray_sweep: start\n" )); 1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( yindex = 0; yindex < ras.ycount; yindex++ ) 1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PCell cell = ras.ycells[yindex]; 1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord cover = 0; 1402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TCoord x = 0; 1403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( ; cell != NULL; cell = cell->next ) 1406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos area; 1408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cell->x > x && cover != 0 ) 1411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), 1412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell->x - x ); 1413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cover += cell->cover; 1415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov area = cover * ( ONE_PIXEL * 2 ) - cell->area; 1416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( area != 0 && cell->x >= 0 ) 1418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_hline( RAS_VAR_ cell->x, yindex, area, 1 ); 1419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov x = cell->x + 1; 1421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cover != 0 ) 1424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ), 1425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.count_ex - x ); 1426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.render_span && ras.num_gray_spans > 0 ) 1429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.render_span( ras.span_y, ras.num_gray_spans, 1430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.gray_spans, ras.render_span_data ); 1431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 1433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.num_gray_spans > 0 ) 1435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Span* span; 1437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int n; 1438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE7(( "y = %3d ", ras.span_y )); 1441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span = ras.gray_spans; 1442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < ras.num_gray_spans; n++, span++ ) 1443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE7(( "[%d..%d]:%02x ", 1444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov span->x, span->x + span->len - 1, span->coverage )); 1445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE7(( "\n" )); 1446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE7(( "gray_sweep: end\n" )); 1449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* FT_DEBUG_LEVEL_TRACE */ 1451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _STANDALONE_ 1456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* The following function should only compile in stand-alone mode, */ 1460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* i.e., when building this component without the rest of FreeType. */ 1461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /*************************************************************************/ 1465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Function> */ 1467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* FT_Outline_Decompose */ 1468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Description> */ 1470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Walk over an outline's structure to decompose it into individual */ 1471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* segments and Bézier arcs. This function is also able to emit */ 1472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* `move to' and `close to' operations to indicate the start and end */ 1473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* of new contours in the outline. */ 1474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Input> */ 1476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* outline :: A pointer to the source target. */ 1477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* func_interface :: A table of `emitters', i.e., function pointers */ 1479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* called during decomposition to indicate path */ 1480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* operations. */ 1481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <InOut> */ 1483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* user :: A typeless pointer which is passed to each */ 1484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* emitter during the decomposition. It can be */ 1485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* used to store the state during the */ 1486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* decomposition. */ 1487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* <Return> */ 1489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Error code. 0 means success. */ 1490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* */ 1491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 1492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline_Decompose( const FT_Outline* outline, 1493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Outline_Funcs* func_interface, 1494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov void* user ) 1495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#undef SCALED 1497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define SCALED( x ) ( ( (x) << shift ) - delta ) 1498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector v_last; 1500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector v_control; 1501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector v_start; 1502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* point; 1504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector* limit; 1505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* tags; 1506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int error; 1508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int n; /* index of contour in outline */ 1510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int first; /* index of first point in contour */ 1511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char tag; /* current point's state */ 1512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int shift; 1514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos delta; 1515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1517e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !outline ) 1518e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return FT_THROW( Invalid_Outline ); 1519e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 1520e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !func_interface ) 1521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 1522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov shift = func_interface->shift; 1524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov delta = func_interface->delta; 1525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = 0; 1526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < outline->n_contours; n++ ) 1528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int last; /* index of last point in contour */ 1530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n )); 1533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov last = outline->contours[n]; 1535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( last < 0 ) 1536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Invalid_Outline; 1537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit = outline->points + last; 1538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start = outline->points[first]; 1540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.x = SCALED( v_start.x ); 1541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.y = SCALED( v_start.y ); 1542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_last = outline->points[last]; 1544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_last.x = SCALED( v_last.x ); 1545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_last.y = SCALED( v_last.y ); 1546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control = v_start; 1548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point = outline->points + first; 1550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tags = outline->tags + first; 1551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tag = FT_CURVE_TAG( tags[0] ); 1552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* A contour cannot start with a cubic control point! */ 1554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag == FT_CURVE_TAG_CUBIC ) 1555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Invalid_Outline; 1556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* check first point to determine origin */ 1558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag == FT_CURVE_TAG_CONIC ) 1559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* first point is conic control. Yes, this happens. */ 1561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON ) 1562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start at last point if it is on the curve */ 1564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start = v_last; 1565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov limit--; 1566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if both first and last points are conic, */ 1570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* start at their middle and record its position */ 1571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* for closure */ 1572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.x = ( v_start.x + v_last.x ) / 2; 1573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.y = ( v_start.y + v_last.y ) / 2; 1574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_last = v_start; 1576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point--; 1578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tags--; 1579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " move to (%.2f, %.2f)\n", 1582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.x / 64.0, v_start.y / 64.0 )); 1583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = func_interface->move_to( &v_start, user ); 1584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while ( point < limit ) 1588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point++; 1590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tags++; 1591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tag = FT_CURVE_TAG( tags[0] ); 1593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch ( tag ) 1594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case FT_CURVE_TAG_ON: /* emit a single line_to */ 1596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector vec; 1598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec.x = SCALED( point->x ); 1601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec.y = SCALED( point->y ); 1602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " line to (%.2f, %.2f)\n", 1604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec.x / 64.0, vec.y / 64.0 )); 1605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = func_interface->line_to( &vec, user ); 1606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case FT_CURVE_TAG_CONIC: /* consume conic arcs */ 1612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control.x = SCALED( point->x ); 1613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control.y = SCALED( point->y ); 1614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Do_Conic: 1616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( point < limit ) 1617ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector vec; 1619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector v_middle; 1620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point++; 1623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tags++; 1624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tag = FT_CURVE_TAG( tags[0] ); 1625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec.x = SCALED( point->x ); 1627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec.y = SCALED( point->y ); 1628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag == FT_CURVE_TAG_ON ) 1630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " conic to (%.2f, %.2f)" 1632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " with control (%.2f, %.2f)\n", 1633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec.x / 64.0, vec.y / 64.0, 1634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control.x / 64.0, v_control.y / 64.0 )); 1635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = func_interface->conic_to( &v_control, &vec, user ); 1636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( tag != FT_CURVE_TAG_CONIC ) 1642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Invalid_Outline; 1643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_middle.x = ( v_control.x + vec.x ) / 2; 1645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_middle.y = ( v_control.y + vec.y ) / 2; 1646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " conic to (%.2f, %.2f)" 1648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " with control (%.2f, %.2f)\n", 1649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_middle.x / 64.0, v_middle.y / 64.0, 1650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control.x / 64.0, v_control.y / 64.0 )); 1651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = func_interface->conic_to( &v_control, &v_middle, user ); 1652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control = vec; 1656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Do_Conic; 1657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " conic to (%.2f, %.2f)" 1660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " with control (%.2f, %.2f)\n", 1661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.x / 64.0, v_start.y / 64.0, 1662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_control.x / 64.0, v_control.y / 64.0 )); 1663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = func_interface->conic_to( &v_control, &v_start, user ); 1664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Close; 1665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov default: /* FT_CURVE_TAG_CUBIC */ 1667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector vec1, vec2; 1669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( point + 1 > limit || 1672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC ) 1673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Invalid_Outline; 1674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov point += 2; 1676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov tags += 2; 1677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec1.x = SCALED( point[-2].x ); 1679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec1.y = SCALED( point[-2].y ); 1680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec2.x = SCALED( point[-1].x ); 1682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec2.y = SCALED( point[-1].y ); 1683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( point <= limit ) 1685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Vector vec; 1687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec.x = SCALED( point->x ); 1690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec.y = SCALED( point->y ); 1691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " cubic to (%.2f, %.2f)" 1693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", 1694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec.x / 64.0, vec.y / 64.0, 1695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec1.x / 64.0, vec1.y / 64.0, 1696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec2.x / 64.0, vec2.y / 64.0 )); 1697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = func_interface->cubic_to( &vec1, &vec2, &vec, user ); 1698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " cubic to (%.2f, %.2f)" 1704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov " with controls (%.2f, %.2f) and (%.2f, %.2f)\n", 1705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.x / 64.0, v_start.y / 64.0, 1706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec1.x / 64.0, vec1.y / 64.0, 1707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov vec2.x / 64.0, vec2.y / 64.0 )); 1708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = func_interface->cubic_to( &vec1, &vec2, &v_start, user ); 1709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Close; 1710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* close the contour with a line segment */ 1715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( " line to (%.2f, %.2f)\n", 1716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov v_start.x / 64.0, v_start.y / 64.0 )); 1717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = func_interface->line_to( &v_start, user ); 1718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Close: 1720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( error ) 1721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto Exit; 1722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov first = last + 1; 1724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( "FT_Outline_Decompose: Done\n", n )); 1727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Exit: 1730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error )); 1731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Invalid_Outline: 1734ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Outline ); 1735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* _STANDALONE_ */ 1738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov typedef struct gray_TBand_ 1741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos min, max; 1743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } gray_TBand; 1745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1746ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1747ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_DEFINE_OUTLINE_FUNCS( 1748ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann func_interface, 1749ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1750ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (FT_Outline_MoveTo_Func) gray_move_to, 1751ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (FT_Outline_LineTo_Func) gray_line_to, 1752ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (FT_Outline_ConicTo_Func)gray_conic_to, 1753ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (FT_Outline_CubicTo_Func)gray_cubic_to, 1754ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0, 1755ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 0 ) 1756ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 1759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_convert_glyph_inner( RAS_ARG ) 1760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov volatile int error = 0; 1763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_CONFIG_OPTION_PIC 1765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Outline_Funcs func_interface; 1766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov Init_Class_func_interface(&func_interface); 1767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1768e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 1769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ft_setjmp( ras.jump_buffer ) == 0 ) 1770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras ); 1772e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov if ( !ras.invalid ) 1773e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov gray_record_cell( RAS_VAR ); 1774e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 1775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = FT_THROW( Memory_Overflow ); 1777e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 1778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 1779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 1783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_convert_glyph( RAS_ARG ) 1784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_TBand bands[40]; 1786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_TBand* volatile band; 1787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int volatile n, num_bands; 1788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos volatile min, max, max_y; 1789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_BBox* clip; 1790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* Set up state in the raster object */ 1793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_compute_cbox( RAS_VAR ); 1794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* clip to target bitmap, exit if nothing to do */ 1796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov clip = &ras.clip_box; 1797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax || 1799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax ) 1800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin; 1803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin; 1804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax; 1806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax; 1807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.count_ex = ras.max_ex - ras.min_ex; 1809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.count_ey = ras.max_ey - ras.min_ey; 1810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* set up vertical bands */ 1812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size ); 1813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( num_bands == 0 ) 1814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_bands = 1; 1815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( num_bands >= 39 ) 1816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov num_bands = 39; 1817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_shoot = 0; 1819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov min = ras.min_ey; 1821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max_y = ras.max_ey; 1822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( n = 0; n < num_bands; n++, min = max ) 1824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = min + ras.band_size; 1826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( n == num_bands - 1 || max > max_y ) 1827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov max = max_y; 1828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bands[0].min = min; 1830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bands[0].max = max; 1831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov band = bands; 1832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1833ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann do 1834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov TPos bottom, top, middle; 1836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int error; 1837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov PCell cells_max; 1840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov int yindex; 1841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov long cell_start, cell_end, cell_mod; 1842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.ycells = (PCell*)ras.buffer; 1845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.ycount = band->max - band->min; 1846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1847ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann cell_start = (long)sizeof ( PCell ) * ras.ycount; 1848ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann cell_mod = cell_start % (long)sizeof ( TCell ); 1849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( cell_mod > 0 ) 1850ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann cell_start += (long)sizeof ( TCell ) - cell_mod; 1851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cell_end = ras.buffer_size; 1853ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann cell_end -= cell_end % (long)sizeof ( TCell ); 1854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cells_max = (PCell)( (char*)ras.buffer + cell_end ); 1856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.cells = (PCell)( (char*)ras.buffer + cell_start ); 1857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.cells >= cells_max ) 1858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto ReduceBands; 1859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.max_cells = cells_max - ras.cells; 1861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.max_cells < 2 ) 1862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov goto ReduceBands; 1863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov for ( yindex = 0; yindex < ras.ycount; yindex++ ) 1865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.ycells[yindex] = NULL; 1866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.num_cells = 0; 1869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.invalid = 1; 1870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.min_ey = band->min; 1871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.max_ey = band->max; 1872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.count_ey = band->max - band->min; 1873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov error = gray_convert_glyph_inner( RAS_VAR ); 1875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !error ) 1877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_sweep( RAS_VAR_ &ras.target ); 1879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov band--; 1880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov continue; 1881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( error != ErrRaster_Memory_Overflow ) 1883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 1; 1884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ReduceBands: 1886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* render pool overflow; we will reduce the render band by half */ 1887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov bottom = band->min; 1888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov top = band->max; 1889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov middle = bottom + ( ( top - bottom ) >> 1 ); 1890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* This is too complex for a single scanline; there must */ 1892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* be some problems. */ 1893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( middle == bottom ) 1894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef FT_DEBUG_LEVEL_TRACE 1896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" )); 1897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif 1898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 1; 1899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( bottom-top >= ras.band_size ) 1902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_shoot++; 1903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov band[1].min = bottom; 1905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov band[1].max = middle; 1906ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov band[0].min = middle; 1907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov band[0].max = top; 1908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov band++; 1909ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann } while ( band >= bands ); 1910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( ras.band_shoot > 8 && ras.band_size > 16 ) 1913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.band_size = ras.band_size / 2; 1914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 1920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_raster_render( gray_PRaster raster, 1921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov const FT_Raster_Params* params ) 1922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1923ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const FT_Outline* outline = (const FT_Outline*)params->source; 1924ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann const FT_Bitmap* target_map = params->target; 1925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1926ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gray_TWorker worker[1]; 1927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1928ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann TCell buffer[FT_MAX( FT_RENDER_POOL_SIZE, 2048 ) / sizeof ( TCell )]; 1929ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann long buffer_size = sizeof ( buffer ); 1930ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann int band_size = (int)( buffer_size / 1931ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (long)( sizeof ( TCell ) * 8 ) ); 1932ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1933ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 1934ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann if ( !raster ) 1935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 1936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !outline ) 1938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Outline ); 1939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* return immediately if the outline is empty */ 1941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( outline->n_points == 0 || outline->n_contours <= 0 ) 1942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !outline->contours || !outline->points ) 1945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Outline ); 1946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( outline->n_points != 1948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov outline->contours[outline->n_contours - 1] + 1 ) 1949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Outline ); 1950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* if direct mode is not set, we must have a target bitmap */ 1952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) 1953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !target_map ) 1955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 1956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* nothing to do */ 1958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !target_map->width || !target_map->rows ) 1959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 1960ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !target_map->buffer ) 1962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Argument ); 1963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* this version does not support monochrome rendering */ 1966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !( params->flags & FT_RASTER_FLAG_AA ) ) 1967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return FT_THROW( Invalid_Mode ); 1968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compute clipping box */ 1970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) ) 1971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* compute clip box from target pixmap */ 1973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.clip_box.xMin = 0; 1974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.clip_box.yMin = 0; 1975ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ras.clip_box.xMax = (FT_Pos)target_map->width; 1976ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ras.clip_box.yMax = (FT_Pos)target_map->rows; 1977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else if ( params->flags & FT_RASTER_FLAG_CLIP ) 1979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.clip_box = params->clip_box; 1980ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 1981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.clip_box.xMin = -32768L; 1983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.clip_box.yMin = -32768L; 1984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.clip_box.xMax = 32767L; 1985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.clip_box.yMax = 32767L; 1986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 1987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1988ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann gray_init_cells( RAS_VAR_ buffer, buffer_size ); 1989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.outline = *outline; 1991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.num_cells = 0; 1992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.invalid = 1; 1993ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ras.band_size = band_size; 1994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.num_gray_spans = 0; 1995ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ras.span_y = 0; 1996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 1997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( params->flags & FT_RASTER_FLAG_DIRECT ) 1998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 1999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.render_span = (FT_Raster_Span_Func)params->gray_spans; 2000ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.render_span_data = params->user; 2001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov else 2003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.target = *target_map; 2005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.render_span = (FT_Raster_Span_Func)gray_render_span; 2006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ras.render_span_data = &ras; 2007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return gray_convert_glyph( RAS_VAR ); 2010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/ 2014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /**** a static object. *****/ 2015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _STANDALONE_ 2017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 2019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_raster_new( void* memory, 2020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Raster* araster ) 2021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static gray_TRaster the_raster; 2023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( memory ); 2025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *araster = (FT_Raster)&the_raster; 2028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) ); 2029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return 0; 2031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_raster_done( FT_Raster raster ) 2036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov /* nothing */ 2038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_UNUSED( raster ); 2039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else /* !_STANDALONE_ */ 2042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static int 2044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_raster_new( FT_Memory memory, 2045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Raster* araster ) 2046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Error error; 2048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_PRaster raster = NULL; 2049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *araster = 0; 2052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if ( !FT_ALLOC( raster, sizeof ( gray_TRaster ) ) ) 2053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov raster->memory = memory; 2055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *araster = (FT_Raster)raster; 2056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return error; 2059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_raster_done( FT_Raster raster ) 2064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_Memory memory = (FT_Memory)((gray_PRaster)raster)->memory; 2066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_FREE( raster ); 2069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif /* !_STANDALONE_ */ 2072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2074ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov static void 2075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov gray_raster_reset( FT_Raster raster, 2076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov char* pool_base, 2077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov long pool_size ) 2078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov { 2079ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_UNUSED( raster ); 2080ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_UNUSED( pool_base ); 2081ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_UNUSED( pool_size ); 2082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 2083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2085e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov static int 2086e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov gray_raster_set_mode( FT_Raster raster, 2087e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov unsigned long mode, 2088e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov void* args ) 2089e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov { 2090e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_UNUSED( raster ); 2091e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_UNUSED( mode ); 2092e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov FT_UNUSED( args ); 2093e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 2094e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 2095e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov return 0; /* nothing to do */ 2096e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov } 2097e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 2098e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov 2099ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann FT_DEFINE_RASTER_FUNCS( 2100ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann ft_grays_raster, 2101ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 2102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FT_GLYPH_FORMAT_OUTLINE, 2103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Raster_New_Func) gray_raster_new, 2105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Raster_Reset_Func) gray_raster_reset, 2106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov (FT_Raster_Set_Mode_Func)gray_raster_set_mode, 2107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (FT_Raster_Render_Func) gray_raster_render, 2108ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann (FT_Raster_Done_Func) gray_raster_done ) 2109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* END */ 2112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* Local Variables: */ 2115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* coding: utf-8 */ 2116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov/* End: */ 2117