diff options
author | Ben Wagner <bungeman@google.com> | 2016-11-10 16:14:52 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-11-10 22:16:27 +0000 |
commit | 2512db21f48ecda9215926b49436c5b534f5da82 (patch) | |
tree | 24f900c6601d162c0fc1a51d7a59c430b85e9b3d | |
parent | b613c266df48cf45296ecc23d1bd7098c84bb7ba (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.cpp | 84 |
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; |