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
This commit is contained in:
bsalomon@google.com 2012-09-10 13:28:00 +00:00
parent 43e1014591
commit c8699ef1b7

View File

@ -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);