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/*                                                                         */
7a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin/*  Copyright 2000-2017 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 */
21055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* 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  /*                                                                       */
27055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* - copy `include/freetype/ftimage.h' and `src/smooth/ftgrays.h' to the */
28055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*   same directory                                                      */
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
30055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* - compile `ftgrays' with the STANDALONE_ macro defined, as in         */
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
32055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*     cc -c -DSTANDALONE_ 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
94055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#ifdef STANDALONE_
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
97fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki  /* The size in bytes of the render pool used by the scan-line converter  */
98fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki  /* to do all of its work.                                                */
99fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define FT_RENDER_POOL_SIZE  16384L
100fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
101fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
102727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* Auxiliary macros for token concatenation. */
103727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_ERR_XCAT( x, y )  x ## y
104727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_ERR_CAT( x, y )   FT_ERR_XCAT( x, y )
105727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#define FT_BEGIN_STMNT  do {
1079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#define FT_END_STMNT    } while ( 0 )
1089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
109055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define FT_MIN( a, b )  ( (a) < (b) ? (a) : (b) )
110fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define FT_MAX( a, b )  ( (a) > (b) ? (a) : (b) )
111fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define FT_ABS( a )     ( (a) < 0 ? -(a) : (a) )
112fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
113fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
114fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki  /*
115fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki   *  Approximate sqrt(x*x+y*y) using the `alpha max plus beta min'
116fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki   *  algorithm.  We use alpha = 1, beta = 3/8, giving us results with a
117fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki   *  largest error less than 7% compared to the exact value.
118fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki   */
119fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki#define FT_HYPOT( x, y )                 \
120fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki          ( x = FT_ABS( x ),             \
121fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki            y = FT_ABS( y ),             \
122fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki            x > y ? x + ( 3 * y >> 3 )   \
123fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                  : y + ( 3 * x >> 3 ) )
124fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
125727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
1260a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* define this to dump debugging information */
1270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* #define FT_DEBUG_LEVEL_TRACE */
1280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
1310a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include <stdio.h>
1320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include <stdarg.h>
1330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
135aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich#include <stddef.h>
1360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include <string.h>
137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <setjmp.h>
138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <limits.h>
139055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define FT_CHAR_BIT   CHAR_BIT
140055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define FT_UINT_MAX   UINT_MAX
141055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define FT_INT_MAX    INT_MAX
142055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define FT_ULONG_MAX  ULONG_MAX
143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_memset   memset
145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_setjmp   setjmp
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_longjmp  longjmp
148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ft_jmp_buf  jmp_buf
149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
150aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevichtypedef ptrdiff_t  FT_PtrDist;
151aacb8e1368a883fcbc9fe64fd0e460cef9c9b20cNick Kralevich
152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Mode      -2
154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Outline   -1
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Invalid_Argument  -3
156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Memory_Overflow   -4
157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
158049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_BEGIN_HEADER
159049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_END_HEADER
160049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftimage.h"
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftgrays.h"
163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* This macro is used to indicate that a function parameter is unused. */
166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Its purpose is simply to reduce compiler warnings.  Note also that  */
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* simply defining it as `(void)x' doesn't avoid warnings with certain */
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* ANSI compilers (e.g. LCC).                                          */
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_UNUSED( x )  (x) = (x)
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* we only use level 5 & 7 tracing messages; cf. ftdebug.h */
1730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_DEBUG_LEVEL_TRACE
1750a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1760a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  void
1770a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_Message( const char*  fmt,
1780a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              ... )
1790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  {
1800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    va_list  ap;
1810a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    va_start( ap, fmt );
1840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    vfprintf( stderr, fmt, ap );
1850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    va_end( ap );
1860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  }
1870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
188727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
189727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* empty function useful for setting a breakpoint to catch errors */
190727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  int
191727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_Throw( int          error,
192727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            int          line,
193727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            const char*  file )
194727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
195727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_UNUSED( error );
196727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_UNUSED( line );
197727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_UNUSED( file );
198727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
199727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return 0;
200727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
201727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
202727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* we don't handle tracing levels in stand-alone mode; */
2040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifndef FT_TRACE5
2050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE5( varformat )  FT_Message varformat
2060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
2070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifndef FT_TRACE7
2080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE7( varformat )  FT_Message varformat
2090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif
210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_ERROR
2110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_ERROR( varformat )   FT_Message varformat
212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
214727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_THROW( e )                               \
215727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease          ( FT_Throw( FT_ERR_CAT( ErrRaster, e ),   \
216727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                      __LINE__,                     \
217727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease                      __FILE__ )                  | \
218727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_ERR_CAT( ErrRaster, e )            )
219727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#else /* !FT_DEBUG_LEVEL_TRACE */
2210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
2220a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE5( x )  do { } while ( 0 )     /* nothing */
2230a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_TRACE7( x )  do { } while ( 0 )     /* nothing */
2240a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#define FT_ERROR( x )   do { } while ( 0 )     /* nothing */
225727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define FT_THROW( e )   FT_ERR_CAT( ErrRaster_, e )
226727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
2270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
2280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* !FT_DEBUG_LEVEL_TRACE */
2290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
231295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define FT_DEFINE_OUTLINE_FUNCS( class_,               \
232295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                 move_to_, line_to_,   \
233295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                 conic_to_, cubic_to_, \
234295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                 shift_, delta_ )      \
235295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          static const FT_Outline_Funcs class_ =       \
236295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          {                                            \
237295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            move_to_,                                  \
238295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            line_to_,                                  \
239295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            conic_to_,                                 \
240295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            cubic_to_,                                 \
241295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            shift_,                                    \
242295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            delta_                                     \
243295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         };
2447f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
245295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define FT_DEFINE_RASTER_FUNCS( class_, glyph_format_,            \
246295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                raster_new_, raster_reset_,       \
247295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                raster_set_mode_, raster_render_, \
248295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                                raster_done_ )                    \
249295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          const FT_Raster_Funcs class_ =                          \
250295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          {                                                       \
251295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            glyph_format_,                                        \
252295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_new_,                                          \
253295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_reset_,                                        \
254295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_set_mode_,                                     \
255295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_render_,                                       \
256295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner            raster_done_                                          \
257295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner         };
258295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
259727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
260055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#else /* !STANDALONE_ */
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftgrays.h"
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_OUTLINE_H
268049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include "ftsmerrs.h"
270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
271295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#include "ftspic.h"
272295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
273727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define Smooth_Err_Invalid_Mode     Smooth_Err_Cannot_Render_Glyph
274727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#define Smooth_Err_Memory_Overflow  Smooth_Err_Out_Of_Memory
275049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ErrRaster_Memory_Overflow   Smooth_Err_Out_Of_Memory
276727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
278055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#endif /* !STANDALONE_ */
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
280727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_MEM_SET
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_MEM_SET( d, s, c )  ft_memset( d, s, c )
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_MEM_ZERO
286049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_MEM_ZERO( dest, count )  FT_MEM_SET( dest, 0, count )
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
289a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#ifndef FT_ZERO
290a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#define FT_ZERO( p )  FT_MEM_ZERO( p, sizeof ( *(p) ) )
291a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#endif
292a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* as usual, for the speed hungry :-) */
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
29541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#undef RAS_ARG
29641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#undef RAS_ARG_
29741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#undef RAS_VAR
29841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#undef RAS_VAR_
29941371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifndef FT_STATIC_RASTER
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
30241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#define RAS_ARG   gray_PWorker  worker
30341371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#define RAS_ARG_  gray_PWorker  worker,
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR   worker
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR_  worker,
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* FT_STATIC_RASTER */
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
310055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define RAS_ARG   void
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_ARG_  /* empty */
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR   /* empty */
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define RAS_VAR_  /* empty */
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* FT_STATIC_RASTER */
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* must be at least 6 bits! */
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define PIXEL_BITS  8
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
32141371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#undef FLOOR
32241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#undef CEILING
32341371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#undef TRUNC
32441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier#undef SCALED
32541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
326055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define ONE_PIXEL       ( 1 << PIXEL_BITS )
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define TRUNC( x )      ( (TCoord)( (x) >> PIXEL_BITS ) )
328055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define SUBPIXELS( x )  ( (TPos)(x) * ONE_PIXEL )
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FLOOR( x )      ( (x) & -ONE_PIXEL )
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define CEILING( x )    ( ( (x) + ONE_PIXEL - 1 ) & -ONE_PIXEL )
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define ROUND( x )      ( ( (x) + ONE_PIXEL / 2 ) & -ONE_PIXEL )
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if PIXEL_BITS >= 6
334055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define UPSCALE( x )    ( (x) * ( ONE_PIXEL >> 6 ) )
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define DOWNSCALE( x )  ( (x) >> ( PIXEL_BITS - 6 ) )
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define UPSCALE( x )    ( (x) >> ( 6 - PIXEL_BITS ) )
338055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define DOWNSCALE( x )  ( (x) * ( 64 >> PIXEL_BITS ) )
339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
342ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /* Compute `dividend / divisor' and return both its quotient and     */
343ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /* remainder, cast to a specific type.  This macro also ensures that */
344a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin  /* the remainder is always positive.  We use the remainder to keep   */
345a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin  /* track of accumulating errors and compensate for them.             */
346ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \
347ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  FT_BEGIN_STMNT                                                   \
348ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    (quotient)  = (type)( (dividend) / (divisor) );                \
349ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    (remainder) = (type)( (dividend) % (divisor) );                \
350ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    if ( (remainder) < 0 )                                         \
351ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    {                                                              \
352ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      (quotient)--;                                                \
353ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      (remainder) += (type)(divisor);                              \
354ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    }                                                              \
355ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  FT_END_STMNT
356ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
357ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#ifdef  __arm__
358ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /* Work around a bug specific to GCC which make the compiler fail to */
359ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /* optimize a division and modulo operation on the same parameters   */
360ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /* into a single call to `__aeabi_idivmod'.  See                     */
361ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /*                                                                   */
362ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /*  http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721                */
363ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#undef FT_DIV_MOD
364ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#define FT_DIV_MOD( type, dividend, divisor, quotient, remainder ) \
365ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  FT_BEGIN_STMNT                                                   \
366ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    (quotient)  = (type)( (dividend) / (divisor) );                \
367ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    (remainder) = (type)( (dividend) - (quotient) * (divisor) );   \
368ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    if ( (remainder) < 0 )                                         \
369ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    {                                                              \
370ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      (quotient)--;                                                \
371ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      (remainder) += (type)(divisor);                              \
372ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    }                                                              \
373ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  FT_END_STMNT
374ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif /* __arm__ */
375ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
376ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
377055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* These macros speed up repetitive divisions by replacing them */
378055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* with multiplications and right shifts.                       */
379a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin#define FT_UDIVPREP( c, b )                                        \
380a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin  long  b ## _r = c ? (long)( FT_ULONG_MAX >> PIXEL_BITS ) / ( b ) \
381a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin                    : 0
382055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define FT_UDIV( a, b )                                        \
383055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  ( ( (unsigned long)( a ) * (unsigned long)( b ## _r ) ) >>   \
384055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ( sizeof( long ) * FT_CHAR_BIT - PIXEL_BITS ) )
385055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
386055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*   TYPE DEFINITIONS                                                    */
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* don't change the following types to FT_Int or FT_Pos, since we might */
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* need to define them to "float" or "double" when experimenting with   */
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* new algorithms                                                       */
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef long  TPos;     /* sub-pixel coordinate              */
397055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  typedef int   TCoord;   /* integer scanline/pixel coordinate */
398055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  typedef int   TArea;    /* cell areas, coordinate products   */
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct TCell_*  PCell;
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  TCell_
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
405055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCoord  x;     /* same with gray_TWorker.ex    */
40641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    TCoord  cover; /* same with gray_TWorker.cover */
40741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    TArea   area;
40841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    PCell   next;
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } TCell;
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
412055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  typedef struct TPixmap_
413055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  {
414055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    unsigned char*  origin;  /* pixmap origin at the bottom-left */
415055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    int             pitch;   /* pitch to go down one row */
416055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
417055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  } TPixmap;
418055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
419055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* maximum number of gray cells in the buffer */
420055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#if FT_RENDER_POOL_SIZE > 2048
421055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define FT_MAX_GRAY_POOL  ( FT_RENDER_POOL_SIZE / sizeof ( TCell ) )
422055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#else
423055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#define FT_MAX_GRAY_POOL  ( 2048 / sizeof ( TCell ) )
424055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#endif
425055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
427ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#if defined( _MSC_VER )      /* Visual C++ (and Intel C++) */
428ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /* We disable the warning `structure was padded due to   */
429ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /* __declspec(align())' in order to compile cleanly with */
430ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease  /* the maximum level of warnings.                        */
431ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#pragma warning( push )
432ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#pragma warning( disable : 4324 )
433ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif /* _MSC_VER */
434ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
43541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier  typedef struct  gray_TWorker_
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
437fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    ft_jmp_buf  jump_buffer;
438fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TCoord  ex, ey;
440055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCoord  min_ex, max_ex;
441055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCoord  min_ey, max_ey;
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TArea   area;
444295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    TCoord  cover;
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int     invalid;
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
447a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    PCell*      ycells;
44841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    PCell       cells;
449295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_PtrDist  max_cells;
450295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_PtrDist  num_cells;
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos    x,  y;
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Outline  outline;
455055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TPixmap     target;
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
457049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Raster_Span_Func  render_span;
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    void*                render_span_data;
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
46041371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier  } gray_TWorker, *gray_PWorker;
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
462ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#if defined( _MSC_VER )
463ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#pragma warning( pop )
464ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif
465ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
467295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifndef FT_STATIC_RASTER
468295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#define ras  (*worker)
469295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#else
47041371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier  static gray_TWorker  ras;
471295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
472295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
473295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
47441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier  typedef struct gray_TRaster_
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
47641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    void*         memory;
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
47841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier  } gray_TRaster, *gray_PRaster;
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
481055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#ifdef FT_DEBUG_LEVEL_TRACE
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
483055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* to be called while in the debugger --                                */
484055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* this function causes a compiler warning since it is unused otherwise */
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
486055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  gray_dump_cells( RAS_ARG )
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
488055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    int  y;
489049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
491055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    for ( y = ras.min_ey; y < ras.max_ey; y++ )
492049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
493055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      PCell  cell = ras.ycells[y - ras.min_ey];
494049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
495049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
496055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      printf( "%3d:", y );
497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
498055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      for ( ; cell != NULL; cell = cell->next )
499055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        printf( " (%3d, c:%4d, a:%6d)",
500055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                cell->x, cell->cover, cell->area );
501055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      printf( "\n" );
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
505055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#endif /* FT_DEBUG_LEVEL_TRACE */
506055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Record the current cell in the table.                                 */
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
512a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin  static void
513a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin  gray_record_cell( RAS_ARG )
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    PCell  *pcell, cell;
516055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCoord  x = ras.ex;
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
519055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    pcell = &ras.ycells[ras.ey - ras.min_ey];
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for (;;)
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      cell = *pcell;
523a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin      if ( !cell || cell->x > x )
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        break;
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cell->x == x )
527a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin        goto Found;
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      pcell = &cell->next;
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.num_cells >= ras.max_cells )
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ft_longjmp( ras.jump_buffer, 1 );
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
535a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    /* insert new cell */
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell        = ras.cells + ras.num_cells++;
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell->x     = x;
538a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    cell->area  = ras.area;
539a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    cell->cover = ras.cover;
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    cell->next  = *pcell;
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *pcell      = cell;
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
544a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    return;
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
546a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin  Found:
547a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    /* update old cell */
548a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    cell->area  += ras.area;
549a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    cell->cover += ras.cover;
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Set the current cell to a new position.                               */
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_set_cell( RAS_ARG_ TCoord  ex,
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                          TCoord  ey )
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Move the cell pointer to a new position.  We set the `invalid'      */
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* flag to indicate that the cell isn't part of those we're interested */
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* in during the render phase.  This means that:                       */
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* . the new vertical position must be within min_ey..max_ey-1.        */
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* . the new horizontal position must be strictly less than max_ex     */
567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                                     */
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Note that if a cell is to the left of the clipping region, it is    */
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* actually set to the (min_ex-1) horizontal position.                 */
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
571055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( ex < ras.min_ex )
572055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ex = ras.min_ex - 1;
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
574055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* record the current one if it is valid */
575055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( !ras.invalid )
576055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      gray_record_cell( RAS_VAR );
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
578055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.area  = 0;
579055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.cover = 0;
580055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.ex    = ex;
581055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.ey    = ey;
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
583055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.invalid = ( ey >= ras.max_ey || ey < ras.min_ey ||
584055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                    ex >= ras.max_ex );
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
588055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#ifndef FT_LONG64
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Render a scanline as one or more cells.                               */
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_scanline( RAS_ARG_ TCoord  ey,
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TPos    x1,
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TCoord  y1,
598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TPos    x2,
599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                 TCoord  y2 )
600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
601a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    TCoord  ex1, ex2, fx1, fx2, first, dy, delta, mod;
602055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TPos    p, dx;
603295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    int     incr;
604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
606049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ex1 = TRUNC( x1 );
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ex2 = TRUNC( x2 );
608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* trivial case.  Happens often */
610049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( y1 == y2 )
611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_set_cell( RAS_VAR_ ex2, ey );
613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
615049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
616055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    fx1   = (TCoord)( x1 - SUBPIXELS( ex1 ) );
617055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    fx2   = (TCoord)( x2 - SUBPIXELS( ex2 ) );
618055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* everything is located in a single cell.  That is easy! */
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                        */
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex1 == ex2 )
622a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin      goto End;
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* ok, we'll have to render a run of adjacent cells on the same */
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* scanline...                                                  */
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                              */
627055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    dx = x2 - x1;
628a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    dy = y2 - y1;
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
630055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( dx > 0 )
631055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    {
632a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin      p     = ( ONE_PIXEL - fx1 ) * dy;
633055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      first = ONE_PIXEL;
634055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      incr  = 1;
635055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
636055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    else
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
638a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin      p     = fx1 * dy;
639049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      first = 0;
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      incr  = -1;
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx    = -dx;
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
644ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    FT_DIV_MOD( TCoord, p, dx, delta, mod );
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
646a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    ras.area  += (TArea)( ( fx1 + first ) * delta );
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.cover += delta;
648a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    y1        += delta;
649a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    ex1       += incr;
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_set_cell( RAS_VAR_ ex1, ey );
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ex1 != ex2 )
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
654727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      TCoord  lift, rem;
655727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
656727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
657a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin      p = ONE_PIXEL * dy;
658ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      FT_DIV_MOD( TCoord, p, dx, lift, rem );
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
660055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      do
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        delta = lift;
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mod  += rem;
664a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin        if ( mod >= (TCoord)dx )
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          mod -= (TCoord)dx;
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          delta++;
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
670a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin        ras.area  += (TArea)( ONE_PIXEL * delta );
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.cover += delta;
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        y1        += delta;
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ex1       += incr;
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_set_cell( RAS_VAR_ ex1, ey );
675055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      } while ( ex1 != ex2 );
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
678a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    fx1 = ONE_PIXEL - first;
679a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin
680a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin  End:
681a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    dy = y2 - y1;
682a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin
683a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    ras.area  += (TArea)( ( fx1 + fx2 ) * dy );
684a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    ras.cover += dy;
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  /*                                                                       */
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Render a given line as a series of scanlines.                         */
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_line( RAS_ARG_ TPos  to_x,
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             TPos  to_y )
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
696055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCoord  ey1, ey2, fy1, fy2, first, delta, mod;
697055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TPos    p, dx, dy, x, x2;
698055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    int     incr;
699049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
700049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
701055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ey1 = TRUNC( ras.y );
702049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ey2 = TRUNC( to_y );     /* if (ey2 >= ras.max_ey) ey2 = ras.max_ey-1; */
703049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
704049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* perform vertical clipping */
705055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
706055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin         ( ey1 <  ras.min_ey && ey2 <  ras.min_ey ) )
707055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      goto End;
708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
709055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    fy1 = (TCoord)( ras.y - SUBPIXELS( ey1 ) );
710055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    fy2 = (TCoord)( to_y - SUBPIXELS( ey2 ) );
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* everything is on a single scanline */
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ey1 == ey2 )
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, to_x, fy2 );
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto End;
717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
718049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
719055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    dx = to_x - ras.x;
720055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    dy = to_y - ras.y;
721049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
722055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* vertical line - avoid calling gray_render_scanline */
723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx == 0 )
724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
725049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  ex     = TRUNC( ras.x );
726049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      TCoord  two_fx = (TCoord)( ( ras.x - SUBPIXELS( ex ) ) << 1 );
727295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      TArea   area;
728049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
729049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
730055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      if ( dy > 0)
731055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      {
732055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        first = ONE_PIXEL;
733055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        incr  = 1;
734055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      }
735055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      else
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        first = 0;
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        incr  = -1;
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
741055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      delta      = first - fy1;
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.area  += (TArea)two_fx * delta;
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.cover += delta;
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ey1       += incr;
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
746295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      gray_set_cell( RAS_VAR_ ex, ey1 );
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
748055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      delta = first + first - ONE_PIXEL;
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      area  = (TArea)two_fx * delta;
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( ey1 != ey2 )
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.area  += area;
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.cover += delta;
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ey1       += incr;
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
756295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner        gray_set_cell( RAS_VAR_ ex, ey1 );
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
759055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      delta      = fy2 - ONE_PIXEL + first;
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.area  += (TArea)two_fx * delta;
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ras.cover += delta;
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      goto End;
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* ok, we have to render several scanlines */
767055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( dy > 0)
768055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    {
769055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      p     = ( ONE_PIXEL - fy1 ) * dx;
770055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      first = ONE_PIXEL;
771055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      incr  = 1;
772055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
773055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    else
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      p     = fy1 * dx;
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      first = 0;
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      incr  = -1;
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dy    = -dy;
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
781055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    FT_DIV_MOD( TCoord, p, dy, delta, mod );
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = ras.x + delta;
784055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    gray_render_scanline( RAS_VAR_ ey1, ras.x, fy1, x, first );
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ey1 += incr;
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
788049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ey1 != ey2 )
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
791055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      TCoord  lift, rem;
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
793055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
794055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      p    = ONE_PIXEL * dx;
795055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      FT_DIV_MOD( TCoord, p, dy, lift, rem );
796055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
797055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      do
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        delta = lift;
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        mod  += rem;
801a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin        if ( mod >= (TCoord)dy )
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
803055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          mod -= (TCoord)dy;
804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          delta++;
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x2 = x + delta;
808055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        gray_render_scanline( RAS_VAR_ ey1,
809055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                                       x, ONE_PIXEL - first,
810055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                                       x2, first );
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x = x2;
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ey1 += incr;
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_set_cell( RAS_VAR_ TRUNC( x ), ey1 );
815055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      } while ( ey1 != ey2 );
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
818055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    gray_render_scanline( RAS_VAR_ ey1,
819055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                                   x, ONE_PIXEL - first,
820055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                                   to_x, fy2 );
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  End:
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.x       = to_x;
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ras.y       = to_y;
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
827055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#else
828055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
829055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*************************************************************************/
830055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*                                                                       */
831055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* Render a straight line across multiple cells in any direction.        */
832055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*                                                                       */
833055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  static void
834055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  gray_render_line( RAS_ARG_ TPos  to_x,
835055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                             TPos  to_y )
836055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  {
837055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TPos    dx, dy, fx1, fy1, fx2, fy2;
838055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCoord  ex1, ex2, ey1, ey2;
839055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
840055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
841055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ey1 = TRUNC( ras.y );
842055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ey2 = TRUNC( to_y );
843055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
844055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* perform vertical clipping */
845055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( ( ey1 >= ras.max_ey && ey2 >= ras.max_ey ) ||
846055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin         ( ey1 <  ras.min_ey && ey2 <  ras.min_ey ) )
847055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      goto End;
848055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
849055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ex1 = TRUNC( ras.x );
850055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ex2 = TRUNC( to_x );
851055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
852055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    fx1 = ras.x - SUBPIXELS( ex1 );
853055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    fy1 = ras.y - SUBPIXELS( ey1 );
854055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
855055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    dx = to_x - ras.x;
856055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    dy = to_y - ras.y;
857055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
858055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( ex1 == ex2 && ey1 == ey2 )       /* inside one cell */
859055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ;
860055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    else if ( dy == 0 ) /* ex1 != ex2 */  /* any horizontal line */
861055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    {
862055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ex1 = ex2;
863055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      gray_set_cell( RAS_VAR_ ex1, ey1 );
864055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
865055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    else if ( dx == 0 )
866055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    {
867055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      if ( dy > 0 )                       /* vertical line up */
868055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        do
869055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        {
870055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy2 = ONE_PIXEL;
871055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.cover += ( fy2 - fy1 );
872055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.area  += ( fy2 - fy1 ) * fx1 * 2;
873055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy1 = 0;
874055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ey1++;
875055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          gray_set_cell( RAS_VAR_ ex1, ey1 );
876055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        } while ( ey1 != ey2 );
877055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      else                                /* vertical line down */
878055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        do
879055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        {
880055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy2 = 0;
881055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.cover += ( fy2 - fy1 );
882055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.area  += ( fy2 - fy1 ) * fx1 * 2;
883055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy1 = ONE_PIXEL;
884055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ey1--;
885055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          gray_set_cell( RAS_VAR_ ex1, ey1 );
886055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        } while ( ey1 != ey2 );
887055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
888055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    else                                  /* any other line */
889055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    {
890055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      TPos  prod = dx * fy1 - dy * fx1;
891a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin      FT_UDIVPREP( ex1 != ex2, dx );
892a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin      FT_UDIVPREP( ey1 != ey2, dy );
893055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
894055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
895055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* The fundamental value `prod' determines which side and the  */
896055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* exact coordinate where the line exits current cell.  It is  */
897055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* also easily updated when moving from one cell to the next.  */
898055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      do
899055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      {
900055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        if      ( prod                                   <= 0 &&
901055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                  prod - dx * ONE_PIXEL                  >  0 ) /* left */
902055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        {
903055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fx2 = 0;
904055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy2 = (TPos)FT_UDIV( -prod, -dx );
905055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          prod -= dy * ONE_PIXEL;
906055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.cover += ( fy2 - fy1 );
907055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
908055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fx1 = ONE_PIXEL;
909055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy1 = fy2;
910055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ex1--;
911055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        }
912055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        else if ( prod - dx * ONE_PIXEL                  <= 0 &&
913055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                  prod - dx * ONE_PIXEL + dy * ONE_PIXEL >  0 ) /* up */
914055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        {
915055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          prod -= dx * ONE_PIXEL;
916055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fx2 = (TPos)FT_UDIV( -prod, dy );
917055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy2 = ONE_PIXEL;
918055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.cover += ( fy2 - fy1 );
919055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
920055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fx1 = fx2;
921055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy1 = 0;
922055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ey1++;
923055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        }
924055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        else if ( prod - dx * ONE_PIXEL + dy * ONE_PIXEL <= 0 &&
925055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                  prod                  + dy * ONE_PIXEL >= 0 ) /* right */
926055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        {
927055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          prod += dy * ONE_PIXEL;
928055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fx2 = ONE_PIXEL;
929055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy2 = (TPos)FT_UDIV( prod, dx );
930055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.cover += ( fy2 - fy1 );
931055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
932055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fx1 = 0;
933055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy1 = fy2;
934055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ex1++;
935055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        }
936055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        else /* ( prod                  + dy * ONE_PIXEL <  0 &&
937055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                  prod                                   >  0 )    down */
938055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        {
939055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fx2 = (TPos)FT_UDIV( prod, -dy );
940055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy2 = 0;
941055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          prod += dx * ONE_PIXEL;
942055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.cover += ( fy2 - fy1 );
943055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
944055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fx1 = fx2;
945055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          fy1 = ONE_PIXEL;
946055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ey1--;
947055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        }
948055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
949055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        gray_set_cell( RAS_VAR_ ex1, ey1 );
950055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      } while ( ex1 != ex2 || ey1 != ey2 );
951055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
952055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
953055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    fx2 = to_x - SUBPIXELS( ex2 );
954055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    fy2 = to_y - SUBPIXELS( ey2 );
955055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
956055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.cover += ( fy2 - fy1 );
957055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.area  += ( fy2 - fy1 ) * ( fx1 + fx2 );
958055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
959055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  End:
960055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.x       = to_x;
961055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.y       = to_y;
962055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  }
963055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
964055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#endif
965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_split_conic( FT_Vector*  base )
968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos  a, b;
970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
971049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].x = base[2].x;
973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].x;
974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    a = base[3].x = ( base[2].x + b ) / 2;
975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].x = ( base[0].x + b ) / 2;
976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].x = ( a + b ) / 2;
977049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
978049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].y = base[2].y;
979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].y;
980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    a = base[3].y = ( base[2].y + b ) / 2;
981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b = base[1].y = ( base[0].y + b ) / 2;
982049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].y = ( a + b ) / 2;
983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
985049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_conic( RAS_ARG_ const FT_Vector*  control,
988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const FT_Vector*  to )
989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
990055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    FT_Vector   bez_stack[16 * 2 + 1];  /* enough to accommodate bisections */
991055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    FT_Vector*  arc = bez_stack;
992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos        dx, dy;
993055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    int         draw, split;
994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
99541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
9967f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[0].x = UPSCALE( to->x );
9977f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[0].y = UPSCALE( to->y );
9987f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[1].x = UPSCALE( control->x );
9997f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[1].y = UPSCALE( control->y );
10007f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[2].x = ras.x;
10017f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    arc[2].y = ras.y;
1002055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1003055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* short-cut the arc that crosses the current band */
1004055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
1005055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin           TRUNC( arc[1].y ) >= ras.max_ey &&
1006055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin           TRUNC( arc[2].y ) >= ras.max_ey ) ||
1007055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin         ( TRUNC( arc[0].y ) <  ras.min_ey &&
1008055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin           TRUNC( arc[1].y ) <  ras.min_ey &&
1009055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin           TRUNC( arc[2].y ) <  ras.min_ey ) )
1010055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    {
1011055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ras.x = arc[0].x;
1012055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ras.y = arc[0].y;
1013055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      return;
1014055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
10157f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
10167f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    dx = FT_ABS( arc[2].x + arc[0].x - 2 * arc[1].x );
10177f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    dy = FT_ABS( arc[2].y + arc[0].y - 2 * arc[1].y );
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( dx < dy )
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      dx = dy;
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1021055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* We can calculate the number of necessary bisections because  */
1022055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* each bisection predictably reduces deviation exactly 4-fold. */
1023055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* Even 32-bit deviation would vanish after 16 bisections.      */
1024055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    draw = 1;
1025055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    while ( dx > ONE_PIXEL / 4 )
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1027055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      dx   >>= 2;
1028055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      draw <<= 1;
1029055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1031055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* We use decrement counter to count the total number of segments */
1032055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* to draw starting from 2^level. Before each draw we split as    */
1033055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* many times as there are trailing zeros in the counter.         */
1034aeb407daf3711a10a27f3bc2223c5eb05158076eDavid 'Digit' Turner    do
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1036055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      split = 1;
1037055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      while ( ( draw & split ) == 0 )
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        gray_split_conic( arc );
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        arc += 2;
1041055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        split <<= 1;
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
10447f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
10457f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      arc -= 2;
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1047055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    } while ( --draw );
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_split_cubic( FT_Vector*  base )
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos  a, b, c, d;
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[6].x = base[3].x;
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = base[1].x;
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    d = base[2].x;
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[1].x = a = ( base[0].x + c ) / 2;
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[5].x = b = ( base[3].x + d ) / 2;
1062049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = ( c + d ) / 2;
1063049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].x = a = ( a + c ) / 2;
1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].x = b = ( b + c ) / 2;
1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[3].x = ( a + b ) / 2;
1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[6].y = base[3].y;
1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = base[1].y;
1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    d = base[2].y;
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[1].y = a = ( base[0].y + c ) / 2;
1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[5].y = b = ( base[3].y + d ) / 2;
1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = ( c + d ) / 2;
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[2].y = a = ( a + c ) / 2;
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[4].y = b = ( b + c ) / 2;
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    base[3].y = ( a + b ) / 2;
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_render_cubic( RAS_ARG_ const FT_Vector*  control1,
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const FT_Vector*  control2,
1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const FT_Vector*  to )
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1084055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    FT_Vector   bez_stack[16 * 3 + 1];  /* enough to accommodate bisections */
1085055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    FT_Vector*  arc = bez_stack;
1086055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TPos        dx, dy, dx_, dy_;
1087055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TPos        dx1, dy1, dx2, dy2;
1088055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TPos        L, s, s_limit;
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[0].x = UPSCALE( to->x );
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[0].y = UPSCALE( to->y );
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[1].x = UPSCALE( control2->x );
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[1].y = UPSCALE( control2->y );
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[2].x = UPSCALE( control1->x );
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[2].y = UPSCALE( control1->y );
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[3].x = ras.x;
1098049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    arc[3].y = ras.y;
1099049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1100055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* short-cut the arc that crosses the current band */
1101055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( ( TRUNC( arc[0].y ) >= ras.max_ey &&
1102055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin           TRUNC( arc[1].y ) >= ras.max_ey &&
1103055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin           TRUNC( arc[2].y ) >= ras.max_ey &&
1104055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin           TRUNC( arc[3].y ) >= ras.max_ey ) ||
1105055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin         ( TRUNC( arc[0].y ) <  ras.min_ey &&
1106055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin           TRUNC( arc[1].y ) <  ras.min_ey &&
1107055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin           TRUNC( arc[2].y ) <  ras.min_ey &&
1108055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin           TRUNC( arc[3].y ) <  ras.min_ey ) )
1109055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    {
1110055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ras.x = arc[0].x;
1111055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ras.y = arc[0].y;
1112055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      return;
1113055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
11147f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1115bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    for (;;)
1116bff90fb5ec88ad7fdfb6d1d2f5a5719c20a2c5dcOlivier Bailly    {
11177f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /* Decide whether to split or draw. See `Rapid Termination          */
11187f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /* Evaluation for Recursive Subdivision of Bezier Curves' by Thomas */
11197f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /* F. Hain, at                                                      */
11207f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      /* http://www.cis.southalabama.edu/~hain/general/Publications/Bezier/Camera-ready%20CISST02%202.pdf */
11217f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1122055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* dx and dy are x and y components of the P0-P3 chord vector. */
1123055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      dx = dx_ = arc[3].x - arc[0].x;
1124055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      dy = dy_ = arc[3].y - arc[0].y;
11257f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1126055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      L = FT_HYPOT( dx_, dy_ );
11277f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1128055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* Avoid possible arithmetic overflow below by splitting. */
1129055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      if ( L > 32767 )
1130055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        goto Split;
1131fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1132055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* Max deviation may be as much as (s/L) * 3/4 (if Hain's v = 1). */
1133055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      s_limit = L * (TPos)( ONE_PIXEL / 6 );
11347f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1135055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* s is L * the perpendicular distance from P1 to the line P0-P3. */
1136055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      dx1 = arc[1].x - arc[0].x;
1137055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      dy1 = arc[1].y - arc[0].y;
1138055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      s = FT_ABS( dy * dx1 - dx * dy1 );
11397f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1140055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      if ( s > s_limit )
1141055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        goto Split;
11427f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1143055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* s is L * the perpendicular distance from P2 to the line P0-P3. */
1144055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      dx2 = arc[2].x - arc[0].x;
1145055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      dy2 = arc[2].y - arc[0].y;
1146055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      s = FT_ABS( dy * dx2 - dx * dy2 );
11477f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1148055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      if ( s > s_limit )
1149055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        goto Split;
11507f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1151055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* Split super curvy segments where the off points are so far
1152055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin         from the chord that the angles P0-P1-P3 or P0-P2-P3 become
1153055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin         acute as detected by appropriate dot products. */
1154055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      if ( dx1 * ( dx1 - dx ) + dy1 * ( dy1 - dy ) > 0 ||
1155055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin           dx2 * ( dx2 - dx ) + dy2 * ( dy2 - dy ) > 0 )
1156055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        goto Split;
11577f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1158055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      gray_render_line( RAS_VAR_ arc[0].x, arc[0].y );
11597f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1160055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      if ( arc == bez_stack )
1161055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        return;
11627f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner
1163055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      arc -= 3;
1164055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      continue;
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
11667f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    Split:
11677f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      gray_split_cubic( arc );
11687f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner      arc += 3;
11697f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner    }
11707f08cbd7d6dcf19b8d8e4328e33032aee342e3b4David 'Digit' Turner  }
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_move_to( const FT_Vector*  to,
117541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier                gray_PWorker      worker )
1176049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1177049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    TPos  x, y;
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* start to a new position */
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    x = UPSCALE( to->x );
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    y = UPSCALE( to->y );
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1184055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    gray_set_cell( RAS_VAR_ TRUNC( x ), TRUNC( y ) );
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1186055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.x = x;
1187055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.y = y;
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_line_to( const FT_Vector*  to,
119441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier                gray_PWorker      worker )
1195049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1196295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_render_line( RAS_VAR_ UPSCALE( to->x ), UPSCALE( to->y ) );
1197049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1198049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_conic_to( const FT_Vector*  control,
1203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Vector*  to,
120441371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier                 gray_PWorker      worker )
1205049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1206295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_render_conic( RAS_VAR_ control, to );
1207049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1209049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1210049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_cubic_to( const FT_Vector*  control1,
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Vector*  control2,
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 const FT_Vector*  to,
121541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier                 gray_PWorker      worker )
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1217295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    gray_render_cubic( RAS_VAR_ control1, control2, to );
1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1223049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_hline( RAS_ARG_ TCoord  x,
1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                       TCoord  y,
1225055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                       TArea   area,
1226295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner                       TCoord  acount )
1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1228055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    int      coverage;
1229055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    FT_Span  span;
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute the coverage line's coverage, depending on the    */
1233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* outline fill rule                                         */
1234049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                           */
1235049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* the coverage percentage is area/(PIXEL_BITS*PIXEL_BITS*2) */
1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /*                                                           */
1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    coverage = (int)( area >> ( PIXEL_BITS * 2 + 1 - 8 ) );
1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                                                    /* use range 0..256 */
1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( coverage < 0 )
1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      coverage = -coverage;
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1242049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ras.outline.flags & FT_OUTLINE_EVEN_ODD_FILL )
1243049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1244049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      coverage &= 511;
1245049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( coverage > 256 )
1247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        coverage = 512 - coverage;
1248049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( coverage == 256 )
1249049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        coverage = 255;
1250049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1251049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1252049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1253049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* normal non-zero winding rule */
1254049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( coverage >= 256 )
1255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        coverage = 255;
1256049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1257049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1258055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( ras.render_span )  /* for FT_RASTER_FLAG_DIRECT only */
1259049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1260055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      span.x        = (short)x;
1261055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      span.len      = (unsigned short)acount;
1262055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      span.coverage = (unsigned char)coverage;
1263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1264055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ras.render_span( y, 1, &span, ras.render_span_data );
1265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1266055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    else
1267049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1268055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      unsigned char*  q = ras.target.origin - ras.target.pitch * y + x;
1269055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      unsigned char   c = (unsigned char)coverage;
1270049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1271049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1272055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* For small-spans it is faster to do it by ourselves than
1273055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin       * calling `memset'.  This is mainly due to the cost of the
1274055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin       * function call.
1275055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin       */
1276055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      switch ( acount )
1277055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      {
1278055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      case 7: *q++ = c;
1279055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      case 6: *q++ = c;
1280055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      case 5: *q++ = c;
1281055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      case 4: *q++ = c;
1282055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      case 3: *q++ = c;
1283055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      case 2: *q++ = c;
1284055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      case 1: *q   = c;
1285055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      case 0: break;
1286055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      default:
1287055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        FT_MEM_SET( q, c, acount );
1288055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      }
1289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1294055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  gray_sweep( RAS_ARG )
1295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1296055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    int  y;
1297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
12990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE7(( "gray_sweep: start\n" ));
13000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1301055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    for ( y = ras.min_ey; y < ras.max_ey; y++ )
1302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1303055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      PCell   cell  = ras.ycells[y - ras.min_ey];
1304055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      TCoord  x     = ras.min_ex;
1305a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin      TArea   cover = 0;
1306a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin      TArea   area;
1307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      for ( ; cell != NULL; cell = cell->next )
1310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1311055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        if ( cover != 0 && cell->x > x )
1312a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin          gray_hline( RAS_VAR_ x, y, cover, cell->x - x );
1313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1314a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin        cover += (TArea)cell->cover * ( ONE_PIXEL * 2 );
1315a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin        area   = cover - cell->area;
1316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1317055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        if ( area != 0 && cell->x >= ras.min_ex )
1318055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          gray_hline( RAS_VAR_ cell->x, y, area, 1 );
1319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        x = cell->x + 1;
1321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( cover != 0 )
1324a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin        gray_hline( RAS_VAR_ x, y, cover, ras.max_ex - x );
1325727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
1326727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
13270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE7(( "gray_sweep: end\n" ));
1328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1331055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#ifdef STANDALONE_
1332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1334049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1335055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*  The following functions should only compile in stand-alone mode,     */
1336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*  i.e., when building this component without the rest of FreeType.     */
1337049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1338049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1339049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1340049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
1341049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Function>                                                            */
1343049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    FT_Outline_Decompose                                               */
1344049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1345049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Description>                                                         */
13460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*    Walk over an outline's structure to decompose it into individual   */
13470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*    segments and Bézier arcs.  This function is also able to emit      */
1348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    `move to' and `close to' operations to indicate the start and end  */
1349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    of new contours in the outline.                                    */
1350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1351049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Input>                                                               */
1352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    outline        :: A pointer to the source target.                  */
1353049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
13540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /*    func_interface :: A table of `emitters', i.e., function pointers   */
1355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      called during decomposition to indicate path     */
1356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      operations.                                      */
1357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
13580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* <InOut>                                                               */
1359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    user           :: A typeless pointer which is passed to each       */
1360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      emitter during the decomposition.  It can be     */
1361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      used to store the state during the               */
1362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                      decomposition.                                   */
1363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
1364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* <Return>                                                              */
1365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*    Error code.  0 means success.                                      */
1366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
13670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  static int
13680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_Outline_Decompose( const FT_Outline*        outline,
13690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        const FT_Outline_Funcs*  func_interface,
13700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        void*                    user )
1371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef SCALED
1373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define SCALED( x )  ( ( (x) << shift ) - delta )
1374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector   v_last;
1376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector   v_control;
1377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector   v_start;
1378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*  point;
1380049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Vector*  limit;
1381049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    char*       tags;
1382049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    int         error;
13840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int   n;         /* index of contour in outline     */
1386049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    int   first;     /* index of first point in contour */
1387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    char  tag;       /* current point's state           */
1388049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
13890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    int   shift;
13900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    TPos  delta;
1391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1393fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    if ( !outline )
1394fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki      return FT_THROW( Invalid_Outline );
1395fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1396fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    if ( !func_interface )
1397727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
13980a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
13990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    shift = func_interface->shift;
14000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    delta = func_interface->delta;
1401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    first = 0;
1402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( n = 0; n < outline->n_contours; n++ )
1404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      int  last;  /* index of last point in contour */
1406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE5(( "FT_Outline_Decompose: Outline %d\n", n ));
14090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      last  = outline->contours[n];
14110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      if ( last < 0 )
14120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        goto Invalid_Outline;
1413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      limit = outline->points + last;
1414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14150a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_start   = outline->points[first];
1416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v_start.x = SCALED( v_start.x );
1417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v_start.y = SCALED( v_start.y );
1418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14190a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_last   = outline->points[last];
14200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_last.x = SCALED( v_last.x );
14210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      v_last.y = SCALED( v_last.y );
1422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      v_control = v_start;
1424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      point = outline->points + first;
14260a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      tags  = outline->tags   + first;
1427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      tag   = FT_CURVE_TAG( tags[0] );
1428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* A contour cannot start with a cubic control point! */
1430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( tag == FT_CURVE_TAG_CUBIC )
1431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Invalid_Outline;
1432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check first point to determine origin */
1434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( tag == FT_CURVE_TAG_CONIC )
1435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* first point is conic control.  Yes, this happens. */
1437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( FT_CURVE_TAG( outline->tags[last] ) == FT_CURVE_TAG_ON )
1438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* start at last point if it is on the curve */
1440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_start = v_last;
1441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          limit--;
1442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else
1444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* if both first and last points are conic,         */
1446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* start at their middle and record its position    */
1447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          /* for closure                                      */
1448049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_start.x = ( v_start.x + v_last.x ) / 2;
1449049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_start.y = ( v_start.y + v_last.y ) / 2;
1450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          v_last = v_start;
1452049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        point--;
1454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        tags--;
1455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE5(( "  move to (%.2f, %.2f)\n",
14580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                  v_start.x / 64.0, v_start.y / 64.0 ));
1459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = func_interface->move_to( &v_start, user );
1460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1462049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      while ( point < limit )
1464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1465049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        point++;
1466049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        tags++;
1467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        tag = FT_CURVE_TAG( tags[0] );
1469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        switch ( tag )
1470049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1471049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case FT_CURVE_TAG_ON:  /* emit a single line_to */
1472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Vector  vec;
1474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec.x = SCALED( point->x );
1477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec.y = SCALED( point->y );
1478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_TRACE5(( "  line to (%.2f, %.2f)\n",
14800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        vec.x / 64.0, vec.y / 64.0 ));
1481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            error = func_interface->line_to( &vec, user );
1482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( error )
1483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Exit;
1484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            continue;
1485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1486049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        case FT_CURVE_TAG_CONIC:  /* consume conic arcs */
14880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          v_control.x = SCALED( point->x );
14890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          v_control.y = SCALED( point->y );
1490049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project        Do_Conic:
14920a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          if ( point < limit )
14930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          {
14940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_Vector  vec;
14950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_Vector  v_middle;
1496049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1497049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
14980a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            point++;
14990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            tags++;
15000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            tag = FT_CURVE_TAG( tags[0] );
1501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            vec.x = SCALED( point->x );
15030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            vec.y = SCALED( point->y );
1504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            if ( tag == FT_CURVE_TAG_ON )
15060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            {
15070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              FT_TRACE5(( "  conic to (%.2f, %.2f)"
15080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          " with control (%.2f, %.2f)\n",
15090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          vec.x / 64.0, vec.y / 64.0,
15100a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          v_control.x / 64.0, v_control.y / 64.0 ));
15110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              error = func_interface->conic_to( &v_control, &vec, user );
1512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( error )
1513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
15140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              continue;
1515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            if ( tag != FT_CURVE_TAG_CONIC )
15180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              goto Invalid_Outline;
15190a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
15200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            v_middle.x = ( v_control.x + vec.x ) / 2;
15210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            v_middle.y = ( v_control.y + vec.y ) / 2;
15220a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
15230a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_TRACE5(( "  conic to (%.2f, %.2f)"
15240a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        " with control (%.2f, %.2f)\n",
15250a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        v_middle.x / 64.0, v_middle.y / 64.0,
15260a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        v_control.x / 64.0, v_control.y / 64.0 ));
15270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            error = func_interface->conic_to( &v_control, &v_middle, user );
15280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            if ( error )
15290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              goto Exit;
15300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
15310a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            v_control = vec;
15320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            goto Do_Conic;
1533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          FT_TRACE5(( "  conic to (%.2f, %.2f)"
15360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      " with control (%.2f, %.2f)\n",
15370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      v_start.x / 64.0, v_start.y / 64.0,
15380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      v_control.x / 64.0, v_control.y / 64.0 ));
15390a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          error = func_interface->conic_to( &v_control, &v_start, user );
15400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project          goto Close;
15410a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        default:  /* FT_CURVE_TAG_CUBIC */
1543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          {
1544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Vector  vec1, vec2;
1545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( point + 1 > limit                             ||
1548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                 FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
1549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              goto Invalid_Outline;
1550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            point += 2;
1552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            tags  += 2;
1553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec1.x = SCALED( point[-2].x );
1555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec1.y = SCALED( point[-2].y );
1556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec2.x = SCALED( point[-1].x );
1558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            vec2.y = SCALED( point[-1].y );
1559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            if ( point <= limit )
1561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            {
1562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_Vector  vec;
1563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              vec.x = SCALED( point->x );
1566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              vec.y = SCALED( point->y );
1567049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project              FT_TRACE5(( "  cubic to (%.2f, %.2f)"
15690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
15700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          vec.x / 64.0, vec.y / 64.0,
15710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          vec1.x / 64.0, vec1.y / 64.0,
15720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                          vec2.x / 64.0, vec2.y / 64.0 ));
1573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              error = func_interface->cubic_to( &vec1, &vec2, &vec, user );
1574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              if ( error )
1575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                goto Exit;
1576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              continue;
1577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            }
1578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
15790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_TRACE5(( "  cubic to (%.2f, %.2f)"
15800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        " with controls (%.2f, %.2f) and (%.2f, %.2f)\n",
15810a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        v_start.x / 64.0, v_start.y / 64.0,
15820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        vec1.x / 64.0, vec1.y / 64.0,
15830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                        vec2.x / 64.0, vec2.y / 64.0 ));
1584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            error = func_interface->cubic_to( &vec1, &vec2, &v_start, user );
1585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            goto Close;
1586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          }
1587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
1589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* close the contour with a line segment */
15910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_TRACE5(( "  line to (%.2f, %.2f)\n",
15920a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                  v_start.x / 64.0, v_start.y / 64.0 ));
1593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = func_interface->line_to( &v_start, user );
1594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project   Close:
1596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( error )
1597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        goto Exit;
1598049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1599049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      first = last + 1;
1600049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1601049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
16020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_TRACE5(( "FT_Outline_Decompose: Done\n", n ));
1603049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1604049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Exit:
1606a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    FT_TRACE5(( "FT_Outline_Decompose: Error 0x%x\n", error ));
1607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1608049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1609049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  Invalid_Outline:
1610727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_THROW( Invalid_Outline );
1611049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1613049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1614055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*************************************************************************/
1615055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*                                                                       */
1616055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* <Function>                                                            */
1617055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    FT_Outline_Get_CBox                                                */
1618055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*                                                                       */
1619055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* <Description>                                                         */
1620055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    Return an outline's `control box'.  The control box encloses all   */
1621055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    the outline's points, including Bézier control points.  Though it  */
1622055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    coincides with the exact bounding box for most glyphs, it can be   */
1623055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    slightly larger in some situations (like when rotating an outline  */
1624055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    that contains Bézier outside arcs).                                */
1625055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*                                                                       */
1626055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    Computing the control box is very fast, while getting the bounding */
1627055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    box can take much more time as it needs to walk over all segments  */
1628055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    and arcs in the outline.  To get the latter, you can use the       */
1629055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    `ftbbox' component, which is dedicated to this single task.        */
1630055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*                                                                       */
1631055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* <Input>                                                               */
1632055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    outline :: A pointer to the source outline descriptor.             */
1633055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*                                                                       */
1634055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* <Output>                                                              */
1635055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    acbox   :: The outline's control box.                              */
1636055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*                                                                       */
1637055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /* <Note>                                                                */
1638055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*    See @FT_Glyph_Get_CBox for a discussion of tricky fonts.           */
1639055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  /*                                                                       */
1640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1641055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  static void
1642055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  FT_Outline_Get_CBox( const FT_Outline*  outline,
1643055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                       FT_BBox           *acbox )
1644049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1645055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TPos  xMin, yMin, xMax, yMax;
1646055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1647055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1648055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( outline && acbox )
1649055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    {
1650055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      if ( outline->n_points == 0 )
1651055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      {
1652055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        xMin = 0;
1653055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        yMin = 0;
1654055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        xMax = 0;
1655055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        yMax = 0;
1656055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      }
1657055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      else
1658055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      {
1659055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        FT_Vector*  vec   = outline->points;
1660055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        FT_Vector*  limit = vec + outline->n_points;
1661055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1662055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1663055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        xMin = xMax = vec->x;
1664055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        yMin = yMax = vec->y;
1665055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        vec++;
1666055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1667055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        for ( ; vec < limit; vec++ )
1668055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        {
1669055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          TPos  x, y;
1670055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1671055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1672055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          x = vec->x;
1673055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          if ( x < xMin ) xMin = x;
1674055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          if ( x > xMax ) xMax = x;
1675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1676055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          y = vec->y;
1677055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          if ( y < yMin ) yMin = y;
1678055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          if ( y > yMax ) yMax = y;
1679055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        }
1680055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      }
1681055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      acbox->xMin = xMin;
1682055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      acbox->xMax = xMax;
1683055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      acbox->yMin = yMin;
1684055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      acbox->yMax = yMax;
1685055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
1686055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  }
1687055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1688055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#endif /* STANDALONE_ */
1689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1690fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1691fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki  FT_DEFINE_OUTLINE_FUNCS(
1692fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    func_interface,
1693fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1694a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    (FT_Outline_MoveTo_Func) gray_move_to,   /* move_to  */
1695a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    (FT_Outline_LineTo_Func) gray_line_to,   /* line_to  */
1696a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    (FT_Outline_ConicTo_Func)gray_conic_to,  /* conic_to */
1697a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    (FT_Outline_CubicTo_Func)gray_cubic_to,  /* cubic_to */
1698a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin
1699a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    0,                                       /* shift    */
1700a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    0                                        /* delta    */
1701a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin  )
1702fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1703295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner
1704295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  static int
1705295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  gray_convert_glyph_inner( RAS_ARG )
1706295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner  {
1707049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1708049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    volatile int  error = 0;
1709049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1710295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#ifdef FT_CONFIG_OPTION_PIC
1711295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      FT_Outline_Funcs func_interface;
1712295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      Init_Class_func_interface(&func_interface);
1713295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner#endif
17140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ft_setjmp( ras.jump_buffer ) == 0 )
1716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1717049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      error = FT_Outline_Decompose( &ras.outline, &func_interface, &ras );
1718ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease      if ( !ras.invalid )
1719ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease        gray_record_cell( RAS_VAR );
1720055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1721055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      FT_TRACE7(( "band [%d..%d]: %d cells\n",
1722055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                  ras.min_ey, ras.max_ey, ras.num_cells ));
1723049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1724049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1725055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    {
1726727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      error = FT_THROW( Memory_Overflow );
1727049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1728055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      FT_TRACE7(( "band [%d..%d]: to be bisected\n",
1729055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                  ras.min_ey, ras.max_ey ));
1730055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
1731055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1732049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1733049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1734049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_convert_glyph( RAS_ARG )
1738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1739055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCell    buffer[FT_MAX_GRAY_POOL];
1740055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCoord   band_size = FT_MAX_GRAY_POOL / 8;
1741055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCoord   count = ras.max_ey - ras.min_ey;
1742055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    int      num_bands;
1743055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCoord   min, max, max_y;
1744055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCoord   bands[32];  /* enough to accommodate bisections */
1745055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    TCoord*  band;
1746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
17480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* set up vertical bands */
1749055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( count > band_size )
1750055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    {
1751055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* two divisions rounded up */
1752055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      num_bands = (int)( ( count + band_size - 1) / band_size );
1753055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      band_size = ( count + num_bands - 1 ) / num_bands;
1754055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
1755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    min   = ras.min_ey;
1757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    max_y = ras.max_ey;
1758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1759055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    for ( ; min < max_y; min = max )
1760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1761055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      max = min + band_size;
1762055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      if ( max > max_y )
1763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        max = max_y;
1764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1765055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      band    = bands;
1766055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      band[1] = min;
1767055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      band[0] = max;
1768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1769055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      do
1770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1771055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        TCoord  width = band[0] - band[1];
1772055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        int     error;
1773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1775055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        /* memory management */
1776055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        {
1777055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          size_t  ycount = (size_t)width;
1778055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          size_t  cell_start;
1779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1781055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          cell_start = ( ycount * sizeof ( PCell ) + sizeof ( TCell ) - 1 ) /
1782055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                       sizeof ( TCell );
1783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1784055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.cells     = buffer + cell_start;
1785055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.max_cells = (FT_PtrDist)( FT_MAX_GRAY_POOL - cell_start );
1786a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin          ras.num_cells = 0;
1787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1788055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          ras.ycells = (PCell*)buffer;
1789055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          while ( ycount )
1790055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin            ras.ycells[--ycount] = NULL;
1791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        ras.invalid   = 1;
1794055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        ras.min_ey    = band[1];
1795055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        ras.max_ey    = band[0];
1796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        error = gray_convert_glyph_inner( RAS_VAR );
1798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( !error )
1800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1801055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin          gray_sweep( RAS_VAR );
1802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          band--;
1803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          continue;
1804049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        else if ( error != ErrRaster_Memory_Overflow )
1806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return 1;
1807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* render pool overflow; we will reduce the render band by half */
1809055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        width >>= 1;
1810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* This is too complex for a single scanline; there must */
1812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        /* be some problems.                                     */
1813055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        if ( width == 0 )
1814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1815295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner          FT_TRACE7(( "gray_convert_glyph: rotten glyph\n" ));
1816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          return 1;
1817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        band++;
1820055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        band[1]  = band[0];
1821055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        band[0] += width;
1822055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      } while ( band >= bands );
1823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1830055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  gray_raster_render( FT_Raster                raster,
1831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      const FT_Raster_Params*  params )
1832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1833a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    const FT_Outline*  outline    = (const FT_Outline*)params->source;
1834a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    const FT_Bitmap*   target_map = params->target;
1835055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    FT_BBox            cbox, clip;
1836fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1837055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#ifndef FT_STATIC_RASTER
1838fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    gray_TWorker  worker[1];
1839055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#endif
1840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1841fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
1842fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    if ( !raster )
1843727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
1844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1845055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* this version does not support monochrome rendering */
1846055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( !( params->flags & FT_RASTER_FLAG_AA ) )
1847055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      return FT_THROW( Invalid_Mode );
1848055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !outline )
1850727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Outline );
1851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* return immediately if the outline is empty */
1853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( outline->n_points == 0 || outline->n_contours <= 0 )
1854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return 0;
1855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !outline->contours || !outline->points )
1857727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Outline );
1858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( outline->n_points !=
1860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           outline->contours[outline->n_contours - 1] + 1 )
1861727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Outline );
1862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1863055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.outline = *outline;
1864055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1865055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( params->flags & FT_RASTER_FLAG_DIRECT )
1866055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    {
1867055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      if ( !params->gray_spans )
1868055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        return 0;
1869055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1870055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ras.render_span      = (FT_Raster_Span_Func)params->gray_spans;
1871055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ras.render_span_data = params->user;
1872055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    }
1873055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    else
1874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1875055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      /* if direct mode is not set, we must have a target bitmap */
1876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !target_map )
1877727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        return FT_THROW( Invalid_Argument );
1878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* nothing to do */
1880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !target_map->width || !target_map->rows )
1881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        return 0;
1882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( !target_map->buffer )
1884727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease        return FT_THROW( Invalid_Argument );
1885055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1886055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      if ( target_map->pitch < 0 )
1887055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        ras.target.origin = target_map->buffer;
1888055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      else
1889055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin        ras.target.origin = target_map->buffer
1890055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin              + ( target_map->rows - 1 ) * (unsigned int)target_map->pitch;
1891055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1892055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ras.target.pitch = target_map->pitch;
1893055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1894055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ras.render_span      = (FT_Raster_Span_Func)NULL;
1895055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      ras.render_span_data = NULL;
1896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1898055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    FT_Outline_Get_CBox( outline, &cbox );
1899055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1900055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* reject too large outline coordinates */
1901055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( cbox.xMin < -0x1000000L || cbox.xMax > 0x1000000L ||
1902055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin         cbox.yMin < -0x1000000L || cbox.yMax > 0x1000000L )
1903055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      return FT_THROW( Invalid_Outline );
1904055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin
1905055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* truncate the bounding box to integer pixels */
1906055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    cbox.xMin = cbox.xMin >> 6;
1907055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    cbox.yMin = cbox.yMin >> 6;
1908055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    cbox.xMax = ( cbox.xMax + 63 ) >> 6;
1909055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    cbox.yMax = ( cbox.yMax + 63 ) >> 6;
1910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* compute clipping box */
19120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !( params->flags & FT_RASTER_FLAG_DIRECT ) )
1913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* compute clip box from target pixmap */
1915055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      clip.xMin = 0;
1916055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      clip.yMin = 0;
1917055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      clip.xMax = (FT_Pos)target_map->width;
1918055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      clip.yMax = (FT_Pos)target_map->rows;
1919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( params->flags & FT_RASTER_FLAG_CLIP )
1921055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      clip = params->clip_box;
1922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
1923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1924055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      clip.xMin = -32768L;
1925055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      clip.yMin = -32768L;
1926055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      clip.xMax =  32767L;
1927055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      clip.yMax =  32767L;
1928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1930055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    /* clip to target bitmap, exit if nothing to do */
1931055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.min_ex = FT_MAX( cbox.xMin, clip.xMin );
1932055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.min_ey = FT_MAX( cbox.yMin, clip.yMin );
1933055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.max_ex = FT_MIN( cbox.xMax, clip.xMax );
1934055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    ras.max_ey = FT_MIN( cbox.yMax, clip.yMax );
1935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1936055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin    if ( ras.max_ex <= ras.min_ex || ras.max_ey <= ras.min_ey )
1937055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin      return 0;
1938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1939295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    return gray_convert_glyph( RAS_VAR );
1940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
19430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /**** RASTER OBJECT CREATION: In stand-alone mode, we simply use *****/
19440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /****                         a static object.                   *****/
1945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1946055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#ifdef STANDALONE_
1947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_new( void*       memory,
1950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Raster*  araster )
1951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
195241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    static gray_TRaster  the_raster;
1953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( memory );
1955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1956049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1957049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *araster = (FT_Raster)&the_raster;
1958a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    FT_ZERO( &the_raster );
1959049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1960049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return 0;
1961049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1962049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1963049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1964049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1965049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_done( FT_Raster  raster )
1966049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1967049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* nothing */
1968049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UNUSED( raster );
1969049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1970049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1971055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#else /* !STANDALONE_ */
1972049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1973049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static int
1974049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_new( FT_Memory   memory,
1975049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                   FT_Raster*  araster )
1976049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
197741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    FT_Error      error;
197841371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    gray_PRaster  raster = NULL;
1979049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1980049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1981049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    *araster = 0;
198241371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    if ( !FT_ALLOC( raster, sizeof ( gray_TRaster ) ) )
1983049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1984049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      raster->memory = memory;
198541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      *araster       = (FT_Raster)raster;
1986049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1987049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1988049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return error;
1989049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1990049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1991049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1992049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
1993049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  gray_raster_done( FT_Raster  raster )
1994049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
199541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    FT_Memory  memory = (FT_Memory)((gray_PRaster)raster)->memory;
1996049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1997049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1998049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_FREE( raster );
1999049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2000049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2001055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin#endif /* !STANDALONE_ */
2002049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2003049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2004049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
2005055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin  gray_raster_reset( FT_Raster       raster,
2006055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                     unsigned char*  pool_base,
2007055aee28cedc3631434b2636fc6093c0d4d818abJungshik Shin                     unsigned long   pool_size )
2008049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
2009fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    FT_UNUSED( raster );
2010fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    FT_UNUSED( pool_base );
2011fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    FT_UNUSED( pool_size );
2012fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki  }
2013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2015fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki  static int
2016fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki  gray_raster_set_mode( FT_Raster      raster,
2017fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                        unsigned long  mode,
2018fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki                        void*          args )
2019fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki  {
2020fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    FT_UNUSED( raster );
2021fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    FT_UNUSED( mode );
2022fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    FT_UNUSED( args );
2023fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
2024fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
2025fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    return 0; /* nothing to do */
2026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
2027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2029fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki  FT_DEFINE_RASTER_FUNCS(
2030fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki    ft_grays_raster,
2031fb6b5b10aaa74b8c8974714b41bac35bdd1c772dMakoto Onuki
2032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_GLYPH_FORMAT_OUTLINE,
2033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2034a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    (FT_Raster_New_Func)     gray_raster_new,       /* raster_new      */
2035a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    (FT_Raster_Reset_Func)   gray_raster_reset,     /* raster_reset    */
2036a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    (FT_Raster_Set_Mode_Func)gray_raster_set_mode,  /* raster_set_mode */
2037a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    (FT_Raster_Render_Func)  gray_raster_render,    /* raster_render   */
2038a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin    (FT_Raster_Done_Func)    gray_raster_done       /* raster_done     */
2039a2527749993cb7f25560e4b1266787f1874435d4Jungshik Shin  )
2040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
2042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
20430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
20440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
20450a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* Local Variables: */
20460a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* coding: utf-8    */
20470a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project/* End:             */
2048