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

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

Powered by Google App Engine
This is Rietveld 408576698