diff options
author | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-09-10 13:28:00 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2012-09-10 13:28:00 +0000 |
commit | c8699ef1b7f862412fc87bf455112ac956b1dd2a (patch) | |
tree | 1ed2f657bcb988fc6ef4806b7fde27e7b6db1758 | |
parent | 43e10145911bde6ac8c3f14fd46611a13c76f8b9 (diff) |
Fix issue where bw bitmask uploaded to gr 565, 8888 glyph cache
Review URL: https://codereview.appspot.com/6498105/
git-svn-id: http://skia.googlecode.com/svn/trunk@5459 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/gpu/SkGrFontScaler.cpp | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/src/gpu/SkGrFontScaler.cpp b/src/gpu/SkGrFontScaler.cpp index 26412f4a35..208e46dfc5 100644 --- a/src/gpu/SkGrFontScaler.cpp +++ b/src/gpu/SkGrFontScaler.cpp @@ -110,17 +110,31 @@ bool SkGrFontScaler::getPackedGlyphBounds(GrGlyph::PackedID packed, } -static void bits_to_bytes(const uint8_t bits[], uint8_t bytes[], int count) { - while (count > 0) { - unsigned mask = *bits++; - for (int i = 7; i >= 0; --i) { - *bytes++ = (mask & (1 << i)) ? 0xFF : 0; - if (--count == 0) { - return; +namespace { +// expands each bit in a bitmask to 0 or ~0 of type INT_TYPE. Used to expand a BW glyph mask to +// A8, RGB565, or RGBA8888. +template <typename INT_TYPE> +void expand_bits(INT_TYPE* dst, + const uint8_t* src, + int width, + int height, + int dstRowBytes, + int srcRowBytes) { + for (int i = 0; i < height; ++i) { + int rowWritesLeft = width; + const uint8_t* s = src; + INT_TYPE* d = dst; + while (rowWritesLeft > 0) { + unsigned mask = *s++; + for (int i = 7; i >= 0 && rowWritesLeft; --i, --rowWritesLeft) { + *d++ = (mask & (1 << i)) ? (INT_TYPE)(~0UL) : 0; } } + dst = reinterpret_cast<INT_TYPE*>(reinterpret_cast<intptr_t>(dst) + dstRowBytes); + src += srcRowBytes; } } +} bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed, int width, int height, @@ -136,14 +150,28 @@ bool SkGrFontScaler::getPackedGlyphImage(GrGlyph::PackedID packed, } int srcRB = glyph.rowBytes(); - if (SkMask::kBW_Format == fStrike->getMaskFormat()) { - // expand bits to bytes + // The windows font host sometimes has BW glyphs in a non-BW strike. So it is important here to + // check the glyph's format, not the strike's format, and to be able to convert to any of the + // GrMaskFormats. + if (SkMask::kBW_Format == glyph.fMaskFormat) { + // expand bits to our mask type const uint8_t* bits = reinterpret_cast<const uint8_t*>(src); - uint8_t* bytes = reinterpret_cast<uint8_t*>(dst); - for (int y = 0; y < height; y++) { - bits_to_bytes(bits, bytes, width); - bits += srcRB; - bytes += dstRB; + switch (this->getMaskFormat()) { + case kA8_GrMaskFormat:{ + uint8_t* bytes = reinterpret_cast<uint8_t*>(dst); + expand_bits(bytes, bits, width, height, dstRB, srcRB); + break; + } + case kA565_GrMaskFormat: { + uint16_t* rgb565 = reinterpret_cast<uint16_t*>(dst); + expand_bits(rgb565, bits, width, height, dstRB, srcRB); + break; + } + case kA888_GrMaskFormat: { + uint32_t* rgba8888 = reinterpret_cast<uint32_t*>(dst); + expand_bits(rgba8888, bits, width, height, dstRB, srcRB); + break; + } } } else if (srcRB == dstRB) { memcpy(dst, src, dstRB * height); |