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