add LCD16 copy routine

git-svn-id: http://skia.googlecode.com/svn/trunk@932 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
reed@google.com 2011-03-14 16:44:56 +00:00
parent 6016962f72
commit ea2333de1e

View File

@ -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;
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);
memset(glyph.fImage, 0, glyph.rowBytes() * glyph.fHeight);
FT_Outline_Get_Bitmap(gFTLibrary, outline, &target);
}
} break;
case FT_GLYPH_FORMAT_BITMAP: {