Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-11 10:26:10

0001 //========================================================================
0002 //
0003 // SplashMath.h
0004 //
0005 //========================================================================
0006 
0007 //========================================================================
0008 //
0009 // Modified under the Poppler project - http://poppler.freedesktop.org
0010 //
0011 // All changes made under the Poppler project to this file are licensed
0012 // under GPL version 2 or later
0013 //
0014 // Copyright (C) 2009-2011 Albert Astals Cid <aacid@kde.org>
0015 // Copyright (C) 2017 Adrian Johnson <ajohnson@redneon.com>
0016 // Copyright (C) 2020 Jean Ghali <jghali@libertysurf.fr>
0017 //
0018 // To see a description of the changes please see the Changelog file that
0019 // came with your tarball or type make ChangeLog if you are building from git
0020 //
0021 //========================================================================
0022 
0023 #ifndef SPLASHMATH_H
0024 #define SPLASHMATH_H
0025 
0026 #include "poppler-config.h"
0027 
0028 #include <cmath>
0029 #include "SplashTypes.h"
0030 
0031 static inline SplashCoord splashAbs(SplashCoord x)
0032 {
0033 #if defined(USE_FLOAT)
0034     return fabsf(x);
0035 #else
0036     return fabs(x);
0037 #endif
0038 }
0039 
0040 static inline int splashFloor(SplashCoord x)
0041 {
0042 #if defined(USE_FLOAT)
0043     return (int)floorf(x);
0044 #elif defined(__GNUC__) && defined(__i386__)
0045     // floor() and (int)() are implemented separately, which results
0046     // in changing the FPCW multiple times - so we optimize it with
0047     // some inline assembly
0048     unsigned short oldCW, newCW, t;
0049     int result;
0050 
0051     __asm__ volatile("fldl   %4\n"
0052                      "fnstcw %0\n"
0053                      "movw   %0, %3\n"
0054                      "andw   $0xf3ff, %3\n"
0055                      "orw    $0x0400, %3\n"
0056                      "movw   %3, %1\n" // round down
0057                      "fldcw  %1\n"
0058                      "fistpl %2\n"
0059                      "fldcw  %0\n"
0060                      : "=m"(oldCW), "=m"(newCW), "=m"(result), "=r"(t)
0061                      : "m"(x));
0062     return result;
0063 #elif defined(_WIN32) && defined(_M_IX86)
0064     // floor() and (int)() are implemented separately, which results
0065     // in changing the FPCW multiple times - so we optimize it with
0066     // some inline assembly
0067     unsigned short oldCW, newCW;
0068     int result;
0069 
0070     __asm fld QWORD PTR x;
0071     __asm fnstcw WORD PTR oldCW;
0072     __asm mov ax, WORD PTR oldCW;
0073     __asm and ax, 0xf3ff;
0074     __asm or ax, 0x0400;
0075     __asm mov WORD PTR newCW, ax; // round down
0076     __asm fldcw WORD PTR newCW;
0077     __asm fistp DWORD PTR result;
0078     __asm fldcw WORD PTR oldCW;
0079     return result;
0080 #else
0081     if (x > 0) {
0082         return (int)x;
0083     } else {
0084         return (int)floor(x);
0085     }
0086 #endif
0087 }
0088 
0089 static inline int splashCeil(SplashCoord x)
0090 {
0091 #if defined(USE_FLOAT)
0092     return (int)ceilf(x);
0093 #elif defined(__GNUC__) && defined(__i386__)
0094     // ceil() and (int)() are implemented separately, which results
0095     // in changing the FPCW multiple times - so we optimize it with
0096     // some inline assembly
0097     unsigned short oldCW, newCW, t;
0098     int result;
0099 
0100     __asm__ volatile("fldl   %4\n"
0101                      "fnstcw %0\n"
0102                      "movw   %0, %3\n"
0103                      "andw   $0xf3ff, %3\n"
0104                      "orw    $0x0800, %3\n"
0105                      "movw   %3, %1\n" // round up
0106                      "fldcw  %1\n"
0107                      "fistpl %2\n"
0108                      "fldcw  %0\n"
0109                      : "=m"(oldCW), "=m"(newCW), "=m"(result), "=r"(t)
0110                      : "m"(x));
0111     return result;
0112 #elif defined(_WIN32) && defined(_M_IX86)
0113     // ceil() and (int)() are implemented separately, which results
0114     // in changing the FPCW multiple times - so we optimize it with
0115     // some inline assembly
0116     unsigned short oldCW, newCW;
0117     int result;
0118 
0119     __asm fld QWORD PTR x;
0120     __asm fnstcw WORD PTR oldCW;
0121     __asm mov ax, WORD PTR oldCW;
0122     __asm and ax, 0xf3ff;
0123     __asm or ax, 0x0800;
0124     __asm mov WORD PTR newCW, ax; // round up
0125     __asm fldcw WORD PTR newCW;
0126     __asm fistp DWORD PTR result;
0127     __asm fldcw WORD PTR oldCW;
0128     return result;
0129 #else
0130     return (int)ceil(x);
0131 #endif
0132 }
0133 
0134 static inline int splashRound(SplashCoord x)
0135 {
0136 #if defined(__GNUC__) && defined(__i386__)
0137     // this could use round-to-nearest mode and avoid the "+0.5",
0138     // but that produces slightly different results (because i+0.5
0139     // sometimes rounds up and sometimes down using the even rule)
0140     unsigned short oldCW, newCW, t;
0141     int result;
0142 
0143     x += 0.5;
0144     __asm__ volatile("fldl   %4\n"
0145                      "fnstcw %0\n"
0146                      "movw   %0, %3\n"
0147                      "andw   $0xf3ff, %3\n"
0148                      "orw    $0x0400, %3\n"
0149                      "movw   %3, %1\n" // round down
0150                      "fldcw  %1\n"
0151                      "fistpl %2\n"
0152                      "fldcw  %0\n"
0153                      : "=m"(oldCW), "=m"(newCW), "=m"(result), "=r"(t)
0154                      : "m"(x));
0155     return result;
0156 #elif defined(_WIN32) && defined(_M_IX86)
0157     // this could use round-to-nearest mode and avoid the "+0.5",
0158     // but that produces slightly different results (because i+0.5
0159     // sometimes rounds up and sometimes down using the even rule)
0160     unsigned short oldCW, newCW;
0161     int result;
0162 
0163     x += 0.5;
0164     __asm fld QWORD PTR x;
0165     __asm fnstcw WORD PTR oldCW;
0166     __asm mov ax, WORD PTR oldCW;
0167     __asm and ax, 0xf3ff;
0168     __asm or ax, 0x0400;
0169     __asm mov WORD PTR newCW, ax; // round down
0170     __asm fldcw WORD PTR newCW;
0171     __asm fistp DWORD PTR result;
0172     __asm fldcw WORD PTR oldCW;
0173     return result;
0174 #else
0175     return (int)splashFloor(x + 0.5);
0176 #endif
0177 }
0178 
0179 static inline SplashCoord splashAvg(SplashCoord x, SplashCoord y)
0180 {
0181     return 0.5 * (x + y);
0182 }
0183 
0184 static inline SplashCoord splashSqrt(SplashCoord x)
0185 {
0186 #if defined(USE_FLOAT)
0187     return sqrtf(x);
0188 #else
0189     return sqrt(x);
0190 #endif
0191 }
0192 
0193 static inline SplashCoord splashPow(SplashCoord x, SplashCoord y)
0194 {
0195 #if defined(USE_FLOAT)
0196     return powf(x, y);
0197 #else
0198     return pow(x, y);
0199 #endif
0200 }
0201 
0202 static inline SplashCoord splashDist(SplashCoord x0, SplashCoord y0, SplashCoord x1, SplashCoord y1)
0203 {
0204     SplashCoord dx, dy;
0205     dx = x1 - x0;
0206     dy = y1 - y0;
0207     return splashSqrt(dx * dx + dy * dy);
0208 }
0209 
0210 static inline bool splashCheckDet(SplashCoord m11, SplashCoord m12, SplashCoord m21, SplashCoord m22, SplashCoord epsilon)
0211 {
0212     return fabs(m11 * m22 - m12 * m21) >= epsilon;
0213 }
0214 
0215 #endif