Merge pull request #1441 from harfbuzz/cff-doublenum
use double as CFF Number implementation
This commit is contained in:
commit
c968869f21
|
@ -218,80 +218,41 @@ inline unsigned int OpCode_Size (OpCode op) { return Is_OpCode_ESC (op) ? 2: 1;
|
||||||
struct Number
|
struct Number
|
||||||
{
|
{
|
||||||
inline void init (void)
|
inline void init (void)
|
||||||
{ set_int (0); }
|
{ set_real (0.0); }
|
||||||
inline void fini (void)
|
inline void fini (void)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
inline void set_int (int v) { format = NumInt; u.int_val = v; }
|
inline void set_int (int v) { value = (double)v; }
|
||||||
inline int to_int (void) const { return is_int ()? u.int_val: (int)to_real (); }
|
inline int to_int (void) const { return (int)value; }
|
||||||
inline void set_fixed (int32_t v) { format = NumFixed; u.fixed_val = v; }
|
inline void set_fixed (int32_t v) { value = v / 65536.0; }
|
||||||
inline int32_t to_fixed (void) const
|
inline int32_t to_fixed (void) const
|
||||||
{
|
{
|
||||||
if (is_fixed ())
|
return (int32_t)(value * 65536.0);
|
||||||
return u.fixed_val;
|
|
||||||
else if (is_real ())
|
|
||||||
return (int32_t)(u.real_val * 65536.0f);
|
|
||||||
else
|
|
||||||
return (int32_t)(u.int_val << 16);
|
|
||||||
}
|
}
|
||||||
inline void set_real (float v) { format = NumReal; u.real_val = v; }
|
inline void set_real (double v) { value = v; }
|
||||||
inline float to_real (void) const
|
inline double to_real (void) const
|
||||||
{
|
{
|
||||||
if (is_real ())
|
return value;
|
||||||
return u.real_val;
|
|
||||||
if (is_fixed ())
|
|
||||||
return u.fixed_val / 65536.0f;
|
|
||||||
else
|
|
||||||
return (float)u.int_val;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int ceil (void) const
|
inline int ceil (void) const
|
||||||
{
|
{
|
||||||
switch (format)
|
return (int)::ceil (value);
|
||||||
{
|
|
||||||
default:
|
|
||||||
case NumInt:
|
|
||||||
return u.int_val;
|
|
||||||
case NumFixed:
|
|
||||||
return (u.fixed_val + 0xFFFF) >> 16;
|
|
||||||
case NumReal:
|
|
||||||
return (int)ceilf (u.real_val);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int floor (void) const
|
inline int floor (void) const
|
||||||
{
|
{
|
||||||
switch (format)
|
return (int)::floor (value);
|
||||||
{
|
|
||||||
default:
|
|
||||||
case NumInt:
|
|
||||||
return u.int_val;
|
|
||||||
case NumFixed:
|
|
||||||
return u.fixed_val >> 16;
|
|
||||||
case NumReal:
|
|
||||||
return (int)floorf (u.real_val);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool in_int_range (void) const
|
inline bool in_int_range (void) const
|
||||||
{
|
{
|
||||||
if (is_int ())
|
return ((double)(int16_t)to_int () == value);
|
||||||
return true;
|
|
||||||
if (is_fixed () && ((u.fixed_val & 0xFFFF) == 0))
|
|
||||||
return true;
|
|
||||||
else
|
|
||||||
return ((float)(int16_t)to_int () == u.real_val);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator > (const Number &n) const
|
inline bool operator > (const Number &n) const
|
||||||
{
|
{
|
||||||
switch (format)
|
return value > n.to_real ();
|
||||||
{
|
|
||||||
default:
|
|
||||||
case NumInt: return u.int_val > n.to_int ();
|
|
||||||
case NumFixed: return u.fixed_val > n.to_fixed ();
|
|
||||||
case NumReal: return u.real_val > n.to_real ();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool operator < (const Number &n) const
|
inline bool operator < (const Number &n) const
|
||||||
|
@ -305,32 +266,13 @@ struct Number
|
||||||
|
|
||||||
inline const Number &operator += (const Number &n)
|
inline const Number &operator += (const Number &n)
|
||||||
{
|
{
|
||||||
if (format == NumReal || n.format == NumReal)
|
set_real (to_real () + n.to_real ());
|
||||||
set_real (to_real () + n.to_real ());
|
|
||||||
else if (format == NumFixed || n.format == NumFixed)
|
|
||||||
set_fixed (to_fixed () + n.to_fixed ());
|
|
||||||
else
|
|
||||||
set_int (to_int () + n.to_int ());
|
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum NumFormat {
|
double value;
|
||||||
NumInt,
|
|
||||||
NumFixed,
|
|
||||||
NumReal
|
|
||||||
};
|
|
||||||
NumFormat format;
|
|
||||||
union {
|
|
||||||
int int_val;
|
|
||||||
int32_t fixed_val;
|
|
||||||
float real_val;
|
|
||||||
} u;
|
|
||||||
|
|
||||||
inline bool is_int (void) const { return format == NumInt; }
|
|
||||||
inline bool is_fixed (void) const { return format == NumFixed; }
|
|
||||||
inline bool is_real (void) const { return format == NumReal; }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* byte string */
|
/* byte string */
|
||||||
|
@ -578,7 +520,7 @@ struct ArgStack : Stack<ARG, 513>
|
||||||
n.set_fixed (v);
|
n.set_fixed (v);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void push_real (float v)
|
inline void push_real (double v)
|
||||||
{
|
{
|
||||||
ARG &n = S::push ();
|
ARG &n = S::push ();
|
||||||
n.set_real (v);
|
n.set_real (v);
|
||||||
|
|
|
@ -103,9 +103,9 @@ struct DictOpSet : OpSet<Number>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline float parse_bcd (SubByteStr& substr)
|
static inline double parse_bcd (SubByteStr& substr)
|
||||||
{
|
{
|
||||||
float v = 0.0f;
|
double v = 0.0;
|
||||||
|
|
||||||
bool neg = false;
|
bool neg = false;
|
||||||
double int_part = 0;
|
double int_part = 0;
|
||||||
|
@ -126,7 +126,7 @@ struct DictOpSet : OpSet<Number>
|
||||||
if (!substr.avail ())
|
if (!substr.avail ())
|
||||||
{
|
{
|
||||||
substr.set_error ();
|
substr.set_error ();
|
||||||
return 0.0f;
|
return 0.0;
|
||||||
}
|
}
|
||||||
byte = substr[0];
|
byte = substr[0];
|
||||||
substr.inc ();
|
substr.inc ();
|
||||||
|
@ -152,13 +152,13 @@ struct DictOpSet : OpSet<Number>
|
||||||
else
|
else
|
||||||
value *= pow (10.0, (double)exp_part);
|
value *= pow (10.0, (double)exp_part);
|
||||||
}
|
}
|
||||||
return (float)value;
|
return value;
|
||||||
|
|
||||||
case NEG:
|
case NEG:
|
||||||
if (i != 0)
|
if (i != 0)
|
||||||
{
|
{
|
||||||
substr.set_error ();
|
substr.set_error ();
|
||||||
return 0.0f;
|
return 0.0;
|
||||||
}
|
}
|
||||||
neg = true;
|
neg = true;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -49,7 +49,7 @@ struct BlendArg : Number
|
||||||
|
|
||||||
inline void set_int (int v) { reset_blends (); Number::set_int (v); }
|
inline void set_int (int v) { reset_blends (); Number::set_int (v); }
|
||||||
inline void set_fixed (int32_t v) { reset_blends (); Number::set_fixed (v); }
|
inline void set_fixed (int32_t v) { reset_blends (); Number::set_fixed (v); }
|
||||||
inline void set_real (float v) { reset_blends (); Number::set_real (v); }
|
inline void set_real (double v) { reset_blends (); Number::set_real (v); }
|
||||||
|
|
||||||
inline void set_blends (unsigned int numValues_, unsigned int valueIndex_,
|
inline void set_blends (unsigned int numValues_, unsigned int valueIndex_,
|
||||||
unsigned int numBlends, const BlendArg *blends_)
|
unsigned int numBlends, const BlendArg *blends_)
|
||||||
|
@ -169,10 +169,10 @@ struct CFF2CSInterpEnv : CSInterpEnv<BlendArg, CFF2Subrs>
|
||||||
{
|
{
|
||||||
if (likely (scalars.len == arg.deltas.len))
|
if (likely (scalars.len == arg.deltas.len))
|
||||||
{
|
{
|
||||||
float v = arg.to_real ();
|
double v = arg.to_real ();
|
||||||
for (unsigned int i = 0; i < scalars.len; i++)
|
for (unsigned int i = 0; i < scalars.len; i++)
|
||||||
{
|
{
|
||||||
v += scalars[i] * arg.deltas[i].to_real ();
|
v += (double)scalars[i] * arg.deltas[i].to_real ();
|
||||||
}
|
}
|
||||||
arg.set_real (v);
|
arg.set_real (v);
|
||||||
arg.deltas.resize (0);
|
arg.deltas.resize (0);
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue