Fix greenish text rendering on Linux.
https://codereview.appspot.com/6484048/ git-svn-id: http://skia.googlecode.com/svn/trunk@5280 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
0032407e29
commit
fd668cfffe
@ -27,7 +27,6 @@
|
||||
],
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'-lfreetype',
|
||||
'-lpthread',
|
||||
],
|
||||
},
|
||||
|
@ -37,12 +37,23 @@
|
||||
],
|
||||
'conditions': [
|
||||
[ 'skia_os in ["linux", "freebsd", "openbsd", "solaris"]', {
|
||||
'defines': [
|
||||
#The font host requires at least FreeType 2.3.0 at runtime.
|
||||
'SK_FONTHOST_FREETYPE_RUNTIME_VERSION=0x020300',
|
||||
'SK_CAN_USE_DLOPEN=1',
|
||||
],
|
||||
'sources': [
|
||||
'../src/ports/SkThread_pthread.cpp',
|
||||
'../src/ports/SkFontHost_FreeType.cpp',
|
||||
'../src/ports/SkFontHost_FreeType_common.cpp',
|
||||
'../src/ports/SkFontHost_linux.cpp',
|
||||
],
|
||||
'link_settings': {
|
||||
'libraries': [
|
||||
'-lfreetype',
|
||||
'-ldl',
|
||||
],
|
||||
},
|
||||
}],
|
||||
[ 'skia_os == "mac"', {
|
||||
'include_dirs': [
|
||||
@ -100,6 +111,12 @@
|
||||
],
|
||||
}],
|
||||
[ 'skia_os == "android"', {
|
||||
'defines': [
|
||||
#Android provides at least FreeType 2.4.0 at runtime.
|
||||
'SK_FONTHOST_FREETYPE_RUNTIME_VERSION=0x020400',
|
||||
#Skia should not use dlopen on Android.
|
||||
'SK_CAN_USE_DLOPEN=0',
|
||||
],
|
||||
'sources!': [
|
||||
'../src/ports/SkDebug_stdio.cpp',
|
||||
],
|
||||
|
@ -53,9 +53,12 @@ void SkTMaskGamma_build_correcting_lut(uint8_t table[256], U8CPU srcI, SkScalar
|
||||
const SkColorSpaceLuminance& dstConvert) {
|
||||
const float src = (float)srcI / 255.0f;
|
||||
const float linSrc = srcConvert.toLuma(src);
|
||||
//Guess at the dst.
|
||||
const float linDst = 1.0f - linSrc;
|
||||
const float dst = dstConvert.fromLuma(linDst);
|
||||
//Guess at the dst. The perceptual inverse provides smaller visual
|
||||
//discontinuities when slight changes to desaturated colors cause a channel
|
||||
//to map to a different correcting lut with neighboring srcI.
|
||||
//See https://code.google.com/p/chromium/issues/detail?id=141425#c59 .
|
||||
const float dst = 1.0f - src;
|
||||
const float linDst = dstConvert.toLuma(dst);
|
||||
|
||||
//Contrast value tapers off to 0 as the src luminance becomes white
|
||||
const float adjustedContrast = SkScalarToFloat(contrast) * linDst;
|
||||
|
@ -1706,8 +1706,11 @@ void SkScalerContext::PostMakeRec(const SkPaint& paint, SkScalerContext::Rec* re
|
||||
SkColor color = rec->getLuminanceColor();
|
||||
SkAutoMutexAcquire ama(gMaskGammaCacheMutex);
|
||||
U8CPU lum = cachedPaintLuminance(rec->getPaintGamma())->computeLuminance(color);
|
||||
// HACK: Prevents green from being pre-blended as white.
|
||||
lum -= ((255 - lum) * lum) / 255;
|
||||
//If we are asked to look like LCD, look like LCD.
|
||||
if (!(rec->fFlags & SkScalerContext::kGenA8FromLCD_Flag)) {
|
||||
// HACK: Prevents green from being pre-blended as white.
|
||||
lum -= ((255 - lum) * lum) / 255;
|
||||
}
|
||||
|
||||
// reduce to our finite number of bits
|
||||
SkMaskGamma* maskGamma = cachedMaskGamma(rec->getContrast(),
|
||||
|
@ -108,8 +108,9 @@ struct SkScalerContextRec {
|
||||
//The following typedef hides from the rest of the implementation the number of
|
||||
//most significant bits to consider when creating mask gamma tables. Two bits
|
||||
//per channel was chosen as a balance between fidelity (more bits) and cache
|
||||
//sizes (fewer bits).
|
||||
typedef SkTMaskGamma<2, 2, 2> SkMaskGamma;
|
||||
//sizes (fewer bits). Three bits per channel was chosen when #303942; (used by
|
||||
//the Chrome UI) turned out too green.
|
||||
typedef SkTMaskGamma<3, 3, 3> SkMaskGamma;
|
||||
|
||||
class SkScalerContext {
|
||||
public:
|
||||
|
@ -24,6 +24,9 @@
|
||||
#include "SkTemplates.h"
|
||||
#include "SkThread.h"
|
||||
|
||||
#if defined(SK_CAN_USE_DLOPEN)
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
#include <ft2build.h>
|
||||
#include FT_FREETYPE_H
|
||||
#include FT_OUTLINE_H
|
||||
@ -83,23 +86,51 @@ static bool gLCDSupportValid; // true iff |gLCDSupport| has been set.
|
||||
static bool gLCDSupport; // true iff LCD is supported by the runtime.
|
||||
static int gLCDExtra; // number of extra pixels for filtering.
|
||||
|
||||
// FT_Library_SetLcdFilterWeights was introduced in FreeType 2.4.0.
|
||||
// The following platforms provide FreeType of at least 2.4.0.
|
||||
// Ubuntu >= 11.04 (previous deprecated April 2013)
|
||||
// Debian >= 6.0 (good)
|
||||
// OpenSuse >= 11.4 (previous deprecated January 2012 / Nov 2013 for Evergreen 11.2)
|
||||
// Fedora >= 14 (good)
|
||||
// Android >= Gingerbread (good)
|
||||
typedef FT_Error (*FT_Library_SetLcdFilterWeightsProc)(FT_Library, unsigned char*);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static bool
|
||||
InitFreetype() {
|
||||
static bool InitFreetype() {
|
||||
FT_Error err = FT_Init_FreeType(&gFTLibrary);
|
||||
if (err) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Setup LCD filtering. This reduces colour fringes for LCD rendered
|
||||
// glyphs.
|
||||
// Setup LCD filtering. This reduces color fringes for LCD smoothed glyphs.
|
||||
#ifdef FT_LCD_FILTER_H
|
||||
err = FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_DEFAULT);
|
||||
// err = FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_LIGHT);
|
||||
gLCDSupport = err == 0;
|
||||
if (gLCDSupport) {
|
||||
gLCDExtra = 2; //DEFAULT and LIGHT add one pixel to each side.
|
||||
//Use light as default, as FT_LCD_FILTER_DEFAULT adds up to 0x110.
|
||||
err = FT_Library_SetLcdFilter(gFTLibrary, FT_LCD_FILTER_LIGHT);
|
||||
if (0 == err) {
|
||||
gLCDSupport = true;
|
||||
gLCDExtra = 2; //Using a filter adds one full pixel to each side.
|
||||
|
||||
static unsigned char gaussianLikeWeights[] = { 0x17, 0x40, 0x52, 0x40, 0x17 };
|
||||
//static unsigned char triangleLikeWeights[] = { 0x1C, 0x39, 0x56, 0x39, 0x1C };
|
||||
|
||||
#if defined(SK_FONTHOST_FREETYPE_RUNTIME_VERSION) && \
|
||||
SK_FONTHOST_FREETYPE_RUNTIME_VERSION > 0x020400
|
||||
err = FT_Library_SetLcdFilterWeights(gFTLibrary, gaussianLikeWeights);
|
||||
#elif defined(SK_CAN_USE_DLOPEN) && SK_CAN_USE_DLOPEN == 1
|
||||
//The FreeType library is already loaded, so symbols are available in process.
|
||||
void* self = dlopen(NULL, RTLD_LAZY);
|
||||
if (NULL != self) {
|
||||
FT_Library_SetLcdFilterWeightsProc setLcdFilterWeights;
|
||||
//The following cast is non-standard, but safe for POSIX.
|
||||
*reinterpret_cast<void**>(&setLcdFilterWeights) = dlsym(self, "FT_Library_SetLcdFilterWeights");
|
||||
dlclose(self);
|
||||
|
||||
if (NULL != setLcdFilterWeights) {
|
||||
err = setLcdFilterWeights(gFTLibrary, gaussianLikeWeights);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
gLCDSupport = false;
|
||||
@ -610,7 +641,7 @@ void SkFontHost::FilterRec(SkScalerContext::Rec* rec) {
|
||||
if (rec->fTextSize > SkIntToScalar(1 << 14)) {
|
||||
rec->fTextSize = SkIntToScalar(1 << 14);
|
||||
}
|
||||
|
||||
|
||||
if (!gLCDSupportValid) {
|
||||
InitFreetype();
|
||||
FT_Done_FreeType(gFTLibrary);
|
||||
|
Loading…
Reference in New Issue
Block a user