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 |