Detect that we're drawing to a device that has per-pixel alpha, and if so,
disable LCD text. Add experimental flag to force AA in fontscaler (windows-only). Hope to remove this later. git-svn-id: http://skia.googlecode.com/svn/trunk@2387 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
e958c6949a
commit
6fc3c1fe42
@ -60,18 +60,16 @@ static void blit_lcd16_row(SkPMColor dst[], const uint16_t src[],
|
||||
maskG = maskG * srcA >> 8;
|
||||
maskB = maskB * srcA >> 8;
|
||||
|
||||
int maskA = SkMax32(SkMax32(maskR, maskG), maskB);
|
||||
|
||||
int dstA = SkGetPackedA32(d);
|
||||
int dstR = SkGetPackedR32(d);
|
||||
int dstG = SkGetPackedG32(d);
|
||||
int dstB = SkGetPackedB32(d);
|
||||
|
||||
// nocheck version for now, until we cleanup GDI's garbage bits
|
||||
dst[i] = SkPackARGB32NoCheck(blend32(0xFF, dstA, maskA),
|
||||
blend32(srcR, dstR, maskR),
|
||||
blend32(srcG, dstG, maskG),
|
||||
blend32(srcB, dstB, maskB));
|
||||
// LCD blitting is only supported if the dst is known/required\
|
||||
// to be opaque
|
||||
dst[i] = SkPackARGB32(0xFF,
|
||||
blend32(srcR, dstR, maskR),
|
||||
blend32(srcG, dstG, maskG),
|
||||
blend32(srcB, dstB, maskB));
|
||||
}
|
||||
}
|
||||
|
||||
@ -105,18 +103,16 @@ static void blit_lcd16_opaque_row(SkPMColor dst[], const uint16_t src[],
|
||||
maskG = upscale31To32(maskG);
|
||||
maskB = upscale31To32(maskB);
|
||||
|
||||
int maskA = SkMax32(SkMax32(maskR, maskG), maskB);
|
||||
|
||||
int dstA = SkGetPackedA32(d);
|
||||
int dstR = SkGetPackedR32(d);
|
||||
int dstG = SkGetPackedG32(d);
|
||||
int dstB = SkGetPackedB32(d);
|
||||
|
||||
// nocheck version for now, until we cleanup GDI's garbage bits
|
||||
dst[i] = SkPackARGB32NoCheck(blend32(0xFF, dstA, maskA),
|
||||
blend32(srcR, dstR, maskR),
|
||||
blend32(srcG, dstG, maskG),
|
||||
blend32(srcB, dstB, maskB));
|
||||
// LCD blitting is only supported if the dst is known/required
|
||||
// to be opaque
|
||||
dst[i] = SkPackARGB32(0xFF,
|
||||
blend32(srcR, dstR, maskR),
|
||||
blend32(srcG, dstG, maskG),
|
||||
blend32(srcB, dstB, maskB));
|
||||
}
|
||||
}
|
||||
|
||||
@ -150,14 +146,13 @@ static void blit_lcd32_row(SkPMColor dst[], const uint32_t src[],
|
||||
maskG = maskG * srcA >> 8;
|
||||
maskB = maskB * srcA >> 8;
|
||||
|
||||
int maskA = SkMax32(SkMax32(maskR, maskG), maskB);
|
||||
|
||||
int dstA = SkGetPackedA32(d);
|
||||
int dstR = SkGetPackedR32(d);
|
||||
int dstG = SkGetPackedG32(d);
|
||||
int dstB = SkGetPackedB32(d);
|
||||
|
||||
dst[i] = SkPackARGB32(SkAlphaBlend(0xFF, dstA, maskA),
|
||||
// LCD blitting is only supported if the dst is known/required
|
||||
// to be opaque
|
||||
dst[i] = SkPackARGB32(0xFF,
|
||||
SkAlphaBlend(srcR, dstR, maskR),
|
||||
SkAlphaBlend(srcG, dstG, maskG),
|
||||
SkAlphaBlend(srcB, dstB, maskB));
|
||||
|
@ -219,12 +219,13 @@ void SkDevice::drawDevice(const SkDraw& draw, SkDevice* device,
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool SkDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
|
||||
if (!paint.isLCDRenderText()) {
|
||||
if (!paint.isLCDRenderText() || !paint.isAntiAlias()) {
|
||||
// we're cool with the paint as is
|
||||
return false;
|
||||
}
|
||||
|
||||
if (SkBitmap::kARGB_8888_Config != fBitmap.config() ||
|
||||
!fBitmap.isOpaque() ||
|
||||
paint.getShader() ||
|
||||
paint.getXfermode() || // unless its srcover
|
||||
paint.getMaskFilter() ||
|
||||
@ -235,6 +236,10 @@ bool SkDevice::filterTextFlags(const SkPaint& paint, TextFlags* flags) {
|
||||
paint.getStyle() != SkPaint::kFill_Style) {
|
||||
// turn off lcd
|
||||
flags->fFlags = paint.getFlags() & ~SkPaint::kLCDRenderText_Flag;
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
// flag that we *really* want AA
|
||||
flags->fFlags |= SkPaint::kForceAAText_Flag;
|
||||
#endif
|
||||
flags->fHinting = paint.getHinting();
|
||||
return true;
|
||||
}
|
||||
|
@ -1340,6 +1340,11 @@ void SkScalerContext::MakeRec(const SkPaint& paint,
|
||||
if (paint.isAutohinted()) {
|
||||
flags |= SkScalerContext::kAutohinting_Flag;
|
||||
}
|
||||
#ifdef SK_BUILD_FOR_WIN
|
||||
if (paint.getFlags() & SkPaint::kForceAAText_Flag) {
|
||||
flags |= SkScalerContext::kForceAA_Flag;
|
||||
}
|
||||
#endif
|
||||
rec->fFlags = SkToU16(flags);
|
||||
|
||||
// setHinting modifies fFlags, so do this last
|
||||
|
@ -31,11 +31,6 @@ template <typename T> T* SkTAddByteOffset(T* ptr, size_t byteOffset) {
|
||||
return (T*)((char*)ptr + byteOffset);
|
||||
}
|
||||
|
||||
// When we request ANTIALIAS quality, we often seemt to get BW instead
|
||||
// This flag "fixes" that by actually requesting LCD output, and filtering
|
||||
// it down to gray-aa
|
||||
#define FORCE_AA_BY_CAPTURING_LCD_OUTPUT
|
||||
|
||||
// define this in your Makefile or .gyp to enforce AA requests
|
||||
// which GDI ignores at small sizes. This flag guarantees AA
|
||||
// for rotated text, regardless of GDI's notions.
|
||||
@ -483,11 +478,15 @@ static BYTE compute_quality(const SkScalerContext::Rec& rec) {
|
||||
case SkMask::kLCD32_Format:
|
||||
return CLEARTYPE_QUALITY;
|
||||
default:
|
||||
#ifdef FORCE_AA_BY_CAPTURING_LCD_OUTPUT
|
||||
return CLEARTYPE_QUALITY;
|
||||
#else
|
||||
return ANTIALIASED_QUALITY;
|
||||
#endif
|
||||
// here we just want AA, but we may have to force the issue
|
||||
// since sometimes GDI will instead really give us BW
|
||||
// (for some fonts and some sizes)
|
||||
if (rec.fFlags & SkScalerContext::kForceAA_Flag) {
|
||||
return CLEARTYPE_QUALITY;
|
||||
} else {
|
||||
return ANTIALIASED_QUALITY;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -697,19 +696,11 @@ void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx, SkPa
|
||||
// whenever we copy it into skia's buffer
|
||||
|
||||
static inline uint8_t rgb_to_a8(SkGdiRGB rgb) {
|
||||
#ifdef FORCE_AA_BY_CAPTURING_LCD_OUTPUT
|
||||
int r = (rgb >> 16) & 0xFF;
|
||||
int g = (rgb >> 8) & 0xFF;
|
||||
int b = (rgb >> 0) & 0xFF;
|
||||
|
||||
// int ave = (r * 5 + g * 6 + b * 5) >> 4;
|
||||
int ave = (r * 2 + g * 5 + b) >> 3; // luminance
|
||||
|
||||
return ave;
|
||||
#else
|
||||
// can pick any component (low 3 bytes), since we're grayscale
|
||||
return rgb & 0xFF;
|
||||
#endif
|
||||
return (r * 2 + g * 5 + b) >> 3; // luminance
|
||||
}
|
||||
|
||||
static inline uint16_t rgb_to_lcd16(SkGdiRGB rgb) {
|
||||
@ -1309,6 +1300,11 @@ void SkFontHost::FilterRec(SkScalerContext::Rec* rec) {
|
||||
rec->fMaskFormat = SkMask::kLCD32_Format;
|
||||
}
|
||||
#endif
|
||||
// don't specify gamma if we BW (perhaps caller should do this check)
|
||||
if (SkMask::kBW_Format == rec->fMaskFormat) {
|
||||
rec->fFlags &= ~(SkScalerContext::kGammaForBlack_Flag |
|
||||
SkScalerContext::kGammaForWhite_Flag);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
Loading…
Reference in New Issue
Block a user