aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Ben Wagner <bungeman@google.com>2016-11-10 16:14:52 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2016-11-10 22:16:27 +0000
commit2512db21f48ecda9215926b49436c5b534f5da82 (patch)
tree24f900c6601d162c0fc1a51d7a59c430b85e9b3d
parentb613c266df48cf45296ecc23d1bd7098c84bb7ba (diff)
Check and report FreeType error.
BUG=chromium:648959 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=4685 Change-Id: Ibc3cd5ddf37926accf1b7bf0959668510de903a8 Reviewed-on: https://skia-review.googlesource.com/4685 Reviewed-by: Mike Klein <mtklein@chromium.org> Commit-Queue: Ben Wagner <bungeman@google.com>
-rw-r--r--src/ports/SkFontHost_FreeType_common.cpp84
1 files changed, 66 insertions, 18 deletions
diff --git a/src/ports/SkFontHost_FreeType_common.cpp b/src/ports/SkFontHost_FreeType_common.cpp
index 26e02fd1b9..9df7268bb4 100644
--- a/src/ports/SkFontHost_FreeType_common.cpp
+++ b/src/ports/SkFontHost_FreeType_common.cpp
@@ -32,7 +32,9 @@
//#define SK_SHOW_TEXT_BLIT_COVERAGE
-static FT_Pixel_Mode compute_pixel_mode(SkMask::Format format) {
+namespace {
+
+FT_Pixel_Mode compute_pixel_mode(SkMask::Format format) {
switch (format) {
case SkMask::kBW_Format:
return FT_PIXEL_MODE_MONO;
@@ -44,7 +46,7 @@ static FT_Pixel_Mode compute_pixel_mode(SkMask::Format format) {
///////////////////////////////////////////////////////////////////////////////
-static uint16_t packTriple(U8CPU r, U8CPU g, U8CPU b) {
+uint16_t packTriple(U8CPU r, U8CPU g, U8CPU b) {
#ifdef SK_SHOW_TEXT_BLIT_COVERAGE
r = SkTMax(r, (U8CPU)0x40);
g = SkTMax(g, (U8CPU)0x40);
@@ -53,14 +55,14 @@ static uint16_t packTriple(U8CPU r, U8CPU g, U8CPU b) {
return SkPack888ToRGB16(r, g, b);
}
-static uint16_t grayToRGB16(U8CPU gray) {
+uint16_t grayToRGB16(U8CPU gray) {
#ifdef SK_SHOW_TEXT_BLIT_COVERAGE
gray = SkTMax(gray, (U8CPU)0x40);
#endif
return SkPack888ToRGB16(gray, gray, gray);
}
-static int bittst(const uint8_t data[], int bitOffset) {
+int bittst(const uint8_t data[], int bitOffset) {
SkASSERT(bitOffset >= 0);
int lowBit = data[bitOffset >> 3] >> (~bitOffset & 7);
return lowBit & 1;
@@ -75,8 +77,8 @@ static int bittst(const uint8_t data[], int bitOffset) {
* FT_PIXEL_MODE_LCD_V
*/
template<bool APPLY_PREBLEND>
-static void copyFT2LCD16(const FT_Bitmap& bitmap, const SkMask& mask, int lcdIsBGR,
- const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB)
+void copyFT2LCD16(const FT_Bitmap& bitmap, const SkMask& mask, int lcdIsBGR,
+ const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB)
{
SkASSERT(SkMask::kLCD16_Format == mask.fFormat);
if (FT_PIXEL_MODE_LCD != bitmap.pixel_mode) {
@@ -176,7 +178,7 @@ static void copyFT2LCD16(const FT_Bitmap& bitmap, const SkMask& mask, int lcdIsB
*
* TODO: All of these N need to be Y or otherwise ruled out.
*/
-static void copyFTBitmap(const FT_Bitmap& srcFTBitmap, SkMask& dstMask) {
+void copyFTBitmap(const FT_Bitmap& srcFTBitmap, SkMask& dstMask) {
SkASSERTF(dstMask.fBounds.width() == static_cast<int>(srcFTBitmap.width),
"dstMask.fBounds.width() = %d\n"
"static_cast<int>(srcFTBitmap.width) = %d",
@@ -259,13 +261,13 @@ static void copyFTBitmap(const FT_Bitmap& srcFTBitmap, SkMask& dstMask) {
}
}
-static inline int convert_8_to_1(unsigned byte) {
+inline int convert_8_to_1(unsigned byte) {
SkASSERT(byte <= 0xFF);
// Arbitrary decision that making the cutoff at 1/4 instead of 1/2 in general looks better.
return (byte >> 6) != 0;
}
-static uint8_t pack_8_to_1(const uint8_t alpha[8]) {
+uint8_t pack_8_to_1(const uint8_t alpha[8]) {
unsigned bits = 0;
for (int i = 0; i < 8; ++i) {
bits <<= 1;
@@ -274,7 +276,7 @@ static uint8_t pack_8_to_1(const uint8_t alpha[8]) {
return SkToU8(bits);
}
-static void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) {
+void packA8ToA1(const SkMask& mask, const uint8_t* src, size_t srcRB) {
const int height = mask.fBounds.height();
const int width = mask.fBounds.width();
const int octs = width >> 3;
@@ -344,6 +346,44 @@ inline SkColorType SkColorType_for_SkMaskFormat(SkMask::Format format) {
}
}
+#ifdef SK_DEBUG
+
+# define SK_STRING(X) SK_STRING_IMPL(X)
+# define SK_STRING_IMPL(X) #X
+
+# undef __FTERRORS_H__
+# define FT_ERROR_START_LIST
+# define FT_ERRORDEF(e, v, s) { SK_STRING(e), s },
+# define FT_ERROR_END_LIST
+
+const struct {
+ const char* err_code;
+ const char* err_msg;
+} sk_ft_errors[] = {
+# include FT_ERRORS_H
+};
+
+void SkTraceFTR(const char* file, unsigned long line, FT_Error err, const char* msg) {
+ SkString s;
+ s.printf("%s:%lu:1: error: 0x%x ", file, line, err);
+ if (0 <= err && (unsigned)err < SK_ARRAY_COUNT(sk_ft_errors)) {
+ s.appendf("%s '%s' ", sk_ft_errors[err].err_code, sk_ft_errors[err].err_msg);
+ } else {
+ s.appendf("<unknown> ");
+ }
+ if (msg) {
+ s.appendf("%s", msg);
+ }
+ SkDebugf("%s\n", s.c_str());
+}
+
+# define SK_TRACEFTR(_err, _msg) SkTraceFTR(__FILE__, __LINE__, _err, _msg)
+#else
+# define SK_TRACEFTR(_err, _msg) sk_ignore_unused_variable(_err)
+#endif
+
+} // namespace
+
void SkScalerContext_FreeType_Base::generateGlyphImage(
FT_Face face,
const SkGlyph& glyph,
@@ -378,7 +418,13 @@ void SkScalerContext_FreeType_Base::generateGlyphImage(
dy - ((bbox.yMin + dy) & ~63));
if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
- FT_Render_Glyph(face->glyph, doVert ? FT_RENDER_MODE_LCD_V : FT_RENDER_MODE_LCD);
+ FT_Error err = FT_Render_Glyph(face->glyph, doVert ? FT_RENDER_MODE_LCD_V :
+ FT_RENDER_MODE_LCD);
+ if (err) {
+ SK_TRACEFTR(err, "Could not render glyph.");
+ sk_bzero(glyph.fImage, glyph.computeImageSize());
+ return;
+ }
SkMask mask;
glyph.toMask(&mask);
if (fPreBlend.isApplicable()) {
@@ -522,20 +568,22 @@ void SkScalerContext_FreeType_Base::generateGlyphImage(
///////////////////////////////////////////////////////////////////////////////
-static int move_proc(const FT_Vector* pt, void* ctx) {
+namespace {
+
+int move_proc(const FT_Vector* pt, void* ctx) {
SkPath* path = (SkPath*)ctx;
path->close(); // to close the previous contour (if any)
path->moveTo(SkFDot6ToScalar(pt->x), -SkFDot6ToScalar(pt->y));
return 0;
}
-static int line_proc(const FT_Vector* pt, void* ctx) {
+int line_proc(const FT_Vector* pt, void* ctx) {
SkPath* path = (SkPath*)ctx;
path->lineTo(SkFDot6ToScalar(pt->x), -SkFDot6ToScalar(pt->y));
return 0;
}
-static int quad_proc(const FT_Vector* pt0, const FT_Vector* pt1,
+int quad_proc(const FT_Vector* pt0, const FT_Vector* pt1,
void* ctx) {
SkPath* path = (SkPath*)ctx;
path->quadTo(SkFDot6ToScalar(pt0->x), -SkFDot6ToScalar(pt0->y),
@@ -543,7 +591,7 @@ static int quad_proc(const FT_Vector* pt0, const FT_Vector* pt1,
return 0;
}
-static int cubic_proc(const FT_Vector* pt0, const FT_Vector* pt1,
+int cubic_proc(const FT_Vector* pt0, const FT_Vector* pt1,
const FT_Vector* pt2, void* ctx) {
SkPath* path = (SkPath*)ctx;
path->cubicTo(SkFDot6ToScalar(pt0->x), -SkFDot6ToScalar(pt0->y),
@@ -552,9 +600,9 @@ static int cubic_proc(const FT_Vector* pt0, const FT_Vector* pt1,
return 0;
}
-void SkScalerContext_FreeType_Base::generateGlyphPath(FT_Face face,
- SkPath* path)
-{
+} // namespace
+
+void SkScalerContext_FreeType_Base::generateGlyphPath(FT_Face face, SkPath* path) {
FT_Outline_Funcs funcs;
funcs.move_to = move_proc;