aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-11-21 02:48:11 +0000
committerGravatar reed@android.com <reed@android.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2009-11-21 02:48:11 +0000
commitd4577757874d1dda1a3bffa3f2347c251859c27e (patch)
tree01d187f7d685451ad6777425dd8c2e5966f48364
parent8d52841110f1017a7dd7f4083fea7369a82f97f3 (diff)
add checks for exceeding 16bits, and apply those for glyphs in getMetrics()
git-svn-id: http://skia.googlecode.com/svn/trunk@441 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r--include/core/SkRect.h5
-rw-r--r--include/core/SkTypes.h46
-rw-r--r--src/core/SkScalerContext.cpp18
3 files changed, 42 insertions, 27 deletions
diff --git a/include/core/SkRect.h b/include/core/SkRect.h
index a9f25aa9f5..c9f432a3c1 100644
--- a/include/core/SkRect.h
+++ b/include/core/SkRect.h
@@ -49,6 +49,11 @@ struct SkIRect {
return memcmp(&a, &b, sizeof(a));
}
+ bool is16Bit() const {
+ return SkIsS16(fLeft) && SkIsS16(fTop) &&
+ SkIsS16(fRight) && SkIsS16(fBottom);
+ }
+
/** Set the rectangle to (0,0,0,0)
*/
void setEmpty() { memset(this, 0, sizeof(*this)); }
diff --git a/include/core/SkTypes.h b/include/core/SkTypes.h
index 00ecb6f4da..8961aa065d 100644
--- a/include/core/SkTypes.h
+++ b/include/core/SkTypes.h
@@ -149,6 +149,19 @@ typedef uint8_t SkBool8;
#define SK_MinU32 0
#define SK_NaN32 0x80000000
+/** Returns true if the value can be represented with signed 16bits
+ */
+static bool SkIsS16(long x) {
+ return (int16_t)x == x;
+}
+
+/** Returns true if the value can be represented with unsigned 16bits
+ */
+static bool SkIsU16(long x) {
+ return (uint16_t)x == x;
+}
+
+//////////////////////////////////////////////////////////////////////////////
#ifndef SK_OFFSETOF
#define SK_OFFSETOF(type, field) ((char*)&(((type*)1)->field) - (char*)1)
#endif
@@ -186,7 +199,6 @@ typedef uint32_t SkMSec;
*/
#define SkMSec_LE(a, b) ((int32_t)(a) - (int32_t)(b) <= 0)
-
/****************************************************************************
The rest of these only build with C++
*/
@@ -194,20 +206,17 @@ typedef uint32_t SkMSec;
/** Faster than SkToBool for integral conditions. Returns 0 or 1
*/
-inline int Sk32ToBool(uint32_t n)
-{
+static inline int Sk32ToBool(uint32_t n) {
return (n | (0-n)) >> 31;
}
-template <typename T> inline void SkTSwap(T& a, T& b)
-{
+template <typename T> inline void SkTSwap(T& a, T& b) {
T c(a);
a = b;
b = c;
}
-inline int32_t SkAbs32(int32_t value)
-{
+static inline int32_t SkAbs32(int32_t value) {
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
if (value < 0)
value = -value;
@@ -218,27 +227,23 @@ inline int32_t SkAbs32(int32_t value)
#endif
}
-inline int32_t SkMax32(int32_t a, int32_t b)
-{
+static inline int32_t SkMax32(int32_t a, int32_t b) {
if (a < b)
a = b;
return a;
}
-inline int32_t SkMin32(int32_t a, int32_t b)
-{
+static inline int32_t SkMin32(int32_t a, int32_t b) {
if (a > b)
a = b;
return a;
}
-inline int32_t SkSign32(int32_t a)
-{
+static inline int32_t SkSign32(int32_t a) {
return (a >> 31) | ((unsigned) -a >> 31);
}
-inline int32_t SkFastMin32(int32_t value, int32_t max)
-{
+static inline int32_t SkFastMin32(int32_t value, int32_t max) {
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
if (value > max)
value = max;
@@ -253,8 +258,7 @@ inline int32_t SkFastMin32(int32_t value, int32_t max)
/** Returns signed 32 bit value pinned between min and max, inclusively
*/
-inline int32_t SkPin32(int32_t value, int32_t min, int32_t max)
-{
+static inline int32_t SkPin32(int32_t value, int32_t min, int32_t max) {
#ifdef SK_CPU_HAS_CONDITIONAL_INSTR
if (value < min)
value = min;
@@ -269,14 +273,14 @@ inline int32_t SkPin32(int32_t value, int32_t min, int32_t max)
return value;
}
-inline uint32_t SkSetClearShift(uint32_t bits, bool cond, unsigned shift)
-{
+static inline uint32_t SkSetClearShift(uint32_t bits, bool cond,
+ unsigned shift) {
SkASSERT((int)cond == 0 || (int)cond == 1);
return (bits & ~(1 << shift)) | ((int)cond << shift);
}
-inline uint32_t SkSetClearMask(uint32_t bits, bool cond, uint32_t mask)
-{
+static inline uint32_t SkSetClearMask(uint32_t bits, bool cond,
+ uint32_t mask) {
return cond ? bits | mask : bits & ~mask;
}
diff --git a/src/core/SkScalerContext.cpp b/src/core/SkScalerContext.cpp
index eab015af18..afa9e48665 100644
--- a/src/core/SkScalerContext.cpp
+++ b/src/core/SkScalerContext.cpp
@@ -312,18 +312,16 @@ void SkScalerContext::getMetrics(SkGlyph* glyph) {
glyph->fWidth = SkToU16(mask.fBounds.width());
glyph->fHeight = SkToU16(mask.fBounds.height());
} else {
- // draw nothing 'cause we failed
- glyph->fLeft = 0;
- glyph->fTop = 0;
- glyph->fWidth = 0;
- glyph->fHeight = 0;
- return;
+ goto ERROR;
}
} else {
// just use devPath
SkIRect ir;
devPath.getBounds().roundOut(&ir);
+ if (ir.isEmpty() || !ir.is16Bit()) {
+ goto ERROR;
+ }
glyph->fLeft = ir.fLeft;
glyph->fTop = ir.fTop;
glyph->fWidth = SkToU16(ir.width());
@@ -350,6 +348,14 @@ void SkScalerContext::getMetrics(SkGlyph* glyph) {
glyph->fMaskFormat = dst.fFormat;
}
}
+ return;
+
+ERROR:
+ // draw nothing 'cause we failed
+ glyph->fLeft = 0;
+ glyph->fTop = 0;
+ glyph->fWidth = 0;
+ glyph->fHeight = 0;
}
void SkScalerContext::getImage(const SkGlyph& origGlyph) {