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/*                                                                         */
79c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod/*  Copyright 1996-2006, 2008, 2012-2014 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#ifndef  FT_CONFIG_OPTION_NO_ASSEMBLER
449c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /* Provide assembler fragments for performance-critical functions. */
459c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /* These must be defined `static __inline__' with GCC.             */
469c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
479c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#if defined( __CC_ARM ) || defined( __ARMCC__ )  /* RVCT */
489c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
499c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
509c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
519c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /* documentation is in freetype.h */
529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
539c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  static __inline FT_Int32
549c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  FT_MulFix_arm( FT_Int32  a,
559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod                 FT_Int32  b )
569c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  {
579c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    register FT_Int32  t, t2;
589c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    __asm
619c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    {
629c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      smull t2, t,  b,  a           /* (lo=t2,hi=t) = a*b */
639c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      mov   a,  t,  asr #31         /* a   = (hi >> 31) */
649c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      add   a,  a,  #0x8000         /* a  += 0x8000 */
659c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      adds  t2, t2, a               /* t2 += a */
669c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      adc   t,  t,  #0              /* t  += carry */
679c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      mov   a,  t2, lsr #16         /* a   = t2 >> 16 */
689c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      orr   a,  a,  t,  lsl #16     /* a  |= t << 16 */
699c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    }
709c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    return a;
719c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  }
729c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
739c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif /* __CC_ARM || __ARMCC__ */
749c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
759c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#ifdef __GNUC__
779c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
789c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#if defined( __arm__ )                                 && \
799c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    ( !defined( __thumb__ ) || defined( __thumb2__ ) ) && \
809c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    !( defined( __CC_ARM ) || defined( __ARMCC__ ) )
819c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
829c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#define FT_MULFIX_ASSEMBLER  FT_MulFix_arm
839c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
849c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /* documentation is in freetype.h */
859c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
869c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  static __inline__ FT_Int32
879c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  FT_MulFix_arm( FT_Int32  a,
889c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod                 FT_Int32  b )
899c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  {
909c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    register FT_Int32  t, t2;
919c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
929c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
939c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    __asm__ __volatile__ (
949c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "smull  %1, %2, %4, %3\n\t"       /* (lo=%1,hi=%2) = a*b */
959c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "mov    %0, %2, asr #31\n\t"      /* %0  = (hi >> 31) */
969c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#if defined( __clang__ ) && defined( __thumb2__ )
979c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "add.w  %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
989c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#else
999c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "add    %0, %0, #0x8000\n\t"      /* %0 += 0x8000 */
1009c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif
1019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "adds   %1, %1, %0\n\t"           /* %1 += %0 */
1029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "adc    %2, %2, #0\n\t"           /* %2 += carry */
1039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "mov    %0, %1, lsr #16\n\t"      /* %0  = %1 >> 16 */
1049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "orr    %0, %0, %2, lsl #16\n\t"  /* %0 |= %2 << 16 */
1059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      : "=r"(a), "=&r"(t2), "=&r"(t)
1069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      : "r"(a), "r"(b)
1079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      : "cc" );
1089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    return a;
1099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  }
1109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif /* __arm__                      && */
1129c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod       /* ( __thumb2__ || !__thumb__ ) && */
1139c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod       /* !( __CC_ARM || __ARMCC__ )      */
1149c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1159c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1169c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#if defined( __i386__ )
1179c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
1199c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1209c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /* documentation is in freetype.h */
1219c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1229c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  static __inline__ FT_Int32
1239c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  FT_MulFix_i386( FT_Int32  a,
1249c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod                  FT_Int32  b )
1259c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  {
1269c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    register FT_Int32  result;
1279c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1289c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1299c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    __asm__ __volatile__ (
1309c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "imul  %%edx\n"
1319c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "movl  %%edx, %%ecx\n"
1329c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "sarl  $31, %%ecx\n"
1339c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "addl  $0x8000, %%ecx\n"
1349c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "addl  %%ecx, %%eax\n"
1359c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "adcl  $0, %%edx\n"
1369c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "shrl  $16, %%eax\n"
1379c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "shll  $16, %%edx\n"
1389c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "addl  %%edx, %%eax\n"
1399c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      : "=a"(result), "=d"(b)
1409c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      : "a"(a), "d"(b)
1419c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      : "%ecx", "cc" );
1429c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    return result;
1439c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  }
1449c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1459c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif /* i386 */
1469c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1479c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif /* __GNUC__ */
1489c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1499c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1509c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#ifdef _MSC_VER /* Visual C++ */
1519c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#ifdef _M_IX86
1539c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1549c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#define FT_MULFIX_ASSEMBLER  FT_MulFix_i386
1559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1569c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /* documentation is in freetype.h */
1579c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1589c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  static __inline FT_Int32
1599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  FT_MulFix_i386( FT_Int32  a,
1609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod                  FT_Int32  b )
1619c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  {
1629c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    register FT_Int32  result;
1639c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1649c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    __asm
1659c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    {
1669c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      mov eax, a
1679c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      mov edx, b
1689c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      imul edx
1699c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      mov ecx, edx
1709c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      sar ecx, 31
1719c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      add ecx, 8000h
1729c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      add eax, ecx
1739c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      adc edx, 0
1749c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      shr eax, 16
1759c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      shl edx, 16
1769c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      add eax, edx
1779c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      mov result, eax
1789c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    }
1799c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    return result;
1809c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  }
1819c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1829c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif /* _M_IX86 */
1839c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1849c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif /* _MSC_VER */
1859c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1869c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1879c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#if defined( __GNUC__ ) && defined( __x86_64__ )
1889c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1899c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#define FT_MULFIX_ASSEMBLER  FT_MulFix_x86_64
1909c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
1919c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  static __inline__ FT_Int32
1929c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  FT_MulFix_x86_64( FT_Int32  a,
1939c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod                    FT_Int32  b )
1949c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  {
1959c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* Temporarily disable the warning that C90 doesn't support */
1969c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* `long long'.                                             */
1979c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
1989c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#pragma GCC diagnostic push
1999c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#pragma GCC diagnostic ignored "-Wlong-long"
2009c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif
2019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2029c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#if 1
2039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* Technically not an assembly fragment, but GCC does a really good */
2049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* job at inlining it and generating good machine code for it.      */
2059c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    long long  ret, tmp;
2069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2079c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    ret  = (long long)a * b;
2099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    tmp  = ret >> 63;
2109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    ret += 0x8000 + tmp;
2119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2129c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    return (FT_Int32)( ret >> 16 );
2139c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#else
2149c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2159c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* For some reason, GCC 4.6 on Ubuntu 12.04 generates invalid machine  */
2169c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* code from the lines below.  The main issue is that `wide_a' is not  */
2179c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* properly initialized by sign-extending `a'.  Instead, the generated */
2189c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* machine code assumes that the register that contains `a' on input   */
2199c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* can be used directly as a 64-bit value, which is wrong most of the  */
2209c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    /* time.                                                               */
2219c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    long long  wide_a = (long long)a;
2229c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    long long  wide_b = (long long)b;
2239c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    long long  result;
2249c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2259c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2269c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    __asm__ __volatile__ (
2279c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "imul %2, %1\n"
2289c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "mov %1, %0\n"
2299c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "sar $63, %0\n"
2309c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "lea 0x8000(%1, %0), %0\n"
2319c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      "sar $16, %0\n"
2329c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      : "=&r"(result), "=&r"(wide_a)
2339c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      : "r"(wide_b)
2349c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod      : "cc" );
2359c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2369c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    return (FT_Int32)result;
2379c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif
2389c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2399c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#if ( __GNUC__ > 4 ) || ( ( __GNUC__ == 4 ) && ( __GNUC_MINOR__ >= 6 ) )
2409c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#pragma GCC diagnostic pop
2419c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif
2429c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  }
2439c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2449c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif /* __GNUC__ && __x86_64__ */
2459c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2469c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#if defined( __GNUC__ )
2479c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#if ( __GNUC__ > 3 ) || ( ( __GNUC__ == 3 ) && ( __GNUC_MINOR__ >= 4 ) )
2489c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2499c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#if FT_SIZEOF_INT == 4
2509c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2519c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#define FT_MSB_BUILTIN( x )  ( 31 - __builtin_clz( x ) )
2529c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2539c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#elif FT_SIZEOF_LONG == 4
2549c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2559c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#define FT_MSB_BUILTIN( x )  ( 31 - __builtin_clzl( x ) )
2569c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2579c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif
2589c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2599c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif
2609c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif /* __GNUC__ */
2619c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2629c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif /* !FT_CONFIG_OPTION_NO_ASSEMBLER */
2639c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2649c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2659c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#ifdef FT_CONFIG_OPTION_INLINE_MULFIX
2669c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#ifdef FT_MULFIX_ASSEMBLER
2679c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#define FT_MULFIX_INLINED  FT_MULFIX_ASSEMBLER
2689c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif
2699c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif
2709c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
2710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#ifdef FT_MULFIX_INLINED
2720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#undef FT_MulFix
273049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
274049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
275727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease/* we need to emulate a 64-bit data type if a real one isn't available */
276049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
277727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#ifndef FT_LONG64
278049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
279049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  typedef struct  FT_Int64_
280049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
281049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  lo;
282049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  hi;
283049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
284049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  } FT_Int64;
285049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
286727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease#endif /* !FT_LONG64 */
287049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
288049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
289049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*************************************************************************/
290049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
291049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The macro FT_COMPONENT is used in trace mode.  It is an implicit      */
292049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log  */
293049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* messages during execution.                                            */
294049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                       */
295049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#undef  FT_COMPONENT
296049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#define FT_COMPONENT  trace_calc
297049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
298049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
299049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The following three functions are available regardless of whether */
300049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* FT_LONG64 is defined.                                             */
301049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
302049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
303049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
304049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
305049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_RoundFix( FT_Fixed  a )
306049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
307049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( a >= 0 ) ?   ( a + 0x8000L ) & ~0xFFFFL
308049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      : -((-a + 0x8000L ) & ~0xFFFFL );
309049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
310049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
311049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
312049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
313049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
314049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
315049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_CeilFix( FT_Fixed  a )
316049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
317049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( a >= 0 ) ?   ( a + 0xFFFFL ) & ~0xFFFFL
318049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      : -((-a + 0xFFFFL ) & ~0xFFFFL );
319049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
320049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
321049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
322049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
323049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
324049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Fixed )
325049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_FloorFix( FT_Fixed  a )
326049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
327049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( a >= 0 ) ?   a & ~0xFFFFL
328049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      : -((-a) & ~0xFFFFL );
329049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
330049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
331049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
332727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_BASE_DEF ( FT_Int )
333727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_MSB( FT_UInt32 z )
334727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
3359c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#ifdef FT_MSB_BUILTIN
3369c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
3379c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    return FT_MSB_BUILTIN( z );
3389c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
3399c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#else
3409c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
341727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Int shift = 0;
342049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
343727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    /* determine msb bit index in `shift' */
344727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( z >= ( 1L << 16 ) )
345727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
346727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      z     >>= 16;
347727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift  += 16;
348727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
349727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( z >= ( 1L << 8 ) )
350727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
351727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      z     >>= 8;
352727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift  += 8;
353727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
354727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( z >= ( 1L << 4 ) )
355727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
356727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      z     >>= 4;
357727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift  += 4;
358727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
359727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( z >= ( 1L << 2 ) )
360727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
361727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      z     >>= 2;
362727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift  += 2;
363727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
364727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( z >= ( 1L << 1 ) )
365727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
3669c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod   /* z     >>= 1; */
367727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      shift  += 1;
368727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
369049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
370727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return shift;
3719c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod
3729c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod#endif /* FT_MSB_BUILTIN */
373727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  }
374049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
375049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
376727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  /* documentation is in ftcalc.h */
377049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
378727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_BASE_DEF( FT_Fixed )
379727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  FT_Hypot( FT_Fixed  x,
380727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease            FT_Fixed  y )
381727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease  {
382727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    FT_Vector  v;
383049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
384049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
385727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    v.x = x;
386727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    v.y = y;
387049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
388727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    return FT_Vector_Length( &v );
389049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
390049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
391049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
392049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_LONG64
393049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
394049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
395049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
396049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
397049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
398049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_MulDiv( FT_Long  a,
399049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Long  b,
400049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Long  c )
401049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
402049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int   s;
403049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long  d;
404049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
405049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
406049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s = 1;
407049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( a < 0 ) { a = -a; s = -1; }
408049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( b < 0 ) { b = -b; s = -s; }
409049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( c < 0 ) { c = -c; s = -s; }
410049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
411049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    d = (FT_Long)( c > 0 ? ( (FT_Int64)a * b + ( c >> 1 ) ) / c
412049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         : 0x7FFFFFFFL );
413049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
414049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s > 0 ) ? d : -d;
415049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
416049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
417049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
418049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
419049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
420049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Long )
421049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_MulDiv_No_Round( FT_Long  a,
422049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long  b,
423049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long  c )
424049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
425049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int   s;
426049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long  d;
427049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
428049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
429049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s = 1;
430049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( a < 0 ) { a = -a; s = -1; }
431049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( b < 0 ) { b = -b; s = -s; }
432049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( c < 0 ) { c = -c; s = -s; }
433049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
434049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    d = (FT_Long)( c > 0 ? (FT_Int64)a * b / c
435049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         : 0x7FFFFFFFL );
436049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
437049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s > 0 ) ? d : -d;
438049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
439049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
440049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
441049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
442049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
443049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
444049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_MulFix( FT_Long  a,
445049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Long  b )
446049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
447049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_MULFIX_ASSEMBLER
4480a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
4490a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    return FT_MULFIX_ASSEMBLER( a, b );
4500a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
451049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
4520a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
453049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int   s = 1;
454049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long  c;
455049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
456049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
4570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( a < 0 )
4580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
4590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      a = -a;
4600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      s = -1;
4610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
4620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
4630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( b < 0 )
4640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
4650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      b = -b;
4660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      s = -s;
4670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
468049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
469049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    c = (FT_Long)( ( (FT_Int64)a * b + 0x8000L ) >> 16 );
4700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
4710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    return ( s > 0 ) ? c : -c;
4720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
4730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* FT_MULFIX_ASSEMBLER */
474049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
475049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
476049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
477049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
478049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
479049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
480049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_DivFix( FT_Long  a,
481049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Long  b )
482049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
483049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int32   s;
484049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  q;
485049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
486727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease
487049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s = 1;
488727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( a < 0 )
489727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
490727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      a = -a;
491727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      s = -1;
492727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
493727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    if ( b < 0 )
494727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    {
495727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      b = -b;
496727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      s = -s;
497727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease    }
498049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
499049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( b == 0 )
500049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check for division by 0 */
501049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      q = 0x7FFFFFFFL;
502049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
503049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* compute result directly */
504727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      q = (FT_UInt32)( ( ( (FT_UInt64)a << 16 ) + ( b >> 1 ) ) / b );
505049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
506049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s < 0 ? -(FT_Long)q : (FT_Long)q );
507049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
508049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
509049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
510049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* !FT_LONG64 */
511049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
512049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
513049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
514049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_multo64( FT_UInt32  x,
515049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_UInt32  y,
516049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_Int64  *z )
517049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
518049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  lo1, hi1, lo2, hi2, lo, hi, i1, i2;
519049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
520049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
521049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo1 = x & 0x0000FFFFU;  hi1 = x >> 16;
522049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo2 = y & 0x0000FFFFU;  hi2 = y >> 16;
523049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
524049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo = lo1 * lo2;
525049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    i1 = lo1 * hi2;
526049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    i2 = lo2 * hi1;
527049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi = hi1 * hi2;
528049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
529049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Check carry overflow of i1 + i2 */
530049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    i1 += i2;
531049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi += (FT_UInt32)( i1 < i2 ) << 16;
532049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
533049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi += i1 >> 16;
534049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    i1  = i1 << 16;
535049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
536049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Check carry overflow of i1 + lo */
537049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo += i1;
538049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi += ( lo < i1 );
539049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
540049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    z->lo = lo;
541049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    z->hi = hi;
542049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
543049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
544049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
545049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static FT_UInt32
546049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_div64by32( FT_UInt32  hi,
547049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_UInt32  lo,
548049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_UInt32  y )
549049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
550049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  r, q;
551049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     i;
552049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
553049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
554049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    q = 0;
555049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    r = hi;
556049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
557049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( r >= y )
558049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return (FT_UInt32)0x7FFFFFFFL;
559049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
560049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    i = 32;
561049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    do
562049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
563049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      r <<= 1;
564049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      q <<= 1;
565049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      r  |= lo >> 31;
566049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
56741371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier      if ( r >= y )
568049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
569049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        r -= y;
570049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        q |= 1;
571049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
572049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      lo <<= 1;
573049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    } while ( --i );
574049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
575049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return q;
576049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
577049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
578049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
579049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  static void
580049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Add64( FT_Int64*  x,
581049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Int64*  y,
582049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project            FT_Int64  *z )
583049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
584049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    register FT_UInt32  lo, hi;
585049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
586049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
587049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo = x->lo + y->lo;
588049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    hi = x->hi + y->hi + ( lo < x->lo );
589049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
590049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    z->lo = lo;
591049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    z->hi = hi;
592049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
593049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
594049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
595049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
596049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
597049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* The FT_MulDiv function has been optimized thanks to ideas from      */
5989c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /* Graham Asher and Alexei Podtelezhnikov.  The trick is to optimize   */
5999c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /* a rather common case when everything fits within 32-bits.           */
6009c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*                                                                     */
6019c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  We compute 'a*b+c/2', then divide it by 'c'. (positive values)     */
602049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
6039c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  The product of two positive numbers never exceeds the square of    */
6049c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  their mean.  Therefore, we always avoid the overflow by imposing   */
605049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
6069c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  ( a + b ) / 2 <= sqrt( X - c/2 )                                   */
607049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
6089c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  where X = 2^31 - 1.  Now we replace sqrt with a linear function    */
6099c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  that is smaller or equal in the entire range of c from 0 to X;     */
6109c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  it should be equal to sqrt(X) and sqrt(X/2) at the range termini.  */
6119c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  Substituting the linear solution and explicit numbers we get       */
612049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
6139c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  a + b <= 92681.9 - c / 79108.95                                    */
614049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
6159c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  In practice we use a faster and even stronger inequality           */
616049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
6179c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod  /*  a + b <= 92681 - (c >> 16)                                         */
618049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /*                                                                     */
619049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
620049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
621049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_MulDiv( FT_Long  a,
622049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Long  b,
623049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Long  c )
624049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
625049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    long  s;
626049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
627049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
628295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* XXX: this function does not allow 64-bit arguments */
629049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( a == 0 || b == c )
630049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return a;
631049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
632049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s  = a; a = FT_ABS( a );
633049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s ^= b; b = FT_ABS( b );
634049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s ^= c; c = FT_ABS( c );
635049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
6369c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    if ( (FT_ULong)a + (FT_ULong)b <= 92681UL - ( c >> 16 ) && c > 0 )
637049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      a = ( a * b + ( c >> 1 ) ) / c;
638049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
63941371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    else if ( (FT_Int32)c > 0 )
640049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
641049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int64  temp, temp2;
642049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
643049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
644295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp );
645049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
646049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      temp2.hi = 0;
647049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      temp2.lo = (FT_UInt32)(c >> 1);
648049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Add64( &temp, &temp2, &temp );
649295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c );
650049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
651049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
652049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      a = 0x7FFFFFFFL;
653049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
654049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s < 0 ? -a : a );
655049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
656049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
657049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
658049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Long )
659049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_MulDiv_No_Round( FT_Long  a,
660049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long  b,
661049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                      FT_Long  c )
662049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
663049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    long  s;
664049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
665049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
666049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( a == 0 || b == c )
667049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return a;
668049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
669049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s  = a; a = FT_ABS( a );
670049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s ^= b; b = FT_ABS( b );
671049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s ^= c; c = FT_ABS( c );
672049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
6739c745321260bb728ab1cd1c8fd5f075854b2ad49Behdad Esfahbod    if ( (FT_ULong)a + (FT_ULong)b <= 92681UL && c > 0 )
674049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      a = a * b / c;
675049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
67641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    else if ( (FT_Int32)c > 0 )
677049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
678049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int64  temp;
679049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
680049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
681295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      ft_multo64( (FT_Int32)a, (FT_Int32)b, &temp );
682295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      a = ft_div64by32( temp.hi, temp.lo, (FT_Int32)c );
683049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
684049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
685049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      a = 0x7FFFFFFFL;
686049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
687049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s < 0 ? -a : a );
688049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
689049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
690049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
691049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
692049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
693049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
694049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_MulFix( FT_Long  a,
695049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Long  b )
696049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
697049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_MULFIX_ASSEMBLER
6980a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
6990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    return FT_MULFIX_ASSEMBLER( a, b );
7000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#elif 0
7020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /*
7040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  This code is nonportable.  See comment below.
7050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *
7060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  However, on a platform where right-shift of a signed quantity fills
7070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  the leftmost bits by copying the sign bit, it might be faster.
7080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     */
7090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
710049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long   sa, sb;
711049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_ULong  ua, ub;
712049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
713049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
714049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( a == 0 || b == 0x10000L )
715049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return a;
716049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
7170a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /*
7180a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  This is a clever way of converting a signed number `a' into its
7190a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  absolute value (stored back into `a') and its sign.  The sign is
7200a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  stored in `sa'; 0 means `a' was positive or zero, and -1 means `a'
7210a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  was negative.  (Similarly for `b' and `sb').
7220a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *
7230a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  Unfortunately, it doesn't work (at least not portably).
7240a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *
7250a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  It makes the assumption that right-shift on a negative signed value
72641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier     *  fills the leftmost bits by copying the sign bit.  This is wrong.
7270a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  According to K&R 2nd ed, section `A7.8 Shift Operators' on page 206,
7280a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  the result of right-shift of a negative signed value is
7290a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  implementation-defined.  At least one implementation fills the
7300a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  leftmost bits with 0s (i.e., it is exactly the same as an unsigned
7310a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  right shift).  This means that when `a' is negative, `sa' ends up
7320a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  with the value 1 rather than -1.  After that, everything else goes
7330a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     *  wrong.
7340a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project     */
735049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    sa = ( a >> ( sizeof ( a ) * 8 - 1 ) );
736049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    a  = ( a ^ sa ) - sa;
737049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    sb = ( b >> ( sizeof ( b ) * 8 - 1 ) );
738049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b  = ( b ^ sb ) - sb;
739049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
740049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ua = (FT_ULong)a;
741049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ub = (FT_ULong)b;
742049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
743049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ua <= 2048 && ub <= 1048576L )
744049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ua = ( ua * ub + 0x8000U ) >> 16;
745049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
746049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
747049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_ULong  al = ua & 0xFFFFU;
748049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
749049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
750049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ua = ( ua >> 16 ) * ub +  al * ( ub >> 16 ) +
751049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project           ( ( al * ( ub & 0xFFFFU ) + 0x8000U ) >> 16 );
752049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
753049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
754049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    sa ^= sb,
755049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ua  = (FT_ULong)(( ua ^ sa ) - sa);
756049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
757049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return (FT_Long)ua;
7580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#else /* 0 */
7600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Long   s;
7620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_ULong  ua, ub;
7630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( a == 0 || b == 0x10000L )
7660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      return a;
7670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    s  = a; a = FT_ABS( a );
7690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    s ^= b; b = FT_ABS( b );
7700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    ua = (FT_ULong)a;
7720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    ub = (FT_ULong)b;
7730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( ua <= 2048 && ub <= 1048576L )
7750a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      ua = ( ua * ub + 0x8000UL ) >> 16;
7760a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    else
7770a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    {
7780a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      FT_ULong  al = ua & 0xFFFFUL;
7790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7810a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      ua = ( ua >> 16 ) * ub +  al * ( ub >> 16 ) +
7820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project           ( ( al * ( ub & 0xFFFFUL ) + 0x8000UL ) >> 16 );
7830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    }
7840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    return ( s < 0 ? -(FT_Long)ua : (FT_Long)ua );
7860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
7870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project#endif /* 0 */
7880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
789049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
790049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
791049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
792049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in freetype.h */
793049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
794049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Long )
795049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_DivFix( FT_Long  a,
796049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project             FT_Long  b )
797049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
798049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int32   s;
799049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  q;
800049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
801049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
802295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* XXX: this function does not allow 64-bit arguments */
803295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    s  = (FT_Int32)a; a = FT_ABS( a );
804295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    s ^= (FT_Int32)b; b = FT_ABS( b );
805049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
80641371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier    if ( (FT_UInt32)b == 0 )
807049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
808049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* check for division by 0 */
809295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      q = (FT_UInt32)0x7FFFFFFFL;
810049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
811049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( ( a >> 16 ) == 0 )
812049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
813049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* compute result directly */
814727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      q = (FT_UInt32)( ( (FT_ULong)a << 16 ) + ( b >> 1 ) ) / (FT_UInt32)b;
815049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
816049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else
817049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
818049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      /* we need more bits; we have to do it by hand */
819049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int64  temp, temp2;
820049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
82141371e1e39c8528eb0c4bc40683c736e6683e60cEric Vannier
822727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      temp.hi  = (FT_Int32)( a >> 16 );
823727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      temp.lo  = (FT_UInt32)a << 16;
824049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      temp2.hi = 0;
825049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      temp2.lo = (FT_UInt32)( b >> 1 );
826049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Add64( &temp, &temp2, &temp );
827295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      q = ft_div64by32( temp.hi, temp.lo, (FT_Int32)b );
828049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
829049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
830049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
831049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
832049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
833049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
834049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 0
835049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
836049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
837049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
838049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( void )
839049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_MulTo64( FT_Int32   x,
840049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_Int32   y,
841049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project              FT_Int64  *z )
842049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
843049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int32  s;
844049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
845049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
846049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s  = x; x = FT_ABS( x );
847049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s ^= y; y = FT_ABS( y );
848049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
849049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ft_multo64( x, y, z );
850049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
851049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( s < 0 )
852049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
853049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      z->lo = (FT_UInt32)-(FT_Int32)z->lo;
854049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      z->hi = ~z->hi + !( z->lo );
855049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
856049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
857049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
858049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
859049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* apparently, the second version of this code is not compiled correctly */
860049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* on Mac machines with the MPW C compiler..  tsk, tsk, tsk...           */
861049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
862049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#if 1
863049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
864049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Int32 )
865049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Div64by32( FT_Int64*  x,
866049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Int32   y )
867049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
868049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int32   s;
869049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  q, r, i, lo;
870049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
871049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
872049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s  = x->hi;
873049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( s < 0 )
874049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
875049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x->lo = (FT_UInt32)-(FT_Int32)x->lo;
876049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x->hi = ~x->hi + !x->lo;
877049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
878049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s ^= y;  y = FT_ABS( y );
879049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
880049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Shortcut */
881049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( x->hi == 0 )
882049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
883049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( y > 0 )
884049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        q = x->lo / y;
885049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
886049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        q = 0x7FFFFFFFL;
887049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
888049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
889049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
890049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
891049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    r  = x->hi;
892049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    lo = x->lo;
893049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
894049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( r >= (FT_UInt32)y ) /* we know y is to be treated as unsigned here */
895049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ( s < 0 ? 0x80000001UL : 0x7FFFFFFFUL );
896049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             /* Return Max/Min Int32 if division overflow. */
897049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             /* This includes division by zero!            */
898049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    q = 0;
899049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    for ( i = 0; i < 32; i++ )
900049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
901049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      r <<= 1;
902049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      q <<= 1;
903049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      r  |= lo >> 31;
904049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
905049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( r >= (FT_UInt32)y )
906049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
907049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        r -= y;
908049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        q |= 1;
909049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      }
910049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      lo <<= 1;
911049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
912049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
913049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
914049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
915049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
916049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else /* 0 */
917049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
918049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_EXPORT_DEF( FT_Int32 )
919049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Div64by32( FT_Int64*  x,
920049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                FT_Int32   y )
921049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
922049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int32   s;
923049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  q;
924049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
925049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
926049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s  = x->hi;
927049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( s < 0 )
928049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
929049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x->lo = (FT_UInt32)-(FT_Int32)x->lo;
930049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      x->hi = ~x->hi + !x->lo;
931049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
932049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    s ^= y;  y = FT_ABS( y );
933049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
934049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* Shortcut */
935049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( x->hi == 0 )
936049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
937049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( y > 0 )
938049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        q = ( x->lo + ( y >> 1 ) ) / y;
939049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
940049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        q = 0x7FFFFFFFL;
941049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
942049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
943049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
944049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
945049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    q = ft_div64by32( x->hi, x->lo, y );
946049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
947049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( s < 0 ? -(FT_Int32)q : (FT_Int32)q );
948049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
949049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
950049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* 0 */
951049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
952049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* 0 */
953049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
954049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
955049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif /* FT_LONG64 */
9560a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9570a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9580a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* documentation is in ftglyph.h */
9590a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9600a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_EXPORT_DEF( void )
9610a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_Matrix_Multiply( const FT_Matrix*  a,
9620a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project                      FT_Matrix        *b )
9630a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  {
9640a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Fixed  xx, xy, yx, yy;
9650a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9660a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9670a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !a || !b )
9680a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project      return;
9690a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9700a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    xx = FT_MulFix( a->xx, b->xx ) + FT_MulFix( a->xy, b->yx );
9710a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    xy = FT_MulFix( a->xx, b->xy ) + FT_MulFix( a->xy, b->yy );
9720a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    yx = FT_MulFix( a->yx, b->xx ) + FT_MulFix( a->yy, b->yx );
9730a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    yy = FT_MulFix( a->yx, b->xy ) + FT_MulFix( a->yy, b->yy );
9740a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9750a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    b->xx = xx;  b->xy = xy;
9760a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    b->yx = yx;  b->yy = yy;
9770a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  }
9780a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9790a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9800a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  /* documentation is in ftglyph.h */
9810a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9820a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_EXPORT_DEF( FT_Error )
9830a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  FT_Matrix_Invert( FT_Matrix*  matrix )
9840a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  {
9850a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    FT_Pos  delta, xx, yy;
9860a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9870a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9880a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !matrix )
989727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );
9900a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9910a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    /* compute discriminant */
9920a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    delta = FT_MulFix( matrix->xx, matrix->yy ) -
9930a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project            FT_MulFix( matrix->xy, matrix->yx );
9940a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9950a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    if ( !delta )
996727dee178a392d20eb050d0c446f2fcc29058fa1Victoria Lease      return FT_THROW( Invalid_Argument );  /* matrix can't be inverted */
9970a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
9980a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    matrix->xy = - FT_DivFix( matrix->xy, delta );
9990a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    matrix->yx = - FT_DivFix( matrix->yx, delta );
10000a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
10010a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    xx = matrix->xx;
10020a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    yy = matrix->yy;
10030a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
10040a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    matrix->xx = FT_DivFix( yy, delta );
10050a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    matrix->yy = FT_DivFix( xx, delta );
10060a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
10070a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project    return FT_Err_Ok;
10080a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project  }
10090a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
10100a9d06e2b5cf75c3d6ba958026bfdf4745f576d6The Android Open Source Project
1011049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
1012049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1013049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
1014049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Matrix_Multiply_Scaled( const FT_Matrix*  a,
1015049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_Matrix        *b,
1016049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                             FT_Long           scaling )
1017049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1018049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Fixed  xx, xy, yx, yy;
1019049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1020049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long   val = 0x10000L * scaling;
1021049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1022049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1023049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !a || !b )
1024049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
1025049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1026049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    xx = FT_MulDiv( a->xx, b->xx, val ) + FT_MulDiv( a->xy, b->yx, val );
1027049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    xy = FT_MulDiv( a->xx, b->xy, val ) + FT_MulDiv( a->xy, b->yy, val );
1028049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    yx = FT_MulDiv( a->yx, b->xx, val ) + FT_MulDiv( a->yy, b->yx, val );
1029049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    yy = FT_MulDiv( a->yx, b->xy, val ) + FT_MulDiv( a->yy, b->yy, val );
1030049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1031049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b->xx = xx;  b->xy = xy;
1032049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    b->yx = yx;  b->yy = yy;
1033049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1034049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1035049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1036049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
1037049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1038049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( void )
1039049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_Vector_Transform_Scaled( FT_Vector*        vector,
1040049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              const FT_Matrix*  matrix,
1041049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                              FT_Long           scaling )
1042049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1043049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos   xz, yz;
1044049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1045049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Long  val = 0x10000L * scaling;
1046049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1047049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1048049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( !vector || !matrix )
1049049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      return;
1050049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1051049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    xz = FT_MulDiv( vector->x, matrix->xx, val ) +
1052049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_MulDiv( vector->y, matrix->xy, val );
1053049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1054049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    yz = FT_MulDiv( vector->x, matrix->yx, val ) +
1055049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project         FT_MulDiv( vector->y, matrix->yy, val );
1056049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1057049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vector->x = xz;
1058049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    vector->y = yz;
1059049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1060049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1061049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1062ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#if 0
1063ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1064049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
1065049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1066049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Int32 )
1067049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_SqrtFixed( FT_Int32  x )
1068049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1069049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_UInt32  root, rem_hi, rem_lo, test_div;
1070049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Int     count;
1071049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1072049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1073049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    root = 0;
1074049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1075049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( x > 0 )
1076049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1077049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      rem_hi = 0;
1078049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      rem_lo = x;
1079049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      count  = 24;
1080049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      do
1081049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      {
1082049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rem_hi   = ( rem_hi << 2 ) | ( rem_lo >> 30 );
1083049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        rem_lo <<= 2;
1084049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        root   <<= 1;
1085049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        test_div = ( root << 1 ) + 1;
1086049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1087049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        if ( rem_hi >= test_div )
1088049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        {
1089049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          rem_hi -= test_div;
1090049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project          root   += 1;
1091049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        }
1092049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      } while ( --count );
1093049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1094049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1095049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return (FT_Int32)root;
1096049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1097049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1098ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease#endif /* 0 */
1099ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1100049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1101049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
1102049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1103049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Int )
1104049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_corner_orientation( FT_Pos  in_x,
1105049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Pos  in_y,
1106049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Pos  out_x,
1107049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                         FT_Pos  out_y )
1108049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1109295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    FT_Long  result; /* avoid overflow on 16-bit system */
1110049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1111049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1112049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    /* deal with the trivial cases quickly */
1113049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( in_y == 0 )
1114049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1115049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( in_x >= 0 )
1116049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = out_y;
1117049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
1118049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -out_y;
1119049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1120049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( in_x == 0 )
1121049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1122049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( in_y >= 0 )
1123049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -out_x;
1124049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
1125049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = out_x;
1126049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1127049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( out_y == 0 )
1128049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1129049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( out_x >= 0 )
1130049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = in_y;
1131049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
1132049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -in_y;
1133049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1134049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else if ( out_x == 0 )
1135049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1136049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( out_y >= 0 )
1137049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -in_x;
1138049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
1139049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result =  in_x;
1140049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1141049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    else /* general case */
1142049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    {
1143049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#ifdef FT_LONG64
1144049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1145049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int64  delta = (FT_Int64)in_x * out_y - (FT_Int64)in_y * out_x;
1146049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1147049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1148049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( delta == 0 )
1149049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = 0;
1150049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
1151049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = 1 - 2 * ( delta < 0 );
1152049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1153049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#else
1154049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1155049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      FT_Int64  z1, z2;
1156049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1157049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1158295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      /* XXX: this function does not allow 64-bit arguments */
1159295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      ft_multo64( (FT_Int32)in_x, (FT_Int32)out_y, &z1 );
1160295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner      ft_multo64( (FT_Int32)in_y, (FT_Int32)out_x, &z2 );
1161049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1162049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      if ( z1.hi > z2.hi )
1163049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = +1;
1164049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( z1.hi < z2.hi )
1165049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -1;
1166049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( z1.lo > z2.lo )
1167049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = +1;
1168049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else if ( z1.lo < z2.lo )
1169049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = -1;
1170049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      else
1171049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project        result = 0;
1172049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1173049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project#endif
1174049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    }
1175049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1176295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    /* XXX: only the sign of return value, +1/0/-1 must be used */
1177295ffce55e0198e7a9f7d46b33f5c2b4147bf821David 'Digit' Turner    return (FT_Int)result;
1178049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1179049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1180049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1181049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  /* documentation is in ftcalc.h */
1182049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1183049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  FT_BASE_DEF( FT_Int )
1184049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  ft_corner_is_flat( FT_Pos  in_x,
1185049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pos  in_y,
1186049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pos  out_x,
1187049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project                     FT_Pos  out_y )
1188049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  {
1189049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos  ax = in_x;
1190049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos  ay = in_y;
1191049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1192049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    FT_Pos  d_in, d_out, d_corner;
1193049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1194049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1195ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* We approximate the Euclidean metric (sqrt(x^2 + y^2)) with */
1196ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* the Taxicab metric (|x| + |y|), which can be computed much */
1197ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* faster.  If one of the two vectors is much longer than the */
1198ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* other one, the direction of the shorter vector doesn't     */
1199ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* influence the result any more.                             */
1200ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*                                                            */
1201ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*                 corner                                     */
1202ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*       x---------------------------x                        */
1203ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*        \                      /                            */
1204ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*         \                /                                 */
1205ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*      in  \          /  out                                 */
1206ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*           \    /                                           */
1207ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*            o                                               */
1208ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*              Point                                         */
1209ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*                                                            */
1210ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1211049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ax < 0 )
1212049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ax = -ax;
1213049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ay < 0 )
1214049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ay = -ay;
1215ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    d_in = ax + ay;  /* d_in = || in || */
1216049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1217049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ax = out_x;
1218049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ax < 0 )
1219049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ax = -ax;
1220049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ay = out_y;
1221049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ay < 0 )
1222049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ay = -ay;
1223ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    d_out = ax + ay;  /* d_out = || out || */
1224049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1225049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ax = out_x + in_x;
1226049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ax < 0 )
1227049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ax = -ax;
1228049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    ay = out_y + in_y;
1229049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    if ( ay < 0 )
1230049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project      ay = -ay;
1231ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    d_corner = ax + ay;  /* d_corner = || in + out || */
1232ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease
1233ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /* now do a simple length comparison: */
1234ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*                                    */
1235ec0bab5697bb31ba980810145f62e3799946ec60Victoria Lease    /*   d_in + d_out < 17/16 d_corner    */
1236049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1237049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project    return ( d_in + d_out - d_corner ) < ( d_corner >> 4 );
1238049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project  }
1239049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1240049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project
1241049d6fea481044fcc000e7782e5bc7046fc70844The Android Open Source Project/* END */
1242