diff options
author | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-03-14 16:44:56 +0000 |
---|---|---|
committer | reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2011-03-14 16:44:56 +0000 |
commit | ea2333de1e93da38045111560295ef825be99956 (patch) | |
tree | 726e75ed1afad29ed223945f24a136f538df0d5c | |
parent | 6016962f7237058eb196987ec0e74a50210eee37 (diff) |
add LCD16 copy routine
git-svn-id: http://skia.googlecode.com/svn/trunk@932 2bbb7eff-a529-9590-31e7-b0007b416f81
-rw-r--r-- | src/ports/SkFontHost_FreeType.cpp | 58 |
1 files changed, 42 insertions, 16 deletions
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index 96cdcca572..56a13fc0a8 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -40,7 +40,7 @@ #include FT_SYNTHESIS_H #include FT_XFREE86_H -#if defined(SK_SUPPORT_LCDTEXT) +#if defined(SK_SUPPORT_LCDTEXT) || true #include FT_LCD_FILTER_H #endif @@ -95,15 +95,14 @@ static const FT_Pos kBitmapEmboldenStrength = 1 << 6; static bool InitFreetype() { FT_Error err = FT_Init_FreeType(&gFTLibrary); - if (err) + if (err) { return false; + } -#if defined(SK_SUPPORT_LCDTEXT) // Setup LCD filtering. This reduces colour fringes for LCD rendered // glyphs. err = FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_DEFAULT); gLCDSupport = err == 0; -#endif gLCDSupportValid = true; return true; @@ -631,10 +630,12 @@ SkScalerContext_FreeType::SkScalerContext_FreeType(const SkDescriptor* desc) break; } loadFlags = FT_LOAD_TARGET_NORMAL; - if (SkMask::kHorizontalLCD_Format == fRec.fMaskFormat) + if (SkMask::kHorizontalLCD_Format == fRec.fMaskFormat || + SkMask::kLCD16_Format == fRec.fMaskFormat) { loadFlags = FT_LOAD_TARGET_LCD; - else if (SkMask::kVerticalLCD_Format == fRec.fMaskFormat) + } else if (SkMask::kVerticalLCD_Format == fRec.fMaskFormat) { loadFlags = FT_LOAD_TARGET_LCD_V; + } break; default: SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting()); @@ -900,6 +901,26 @@ extern void CopyFreetypeBitmapToVerticalLCDMask(const SkGlyph& dest, const FT_Bi using namespace skia_freetype_support; #endif +static void copyFT2LCD16(const SkGlyph& glyph, const FT_Bitmap& bitmap) { + SkASSERT(glyph.fWidth * 3 == bitmap.width); + SkASSERT(glyph.fHeight == bitmap.rows); + + const uint8_t* src = bitmap.buffer; + uint16_t* dst = reinterpret_cast<uint16_t*>(glyph.fImage); + size_t dstRB = glyph.rowBytes(); + int width = glyph.fWidth; + + for (int y = 0; y < glyph.fHeight; y++) { + const uint8_t* triple = src; + for (int x = 0; x < width; x++) { + dst[x] = SkPackRGB16(triple[0] >> 3, triple[1] >> 2, triple[2] >> 3); + triple += 3; + } + src += bitmap.pitch; + dst = (uint16_t*)((char*)dst + dstRB); + } +} + void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { SkAutoMutexAcquire ac(gFTMutex); @@ -967,16 +988,21 @@ void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { } #endif - target.width = glyph.fWidth; - target.rows = glyph.fHeight; - target.pitch = glyph.rowBytes(); - target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage); - target.pixel_mode = compute_pixel_mode( - (SkMask::Format)fRec.fMaskFormat); - target.num_grays = 256; - - memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); - FT_Outline_Get_Bitmap(gFTLibrary, outline, &target); + if (SkMask::kLCD16_Format == glyph.fMaskFormat) { + FT_Render_Glyph(fFace->glyph, FT_RENDER_MODE_LCD); + copyFT2LCD16(glyph, fFace->glyph->bitmap); + } else { + target.width = glyph.fWidth; + target.rows = glyph.fHeight; + target.pitch = glyph.rowBytes(); + target.buffer = reinterpret_cast<uint8_t*>(glyph.fImage); + target.pixel_mode = compute_pixel_mode( + (SkMask::Format)fRec.fMaskFormat); + target.num_grays = 256; + + memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight); + FT_Outline_Get_Bitmap(gFTLibrary, outline, &target); + } } break; case FT_GLYPH_FORMAT_BITMAP: { |