ftgrays.c revision 295ffce55e0198e7a9f7d46b33f5c2b4147bf821
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/*                                                                         */
7295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner/*  Copyright 2000-2001, 2002, 2003, 2005, 2006, 2007, 2008, 2009 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
1060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include <string.h>
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <setjmp.h>
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <limits.h>
109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_UINT_MAX  UINT_MAX
110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_memset   memset
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_setjmp   setjmp
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_longjmp  longjmp
115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_jmp_buf  jmp_buf
116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Mode      -2
119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Outline   -1
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Argument  -3
121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Memory_Overflow   -4
122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_BEGIN_HEADER
124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_END_HEADER
125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftimage.h"
127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftgrays.h"
128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* This macro is used to indicate that a function parameter is unused. */
131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Its purpose is simply to reduce compiler warnings.  Note also that  */
132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* simply defining it as `(void)x' doesn't avoid warnings with certain */
133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* ANSI compilers (e.g. LCC).                                          */
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_UNUSED( x )  (x) = (x)
135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* we only use level 5 & 7 tracing messages; cf. ftdebug.h */
1380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1390a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
1400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1410a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  void
1420a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_Message( const char*  fmt,
1430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              ... )
1440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  {
1450a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    va_list  ap;
1460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    va_start( ap, fmt );
1490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    vfprintf( stderr, fmt, ap );
1500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    va_end( ap );
1510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  }
1520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* we don't handle tracing levels in stand-alone mode; */
1540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifndef FT_TRACE5
1550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE5( varformat )  FT_Message varformat
1560a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
1570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifndef FT_TRACE7
1580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE7( varformat )  FT_Message varformat
1590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_ERROR
1610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_ERROR( varformat )   FT_Message varformat
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#else /* !FT_DEBUG_LEVEL_TRACE */
1650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE5( x )  do { } while ( 0 )     /* nothing */
1670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE7( x )  do { } while ( 0 )     /* nothing */
1680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_ERROR( x )   do { } while ( 0 )     /* nothing */
1690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* !FT_DEBUG_LEVEL_TRACE */
1710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
173295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define FT_DEFINE_OUTLINE_FUNCS( class_,               \
174295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                 move_to_, line_to_,   \
175295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                 conic_to_, cubic_to_, \
176295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                 shift_, delta_ )      \
177295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          static const FT_Outline_Funcs class_ =       \
178295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          {                                            \
179295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            move_to_,                                  \
180295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            line_to_,                                  \
181295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            conic_to_,                                 \
182295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            cubic_to_,                                 \
183295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            shift_,                                    \
184295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            delta_                                     \
185295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         };
186295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
187295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_,            \
188295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                raster_new_, raster_reset_,       \
189295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                raster_set_mode_, raster_render_, \
190295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                raster_done_ )                    \
191295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          const FT_Raster_Funcs class_ =                          \
192295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          {                                                       \
193295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            glyph_format_,                                        \
194295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_new_,                                          \
195295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_reset_,                                        \
196295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_set_mode_,                                     \
197295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_render_,                                       \
198295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_done_                                          \
199295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         };
200295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !_STANDALONE_ */
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftgrays.h"
206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_OUTLINE_H
209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftsmerrs.h"
211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
212295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "ftspic.h"
213295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Mode      Smooth_Err_Cannot_Render_Glyph
215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Outline   Smooth_Err_Invalid_Outline
216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Memory_Overflow   Smooth_Err_Out_Of_Memory
2170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define ErrRaster_Invalid_Argument  Smooth_Err_Invalid_Argument
218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* !_STANDALONE_ */
220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_MEM_SET
222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_MEM_SET( d, s, c )  ft_memset( d, s, c )
223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_MEM_ZERO
226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_MEM_ZERO( dest, count )  FT_MEM_SET( dest, 0, count )
227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* as usual, for the speed hungry :-) */
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_STATIC_RASTER
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_ARG   PWorker  worker
234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_ARG_  PWorker  worker,
235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR   worker
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR_  worker,
238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* FT_STATIC_RASTER */
240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_ARG   /* empty */
242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_ARG_  /* empty */
243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR   /* empty */
244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR_  /* empty */
245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* FT_STATIC_RASTER */
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* must be at least 6 bits! */
250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define PIXEL_BITS  8
251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ONE_PIXEL       ( 1L << PIXEL_BITS )
253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define PIXEL_MASK      ( -1L << PIXEL_BITS )
254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TRUNC( x )      ( (TCoord)( (x) >> PIXEL_BITS ) )
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define SUBPIXELS( x )  ( (TPos)(x) << PIXEL_BITS )
256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FLOOR( x )      ( (x) & -ONE_PIXEL )
257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define CEILING( x )    ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ROUND( x )      ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if PIXEL_BITS >= 6
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define UPSCALE( x )    ( (x) << ( PIXEL_BITS - 6 ) )
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define DOWNSCALE( x )  ( (x) >> ( PIXEL_BITS - 6 ) )
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define UPSCALE( x )    ( (x) >> ( 6 - PIXEL_BITS ) )
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define DOWNSCALE( x )  ( (x) << ( 6 - PIXEL_BITS ) )
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   TYPE DEFINITIONS                                                    */
272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* don't change the following types to FT_Int or FT_Pos, since we might */
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* need to define them to "float" or "double" when experimenting with   */
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* new algorithms                                                       */
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
278295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  typedef long  TCoord;   /* integer scanline/pixel coordinate */
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef long  TPos;     /* sub-pixel coordinate              */
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* determine the type used to store cell areas.  This normally takes at */
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* least PIXEL_BITS*2 + 1 bits.  On 16-bit systems, we need to use      */
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* `long' instead of `int', otherwise bad things happen                 */
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if PIXEL_BITS <= 7
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef int  TArea;
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* PIXEL_BITS >= 8 */
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* approximately determine the size of integers using an ANSI-C header */
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if FT_UINT_MAX == 0xFFFFU
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef long  TArea;
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef int   TArea;
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* PIXEL_BITS >= 8 */
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* maximal number of gray spans in a call to the span callback */
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_MAX_GRAY_SPANS  32
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct TCell_*  PCell;
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  TCell_
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
309295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TPos   x;     /* same with TWorker.ex */
310295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TCoord cover; /* same with TWorker.cover */
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TArea  area;
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PCell  next;
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } TCell;
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  TWorker_
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TCoord  ex, ey;
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    min_ex, max_ex;
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    min_ey, max_ey;
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    count_ex, count_ey;
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TArea   area;
325295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TCoord  cover;
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int     invalid;
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PCell   cells;
329295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_PtrDist  max_cells;
330295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_PtrDist  num_cells;
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TCoord  cx, cy;
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    x,  y;
334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    last_ey;
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector   bez_stack[32 * 3 + 1];
338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int         lev_stack[32];
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline  outline;
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bitmap   target;
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_BBox     clip_box;
343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Span     gray_spans[FT_MAX_GRAY_SPANS];
345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int         num_gray_spans;
346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Raster_Span_Func  render_span;
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*                render_span_data;
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int                  span_y;
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int  band_size;
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int  band_shoot;
353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int  conic_level;
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int  cubic_level;
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_jmp_buf  jump_buffer;
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*       buffer;
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    long        buffer_size;
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PCell*     ycells;
362295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TPos       ycount;
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } TWorker, *PWorker;
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
367295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifndef FT_STATIC_RASTER
368295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define ras  (*worker)
369295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#else
370295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  static TWorker  ras;
371295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
372295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
373295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct TRaster_
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*    buffer;
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    long     buffer_size;
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int      band_size;
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*    memory;
380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PWorker  worker;
381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } TRaster, *PRaster;
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Initialize the cells table.                                           */
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_init_cells( RAS_ARG_ void*  buffer,
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   long            byte_size )
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.buffer      = buffer;
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.buffer_size = byte_size;
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.ycells      = (PCell*) buffer;
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cells       = NULL;
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.max_cells   = 0;
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.num_cells   = 0;
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.area        = 0;
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cover       = 0;
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.invalid     = 1;
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Compute the outline bounding box.                                     */
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_compute_cbox( RAS_ARG )
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline*  outline = &ras.outline;
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*   vec     = outline->points;
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*   limit   = vec + outline->n_points;
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( outline->n_points <= 0 )
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.min_ex = ras.max_ex = 0;
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.min_ey = ras.max_ey = 0;
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.min_ex = ras.max_ex = vec->x;
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.min_ey = ras.max_ey = vec->y;
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vec++;
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; vec < limit; vec++ )
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TPos  x = vec->x;
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TPos  y = vec->y;
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( x < ras.min_ex ) ras.min_ex = x;
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( x > ras.max_ex ) ras.max_ex = x;
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( y < ras.min_ey ) ras.min_ey = y;
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( y > ras.max_ey ) ras.max_ey = y;
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* truncate the bounding box to integer pixels */
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.min_ex = ras.min_ex >> 6;
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.min_ey = ras.min_ey >> 6;
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.max_ex = ( ras.max_ex + 63 ) >> 6;
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.max_ey = ( ras.max_ey + 63 ) >> 6;
448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Record the current cell in the table.                                 */
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static PCell
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_find_cell( RAS_ARG )
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PCell  *pcell, cell;
459295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TPos    x = ras.ex;
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( x > ras.count_ex )
4630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      x = ras.count_ex;
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    pcell = &ras.ycells[ras.ey];
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for (;;)
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cell = *pcell;
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cell == NULL || cell->x > x )
470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cell->x == x )
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pcell = &cell->next;
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.num_cells >= ras.max_cells )
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_longjmp( ras.jump_buffer, 1 );
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell        = ras.cells + ras.num_cells++;
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell->x     = x;
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell->area  = 0;
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell->cover = 0;
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell->next  = *pcell;
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *pcell      = cell;
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return cell;
491049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_record_cell( RAS_ARG )
496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !ras.invalid && ( ras.area | ras.cover ) )
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      PCell  cell = gray_find_cell( RAS_VAR );
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cell->area  += ras.area;
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cell->cover += ras.cover;
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
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  /* Set the current cell to a new position.                               */
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_set_cell( RAS_ARG_ TCoord  ex,
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          TCoord  ey )
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Move the cell pointer to a new position.  We set the `invalid'      */
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* flag to indicate that the cell isn't part of those we're interested */
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* in during the render phase.  This means that:                       */
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* . the new vertical position must be within min_ey..max_ey-1.        */
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* . the new horizontal position must be strictly less than max_ex     */
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Note that if a cell is to the left of the clipping region, it is    */
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* actually set to the (min_ex-1) horizontal position.                 */
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* All cells that are on the left of the clipping region go to the */
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* min_ex - 1 horizontal position.                                 */
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ey -= ras.min_ey;
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex > ras.max_ex )
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ex = ras.max_ex;
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ex -= ras.min_ex;
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex < 0 )
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ex = -1;
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* are we moving to a different cell ? */
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex != ras.ex || ey != ras.ey )
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* record the current one if it is valid */
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !ras.invalid )
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_record_cell( RAS_VAR );
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.area  = 0;
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.cover = 0;
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.ex      = ex;
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.ey      = ey;
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.invalid = ( (unsigned)ey >= (unsigned)ras.count_ey ||
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              ex >= ras.count_ex           );
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Start a new contour at a given cell.                                  */
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_start_cell( RAS_ARG_ TCoord  ex,
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                            TCoord  ey )
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex > ras.max_ex )
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ex = (TCoord)( ras.max_ex );
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex < ras.min_ex )
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ex = (TCoord)( ras.min_ex - 1 );
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.area    = 0;
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cover   = 0;
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.ex      = ex - ras.min_ex;
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.ey      = ey - ras.min_ey;
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.last_ey = SUBPIXELS( ey );
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.invalid = 0;
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_set_cell( RAS_VAR_ ex, ey );
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Render a scanline as one or more cells.                               */
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_scanline( RAS_ARG_ TCoord  ey,
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TPos    x1,
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TCoord  y1,
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TPos    x2,
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TCoord  y2 )
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
591295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TCoord  ex1, ex2, fx1, fx2, delta, mod, lift, rem;
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    long    p, first, dx;
593295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    int     incr;
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dx = x2 - x1;
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ex1 = TRUNC( x1 );
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ex2 = TRUNC( x2 );
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fx1 = (TCoord)( x1 - SUBPIXELS( ex1 ) );
601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fx2 = (TCoord)( x2 - SUBPIXELS( ex2 ) );
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* trivial case.  Happens often */
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( y1 == y2 )
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_set_cell( RAS_VAR_ ex2, ey );
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* everything is located in a single cell.  That is easy! */
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                        */
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex1 == ex2 )
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta      = y2 - y1;
615295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      ras.area  += (TArea)(( fx1 + fx2 ) * delta);
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.cover += delta;
617049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* ok, we'll have to render a run of adjacent cells on the same */
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* scanline...                                                  */
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                              */
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p     = ( ONE_PIXEL - fx1 ) * ( y2 - y1 );
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = ONE_PIXEL;
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    incr  = 1;
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx < 0 )
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p     = fx1 * ( y2 - y1 );
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      first = 0;
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      incr  = -1;
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx    = -dx;
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    delta = (TCoord)( p / dx );
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    mod   = (TCoord)( p % dx );
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( mod < 0 )
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta--;
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mod += (TCoord)dx;
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
643295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    ras.area  += (TArea)(( fx1 + first ) * delta);
644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cover += delta;
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ex1 += incr;
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_set_cell( RAS_VAR_ ex1, ey );
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y1  += delta;
649049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex1 != ex2 )
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p    = ONE_PIXEL * ( y2 - y1 + delta );
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      lift = (TCoord)( p / dx );
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      rem  = (TCoord)( p % dx );
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( rem < 0 )
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        lift--;
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rem += (TCoord)dx;
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mod -= (int)dx;
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( ex1 != ex2 )
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        delta = lift;
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mod  += rem;
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( mod >= 0 )
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          mod -= (TCoord)dx;
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          delta++;
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
673295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        ras.area  += (TArea)(ONE_PIXEL * delta);
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.cover += delta;
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y1        += delta;
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ex1       += incr;
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_set_cell( RAS_VAR_ ex1, ey );
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
681049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    delta      = y2 - y1;
682295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    ras.area  += (TArea)(( fx2 + ONE_PIXEL - first ) * delta);
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cover += delta;
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Render a given line as a series of scanlines.                         */
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_line( RAS_ARG_ TPos  to_x,
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             TPos  to_y )
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
695295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TCoord  ey1, ey2, fy1, fy2, mod;
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    dx, dy, x, x2;
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    long    p, first;
698295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    int     delta, rem, lift, incr;
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
701049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ey1 = TRUNC( ras.last_ey );
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ey2 = TRUNC( to_y );     /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fy1 = (TCoord)( ras.y - ras.last_ey );
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dx = to_x - ras.x;
707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dy = to_y - ras.y;
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* XXX: we should do something about the trivial case where dx == 0, */
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*      as it happens very often!                                    */
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* perform vertical clipping */
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  min, max;
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      min = ey1;
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      max = ey2;
719049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ey1 > ey2 )
720049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        min = ey2;
722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        max = ey1;
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( min >= ras.max_ey || max < ras.min_ey )
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto End;
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* everything is on a single scanline */
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ey1 == ey2 )
730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 );
732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto End;
733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* vertical line - avoid calling gray_render_scanline */
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    incr = 1;
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx == 0 )
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  ex     = TRUNC( ras.x );
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 );
742295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      TArea   area;
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      first = ONE_PIXEL;
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( dy < 0 )
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        first = 0;
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        incr  = -1;
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta      = (int)( first - fy1 );
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.area  += (TArea)two_fx * delta;
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.cover += delta;
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ey1       += incr;
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
757295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      gray_set_cell( RAS_VAR_ ex, ey1 );
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta = (int)( first + first - ONE_PIXEL );
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      area  = (TArea)two_fx * delta;
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( ey1 != ey2 )
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.area  += area;
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.cover += delta;
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ey1       += incr;
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
767295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        gray_set_cell( RAS_VAR_ ex, ey1 );
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta      = (int)( fy2 - ONE_PIXEL + first );
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.area  += (TArea)two_fx * delta;
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.cover += delta;
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto End;
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* ok, we have to render several scanlines */
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p     = ( ONE_PIXEL - fy1 ) * dx;
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = ONE_PIXEL;
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    incr  = 1;
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dy < 0 )
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p     = fy1 * dx;
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      first = 0;
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      incr  = -1;
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dy    = -dy;
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    delta = (int)( p / dy );
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    mod   = (int)( p % dy );
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( mod < 0 )
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      delta--;
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mod += (TCoord)dy;
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = ras.x + delta;
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, (TCoord)first );
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ey1 += incr;
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ey1 != ey2 )
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p     = ONE_PIXEL * dx;
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      lift  = (int)( p / dy );
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      rem   = (int)( p % dy );
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( rem < 0 )
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        lift--;
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rem += (int)dy;
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mod -= (int)dy;
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( ey1 != ey2 )
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        delta = lift;
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mod  += rem;
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( mod >= 0 )
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          mod -= (int)dy;
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          delta++;
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x2 = x + delta;
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_render_scanline( RAS_VAR_ ey1, x,
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       (TCoord)( ONE_PIXEL - first ), x2,
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                       (TCoord)first );
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x = x2;
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ey1 += incr;
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_render_scanline( RAS_VAR_ ey1, x,
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   (TCoord)( ONE_PIXEL - first ), to_x,
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                   fy2 );
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  End:
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.x       = to_x;
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.y       = to_y;
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.last_ey = SUBPIXELS( ey2 );
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_split_conic( FT_Vector*  base )
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos  a, b;
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].x = base[2].x;
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].x;
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    a = base[3].x = ( base[2].x + b ) / 2;
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].x = ( base[0].x + b ) / 2;
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].x = ( a + b ) / 2;
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].y = base[2].y;
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].y;
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    a = base[3].y = ( base[2].y + b ) / 2;
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].y = ( base[0].y + b ) / 2;
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].y = ( a + b ) / 2;
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_conic( RAS_ARG_ const FT_Vector*  control,
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const FT_Vector*  to )
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos        dx, dy;
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int         top, level;
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int*        levels;
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*  arc;
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dx = DOWNSCALE( ras.x ) + to->x - ( control->x << 1 );
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx < 0 )
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx = -dx;
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dy = DOWNSCALE( ras.y ) + to->y - ( control->y << 1 );
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dy < 0 )
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dy = -dy;
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx < dy )
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx = dy;
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    level = 1;
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dx = dx / ras.conic_level;
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( dx > 0 )
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx >>= 2;
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      level++;
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* a shortcut to speed things up */
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( level <= 1 )
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we compute the mid-point directly in order to avoid */
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* calling gray_split_conic()                          */
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TPos  to_x, to_y, mid_x, mid_y;
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      to_x  = UPSCALE( to->x );
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      to_y  = UPSCALE( to->y );
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mid_x = ( ras.x + to_x + 2 * UPSCALE( control->x ) ) / 4;
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mid_y = ( ras.y + to_y + 2 * UPSCALE( control->y ) ) / 4;
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_render_line( RAS_VAR_ mid_x, mid_y );
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_render_line( RAS_VAR_ to_x, to_y );
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc       = ras.bez_stack;
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    levels    = ras.lev_stack;
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top       = 0;
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    levels[0] = level;
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[0].x = UPSCALE( to->x );
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[0].y = UPSCALE( to->y );
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[1].x = UPSCALE( control->x );
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[1].y = UPSCALE( control->y );
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[2].x = ras.x;
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[2].y = ras.y;
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( top >= 0 )
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      level = levels[top];
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( level > 1 )
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* check that the arc crosses the current band */
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TPos  min, max, y;
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        min = max = arc[0].y;
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = arc[1].y;
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y < min ) min = y;
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y > max ) max = y;
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = arc[2].y;
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y < min ) min = y;
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y > max ) max = y;
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < ras.min_ey )
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Draw;
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_split_conic( arc );
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        arc += 2;
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        top++;
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        levels[top] = levels[top - 1] = level - 1;
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Draw:
956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TPos  to_x, to_y, mid_x, mid_y;
958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        to_x  = arc[0].x;
961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        to_y  = arc[0].y;
962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mid_x = ( ras.x + to_x + 2 * arc[1].x ) / 4;
963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mid_y = ( ras.y + to_y + 2 * arc[1].y ) / 4;
964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_render_line( RAS_VAR_ mid_x, mid_y );
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_render_line( RAS_VAR_ to_x, to_y );
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        top--;
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        arc -= 2;
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return;
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_split_cubic( FT_Vector*  base )
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos  a, b, c, d;
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[6].x = base[3].x;
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = base[1].x;
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    d = base[2].x;
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[1].x = a = ( base[0].x + c ) / 2;
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[5].x = b = ( base[3].x + d ) / 2;
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = ( c + d ) / 2;
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].x = a = ( a + c ) / 2;
990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].x = b = ( b + c ) / 2;
991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[3].x = ( a + b ) / 2;
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[6].y = base[3].y;
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = base[1].y;
995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    d = base[2].y;
996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[1].y = a = ( base[0].y + c ) / 2;
997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[5].y = b = ( base[3].y + d ) / 2;
998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = ( c + d ) / 2;
999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].y = a = ( a + c ) / 2;
1000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].y = b = ( b + c ) / 2;
1001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[3].y = ( a + b ) / 2;
1002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_cubic( RAS_ARG_ const FT_Vector*  control1,
1007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const FT_Vector*  control2,
1008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const FT_Vector*  to )
1009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos        dx, dy, da, db;
1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int         top, level;
1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int*        levels;
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*  arc;
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dx = DOWNSCALE( ras.x ) + to->x - ( control1->x << 1 );
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx < 0 )
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx = -dx;
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dy = DOWNSCALE( ras.y ) + to->y - ( control1->y << 1 );
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dy < 0 )
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dy = -dy;
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx < dy )
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx = dy;
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    da = dx;
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dx = DOWNSCALE( ras.x ) + to->x - 3 * ( control1->x + control2->x );
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx < 0 )
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx = -dx;
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    dy = DOWNSCALE( ras.y ) + to->y - 3 * ( control1->x + control2->y );
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dy < 0 )
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dy = -dy;
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx < dy )
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx = dy;
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    db = dx;
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    level = 1;
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    da    = da / ras.cubic_level;
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    db    = db / ras.conic_level;
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( da > 0 || db > 0 )
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      da >>= 2;
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      db >>= 3;
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      level++;
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( level <= 1 )
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TPos   to_x, to_y, mid_x, mid_y;
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      to_x  = UPSCALE( to->x );
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      to_y  = UPSCALE( to->y );
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mid_x = ( ras.x + to_x +
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                3 * UPSCALE( control1->x + control2->x ) ) / 8;
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      mid_y = ( ras.y + to_y +
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                3 * UPSCALE( control1->y + control2->y ) ) / 8;
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_render_line( RAS_VAR_ mid_x, mid_y );
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_render_line( RAS_VAR_ to_x, to_y );
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc      = ras.bez_stack;
1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[0].x = UPSCALE( to->x );
1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[0].y = UPSCALE( to->y );
1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[1].x = UPSCALE( control2->x );
1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[1].y = UPSCALE( control2->y );
1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[2].x = UPSCALE( control1->x );
1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[2].y = UPSCALE( control1->y );
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[3].x = ras.x;
1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[3].y = ras.y;
1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    levels    = ras.lev_stack;
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    top       = 0;
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    levels[0] = level;
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    while ( top >= 0 )
1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      level = levels[top];
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( level > 1 )
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* check that the arc crosses the current band */
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TPos  min, max, y;
1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        min = max = arc[0].y;
1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = arc[1].y;
1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y < min ) min = y;
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y > max ) max = y;
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = arc[2].y;
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y < min ) min = y;
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y > max ) max = y;
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y = arc[3].y;
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y < min ) min = y;
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( y > max ) max = y;
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( TRUNC( min ) >= ras.max_ey || TRUNC( max ) < 0 )
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          goto Draw;
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_split_cubic( arc );
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        arc += 3;
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        top ++;
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        levels[top] = levels[top - 1] = level - 1;
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        continue;
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    Draw:
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TPos  to_x, to_y, mid_x, mid_y;
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1109049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        to_x  = arc[0].x;
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        to_y  = arc[0].y;
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mid_x = ( ras.x + to_x + 3 * ( arc[1].x + arc[2].x ) ) / 8;
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mid_y = ( ras.y + to_y + 3 * ( arc[1].y + arc[2].y ) ) / 8;
1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_render_line( RAS_VAR_ mid_x, mid_y );
1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_render_line( RAS_VAR_ to_x, to_y );
1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        top --;
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        arc -= 3;
1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return;
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_move_to( const FT_Vector*  to,
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                PWorker           worker )
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos  x, y;
1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* record current cell, if any */
1135295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_record_cell( RAS_VAR );
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* start to a new position */
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = UPSCALE( to->x );
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y = UPSCALE( to->y );
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1141295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_start_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) );
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    worker->x = x;
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    worker->y = y;
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_line_to( const FT_Vector*  to,
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                PWorker           worker )
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1153295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_conic_to( const FT_Vector*  control,
1160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Vector*  to,
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 PWorker           worker )
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1163295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_render_conic( RAS_VAR_ control, to );
1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_cubic_to( const FT_Vector*  control1,
1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Vector*  control2,
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Vector*  to,
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 PWorker           worker )
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1174295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_render_cubic( RAS_VAR_ control1, control2, to );
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_span( int             y,
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    int             count,
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    const FT_Span*  spans,
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    PWorker         worker )
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    unsigned char*  p;
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Bitmap*      map = &worker->target;
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* first of all, compute the scanline offset */
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    p = (unsigned char*)map->buffer - y * map->pitch;
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( map->pitch >= 0 )
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p += ( map->rows - 1 ) * map->pitch;
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( ; count > 0; count--, spans++ )
1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1196049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      unsigned char  coverage = spans->coverage;
1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( coverage )
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* For small-spans it is faster to do it by ourselves than
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         * calling `memset'.  This is mainly due to the cost of the
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         * function call.
1204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         */
1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( spans->len >= 8 )
1206049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          FT_MEM_SET( p + spans->x, (unsigned char)coverage, spans->len );
1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          unsigned char*  q = p + spans->x;
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          switch ( spans->len )
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 7: *q++ = (unsigned char)coverage;
1215049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 6: *q++ = (unsigned char)coverage;
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 5: *q++ = (unsigned char)coverage;
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 4: *q++ = (unsigned char)coverage;
1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 3: *q++ = (unsigned char)coverage;
1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 2: *q++ = (unsigned char)coverage;
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          case 1: *q   = (unsigned char)coverage;
1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          default:
1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ;
1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_hline( RAS_ARG_ TCoord  x,
1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       TCoord  y,
1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       TPos    area,
1234295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                       TCoord  acount )
1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Span*  span;
1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int       count;
1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int       coverage;
1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute the coverage line's coverage, depending on the    */
1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* outline fill rule                                         */
1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                           */
1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */
1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                           */
1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) );
1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    /* use range 0..256 */
1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( coverage < 0 )
1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      coverage = -coverage;
1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL )
1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      coverage &= 511;
1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( coverage > 256 )
1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        coverage = 512 - coverage;
1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( coverage == 256 )
1258049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        coverage = 255;
1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1260049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* normal non-zero winding rule */
1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( coverage >= 256 )
1264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        coverage = 255;
1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y += (TCoord)ras.min_ey;
1268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x += (TCoord)ras.min_ex;
1269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* FT_Span.x is a 16-bit short, so limit our coordinates appropriately */
12710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( x >= 32767 )
1272049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x = 32767;
1273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1274295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* FT_Span.y is an integer, so limit our coordinates appropriately */
1275295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    if ( y >= FT_INT_MAX )
1276295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      y = FT_INT_MAX;
1277295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
1278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( coverage )
1279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* see whether we can add this span to the current list */
1281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      count = ras.num_gray_spans;
1282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      span  = ras.gray_spans + count - 1;
1283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( count > 0                          &&
1284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ras.span_y == y                    &&
1285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           (int)span->x + span->len == (int)x &&
1286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           span->coverage == coverage         )
1287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        span->len = (unsigned short)( span->len + acount );
1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return;
1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ras.span_y != y || count >= FT_MAX_GRAY_SPANS )
1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( ras.render_span && count > 0 )
1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.render_span( ras.span_y, count, ras.gray_spans,
1296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                           ras.render_span_data );
1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
12980a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
1299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        if ( count > 0 )
1301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          int  n;
1303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_TRACE7(( "y = %3d ", ras.span_y ));
1306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          span = ras.gray_spans;
1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( n = 0; n < count; n++, span++ )
13080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_TRACE7(( "[%d..%d]:%02x ",
13090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        span->x, span->x + span->len - 1, span->coverage ));
13100a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_TRACE7(( "\n" ));
1311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13130a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* FT_DEBUG_LEVEL_TRACE */
1314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.num_gray_spans = 0;
1316295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        ras.span_y         = (int)y;
1317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        count = 0;
1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        span  = ras.gray_spans;
1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        span++;
1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* add a gray span to the current list */
1325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      span->x        = (short)x;
1326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      span->len      = (unsigned short)acount;
1327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      span->coverage = (unsigned char)coverage;
1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.num_gray_spans++;
1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
1335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* to be called while in the debugger --                                */
13370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* this function causes a compiler warning since it is unused otherwise */
13380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  static void
1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_dump_cells( RAS_ARG )
1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int  yindex;
1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( yindex = 0; yindex < ras.ycount; yindex++ )
1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1346049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      PCell  cell;
1347049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      printf( "%3d:", yindex );
1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( cell = ras.ycells[yindex]; cell != NULL; cell = cell->next )
1352295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        printf( " (%3ld, c:%4ld, a:%6d)", cell->x, cell->cover, cell->area );
1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      printf( "\n" );
1354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* FT_DEBUG_LEVEL_TRACE */
1358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_sweep( RAS_ARG_ const FT_Bitmap*  target )
1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int  yindex;
1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( target );
1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.num_cells == 0 )
1369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
1370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.num_gray_spans = 0;
1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE7(( "gray_sweep: start\n" ));
13740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( yindex = 0; yindex < ras.ycount; yindex++ )
1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      PCell   cell  = ras.ycells[yindex];
1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  cover = 0;
1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  x     = 0;
1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; cell != NULL; cell = cell->next )
1383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1384295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        TPos  area;
1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( cell->x > x && cover != 0 )
1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
1389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      cell->x - x );
1390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        cover += cell->cover;
1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        area   = cover * ( ONE_PIXEL * 2 ) - cell->area;
1393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( area != 0 && cell->x >= 0 )
1395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          gray_hline( RAS_VAR_ cell->x, yindex, area, 1 );
1396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x = cell->x + 1;
1398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cover != 0 )
1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_hline( RAS_VAR_ x, yindex, cover * ( ONE_PIXEL * 2 ),
1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                    ras.count_ex - x );
1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.render_span && ras.num_gray_spans > 0 )
1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.render_span( ras.span_y, ras.num_gray_spans,
1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       ras.gray_spans, ras.render_span_data );
14080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
14090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE7(( "gray_sweep: end\n" ));
1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef _STANDALONE_
1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
14170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*  The following function should only compile in stand-alone mode,      */
1418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*  i.e., when building this component without the rest of FreeType.     */
1419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FT_Outline_Decompose                                               */
1426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
14280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*    Walk over an outline's structure to decompose it into individual   */
14290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*    segments and Bézier arcs.  This function is also able to emit      */
1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    `move to' and `close to' operations to indicate the start and end  */
1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    of new contours in the outline.                                    */
1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    outline        :: A pointer to the source target.                  */
1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
14360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*    func_interface :: A table of `emitters', i.e., function pointers   */
1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      called during decomposition to indicate path     */
1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      operations.                                      */
1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
14400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* <InOut>                                                               */
1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    user           :: A typeless pointer which is passed to each       */
1442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      emitter during the decomposition.  It can be     */
1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      used to store the state during the               */
1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      decomposition.                                   */
1445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Error code.  0 means success.                                      */
1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
14490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  static int
14500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_Outline_Decompose( const FT_Outline*        outline,
14510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        const FT_Outline_Funcs*  func_interface,
14520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        void*                    user )
1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef SCALED
1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define SCALED( x )  ( ( (x) << shift ) - delta )
1456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector   v_last;
1458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector   v_control;
1459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector   v_start;
1460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*  point;
1462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*  limit;
1463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    char*       tags;
1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    int         error;
14660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int   n;         /* index of contour in outline     */
1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int   first;     /* index of first point in contour */
1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    char  tag;       /* current point's state           */
1470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    int   shift;
14720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    TPos  delta;
1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14750a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !outline || !func_interface )
14760a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      return ErrRaster_Invalid_Argument;
14770a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
14780a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    shift = func_interface->shift;
14790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    delta = func_interface->delta;
1480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = 0;
1481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( n = 0; n < outline->n_contours; n++ )
1483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      int  last;  /* index of last point in contour */
1485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));
14880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      last  = outline->contours[n];
14900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( last < 0 )
14910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        goto Invalid_Outline;
1492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      limit = outline->points + last;
1493049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_start   = outline->points[first];
1495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v_start.x = SCALED( v_start.x );
1496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v_start.y = SCALED( v_start.y );
1497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14980a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_last   = outline->points[last];
14990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_last.x = SCALED( v_last.x );
15000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_last.y = SCALED( v_last.y );
1501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v_control = v_start;
1503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      point = outline->points + first;
15050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      tags  = outline->tags   + first;
1506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      tag   = FT_CURVE_TAG( tags[0] );
1507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* A contour cannot start with a cubic control point! */
1509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( tag == FT_CURVE_TAG_CUBIC )
1510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Invalid_Outline;
1511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check first point to determine origin */
1513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( tag == FT_CURVE_TAG_CONIC )
1514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* first point is conic control.  Yes, this happens. */
1516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )
1517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* start at last point if it is on the curve */
1519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_start = v_last;
1520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          limit--;
1521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
1523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* if both first and last points are conic,         */
1525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* start at their middle and record its position    */
1526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* for closure                                      */
1527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_start.x = ( v_start.x + v_last.x ) / 2;
1528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_start.y = ( v_start.y + v_last.y ) / 2;
1529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_last = v_start;
1531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        point--;
1533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        tags--;
1534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE5(( "  move to (%.2f, %.2f)\n",
15370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                  v_start.x / 64.0, v_start.y / 64.0 ));
1538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = func_interface->move_to( &v_start, user );
1539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( point < limit )
1543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        point++;
1545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        tags++;
1546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        tag = FT_CURVE_TAG( tags[0] );
1548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        switch ( tag )
1549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case FT_CURVE_TAG_ON:  /* emit a single line_to */
1551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Vector  vec;
1553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec.x = SCALED( point->x );
1556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec.y = SCALED( point->y );
1557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_TRACE5(( "  line to (%.2f, %.2f)\n",
15590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        vec.x / 64.0, vec.y / 64.0 ));
1560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            error = func_interface->line_to( &vec, user );
1561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( error )
1562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Exit;
1563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            continue;
1564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case FT_CURVE_TAG_CONIC:  /* consume conic arcs */
15670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          v_control.x = SCALED( point->x );
15680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          v_control.y = SCALED( point->y );
1569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        Do_Conic:
15710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          if ( point < limit )
15720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          {
15730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_Vector  vec;
15740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_Vector  v_middle;
1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15770a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            point++;
15780a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            tags++;
15790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            tag = FT_CURVE_TAG( tags[0] );
1580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15810a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            vec.x = SCALED( point->x );
15820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            vec.y = SCALED( point->y );
1583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            if ( tag == FT_CURVE_TAG_ON )
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                          vec.x / 64.0, vec.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, &vec, user );
1591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( error )
1592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
15930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              continue;
1594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15960a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            if ( tag != FT_CURVE_TAG_CONIC )
15970a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              goto Invalid_Outline;
15980a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
15990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            v_middle.x = ( v_control.x + vec.x ) / 2;
16000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            v_middle.y = ( v_control.y + vec.y ) / 2;
16010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
16020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_TRACE5(( "  conic to (%.2f, %.2f)"
16030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        " with control (%.2f, %.2f)\n",
16040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        v_middle.x / 64.0, v_middle.y / 64.0,
16050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        v_control.x / 64.0, v_control.y / 64.0 ));
16060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            error = func_interface->conic_to( &v_control, &v_middle, user );
16070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            if ( error )
16080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              goto Exit;
16090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
16100a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            v_control = vec;
16110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            goto Do_Conic;
1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
16140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_TRACE5(( "  conic to (%.2f, %.2f)"
16150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      " with control (%.2f, %.2f)\n",
16160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      v_start.x / 64.0, v_start.y / 64.0,
16170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      v_control.x / 64.0, v_control.y / 64.0 ));
16180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          error = func_interface->conic_to( &v_control, &v_start, user );
16190a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          goto Close;
16200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        default:  /* FT_CURVE_TAG_CUBIC */
1622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Vector  vec1, vec2;
1624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( point + 1 > limit                             ||
1627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
1628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Invalid_Outline;
1629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            point += 2;
1631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tags  += 2;
1632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec1.x = SCALED( point[-2].x );
1634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec1.y = SCALED( point[-2].y );
1635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec2.x = SCALED( point[-1].x );
1637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec2.y = SCALED( point[-1].y );
1638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( point <= limit )
1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
1641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_Vector  vec;
1642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              vec.x = SCALED( point->x );
1645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              vec.y = SCALED( point->y );
1646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
16470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              FT_TRACE5(( "  cubic to (%.2f, %.2f)"
16480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
16490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          vec.x / 64.0, vec.y / 64.0,
16500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          vec1.x / 64.0, vec1.y / 64.0,
16510a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          vec2.x / 64.0, vec2.y / 64.0 ));
1652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              error = func_interface->cubic_to( &vec1, &vec2, &vec, user );
1653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( error )
1654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
1655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              continue;
1656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
16580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_TRACE5(( "  cubic to (%.2f, %.2f)"
16590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
16600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        v_start.x / 64.0, v_start.y / 64.0,
16610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        vec1.x / 64.0, vec1.y / 64.0,
16620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        vec2.x / 64.0, vec2.y / 64.0 ));
1663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );
1664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Close;
1665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* close the contour with a line segment */
16700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE5(( "  line to (%.2f, %.2f)\n",
16710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                  v_start.x / 64.0, v_start.y / 64.0 ));
1672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = func_interface->line_to( &v_start, user );
1673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   Close:
1675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      first = last + 1;
1679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
16810a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
1682049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
16850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE5(( "FT_Outline_Decompose: Error %d\n", error ));
1686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Invalid_Outline:
1689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ErrRaster_Invalid_Outline;
1690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* _STANDALONE_ */
1693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  TBand_
1696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos  min, max;
1698049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } TBand;
1700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1701295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_DEFINE_OUTLINE_FUNCS(func_interface,
1702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (FT_Outline_MoveTo_Func) gray_move_to,
1703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (FT_Outline_LineTo_Func) gray_line_to,
1704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (FT_Outline_ConicTo_Func)gray_conic_to,
1705049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      (FT_Outline_CubicTo_Func)gray_cubic_to,
1706049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0,
1707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      0
1708295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    )
1709295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
1710295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  static int
1711295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  gray_convert_glyph_inner( RAS_ARG )
1712295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  {
1713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    volatile int  error = 0;
1715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1716295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
1717295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_Outline_Funcs func_interface;
1718295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      Init_Class_func_interface(&func_interface);
1719295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
17200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ft_setjmp( ras.jump_buffer ) == 0 )
1722049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
1724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_record_cell( RAS_VAR );
1725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = ErrRaster_Memory_Overflow;
1728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1730049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1731049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_convert_glyph( RAS_ARG )
1735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TBand            bands[40];
1737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TBand* volatile  band;
1738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int volatile     n, num_bands;
1739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos volatile    min, max, max_y;
1740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_BBox*         clip;
1741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Set up state in the raster object */
1744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_compute_cbox( RAS_VAR );
1745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* clip to target bitmap, exit if nothing to do */
1747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    clip = &ras.clip_box;
1748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.max_ex <= clip->xMin || ras.min_ex >= clip->xMax ||
1750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         ras.max_ey <= clip->yMin || ras.min_ey >= clip->yMax )
1751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
1752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.min_ex < clip->xMin ) ras.min_ex = clip->xMin;
1754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.min_ey < clip->yMin ) ras.min_ey = clip->yMin;
1755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.max_ex > clip->xMax ) ras.max_ex = clip->xMax;
1757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.max_ey > clip->yMax ) ras.max_ey = clip->yMax;
1758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.count_ex = ras.max_ex - ras.min_ex;
1760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.count_ey = ras.max_ey - ras.min_ey;
1761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* simple heuristic used to speed up the bezier decomposition -- see */
1763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the code in gray_render_conic() and gray_render_cubic() for more  */
1764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* details                                                           */
1765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.conic_level = 32;
1766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cubic_level = 16;
1767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
17690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      int  level = 0;
1770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ras.count_ex > 24 || ras.count_ey > 24 )
1773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        level++;
1774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( ras.count_ex > 120 || ras.count_ey > 120 )
1775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        level++;
1776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.conic_level <<= level;
1778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.cubic_level <<= level;
1779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
17810a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* set up vertical bands */
1782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    num_bands = (int)( ( ras.max_ey - ras.min_ey ) / ras.band_size );
17830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( num_bands == 0 )
17840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      num_bands = 1;
17850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( num_bands >= 39 )
17860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      num_bands = 39;
1787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.band_shoot = 0;
1789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    min   = ras.min_ey;
1791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    max_y = ras.max_ey;
1792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( n = 0; n < num_bands; n++, min = max )
1794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      max = min + ras.band_size;
1796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( n == num_bands - 1 || max > max_y )
1797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        max = max_y;
1798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bands[0].min = min;
1800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      bands[0].max = max;
1801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      band         = bands;
1802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( band >= bands )
1804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        TPos  bottom, top, middle;
1806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        int   error;
1807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          PCell  cells_max;
1810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          int    yindex;
1811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          long   cell_start, cell_end, cell_mod;
1812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.ycells = (PCell*)ras.buffer;
1815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.ycount = band->max - band->min;
1816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cell_start = sizeof ( PCell ) * ras.ycount;
1818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cell_mod   = cell_start % sizeof ( TCell );
1819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( cell_mod > 0 )
1820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            cell_start += sizeof ( TCell ) - cell_mod;
1821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cell_end  = ras.buffer_size;
1823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cell_end -= cell_end % sizeof( TCell );
1824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          cells_max = (PCell)( (char*)ras.buffer + cell_end );
1826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.cells = (PCell)( (char*)ras.buffer + cell_start );
1827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( ras.cells >= cells_max )
1828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto ReduceBands;
1829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.max_cells = cells_max - ras.cells;
1831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          if ( ras.max_cells < 2 )
1832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto ReduceBands;
1833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          for ( yindex = 0; yindex < ras.ycount; yindex++ )
1835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            ras.ycells[yindex] = NULL;
1836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.num_cells = 0;
1839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.invalid   = 1;
1840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.min_ey    = band->min;
1841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.max_ey    = band->max;
1842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.count_ey  = band->max - band->min;
1843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = gray_convert_glyph_inner( RAS_VAR );
1845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error )
1847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          gray_sweep( RAS_VAR_ &ras.target );
1849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          band--;
1850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          continue;
1851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( error != ErrRaster_Memory_Overflow )
1853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return 1;
1854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ReduceBands:
1856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* render pool overflow; we will reduce the render band by half */
1857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        bottom = band->min;
1858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        top    = band->max;
1859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        middle = bottom + ( ( top - bottom ) >> 1 );
1860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* This is too complex for a single scanline; there must */
1862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* be some problems.                                     */
1863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( middle == bottom )
1864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
18650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
1866295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
1867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return 1;
1869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( bottom-top >= ras.band_size )
1872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          ras.band_shoot++;
1873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        band[1].min = bottom;
1875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        band[1].max = middle;
1876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        band[0].min = middle;
1877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        band[0].max = top;
1878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        band++;
1879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.band_shoot > 8 && ras.band_size > 16 )
1883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.band_size = ras.band_size / 2;
1884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_render( PRaster                  raster,
1891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      const FT_Raster_Params*  params )
1892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Outline*  outline    = (const FT_Outline*)params->source;
1894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    const FT_Bitmap*   target_map = params->target;
1895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PWorker            worker;
1896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !raster || !raster->buffer || !raster->buffer_size )
1899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ErrRaster_Invalid_Argument;
1900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !outline )
1902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ErrRaster_Invalid_Outline;
1903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* return immediately if the outline is empty */
1905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( outline->n_points == 0 || outline->n_contours <= 0 )
1906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
1907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !outline->contours || !outline->points )
1909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ErrRaster_Invalid_Outline;
1910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( outline->n_points !=
1912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           outline->contours[outline->n_contours - 1] + 1 )
1913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ErrRaster_Invalid_Outline;
1914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    worker = raster->worker;
1916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* if direct mode is not set, we must have a target bitmap */
19180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
1919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !target_map )
1921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return ErrRaster_Invalid_Argument;
1922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* nothing to do */
1924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !target_map->width || !target_map->rows )
1925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return 0;
1926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !target_map->buffer )
1928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return ErrRaster_Invalid_Argument;
1929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* this version does not support monochrome rendering */
1932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !( params->flags & FT_RASTER_FLAG_AA ) )
1933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ErrRaster_Invalid_Mode;
1934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute clipping box */
19360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
1937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* compute clip box from target pixmap */
1939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.xMin = 0;
1940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.yMin = 0;
1941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.xMax = target_map->width;
1942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.yMax = target_map->rows;
1943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( params->flags & FT_RASTER_FLAG_CLIP )
1945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box = params->clip_box;
1946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.xMin = -32768L;
1949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.yMin = -32768L;
1950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.xMax =  32767L;
1951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.clip_box.yMax =  32767L;
1952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1954295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_init_cells( RAS_VAR_ raster->buffer, raster->buffer_size );
1955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.outline        = *outline;
1957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.num_cells      = 0;
1958049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.invalid        = 1;
1959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.band_size      = raster->band_size;
1960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.num_gray_spans = 0;
1961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( params->flags & FT_RASTER_FLAG_DIRECT )
1963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.render_span      = (FT_Raster_Span_Func)params->gray_spans;
1965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.render_span_data = params->user;
1966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
19670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    else
19680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
19690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      ras.target           = *target_map;
19700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      ras.render_span      = (FT_Raster_Span_Func)gray_render_span;
19710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      ras.render_span_data = &ras;
19720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
1973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1974295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    return gray_convert_glyph( RAS_VAR );
1975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19780a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/
19790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /****                         a static object.                   *****/
1980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef _STANDALONE_
1982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_new( void*       memory,
1985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Raster*  araster )
1986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    static TRaster  the_raster;
1988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( memory );
1990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *araster = (FT_Raster)&the_raster;
1993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_MEM_ZERO( &the_raster, sizeof ( the_raster ) );
1994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1995049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
2000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_done( FT_Raster  raster )
2001049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* nothing */
2003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( raster );
2004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2005049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2006049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* _STANDALONE_ */
2007049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
2009049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_new( FT_Memory   memory,
2010049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Raster*  araster )
2011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Error  error;
2013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PRaster   raster;
2014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *araster = 0;
2017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !FT_ALLOC( raster, sizeof ( TRaster ) ) )
2018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      raster->memory = memory;
2020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      *araster = (FT_Raster)raster;
2021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
2024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
2028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_done( FT_Raster  raster )
2029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Memory  memory = (FT_Memory)((PRaster)raster)->memory;
2031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( raster );
2034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* _STANDALONE_ */
2037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
2040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_reset( FT_Raster  raster,
2041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     char*      pool_base,
2042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     long       pool_size )
2043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PRaster  rast = (PRaster)raster;
2045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( raster )
2048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
2049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( pool_base && pool_size >= (long)sizeof ( TWorker ) + 2048 )
2050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        PWorker  worker = (PWorker)pool_base;
2052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->worker      = worker;
2055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->buffer      = pool_base +
2056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              ( ( sizeof ( TWorker ) + sizeof ( TCell ) - 1 ) &
2057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                ~( sizeof ( TCell ) - 1 ) );
2058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->buffer_size = (long)( ( pool_base + pool_size ) -
2059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                    (char*)rast->buffer ) &
2060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                      ~( sizeof ( TCell ) - 1 );
2061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->band_size   = (int)( rast->buffer_size /
2062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                     ( sizeof ( TCell ) * 8 ) );
2063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
2065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
2066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->buffer      = NULL;
2067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->buffer_size = 0;
2068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rast->worker      = NULL;
2069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
2070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
2071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2074295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  FT_DEFINE_RASTER_FUNCS(ft_grays_raster,
2075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GLYPH_FORMAT_OUTLINE,
2076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Raster_New_Func)     gray_raster_new,
2078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Raster_Reset_Func)   gray_raster_reset,
2079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Raster_Set_Mode_Func)0,
2080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Raster_Render_Func)  gray_raster_render,
2081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    (FT_Raster_Done_Func)    gray_raster_done
2082295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  )
2083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
20860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
20870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
20880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* Local Variables: */
20890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* coding: utf-8    */
20900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* End:             */
2091