diff options
author | agl@chromium.org <agl@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-07-28 00:02:42 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@2bbb7eff-a529-9590-31e7-b0007b416f81> | 2009-07-28 00:02:42 +0000 |
commit | ac3011c6d4a885af4f37e22ce94451a778239b0d (patch) | |
tree | 308f1a2696e435624db0d8d71ccd2f35db6fab83 /src/ports | |
parent | e2ca20740b1b3c9e71c085017b64fc9d2f553d93 (diff) |
Support subpixel text when FreeType is built without such support.
On Fedora, at least, FreeType is built without subpixel support. It
tries to simulate subpixel mode by replicating the gray-values three
times. However, it fails to simulate the actions of the low-pass
filter and so doesn't add border around the glyphs. This patch adds a
compile-time constant, which is the number of bytes of filter border.
If this value is zero (because FreeType is simulating subpixel
support), then we add a transparent border ourselves when transforming
from FreeType rendered glyphs to masks.
http://codereview.appspot.com/96171
git-svn-id: http://skia.googlecode.com/svn/trunk@291 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'src/ports')
-rw-r--r-- | src/ports/SkFontHost_FreeType_Subpixel.cpp | 35 |
1 files changed, 28 insertions, 7 deletions
diff --git a/src/ports/SkFontHost_FreeType_Subpixel.cpp b/src/ports/SkFontHost_FreeType_Subpixel.cpp index bc01585ee8..82bb5542cc 100644 --- a/src/ports/SkFontHost_FreeType_Subpixel.cpp +++ b/src/ports/SkFontHost_FreeType_Subpixel.cpp @@ -27,6 +27,7 @@ #include <ft2build.h> #include FT_FREETYPE_H +#include FT_CONFIG_OPTIONS_H #if 0 // Also include the files by name for build tools which require this. @@ -35,10 +36,16 @@ namespace skia_freetype_support { +#if defined(FT_CONFIG_OPTION_SUBPIXEL_RENDERING) +static const int kFilterBorderWidth = 3; +#else +static const int kFilterBorderWidth = 0; +#endif + void CopyFreetypeBitmapToLCDMask(const SkGlyph& dest, const FT_Bitmap& source) { // |source| has three alpha values per pixel and has an extra column at the - // left and right edges. + // left and right edges (if FT_CONFIG_OPTION_SUBPIXEL_RENDERING). // ----- <--- a single pixel in the output // source .oOo.. |.oO|o.. @@ -47,15 +54,15 @@ void CopyFreetypeBitmapToLCDMask(const SkGlyph& dest, const FT_Bitmap& source) // .oO o.. uint8_t* output = reinterpret_cast<uint8_t*>(dest.fImage); - const unsigned outputPitch = SkAlign4((source.width / 3) - 2); + const unsigned outputPitch = SkAlign4((source.width - 2 * kFilterBorderWidth) / 3); const uint8_t* input = source.buffer; // First we calculate the A8 mask. for (int y = 0; y < source.rows; ++y) { const uint8_t* inputRow = input; uint8_t* outputRow = output; - inputRow += 3; // skip the extra column on the left - for (int x = 3; x < source.width - 3; x += 3) { + inputRow += kFilterBorderWidth; // skip the extra column on the left + for (int x = kFilterBorderWidth; x < source.width - kFilterBorderWidth; x += 3) { const uint8_t averageAlpha = (static_cast<unsigned>(inputRow[0]) + inputRow[1] + inputRow[2] + 1) / 3; *outputRow++ = averageAlpha; inputRow += 3; @@ -74,6 +81,8 @@ void CopyFreetypeBitmapToLCDMask(const SkGlyph& dest, const FT_Bitmap& source) for (int y = 0; y < source.rows; ++y) { const uint8_t* inputRow = input; + if (!kFilterBorderWidth) + *output32++ = SkPackARGB32(0, 0, 0, 0); for (int x = 0; x < source.width; x += 3) { const uint8_t alphaRed = isBGR ? inputRow[2] : inputRow[0]; const uint8_t alphaGreen = inputRow[1]; @@ -83,6 +92,8 @@ void CopyFreetypeBitmapToLCDMask(const SkGlyph& dest, const FT_Bitmap& source) inputRow += 3; } + if (!kFilterBorderWidth) + *output32++ = SkPackARGB32(0, 0, 0, 0); input += source.pitch; } @@ -91,7 +102,7 @@ void CopyFreetypeBitmapToLCDMask(const SkGlyph& dest, const FT_Bitmap& source) void CopyFreetypeBitmapToVerticalLCDMask(const SkGlyph& dest, const FT_Bitmap& source) { // |source| has three times as many rows as normal, and an extra triple on the - // top and bottom. + // top and bottom (if FT_CONFIG_OPTION_SUBPIXEL_RENDERING). // source .oOo.. |.|oOo.. // .OOO.. --> |.|OOO.. @@ -104,8 +115,8 @@ void CopyFreetypeBitmapToVerticalLCDMask(const SkGlyph& dest, const FT_Bitmap& s const uint8_t* input = source.buffer; // First we calculate the A8 mask. - input += 3 * source.pitch; // skip the extra at the beginning - for (int y = 3; y < source.rows - 3; y += 3) { + input += kFilterBorderWidth * source.pitch; // skip the extra at the beginning + for (int y = kFilterBorderWidth; y < source.rows - kFilterBorderWidth; y += 3) { const uint8_t* inputRow = input; uint8_t* outputRow = output; for (int x = 0; x < source.width; ++x) { @@ -125,6 +136,11 @@ void CopyFreetypeBitmapToVerticalLCDMask(const SkGlyph& dest, const FT_Bitmap& s const int isBGR = SkFontHost::GetSubpixelOrder() == SkFontHost::kBGR_LCDOrder; input = source.buffer; + if (!kFilterBorderWidth) { + for (int x = 0; x < source.width; ++x) + *output32++ = SkPackARGB32(0, 0, 0, 0); + } + for (int y = 0; y < source.rows; y += 3) { const uint8_t* inputRow = input; for (int x = 0; x < source.width; ++x) { @@ -138,6 +154,11 @@ void CopyFreetypeBitmapToVerticalLCDMask(const SkGlyph& dest, const FT_Bitmap& s input += source.pitch * 3; } + + if (!kFilterBorderWidth) { + for (int x = 0; x < source.width; ++x) + *output32++ = SkPackARGB32(0, 0, 0, 0); + } } } // namespace skia_freetype_support |