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 "SkTypes.h" // Keep this before any #ifdef ... | 9 #include "SkTypes.h" // Keep this before any #ifdef ... |
10 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) | 10 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) |
(...skipping 855 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
866 CGContextSetShouldSubpixelQuantizeFonts(fCG, false); | 866 CGContextSetShouldSubpixelQuantizeFonts(fCG, false); |
867 | 867 |
868 // Because CG always draws from the horizontal baseline, | 868 // Because CG always draws from the horizontal baseline, |
869 // if there is a non-integral translation from the horizontal origin to
the vertical origin, | 869 // if there is a non-integral translation from the horizontal origin to
the vertical origin, |
870 // then CG cannot draw the glyph in the correct location without subpixe
l positioning. | 870 // then CG cannot draw the glyph in the correct location without subpixe
l positioning. |
871 CGContextSetAllowsFontSubpixelPositioning(fCG, true); | 871 CGContextSetAllowsFontSubpixelPositioning(fCG, true); |
872 CGContextSetShouldSubpixelPositionFonts(fCG, true); | 872 CGContextSetShouldSubpixelPositionFonts(fCG, true); |
873 | 873 |
874 CGContextSetTextDrawingMode(fCG, kCGTextFill); | 874 CGContextSetTextDrawingMode(fCG, kCGTextFill); |
875 | 875 |
876 #if SK_IGNORE_MAC_FONT_WEIGHT_FIX | |
877 // Draw white on black to create mask. | |
878 // TODO: Draw black on white and invert, CG has a special case codepath. | |
879 CGContextSetGrayFillColor(fCG, 1.0f, 1.0f); | |
880 #else | |
881 // Draw black on white to create mask. (Special path exists to speed thi
s up in CG.) | 876 // Draw black on white to create mask. (Special path exists to speed thi
s up in CG.) |
882 CGContextSetGrayFillColor(fCG, 0.0f, 1.0f); | 877 CGContextSetGrayFillColor(fCG, 0.0f, 1.0f); |
883 #endif | |
884 | 878 |
885 // force our checks below to happen | 879 // force our checks below to happen |
886 fDoAA = !doAA; | 880 fDoAA = !doAA; |
887 fDoLCD = !doLCD; | 881 fDoLCD = !doLCD; |
888 | 882 |
889 if (legacy_CTFontDrawGlyphs == ctFontDrawGlyphs) { | 883 if (legacy_CTFontDrawGlyphs == ctFontDrawGlyphs) { |
890 // CTFontDrawGlyphs will apply the font, font size, and font matrix
to the CGContext. | 884 // CTFontDrawGlyphs will apply the font, font size, and font matrix
to the CGContext. |
891 // Our 'fake' one does not, so set up the CGContext here. | 885 // Our 'fake' one does not, so set up the CGContext here. |
892 CGContextSetFont(fCG, context.fCGFont); | 886 CGContextSetFont(fCG, context.fCGFont); |
893 CGContextSetFontSize(fCG, CTFontGetSize(context.fCTFont)); | 887 CGContextSetFontSize(fCG, CTFontGetSize(context.fCTFont)); |
894 } | 888 } |
895 CGContextSetTextMatrix(fCG, context.fTransform); | 889 CGContextSetTextMatrix(fCG, context.fTransform); |
896 } | 890 } |
897 | 891 |
898 if (fDoAA != doAA) { | 892 if (fDoAA != doAA) { |
899 CGContextSetShouldAntialias(fCG, doAA); | 893 CGContextSetShouldAntialias(fCG, doAA); |
900 fDoAA = doAA; | 894 fDoAA = doAA; |
901 } | 895 } |
902 if (fDoLCD != doLCD) { | 896 if (fDoLCD != doLCD) { |
903 CGContextSetShouldSmoothFonts(fCG, doLCD); | 897 CGContextSetShouldSmoothFonts(fCG, doLCD); |
904 fDoLCD = doLCD; | 898 fDoLCD = doLCD; |
905 } | 899 } |
906 | 900 |
907 CGRGBPixel* image = (CGRGBPixel*)fImageStorage.get(); | 901 CGRGBPixel* image = (CGRGBPixel*)fImageStorage.get(); |
908 // skip rows based on the glyph's height | 902 // skip rows based on the glyph's height |
909 image += (fSize.fHeight - glyph.fHeight) * fSize.fWidth; | 903 image += (fSize.fHeight - glyph.fHeight) * fSize.fWidth; |
910 | 904 |
911 #if SK_IGNORE_MAC_FONT_WEIGHT_FIX | |
912 // erase to black | |
913 sk_memset_rect32(image, 0, glyph.fWidth, glyph.fHeight, rowBytes); | |
914 #else | |
915 // Erase to white (or transparent black if it's a color glyph, to not compos
ite against white). | 905 // Erase to white (or transparent black if it's a color glyph, to not compos
ite against white). |
916 uint32_t bgColor = (SkMask::kARGB32_Format != glyph.fMaskFormat) ? 0xFFFFFFF
F : 0x00000000; | 906 uint32_t bgColor = (SkMask::kARGB32_Format != glyph.fMaskFormat) ? 0xFFFFFFF
F : 0x00000000; |
917 sk_memset_rect32(image, bgColor, glyph.fWidth, glyph.fHeight, rowBytes); | 907 sk_memset_rect32(image, bgColor, glyph.fWidth, glyph.fHeight, rowBytes); |
918 #endif | |
919 | 908 |
920 float subX = 0; | 909 float subX = 0; |
921 float subY = 0; | 910 float subY = 0; |
922 if (context.fDoSubPosition) { | 911 if (context.fDoSubPosition) { |
923 subX = SkFixedToFloat(glyph.getSubXFixed()); | 912 subX = SkFixedToFloat(glyph.getSubXFixed()); |
924 subY = SkFixedToFloat(glyph.getSubYFixed()); | 913 subY = SkFixedToFloat(glyph.getSubYFixed()); |
925 } | 914 } |
926 | 915 |
927 // CoreText and CoreGraphics always draw using the horizontal baseline origi
n. | 916 // CoreText and CoreGraphics always draw using the horizontal baseline origi
n. |
928 if (context.fVertical) { | 917 if (context.fVertical) { |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1182 build_power_table(gTableCoreGraphicsSmoothing); | 1171 build_power_table(gTableCoreGraphicsSmoothing); |
1183 gInited = true; | 1172 gInited = true; |
1184 } | 1173 } |
1185 return gTableCoreGraphicsSmoothing; | 1174 return gTableCoreGraphicsSmoothing; |
1186 } | 1175 } |
1187 | 1176 |
1188 static void cgpixels_to_bits(uint8_t dst[], const CGRGBPixel src[], int count) { | 1177 static void cgpixels_to_bits(uint8_t dst[], const CGRGBPixel src[], int count) { |
1189 while (count > 0) { | 1178 while (count > 0) { |
1190 uint8_t mask = 0; | 1179 uint8_t mask = 0; |
1191 for (int i = 7; i >= 0; --i) { | 1180 for (int i = 7; i >= 0; --i) { |
1192 #if SK_IGNORE_MAC_FONT_WEIGHT_FIX | |
1193 mask |= (CGRGBPixel_getAlpha(*src++) >> 7) << i; | |
1194 #else | |
1195 mask |= ((CGRGBPixel_getAlpha(*src++) >> 7) ^ 0x1) << i; | 1181 mask |= ((CGRGBPixel_getAlpha(*src++) >> 7) ^ 0x1) << i; |
1196 #endif | |
1197 if (0 == --count) { | 1182 if (0 == --count) { |
1198 break; | 1183 break; |
1199 } | 1184 } |
1200 } | 1185 } |
1201 *dst++ = mask; | 1186 *dst++ = mask; |
1202 } | 1187 } |
1203 } | 1188 } |
1204 | 1189 |
1205 template<bool APPLY_PREBLEND> | 1190 template<bool APPLY_PREBLEND> |
1206 static inline uint8_t rgb_to_a8(CGRGBPixel rgb, const uint8_t* table8) { | 1191 static inline uint8_t rgb_to_a8(CGRGBPixel rgb, const uint8_t* table8) { |
1207 #if SK_IGNORE_MAC_FONT_WEIGHT_FIX | |
1208 U8CPU r = (rgb >> 16) & 0xFF; | |
1209 U8CPU g = (rgb >> 8) & 0xFF; | |
1210 U8CPU b = (rgb >> 0) & 0xFF; | |
1211 #else | |
1212 U8CPU r = 0xFF - ((rgb >> 16) & 0xFF); | 1192 U8CPU r = 0xFF - ((rgb >> 16) & 0xFF); |
1213 U8CPU g = 0xFF - ((rgb >> 8) & 0xFF); | 1193 U8CPU g = 0xFF - ((rgb >> 8) & 0xFF); |
1214 U8CPU b = 0xFF - ((rgb >> 0) & 0xFF); | 1194 U8CPU b = 0xFF - ((rgb >> 0) & 0xFF); |
1215 #endif | |
1216 U8CPU lum = sk_apply_lut_if<APPLY_PREBLEND>(SkComputeLuminance(r, g, b), tab
le8); | 1195 U8CPU lum = sk_apply_lut_if<APPLY_PREBLEND>(SkComputeLuminance(r, g, b), tab
le8); |
1217 #if SK_SHOW_TEXT_BLIT_COVERAGE | 1196 #if SK_SHOW_TEXT_BLIT_COVERAGE |
1218 lum = SkTMax(lum, (U8CPU)0x30); | 1197 lum = SkTMax(lum, (U8CPU)0x30); |
1219 #endif | 1198 #endif |
1220 return lum; | 1199 return lum; |
1221 } | 1200 } |
1222 template<bool APPLY_PREBLEND> | 1201 template<bool APPLY_PREBLEND> |
1223 static void rgb_to_a8(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowBytes, | 1202 static void rgb_to_a8(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowBytes, |
1224 const SkGlyph& glyph, const uint8_t* table8) { | 1203 const SkGlyph& glyph, const uint8_t* table8) { |
1225 const int width = glyph.fWidth; | 1204 const int width = glyph.fWidth; |
1226 size_t dstRB = glyph.rowBytes(); | 1205 size_t dstRB = glyph.rowBytes(); |
1227 uint8_t* SK_RESTRICT dst = (uint8_t*)glyph.fImage; | 1206 uint8_t* SK_RESTRICT dst = (uint8_t*)glyph.fImage; |
1228 | 1207 |
1229 for (int y = 0; y < glyph.fHeight; y++) { | 1208 for (int y = 0; y < glyph.fHeight; y++) { |
1230 for (int i = 0; i < width; ++i) { | 1209 for (int i = 0; i < width; ++i) { |
1231 dst[i] = rgb_to_a8<APPLY_PREBLEND>(cgPixels[i], table8); | 1210 dst[i] = rgb_to_a8<APPLY_PREBLEND>(cgPixels[i], table8); |
1232 } | 1211 } |
1233 cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes); | 1212 cgPixels = (CGRGBPixel*)((char*)cgPixels + cgRowBytes); |
1234 dst += dstRB; | 1213 dst += dstRB; |
1235 } | 1214 } |
1236 } | 1215 } |
1237 | 1216 |
1238 template<bool APPLY_PREBLEND> | 1217 template<bool APPLY_PREBLEND> |
1239 static inline uint16_t rgb_to_lcd16(CGRGBPixel rgb, const uint8_t* tableR, | 1218 static inline uint16_t rgb_to_lcd16(CGRGBPixel rgb, const uint8_t* tableR, |
1240 const uint8_t* tableG, | 1219 const uint8_t* tableG, |
1241 const uint8_t* tableB) { | 1220 const uint8_t* tableB) { |
1242 #if SK_IGNORE_MAC_FONT_WEIGHT_FIX | |
1243 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 16) & 0xFF, tableR); | |
1244 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 8) & 0xFF, tableG); | |
1245 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>((rgb >> 0) & 0xFF, tableB); | |
1246 #else | |
1247 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 16) & 0xFF), table
R); | 1221 U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 16) & 0xFF), table
R); |
1248 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 8) & 0xFF), table
G); | 1222 U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 8) & 0xFF), table
G); |
1249 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 0) & 0xFF), table
B); | 1223 U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(0xFF - ((rgb >> 0) & 0xFF), table
B); |
1250 #endif | |
1251 #if SK_SHOW_TEXT_BLIT_COVERAGE | 1224 #if SK_SHOW_TEXT_BLIT_COVERAGE |
1252 r = SkTMax(r, (U8CPU)0x30); | 1225 r = SkTMax(r, (U8CPU)0x30); |
1253 g = SkTMax(g, (U8CPU)0x30); | 1226 g = SkTMax(g, (U8CPU)0x30); |
1254 b = SkTMax(b, (U8CPU)0x30); | 1227 b = SkTMax(b, (U8CPU)0x30); |
1255 #endif | 1228 #endif |
1256 return SkPack888ToRGB16(r, g, b); | 1229 return SkPack888ToRGB16(r, g, b); |
1257 } | 1230 } |
1258 template<bool APPLY_PREBLEND> | 1231 template<bool APPLY_PREBLEND> |
1259 static void rgb_to_lcd16(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowByt
es, const SkGlyph& glyph, | 1232 static void rgb_to_lcd16(const CGRGBPixel* SK_RESTRICT cgPixels, size_t cgRowByt
es, const SkGlyph& glyph, |
1260 const uint8_t* tableR, const uint8_t* tableG, const uin
t8_t* tableB) { | 1233 const uint8_t* tableR, const uint8_t* tableG, const uin
t8_t* tableB) { |
(...skipping 1391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2652 } | 2625 } |
2653 return face; | 2626 return face; |
2654 } | 2627 } |
2655 }; | 2628 }; |
2656 | 2629 |
2657 /////////////////////////////////////////////////////////////////////////////// | 2630 /////////////////////////////////////////////////////////////////////////////// |
2658 | 2631 |
2659 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } | 2632 SkFontMgr* SkFontMgr::Factory() { return new SkFontMgr_Mac; } |
2660 | 2633 |
2661 #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) | 2634 #endif//defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) |
OLD | NEW |