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 "SkBitmap.h" | 10 #include "SkBitmap.h" |
11 #include "SkCanvas.h" | 11 #include "SkCanvas.h" |
12 #include "SkColorPriv.h" | 12 #include "SkColorPriv.h" |
13 #include "SkDescriptor.h" | 13 #include "SkDescriptor.h" |
14 #include "SkFDot6.h" | 14 #include "SkFDot6.h" |
15 #include "SkFloatingPoint.h" | 15 #include "SkFloatingPoint.h" |
16 #include "SkFontHost.h" | 16 #include "SkFontHost.h" |
17 #include "SkFontHost_FreeType_common.h" | 17 #include "SkFontHost_FreeType_common.h" |
18 #include "SkGlyph.h" | 18 #include "SkGlyph.h" |
19 #include "SkMask.h" | 19 #include "SkMask.h" |
20 #include "SkMaskGamma.h" | 20 #include "SkMaskGamma.h" |
| 21 #include "SkMatrix22.h" |
21 #include "SkOTUtils.h" | 22 #include "SkOTUtils.h" |
22 #include "SkOnce.h" | 23 #include "SkOnce.h" |
23 #include "SkScalerContext.h" | 24 #include "SkScalerContext.h" |
24 #include "SkStream.h" | 25 #include "SkStream.h" |
25 #include "SkString.h" | 26 #include "SkString.h" |
26 #include "SkTemplates.h" | 27 #include "SkTemplates.h" |
27 #include "SkThread.h" | 28 #include "SkThread.h" |
28 | 29 |
29 #if defined(SK_CAN_USE_DLOPEN) | 30 #if defined(SK_CAN_USE_DLOPEN) |
30 #include <dlfcn.h> | 31 #include <dlfcn.h> |
31 #endif | 32 #endif |
32 #include <ft2build.h> | 33 #include <ft2build.h> |
33 #include FT_FREETYPE_H | 34 #include FT_FREETYPE_H |
34 #include FT_OUTLINE_H | 35 #include FT_OUTLINE_H |
35 #include FT_SIZES_H | 36 #include FT_SIZES_H |
36 #include FT_TRUETYPE_TABLES_H | 37 #include FT_TRUETYPE_TABLES_H |
37 #include FT_TYPE1_TABLES_H | 38 #include FT_TYPE1_TABLES_H |
38 #include FT_BITMAP_H | 39 #include FT_BITMAP_H |
39 // In the past, FT_GlyphSlot_Own_Bitmap was defined in this header file. | 40 // In the past, FT_GlyphSlot_Own_Bitmap was defined in this header file. |
40 #include FT_SYNTHESIS_H | 41 #include FT_SYNTHESIS_H |
41 #include FT_XFREE86_H | 42 #include FT_XFREE86_H |
42 #ifdef FT_LCD_FILTER_H | 43 #ifdef FT_LCD_FILTER_H |
43 #include FT_LCD_FILTER_H | 44 #include FT_LCD_FILTER_H |
44 #endif | 45 #endif |
45 | 46 |
| 47 // Defined in FreeType 2.3.8 and later. |
| 48 // This is a silly build time check, we would need a runtime check if we really
cared. |
46 #ifdef FT_ADVANCES_H | 49 #ifdef FT_ADVANCES_H |
47 #include FT_ADVANCES_H | 50 #include FT_ADVANCES_H |
48 #endif | 51 #endif |
49 | 52 |
50 #if 0 | 53 #if 0 |
51 // Also include the files by name for build tools which require this. | 54 // Also include the files by name for build tools which require this. |
52 #include <freetype/freetype.h> | 55 #include <freetype/freetype.h> |
53 #include <freetype/ftoutln.h> | 56 #include <freetype/ftoutln.h> |
54 #include <freetype/ftsizes.h> | 57 #include <freetype/ftsizes.h> |
55 #include <freetype/tttables.h> | 58 #include <freetype/tttables.h> |
(...skipping 630 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
686 | 689 |
687 if (!canEmbed(face)) | 690 if (!canEmbed(face)) |
688 info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; | 691 info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font; |
689 | 692 |
690 return info; | 693 return info; |
691 #endif | 694 #endif |
692 } | 695 } |
693 | 696 |
694 /////////////////////////////////////////////////////////////////////////// | 697 /////////////////////////////////////////////////////////////////////////// |
695 | 698 |
696 #define BLACK_LUMINANCE_LIMIT 0x40 | |
697 #define WHITE_LUMINANCE_LIMIT 0xA0 | |
698 | |
699 static bool bothZero(SkScalar a, SkScalar b) { | 699 static bool bothZero(SkScalar a, SkScalar b) { |
700 return 0 == a && 0 == b; | 700 return 0 == a && 0 == b; |
701 } | 701 } |
702 | 702 |
703 // returns false if there is any non-90-rotation or skew | 703 // returns false if there is any non-90-rotation or skew |
704 static bool isAxisAligned(const SkScalerContext::Rec& rec) { | 704 static bool isAxisAligned(const SkScalerContext::Rec& rec) { |
705 return 0 == rec.fPreSkewX && | 705 return 0 == rec.fPreSkewX && |
706 (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) || | 706 (bothZero(rec.fPost2x2[0][1], rec.fPost2x2[1][0]) || |
707 bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1])); | 707 bothZero(rec.fPost2x2[0][0], rec.fPost2x2[1][1])); |
708 } | 708 } |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
842 // load the font file | 842 // load the font file |
843 fStrikeIndex = -1; | 843 fStrikeIndex = -1; |
844 fFTSize = NULL; | 844 fFTSize = NULL; |
845 fFace = NULL; | 845 fFace = NULL; |
846 fFaceRec = ref_ft_face(typeface); | 846 fFaceRec = ref_ft_face(typeface); |
847 if (NULL == fFaceRec) { | 847 if (NULL == fFaceRec) { |
848 return; | 848 return; |
849 } | 849 } |
850 fFace = fFaceRec->fFace; | 850 fFace = fFaceRec->fFace; |
851 | 851 |
852 // compute our factors from the record | 852 // A is the total matrix. |
| 853 SkMatrix A; |
| 854 fRec.getSingleMatrix(&A); |
853 | 855 |
854 SkMatrix m; | 856 SkScalar sx = A.getScaleX(); |
855 | 857 SkScalar sy = A.getScaleY(); |
856 fRec.getSingleMatrix(&m); | |
857 | |
858 #ifdef DUMP_STRIKE_CREATION | |
859 SkString keyString; | |
860 SkFontHost::GetDescriptorKeyString(desc, &keyString); | |
861 printf("========== strike [%g %g %g] [%g %g %g %g] hints %d format %d %s\n",
SkScalarToFloat(fRec.fTextSize), | |
862 SkScalarToFloat(fRec.fPreScaleX), SkScalarToFloat(fRec.fPreSkewX), | |
863 SkScalarToFloat(fRec.fPost2x2[0][0]), SkScalarToFloat(fRec.fPost2x2[0
][1]), | |
864 SkScalarToFloat(fRec.fPost2x2[1][0]), SkScalarToFloat(fRec.fPost2x2[1
][1]), | |
865 fRec.getHinting(), fRec.fMaskFormat, keyString.c_str()); | |
866 #endif | |
867 | |
868 // now compute our scale factors | |
869 SkScalar sx = m.getScaleX(); | |
870 SkScalar sy = m.getScaleY(); | |
871 | |
872 fMatrix22Scalar.reset(); | 858 fMatrix22Scalar.reset(); |
873 | 859 |
874 if (m.getSkewX() || m.getSkewY() || sx < 0 || sy < 0) { | 860 //#define SK_IGNORE_FREETYPE_ROTATION_FIX |
| 861 #ifdef SK_IGNORE_FREETYPE_ROTATION_FIX |
| 862 if (A.getSkewX() || A.getSkewY() || sx < 0 || sy < 0) { |
875 // sort of give up on hinting | 863 // sort of give up on hinting |
876 sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(m.getSkewX())); | 864 sx = SkMaxScalar(SkScalarAbs(sx), SkScalarAbs(A.getSkewX())); |
877 sy = SkMaxScalar(SkScalarAbs(m.getSkewY()), SkScalarAbs(sy)); | 865 sy = SkMaxScalar(SkScalarAbs(A.getSkewY()), SkScalarAbs(sy)); |
878 sx = sy = SkScalarAve(sx, sy); | 866 sx = sy = SkScalarAve(sx, sy); |
879 | 867 |
880 SkScalar inv = SkScalarInvert(sx); | 868 SkScalar inv = SkScalarInvert(sx); |
881 | 869 |
882 // flip the skew elements to go from our Y-down system to FreeType's | 870 // flip the skew elements to go from our Y-down system to FreeType's |
883 fMatrix22.xx = SkScalarToFixed(SkScalarMul(m.getScaleX(), inv)); | 871 fMatrix22.xx = SkScalarToFixed(SkScalarMul(A.getScaleX(), inv)); |
884 fMatrix22.xy = -SkScalarToFixed(SkScalarMul(m.getSkewX(), inv)); | 872 fMatrix22.xy = -SkScalarToFixed(SkScalarMul(A.getSkewX(), inv)); |
885 fMatrix22.yx = -SkScalarToFixed(SkScalarMul(m.getSkewY(), inv)); | 873 fMatrix22.yx = -SkScalarToFixed(SkScalarMul(A.getSkewY(), inv)); |
886 fMatrix22.yy = SkScalarToFixed(SkScalarMul(m.getScaleY(), inv)); | 874 fMatrix22.yy = SkScalarToFixed(SkScalarMul(A.getScaleY(), inv)); |
887 | 875 |
888 fMatrix22Scalar.setScaleX(SkScalarMul(m.getScaleX(), inv)); | 876 fMatrix22Scalar.setScaleX(SkScalarMul(A.getScaleX(), inv)); |
889 fMatrix22Scalar.setSkewX(-SkScalarMul(m.getSkewX(), inv)); | 877 fMatrix22Scalar.setSkewX(-SkScalarMul(A.getSkewX(), inv)); |
890 fMatrix22Scalar.setSkewY(-SkScalarMul(m.getSkewY(), inv)); | 878 fMatrix22Scalar.setSkewY(-SkScalarMul(A.getSkewY(), inv)); |
891 fMatrix22Scalar.setScaleY(SkScalarMul(m.getScaleY(), inv)); | 879 fMatrix22Scalar.setScaleY(SkScalarMul(A.getScaleY(), inv)); |
892 } else { | 880 } else { |
893 fMatrix22.xx = fMatrix22.yy = SK_Fixed1; | 881 fMatrix22.xx = fMatrix22.yy = SK_Fixed1; |
894 fMatrix22.xy = fMatrix22.yx = 0; | 882 fMatrix22.xy = fMatrix22.yx = 0; |
895 } | 883 } |
896 fScale.set(sx, sy); | 884 fScale.set(sx, sy); |
897 fScaleX = SkScalarToFixed(sx); | 885 fScaleX = SkScalarToFixed(sx); |
898 fScaleY = SkScalarToFixed(sy); | 886 fScaleY = SkScalarToFixed(sy); |
| 887 #else |
| 888 // In GDI, the hinter is aware of the current transformation |
| 889 // (the transform is in some sense applied before/with the hinting). |
| 890 // The bytecode can then test if it is rotated or stretched and decide |
| 891 // to apply instructions or not. |
| 892 // |
| 893 // FreeType, however, always does the transformation strictly after hinting. |
| 894 // It just sets 'rotated' and 'stretched' to false and only applies the |
| 895 // size before hinting. |
| 896 // |
| 897 // Also, FreeType respects the head::flags::IntegerScaling flag, |
| 898 // (although this is patched out on most major distros) |
| 899 // so it is critical to get the size correct on the request. |
| 900 // |
| 901 // This also gets us the actual closest size on bitmap fonts as well. |
| 902 if (A.getSkewX() || A.getSkewY() || sx < 0 || sy < 0) { |
| 903 // h is where A maps the horizontal baseline. |
| 904 SkPoint h = SkPoint::Make(SK_Scalar1, 0); |
| 905 A.mapPoints(&h, 1); |
| 906 |
| 907 // G is the Givens Matrix for A (rotational matrix where GA[0][1] == 0). |
| 908 SkMatrix G; |
| 909 SkComputeGivensRotation(h, &G); |
| 910 |
| 911 // GA is the matrix A with rotation removed. |
| 912 SkMatrix GA(G); |
| 913 GA.preConcat(A); |
| 914 |
| 915 sx = SkScalarAbs(GA.get(SkMatrix::kMScaleX)); |
| 916 sy = SkScalarAbs(GA.get(SkMatrix::kMScaleY)); |
| 917 |
| 918 // sA is the total matrix A without the text scale. |
| 919 SkMatrix sA(A); |
| 920 sA.preScale(SkScalarInvert(sx), SkScalarInvert(sy)); //remove text size |
| 921 |
| 922 fMatrix22Scalar.setScaleX(sA.getScaleX()); |
| 923 fMatrix22Scalar.setSkewX(-sA.getSkewX()); |
| 924 fMatrix22Scalar.setSkewY(-sA.getSkewY()); |
| 925 fMatrix22Scalar.setScaleY(sA.getScaleY()); |
| 926 } |
| 927 fScale.set(sx, sy); |
| 928 fScaleX = SkScalarToFixed(sx); |
| 929 fScaleY = SkScalarToFixed(sy); |
| 930 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX()); |
| 931 fMatrix22.xy = SkScalarToFixed(fMatrix22Scalar.getSkewX()); |
| 932 fMatrix22.yx = SkScalarToFixed(fMatrix22Scalar.getSkewY()); |
| 933 fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY()); |
| 934 #endif |
899 | 935 |
900 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag); | 936 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag); |
901 | 937 |
902 // compute the flags we send to Load_Glyph | 938 // compute the flags we send to Load_Glyph |
903 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPositi
oning_Flag); | 939 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPositi
oning_Flag); |
904 { | 940 { |
905 FT_Int32 loadFlags = FT_LOAD_DEFAULT; | 941 FT_Int32 loadFlags = FT_LOAD_DEFAULT; |
906 | 942 |
907 if (SkMask::kBW_Format == fRec.fMaskFormat) { | 943 if (SkMask::kBW_Format == fRec.fMaskFormat) { |
908 // See http://code.google.com/p/chromium/issues/detail?id=43252#c24 | 944 // See http://code.google.com/p/chromium/issues/detail?id=43252#c24 |
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1720 *style = (SkTypeface::Style) tempStyle; | 1756 *style = (SkTypeface::Style) tempStyle; |
1721 } | 1757 } |
1722 if (isFixedPitch) { | 1758 if (isFixedPitch) { |
1723 *isFixedPitch = FT_IS_FIXED_WIDTH(face); | 1759 *isFixedPitch = FT_IS_FIXED_WIDTH(face); |
1724 } | 1760 } |
1725 | 1761 |
1726 FT_Done_Face(face); | 1762 FT_Done_Face(face); |
1727 FT_Done_FreeType(library); | 1763 FT_Done_FreeType(library); |
1728 return true; | 1764 return true; |
1729 } | 1765 } |
OLD | NEW |