| OLD | NEW |
| 1 | 1 |
| 2 /* | 2 /* |
| 3 * Copyright 2006 The Android Open Source Project | 3 * Copyright 2006 The Android Open Source Project |
| 4 * | 4 * |
| 5 * Use of this source code is governed by a BSD-style license that can be | 5 * Use of this source code is governed by a BSD-style license that can be |
| 6 * found in the LICENSE file. | 6 * found in the LICENSE file. |
| 7 */ | 7 */ |
| 8 | 8 |
| 9 #include "SkAdvancedTypefaceMetrics.h" | 9 #include "SkAdvancedTypefaceMetrics.h" |
| 10 #include "SkBase64.h" | 10 #include "SkBase64.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 | 51 |
| 52 // always packed xxRRGGBB | 52 // always packed xxRRGGBB |
| 53 typedef uint32_t SkGdiRGB; | 53 typedef uint32_t SkGdiRGB; |
| 54 | 54 |
| 55 // define this in your Makefile or .gyp to enforce AA requests | 55 // define this in your Makefile or .gyp to enforce AA requests |
| 56 // which GDI ignores at small sizes. This flag guarantees AA | 56 // which GDI ignores at small sizes. This flag guarantees AA |
| 57 // for rotated text, regardless of GDI's notions. | 57 // for rotated text, regardless of GDI's notions. |
| 58 //#define SK_ENFORCE_ROTATED_TEXT_AA_ON_WINDOWS | 58 //#define SK_ENFORCE_ROTATED_TEXT_AA_ON_WINDOWS |
| 59 | 59 |
| 60 static bool isLCD(const SkScalerContext::Rec& rec) { | 60 static bool isLCD(const SkScalerContext::Rec& rec) { |
| 61 return SkMask::kLCD16_Format == rec.fMaskFormat || | 61 return SkMask::kLCD16_Format == rec.fMaskFormat; |
| 62 SkMask::kLCD32_Format == rec.fMaskFormat; | |
| 63 } | 62 } |
| 64 | 63 |
| 65 static bool bothZero(SkScalar a, SkScalar b) { | 64 static bool bothZero(SkScalar a, SkScalar b) { |
| 66 return 0 == a && 0 == b; | 65 return 0 == a && 0 == b; |
| 67 } | 66 } |
| 68 | 67 |
| 69 // returns false if there is any non-90-rotation or skew | 68 // returns false if there is any non-90-rotation or skew |
| 70 static bool isAxisAligned(const SkScalerContext::Rec& rec) { | 69 static bool isAxisAligned(const SkScalerContext::Rec& rec) { |
| 71 return 0 == rec.fPreSkewX && | 70 return 0 == rec.fPreSkewX && |
| 72 (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) || | 71 (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) || |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 583 | 582 |
| 584 static FIXED float2FIXED(float x) { | 583 static FIXED float2FIXED(float x) { |
| 585 return SkFixedToFIXED(SkFloatToFixed(x)); | 584 return SkFixedToFIXED(SkFloatToFixed(x)); |
| 586 } | 585 } |
| 587 | 586 |
| 588 static BYTE compute_quality(const SkScalerContext::Rec& rec) { | 587 static BYTE compute_quality(const SkScalerContext::Rec& rec) { |
| 589 switch (rec.fMaskFormat) { | 588 switch (rec.fMaskFormat) { |
| 590 case SkMask::kBW_Format: | 589 case SkMask::kBW_Format: |
| 591 return NONANTIALIASED_QUALITY; | 590 return NONANTIALIASED_QUALITY; |
| 592 case SkMask::kLCD16_Format: | 591 case SkMask::kLCD16_Format: |
| 593 case SkMask::kLCD32_Format: | |
| 594 return CLEARTYPE_QUALITY; | 592 return CLEARTYPE_QUALITY; |
| 595 default: | 593 default: |
| 596 if (rec.fFlags & SkScalerContext::kGenA8FromLCD_Flag) { | 594 if (rec.fFlags & SkScalerContext::kGenA8FromLCD_Flag) { |
| 597 return CLEARTYPE_QUALITY; | 595 return CLEARTYPE_QUALITY; |
| 598 } else { | 596 } else { |
| 599 return ANTIALIASED_QUALITY; | 597 return ANTIALIASED_QUALITY; |
| 600 } | 598 } |
| 601 } | 599 } |
| 602 } | 600 } |
| 603 | 601 |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1126 const uint8_t* tableB) { | 1124 const uint8_t* tableB) { |
| 1127 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 16) & 0xFF, tableR); | 1125 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 16) & 0xFF, tableR); |
| 1128 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 8) & 0xFF, tableG); | 1126 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 8) & 0xFF, tableG); |
| 1129 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 0) & 0xFF, tableB); | 1127 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 0) & 0xFF, tableB); |
| 1130 #if SK_SHOW_TEXT_BLIT_COVERAGE | 1128 #if SK_SHOW_TEXT_BLIT_COVERAGE |
| 1131 r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10); | 1129 r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10); |
| 1132 #endif | 1130 #endif |
| 1133 return SkPack888ToRGB16(r, g, b); | 1131 return SkPack888ToRGB16(r, g, b); |
| 1134 } | 1132 } |
| 1135 | 1133 |
| 1136 template<bool APPLY_PREBLEND> | |
| 1137 static inline SkPMColor rgb_to_lcd32(SkGdiRGB rgb, const uint8_t* tableR, | |
| 1138 const uint8_t* tableG, | |
| 1139 const uint8_t* tableB) { | |
| 1140 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 16) & 0xFF, tableR); | |
| 1141 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 8) & 0xFF, tableG); | |
| 1142 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 0) & 0xFF, tableB); | |
| 1143 #if SK_SHOW_TEXT_BLIT_COVERAGE | |
| 1144 r = SkMax32(r, 10); g = SkMax32(g, 10); b = SkMax32(b, 10); | |
| 1145 #endif | |
| 1146 return SkPackARGB32(0xFF, r, g, b); | |
| 1147 } | |
| 1148 | |
| 1149 // Is this GDI color neither black nor white? If so, we have to keep this | 1134 // Is this GDI color neither black nor white? If so, we have to keep this |
| 1150 // image as is, rather than smashing it down to a BW mask. | 1135 // image as is, rather than smashing it down to a BW mask. |
| 1151 // | 1136 // |
| 1152 // returns int instead of bool, since we don't want/have to pay to convert | 1137 // returns int instead of bool, since we don't want/have to pay to convert |
| 1153 // the zero/non-zero value into a bool | 1138 // the zero/non-zero value into a bool |
| 1154 static int is_not_black_or_white(SkGdiRGB c) { | 1139 static int is_not_black_or_white(SkGdiRGB c) { |
| 1155 // same as (but faster than) | 1140 // same as (but faster than) |
| 1156 // c &= 0x00FFFFFF; | 1141 // c &= 0x00FFFFFF; |
| 1157 // return 0 == c || 0x00FFFFFF == c; | 1142 // return 0 == c || 0x00FFFFFF == c; |
| 1158 return (c + (c & 1)) & 0x00FFFFFF; | 1143 return (c + (c & 1)) & 0x00FFFFFF; |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1251 | 1236 |
| 1252 for (int y = 0; y < glyph.fHeight; y++) { | 1237 for (int y = 0; y < glyph.fHeight; y++) { |
| 1253 for (int i = 0; i < width; i++) { | 1238 for (int i = 0; i < width; i++) { |
| 1254 dst[i] = rgb_to_lcd16<APPLY_PREBLEND>(src[i], tableR, tableG, tableB
); | 1239 dst[i] = rgb_to_lcd16<APPLY_PREBLEND>(src[i], tableR, tableG, tableB
); |
| 1255 } | 1240 } |
| 1256 src = SkTAddOffset<const SkGdiRGB>(src, srcRB); | 1241 src = SkTAddOffset<const SkGdiRGB>(src, srcRB); |
| 1257 dst = (uint16_t*)((char*)dst - dstRB); | 1242 dst = (uint16_t*)((char*)dst - dstRB); |
| 1258 } | 1243 } |
| 1259 } | 1244 } |
| 1260 | 1245 |
| 1261 template<bool APPLY_PREBLEND> | |
| 1262 static void rgb_to_lcd32(const SkGdiRGB* SK_RESTRICT src, size_t srcRB, const Sk
Glyph& glyph, | |
| 1263 const uint8_t* tableR, const uint8_t* tableG, const uin
t8_t* tableB) { | |
| 1264 const size_t dstRB = glyph.rowBytes(); | |
| 1265 const int width = glyph.fWidth; | |
| 1266 uint32_t* SK_RESTRICT dst = (uint32_t*)((char*)glyph.fImage + (glyph.fHeight
- 1) * dstRB); | |
| 1267 | |
| 1268 for (int y = 0; y < glyph.fHeight; y++) { | |
| 1269 for (int i = 0; i < width; i++) { | |
| 1270 dst[i] = rgb_to_lcd32<APPLY_PREBLEND>(src[i], tableR, tableG, tableB
); | |
| 1271 } | |
| 1272 src = SkTAddOffset<const SkGdiRGB>(src, srcRB); | |
| 1273 dst = (uint32_t*)((char*)dst - dstRB); | |
| 1274 } | |
| 1275 } | |
| 1276 | |
| 1277 static inline unsigned clamp255(unsigned x) { | 1246 static inline unsigned clamp255(unsigned x) { |
| 1278 SkASSERT(x <= 256); | 1247 SkASSERT(x <= 256); |
| 1279 return x - (x >> 8); | 1248 return x - (x >> 8); |
| 1280 } | 1249 } |
| 1281 | 1250 |
| 1282 void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) { | 1251 void SkScalerContext_GDI::generateImage(const SkGlyph& glyph) { |
| 1283 SkASSERT(fDDC); | 1252 SkASSERT(fDDC); |
| 1284 | 1253 |
| 1285 const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; | 1254 const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; |
| 1286 const bool isAA = !isLCD(fRec); | 1255 const bool isAA = !isLCD(fRec); |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1349 rgb_to_a8<true>(src, srcRB, glyph, fPreBlend.fG); | 1318 rgb_to_a8<true>(src, srcRB, glyph, fPreBlend.fG); |
| 1350 } else { | 1319 } else { |
| 1351 rgb_to_a8<false>(src, srcRB, glyph, fPreBlend.fG); | 1320 rgb_to_a8<false>(src, srcRB, glyph, fPreBlend.fG); |
| 1352 } | 1321 } |
| 1353 } else { // LCD16 | 1322 } else { // LCD16 |
| 1354 const SkGdiRGB* src = (const SkGdiRGB*)bits; | 1323 const SkGdiRGB* src = (const SkGdiRGB*)bits; |
| 1355 if (is_rgb_really_bw(src, width, glyph.fHeight, srcRB)) { | 1324 if (is_rgb_really_bw(src, width, glyph.fHeight, srcRB)) { |
| 1356 rgb_to_bw(src, srcRB, glyph); | 1325 rgb_to_bw(src, srcRB, glyph); |
| 1357 ((SkGlyph*)&glyph)->fMaskFormat = SkMask::kBW_Format; | 1326 ((SkGlyph*)&glyph)->fMaskFormat = SkMask::kBW_Format; |
| 1358 } else { | 1327 } else { |
| 1359 if (SkMask::kLCD16_Format == glyph.fMaskFormat) { | 1328 SkASSERT(SkMask::kLCD16_Format == glyph.fMaskFormat); |
| 1360 if (fPreBlend.isApplicable()) { | 1329 if (fPreBlend.isApplicable()) { |
| 1361 rgb_to_lcd16<true>(src, srcRB, glyph, | 1330 rgb_to_lcd16<true>(src, srcRB, glyph, |
| 1362 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB)
; | 1331 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB); |
| 1363 } else { | |
| 1364 rgb_to_lcd16<false>(src, srcRB, glyph, | |
| 1365 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB
); | |
| 1366 } | |
| 1367 } else { | 1332 } else { |
| 1368 SkASSERT(SkMask::kLCD32_Format == glyph.fMaskFormat); | 1333 rgb_to_lcd16<false>(src, srcRB, glyph, |
| 1369 if (fPreBlend.isApplicable()) { | 1334 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB); |
| 1370 rgb_to_lcd32<true>(src, srcRB, glyph, | |
| 1371 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB)
; | |
| 1372 } else { | |
| 1373 rgb_to_lcd32<false>(src, srcRB, glyph, | |
| 1374 fPreBlend.fR, fPreBlend.fG, fPreBlend.fB
); | |
| 1375 } | |
| 1376 } | 1335 } |
| 1377 } | 1336 } |
| 1378 } | 1337 } |
| 1379 } | 1338 } |
| 1380 | 1339 |
| 1381 class GDIGlyphbufferPointIter { | 1340 class GDIGlyphbufferPointIter { |
| 1382 public: | 1341 public: |
| 1383 GDIGlyphbufferPointIter(const uint8_t* glyphbuf, DWORD total_size) | 1342 GDIGlyphbufferPointIter(const uint8_t* glyphbuf, DWORD total_size) |
| 1384 : fHeaderIter(glyphbuf, total_size), fCurveIter(), fPointIter() | 1343 : fHeaderIter(glyphbuf, total_size), fCurveIter(), fPointIter() |
| 1385 { } | 1344 { } |
| (...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2576 | 2535 |
| 2577 private: | 2536 private: |
| 2578 SkTDArray<ENUMLOGFONTEX> fLogFontArray; | 2537 SkTDArray<ENUMLOGFONTEX> fLogFontArray; |
| 2579 }; | 2538 }; |
| 2580 | 2539 |
| 2581 /////////////////////////////////////////////////////////////////////////////// | 2540 /////////////////////////////////////////////////////////////////////////////// |
| 2582 | 2541 |
| 2583 SkFontMgr* SkFontMgr_New_GDI() { | 2542 SkFontMgr* SkFontMgr_New_GDI() { |
| 2584 return SkNEW(SkFontMgrGDI); | 2543 return SkNEW(SkFontMgrGDI); |
| 2585 } | 2544 } |
| OLD | NEW |