ftgrays.c revision aeb407daf3711a10a27f3bc2223c5eb05158076e
1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  ftgrays.c                                                              */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    A new `perfect' anti-aliasing renderer (body).                       */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
7aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner/*  Copyright 2000-2003, 2005-2011 by                                      */
8049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  David Turner, Robert Wilhelm, and Werner Lemberg.                      */
9049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
10049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  This file is part of the FreeType project, and may only be used,       */
11049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  modified, and distributed under the terms of the FreeType project      */
12049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  license, LICENSE.TXT.  By continuing to use, modify, or distribute     */
13049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  this file you indicate that you have read the license and              */
14049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  understand and accept it fully.                                        */
15049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
16049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
17049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
18049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
19049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
20049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* This file can be compiled without the rest of the FreeType engine, by */
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* defining the _STANDALONE_ macro when compiling it.  You also need to  */
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* put the files `ftgrays.h' and `ftimage.h' into the current            */
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* compilation directory.  Typically, you could do something like        */
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* - copy `src/smooth/ftgrays.c' (this file) to your current directory   */
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   same directory                                                      */
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* - compile `ftgrays' with the _STANDALONE_ macro defined, as in        */
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*     cc -c -D_STANDALONE_ ftgrays.c                                    */
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The renderer can be initialized with a call to                        */
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* `ft_gray_raster.raster_new'; an anti-aliased bitmap can be generated  */
36049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* with a call to `ft_gray_raster.raster_render'.                        */
37049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* See the comments and documentation in the file `ftimage.h' for more   */
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* details on how the raster works.                                      */
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
42049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
43049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
44049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* This is a new anti-aliasing scan-converter for FreeType 2.  The       */
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* algorithm used here is _very_ different from the one in the standard  */
47049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* `ftraster' module.  Actually, `ftgrays' computes the _exact_          */
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* coverage of the outline on each pixel cell.                           */
49049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* It is based on ideas that I initially found in Raph Levien's          */
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* excellent LibArt graphics library (see http://www.levien.com/libart   */
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* for more information, though the web pages do not tell anything       */
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* about the renderer; you'll have to dive into the source code to       */
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* understand how it works).                                             */
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Note, however, that this is a _very_ different implementation         */
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* compared to Raph's.  Coverage information is stored in a very         */
58049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* different way, and I don't use sorted vector paths.  Also, it doesn't */
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* use floating point values.                                            */
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* This renderer has the following advantages:                           */
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* - It doesn't need an intermediate bitmap.  Instead, one can supply a  */
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   callback function that will be called by the renderer to draw gray  */
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   spans on any target surface.  You can thus do direct composition on */
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   any kind of bitmap, provided that you give the renderer the right   */
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   callback.                                                           */
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* - A perfect anti-aliaser, i.e., it computes the _exact_ coverage on   */
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   each pixel cell.                                                    */
71049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
72049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* - It performs a single pass on the outline (the `standard' FT2        */
73049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   renderer makes two passes).                                         */
74049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
75049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* - It can easily be modified to render to _any_ number of gray levels  */
76049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   cheaply.                                                            */
77049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
78049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* - For small (< 20) pixel sizes, it is faster than the standard        */
79049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   renderer.                                                           */
80049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* messages during execution.                                            */
89049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
90049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_smooth
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef _STANDALONE_
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
970a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* define this to dump debugging information */
980a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* #define FT_DEBUG_LEVEL_TRACE */
990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
1020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include <stdio.h>
1030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include <stdarg.h>
1040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
106aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#include <stddef.h>
1070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include <string.h>
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <setjmp.h>
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <limits.h>
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_UINT_MAX  UINT_MAX
111aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#define FT_INT_MAX   INT_MAX
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_memset   memset
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_setjmp   setjmp
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_longjmp  longjmp
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_jmp_buf  jmp_buf
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
119aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevichtypedef ptrdiff_t  FT_PtrDist;
120aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Mode      -2
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Outline   -1
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Argument  -3
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Memory_Overflow   -4
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_BEGIN_HEADER
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_END_HEADER
129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftimage.h"
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftgrays.h"
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* This macro is used to indicate that a function parameter is unused. */
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Its purpose is simply to reduce compiler warnings.  Note also that  */
136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* simply defining it as `(void)x' doesn't avoid warnings with certain */
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* ANSI compilers (e.g. LCC).                                          */
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_UNUSED( x )  (x) = (x)
139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1410a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* we only use level 5 & 7 tracing messages; cf. ftdebug.h */
1420a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
1440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1450a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  void
1460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_Message( const char*  fmt,
1470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              ... )
1480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  {
1490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    va_list  ap;
1500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    va_start( ap, fmt );
1530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    vfprintf( stderr, fmt, ap );
1540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    va_end( ap );
1550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  }
1560a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* we don't handle tracing levels in stand-alone mode; */
1580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifndef FT_TRACE5
1590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE5( varformat )  FT_Message varformat
1600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
1610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifndef FT_TRACE7
1620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE7( varformat )  FT_Message varformat
1630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_ERROR
1650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_ERROR( varformat )   FT_Message varformat
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#else /* !FT_DEBUG_LEVEL_TRACE */
1690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE5( x )  do { } while ( 0 )     /* nothing */
1710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE7( x )  do { } while ( 0 )     /* nothing */
1720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_ERROR( x )   do { } while ( 0 )     /* nothing */
1730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* !FT_DEBUG_LEVEL_TRACE */
1750a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
177295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define FT_DEFINE_OUTLINE_FUNCS( class_,               \
178295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                 move_to_, line_to_,   \
179295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                 conic_to_, cubic_to_, \
180295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                 shift_, delta_ )      \
181295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          static const FT_Outline_Funcs class_ =       \
182295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          {                                            \
183295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            move_to_,                                  \
184295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            line_to_,                                  \
185295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            conic_to_,                                 \
186295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            cubic_to_,                                 \
187295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            shift_,                                    \
188295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            delta_                                     \
189295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         };
1907f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
191295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_,            \
192295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                raster_new_, raster_reset_,       \
193295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                raster_set_mode_, raster_render_, \
194295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                raster_done_ )                    \
195295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          const FT_Raster_Funcs class_ =                          \
196295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          {                                                       \
197295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            glyph_format_,                                        \
198295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_new_,                                          \
199295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_reset_,                                        \
200295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_set_mode_,                                     \
201295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_render_,                                       \
202295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_done_                                          \
203295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         };
204295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !_STANDALONE_ */
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftgrays.h"
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_OUTLINE_H
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftsmerrs.h"
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
216295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "ftspic.h"
217295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Mode      Smooth_Err_Cannot_Render_Glyph
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Outline   Smooth_Err_Invalid_Outline
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Memory_Overflow   Smooth_Err_Out_Of_Memory
2210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define ErrRaster_Invalid_Argument  Smooth_Err_Invalid_Argument
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* !_STANDALONE_ */
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_MEM_SET
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_MEM_SET( d, s, c )  ft_memset( d, s, c )
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_MEM_ZERO
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_MEM_ZERO( dest, count )  FT_MEM_SET( dest, 0, count )
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* as usual, for the speed hungry :-) */
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_STATIC_RASTER
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_ARG   PWorker  worker
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_ARG_  PWorker  worker,
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR   worker
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR_  worker,
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* FT_STATIC_RASTER */
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_ARG   /* empty */
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_ARG_  /* empty */
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR   /* empty */
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR_  /* empty */
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* FT_STATIC_RASTER */
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* must be at least 6 bits! */
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define PIXEL_BITS  8
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ONE_PIXEL       ( 1L << PIXEL_BITS )
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define PIXEL_MASK      ( -1L << PIXEL_BITS )
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TRUNC( x )      ( (TCoord)( (x) >> PIXEL_BITS ) )
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define SUBPIXELS( x )  ( (TPos)(x) << PIXEL_BITS )
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FLOOR( x )      ( (x) & -ONE_PIXEL )
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define CEILING( x )    ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ROUND( x )      ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if PIXEL_BITS >= 6
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define UPSCALE( x )    ( (x) << ( PIXEL_BITS - 6 ) )
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define DOWNSCALE( x )  ( (x) >> ( PIXEL_BITS - 6 ) )
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define UPSCALE( x )    ( (x) >> ( 6 - PIXEL_BITS ) )
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define DOWNSCALE( x )  ( (x) << ( 6 - PIXEL_BITS ) )
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   TYPE DEFINITIONS                                                    */
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* don't change the following types to FT_Int or FT_Pos, since we might */
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* need to define them to "float" or "double" when experimenting with   */
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* new algorithms                                                       */
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
282295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  typedef long  TCoord;   /* integer scanline/pixel coordinate */
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef long  TPos;     /* sub-pixel coordinate              */
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* determine the type used to store cell areas.  This normally takes at */
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* least PIXEL_BITS*2 + 1 bits.  On 16-bit systems, we need to use      */
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* `long' instead of `int', otherwise bad things happen                 */
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if PIXEL_BITS <= 7
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef int  TArea;
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* PIXEL_BITS >= 8 */
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* approximately determine the size of integers using an ANSI-C header */
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if FT_UINT_MAX == 0xFFFFU
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef long  TArea;
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef int   TArea;
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* PIXEL_BITS >= 8 */
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* maximal number of gray spans in a call to the span callback */
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_MAX_GRAY_SPANS  32
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct TCell_*  PCell;
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  TCell_
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
313295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TPos   x;     /* same with TWorker.ex */
314295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TCoord cover; /* same with TWorker.cover */
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TArea  area;
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PCell  next;
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } TCell;
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  TWorker_
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TCoord  ex, ey;
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    min_ex, max_ex;
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    min_ey, max_ey;
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    count_ex, count_ey;
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TArea   area;
329295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TCoord  cover;
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int     invalid;
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PCell   cells;
333295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_PtrDist  max_cells;
334295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_PtrDist  num_cells;
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TCoord  cx, cy;
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    x,  y;
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    last_ey;
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector   bez_stack[32 * 3 + 1];
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int         lev_stack[32];
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline  outline;
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bitmap   target;
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_BBox     clip_box;
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Span     gray_spans[FT_MAX_GRAY_SPANS];
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int         num_gray_spans;
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Raster_Span_Func  render_span;
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*                render_span_data;
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int                  span_y;
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int  band_size;
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int  band_shoot;
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_jmp_buf  jump_buffer;
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*       buffer;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    long        buffer_size;
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PCell*     ycells;
364295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TPos       ycount;
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } TWorker, *PWorker;
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
369295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifndef FT_STATIC_RASTER
370295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define ras  (*worker)
371295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#else
372295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  static TWorker  ras;
373295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
374295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
375295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct TRaster_
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*    buffer;
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    long     buffer_size;
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int      band_size;
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*    memory;
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PWorker  worker;
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } TRaster, *PRaster;
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Initialize the cells table.                                           */
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_init_cells( RAS_ARG_ void*  buffer,
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   long            byte_size )
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.buffer      = buffer;
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.buffer_size = byte_size;
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.ycells      = (PCell*) buffer;
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cells       = NULL;
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.max_cells   = 0;
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.num_cells   = 0;
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.area        = 0;
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cover       = 0;
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.invalid     = 1;
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Compute the outline bounding box.                                     */
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_compute_cbox( RAS_ARG )
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*  outline = &ras.outline;
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*   vec     = outline->points;
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*   limit   = vec + outline->n_points;
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( outline->n_points <= 0 )
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.min_ex = ras.max_ex = 0;
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.min_ey = ras.max_ey = 0;
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.min_ex = ras.max_ex = vec->x;
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.min_ey = ras.max_ey = vec->y;
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec++;
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; vec < limit; vec++ )
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TPos  x = vec->x;
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TPos  y = vec->y;
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( x < ras.min_ex ) ras.min_ex = x;
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( x > ras.max_ex ) ras.max_ex = x;
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( y < ras.min_ey ) ras.min_ey = y;
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( y > ras.max_ey ) ras.max_ey = y;
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* truncate the bounding box to integer pixels */
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.min_ex = ras.min_ex >> 6;
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.min_ey = ras.min_ey >> 6;
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.max_ex = ( ras.max_ex + 63 ) >> 6;
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.max_ey = ( ras.max_ey + 63 ) >> 6;
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Record the current cell in the table.                                 */
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static PCell
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_find_cell( RAS_ARG )
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PCell  *pcell, cell;
461295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TPos    x = ras.ex;
462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( x > ras.count_ex )
4650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      x = ras.count_ex;
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pcell = &ras.ycells[ras.ey];
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for (;;)
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cell = *pcell;
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cell == NULL || cell->x > x )
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cell->x == x )
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pcell = &cell->next;
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.num_cells >= ras.max_cells )
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_longjmp( ras.jump_buffer, 1 );
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell        = ras.cells + ras.num_cells++;
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell->x     = x;
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell->area  = 0;
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell->cover = 0;
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell->next  = *pcell;
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *pcell      = cell;
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return cell;
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_record_cell( RAS_ARG )
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !ras.invalid && ( ras.area | ras.cover ) )
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      PCell  cell = gray_find_cell( RAS_VAR );
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cell->area  += ras.area;
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cell->cover += ras.cover;
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Set the current cell to a new position.                               */
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_set_cell( RAS_ARG_ TCoord  ex,
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          TCoord  ey )
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Move the cell pointer to a new position.  We set the `invalid'      */
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* flag to indicate that the cell isn't part of those we're interested */
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* in during the render phase.  This means that:                       */
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* . the new vertical position must be within min_ey..max_ey-1.        */
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* . the new horizontal position must be strictly less than max_ex     */
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Note that if a cell is to the left of the clipping region, it is    */
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* actually set to the (min_ex-1) horizontal position.                 */
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* All cells that are on the left of the clipping region go to the */
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* min_ex - 1 horizontal position.                                 */
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ey -= ras.min_ey;
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex > ras.max_ex )
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ex = ras.max_ex;
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ex -= ras.min_ex;
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex < 0 )
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ex = -1;
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* are we moving to a different cell ? */
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex != ras.ex || ey != ras.ey )
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* record the current one if it is valid */
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !ras.invalid )
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_record_cell( RAS_VAR );
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.area  = 0;
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.cover = 0;
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.ex      = ex;
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.ey      = ey;
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey ||
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              ex >= ras.count_ex           );
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Start a new contour at a given cell.                                  */
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_start_cell( RAS_ARG_ TCoord  ex,
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            TCoord  ey )
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex > ras.max_ex )
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ex = (TCoord)( ras.max_ex );
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex < ras.min_ex )
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ex = (TCoord)( ras.min_ex - 1 );
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.area    = 0;
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cover   = 0;
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.ex      = ex - ras.min_ex;
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.ey      = ey - ras.min_ey;
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.last_ey = SUBPIXELS( ey );
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.invalid = 0;
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_set_cell( RAS_VAR_ ex, ey );
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Render a scanline as one or more cells.                               */
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_scanline( RAS_ARG_ TCoord  ey,
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TPos    x1,
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TCoord  y1,
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TPos    x2,
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TCoord  y2 )
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
593295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TCoord  ex1, ex2, fx1, fx2, delta, mod, lift, rem;
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    long    p, first, dx;
595295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    int     incr;
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dx = x2 - x1;
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ex1 = TRUNC( x1 );
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ex2 = TRUNC( x2 );
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) );
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) );
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* trivial case.  Happens often */
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( y1 == y2 )
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_set_cell( RAS_VAR_ ex2, ey );
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* everything is located in a single cell.  That is easy! */
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                        */
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex1 == ex2 )
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta      = y2 - y1;
617295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      ras.area  += (TArea)(( fx1 + fx2 ) * delta);
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.cover += delta;
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* ok, we'll have to render a run of adjacent cells on the same */
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* scanline...                                                  */
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                              */
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p     = ( ONE_PIXEL - fx1 ) * ( y2 - y1 );
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = ONE_PIXEL;
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    incr  = 1;
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx < 0 )
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p     = fx1 * ( y2 - y1 );
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      first = 0;
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      incr  = -1;
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx    = -dx;
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    delta = (TCoord)( p / dx );
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    mod   = (TCoord)( p % dx );
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( mod < 0 )
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta--;
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mod += (TCoord)dx;
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
645295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    ras.area  += (TArea)(( fx1 + first ) * delta);
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cover += delta;
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ex1 += incr;
649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_set_cell( RAS_VAR_ ex1, ey );
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y1  += delta;
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex1 != ex2 )
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p    = ONE_PIXEL * ( y2 - y1 + delta );
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      lift = (TCoord)( p / dx );
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      rem  = (TCoord)( p % dx );
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( rem < 0 )
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        lift--;
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rem += (TCoord)dx;
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mod -= (int)dx;
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( ex1 != ex2 )
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        delta = lift;
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mod  += rem;
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( mod >= 0 )
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          mod -= (TCoord)dx;
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          delta++;
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
675295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        ras.area  += (TArea)(ONE_PIXEL * delta);
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.cover += delta;
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y1        += delta;
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ex1       += incr;
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_set_cell( RAS_VAR_ ex1, ey );
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    delta      = y2 - y1;
684295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    ras.area  += (TArea)(( fx2 + ONE_PIXEL - first ) * delta);
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cover += delta;
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Render a given line as a series of scanlines.                         */
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_line( RAS_ARG_ TPos  to_x,
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             TPos  to_y )
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
697295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TCoord  ey1, ey2, fy1, fy2, mod;
698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    dx, dy, x, x2;
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    long    p, first;
700295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    int     delta, rem, lift, incr;
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ey1 = TRUNC( ras.last_ey );
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ey2 = TRUNC( to_y );     /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fy1 = (TCoord)( ras.y - ras.last_ey );
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dx = to_x - ras.x;
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dy = to_y - ras.y;
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* XXX: we should do something about the trivial case where dx == 0, */
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      as it happens very often!                                    */
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* perform vertical clipping */
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  min, max;
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      min = ey1;
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      max = ey2;
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ey1 > ey2 )
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        min = ey2;
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        max = ey1;
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( min >= ras.max_ey || max < ras.min_ey )
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto End;
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* everything is on a single scanline */
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ey1 == ey2 )
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 );
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto End;
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* vertical line - avoid calling gray_render_scanline */
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    incr = 1;
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx == 0 )
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  ex     = TRUNC( ras.x );
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 );
744295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      TArea   area;
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      first = ONE_PIXEL;
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( dy < 0 )
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        first = 0;
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        incr  = -1;
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta      = (int)( first - fy1 );
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.area  += (TArea)two_fx * delta;
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.cover += delta;
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ey1       += incr;
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
759295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      gray_set_cell( RAS_VAR_ ex, ey1 );
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta = (int)( first + first - ONE_PIXEL );
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      area  = (TArea)two_fx * delta;
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( ey1 != ey2 )
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.area  += area;
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.cover += delta;
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ey1       += incr;
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
769295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        gray_set_cell( RAS_VAR_ ex, ey1 );
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta      = (int)( fy2 - ONE_PIXEL + first );
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.area  += (TArea)two_fx * delta;
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.cover += delta;
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto End;
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* ok, we have to render several scanlines */
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p     = ( ONE_PIXEL - fy1 ) * dx;
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = ONE_PIXEL;
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    incr  = 1;
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dy < 0 )
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p     = fy1 * dx;
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      first = 0;
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      incr  = -1;
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dy    = -dy;
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    delta = (int)( p / dy );
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    mod   = (int)( p % dy );
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( mod < 0 )
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta--;
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mod += (TCoord)dy;
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = ras.x + delta;
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first );
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ey1 += incr;
804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ey1 != ey2 )
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p     = ONE_PIXEL * dx;
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      lift  = (int)( p / dy );
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      rem   = (int)( p % dy );
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( rem < 0 )
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        lift--;
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rem += (int)dy;
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mod -= (int)dy;
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( ey1 != ey2 )
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        delta = lift;
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mod  += rem;
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( mod >= 0 )
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          mod -= (int)dy;
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          delta++;
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x2 = x + delta;
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_render_scanline( RAS_VAR_ ey1, x,
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       (TCoord)( ONE_PIXEL - first ), x2,
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       (TCoord)first );
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x = x2;
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ey1 += incr;
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_render_scanline( RAS_VAR_ ey1, x,
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   (TCoord)( ONE_PIXEL - first ), to_x,
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   fy2 );
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  End:
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.x       = to_x;
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.y       = to_y;
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.last_ey = SUBPIXELS( ey2 );
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_split_conic( FT_Vector*  base )
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos  a, b;
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].x = base[2].x;
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].x;
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    a = base[3].x = ( base[2].x + b ) / 2;
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].x = ( base[0].x + b ) / 2;
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].x = ( a + b ) / 2;
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].y = base[2].y;
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].y;
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    a = base[3].y = ( base[2].y + b ) / 2;
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].y = ( base[0].y + b ) / 2;
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].y = ( a + b ) / 2;
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_conic( RAS_ARG_ const FT_Vector*  control,
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const FT_Vector*  to )
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos        dx, dy;
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int         top, level;
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int*        levels;
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*  arc;
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
8807f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc      = ras.bez_stack;
8817f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[0].x = UPSCALE( to->x );
8827f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[0].y = UPSCALE( to->y );
8837f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[1].x = UPSCALE( control->x );
8847f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[1].y = UPSCALE( control->y );
8857f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[2].x = ras.x;
8867f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[2].y = ras.y;
8877f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
8887f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x );
8897f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y );
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx < dy )
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx = dy;
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
8937f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    level = 0;
894aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    while ( dx > ONE_PIXEL / 6 )
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
8967f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      dx >>= 2;
8977f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      level++;
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    levels    = ras.lev_stack;
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    levels[0] = level;
9027f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    top       = 0;
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
904aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    do
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      level = levels[top];
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( level > 1 )
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* check that the arc crosses the current band */
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TPos  min, max, y;
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        min = max = arc[0].y;
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = arc[1].y;
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y < min ) min = y;
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y > max ) max = y;
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = arc[2].y;
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y < min ) min = y;
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y > max ) max = y;
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Draw;
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_split_conic( arc );
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        arc += 2;
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        top++;
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        levels[top] = levels[top - 1] = level - 1;
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Draw:
9347f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
9357f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      top--;
9367f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      arc -= 2;
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
938aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    } while ( top >= 0 );
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_split_cubic( FT_Vector*  base )
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos  a, b, c, d;
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[6].x = base[3].x;
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = base[1].x;
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    d = base[2].x;
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[1].x = a = ( base[0].x + c ) / 2;
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[5].x = b = ( base[3].x + d ) / 2;
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = ( c + d ) / 2;
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].x = a = ( a + c ) / 2;
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].x = b = ( b + c ) / 2;
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[3].x = ( a + b ) / 2;
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[6].y = base[3].y;
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = base[1].y;
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    d = base[2].y;
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[1].y = a = ( base[0].y + c ) / 2;
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[5].y = b = ( base[3].y + d ) / 2;
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = ( c + d ) / 2;
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].y = a = ( a + c ) / 2;
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].y = b = ( b + c ) / 2;
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[3].y = ( a + b ) / 2;
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_cubic( RAS_ARG_ const FT_Vector*  control1,
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const FT_Vector*  control2,
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const FT_Vector*  to )
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*  arc;
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc      = ras.bez_stack;
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[0].x = UPSCALE( to->x );
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[0].y = UPSCALE( to->y );
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[1].x = UPSCALE( control2->x );
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[1].y = UPSCALE( control2->y );
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[2].x = UPSCALE( control1->x );
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[2].y = UPSCALE( control1->y );
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[3].x = ras.x;
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[3].y = ras.y;
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
9887f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    for (;;)
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
9907f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /* Check that the arc crosses the current band. */
9917f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      TPos  min, max, y;
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
9947f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      min = max = arc[0].y;
995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
9967f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      y = arc[1].y;
9977f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( y < min )
9987f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        min = y;
9997f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( y > max )
10007f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        max = y;
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
10027f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      y = arc[2].y;
10037f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( y < min )
10047f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        min = y;
10057f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( y > max )
10067f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        max = y;
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
10087f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      y = arc[3].y;
10097f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( y < min )
10107f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        min = y;
10117f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( y > max )
10127f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        max = y;
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
10147f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
10157f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        goto Draw;
10167f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10177f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /* Decide whether to split or draw. See `Rapid Termination          */
10187f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */
10197f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /* F. Hain, at                                                      */
10207f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */
10217f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10227f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      {
10237f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        TPos  dx, dy, dx_, dy_;
10247f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        TPos  dx1, dy1, dx2, dy2;
10257f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        TPos  L, s, s_limit;
10267f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10277f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10287f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* dx and dy are x and y components of the P0-P3 chord vector. */
10297f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        dx = arc[3].x - arc[0].x;
10307f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        dy = arc[3].y - arc[0].y;
10317f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10327f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* L is an (under)estimate of the Euclidean distance P0-P3.       */
10337f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*                                                                */
10347f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* If dx >= dy, then r = sqrt(dx^2 + dy^2) can be overestimated   */
10357f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* with least maximum error by                                    */
10367f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*                                                                */
10377f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*   r_upperbound = dx + (sqrt(2) - 1) * dy  ,                    */
10387f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*                                                                */
10397f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* where sqrt(2) - 1 can be (over)estimated by 107/256, giving an */
10407f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* error of no more than 8.4%.                                    */
10417f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*                                                                */
10427f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* Similarly, some elementary calculus shows that r can be        */
10437f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* underestimated with least maximum error by                     */
10447f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*                                                                */
10457f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*   r_lowerbound = sqrt(2 + sqrt(2)) / 2 * dx                    */
10467f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*                  + sqrt(2 - sqrt(2)) / 2 * dy  .               */
10477f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*                                                                */
10487f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* 236/256 and 97/256 are (under)estimates of the two algebraic   */
10497f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* numbers, giving an error of no more than 8.1%.                 */
10507f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10517f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        dx_ = FT_ABS( dx );
10527f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        dy_ = FT_ABS( dy );
10537f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10547f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* This is the same as                     */
10557f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*                                         */
10567f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*   L = ( 236 * FT_MAX( dx_, dy_ )        */
10577f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /*       + 97 * FT_MIN( dx_, dy_ ) ) >> 8; */
10587f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        L = ( dx_ > dy_ ? 236 * dx_ +  97 * dy_
10597f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner                        :  97 * dx_ + 236 * dy_ ) >> 8;
10607f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10617f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* Avoid possible arithmetic overflow below by splitting. */
10627f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        if ( L > 32767 )
10637f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner          goto Split;
10647f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10657f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
10667f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        s_limit = L * (TPos)( ONE_PIXEL / 6 );
10677f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10687f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* s is L * the perpendicular distance from P1 to the line P0-P3. */
10697f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        dx1 = arc[1].x - arc[0].x;
10707f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        dy1 = arc[1].y - arc[0].y;
10717f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        s = FT_ABS( dy * dx1 - dx * dy1 );
10727f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10737f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        if ( s > s_limit )
10747f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner          goto Split;
10757f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10767f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* s is L * the perpendicular distance from P2 to the line P0-P3. */
10777f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        dx2 = arc[2].x - arc[0].x;
10787f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        dy2 = arc[2].y - arc[0].y;
10797f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        s = FT_ABS( dy * dx2 - dx * dy2 );
10807f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10817f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        if ( s > s_limit )
10827f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner          goto Split;
10837f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10847f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* If P1 or P2 is outside P0-P3, split the curve. */
10857f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        if ( dy * dy1 + dx * dx1 < 0                                     ||
10867f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner             dy * dy2 + dx * dx2 < 0                                     ||
10877f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner             dy * (arc[3].y - arc[1].y) + dx * (arc[3].x - arc[1].x) < 0 ||
10887f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner             dy * (arc[3].y - arc[2].y) + dx * (arc[3].x - arc[2].x) < 0 )
10897f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner          goto Split;
10907f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10917f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        /* No reason to split. */
10927f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        goto Draw;
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
10957f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    Split:
10967f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      gray_split_cubic( arc );
10977f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      arc += 3;
10987f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      continue;
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
11007f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    Draw:
11017f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
11027f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
11037f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      if ( arc == ras.bez_stack )
11047f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner        return;
11057f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
11067f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      arc -= 3;
11077f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    }
11087f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner  }
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_move_to( const FT_Vector*  to,
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                PWorker           worker )
1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos  x, y;
1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* record current cell, if any */
1119295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_record_cell( RAS_VAR );
1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* start to a new position */
1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = UPSCALE( to->x );
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y = UPSCALE( to->y );
1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1125295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) );
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    worker->x = x;
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    worker->y = y;
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_line_to( const FT_Vector*  to,
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                PWorker           worker )
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1137295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_conic_to( const FT_Vector*  control,
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Vector*  to,
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 PWorker           worker )
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1147295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_render_conic( RAS_VAR_ control, to );
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_cubic_to( const FT_Vector*  control1,
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Vector*  control2,
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Vector*  to,
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 PWorker           worker )
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1158295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_render_cubic( RAS_VAR_ control1, control2, to );
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_span( int             y,
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    int             count,
1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    const FT_Span*  spans,
1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    PWorker         worker )
1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned char*  p;
1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bitmap*      map = &worker->target;
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* first of all, compute the scanline offset */
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p = (unsigned char*)map->buffer - y * map->pitch;
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( map->pitch >= 0 )
1176aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich      p += (unsigned)( ( map->rows - 1 ) * map->pitch );
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; count > 0; count--, spans++ )
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      unsigned char  coverage = spans->coverage;
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( coverage )
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* For small-spans it is faster to do it by ourselves than
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         * calling `memset'.  This is mainly due to the cost of the
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         * function call.
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         */
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( spans->len >= 8 )
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len );
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          unsigned char*  q = p + spans->x;
1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          switch ( spans->len )
1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 7: *q++ = (unsigned char)coverage;
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 6: *q++ = (unsigned char)coverage;
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 5: *q++ = (unsigned char)coverage;
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 4: *q++ = (unsigned char)coverage;
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 3: *q++ = (unsigned char)coverage;
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 2: *q++ = (unsigned char)coverage;
1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 1: *q   = (unsigned char)coverage;
1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          default:
1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ;
1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_hline( RAS_ARG_ TCoord  x,
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       TCoord  y,
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       TPos    area,
1218295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                       TCoord  acount )
1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Span*  span;
1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int       count;
1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int       coverage;
1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute the coverage line's coverage, depending on the    */
1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* outline fill rule                                         */
1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                           */
1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */
1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                           */
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) );
1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    /* use range 0..256 */
1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( coverage < 0 )
1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      coverage = -coverage;
1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL )
1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      coverage &= 511;
1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( coverage > 256 )
1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        coverage = 512 - coverage;
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( coverage == 256 )
1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        coverage = 255;
1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* normal non-zero winding rule */
1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( coverage >= 256 )
1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        coverage = 255;
1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y += (TCoord)ras.min_ey;
1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x += (TCoord)ras.min_ex;
1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */
12550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( x >= 32767 )
1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x = 32767;
1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1258295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* FT_Span.y is an integer, so limit our coordinates appropriately */
1259295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( y >= FT_INT_MAX )
1260295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      y = FT_INT_MAX;
1261295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( coverage )
1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* see whether we can add this span to the current list */
1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      count = ras.num_gray_spans;
1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      span  = ras.gray_spans + count - 1;
1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count > 0                          &&
1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ras.span_y == y                    &&
1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           (int)span->x + span->len == (int)x &&
1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           span->coverage == coverage         )
1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        span->len = (unsigned short)( span->len + acount );
1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return;
1274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS )
1277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ras.render_span && count > 0 )
1279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.render_span( ras.span_y, count, ras.gray_spans,
1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           ras.render_span_data );
1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
12820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
12840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        if ( count > 0 )
1285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          int  n;
1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
12890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_TRACE7(( "y = %3d ", ras.span_y ));
1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          span = ras.gray_spans;
1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( n = 0; n < count; n++, span++ )
12920a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_TRACE7(( "[%d..%d]:%02x ",
12930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        span->x, span->x + span->len - 1, span->coverage ));
12940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_TRACE7(( "\n" ));
1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
12970a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* FT_DEBUG_LEVEL_TRACE */
1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.num_gray_spans = 0;
1300295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        ras.span_y         = (int)y;
1301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count = 0;
1303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        span  = ras.gray_spans;
1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        span++;
1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* add a gray span to the current list */
1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      span->x        = (short)x;
1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      span->len      = (unsigned short)acount;
1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      span->coverage = (unsigned char)coverage;
1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.num_gray_spans++;
1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* to be called while in the debugger --                                */
13210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* this function causes a compiler warning since it is unused otherwise */
13220a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  static void
1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_dump_cells( RAS_ARG )
1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int  yindex;
1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( yindex = 0; yindex < ras.ycount; yindex++ )
1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      PCell  cell;
1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      printf( "%3d:", yindex );
1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )
1336295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area );
1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      printf( "\n" );
1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13410a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* FT_DEBUG_LEVEL_TRACE */
1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_sweep( RAS_ARG_ const FT_Bitmap*  target )
1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int  yindex;
1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( target );
1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.num_cells == 0 )
1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.num_gray_spans = 0;
1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE7(( "gray_sweep: start\n" ));
13580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( yindex = 0; yindex < ras.ycount; yindex++ )
1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      PCell   cell  = ras.ycells[yindex];
1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  cover = 0;
1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  x     = 0;
1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; cell != NULL; cell = cell->next )
1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1368295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        TPos  area;
1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( cell->x > x && cover != 0 )
1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      cell->x - x );
1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cover += cell->cover;
1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        area   = cover * ( ONE_PIXEL * 2 ) - cell->area;
1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( area != 0 && cell->x >= 0 )
1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          gray_hline( RAS_VAR_ cell->x, yindex, area, 1 );
1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x = cell->x + 1;
1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cover != 0 )
1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    ras.count_ex - x );
1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.render_span && ras.num_gray_spans > 0 )
1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.render_span( ras.span_y, ras.num_gray_spans,
1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       ras.gray_spans, ras.render_span_data );
13920a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
13930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE7(( "gray_sweep: end\n" ));
1394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef _STANDALONE_
1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
14010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*  The following function should only compile in stand-alone mode,      */
1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*  i.e., when building this component without the rest of FreeType.     */
1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FT_Outline_Decompose                                               */
1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
14120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*    Walk over an outline's structure to decompose it into individual   */
14130a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*    segments and Bézier arcs.  This function is also able to emit      */
1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    `move to' and `close to' operations to indicate the start and end  */
1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    of new contours in the outline.                                    */
1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
1418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    outline        :: A pointer to the source target.                  */
1419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
14200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*    func_interface :: A table of `emitters', i.e., function pointers   */
1421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      called during decomposition to indicate path     */
1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      operations.                                      */
1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
14240a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* <InOut>                                                               */
1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    user           :: A typeless pointer which is passed to each       */
1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      emitter during the decomposition.  It can be     */
1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      used to store the state during the               */
1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      decomposition.                                   */
1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Error code.  0 means success.                                      */
1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
14330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  static int
14340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_Outline_Decompose( const FT_Outline*        outline,
14350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        const FT_Outline_Funcs*  func_interface,
14360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        void*                    user )
1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef SCALED
1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define SCALED( x )  ( ( (x) << shift ) - delta )
1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector   v_last;
1442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector   v_control;
1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector   v_start;
1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*  point;
1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*  limit;
1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    char*       tags;
1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    int         error;
14500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int   n;         /* index of contour in outline     */
1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int   first;     /* index of first point in contour */
1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    char  tag;       /* current point's state           */
1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    int   shift;
14560a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    TPos  delta;
1457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !outline || !func_interface )
14600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      return ErrRaster_Invalid_Argument;
14610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
14620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    shift = func_interface->shift;
14630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    delta = func_interface->delta;
1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = 0;
1465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( n = 0; n < outline->n_contours; n++ )
1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      int  last;  /* index of last point in contour */
1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));
14720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      last  = outline->contours[n];
14740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( last < 0 )
14750a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        goto Invalid_Outline;
1476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      limit = outline->points + last;
1477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14780a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_start   = outline->points[first];
1479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v_start.x = SCALED( v_start.x );
1480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v_start.y = SCALED( v_start.y );
1481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_last   = outline->points[last];
14830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_last.x = SCALED( v_last.x );
14840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_last.y = SCALED( v_last.y );
1485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v_control = v_start;
1487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      point = outline->points + first;
14890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      tags  = outline->tags   + first;
1490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      tag   = FT_CURVE_TAG( tags[0] );
1491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* A contour cannot start with a cubic control point! */
1493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( tag == FT_CURVE_TAG_CUBIC )
1494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Invalid_Outline;
1495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check first point to determine origin */
1497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( tag == FT_CURVE_TAG_CONIC )
1498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* first point is conic control.  Yes, this happens. */
1500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )
1501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* start at last point if it is on the curve */
1503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_start = v_last;
1504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          limit--;
1505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
1507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* if both first and last points are conic,         */
1509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* start at their middle and record its position    */
1510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* for closure                                      */
1511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_start.x = ( v_start.x + v_last.x ) / 2;
1512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_start.y = ( v_start.y + v_last.y ) / 2;
1513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_last = v_start;
1515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        point--;
1517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        tags--;
1518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE5(( "  move to (%.2f, %.2f)\n",
15210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                  v_start.x / 64.0, v_start.y / 64.0 ));
1522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = func_interface->move_to( &v_start, user );
1523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( point < limit )
1527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        point++;
1529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        tags++;
1530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        tag = FT_CURVE_TAG( tags[0] );
1532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        switch ( tag )
1533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case FT_CURVE_TAG_ON:  /* emit a single line_to */
1535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Vector  vec;
1537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec.x = SCALED( point->x );
1540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec.y = SCALED( point->y );
1541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15420a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_TRACE5(( "  line to (%.2f, %.2f)\n",
15430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        vec.x / 64.0, vec.y / 64.0 ));
1544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            error = func_interface->line_to( &vec, user );
1545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( error )
1546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Exit;
1547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            continue;
1548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case FT_CURVE_TAG_CONIC:  /* consume conic arcs */
15510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          v_control.x = SCALED( point->x );
15520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          v_control.y = SCALED( point->y );
1553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        Do_Conic:
15550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          if ( point < limit )
15560a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          {
15570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_Vector  vec;
15580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_Vector  v_middle;
1559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            point++;
15620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            tags++;
15630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            tag = FT_CURVE_TAG( tags[0] );
1564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            vec.x = SCALED( point->x );
15660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            vec.y = SCALED( point->y );
1567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            if ( tag == FT_CURVE_TAG_ON )
15690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            {
15700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              FT_TRACE5(( "  conic to (%.2f, %.2f)"
15710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          " with control (%.2f, %.2f)\n",
15720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          vec.x / 64.0, vec.y / 64.0,
15730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          v_control.x / 64.0, v_control.y / 64.0 ));
15740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              error = func_interface->conic_to( &v_control, &vec, user );
1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( error )
1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
15770a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              continue;
1578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            if ( tag != FT_CURVE_TAG_CONIC )
15810a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              goto Invalid_Outline;
15820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
15830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            v_middle.x = ( v_control.x + vec.x ) / 2;
15840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            v_middle.y = ( v_control.y + vec.y ) / 2;
15850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
15860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_TRACE5(( "  conic to (%.2f, %.2f)"
15870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        " with control (%.2f, %.2f)\n",
15880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        v_middle.x / 64.0, v_middle.y / 64.0,
15890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        v_control.x / 64.0, v_control.y / 64.0 ));
15900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            error = func_interface->conic_to( &v_control, &v_middle, user );
15910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            if ( error )
15920a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              goto Exit;
15930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
15940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            v_control = vec;
15950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            goto Do_Conic;
1596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15980a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_TRACE5(( "  conic to (%.2f, %.2f)"
15990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      " with control (%.2f, %.2f)\n",
16000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      v_start.x / 64.0, v_start.y / 64.0,
16010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      v_control.x / 64.0, v_control.y / 64.0 ));
16020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          error = func_interface->conic_to( &v_control, &v_start, user );
16030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          goto Close;
16040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        default:  /* FT_CURVE_TAG_CUBIC */
1606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Vector  vec1, vec2;
1608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( point + 1 > limit                             ||
1611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Invalid_Outline;
1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            point += 2;
1615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tags  += 2;
1616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec1.x = SCALED( point[-2].x );
1618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec1.y = SCALED( point[-2].y );
1619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec2.x = SCALED( point[-1].x );
1621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec2.y = SCALED( point[-1].y );
1622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( point <= limit )
1624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
1625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_Vector  vec;
1626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              vec.x = SCALED( point->x );
1629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              vec.y = SCALED( point->y );
1630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
16310a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              FT_TRACE5(( "  cubic to (%.2f, %.2f)"
16320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
16330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          vec.x / 64.0, vec.y / 64.0,
16340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          vec1.x / 64.0, vec1.y / 64.0,
16350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          vec2.x / 64.0, vec2.y / 64.0 ));
1636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              error = func_interface->cubic_to( &vec1, &vec2, &vec, user );
1637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( error )
1638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
1639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              continue;
1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
16420a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_TRACE5(( "  cubic to (%.2f, %.2f)"
16430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
16440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        v_start.x / 64.0, v_start.y / 64.0,
16450a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        vec1.x / 64.0, vec1.y / 64.0,
16460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        vec2.x / 64.0, vec2.y / 64.0 ));
1647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );
1648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Close;
1649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* close the contour with a line segment */
16540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE5(( "  line to (%.2f, %.2f)\n",
16550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                  v_start.x / 64.0, v_start.y / 64.0 ));
1656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = func_interface->line_to( &v_start, user );
1657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   Close:
1659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      first = last + 1;
1663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
16650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
1666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
16690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error ));
1670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Invalid_Outline:
1673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ErrRaster_Invalid_Outline;
1674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* _STANDALONE_ */
1677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  TBand_
1680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos  min, max;
1682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } TBand;
1684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1685295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_DEFINE_OUTLINE_FUNCS(func_interface,
1686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (FT_Outline_MoveTo_Func) gray_move_to,
1687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (FT_Outline_LineTo_Func) gray_line_to,
1688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (FT_Outline_ConicTo_Func)gray_conic_to,
1689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (FT_Outline_CubicTo_Func)gray_cubic_to,
1690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,
1691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0
1692295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    )
1693295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
1694295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  static int
1695295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  gray_convert_glyph_inner( RAS_ARG )
1696295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  {
1697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    volatile int  error = 0;
1699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1700295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
1701295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_Outline_Funcs func_interface;
1702295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      Init_Class_func_interface(&func_interface);
1703295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
17040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ft_setjmp( ras.jump_buffer ) == 0 )
1706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
1708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_record_cell( RAS_VAR );
1709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = ErrRaster_Memory_Overflow;
1712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_convert_glyph( RAS_ARG )
1719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TBand            bands[40];
1721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TBand* volatile  band;
1722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int volatile     n, num_bands;
1723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos volatile    min, max, max_y;
1724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_BBox*         clip;
1725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Set up state in the raster object */
1728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_compute_cbox( RAS_VAR );
1729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* clip to target bitmap, exit if nothing to do */
1731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clip = &ras.clip_box;
1732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax ||
1734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax )
1735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
1736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin;
1738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin;
1739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax;
1741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax;
1742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.count_ex = ras.max_ex - ras.min_ex;
1744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.count_ey = ras.max_ey - ras.min_ey;
1745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
17460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* set up vertical bands */
1747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size );
17480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( num_bands == 0 )
17490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      num_bands = 1;
17500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( num_bands >= 39 )
17510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      num_bands = 39;
1752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.band_shoot = 0;
1754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    min   = ras.min_ey;
1756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    max_y = ras.max_ey;
1757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( n = 0; n < num_bands; n++, min = max )
1759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      max = min + ras.band_size;
1761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( n == num_bands - 1 || max > max_y )
1762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        max = max_y;
1763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bands[0].min = min;
1765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bands[0].max = max;
1766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      band         = bands;
1767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( band >= bands )
1769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TPos  bottom, top, middle;
1771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        int   error;
1772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          PCell  cells_max;
1775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          int    yindex;
1776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          long   cell_start, cell_end, cell_mod;
1777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.ycells = (PCell*)ras.buffer;
1780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.ycount = band->max - band->min;
1781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cell_start = sizeof ( PCell ) * ras.ycount;
1783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cell_mod   = cell_start % sizeof ( TCell );
1784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( cell_mod > 0 )
1785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            cell_start += sizeof ( TCell ) - cell_mod;
1786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cell_end  = ras.buffer_size;
1788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cell_end -= cell_end % sizeof( TCell );
1789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cells_max = (PCell)( (char*)ras.buffer + cell_end );
1791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.cells = (PCell)( (char*)ras.buffer + cell_start );
1792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( ras.cells >= cells_max )
1793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto ReduceBands;
1794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.max_cells = cells_max - ras.cells;
1796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( ras.max_cells < 2 )
1797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto ReduceBands;
1798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( yindex = 0; yindex < ras.ycount; yindex++ )
1800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ras.ycells[yindex] = NULL;
1801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.num_cells = 0;
1804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.invalid   = 1;
1805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.min_ey    = band->min;
1806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.max_ey    = band->max;
1807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.count_ey  = band->max - band->min;
1808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = gray_convert_glyph_inner( RAS_VAR );
1810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error )
1812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          gray_sweep( RAS_VAR_ &ras.target );
1814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          band--;
1815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          continue;
1816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( error != ErrRaster_Memory_Overflow )
1818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return 1;
1819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ReduceBands:
1821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* render pool overflow; we will reduce the render band by half */
1822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        bottom = band->min;
1823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        top    = band->max;
1824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        middle = bottom + ( ( top - bottom ) >> 1 );
1825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* This is too complex for a single scanline; there must */
1827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* be some problems.                                     */
1828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( middle == bottom )
1829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
18300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
1831295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
1832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return 1;
1834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bottom-top >= ras.band_size )
1837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.band_shoot++;
1838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        band[1].min = bottom;
1840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        band[1].max = middle;
1841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        band[0].min = middle;
1842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        band[0].max = top;
1843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        band++;
1844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.band_shoot > 8 && ras.band_size > 16 )
1848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.band_size = ras.band_size / 2;
1849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_render( PRaster                  raster,
1856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      const FT_Raster_Params*  params )
1857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Outline*  outline    = (const FT_Outline*)params->source;
1859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Bitmap*   target_map = params->target;
1860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PWorker            worker;
1861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !raster || !raster->buffer || !raster->buffer_size )
1864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ErrRaster_Invalid_Argument;
1865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !outline )
1867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ErrRaster_Invalid_Outline;
1868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* return immediately if the outline is empty */
1870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( outline->n_points == 0 || outline->n_contours <= 0 )
1871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
1872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !outline->contours || !outline->points )
1874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ErrRaster_Invalid_Outline;
1875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( outline->n_points !=
1877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           outline->contours[outline->n_contours - 1] + 1 )
1878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ErrRaster_Invalid_Outline;
1879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    worker = raster->worker;
1881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if direct mode is not set, we must have a target bitmap */
18830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
1884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !target_map )
1886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return ErrRaster_Invalid_Argument;
1887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* nothing to do */
1889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !target_map->width || !target_map->rows )
1890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return 0;
1891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !target_map->buffer )
1893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return ErrRaster_Invalid_Argument;
1894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* this version does not support monochrome rendering */
1897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !( params->flags & FT_RASTER_FLAG_AA ) )
1898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ErrRaster_Invalid_Mode;
1899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute clipping box */
19010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
1902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* compute clip box from target pixmap */
1904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.xMin = 0;
1905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.yMin = 0;
1906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.xMax = target_map->width;
1907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.yMax = target_map->rows;
1908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( params->flags & FT_RASTER_FLAG_CLIP )
1910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box = params->clip_box;
1911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.xMin = -32768L;
1914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.yMin = -32768L;
1915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.xMax =  32767L;
1916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.yMax =  32767L;
1917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1919295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size );
1920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.outline        = *outline;
1922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.num_cells      = 0;
1923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.invalid        = 1;
1924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.band_size      = raster->band_size;
1925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.num_gray_spans = 0;
1926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( params->flags & FT_RASTER_FLAG_DIRECT )
1928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.render_span      = (FT_Raster_Span_Func)params->gray_spans;
1930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.render_span_data = params->user;
1931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
19320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    else
19330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
19340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      ras.target           = *target_map;
19350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      ras.render_span      = (FT_Raster_Span_Func)gray_render_span;
19360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      ras.render_span_data = &ras;
19370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
1938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1939295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    return gray_convert_glyph( RAS_VAR );
1940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/
19440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /****                         a static object.                   *****/
1945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef _STANDALONE_
1947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_new( void*       memory,
1950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Raster*  araster )
1951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static TRaster  the_raster;
1953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( memory );
1955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *araster = (FT_Raster)&the_raster;
1958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
1959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_done( FT_Raster  raster )
1966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* nothing */
1968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( raster );
1969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1971aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#else /* !_STANDALONE_ */
1972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_new( FT_Memory   memory,
1975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Raster*  araster )
1976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
1978aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich    PRaster   raster = NULL;
1979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *araster = 0;
1982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_ALLOC( raster, sizeof ( TRaster ) ) )
1983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      raster->memory = memory;
1985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *araster = (FT_Raster)raster;
1986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_done( FT_Raster  raster )
1994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = (FT_Memory)((PRaster)raster)->memory;
1996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( raster );
1999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2001aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#endif /* !_STANDALONE_ */
2002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
2005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_reset( FT_Raster  raster,
2006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     char*      pool_base,
2007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     long       pool_size )
2008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PRaster  rast = (PRaster)raster;
2010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( raster )
2013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( pool_base && pool_size >= (long)sizeof ( TWorker ) + 2048 )
2015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        PWorker  worker = (PWorker)pool_base;
2017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->worker      = worker;
2020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->buffer      = pool_base +
2021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              ( ( sizeof ( TWorker ) + sizeof ( TCell ) - 1 ) &
2022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                ~( sizeof ( TCell ) - 1 ) );
2023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->buffer_size = (long)( ( pool_base + pool_size ) -
2024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    (char*)rast->buffer ) &
2025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      ~( sizeof ( TCell ) - 1 );
2026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->band_size   = (int)( rast->buffer_size /
2027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     ( sizeof ( TCell ) * 8 ) );
2028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
2030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->buffer      = NULL;
2032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->buffer_size = 0;
2033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->worker      = NULL;
2034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2039295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  FT_DEFINE_RASTER_FUNCS(ft_grays_raster,
2040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GLYPH_FORMAT_OUTLINE,
2041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Raster_New_Func)     gray_raster_new,
2043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Raster_Reset_Func)   gray_raster_reset,
2044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Raster_Set_Mode_Func)0,
2045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Raster_Render_Func)  gray_raster_render,
2046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Raster_Done_Func)    gray_raster_done
2047295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  )
2048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
20510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
20520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
20530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* Local Variables: */
20540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* coding: utf-8    */
20550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* End:             */
2056