aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-03-14 16:44:56 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2011-03-14 16:44:56 +0000
commitea2333de1e93da38045111560295ef825be99956 (patch)
tree726e75ed1afad29ed223945f24a136f538df0d5c
parent6016962f7237058eb196987ec0e74a50210eee37 (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.cpp58
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: {