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

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: reduce indentation 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
« no previous file with comments | « resources/fonts/Funkster.ttf ('k') | src/ports/SkFontHost_FreeType_common.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
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 = SkToU16(SkScalarRoundToInt(SkScalarMul(SkIntToScalar(glyph.fW idth), scale)));
reed1 2013/11/20 21:52:12 SkScalar has not been SkFixed for over a year, and
1163 glyph.fHeight = SkToU16(SkScalarRoundToInt(SkScalarMul(SkIntToScalar(glyph.f Height), scale)));
1164
1165 glyph.fTop = SkToS16(SkScalarRoundToInt(SkScalarMul(SkIntToScalar(glyph.fTop ), scale)));
1166 glyph.fLeft = SkToS16(SkScalarRoundToInt(SkScalarMul(SkIntToScalar(glyph.fLe ft), scale)));
1167
1168 SkFixed fixedScale = SkScalarToFixed(scale);
1169 glyph.fAdvanceX = SkFixedMul(glyph.fAdvanceX, fixedScale);
1170 glyph.fAdvanceY = SkFixedMul(glyph.fAdvanceY, fixedScale);
1171 }
1172
1044 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { 1173 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
1045 SkAutoMutexAcquire ac(gFTMutex); 1174 SkAutoMutexAcquire ac(gFTMutex);
1046 1175
1047 glyph->fRsbDelta = 0; 1176 glyph->fRsbDelta = 0;
1048 glyph->fLsbDelta = 0; 1177 glyph->fLsbDelta = 0;
1049 1178
1050 FT_Error err; 1179 FT_Error err;
1051 1180
1052 if (this->setupSize()) { 1181 if (this->setupSize()) {
1053 goto ERROR; 1182 goto ERROR;
1054 } 1183 }
1055 1184
1056 err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFl ags ); 1185 err = FT_Load_Glyph( fFace, glyph->getGlyphID(fBaseGlyphCount), fLoadGlyphFl ags );
1057 if (err != 0) { 1186 if (err != 0) {
1058 #if 0 1187 #if 0
1059 SkDEBUGF(("SkScalerContext_FreeType::generateMetrics(%x): FT_Load_Glyph( glyph:%d flags:%x) returned 0x%x\n", 1188 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)); 1189 fFaceRec->fFontID, glyph->getGlyphID(fBaseGlyphCount), fLoad GlyphFlags, err));
1061 #endif 1190 #endif
1062 ERROR: 1191 ERROR:
1063 glyph->zeroMetrics(); 1192 glyph->zeroMetrics();
1064 return; 1193 return;
1065 } 1194 }
1066 1195
1067 switch ( fFace->glyph->format ) { 1196 switch ( fFace->glyph->format ) {
1068 case FT_GLYPH_FORMAT_OUTLINE: { 1197 case FT_GLYPH_FORMAT_OUTLINE:
1069 FT_BBox bbox;
1070
1071 if (0 == fFace->glyph->outline.n_contours) { 1198 if (0 == fFace->glyph->outline.n_contours) {
1072 glyph->fWidth = 0; 1199 glyph->fWidth = 0;
1073 glyph->fHeight = 0; 1200 glyph->fHeight = 0;
1074 glyph->fTop = 0; 1201 glyph->fTop = 0;
1075 glyph->fLeft = 0; 1202 glyph->fLeft = 0;
1076 break; 1203 } else {
1204 if (fRec.fFlags & kEmbolden_Flag && !(fFace->style_flags & FT_STYLE_ FLAG_BOLD)) {
1205 emboldenOutline(fFace, &fFace->glyph->outline);
1206 }
1207
1208 FT_BBox bbox;
1209 getBBoxForCurrentGlyph(glyph, &bbox, true);
1210
1211 glyph->fWidth = SkToU16(SkFDot6Floor(bbox.xMax - bbox.xMin));
1212 glyph->fHeight = SkToU16(SkFDot6Floor(bbox.yMax - bbox.yMin));
1213 glyph->fTop = -SkToS16(SkFDot6Floor(bbox.yMax));
1214 glyph->fLeft = SkToS16(SkFDot6Floor(bbox.xMin));
1215
1216 updateGlyphIfLCD(glyph);
1077 } 1217 }
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; 1218 break;
1093 }
1094 1219
1095 case FT_GLYPH_FORMAT_BITMAP: 1220 case FT_GLYPH_FORMAT_BITMAP:
1096 if (fRec.fFlags & kEmbolden_Flag) { 1221 if (fRec.fFlags & kEmbolden_Flag) {
1097 FT_GlyphSlot_Own_Bitmap(fFace->glyph); 1222 FT_GlyphSlot_Own_Bitmap(fFace->glyph);
1098 FT_Bitmap_Embolden(gFTLibrary, &fFace->glyph->bitmap, kBitmapEmbolde nStrength, 0); 1223 FT_Bitmap_Embolden(gFTLibrary, &fFace->glyph->bitmap, kBitmapEmbolde nStrength, 0);
1099 } 1224 }
1100 1225
1101 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 1226 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
1102 FT_Vector vector; 1227 FT_Vector vector;
1103 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metric s.horiBearingX; 1228 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metric s.horiBearingX;
1104 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY; 1229 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY;
1105 FT_Vector_Transform(&vector, &fMatrix22); 1230 FT_Vector_Transform(&vector, &fMatrix22);
1106 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x); 1231 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x);
1107 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y); 1232 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y);
1108 } 1233 }
1109 1234
1235 #ifdef FT_LOAD_COLOR
1236 if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) {
1237 glyph->fMaskFormat = SkMask::kARGB32_Format;
1238 }
1239 #endif
1240
1110 glyph->fWidth = SkToU16(fFace->glyph->bitmap.width); 1241 glyph->fWidth = SkToU16(fFace->glyph->bitmap.width);
1111 glyph->fHeight = SkToU16(fFace->glyph->bitmap.rows); 1242 glyph->fHeight = SkToU16(fFace->glyph->bitmap.rows);
1112 glyph->fTop = -SkToS16(fFace->glyph->bitmap_top); 1243 glyph->fTop = -SkToS16(fFace->glyph->bitmap_top);
1113 glyph->fLeft = SkToS16(fFace->glyph->bitmap_left); 1244 glyph->fLeft = SkToS16(fFace->glyph->bitmap_left);
1114 break; 1245 break;
1115 1246
1116 default: 1247 default:
1117 SkDEBUGFAIL("unknown glyph format"); 1248 SkDEBUGFAIL("unknown glyph format");
1118 goto ERROR; 1249 goto ERROR;
1119 } 1250 }
(...skipping 14 matching lines...) Expand all
1134 glyph->fAdvanceX = SkFDot6ToFixed(fFace->glyph->advance.x); 1265 glyph->fAdvanceX = SkFDot6ToFixed(fFace->glyph->advance.x);
1135 glyph->fAdvanceY = -SkFDot6ToFixed(fFace->glyph->advance.y); 1266 glyph->fAdvanceY = -SkFDot6ToFixed(fFace->glyph->advance.y);
1136 1267
1137 if (fRec.fFlags & kDevKernText_Flag) { 1268 if (fRec.fFlags & kDevKernText_Flag) {
1138 glyph->fRsbDelta = SkToS8(fFace->glyph->rsb_delta); 1269 glyph->fRsbDelta = SkToS8(fFace->glyph->rsb_delta);
1139 glyph->fLsbDelta = SkToS8(fFace->glyph->lsb_delta); 1270 glyph->fLsbDelta = SkToS8(fFace->glyph->lsb_delta);
1140 } 1271 }
1141 } 1272 }
1142 } 1273 }
1143 1274
1275 if (fFace->glyph->format == FT_GLYPH_FORMAT_BITMAP && fScaleY && fFace->size ->metrics.y_ppem) {
1276 #ifdef DEBUG_METRICS
1277 SkDebugf("pre-scale glyph metrics:\n");
1278 dumpSkGlyphMetrics(*glyph);
1279 #endif
1280 // NOTE: both dimensions are scaled by y_ppem. this is WAI.
1281 scaleGlyphMetrics(*glyph, SkScalarDiv(SkFixedToScalar(fScaleY),
1282 SkIntToScalar(fFace->size->metrics .y_ppem)));
1283 }
1284 #ifdef DEBUG_METRICS
1285 SkDebugf("post-scale glyph metrics:\n");
1286 dumpSkGlyphMetrics(*glyph);
1287 #endif
1288
1144 1289
1145 #ifdef ENABLE_GLYPH_SPEW 1290 #ifdef ENABLE_GLYPH_SPEW
1146 SkDEBUGF(("FT_Set_Char_Size(this:%p sx:%x sy:%x ", this, fScaleX, fScaleY)); 1291 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)); 1292 SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(fBaseGlyp hCount), fLoadGlyphFlags, glyph->fWidth));
1148 #endif 1293 #endif
1149 } 1294 }
1150 1295
1151 1296
1152 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { 1297 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
1153 SkAutoMutexAcquire ac(gFTMutex); 1298 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. 1346 // Offset the path so that it is relative to the vertical origin if needed.
1202 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 1347 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
1203 FT_Vector vector; 1348 FT_Vector vector;
1204 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho riBearingX; 1349 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.ho riBearingX;
1205 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h oriBearingY; 1350 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.h oriBearingY;
1206 FT_Vector_Transform(&vector, &fMatrix22); 1351 FT_Vector_Transform(&vector, &fMatrix22);
1207 path->offset(SkFDot6ToScalar(vector.x), -SkFDot6ToScalar(vector.y)); 1352 path->offset(SkFDot6ToScalar(vector.x), -SkFDot6ToScalar(vector.y));
1208 } 1353 }
1209 } 1354 }
1210 1355
1211 void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx, 1356 #ifdef DEBUG_METRICS
1212 SkPaint::FontMetrics* my) { 1357 void generateFontMetricsOLD(FT_Face face, SkScalar scaleX, SkScalar scaleY,
1358 uint32_t loadGlyphFlags, uint16_t recFlags, SkMatrix matrix22Scalar,
1359 SkPaint::FontMetrics* mx, SkPaint::FontMetrics* my) {
1213 if (NULL == mx && NULL == my) { 1360 if (NULL == mx && NULL == my) {
1214 return; 1361 return;
1215 } 1362 }
1216 1363
1217 SkAutoMutexAcquire ac(gFTMutex); 1364 if (false) {
1218 1365 ERROR:
1219 if (this->setupSize()) {
1220 ERROR:
1221 if (mx) { 1366 if (mx) {
1222 sk_bzero(mx, sizeof(SkPaint::FontMetrics)); 1367 sk_bzero(mx, sizeof(SkPaint::FontMetrics));
1223 } 1368 }
1224 if (my) { 1369 if (my) {
1225 sk_bzero(my, sizeof(SkPaint::FontMetrics)); 1370 sk_bzero(my, sizeof(SkPaint::FontMetrics));
1226 } 1371 }
1227 return; 1372 return;
1228 } 1373 }
1229 1374
1230 FT_Face face = fFace;
1231 int upem = face->units_per_EM; 1375 int upem = face->units_per_EM;
1232 if (upem <= 0) { 1376 if (upem <= 0) {
1233 goto ERROR; 1377 goto ERROR;
1234 } 1378 }
1235 1379
1236 SkPoint pts[6]; 1380 SkPoint pts[6];
1237 SkFixed ys[6]; 1381 SkFixed ys[6];
1238 SkScalar scaleY = fScale.y(); 1382 SkScalar mxy = matrix22Scalar.getSkewX();
1239 SkScalar mxy = fMatrix22Scalar.getSkewX(); 1383 SkScalar myy = matrix22Scalar.getScaleY();
1240 SkScalar myy = fMatrix22Scalar.getScaleY();
1241 SkScalar xmin = SkIntToScalar(face->bbox.xMin) / upem; 1384 SkScalar xmin = SkIntToScalar(face->bbox.xMin) / upem;
1242 SkScalar xmax = SkIntToScalar(face->bbox.xMax) / upem; 1385 SkScalar xmax = SkIntToScalar(face->bbox.xMax) / upem;
1243 1386
1244 int leading = face->height - (face->ascender + -face->descender); 1387 int leading = face->height - (face->ascender + -face->descender);
1245 if (leading < 0) { 1388 if (leading < 0) {
1246 leading = 0; 1389 leading = 0;
1247 } 1390 }
1248 1391
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); 1392 TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
1252 1393
1253 ys[0] = -face->bbox.yMax; 1394 ys[0] = -face->bbox.yMax;
1254 ys[1] = -face->ascender; 1395 ys[1] = -face->ascender;
1255 ys[2] = -face->descender; 1396 ys[2] = -face->descender;
1256 ys[3] = -face->bbox.yMin; 1397 ys[3] = -face->bbox.yMin;
1257 ys[4] = leading; 1398 ys[4] = leading;
1258 ys[5] = os2 ? os2->xAvgCharWidth : 0; 1399 ys[5] = os2 ? os2->xAvgCharWidth : 0;
1259 1400
1260 SkScalar x_height; 1401 SkScalar x_height;
1261 if (os2 && os2->sxHeight) { 1402 if (os2 && os2->sxHeight) {
1262 x_height = fScale.x() * os2->sxHeight / upem; 1403 x_height = scaleX * os2->sxHeight / upem;
1263 } else { 1404 } else {
1264 const FT_UInt x_glyph = FT_Get_Char_Index(fFace, 'x'); 1405 const FT_UInt x_glyph = FT_Get_Char_Index(face, 'x');
1265 if (x_glyph) { 1406 if (x_glyph) {
1266 FT_BBox bbox; 1407 FT_BBox bbox;
1267 FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags); 1408 FT_Load_Glyph(face, x_glyph, loadGlyphFlags);
1268 if (fRec.fFlags & kEmbolden_Flag) { 1409 if (recFlags & SkScalerContext::kEmbolden_Flag) {
1269 emboldenOutline(fFace, &fFace->glyph->outline); 1410 SkDebugf("x_height is incorrect (skipped embolden step)\n");
1270 } 1411 }
1271 FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox); 1412 FT_Outline_Get_CBox(&face->glyph->outline, &bbox);
1272 x_height = bbox.yMax / 64.0f; 1413 x_height = bbox.yMax / 64.0f;
1273 } else { 1414 } else {
1274 x_height = 0; 1415 x_height = 0;
1275 } 1416 }
1276 } 1417 }
1277 1418
1278 // convert upem-y values into scalar points
1279 for (int i = 0; i < 6; i++) { 1419 for (int i = 0; i < 6; i++) {
1280 SkScalar y = scaleY * ys[i] / upem; 1420 SkScalar y = scaleY * ys[i] / upem;
1281 pts[i].set(y * mxy, y * myy); 1421 pts[i].set(y * mxy, y * myy);
1282 } 1422 }
1283 1423
1284 if (mx) { 1424 if (mx) {
1285 mx->fTop = pts[0].fX; 1425 mx->fTop = pts[0].fX;
1286 mx->fAscent = pts[1].fX; 1426 mx->fAscent = pts[1].fX;
1287 mx->fDescent = pts[2].fX; 1427 mx->fDescent = pts[2].fX;
1288 mx->fBottom = pts[3].fX; 1428 mx->fBottom = pts[3].fX;
1289 mx->fLeading = pts[4].fX; 1429 mx->fLeading = pts[4].fX;
1290 mx->fAvgCharWidth = pts[5].fX; 1430 mx->fAvgCharWidth = pts[5].fX;
1291 mx->fXMin = xmin; 1431 mx->fXMin = xmin;
1292 mx->fXMax = xmax; 1432 mx->fXMax = xmax;
1293 mx->fXHeight = x_height; 1433 mx->fXHeight = x_height;
1294 } 1434 SkDebugf("generateFontMetricsOLD(\"%s\"): mx is:\n", face->family_name);
1295 if (my) { 1435 dumpSkFontMetrics(*mx);
1436 }
1437
1438 if (my) {
1296 my->fTop = pts[0].fY; 1439 my->fTop = pts[0].fY;
1297 my->fAscent = pts[1].fY; 1440 my->fAscent = pts[1].fY;
1298 my->fDescent = pts[2].fY; 1441 my->fDescent = pts[2].fY;
1299 my->fBottom = pts[3].fY; 1442 my->fBottom = pts[3].fY;
1300 my->fLeading = pts[4].fY; 1443 my->fLeading = pts[4].fY;
1301 my->fAvgCharWidth = pts[5].fY; 1444 my->fAvgCharWidth = pts[5].fY;
1302 my->fXMin = xmin; 1445 my->fXMin = xmin;
1303 my->fXMax = xmax; 1446 my->fXMax = xmax;
1304 my->fXHeight = x_height; 1447 my->fXHeight = x_height;
1448 SkDebugf("generateFontMetricsOLD(\"%s\"): my is:\n", face->family_name);
1449 dumpSkFontMetrics(*my);
1450 }
1451 }
1452 #endif
1453
1454 void SkScalerContext_FreeType::generateFontMetrics(SkPaint::FontMetrics* mx,
1455 SkPaint::FontMetrics* my) {
1456 if (NULL == mx && NULL == my) {
1457 return;
1458 }
1459
1460 SkAutoMutexAcquire ac(gFTMutex);
1461
1462 if (this->setupSize()) {
1463 ERROR:
1464 if (mx) {
1465 sk_bzero(mx, sizeof(SkPaint::FontMetrics));
1466 }
1467 if (my) {
1468 sk_bzero(my, sizeof(SkPaint::FontMetrics));
1469 }
1470 return;
1471 }
1472
1473 FT_Face face = fFace;
1474 SkScalar scaleX = fScale.x();
1475 SkScalar scaleY = fScale.y();
1476 SkScalar mxy = fMatrix22Scalar.getSkewX() * scaleY;
1477 SkScalar myy = fMatrix22Scalar.getScaleY() * scaleY;
1478
1479 #ifdef DEBUG_METRICS
1480 SkDebugf("generateFontMetrics(\"%s\"):\n", face->family_name);
1481 dumpFTFaceMetrics(face);
1482 dumpFTSize(face->size);
1483 #endif
1484
1485 // fetch units/EM from "head" table if needed (ie for bitmap fonts)
1486 SkScalar upem = SkIntToScalar(face->units_per_EM);
1487 if (!upem) {
1488 TT_Header* ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head);
1489 if (ttHeader) {
1490 upem = SkIntToScalar(ttHeader->Units_Per_EM);
1491 }
1492 }
1493
1494 // use the os/2 table as a source of reasonable defaults.
1495 SkScalar x_height = 0.0f;
1496 SkScalar avgCharWidth = 0.0f;
1497 TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
1498 if (os2) {
1499 x_height = scaleX * SkIntToScalar(os2->sxHeight) / upem;
1500 avgCharWidth = SkIntToScalar(os2->xAvgCharWidth) / upem;
1501 }
1502
1503 // pull from format-specific metrics as needed
1504 SkScalar ascent, descent, leading, xmin, xmax, ymin, ymax;
1505 if (face->face_flags & FT_FACE_FLAG_SCALABLE) { // scalable outline font
1506 ascent = -SkIntToScalar(face->ascender) / upem;
1507 descent = -SkIntToScalar(face->descender) / upem;
1508 leading = SkIntToScalar(face->height + (face->descender - face->ascender )) / upem;
1509 xmin = SkIntToScalar(face->bbox.xMin) / upem;
1510 xmax = SkIntToScalar(face->bbox.xMax) / upem;
1511 ymin = -SkIntToScalar(face->bbox.yMin) / upem;
1512 ymax = -SkIntToScalar(face->bbox.yMax) / upem;
1513 // we may be able to synthesize x_height from outline
1514 if (!x_height) {
1515 const FT_UInt x_glyph = FT_Get_Char_Index(fFace, 'x');
1516 if (x_glyph) {
1517 FT_BBox bbox;
1518 FT_Load_Glyph(fFace, x_glyph, fLoadGlyphFlags);
1519 if ((fRec.fFlags & kEmbolden_Flag) && !(fFace->style_flags & FT_ STYLE_FLAG_BOLD)) {
1520 emboldenOutline(fFace, &fFace->glyph->outline);
1521 }
1522 FT_Outline_Get_CBox(&fFace->glyph->outline, &bbox);
1523 x_height = SkIntToScalar(bbox.yMax) / 64.0f;
1524 }
1525 }
1526 } else if (fStrikeIndex != -1) { // bitmap strike metrics
1527 #ifdef DEBUG_METRICS
1528 dumpBitmapStrikeMetrics(fFace, fStrikeIndex);
1529 #endif
1530 SkScalar xppem = SkIntToScalar(face->size->metrics.x_ppem);
1531 SkScalar yppem = SkIntToScalar(face->size->metrics.y_ppem);
1532 ascent = -SkIntToScalar(face->size->metrics.ascender) / (yppem * 64.0f);
1533 descent = -SkIntToScalar(face->size->metrics.descender) / (yppem * 64.0f );
1534 leading = (SkIntToScalar(face->size->metrics.height) / (yppem * 64.0f))
1535 + ascent - descent;
1536 xmin = 0.0f;
1537 xmax = SkIntToScalar(face->available_sizes[fStrikeIndex].width) / xppem;
1538 ymin = descent + leading;
1539 ymax = ascent - descent;
1540 if (!x_height) {
1541 x_height = -ascent;
1542 }
1543 if (!avgCharWidth) {
1544 avgCharWidth = xmax - xmin;
1545 }
1546 } else {
1547 goto ERROR;
1548 }
1549
1550 // synthesize elements that were not provided by the os/2 table or format-sp ecific metrics
1551 if (!x_height) {
1552 x_height = -ascent;
1553 }
1554 if (!avgCharWidth) {
1555 avgCharWidth = xmax - xmin;
1556 }
1557
1558 // disallow negative linespacing
1559 if (leading < 0.0f) {
1560 leading = 0.0f;
1561 }
1562
1563 #ifdef DEBUG_METRICS
1564 generateFontMetricsOLD(fFace, fScale.x(), fScale.y(), fLoadGlyphFlags, fRec. fFlags,
1565 fMatrix22Scalar, mx, my);
1566 #endif
1567 if (mx) {
1568 mx->fTop = ymax * mxy;
1569 mx->fAscent = ascent * mxy;
1570 mx->fDescent = descent * mxy;
1571 mx->fBottom = ymin * mxy;
1572 mx->fLeading = leading * mxy;
1573 mx->fAvgCharWidth = avgCharWidth * mxy;
1574 mx->fXMin = xmin;
1575 mx->fXMax = xmax;
1576 mx->fXHeight = x_height;
1577 #ifdef DEBUG_METRICS
1578 SkDebugf("generateFontMetrics(\"%s\"): mx is:\n", face->family_name);
1579 dumpSkFontMetrics(*mx);
1580 #endif
1581 }
1582 if (my) {
1583 my->fTop = ymax * myy;
1584 my->fAscent = ascent * myy;
1585 my->fDescent = descent * myy;
1586 my->fBottom = ymin * myy;
1587 my->fLeading = leading * myy;
1588 my->fAvgCharWidth = avgCharWidth * myy;
1589 my->fXMin = xmin;
1590 my->fXMax = xmax;
1591 my->fXHeight = x_height;
1592 #ifdef DEBUG_METRICS
1593 SkDebugf("generateFontMetrics(\"%s\"): my is:\n", face->family_name);
1594 dumpSkFontMetrics(*my);
1595 #endif
1305 } 1596 }
1306 } 1597 }
1307 1598
1308 /////////////////////////////////////////////////////////////////////////////// 1599 ///////////////////////////////////////////////////////////////////////////////
1309 1600
1310 #include "SkUtils.h" 1601 #include "SkUtils.h"
1311 1602
1312 static SkUnichar next_utf8(const void** chars) { 1603 static SkUnichar next_utf8(const void** chars) {
1313 return SkUTF8_NextUnichar((const char**)chars); 1604 return SkUTF8_NextUnichar((const char**)chars);
1314 } 1605 }
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
1501 *style = (SkTypeface::Style) tempStyle; 1792 *style = (SkTypeface::Style) tempStyle;
1502 } 1793 }
1503 if (isFixedPitch) { 1794 if (isFixedPitch) {
1504 *isFixedPitch = FT_IS_FIXED_WIDTH(face); 1795 *isFixedPitch = FT_IS_FIXED_WIDTH(face);
1505 } 1796 }
1506 1797
1507 FT_Done_Face(face); 1798 FT_Done_Face(face);
1508 FT_Done_FreeType(library); 1799 FT_Done_FreeType(library);
1509 return true; 1800 return true;
1510 } 1801 }
OLDNEW
« no previous file with comments | « resources/fonts/Funkster.ttf ('k') | src/ports/SkFontHost_FreeType_common.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698