1049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/***************************************************************************/
2049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
3049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*  ftcalc.c                                                               */
4049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
5049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*    Arithmetic computations (body).                                      */
6049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/*                                                                         */
7ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki/*  Copyright 1996-2015 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  /* Support for 1-complement arithmetic has been totally dropped in this  */
21049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* release.  You can still write your own code if you need it.           */
22049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
23049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
24049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
25049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
26049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
27049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* Implementing basic computation routines.                              */
28049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
29049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* FT_MulDiv(), FT_MulFix(), FT_DivFix(), FT_RoundFix(), FT_CeilFix(),   */
30049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* and FT_FloorFix() are declared in freetype.h.                         */
31049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
32049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
33049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
34049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
35049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include <ft2build.h>
360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#include FT_GLYPH_H
37727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#include FT_TRIGONOMETRY_H
38049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_CALC_H
39049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_DEBUG_H
40049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#include FT_INTERNAL_OBJECTS_H
41049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
429c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
439c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#ifdef FT_MULFIX_ASSEMBLER
440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#undef FT_MulFix
45049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
46049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
47727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* we need to emulate a 64-bit data type if a real one isn't available */
48049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
49727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifndef FT_LONG64
50049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
51049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  FT_Int64_
52049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
53049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  lo;
54049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  hi;
55049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
56049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } FT_Int64;
57049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
58727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* !FT_LONG64 */
59049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
60049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
61049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
62049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
63049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
64049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
65049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* messages during execution.                                            */
66049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
67049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
68049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_calc
69049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
70049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
71ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /* transfer sign leaving a positive number */
72ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki#define FT_MOVE_SIGN( x, s ) \
73ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  FT_BEGIN_STMNT             \
74ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( x < 0 )             \
75ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    {                        \
76ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      x = -x;                \
77ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      s = -s;                \
78ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    }                        \
79ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  FT_END_STMNT
80ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
81049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The following three functions are available regardless of whether */
82049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* FT_LONG64 is defined.                                             */
83049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
84049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
85049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
86049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
87049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_RoundFix( FT_Fixed  a )
88049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
89ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return a >= 0 ?   ( a + 0x8000L ) & ~0xFFFFL
90ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                  : -((-a + 0x8000L ) & ~0xFFFFL );
91049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
92049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
93049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
94049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
95049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
96049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
97049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CeilFix( FT_Fixed  a )
98049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
99ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return a >= 0 ?   ( a + 0xFFFFL ) & ~0xFFFFL
100ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                  : -((-a + 0xFFFFL ) & ~0xFFFFL );
101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_FloorFix( FT_Fixed  a )
108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
109ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return a >= 0 ?   a & ~0xFFFFL
110ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                  : -((-a) & ~0xFFFFL );
111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
113ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki#ifndef FT_MSB
114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
115727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_BASE_DEF ( FT_Int )
116727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_MSB( FT_UInt32 z )
117727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
118ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Int  shift = 0;
1199c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
121727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* determine msb bit index in `shift' */
122ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( z & 0xFFFF0000UL )
123727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
124727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      z     >>= 16;
125727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift  += 16;
126727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
127ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( z & 0x0000FF00UL )
128727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
129727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      z     >>= 8;
130727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift  += 8;
131727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
132ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( z & 0x000000F0UL )
133727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
134727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      z     >>= 4;
135727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift  += 4;
136727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
137ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( z & 0x0000000CUL )
138727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
139727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      z     >>= 2;
140727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift  += 2;
141727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
142ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( z & 0x00000002UL )
143727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
1449c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod   /* z     >>= 1; */
145727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift  += 1;
146727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
148727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return shift;
149727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
151ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki#endif /* !FT_MSB */
152ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
154727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* documentation is in ftcalc.h */
155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
156727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_BASE_DEF( FT_Fixed )
157727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_Hypot( FT_Fixed  x,
158727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_Fixed  y )
159727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
160727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Vector  v;
161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
163727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    v.x = x;
164727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    v.y = y;
165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
166727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_Vector_Length( &v );
167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_LONG64
171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
176ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  FT_MulDiv( FT_Long  a_,
177ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki             FT_Long  b_,
178ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki             FT_Long  c_ )
179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
180ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Int     s = 1;
181ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UInt64  a, b, c, d;
182ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Long    d_;
183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
185ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( a_, s );
186ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( b_, s );
187ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( c_, s );
188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
189ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a = (FT_UInt64)a_;
190ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    b = (FT_UInt64)b_;
191ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    c = (FT_UInt64)c_;
192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
193ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    d = c > 0 ? ( a * b + ( c >> 1 ) ) / c
194ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki              : 0x7FFFFFFFUL;
195ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
196ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    d_ = (FT_Long)d;
197ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
198ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return s < 0 ? -d_ : d_;
199049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
200049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
201049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
202049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
203049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
204049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Long )
205ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  FT_MulDiv_No_Round( FT_Long  a_,
206ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                      FT_Long  b_,
207ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                      FT_Long  c_ )
208049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
209ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Int     s = 1;
210ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UInt64  a, b, c, d;
211ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Long    d_;
212ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
214ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( a_, s );
215ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( b_, s );
216ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( c_, s );
217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
218ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a = (FT_UInt64)a_;
219ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    b = (FT_UInt64)b_;
220ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    c = (FT_UInt64)c_;
221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
222ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    d = c > 0 ? a * b / c
223ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki              : 0x7FFFFFFFUL;
224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
225ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    d_ = (FT_Long)d;
226ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
227ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return s < 0 ? -d_ : d_;
228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
231049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
232049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
233049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
234ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  FT_MulFix( FT_Long  a_,
235ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki             FT_Long  b_ )
236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_MULFIX_ASSEMBLER
2380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
239ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return FT_MULFIX_ASSEMBLER( a_, b_ );
2400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
2420a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
243ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Int     s = 1;
244ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UInt64  a, b, c;
245ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Long    c_;
246049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
247049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
248ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( a_, s );
249ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( b_, s );
2500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
251ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a = (FT_UInt64)a_;
252ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    b = (FT_UInt64)b_;
253ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
254ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    c = ( a * b + 0x8000UL ) >> 16;
255049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
256ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    c_ = (FT_Long)c;
2570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
258ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return s < 0 ? -c_ : c_;
2590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
2600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* FT_MULFIX_ASSEMBLER */
261049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
262049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
263049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
264049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
265049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
266049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
267ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  FT_DivFix( FT_Long  a_,
268ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki             FT_Long  b_ )
269049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
270ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Int     s = 1;
271ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UInt64  a, b, q;
272ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Long    q_;
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
274727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
275ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( a_, s );
276ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( b_, s );
277049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
278ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a = (FT_UInt64)a_;
279ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    b = (FT_UInt64)b_;
280ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
281ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    q = b > 0 ? ( ( a << 16 ) + ( b >> 1 ) ) / b
282ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki              : 0x7FFFFFFFUL;
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
284ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    q_ = (FT_Long)q;
285ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
286ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return s < 0 ? -q_ : q_;
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !FT_LONG64 */
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_multo64( FT_UInt32  x,
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_UInt32  y,
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_Int64  *z )
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  lo1, hi1, lo2, hi2, lo, hi, i1, i2;
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo1 = x & 0x0000FFFFU;  hi1 = x >> 16;
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo2 = y & 0x0000FFFFU;  hi2 = y >> 16;
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo = lo1 * lo2;
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    i1 = lo1 * hi2;
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    i2 = lo2 * hi1;
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi = hi1 * hi2;
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Check carry overflow of i1 + i2 */
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    i1 += i2;
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi += (FT_UInt32)( i1 < i2 ) << 16;
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi += i1 >> 16;
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    i1  = i1 << 16;
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Check carry overflow of i1 + lo */
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo += i1;
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi += ( lo < i1 );
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    z->lo = lo;
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    z->hi = hi;
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_UInt32
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_div64by32( FT_UInt32  hi,
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_UInt32  lo,
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_UInt32  y )
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  r, q;
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     i;
332049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
333049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
334ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( hi >= y )
335049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return (FT_UInt32)0x7FFFFFFFL;
336049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
337ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* We shift as many bits as we can into the high register, perform     */
338ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* 32-bit division with modulo there, then work through the remaining  */
339ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* bits with long division. This optimization is especially noticeable */
340ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* for smaller dividends that barely use the high register.            */
341ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
342ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    i = 31 - FT_MSB( hi );
343ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    r = ( hi << i ) | ( lo >> ( 32 - i ) ); lo <<= i; /* left 64-bit shift */
344ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    q = r / y;
345ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    r -= q * y;   /* remainder */
346ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
347ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    i = 32 - i;   /* bits remaining in low register */
348049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    do
349049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
350049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      q <<= 1;
351ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      r   = ( r << 1 ) | ( lo >> 31 ); lo <<= 1;
352049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
35341371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      if ( r >= y )
354049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
355049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        r -= y;
356049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        q |= 1;
357049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
358049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    } while ( --i );
359049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
360049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return q;
361049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
362049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
363049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
364049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
365049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Add64( FT_Int64*  x,
366049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Int64*  y,
367049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Int64  *z )
368049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
369ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UInt32  lo, hi;
370049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
371049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
372049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo = x->lo + y->lo;
373049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi = x->hi + y->hi + ( lo < x->lo );
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    z->lo = lo;
376049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    z->hi = hi;
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
378049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
379049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
380ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  The FT_MulDiv function has been optimized thanks to ideas from     */
381ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  Graham Asher and Alexei Podtelezhnikov.  The trick is to optimize  */
382ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  a rather common case when everything fits within 32-bits.          */
3839c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*                                                                     */
384ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  We compute 'a*b+c/2', then divide it by 'c' (all positive values). */
385049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
3869c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  The product of two positive numbers never exceeds the square of    */
387ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  its mean values.  Therefore, we always avoid the overflow by       */
388ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  imposing                                                           */
389ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*                                                                     */
390ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*    (a + b) / 2 <= sqrt(X - c/2)    ,                                */
391ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*                                                                     */
392ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  where X = 2^32 - 1, the maximum unsigned 32-bit value, and using   */
393ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  unsigned arithmetic.  Now we replace `sqrt' with a linear function */
394ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  that is smaller or equal for all values of c in the interval       */
395ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  [0;X/2]; it should be equal to sqrt(X) and sqrt(3X/4) at the       */
396ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  endpoints.  Substituting the linear solution and explicit numbers  */
397ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  we get                                                             */
398ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*                                                                     */
399ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*    a + b <= 131071.99 - c / 122291.84    .                          */
400ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*                                                                     */
401ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  In practice, we should use a faster and even stronger inequality   */
402ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*                                                                     */
403ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*    a + b <= 131071 - (c >> 16)                                      */
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
405ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  or, alternatively,                                                 */
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
407ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*    a + b <= 129894 - (c >> 17)    .                                 */
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
409ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  FT_MulFix, on the other hand, is optimized for a small value of    */
410ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  the first argument, when the second argument can be much larger.   */
411ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  This can be achieved by scaling the second argument and the limit  */
412ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  in the above inequalities.  For example,                           */
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
414ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*    a + (b >> 8) <= (131071 >> 4)                                    */
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
416ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  covers the practical range of use. The actual test below is a bit  */
417ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  tighter to avoid the border case overflows.                        */
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
419ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  In the case of FT_DivFix, the exact overflow check                 */
420ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*                                                                     */
421ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*    a << 16 <= X - c/2                                               */
422ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*                                                                     */
423ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*  is scaled down by 2^16 and we use                                  */
424ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*                                                                     */
425ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /*    a <= 65535 - (c >> 17)    .                                      */
426ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
427ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  /* documentation is in freetype.h */
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
430ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  FT_MulDiv( FT_Long  a_,
431ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki             FT_Long  b_,
432ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki             FT_Long  c_ )
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
434ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Int     s = 1;
435ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UInt32  a, b, c;
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
438295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* XXX: this function does not allow 64-bit arguments */
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
440ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( a_ == 0 || b_ == c_ )
441ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      return a_;
442ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
443ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( a_, s );
444ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( b_, s );
445ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( c_, s );
446ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
447ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a = (FT_UInt32)a_;
448ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    b = (FT_UInt32)b_;
449ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    c = (FT_UInt32)c_;
450049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
451ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( c == 0 )
452ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      a = 0x7FFFFFFFUL;
453ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
454ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    else if ( a + b <= 129894UL - ( c >> 17 ) )
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      a = ( a * b + ( c >> 1 ) ) / c;
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
457ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    else
458049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
459049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int64  temp, temp2;
460049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
461049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
462ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      ft_multo64( a, b, &temp );
463049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
464049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      temp2.hi = 0;
465ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      temp2.lo = c >> 1;
466ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
467049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Add64( &temp, &temp2, &temp );
468ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
469ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      /* last attempt to ditch long division */
470ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      a = temp.hi == 0 ? temp.lo / c
471ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                       : ft_div64by32( temp.hi, temp.lo, c );
472049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
473049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
474ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a_ = (FT_Long)a;
475ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
476ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return s < 0 ? -a_ : a_;
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Long )
481ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  FT_MulDiv_No_Round( FT_Long  a_,
482ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                      FT_Long  b_,
483ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                      FT_Long  c_ )
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
485ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Int     s = 1;
486ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UInt32  a, b, c;
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
488049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
489ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* XXX: this function does not allow 64-bit arguments */
490ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
491ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( a_ == 0 || b_ == c_ )
492ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      return a_;
493ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
494ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( a_, s );
495ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( b_, s );
496ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( c_, s );
497ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
498ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a = (FT_UInt32)a_;
499ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    b = (FT_UInt32)b_;
500ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    c = (FT_UInt32)c_;
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
502ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( c == 0 )
503ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      a = 0x7FFFFFFFUL;
504049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
505ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    else if ( a + b <= 131071UL )
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      a = a * b / c;
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
508ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    else
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int64  temp;
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
513ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      ft_multo64( a, b, &temp );
514ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
515ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      /* last attempt to ditch long division */
516ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      a = temp.hi == 0 ? temp.lo / c
517ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki                       : ft_div64by32( temp.hi, temp.lo, c );
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
520ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a_ = (FT_Long)a;
521ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
522ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return s < 0 ? -a_ : a_;
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
529ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  FT_MulFix( FT_Long  a_,
530ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki             FT_Long  b_ )
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_MULFIX_ASSEMBLER
5330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
534ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return FT_MULFIX_ASSEMBLER( a_, b_ );
5350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
5360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#elif 0
5370a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
5380a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /*
5390a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  This code is nonportable.  See comment below.
5400a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *
5410a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  However, on a platform where right-shift of a signed quantity fills
5420a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  the leftmost bits by copying the sign bit, it might be faster.
5430a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     */
5440a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
545ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Long    sa, sb;
546ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UInt32  a, b;
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
549ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( a_ == 0 || b_ == 0x10000L )
550ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      return a_;
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
5520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /*
5530a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  This is a clever way of converting a signed number `a' into its
5540a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  absolute value (stored back into `a') and its sign.  The sign is
5550a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  stored in `sa'; 0 means `a' was positive or zero, and -1 means `a'
5560a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  was negative.  (Similarly for `b' and `sb').
5570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *
5580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  Unfortunately, it doesn't work (at least not portably).
5590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *
5600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  It makes the assumption that right-shift on a negative signed value
56141371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier     *  fills the leftmost bits by copying the sign bit.  This is wrong.
5620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206,
5630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  the result of right-shift of a negative signed value is
5640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  implementation-defined.  At least one implementation fills the
5650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  leftmost bits with 0s (i.e., it is exactly the same as an unsigned
5660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  right shift).  This means that when `a' is negative, `sa' ends up
5670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  with the value 1 rather than -1.  After that, everything else goes
5680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  wrong.
5690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     */
570ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    sa = ( a_ >> ( sizeof ( a_ ) * 8 - 1 ) );
571ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a  = ( a_ ^ sa ) - sa;
572ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    sb = ( b_ >> ( sizeof ( b_ ) * 8 - 1 ) );
573ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    b  = ( b_ ^ sb ) - sb;
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
575ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a = (FT_UInt32)a_;
576ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    b = (FT_UInt32)b_;
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
578ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( a + ( b >> 8 ) <= 8190UL )
579ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      a = ( a * b + 0x8000U ) >> 16;
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
582ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      FT_UInt32  al = a & 0xFFFFUL;
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
585ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      a = ( a >> 16 ) * b + al * ( b >> 16 ) +
586ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki          ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 );
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
589ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    sa ^= sb;
590ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a   = ( a ^ sa ) - sa;
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
592ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return (FT_Long)a;
5930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
5940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#else /* 0 */
5950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
596ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Int     s = 1;
597ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UInt32  a, b;
598ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
5990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
600ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* XXX: this function does not allow 64-bit arguments */
6010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
602ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( a_ == 0 || b_ == 0x10000L )
603ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      return a_;
6040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
605ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( a_, s );
606ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( b_, s );
6070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
608ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a = (FT_UInt32)a_;
609ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    b = (FT_UInt32)b_;
6100a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
611ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( a + ( b >> 8 ) <= 8190UL )
612ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      a = ( a * b + 0x8000UL ) >> 16;
6130a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    else
6140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
615ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      FT_UInt32  al = a & 0xFFFFUL;
6160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
6170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
618ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      a = ( a >> 16 ) * b + al * ( b >> 16 ) +
619ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki          ( ( al * ( b & 0xFFFFUL ) + 0x8000UL ) >> 16 );
6200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
6210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
622ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a_ = (FT_Long)a;
623ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
624ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return s < 0 ? -a_ : a_;
6250a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
6260a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* 0 */
6270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
628049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
634ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki  FT_DivFix( FT_Long  a_,
635ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki             FT_Long  b_ )
636049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
637ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Int     s = 1;
638ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_UInt32  a, b, q;
639ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Long    q_;
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
642295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* XXX: this function does not allow 64-bit arguments */
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
644ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( a_, s );
645ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_MOVE_SIGN( b_, s );
646ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
647ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    a = (FT_UInt32)a_;
648ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    b = (FT_UInt32)b_;
649ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
650ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    if ( b == 0 )
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check for division by 0 */
653ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      q = 0x7FFFFFFFUL;
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
655ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    else if ( a <= 65535UL - ( b >> 17 ) )
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* compute result directly */
658ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      q = ( ( a << 16 ) + ( b >> 1 ) ) / b;
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we need more bits; we have to do it by hand */
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int64  temp, temp2;
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
66541371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
666ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      temp.hi  = a >> 16;
667ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      temp.lo  = a << 16;
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      temp2.hi = 0;
669ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      temp2.lo = b >> 1;
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
671ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      FT_Add64( &temp, &temp2, &temp );
672ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      q = ft_div64by32( temp.hi, temp.lo, b );
673049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
675ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    q_ = (FT_Long)q;
676049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
677ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return s < 0 ? -q_ : q_;
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
681ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki#endif /* !FT_LONG64 */
6820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
6830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
6840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* documentation is in ftglyph.h */
6850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
6860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_EXPORT_DEF( void )
6870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_Matrix_Multiply( const FT_Matrix*  a,
6880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      FT_Matrix        *b )
6890a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  {
6900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Fixed  xx, xy, yx, yy;
6910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
6920a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
6930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !a || !b )
6940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      return;
6950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
6960a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx );
6970a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy );
6980a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx );
6990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy );
7000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    b->xx = xx;  b->xy = xy;
7020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    b->yx = yx;  b->yy = yy;
7030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  }
7040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* documentation is in ftglyph.h */
7070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
7090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_Matrix_Invert( FT_Matrix*  matrix )
7100a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  {
7110a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Pos  delta, xx, yy;
7120a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7130a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7140a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !matrix )
715727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
7160a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* compute discriminant */
7180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    delta = FT_MulFix( matrix->xx, matrix->yy ) -
7190a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_MulFix( matrix->xy, matrix->yx );
7200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !delta )
722727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );  /* matrix can't be inverted */
7230a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7240a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    matrix->xy = - FT_DivFix( matrix->xy, delta );
7250a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    matrix->yx = - FT_DivFix( matrix->yx, delta );
7260a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    xx = matrix->xx;
7280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    yy = matrix->yy;
7290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    matrix->xx = FT_DivFix( yy, delta );
7310a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    matrix->yy = FT_DivFix( xx, delta );
7320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    return FT_Err_Ok;
7340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  }
7350a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7360a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Matrix_Multiply_Scaled( const FT_Matrix*  a,
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_Matrix        *b,
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_Long           scaling )
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed  xx, xy, yx, yy;
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long   val = 0x10000L * scaling;
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !a || !b )
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val );
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val );
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val );
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val );
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b->xx = xx;  b->xy = xy;
758049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b->yx = yx;  b->yy = yy;
759049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
760049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
761049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
762049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
763049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
764049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
765049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_Transform_Scaled( FT_Vector*        vector,
766049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const FT_Matrix*  matrix,
767049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              FT_Long           scaling )
768049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
769049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos   xz, yz;
770049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
771049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long  val = 0x10000L * scaling;
772049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
773049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
774049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !vector || !matrix )
775049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
776049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
777049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    xz = FT_MulDiv( vector->x, matrix->xx, val ) +
778049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_MulDiv( vector->y, matrix->xy, val );
779049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
780049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    yz = FT_MulDiv( vector->x, matrix->yx, val ) +
781049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_MulDiv( vector->y, matrix->yy, val );
782049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
783049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vector->x = xz;
784049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vector->y = yz;
785049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
786049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
787049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
788ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#if 0
789ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Int32 )
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_SqrtFixed( FT_Int32  x )
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  root, rem_hi, rem_lo, test_div;
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     count;
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    root = 0;
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( x > 0 )
802049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
803049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      rem_hi = 0;
804ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      rem_lo = (FT_UInt32)x;
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      count  = 24;
806049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      do
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rem_hi   = ( rem_hi << 2 ) | ( rem_lo >> 30 );
809049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rem_lo <<= 2;
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        root   <<= 1;
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        test_div = ( root << 1 ) + 1;
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( rem_hi >= test_div )
814049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          rem_hi -= test_div;
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          root   += 1;
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      } while ( --count );
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
821049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return (FT_Int32)root;
822049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
823049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
824ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif /* 0 */
825ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
827049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Int )
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_corner_orientation( FT_Pos  in_x,
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Pos  in_y,
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Pos  out_x,
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Pos  out_y )
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
835295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Long  result; /* avoid overflow on 16-bit system */
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* deal with the trivial cases quickly */
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( in_y == 0 )
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( in_x >= 0 )
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = out_y;
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -out_y;
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( in_x == 0 )
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( in_y >= 0 )
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -out_x;
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = out_x;
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( out_y == 0 )
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( out_x >= 0 )
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = in_y;
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -in_y;
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( out_x == 0 )
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( out_y >= 0 )
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -in_x;
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result =  in_x;
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else /* general case */
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_LONG64
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int64  delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( delta == 0 )
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = 0;
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = 1 - 2 * ( delta < 0 );
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int64  z1, z2;
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
884295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      /* XXX: this function does not allow 64-bit arguments */
885ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      ft_multo64( (FT_UInt32)in_x, (FT_UInt32)out_y, &z1 );
886ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki      ft_multo64( (FT_UInt32)in_y, (FT_UInt32)out_x, &z2 );
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( z1.hi > z2.hi )
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = +1;
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( z1.hi < z2.hi )
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -1;
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( z1.lo > z2.lo )
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = +1;
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( z1.lo < z2.lo )
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -1;
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = 0;
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
902295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* XXX: only the sign of return value, +1/0/-1 must be used */
903295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    return (FT_Int)result;
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Int )
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_corner_is_flat( FT_Pos  in_x,
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pos  in_y,
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pos  out_x,
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pos  out_y )
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
915ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Pos  ax = in_x + out_x;
916ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Pos  ay = in_y + out_y;
917ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
918ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    FT_Pos  d_in, d_out, d_hypot;
919ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
920ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
921ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* The idea of this function is to compare the length of the */
922ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* hypotenuse with the `in' and `out' length.  The `corner'  */
923ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* represented by `in' and `out' is flat if the hypotenuse's */
924ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* length isn't too large.                                   */
925ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /*                                                           */
926ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* This approach has the advantage that the angle between    */
927ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* `in' and `out' is not checked.  In case one of the two    */
928ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* vectors is `dominant', this is, much larger than the      */
929ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /* other vector, we thus always have a flat corner.          */
930ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /*                                                           */
931ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /*                hypotenuse                                 */
932ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /*       x---------------------------x                       */
933ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /*        \                      /                           */
934ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /*         \                /                                */
935ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /*      in  \          /  out                                */
936ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /*           \    /                                          */
937ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /*            o                                              */
938ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /*              Point                                        */
939ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki
940ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    d_in    = FT_HYPOT(  in_x,  in_y );
941ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    d_out   = FT_HYPOT( out_x, out_y );
942ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    d_hypot = FT_HYPOT(    ax,    ay );
943ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
944ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* now do a simple length comparison: */
945ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*                                    */
946ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    /*   d_in + d_out < 17/16 d_hypot     */
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
948ec62c527eb34ee4481a0153ceb42dfd35d7e1d26Makoto Onuki    return ( d_in + d_out - d_hypot ) < ( d_hypot >> 4 );
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
953