diff -Naur chromium-7.0.528.0.orig/chrome/browser/renderer_host/render_sandbox_host_linux.cc chromium-7.0.528.0/chrome/browser/renderer_host/render_sandbox_host_linux.cc --- chromium-7.0.528.0.orig/chrome/browser/renderer_host/render_sandbox_host_linux.cc 2010-09-18 10:03:44.000000000 +0200 +++ chromium-7.0.528.0/chrome/browser/renderer_host/render_sandbox_host_linux.cc 2010-09-19 21:37:33.264681987 +0200 @@ -285,6 +285,7 @@ reply.WriteInt(style.useAutoHint); reply.WriteInt(style.useHinting); reply.WriteInt(style.hintStyle); + reply.WriteInt(style.lcdFilter); reply.WriteInt(style.useAntiAlias); reply.WriteInt(style.useSubpixel); diff -Naur chromium-7.0.528.0.orig/chrome/renderer/renderer_sandbox_support_linux.cc chromium-7.0.528.0/chrome/renderer/renderer_sandbox_support_linux.cc --- chromium-7.0.528.0.orig/chrome/renderer/renderer_sandbox_support_linux.cc 2010-09-18 10:03:54.000000000 +0200 +++ chromium-7.0.528.0/chrome/renderer/renderer_sandbox_support_linux.cc 2010-09-19 21:37:33.264681987 +0200 @@ -63,16 +63,19 @@ Pickle reply(reinterpret_cast(buf), n); void* pickle_iter = NULL; int useBitmaps, useAutoHint, useHinting, hintStyle, useAntiAlias, useSubpixel; + int lcdFilter; if (reply.ReadInt(&pickle_iter, &useBitmaps) && reply.ReadInt(&pickle_iter, &useAutoHint) && reply.ReadInt(&pickle_iter, &useHinting) && reply.ReadInt(&pickle_iter, &hintStyle) && + reply.ReadInt(&pickle_iter, &lcdFilter) && reply.ReadInt(&pickle_iter, &useAntiAlias) && reply.ReadInt(&pickle_iter, &useSubpixel)) { out->useBitmaps = useBitmaps; out->useAutoHint = useAutoHint; out->useHinting = useHinting; out->hintStyle = hintStyle; + out->lcdFilter = lcdFilter; out->useAntiAlias = useAntiAlias; out->useSubpixel = useSubpixel; } diff -Naur chromium-7.0.528.0.orig/third_party/skia/include/core/SkPaint.h chromium-7.0.528.0/third_party/skia/include/core/SkPaint.h --- chromium-7.0.528.0.orig/third_party/skia/include/core/SkPaint.h 2010-09-18 10:05:18.000000000 +0200 +++ chromium-7.0.528.0/third_party/skia/include/core/SkPaint.h 2010-09-19 21:37:33.265681993 +0200 @@ -96,6 +96,23 @@ fHinting = hintingLevel; } + enum LCDFilter { + kLCDNone = 0, + kLCDDefault = 1, //!< this is the default + kLCDLight = 2, + kLCDLegacy = 3, + }; + + LCDFilter getLCDFilter() const + { + return static_cast(fLCDFilter); + } + + void setLCDFilter(LCDFilter filter) + { + fLCDFilter = filter; + } + /** Specifies the bit values that are stored in the paint's flags. */ enum Flags { @@ -843,6 +860,7 @@ unsigned fStyle : 2; unsigned fTextEncoding : 2; // 3 values unsigned fHinting : 2; + unsigned fLCDFilter : 2; SkDrawCacheProc getDrawCacheProc() const; SkMeasureCacheProc getMeasureCacheProc(TextBufferDirection dir, diff -Naur chromium-7.0.528.0.orig/third_party/skia/include/core/SkScalerContext.h chromium-7.0.528.0/third_party/skia/include/core/SkScalerContext.h --- chromium-7.0.528.0.orig/third_party/skia/include/core/SkScalerContext.h 2010-09-18 10:05:18.000000000 +0200 +++ chromium-7.0.528.0/third_party/skia/include/core/SkScalerContext.h 2010-09-19 21:37:33.265681993 +0200 @@ -158,10 +158,15 @@ kEmbolden_Flag = 0x80, kSubpixelPositioning_Flag = 0x100, kAutohinting_Flag = 0x200, + kLCDFilterBit1_Flag = 0x400, + kLCDFilterBit2_Flag = 0x800, }; private: enum { - kHintingMask = kHintingBit1_Flag | kHintingBit2_Flag + kHintingMask = kHintingBit1_Flag | kHintingBit2_Flag, + kHintingShift = 4, + kLCDFilterMask = kLCDFilterBit1_Flag | kLCDFilterBit2_Flag, + kLCDFilterShift = 10, }; public: struct Rec { @@ -182,11 +187,19 @@ void getSingleMatrix(SkMatrix*) const; SkPaint::Hinting getHinting() const { - return static_cast((fFlags & kHintingMask) >> 4); + return static_cast((fFlags & kHintingMask) >> kHintingShift); } void setHinting(SkPaint::Hinting hinting) { - fFlags = (fFlags & ~kHintingMask) | (hinting << 4); + fFlags = (fFlags & ~kHintingMask) | (hinting << kHintingShift); + } + + SkPaint::LCDFilter getLCDFilter() const { + return static_cast((fFlags & kLCDFilterMask) >> kLCDFilterShift); + } + + void setLCDFilter(SkPaint::LCDFilter hinting) { + fFlags = (fFlags & ~kLCDFilterMask) | (hinting << kLCDFilterShift); } SkMask::Format getFormat() const { diff -Naur chromium-7.0.528.0.orig/third_party/skia/src/core/SkPaint.cpp chromium-7.0.528.0/third_party/skia/src/core/SkPaint.cpp --- chromium-7.0.528.0.orig/third_party/skia/src/core/SkPaint.cpp 2010-09-18 10:06:53.000000000 +0200 +++ chromium-7.0.528.0/third_party/skia/src/core/SkPaint.cpp 2010-09-19 21:37:33.266682002 +0200 @@ -1319,6 +1319,7 @@ rec->fMaskFormat = SkToU8(computeMaskFormat(paint)); rec->fFlags = SkToU8(flags); rec->setHinting(computeHinting(paint)); + rec->setLCDFilter(paint.getLCDFilter()); if (paint.isEmbeddedBitmapText()) rec->fFlags |= SkScalerContext::kEmbeddedBitmapText_Flag; if (paint.isSubpixelText()) diff -Naur chromium-7.0.528.0.orig/third_party/skia/src/ports/SkFontHost_FreeType.cpp chromium-7.0.528.0/third_party/skia/src/ports/SkFontHost_FreeType.cpp --- chromium-7.0.528.0.orig/third_party/skia/src/ports/SkFontHost_FreeType.cpp 2010-09-18 10:06:52.000000000 +0200 +++ chromium-7.0.528.0/third_party/skia/src/ports/SkFontHost_FreeType.cpp 2010-09-19 21:37:33.267682015 +0200 @@ -95,7 +95,7 @@ #if defined(SK_SUPPORT_LCDTEXT) // Setup LCD filtering. This reduces colour fringes for LCD rendered - // glyphs. + // glyphs. May be overridden based on SkPaint/SkScalerContext settings. err = FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_DEFAULT); gLCDSupport = err == 0; #endif @@ -133,6 +133,7 @@ SkFixed fScaleX, fScaleY; FT_Matrix fMatrix22; uint32_t fLoadGlyphFlags; + int fFilterBorder; // LCDFilter dependent, zero for NONE/LEGACY, one for DEFAULT/LIGHT FT_Error setupSize(); void emboldenOutline(FT_Outline* outline); @@ -403,6 +404,29 @@ SkDebugf("---------- UNKNOWN hinting %d\n", fRec.getHinting()); break; } + switch (fRec.getLCDFilter()) { + case SkPaint::kLCDNone: + // TODO(klausw): is this thread safe? If not, need to create + // a separate gFTLibrary instance for each type in use. + FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_NONE); + fFilterBorder = 0; + break; + case SkPaint::kLCDDefault: + FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_DEFAULT); + fFilterBorder = 1; + break; + case SkPaint::kLCDLight: + FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_LIGHT); + fFilterBorder = 1; + break; + case SkPaint::kLCDLegacy: + FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_LEGACY); + fFilterBorder = 0; + break; + default: + SkDebugf("---------- UNKNOWN LCDFilter %d\n", fRec.getLCDFilter()); + break; + } } if ((fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) == 0) @@ -656,8 +680,8 @@ #if defined(SK_SUPPORT_LCDTEXT) namespace skia_freetype_support { // extern functions from SkFontHost_FreeType_Subpixel -extern void CopyFreetypeBitmapToLCDMask(const SkGlyph& dest, const FT_Bitmap& source); -extern void CopyFreetypeBitmapToVerticalLCDMask(const SkGlyph& dest, const FT_Bitmap& source); +extern void CopyFreetypeBitmapToLCDMask(const SkGlyph& dest, const FT_Bitmap& source, const int border); +extern void CopyFreetypeBitmapToVerticalLCDMask(const SkGlyph& dest, const FT_Bitmap& source, const int border); } using namespace skia_freetype_support; @@ -722,9 +746,9 @@ FT_Render_Glyph(fFace->glyph, mode); if (isVertical) - CopyFreetypeBitmapToVerticalLCDMask(glyph, fFace->glyph->bitmap); + CopyFreetypeBitmapToVerticalLCDMask(glyph, fFace->glyph->bitmap, fFilterBorder); else - CopyFreetypeBitmapToLCDMask(glyph, fFace->glyph->bitmap); + CopyFreetypeBitmapToLCDMask(glyph, fFace->glyph->bitmap, fFilterBorder); break; } diff -Naur chromium-7.0.528.0.orig/third_party/skia/src/ports/SkFontHost_FreeType_Subpixel.cpp chromium-7.0.528.0/third_party/skia/src/ports/SkFontHost_FreeType_Subpixel.cpp --- chromium-7.0.528.0.orig/third_party/skia/src/ports/SkFontHost_FreeType_Subpixel.cpp 2010-09-18 10:06:52.000000000 +0200 +++ chromium-7.0.528.0/third_party/skia/src/ports/SkFontHost_FreeType_Subpixel.cpp 2010-09-19 21:37:33.267682015 +0200 @@ -35,10 +35,10 @@ namespace skia_freetype_support { -void CopyFreetypeBitmapToLCDMask(const SkGlyph& dest, const FT_Bitmap& source) +void CopyFreetypeBitmapToLCDMask(const SkGlyph& dest, const FT_Bitmap& source, const int border) { // |source| has three alpha values per pixel and has an extra column at the - // left and right edges. + // left and right edges if border is 1. // ----- <--- a single pixel in the output // source .oOo.. |.oO|o.. @@ -47,15 +47,15 @@ // .oO o.. uint8_t* output = reinterpret_cast(dest.fImage); - const unsigned outputPitch = SkAlign4((source.width / 3) - 2); + const unsigned outputPitch = SkAlign4((source.width / 3) - 2 * border); 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 += 3*border; // skip the extra column on the left + for (int x = 3*border; x < source.width - 3*border; x += 3) { const uint8_t averageAlpha = (static_cast(inputRow[0]) + inputRow[1] + inputRow[2] + 1) / 3; *outputRow++ = averageAlpha; inputRow += 3; @@ -74,6 +74,7 @@ for (int y = 0; y < source.rows; ++y) { const uint8_t* inputRow = input; + if (!border) *output32++ = 0; // add one column on left 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,15 +84,16 @@ inputRow += 3; } + if (!border) *output32++ = 0; // add one column on right input += source.pitch; } } -void CopyFreetypeBitmapToVerticalLCDMask(const SkGlyph& dest, const FT_Bitmap& source) +void CopyFreetypeBitmapToVerticalLCDMask(const SkGlyph& dest, const FT_Bitmap& source, int border) { // |source| has three times as many rows as normal, and an extra triple on the - // top and bottom. + // top and bottom if border is 1. // source .oOo.. |.|oOo.. // .OOO.. --> |.|OOO.. @@ -104,8 +106,8 @@ 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 += 3 * source.pitch * border; // skip the extra at the beginning + for (int y = 3 * border; y < source.rows - 3 * border; y += 3) { const uint8_t* inputRow = input; uint8_t* outputRow = output; for (int x = 0; x < source.width; ++x) { @@ -125,6 +127,9 @@ const int isBGR = SkFontHost::GetSubpixelOrder() == SkFontHost::kBGR_LCDOrder; input = source.buffer; + if (!border) { + for (int x = 0; x < source.width; ++x) *output32++ = 0; // add one row at top + } for (int y = 0; y < source.rows; y += 3) { const uint8_t* inputRow = input; for (int x = 0; x < source.width; ++x) { @@ -138,6 +143,9 @@ input += source.pitch * 3; } + if (!border) { + for (int x = 0; x < source.width; ++x) *output32++ = 0; // add one row at bottom + } } } // namespace skia_freetype_support diff -Naur chromium-7.0.528.0.orig/third_party/WebKit/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp chromium-7.0.528.0/third_party/WebKit/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp --- chromium-7.0.528.0.orig/third_party/WebKit/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp 2010-09-18 10:11:01.000000000 +0200 +++ chromium-7.0.528.0/third_party/WebKit/WebCore/platform/graphics/chromium/FontPlatformDataLinux.cpp 2010-09-19 21:37:33.268682022 +0200 @@ -144,6 +144,14 @@ paint->setHinting(static_cast(m_style.hintStyle)); break; } + switch (m_style.lcdFilter) { + case FontRenderStyle::NoPreference: + paint->setHinting(skiaHinting); + break; + default: + paint->setLCDFilter(static_cast(m_style.lcdFilter)); + break; + } paint->setEmbeddedBitmapText(m_style.useBitmaps); paint->setTextSize(SkFloatToScalar(ts)); diff -Naur chromium-7.0.528.0.orig/third_party/WebKit/WebCore/platform/graphics/chromium/FontRenderStyle.h chromium-7.0.528.0/third_party/WebKit/WebCore/platform/graphics/chromium/FontRenderStyle.h --- chromium-7.0.528.0.orig/third_party/WebKit/WebCore/platform/graphics/chromium/FontRenderStyle.h 2010-09-18 10:11:01.000000000 +0200 +++ chromium-7.0.528.0/third_party/WebKit/WebCore/platform/graphics/chromium/FontRenderStyle.h 2010-09-19 21:37:33.268682022 +0200 @@ -44,6 +44,7 @@ useAutoHint(0), useHinting(0), hintStyle(0), + lcdFilter(0), useAntiAlias(0), useSubpixel(0) { } @@ -53,6 +54,7 @@ && useAutoHint == a.useAutoHint && useHinting == a.useHinting && hintStyle == a.hintStyle + && lcdFilter == a.lcdFilter && useAntiAlias == a.useAntiAlias && useSubpixel == a.useSubpixel; } @@ -65,6 +67,7 @@ char useAutoHint; // use 'auto' hinting (FreeType specific) char useHinting; // hint glyphs to the pixel grid char hintStyle; // level of hinting, 0..3 + char lcdFilter; // LCD filter style, 0..3 char useAntiAlias; // antialias glyph shapes char useSubpixel; // use subpixel antialias }; diff -Naur chromium-7.0.528.0.orig/third_party/WebKit/WebKit/chromium/public/linux/WebFontRenderStyle.h chromium-7.0.528.0/third_party/WebKit/WebKit/chromium/public/linux/WebFontRenderStyle.h --- chromium-7.0.528.0.orig/third_party/WebKit/WebKit/chromium/public/linux/WebFontRenderStyle.h 2010-09-18 10:09:02.000000000 +0200 +++ chromium-7.0.528.0/third_party/WebKit/WebKit/chromium/public/linux/WebFontRenderStyle.h 2010-09-19 21:37:33.268682022 +0200 @@ -46,6 +46,7 @@ char useAutoHint; // use 'auto' hinting (FreeType specific) char useHinting; // hint glyphs to the pixel grid char hintStyle; // level of hinting, 0..3 + char lcdFilter; // LCD filter style, 0..3 char useAntiAlias; // antialias glyph shapes char useSubpixel; // use subpixel antialias diff -Naur chromium-7.0.528.0.orig/third_party/WebKit/WebKit/chromium/src/gtk/WebFontInfo.cpp chromium-7.0.528.0/third_party/WebKit/WebKit/chromium/src/gtk/WebFontInfo.cpp --- chromium-7.0.528.0.orig/third_party/WebKit/WebKit/chromium/src/gtk/WebFontInfo.cpp 2010-09-18 10:08:48.000000000 +0200 +++ chromium-7.0.528.0/third_party/WebKit/WebKit/chromium/src/gtk/WebFontInfo.cpp 2010-09-19 21:37:33.269682023 +0200 @@ -165,6 +165,8 @@ out->useHinting = b; if (FcPatternGetInteger(match, FC_HINT_STYLE, 0, &i) == FcResultMatch) out->hintStyle = i; + if (FcPatternGetInteger(match, FC_LCD_FILTER, 0, &i) == FcResultMatch) + out->lcdFilter = i; if (FcPatternGetInteger(match, FC_RGBA, 0, &i) == FcResultMatch) { switch (i) { case FC_RGBA_NONE: diff -Naur chromium-7.0.528.0.orig/third_party/WebKit/WebKit/chromium/src/linux/WebFontRenderStyle.cpp chromium-7.0.528.0/third_party/WebKit/WebKit/chromium/src/linux/WebFontRenderStyle.cpp --- chromium-7.0.528.0.orig/third_party/WebKit/WebKit/chromium/src/linux/WebFontRenderStyle.cpp 2010-09-18 10:08:51.000000000 +0200 +++ chromium-7.0.528.0/third_party/WebKit/WebKit/chromium/src/linux/WebFontRenderStyle.cpp 2010-09-19 21:37:33.269682023 +0200 @@ -43,6 +43,7 @@ out->useAutoHint = useAutoHint; out->useHinting = useHinting; out->hintStyle = hintStyle; + out->lcdFilter = lcdFilter; out->useAntiAlias = useAntiAlias; out->useSubpixel = useSubpixel; } @@ -53,6 +54,7 @@ useAutoHint = 2; useHinting = 2; hintStyle = 0; + lcdFilter = 1; useAntiAlias = 2; useSubpixel = 2; }