Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(150)

Side by Side Diff: src/ports/SkFontHost_FreeType.cpp

Issue 23684041: improve bitmap font support (FreeType only) (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Rebase against current; build with older FreeTypes. Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkCanvas.h" 10 #include "SkCanvas.h"
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
51 #include <freetype/freetype.h> 51 #include <freetype/freetype.h>
52 #include <freetype/ftoutln.h> 52 #include <freetype/ftoutln.h>
53 #include <freetype/ftsizes.h> 53 #include <freetype/ftsizes.h>
54 #include <freetype/tttables.h> 54 #include <freetype/tttables.h>
55 #include <freetype/ftadvanc.h> 55 #include <freetype/ftadvanc.h>
56 #include <freetype/ftlcdfil.h> 56 #include <freetype/ftlcdfil.h>
57 #include <freetype/ftbitmap.h> 57 #include <freetype/ftbitmap.h>
58 #include <freetype/ftsynth.h> 58 #include <freetype/ftsynth.h>
59 #endif 59 #endif
60 60
61 // FT_LOAD_COLOR and the corresponding FT_Pixel_Mode::FT_PIXEL_MODE_BGRA
62 // were introduced in FreeType 2.5.0.
63 // The following may be removed once FreeType 2.5.0 is required to build.
64 #ifndef FT_LOAD_COLOR
65 # define FT_LOAD_COLOR ( 1L << 20 )
66 # define FT_PIXEL_MODE_BGRA 7
67 #endif
68
61 //#define ENABLE_GLYPH_SPEW // for tracing calls 69 //#define ENABLE_GLYPH_SPEW // for tracing calls
62 //#define DUMP_STRIKE_CREATION 70 //#define DUMP_STRIKE_CREATION
63 71
64 //#define SK_GAMMA_APPLY_TO_A8 72 //#define SK_GAMMA_APPLY_TO_A8
65 73
74 //#define DEBUG_METRICS
75
66 using namespace skia_advanced_typeface_metrics_utils; 76 using namespace skia_advanced_typeface_metrics_utils;
67 77
68 static bool isLCD(const SkScalerContext::Rec& rec) { 78 static bool isLCD(const SkScalerContext::Rec& rec) {
69 switch (rec.fMaskFormat) { 79 switch (rec.fMaskFormat) {
70 case SkMask::kLCD16_Format: 80 case SkMask::kLCD16_Format:
71 case SkMask::kLCD32_Format: 81 case SkMask::kLCD32_Format:
72 return true; 82 return true;
73 default: 83 default:
74 return false; 84 return false;
75 } 85 }
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
177 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE; 187 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
178 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE; 188 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
179 virtual void generateFontMetrics(SkPaint::FontMetrics* mx, 189 virtual void generateFontMetrics(SkPaint::FontMetrics* mx,
180 SkPaint::FontMetrics* my) SK_OVERRIDE; 190 SkPaint::FontMetrics* my) SK_OVERRIDE;
181 virtual SkUnichar generateGlyphToChar(uint16_t glyph) SK_OVERRIDE; 191 virtual SkUnichar generateGlyphToChar(uint16_t glyph) SK_OVERRIDE;
182 192
183 private: 193 private:
184 SkFaceRec* fFaceRec; 194 SkFaceRec* fFaceRec;
185 FT_Face fFace; // reference to shared face in gFaceRecHead 195 FT_Face fFace; // reference to shared face in gFaceRecHead
186 FT_Size fFTSize; // our own copy 196 FT_Size fFTSize; // our own copy
197 FT_Int fStrikeIndex;
187 SkFixed fScaleX, fScaleY; 198 SkFixed fScaleX, fScaleY;
188 FT_Matrix fMatrix22; 199 FT_Matrix fMatrix22;
189 uint32_t fLoadGlyphFlags; 200 uint32_t fLoadGlyphFlags;
190 bool fDoLinearMetrics; 201 bool fDoLinearMetrics;
191 bool fLCDIsVert; 202 bool fLCDIsVert;
192 203
193 // Need scalar versions for generateFontMetrics 204 // Need scalar versions for generateFontMetrics
194 SkVector fScale; 205 SkVector fScale;
195 SkMatrix fMatrix22Scalar; 206 SkMatrix fMatrix22Scalar;
196 207
(...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 FT_Error err = FT_Get_Kerning(face, glyphs[i], glyphs[i+1], 753 FT_Error err = FT_Get_Kerning(face, glyphs[i], glyphs[i+1],
743 FT_KERNING_UNSCALED, &delta); 754 FT_KERNING_UNSCALED, &delta);
744 if (err) { 755 if (err) {
745 return false; 756 return false;
746 } 757 }
747 adjustments[i] = delta.x; 758 adjustments[i] = delta.x;
748 } 759 }
749 return true; 760 return true;
750 } 761 }
751 762
763 #ifdef DEBUG_METRICS
764 static void dumpFTFaceMetrics(const FT_Face face) {
765 SkASSERT(face);
766 SkDebugf(" units_per_EM: %hu\n", face->units_per_EM);
767 SkDebugf(" ascender: %hd\n", face->ascender);
768 SkDebugf(" descender: %hd\n", face->descender);
769 SkDebugf(" height: %hd\n", face->height);
770 SkDebugf(" max_advance_width: %hd\n", face->max_advance_width);
771 SkDebugf(" max_advance_height: %hd\n", face->max_advance_height);
772 }
773
774 static void dumpFTSize(const FT_Size size) {
775 SkASSERT(size);
776 SkDebugf(" x_ppem: %hu\n", size->metrics.x_ppem);
777 SkDebugf(" y_ppem: %hu\n", size->metrics.y_ppem);
778 SkDebugf(" x_scale: %f\n", size->metrics.x_scale / 65536.0f);
779 SkDebugf(" y_scale: %f\n", size->metrics.y_scale / 65536.0f);
780 SkDebugf(" ascender: %f\n", size->metrics.ascender / 64.0f);
781 SkDebugf(" descender: %f\n", size->metrics.descender / 64.0f);
782 SkDebugf(" height: %f\n", size->metrics.height / 64.0f);
783 SkDebugf(" max_advance: %f\n", size->metrics.max_advance / 64.0f);
784 }
785
786 static void dumpBitmapStrikeMetrics(const FT_Face face, int strikeIndex) {
787 SkASSERT(face);
788 SkASSERT(strikeIndex >= 0 && strikeIndex < face->num_fixed_sizes);
789 SkDebugf(" height: %hd\n", face->available_sizes[strikeIndex].height);
790 SkDebugf(" width: %hd\n", face->available_sizes[strikeIndex].width);
791 SkDebugf(" size: %f\n", face->available_sizes[strikeIndex].size / 64.0f);
792 SkDebugf(" x_ppem: %f\n", face->available_sizes[strikeIndex].x_ppem / 64.0f );
793 SkDebugf(" y_ppem: %f\n", face->available_sizes[strikeIndex].y_ppem / 64.0f );
794 }
795
796 static void dumpSkFontMetrics(const SkPaint::FontMetrics& metrics) {
797 SkDebugf(" fTop: %f\n", metrics.fTop);
798 SkDebugf(" fAscent: %f\n", metrics.fAscent);
799 SkDebugf(" fDescent: %f\n", metrics.fDescent);
800 SkDebugf(" fBottom: %f\n", metrics.fBottom);
801 SkDebugf(" fLeading: %f\n", metrics.fLeading);
802 SkDebugf(" fAvgCharWidth: %f\n", metrics.fAvgCharWidth);
803 SkDebugf(" fXMin: %f\n", metrics.fXMin);
804 SkDebugf(" fXMax: %f\n", metrics.fXMax);
805 SkDebugf(" fXHeight: %f\n", metrics.fXHeight);
806 }
807
808 static void dumpSkGlyphMetrics(const SkGlyph& glyph) {
809 SkDebugf(" fAdvanceX: %f\n", SkFixedToScalar(glyph.fAdvanceX));
810 SkDebugf(" fAdvanceY: %f\n", SkFixedToScalar(glyph.fAdvanceY));
811 SkDebugf(" fWidth: %hu\n", glyph.fWidth);
812 SkDebugf(" fHeight: %hu\n", glyph.fHeight);
813 SkDebugf(" fTop: %hd\n", glyph.fTop);
814 SkDebugf(" fLeft: %hd\n", glyph.fLeft);
815 }
816 #endif
817
818 static FT_Int chooseBitmapStrike(FT_Face face, SkFixed scaleY) {
819 // early out if face is bad
820 if (face == NULL) {
821 SkDEBUGF(("chooseBitmapStrike aborted due to NULL face\n"));
822 return -1;
823 }
824 // determine target ppem
825 FT_Pos targetPPEM = SkFixedToFDot6(scaleY);
826 // find a bitmap strike equal to or just larger than the requested size
827 FT_Int chosenStrikeIndex = -1;
828 FT_Pos chosenPPEM = 0;
829 for (FT_Int strikeIndex = 0; strikeIndex < face->num_fixed_sizes; ++strikeIn dex) {
830 FT_Pos thisPPEM = face->available_sizes[strikeIndex].y_ppem;
831 if (thisPPEM == targetPPEM) {
832 // exact match - our search stops here
833 chosenPPEM = thisPPEM;
834 chosenStrikeIndex = strikeIndex;
835 break;
836 } else if (chosenPPEM < targetPPEM) {
837 // attempt to increase chosenPPEM
838 if (thisPPEM > chosenPPEM) {
839 chosenPPEM = thisPPEM;
840 chosenStrikeIndex = strikeIndex;
841 }
842 } else {
843 // attempt to decrease chosenPPEM, but not below targetPPEM
844 if (thisPPEM < chosenPPEM && thisPPEM > targetPPEM) {
845 chosenPPEM = thisPPEM;
846 chosenStrikeIndex = strikeIndex;
847 }
848 }
849 }
850 if (chosenStrikeIndex != -1) {
851 // use the chosen strike
852 #ifdef DEBUG_METRICS
853 SkDebugf("chooseBitmapStrike: chose strike %d for face \"%s\" at size %f \n",
854 chosenStrikeIndex, face->family_name, SkFixedToScalar(scaleY));
855 dumpBitmapStrikeMetrics(face, chosenStrikeIndex);
856 #endif
857 FT_Error err = FT_Select_Size(face, chosenStrikeIndex);
858 if (err != 0) {
859 SkDEBUGF(("FT_Select_Size(%s, %d) returned 0x%x\n", face->family_nam e,
860 chosenStrikeIndex, err));
861 chosenStrikeIndex = -1;
862 }
863 }
864 return chosenStrikeIndex;
865 }
866
752 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, 867 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface,
753 const SkDescriptor* desc) 868 const SkDescriptor* desc)
754 : SkScalerContext_FreeType_Base(typeface, desc) { 869 : SkScalerContext_FreeType_Base(typeface, desc) {
755 SkAutoMutexAcquire ac(gFTMutex); 870 SkAutoMutexAcquire ac(gFTMutex);
756 871
757 if (gFTCount == 0) { 872 if (gFTCount == 0) {
758 if (!InitFreetype()) { 873 if (!InitFreetype()) {
759 sk_throw(); 874 sk_throw();
760 } 875 }
761 } 876 }
762 ++gFTCount; 877 ++gFTCount;
763 878
764 // load the font file 879 // load the font file
880 fStrikeIndex = -1;
765 fFTSize = NULL; 881 fFTSize = NULL;
766 fFace = NULL; 882 fFace = NULL;
767 fFaceRec = ref_ft_face(typeface); 883 fFaceRec = ref_ft_face(typeface);
768 if (NULL == fFaceRec) { 884 if (NULL == fFaceRec) {
769 return; 885 return;
770 } 886 }
771 fFace = fFaceRec->fFace; 887 fFace = fFaceRec->fFace;
772 888
773 // compute our factors from the record 889 // compute our factors from the record
774 890
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
814 fMatrix22.xx = fMatrix22.yy = SK_Fixed1; 930 fMatrix22.xx = fMatrix22.yy = SK_Fixed1;
815 fMatrix22.xy = fMatrix22.yx = 0; 931 fMatrix22.xy = fMatrix22.yx = 0;
816 } 932 }
817 fScale.set(sx, sy); 933 fScale.set(sx, sy);
818 fScaleX = SkScalarToFixed(sx); 934 fScaleX = SkScalarToFixed(sx);
819 fScaleY = SkScalarToFixed(sy); 935 fScaleY = SkScalarToFixed(sy);
820 936
821 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag); 937 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
822 938
823 // compute the flags we send to Load_Glyph 939 // compute the flags we send to Load_Glyph
940 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPositi oning_Flag);
824 { 941 {
825 FT_Int32 loadFlags = FT_LOAD_DEFAULT; 942 FT_Int32 loadFlags = FT_LOAD_DEFAULT;
826 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPo sitioning_Flag);
827 943
828 if (SkMask::kBW_Format == fRec.fMaskFormat) { 944 if (SkMask::kBW_Format == fRec.fMaskFormat) {
829 // See http://code.google.com/p/chromium/issues/detail?id=43252#c24 945 // See http://code.google.com/p/chromium/issues/detail?id=43252#c24
830 loadFlags = FT_LOAD_TARGET_MONO; 946 loadFlags = FT_LOAD_TARGET_MONO;
831 if (fRec.getHinting() == SkPaint::kNo_Hinting) { 947 if (fRec.getHinting() == SkPaint::kNo_Hinting) {
832 loadFlags = FT_LOAD_NO_HINTING; 948 loadFlags = FT_LOAD_NO_HINTING;
833 linearMetrics = true; 949 linearMetrics = true;
834 } 950 }
835 } else { 951 } else {
836 switch (fRec.getHinting()) { 952 switch (fRec.getHinting()) {
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
874 // Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct 990 // Always using FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH to get correct
875 // advances, as fontconfig and cairo do. 991 // advances, as fontconfig and cairo do.
876 // See http://code.google.com/p/skia/issues/detail?id=222. 992 // See http://code.google.com/p/skia/issues/detail?id=222.
877 loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH; 993 loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
878 994
879 // Use vertical layout if requested. 995 // Use vertical layout if requested.
880 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 996 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
881 loadFlags |= FT_LOAD_VERTICAL_LAYOUT; 997 loadFlags |= FT_LOAD_VERTICAL_LAYOUT;
882 } 998 }
883 999
1000 loadFlags |= FT_LOAD_COLOR;
bungeman-skia 2013/11/27 00:04:49 We should actually check FT_HAS_COLOR(face) and se
1001
884 fLoadGlyphFlags = loadFlags; 1002 fLoadGlyphFlags = loadFlags;
885 fDoLinearMetrics = linearMetrics;
886 } 1003 }
887 1004
888 // now create the FT_Size 1005 FT_Error err = FT_New_Size(fFace, &fFTSize);
1006 if (err != 0) {
1007 SkDEBUGF(("FT_New_Size returned %x for face %s\n", err, fFace->family_na me));
1008 fFace = NULL;
1009 return;
1010 }
1011 err = FT_Activate_Size(fFTSize);
1012 if (err != 0) {
1013 SkDEBUGF(("FT_Activate_Size(%08x, 0x%x, 0x%x) returned 0x%x\n", fFace, f ScaleX, fScaleY,
1014 err));
1015 fFTSize = NULL;
1016 return;
1017 }
889 1018
890 { 1019 if (fRec.fFlags & SkScalerContext::kEmbeddedBitmapText_Flag) {
891 FT_Error err; 1020 fStrikeIndex = chooseBitmapStrike(fFace, fScaleY);
1021 }
892 1022
893 err = FT_New_Size(fFace, &fFTSize); 1023 if (fStrikeIndex == -1) {
894 if (err != 0) { 1024 if (fFace->face_flags & FT_FACE_FLAG_SCALABLE) {
895 SkDEBUGF(("SkScalerContext_FreeType::FT_New_Size(%x): FT_Set_Char_Si ze(0x%x, 0x%x) returned 0x%x\n", 1025 err = FT_Set_Char_Size(fFace,
896 fFaceRec->fFontID, fScaleX, fScaleY, err)); 1026 SkFixedToFDot6(fScaleX), SkFixedToFDot6(fScal eY),
897 fFace = NULL; 1027 72, 72);
898 return; 1028 if (err != 0) {
1029 SkDEBUGF(("FT_Set_CharSize(%08x, 0x%x, 0x%x) returned 0x%x\n", f Face, fScaleX,
1030 fScaleY, err));
1031 fFace = NULL;
1032 return;
1033 }
1034 FT_Set_Transform(fFace, &fMatrix22, NULL);
1035 } else {
1036 SkDEBUGF(("no glyphs for font \"%s\" size %f?\n", fFace->family_name ,
1037 SkFixedToScalar(fScaleY)));
899 } 1038 }
900 1039 } else {
901 err = FT_Activate_Size(fFTSize); 1040 linearMetrics = false; // no linear metrics for bitmap fonts
902 if (err != 0) {
903 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x ) returned 0x%x\n",
904 fFaceRec->fFontID, fScaleX, fScaleY, err));
905 fFTSize = NULL;
906 }
907
908 err = FT_Set_Char_Size( fFace,
909 SkFixedToFDot6(fScaleX), SkFixedToFDot6(fScaleY) ,
910 72, 72);
911 if (err != 0) {
912 SkDEBUGF(("SkScalerContext_FreeType::FT_Set_Char_Size(%x, 0x%x, 0x%x ) returned 0x%x\n",
913 fFaceRec->fFontID, fScaleX, fScaleY, err));
914 fFace = NULL;
915 return;
916 }
917
918 FT_Set_Transform( fFace, &fMatrix22, NULL);
919 } 1041 }
1042 fDoLinearMetrics = linearMetrics;
920 } 1043 }
921 1044
922 SkScalerContext_FreeType::~SkScalerContext_FreeType() { 1045 SkScalerContext_FreeType::~SkScalerContext_FreeType() {
923 SkAutoMutexAcquire ac(gFTMutex); 1046 SkAutoMutexAcquire ac(gFTMutex);
924 1047
925 if (fFTSize != NULL) { 1048 if (fFTSize != NULL) {
926 FT_Done_Size(fFTSize); 1049 FT_Done_Size(fFTSize);
927 } 1050 }
928 1051
929 if (fFace != NULL) { 1052 if (fFace != NULL) {
930 unref_ft_face(fFace); 1053 unref_ft_face(fFace);
931 } 1054 }
932 if (--gFTCount == 0) { 1055 if (--gFTCount == 0) {
933 // SkDEBUGF(("FT_Done_FreeType\n")); 1056 // SkDEBUGF(("FT_Done_FreeType\n"));
934 FT_Done_FreeType(gFTLibrary); 1057 FT_Done_FreeType(gFTLibrary);
935 SkDEBUGCODE(gFTLibrary = NULL;) 1058 SkDEBUGCODE(gFTLibrary = NULL;)
936 } 1059 }
937 } 1060 }
938 1061
939 /* We call this before each use of the fFace, since we may be sharing 1062 /* We call this before each use of the fFace, since we may be sharing
940 this face with other context (at different sizes). 1063 this face with other context (at different sizes).
941 */ 1064 */
942 FT_Error SkScalerContext_FreeType::setupSize() { 1065 FT_Error SkScalerContext_FreeType::setupSize() {
943 FT_Error err = FT_Activate_Size(fFTSize); 1066 FT_Error err = FT_Activate_Size(fFTSize);
944
945 if (err != 0) { 1067 if (err != 0) {
946 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x) re turned 0x%x\n", 1068 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%x, 0x%x, 0x%x) re turned 0x%x\n",
947 fFaceRec->fFontID, fScaleX, fScaleY, err)); 1069 fFaceRec->fFontID, fScaleX, fScaleY, err));
948 fFTSize = NULL; 1070 fFTSize = NULL;
949 } else { 1071 return err;
950 // seems we need to reset this every time (not sure why, but without it
951 // I get random italics from some other fFTSize)
952 FT_Set_Transform( fFace, &fMatrix22, NULL);
953 } 1072 }
954 return err; 1073
1074 // seems we need to reset this every time (not sure why, but without it
1075 // I get random italics from some other fFTSize)
1076 FT_Set_Transform(fFace, &fMatrix22, NULL);
1077 return 0;
955 } 1078 }
956 1079
957 unsigned SkScalerContext_FreeType::generateGlyphCount() { 1080 unsigned SkScalerContext_FreeType::generateGlyphCount() {
958 return fFace->num_glyphs; 1081 return fFace->num_glyphs;
959 } 1082 }
960 1083
961 uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) { 1084 uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) {
962 return SkToU16(FT_Get_Char_Index( fFace, uni )); 1085 return SkToU16(FT_Get_Char_Index( fFace, uni ));
963 } 1086 }
964 1087
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
1054 if (fLCDIsVert) { 1177 if (fLCDIsVert) {
1055 glyph->fHeight += gLCDExtra; 1178 glyph->fHeight += gLCDExtra;
1056 glyph->fTop -= gLCDExtra >> 1; 1179 glyph->fTop -= gLCDExtra >> 1;
1057 } else { 1180 } else {
1058 glyph->fWidth += gLCDExtra; 1181 glyph->fWidth += gLCDExtra;
1059 glyph->fLeft -= gLCDExtra >> 1; 1182 glyph->fLeft -= gLCDExtra >> 1;
1060 } 1183 }
1061 } 1184 }
1062 } 1185 }
1063 1186
1187 inline void scaleGlyphMetrics(SkGlyph& glyph, SkScalar scale) {
1188 glyph.fWidth *= scale;
1189 glyph.fHeight *= scale;
1190 glyph.fTop *= scale;
1191 glyph.fLeft *= scale;
1192
1193 SkFixed fixedScale = SkScalarToFixed(scale);
1194 glyph.fAdvanceX = SkFixedMul(glyph.fAdvanceX, fixedScale);
1195 glyph.fAdvanceY = SkFixedMul(glyph.fAdvanceY, fixedScale);
1196 }
1197
1064 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { 1198 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
1065 SkAutoMutexAcquire ac(gFTMutex); 1199 SkAutoMutexAcquire ac(gFTMutex);
1066 1200
1067 glyph->fRsbDelta = 0; 1201 glyph->fRsbDelta = 0;
1068 glyph->fLsbDelta = 0; 1202 glyph->fLsbDelta = 0;
1069 1203
1070 FT_Error err; 1204 FT_Error err;
1071 1205
1072 if (this->setupSize()) { 1206 if (this->setupSize()) {
1073 goto ERROR; 1207 goto ERROR;
1074 } 1208 }
1075 1209
1076 err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFl ags ); 1210 err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFl ags );
1077 if (err != 0) { 1211 if (err != 0) {
1078 #if 0 1212 #if 0
1079 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph( glyph:%d flags:%x) returned 0x%x\n", 1213 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph( glyph:%d flags:%x) returned 0x%x\n",
1080 fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoad GlyphFlags, err)); 1214 fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoad GlyphFlags, err));
1081 #endif 1215 #endif
1082 ERROR: 1216 ERROR:
1083 glyph->zeroMetrics(); 1217 glyph->zeroMetrics();
1084 return; 1218 return;
1085 } 1219 }
1086 1220
1087 switch ( fFace->glyph->format ) { 1221 switch ( fFace->glyph->format ) {
1088 case FT_GLYPH_FORMAT_OUTLINE: { 1222 case FT_GLYPH_FORMAT_OUTLINE:
1089 FT_BBox bbox;
1090
1091 if (0 == fFace->glyph->outline.n_contours) { 1223 if (0 == fFace->glyph->outline.n_contours) {
1092 glyph->fWidth = 0; 1224 glyph->fWidth = 0;
1093 glyph->fHeight = 0; 1225 glyph->fHeight = 0;
1094 glyph->fTop = 0; 1226 glyph->fTop = 0;
1095 glyph->fLeft = 0; 1227 glyph->fLeft = 0;
1096 break; 1228 } else {
1229 if (fRec.fFlags & kEmbolden_Flag && !(fFace->style_flags & FT_STYLE_ FLAG_BOLD)) {
1230 emboldenOutline(fFace, &fFace->glyph->outline);
1231 }
1232
1233 FT_BBox bbox;
1234 getBBoxForCurrentGlyph(glyph, &bbox, true);
1235
1236 glyph->fWidth = SkToU16(SkFDot6Floor(bbox.xMax - bbox.xMin));
1237 glyph->fHeight = SkToU16(SkFDot6Floor(bbox.yMax - bbox.yMin));
1238 glyph->fTop = -SkToS16(SkFDot6Floor(bbox.yMax));
1239 glyph->fLeft = SkToS16(SkFDot6Floor(bbox.xMin));
1240
1241 updateGlyphIfLCD(glyph);
1097 } 1242 }
1098
1099 if (fRec.fFlags & kEmbolden_Flag) {
1100 emboldenOutline(fFace, &fFace->glyph->outline);
1101 }
1102
1103 getBBoxForCurrentGlyph(glyph, &bbox, true);
1104
1105 glyph->fWidth = SkToU16(SkFDot6Floor(bbox.xMax - bbox.xMin));
1106 glyph->fHeight = SkToU16(SkFDot6Floor(bbox.yMax - bbox.yMin));
1107 glyph->fTop = -SkToS16(SkFDot6Floor(bbox.yMax));
1108 glyph->fLeft = SkToS16(SkFDot6Floor(bbox.xMin));
1109
1110 updateGlyphIfLCD(glyph);
1111
1112 break; 1243 break;
1113 }
1114 1244
1115 case FT_GLYPH_FORMAT_BITMAP: 1245 case FT_GLYPH_FORMAT_BITMAP:
1116 if (fRec.fFlags & kEmbolden_Flag) { 1246 if (fRec.fFlags & kEmbolden_Flag) {
1117 FT_GlyphSlot_Own_Bitmap(fFace->glyph); 1247 FT_GlyphSlot_Own_Bitmap(fFace->glyph);
1118 FT_Bitmap_Embolden(gFTLibrary, &fFace->glyph->bitmap, kBitmapEmbolde nStrength, 0); 1248 FT_Bitmap_Embolden(gFTLibrary, &fFace->glyph->bitmap, kBitmapEmbolde nStrength, 0);
1119 } 1249 }
1120 1250
1121 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 1251 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
1122 FT_Vector vector; 1252 FT_Vector vector;
1123 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metric s.horiBearingX; 1253 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metric s.horiBearingX;
1124 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY; 1254 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY;
1125 FT_Vector_Transform(&vector, &fMatrix22); 1255 FT_Vector_Transform(&vector, &fMatrix22);
1126 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x); 1256 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x);
1127 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y); 1257 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y);
1128 } 1258 }
1129 1259
1260 if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) {
1261 glyph->fMaskFormat = SkMask::kARGB32_Format;
1262 }
1263
1130 glyph->fWidth = SkToU16(fFace->glyph->bitmap.width); 1264 glyph->fWidth = SkToU16(fFace->glyph->bitmap.width);
1131 glyph->fHeight = SkToU16(fFace->glyph->bitmap.rows); 1265 glyph->fHeight = SkToU16(fFace->glyph->bitmap.rows);
1132 glyph->fTop = -SkToS16(fFace->glyph->bitmap_top); 1266 glyph->fTop = -SkToS16(fFace->glyph->bitmap_top);
1133 glyph->fLeft = SkToS16(fFace->glyph->bitmap_left); 1267 glyph->fLeft = SkToS16(fFace->glyph->bitmap_left);
1134 break; 1268 break;
1135 1269
1136 default: 1270 default:
1137 SkDEBUGFAIL("unknown glyph format"); 1271 SkDEBUGFAIL("unknown glyph format");
1138 goto ERROR; 1272 goto ERROR;
1139 } 1273 }
(...skipping 14 matching lines...) Expand all
1154 glyph->fAdvanceX = SkFDot6ToFixed(fFace->glyph->advance.x); 1288 glyph->fAdvanceX = SkFDot6ToFixed(fFace->glyph->advance.x);
1155 glyph->fAdvanceY = -SkFDot6ToFixed(fFace->glyph->advance.y); 1289 glyph->fAdvanceY = -SkFDot6ToFixed(fFace->glyph->advance.y);
1156 1290
1157 if (fRec.fFlags & kDevKernText_Flag) { 1291 if (fRec.fFlags & kDevKernText_Flag) {
1158 glyph->fRsbDelta = SkToS8(fFace->glyph->rsb_delta); 1292 glyph->fRsbDelta = SkToS8(fFace->glyph->rsb_delta);
1159 glyph->fLsbDelta = SkToS8(fFace->glyph->lsb_delta); 1293 glyph->fLsbDelta = SkToS8(fFace->glyph->lsb_delta);
1160 } 1294 }
1161 } 1295 }
1162 } 1296 }
1163 1297
1298 if (fFace->glyph->format == FT_GLYPH_FORMAT_BITMAP && fScaleY && fFace->size ->metrics.y_ppem) {
1299 #ifdef DEBUG_METRICS
1300 SkDebugf("pre-scale glyph metrics:\n");
1301 dumpSkGlyphMetrics(*glyph);
1302 #endif
1303 // NOTE: both dimensions are scaled by y_ppem. this is WAI.
1304 scaleGlyphMetrics(*glyph, SkScalarDiv(SkFixedToScalar(fScaleY),
1305 SkIntToScalar(fFace->size->metrics .y_ppem)));
1306 }
1307 #ifdef DEBUG_METRICS
1308 SkDebugf("post-scale glyph metrics:\n");
1309 dumpSkGlyphMetrics(*glyph);
1310 #endif
1311
1164 1312
1165 #ifdef ENABLE_GLYPH_SPEW 1313 #ifdef ENABLE_GLYPH_SPEW
1166 SkDEBUGF(("FT_Set_Char_Size(this:%p sx:%x sy:%x ", this, fScaleX, fScaleY)); 1314 SkDEBUGF(("FT_Set_Char_Size(this:%p sx:%x sy:%x ", this, fScaleX, fScaleY));
1167 SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(fBaseGlyp hCount), fLoadGlyphFlags, glyph->fWidth)); 1315 SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(fBaseGlyp hCount), fLoadGlyphFlags, glyph->fWidth));
1168 #endif 1316 #endif
1169 } 1317 }
1170 1318
1171 1319
1172 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { 1320 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
1173 SkAutoMutexAcquire ac(gFTMutex); 1321 SkAutoMutexAcquire ac(gFTMutex);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1221 // Offset the path so that it is relative to the vertical origin if needed. 1369 // Offset the path so that it is relative to the vertical origin if needed.
1222 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 1370 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
1223 FT_Vector vector; 1371 FT_Vector vector;
1224 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho riBearingX; 1372 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho riBearingX;
1225 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h oriBearingY; 1373 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h oriBearingY;
1226 FT_Vector_Transform(&vector, &fMatrix22); 1374 FT_Vector_Transform(&vector, &fMatrix22);
1227 path->offset(SkFDot6ToScalar(vector.x), -SkFDot6ToScalar(vector.y)); 1375 path->offset(SkFDot6ToScalar(vector.x), -SkFDot6ToScalar(vector.y));
1228 } 1376 }
1229 } 1377 }
1230 1378
1231 void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx, 1379 #ifdef DEBUG_METRICS
1232 SkPaint::FontMetrics* my) { 1380 void generateFontMetricsOLD(FT_Face face, SkScalar scaleX, SkScalar scaleY,
1381 uint32_t loadGlyphFlags, uint16_t recFlags, SkMatrix matrix22Scalar,
1382 SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) {
1233 if (NULL == mx && NULL == my) { 1383 if (NULL == mx && NULL == my) {
1234 return; 1384 return;
1235 } 1385 }
1236 1386
1237 SkAutoMutexAcquire ac(gFTMutex); 1387 if (false) {
1238 1388 ERROR:
1239 if (this->setupSize()) {
1240 ERROR:
1241 if (mx) { 1389 if (mx) {
1242 sk_bzero(mx, sizeof(SkPaint::FontMetrics)); 1390 sk_bzero(mx, sizeof(SkPaint::FontMetrics));
1243 } 1391 }
1244 if (my) { 1392 if (my) {
1245 sk_bzero(my, sizeof(SkPaint::FontMetrics)); 1393 sk_bzero(my, sizeof(SkPaint::FontMetrics));
1246 } 1394 }
1247 return; 1395 return;
1248 } 1396 }
1249 1397
1250 FT_Face face = fFace;
1251 int upem = face->units_per_EM; 1398 int upem = face->units_per_EM;
1252 if (upem <= 0) { 1399 if (upem <= 0) {
1253 goto ERROR; 1400 goto ERROR;
1254 } 1401 }
1255 1402
1256 SkPoint pts[6]; 1403 SkPoint pts[6];
1257 SkFixed ys[6]; 1404 SkFixed ys[6];
1258 SkScalar scaleY = fScale.y(); 1405 SkScalar mxy = matrix22Scalar.getSkewX();
1259 SkScalar mxy = fMatrix22Scalar.getSkewX(); 1406 SkScalar myy = matrix22Scalar.getScaleY();
1260 SkScalar myy = fMatrix22Scalar.getScaleY();
1261 SkScalar xmin = SkIntToScalar(face->bbox.xMin) / upem; 1407 SkScalar xmin = SkIntToScalar(face->bbox.xMin) / upem;
1262 SkScalar xmax = SkIntToScalar(face->bbox.xMax) / upem; 1408 SkScalar xmax = SkIntToScalar(face->bbox.xMax) / upem;
1263 1409
1264 int leading = face->height - (face->ascender + -face->descender); 1410 int leading = face->height - (face->ascender + -face->descender);
1265 if (leading < 0) { 1411 if (leading < 0) {
1266 leading = 0; 1412 leading = 0;
1267 } 1413 }
1268 1414
1269 // Try to get the OS/2 table from the font. This contains the specific
1270 // average font width metrics which Windows uses.
1271 TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2); 1415 TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
1272 1416
1273 ys[0] = -face->bbox.yMax; 1417 ys[0] = -face->bbox.yMax;
1274 ys[1] = -face->ascender; 1418 ys[1] = -face->ascender;
1275 ys[2] = -face->descender; 1419 ys[2] = -face->descender;
1276 ys[3] = -face->bbox.yMin; 1420 ys[3] = -face->bbox.yMin;
1277 ys[4] = leading; 1421 ys[4] = leading;
1278 ys[5] = os2 ? os2->xAvgCharWidth : 0; 1422 ys[5] = os2 ? os2->xAvgCharWidth : 0;
1279 1423
1280 SkScalar x_height; 1424 SkScalar x_height;
1281 if (os2 && os2->sxHeight) { 1425 if (os2 && os2->sxHeight) {
1282 x_height = fScale.x() * os2->sxHeight / upem; 1426 x_height = scaleX * os2->sxHeight / upem;
1283 } else { 1427 } else {
1284 const FT_UInt x_glyph = FT_Get_Char_Index(fFace, 'x'); 1428 const FT_UInt x_glyph = FT_Get_Char_Index(face, 'x');
1285 if (x_glyph) { 1429 if (x_glyph) {
1286 FT_BBox bbox; 1430 FT_BBox bbox;
1287 FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags); 1431 FT_Load_Glyph(face, x_glyph, loadGlyphFlags);
1288 if (fRec.fFlags & kEmbolden_Flag) { 1432 if (recFlags & SkScalerContext::kEmbolden_Flag) {
1289 emboldenOutline(fFace, &fFace->glyph->outline); 1433 SkDebugf("x_height is incorrect (skipped embolden step)\n");
1290 } 1434 }
1291 FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox); 1435 FT_Outline_Get_CBox(&face->glyph->outline, &bbox);
1292 x_height = bbox.yMax / 64.0f; 1436 x_height = bbox.yMax / 64.0f;
1293 } else { 1437 } else {
1294 x_height = 0; 1438 x_height = 0;
1295 } 1439 }
1296 } 1440 }
1297 1441
1298 // convert upem-y values into scalar points
1299 for (int i = 0; i < 6; i++) { 1442 for (int i = 0; i < 6; i++) {
1300 SkScalar y = scaleY * ys[i] / upem; 1443 SkScalar y = scaleY * ys[i] / upem;
1301 pts[i].set(y * mxy, y * myy); 1444 pts[i].set(y * mxy, y * myy);
1302 } 1445 }
1303 1446
1304 if (mx) { 1447 if (mx) {
1305 mx->fTop = pts[0].fX; 1448 mx->fTop = pts[0].fX;
1306 mx->fAscent = pts[1].fX; 1449 mx->fAscent = pts[1].fX;
1307 mx->fDescent = pts[2].fX; 1450 mx->fDescent = pts[2].fX;
1308 mx->fBottom = pts[3].fX; 1451 mx->fBottom = pts[3].fX;
1309 mx->fLeading = pts[4].fX; 1452 mx->fLeading = pts[4].fX;
1310 mx->fAvgCharWidth = pts[5].fX; 1453 mx->fAvgCharWidth = pts[5].fX;
1311 mx->fXMin = xmin; 1454 mx->fXMin = xmin;
1312 mx->fXMax = xmax; 1455 mx->fXMax = xmax;
1313 mx->fXHeight = x_height; 1456 mx->fXHeight = x_height;
1314 } 1457 SkDebugf("generateFontMetricsOLD(\"%s\"): mx is:\n", face->family_name);
1315 if (my) { 1458 dumpSkFontMetrics(*mx);
1459 }
1460
1461 if (my) {
1316 my->fTop = pts[0].fY; 1462 my->fTop = pts[0].fY;
1317 my->fAscent = pts[1].fY; 1463 my->fAscent = pts[1].fY;
1318 my->fDescent = pts[2].fY; 1464 my->fDescent = pts[2].fY;
1319 my->fBottom = pts[3].fY; 1465 my->fBottom = pts[3].fY;
1320 my->fLeading = pts[4].fY; 1466 my->fLeading = pts[4].fY;
1321 my->fAvgCharWidth = pts[5].fY; 1467 my->fAvgCharWidth = pts[5].fY;
1322 my->fXMin = xmin; 1468 my->fXMin = xmin;
1323 my->fXMax = xmax; 1469 my->fXMax = xmax;
1324 my->fXHeight = x_height; 1470 my->fXHeight = x_height;
1471 SkDebugf("generateFontMetricsOLD(\"%s\"): my is:\n", face->family_name);
1472 dumpSkFontMetrics(*my);
1473 }
1474 }
1475 #endif
1476
1477 void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx,
1478 SkPaint::FontMetrics* my) {
1479 if (NULL == mx && NULL == my) {
1480 return;
1481 }
1482
1483 SkAutoMutexAcquire ac(gFTMutex);
1484
1485 if (this->setupSize()) {
1486 ERROR:
1487 if (mx) {
1488 sk_bzero(mx, sizeof(SkPaint::FontMetrics));
1489 }
1490 if (my) {
1491 sk_bzero(my, sizeof(SkPaint::FontMetrics));
1492 }
1493 return;
1494 }
1495
1496 FT_Face face = fFace;
1497 SkScalar scaleX = fScale.x();
1498 SkScalar scaleY = fScale.y();
1499 SkScalar mxy = fMatrix22Scalar.getSkewX() * scaleY;
1500 SkScalar myy = fMatrix22Scalar.getScaleY() * scaleY;
1501
1502 #ifdef DEBUG_METRICS
1503 SkDebugf("generateFontMetrics(\"%s\"):\n", face->family_name);
1504 dumpFTFaceMetrics(face);
1505 dumpFTSize(face->size);
1506 #endif
1507
1508 // fetch units/EM from "head" table if needed (ie for bitmap fonts)
1509 SkScalar upem = SkIntToScalar(face->units_per_EM);
1510 if (!upem) {
1511 TT_Header* ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head);
1512 if (ttHeader) {
1513 upem = SkIntToScalar(ttHeader->Units_Per_EM);
1514 }
1515 }
1516
1517 // use the os/2 table as a source of reasonable defaults.
1518 SkScalar x_height = 0.0f;
1519 SkScalar avgCharWidth = 0.0f;
1520 TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
1521 if (os2) {
1522 x_height = scaleX * SkIntToScalar(os2->sxHeight) / upem;
1523 avgCharWidth = SkIntToScalar(os2->xAvgCharWidth) / upem;
1524 }
1525
1526 // pull from format-specific metrics as needed
1527 SkScalar ascent, descent, leading, xmin, xmax, ymin, ymax;
1528 if (face->face_flags & FT_FACE_FLAG_SCALABLE) { // scalable outline font
1529 ascent = -SkIntToScalar(face->ascender) / upem;
1530 descent = -SkIntToScalar(face->descender) / upem;
1531 leading = SkIntToScalar(face->height + (face->descender - face->ascender )) / upem;
1532 xmin = SkIntToScalar(face->bbox.xMin) / upem;
1533 xmax = SkIntToScalar(face->bbox.xMax) / upem;
1534 ymin = -SkIntToScalar(face->bbox.yMin) / upem;
1535 ymax = -SkIntToScalar(face->bbox.yMax) / upem;
1536 // we may be able to synthesize x_height from outline
1537 if (!x_height) {
1538 const FT_UInt x_glyph = FT_Get_Char_Index(fFace, 'x');
1539 if (x_glyph) {
1540 FT_BBox bbox;
1541 FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags);
1542 if ((fRec.fFlags & kEmbolden_Flag) && !(fFace->style_flags & FT_ STYLE_FLAG_BOLD)) {
1543 emboldenOutline(fFace, &fFace->glyph->outline);
1544 }
1545 FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox);
1546 x_height = SkIntToScalar(bbox.yMax) / 64.0f;
1547 }
1548 }
1549 } else if (fStrikeIndex != -1) { // bitmap strike metrics
1550 #ifdef DEBUG_METRICS
1551 dumpBitmapStrikeMetrics(fFace, fStrikeIndex);
1552 #endif
1553 SkScalar xppem = SkIntToScalar(face->size->metrics.x_ppem);
1554 SkScalar yppem = SkIntToScalar(face->size->metrics.y_ppem);
1555 ascent = -SkIntToScalar(face->size->metrics.ascender) / (yppem * 64.0f);
1556 descent = -SkIntToScalar(face->size->metrics.descender) / (yppem * 64.0f );
1557 leading = (SkIntToScalar(face->size->metrics.height) / (yppem * 64.0f))
1558 + ascent - descent;
1559 xmin = 0.0f;
1560 xmax = SkIntToScalar(face->available_sizes[fStrikeIndex].width) / xppem;
1561 ymin = descent + leading;
1562 ymax = ascent - descent;
1563 if (!x_height) {
1564 x_height = -ascent;
1565 }
1566 if (!avgCharWidth) {
1567 avgCharWidth = xmax - xmin;
1568 }
1569 } else {
1570 goto ERROR;
1571 }
1572
1573 // synthesize elements that were not provided by the os/2 table or format-sp ecific metrics
1574 if (!x_height) {
1575 x_height = -ascent;
1576 }
1577 if (!avgCharWidth) {
1578 avgCharWidth = xmax - xmin;
1579 }
1580
1581 // disallow negative linespacing
1582 if (leading < 0.0f) {
1583 leading = 0.0f;
1584 }
1585
1586 #ifdef DEBUG_METRICS
1587 generateFontMetricsOLD(fFace, fScale.x(), fScale.y(), fLoadGlyphFlags, fRec. fFlags,
1588 fMatrix22Scalar, mx, my);
1589 #endif
1590 if (mx) {
1591 mx->fTop = ymax * mxy;
1592 mx->fAscent = ascent * mxy;
1593 mx->fDescent = descent * mxy;
1594 mx->fBottom = ymin * mxy;
1595 mx->fLeading = leading * mxy;
1596 mx->fAvgCharWidth = avgCharWidth * mxy;
1597 mx->fXMin = xmin;
1598 mx->fXMax = xmax;
1599 mx->fXHeight = x_height;
1600 #ifdef DEBUG_METRICS
1601 SkDebugf("generateFontMetrics(\"%s\"): mx is:\n", face->family_name);
1602 dumpSkFontMetrics(*mx);
1603 #endif
1604 }
1605 if (my) {
1606 my->fTop = ymax * myy;
1607 my->fAscent = ascent * myy;
1608 my->fDescent = descent * myy;
1609 my->fBottom = ymin * myy;
1610 my->fLeading = leading * myy;
1611 my->fAvgCharWidth = avgCharWidth * myy;
1612 my->fXMin = xmin;
1613 my->fXMax = xmax;
1614 my->fXHeight = x_height;
1615 #ifdef DEBUG_METRICS
1616 SkDebugf("generateFontMetrics(\"%s\"): my is:\n", face->family_name);
1617 dumpSkFontMetrics(*my);
1618 #endif
1325 } 1619 }
1326 } 1620 }
1327 1621
1328 /////////////////////////////////////////////////////////////////////////////// 1622 ///////////////////////////////////////////////////////////////////////////////
1329 1623
1330 #include "SkUtils.h" 1624 #include "SkUtils.h"
1331 1625
1332 static SkUnichar next_utf8(const void** chars) { 1626 static SkUnichar next_utf8(const void** chars) {
1333 return SkUTF8_NextUnichar((const char**)chars); 1627 return SkUTF8_NextUnichar((const char**)chars);
1334 } 1628 }
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1521 *style = (SkTypeface::Style) tempStyle; 1815 *style = (SkTypeface::Style) tempStyle;
1522 } 1816 }
1523 if (isFixedPitch) { 1817 if (isFixedPitch) {
1524 *isFixedPitch = FT_IS_FIXED_WIDTH(face); 1818 *isFixedPitch = FT_IS_FIXED_WIDTH(face);
1525 } 1819 }
1526 1820
1527 FT_Done_Face(face); 1821 FT_Done_Face(face);
1528 FT_Done_FreeType(library); 1822 FT_Done_FreeType(library);
1529 return true; 1823 return true;
1530 } 1824 }
OLDNEW
« no previous file with comments | « no previous file | src/ports/SkFontHost_FreeType_common.cpp » ('j') | src/ports/SkFontHost_FreeType_common.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698