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

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

Issue 2139703002: Rotate emoji with FreeType. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Less invasive, update comments. Created 4 years, 5 months 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
OLDNEW
1 /* 1 /*
2 * Copyright 2006 The Android Open Source Project 2 * Copyright 2006 The Android Open Source Project
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkAdvancedTypefaceMetrics.h" 8 #include "SkAdvancedTypefaceMetrics.h"
9 #include "SkBitmap.h" 9 #include "SkBitmap.h"
10 #include "SkCanvas.h" 10 #include "SkCanvas.h"
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
190 unsigned generateGlyphCount() override; 190 unsigned generateGlyphCount() override;
191 uint16_t generateCharToGlyph(SkUnichar uni) override; 191 uint16_t generateCharToGlyph(SkUnichar uni) override;
192 void generateAdvance(SkGlyph* glyph) override; 192 void generateAdvance(SkGlyph* glyph) override;
193 void generateMetrics(SkGlyph* glyph) override; 193 void generateMetrics(SkGlyph* glyph) override;
194 void generateImage(const SkGlyph& glyph) override; 194 void generateImage(const SkGlyph& glyph) override;
195 void generatePath(const SkGlyph& glyph, SkPath* path) override; 195 void generatePath(const SkGlyph& glyph, SkPath* path) override;
196 void generateFontMetrics(SkPaint::FontMetrics*) override; 196 void generateFontMetrics(SkPaint::FontMetrics*) override;
197 SkUnichar generateGlyphToChar(uint16_t glyph) override; 197 SkUnichar generateGlyphToChar(uint16_t glyph) override;
198 198
199 private: 199 private:
200 FT_Face fFace; // reference to shared face in gFaceRecHead 200 FT_Face fFace; // Shared face from gFaceRecHead.
201 FT_Size fFTSize; // our own copy 201 FT_Size fFTSize; // The size on the fFace for this scaler.
202 FT_Int fStrikeIndex; 202 FT_Int fStrikeIndex;
203 FT_F26Dot6 fScaleX, fScaleY;
204 FT_Matrix fMatrix22;
205 uint32_t fLoadGlyphFlags;
206 bool fDoLinearMetrics;
207 bool fLCDIsVert;
208 203
209 // Need scalar versions for generateFontMetrics 204 /** The rest of the matrix after FreeType handles the size.
210 SkVector fScale; 205 * With outline font rasterization this is handled by FreeType with FT_Set_ Transform.
211 SkMatrix fMatrix22Scalar; 206 * With bitmap only fonts this matrix must be applied to scale the bitmap.
207 */
208 SkMatrix fMatrix22Scalar;
209 /** Same as fMatrix22Scalar, but in FreeType units and space. */
210 FT_Matrix fMatrix22;
211 /** The actual size requested. */
212 SkVector fScale;
213
214 uint32_t fLoadGlyphFlags;
215 bool fDoLinearMetrics;
216 bool fLCDIsVert;
212 217
213 FT_Error setupSize(); 218 FT_Error setupSize();
214 void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox, 219 void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox,
215 bool snapToPixelBoundary = false); 220 bool snapToPixelBoundary = false);
216 bool getCBoxForLetter(char letter, FT_BBox* bbox); 221 bool getCBoxForLetter(char letter, FT_BBox* bbox);
217 // Caller must lock gFTMutex before calling this function. 222 // Caller must lock gFTMutex before calling this function.
218 void updateGlyphIfLCD(SkGlyph* glyph); 223 void updateGlyphIfLCD(SkGlyph* glyph);
219 // Caller must lock gFTMutex before calling this function. 224 // Caller must lock gFTMutex before calling this function.
220 // update FreeType2 glyph slot with glyph emboldened 225 // update FreeType2 glyph slot with glyph emboldened
221 void emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph); 226 void emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph);
(...skipping 518 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 FT_Error err = FT_Get_Kerning(face, glyphs[i], glyphs[i+1], 745 FT_Error err = FT_Get_Kerning(face, glyphs[i], glyphs[i+1],
741 FT_KERNING_UNSCALED, &delta); 746 FT_KERNING_UNSCALED, &delta);
742 if (err) { 747 if (err) {
743 return false; 748 return false;
744 } 749 }
745 adjustments[i] = delta.x; 750 adjustments[i] = delta.x;
746 } 751 }
747 return true; 752 return true;
748 } 753 }
749 754
755 /** Returns the bitmap strike equal to or just larger than the requested size. * /
750 static FT_Int chooseBitmapStrike(FT_Face face, FT_F26Dot6 scaleY) { 756 static FT_Int chooseBitmapStrike(FT_Face face, FT_F26Dot6 scaleY) {
751 // early out if face is bad
752 if (face == nullptr) { 757 if (face == nullptr) {
753 SkDEBUGF(("chooseBitmapStrike aborted due to nullptr face\n")); 758 SkDEBUGF(("chooseBitmapStrike aborted due to nullptr face.\n"));
754 return -1; 759 return -1;
755 } 760 }
756 // determine target ppem 761
757 FT_Pos targetPPEM = scaleY; 762 FT_Pos requestedPPEM = scaleY; // FT_Bitmap_Size::y_ppem is in 26.6 format.
758 // find a bitmap strike equal to or just larger than the requested size
759 FT_Int chosenStrikeIndex = -1; 763 FT_Int chosenStrikeIndex = -1;
760 FT_Pos chosenPPEM = 0; 764 FT_Pos chosenPPEM = 0;
761 for (FT_Int strikeIndex = 0; strikeIndex < face->num_fixed_sizes; ++strikeIn dex) { 765 for (FT_Int strikeIndex = 0; strikeIndex < face->num_fixed_sizes; ++strikeIn dex) {
762 FT_Pos thisPPEM = face->available_sizes[strikeIndex].y_ppem; 766 FT_Pos strikePPEM = face->available_sizes[strikeIndex].y_ppem;
763 if (thisPPEM == targetPPEM) { 767 if (strikePPEM == requestedPPEM) {
764 // exact match - our search stops here 768 // exact match - our search stops here
765 chosenPPEM = thisPPEM; 769 return strikeIndex;
766 chosenStrikeIndex = strikeIndex; 770 } else if (chosenPPEM < requestedPPEM) {
767 break;
768 } else if (chosenPPEM < targetPPEM) {
769 // attempt to increase chosenPPEM 771 // attempt to increase chosenPPEM
770 if (thisPPEM > chosenPPEM) { 772 if (chosenPPEM < strikePPEM) {
771 chosenPPEM = thisPPEM; 773 chosenPPEM = strikePPEM;
772 chosenStrikeIndex = strikeIndex; 774 chosenStrikeIndex = strikeIndex;
773 } 775 }
774 } else { 776 } else {
775 // attempt to decrease chosenPPEM, but not below targetPPEM 777 // attempt to decrease chosenPPEM, but not below requestedPPEM
776 if (thisPPEM < chosenPPEM && thisPPEM > targetPPEM) { 778 if (requestedPPEM < strikePPEM && strikePPEM < chosenPPEM) {
777 chosenPPEM = thisPPEM; 779 chosenPPEM = strikePPEM;
778 chosenStrikeIndex = strikeIndex; 780 chosenStrikeIndex = strikeIndex;
779 } 781 }
780 } 782 }
781 } 783 }
782 if (chosenStrikeIndex != -1) {
783 // use the chosen strike
784 FT_Error err = FT_Select_Size(face, chosenStrikeIndex);
785 if (err != 0) {
786 SkDEBUGF(("FT_Select_Size(%s, %d) returned 0x%x\n", face->family_nam e,
787 chosenStrikeIndex, err));
788 chosenStrikeIndex = -1;
789 }
790 }
791 return chosenStrikeIndex; 784 return chosenStrikeIndex;
792 } 785 }
793 786
794 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, 787 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface,
795 const SkScalerContextEffects& effects, 788 const SkScalerContextEffects& effects,
796 const SkDescriptor* desc) 789 const SkDescriptor* desc)
797 : SkScalerContext_FreeType_Base(typeface, effects, desc) 790 : SkScalerContext_FreeType_Base(typeface, effects, desc)
798 , fFace(nullptr) 791 , fFace(nullptr)
799 , fFTSize(nullptr) 792 , fFTSize(nullptr)
800 , fStrikeIndex(-1) 793 , fStrikeIndex(-1)
801 { 794 {
802 SkAutoMutexAcquire ac(gFTMutex); 795 SkAutoMutexAcquire ac(gFTMutex);
803 796
804 if (!ref_ft_library()) { 797 if (!ref_ft_library()) {
805 sk_throw(); 798 sk_throw();
806 } 799 }
807 800
808 // load the font file 801 // load the font file
809 using UnrefFTFace = SkFunctionWrapper<void, skstd::remove_pointer_t<FT_Face> , unref_ft_face>; 802 using UnrefFTFace = SkFunctionWrapper<void, skstd::remove_pointer_t<FT_Face> , unref_ft_face>;
810 std::unique_ptr<skstd::remove_pointer_t<FT_Face>, UnrefFTFace> ftFace(ref_ft _face(typeface)); 803 std::unique_ptr<skstd::remove_pointer_t<FT_Face>, UnrefFTFace> ftFace(ref_ft _face(typeface));
811 if (nullptr == ftFace) { 804 if (nullptr == ftFace) {
812 SkDEBUGF(("Could not create FT_Face.\n")); 805 SkDEBUGF(("Could not create FT_Face.\n"));
813 return; 806 return;
814 } 807 }
815 808
816 fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMa trix22Scalar); 809 fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMa trix22Scalar);
817 fMatrix22Scalar.setSkewX(-fMatrix22Scalar.getSkewX());
818 fMatrix22Scalar.setSkewY(-fMatrix22Scalar.getSkewY());
819 810
820 fScaleX = SkScalarToFDot6(fScale.fX); 811 FT_F26Dot6 scaleX = SkScalarToFDot6(fScale.fX);
821 fScaleY = SkScalarToFDot6(fScale.fY); 812 FT_F26Dot6 scaleY = SkScalarToFDot6(fScale.fY);
822 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX()); 813 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
823 fMatrix22.xy = SkScalarToFixed(fMatrix22Scalar.getSkewX()); 814 fMatrix22.xy = SkScalarToFixed(-fMatrix22Scalar.getSkewX());
824 fMatrix22.yx = SkScalarToFixed(fMatrix22Scalar.getSkewY()); 815 fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY());
825 fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY()); 816 fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
826 817
827 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag); 818 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
828 819
829 // compute the flags we send to Load_Glyph 820 // compute the flags we send to Load_Glyph
830 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPositi oning_Flag); 821 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPositi oning_Flag);
831 { 822 {
832 FT_Int32 loadFlags = FT_LOAD_DEFAULT; 823 FT_Int32 loadFlags = FT_LOAD_DEFAULT;
833 824
834 if (SkMask::kBW_Format == fRec.fMaskFormat) { 825 if (SkMask::kBW_Format == fRec.fMaskFormat) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
893 loadFlags |= FT_LOAD_COLOR; 884 loadFlags |= FT_LOAD_COLOR;
894 885
895 fLoadGlyphFlags = loadFlags; 886 fLoadGlyphFlags = loadFlags;
896 } 887 }
897 888
898 using DoneFTSize = SkFunctionWrapper<FT_Error, skstd::remove_pointer_t<FT_Si ze>, FT_Done_Size>; 889 using DoneFTSize = SkFunctionWrapper<FT_Error, skstd::remove_pointer_t<FT_Si ze>, FT_Done_Size>;
899 std::unique_ptr<skstd::remove_pointer_t<FT_Size>, DoneFTSize> ftSize([&ftFac e]() -> FT_Size { 890 std::unique_ptr<skstd::remove_pointer_t<FT_Size>, DoneFTSize> ftSize([&ftFac e]() -> FT_Size {
900 FT_Size size; 891 FT_Size size;
901 FT_Error err = FT_New_Size(ftFace.get(), &size); 892 FT_Error err = FT_New_Size(ftFace.get(), &size);
902 if (err != 0) { 893 if (err != 0) {
903 SkDEBUGF(("FT_New_Size returned %x for face %s\n", err, ftFace->fami ly_name)); 894 SkDEBUGF(("FT_New_Size(%s) returned 0x%x.\n", ftFace->family_name, e rr));
904 return nullptr; 895 return nullptr;
905 } 896 }
906 return size; 897 return size;
907 }()); 898 }());
908 if (nullptr == ftSize) { 899 if (nullptr == ftSize) {
909 SkDEBUGF(("Could not create FT_Size.\n")); 900 SkDEBUGF(("Could not create FT_Size.\n"));
910 return; 901 return;
911 } 902 }
912 903
913 FT_Error err = FT_Activate_Size(ftSize.get()); 904 FT_Error err = FT_Activate_Size(ftSize.get());
914 if (err != 0) { 905 if (err != 0) {
915 SkDEBUGF(("FT_Activate_Size(%08x, 0x%x, 0x%x) returned 0x%x\n", 906 SkDEBUGF(("FT_Activate_Size(%s) returned 0x%x.\n", ftFace->family_name, err));
916 ftFace.get(), fScaleX, fScaleY, err));
917 return; 907 return;
918 } 908 }
919 909
920 if (FT_IS_SCALABLE(ftFace)) { 910 if (FT_IS_SCALABLE(ftFace)) {
921 err = FT_Set_Char_Size(ftFace.get(), fScaleX, fScaleY, 72, 72); 911 err = FT_Set_Char_Size(ftFace.get(), scaleX, scaleY, 72, 72);
922 if (err != 0) { 912 if (err != 0) {
923 SkDEBUGF(("FT_Set_CharSize(%08x, 0x%x, 0x%x) returned 0x%x\n", 913 SkDEBUGF(("FT_Set_CharSize(%s, %f, %f) returned 0x%x.\n",
924 ftFace.get(), fScaleX, fScaleY, err)); 914 ftFace->family_name, fScale.fX, fScale.fY, err));
925 return; 915 return;
926 } 916 }
927 FT_Set_Transform(ftFace.get(), &fMatrix22, nullptr);
928 } else if (FT_HAS_FIXED_SIZES(ftFace)) { 917 } else if (FT_HAS_FIXED_SIZES(ftFace)) {
929 fStrikeIndex = chooseBitmapStrike(ftFace.get(), fScaleY); 918 fStrikeIndex = chooseBitmapStrike(ftFace.get(), scaleY);
930 if (fStrikeIndex == -1) { 919 if (fStrikeIndex == -1) {
931 SkDEBUGF(("no glyphs for font \"%s\" size %f?\n", 920 SkDEBUGF(("No glyphs for font \"%s\" size %f.\n", ftFace->family_nam e, fScale.fY));
932 ftFace->family_name, SkFDot6ToScalar(fScaleY))) ; 921 return;
933 } else { 922 }
934 // FreeType does no provide linear metrics for bitmap fonts.
935 linearMetrics = false;
936 923
937 // FreeType documentation says: 924 err = FT_Select_Size(ftFace.get(), fStrikeIndex);
938 // FT_LOAD_NO_BITMAP -- Ignore bitmap strikes when loading. 925 if (err != 0) {
939 // Bitmap-only fonts ignore this flag. 926 SkDEBUGF(("FT_Select_Size(%s, %d) returned 0x%x.\n",
940 // 927 ftFace->family_name, fStrikeIndex, err));
941 // However, in FreeType 2.5.1 color bitmap only fonts do not ignore this flag. 928 fStrikeIndex = -1;
942 // Force this flag off for bitmap only fonts. 929 return;
943 fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP;
944 } 930 }
931
932 // A non-ideal size was picked, so recompute the matrix.
933 // This adjusts for the difference between FT_Set_Char_Size and FT_Selec t_Size.
934 fMatrix22Scalar.preScale(fScale.x() / ftFace->size->metrics.x_ppem,
935 fScale.y() / ftFace->size->metrics.y_ppem);
936 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
937 fMatrix22.xy = SkScalarToFixed(-fMatrix22Scalar.getSkewX());
938 fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY());
939 fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
940
941 // FreeType does not provide linear metrics for bitmap fonts.
942 linearMetrics = false;
943
944 // FreeType documentation says:
945 // FT_LOAD_NO_BITMAP -- Ignore bitmap strikes when loading.
946 // Bitmap-only fonts ignore this flag.
947 //
948 // However, in FreeType 2.5.1 color bitmap only fonts do not ignore this flag.
949 // Force this flag off for bitmap only fonts.
950 fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP;
945 } else { 951 } else {
946 SkDEBUGF(("unknown kind of font \"%s\" size %f?\n", 952 SkDEBUGF(("Unknown kind of font \"%s\" size %f.\n", fFace->family_name, fScale.fY));
947 fFace->family_name, SkFDot6ToScalar(fScaleY))); 953 return;
948 } 954 }
949 955
950 fFTSize = ftSize.release(); 956 fFTSize = ftSize.release();
951 fFace = ftFace.release(); 957 fFace = ftFace.release();
952 fDoLinearMetrics = linearMetrics; 958 fDoLinearMetrics = linearMetrics;
953 } 959 }
954 960
955 SkScalerContext_FreeType::~SkScalerContext_FreeType() { 961 SkScalerContext_FreeType::~SkScalerContext_FreeType() {
956 SkAutoMutexAcquire ac(gFTMutex); 962 SkAutoMutexAcquire ac(gFTMutex);
957 963
958 if (fFTSize != nullptr) { 964 if (fFTSize != nullptr) {
959 FT_Done_Size(fFTSize); 965 FT_Done_Size(fFTSize);
960 } 966 }
961 967
962 if (fFace != nullptr) { 968 if (fFace != nullptr) {
963 unref_ft_face(fFace); 969 unref_ft_face(fFace);
964 } 970 }
965 971
966 unref_ft_library(); 972 unref_ft_library();
967 } 973 }
968 974
969 /* We call this before each use of the fFace, since we may be sharing 975 /* We call this before each use of the fFace, since we may be sharing
970 this face with other context (at different sizes). 976 this face with other context (at different sizes).
971 */ 977 */
972 FT_Error SkScalerContext_FreeType::setupSize() { 978 FT_Error SkScalerContext_FreeType::setupSize() {
973 gFTMutex.assertHeld(); 979 gFTMutex.assertHeld();
974 FT_Error err = FT_Activate_Size(fFTSize); 980 FT_Error err = FT_Activate_Size(fFTSize);
975 if (err != 0) { 981 if (err != 0) {
976 SkDEBUGF(("SkScalerContext_FreeType::FT_Activate_Size(%s %s, 0x%x, 0x%x) returned 0x%x\n",
977 fFace->family_name, fFace->style_name, fScaleX, fScaleY, err)) ;
978 fFTSize = nullptr;
979 return err; 982 return err;
980 } 983 }
981
982 // seems we need to reset this every time (not sure why, but without it
983 // I get random italics from some other fFTSize)
984 FT_Set_Transform(fFace, &fMatrix22, nullptr); 984 FT_Set_Transform(fFace, &fMatrix22, nullptr);
985 return 0; 985 return 0;
986 } 986 }
987 987
988 unsigned SkScalerContext_FreeType::generateGlyphCount() { 988 unsigned SkScalerContext_FreeType::generateGlyphCount() {
989 return fFace->num_glyphs; 989 return fFace->num_glyphs;
990 } 990 }
991 991
992 uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) { 992 uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) {
993 SkAutoMutexAcquire ac(gFTMutex); 993 SkAutoMutexAcquire ac(gFTMutex);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1030 FT_Fixed advance; 1030 FT_Fixed advance;
1031 1031
1032 error = FT_Get_Advance( fFace, glyph->getGlyphID(), 1032 error = FT_Get_Advance( fFace, glyph->getGlyphID(),
1033 fLoadGlyphFlags | FT_ADVANCE_FLAG_FAST_ONLY, 1033 fLoadGlyphFlags | FT_ADVANCE_FLAG_FAST_ONLY,
1034 &advance ); 1034 &advance );
1035 if (0 == error) { 1035 if (0 == error) {
1036 glyph->fRsbDelta = 0; 1036 glyph->fRsbDelta = 0;
1037 glyph->fLsbDelta = 0; 1037 glyph->fLsbDelta = 0;
1038 const SkScalar advanceScalar = SkFT_FixedToScalar(advance); 1038 const SkScalar advanceScalar = SkFT_FixedToScalar(advance);
1039 glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getScaleX() * adv anceScalar); 1039 glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getScaleX() * adv anceScalar);
1040 glyph->fAdvanceY = -SkScalarToFloat(fMatrix22Scalar.getSkewY() * adv anceScalar); 1040 glyph->fAdvanceY = SkScalarToFloat(fMatrix22Scalar.getSkewY() * adva nceScalar);
1041 return; 1041 return;
1042 } 1042 }
1043 } 1043 }
1044 1044
1045 /* otherwise, we need to load/hint the glyph, which is slower */ 1045 /* otherwise, we need to load/hint the glyph, which is slower */
1046 this->generateMetrics(glyph); 1046 this->generateMetrics(glyph);
1047 return; 1047 return;
1048 } 1048 }
1049 1049
1050 void SkScalerContext_FreeType::getBBoxForCurrentGlyph(SkGlyph* glyph, 1050 void SkScalerContext_FreeType::getBBoxForCurrentGlyph(SkGlyph* glyph,
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1104 if (fLCDIsVert) { 1104 if (fLCDIsVert) {
1105 glyph->fHeight += gFTLibrary->lcdExtra(); 1105 glyph->fHeight += gFTLibrary->lcdExtra();
1106 glyph->fTop -= gFTLibrary->lcdExtra() >> 1; 1106 glyph->fTop -= gFTLibrary->lcdExtra() >> 1;
1107 } else { 1107 } else {
1108 glyph->fWidth += gFTLibrary->lcdExtra(); 1108 glyph->fWidth += gFTLibrary->lcdExtra();
1109 glyph->fLeft -= gFTLibrary->lcdExtra() >> 1; 1109 glyph->fLeft -= gFTLibrary->lcdExtra() >> 1;
1110 } 1110 }
1111 } 1111 }
1112 } 1112 }
1113 1113
1114 inline void scaleGlyphMetrics(SkGlyph& glyph, SkScalar scale) {
1115 glyph.fWidth *= scale;
1116 glyph.fHeight *= scale;
1117 glyph.fTop *= scale;
1118 glyph.fLeft *= scale;
1119
1120 float floatScale = SkScalarToFloat(scale);
1121 glyph.fAdvanceX *= floatScale;
1122 glyph.fAdvanceY *= floatScale;
1123 }
1124
1125 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { 1114 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
1126 SkAutoMutexAcquire ac(gFTMutex); 1115 SkAutoMutexAcquire ac(gFTMutex);
1127 1116
1128 glyph->fRsbDelta = 0; 1117 glyph->fRsbDelta = 0;
1129 glyph->fLsbDelta = 0; 1118 glyph->fLsbDelta = 0;
1130 1119
1131 FT_Error err; 1120 FT_Error err;
1132 1121
1133 if (this->setupSize()) { 1122 if (this->setupSize()) {
1134 glyph->zeroMetrics(); 1123 glyph->zeroMetrics();
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY; 1158 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY;
1170 FT_Vector_Transform(&vector, &fMatrix22); 1159 FT_Vector_Transform(&vector, &fMatrix22);
1171 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x); 1160 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x);
1172 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y); 1161 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y);
1173 } 1162 }
1174 1163
1175 if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { 1164 if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) {
1176 glyph->fMaskFormat = SkMask::kARGB32_Format; 1165 glyph->fMaskFormat = SkMask::kARGB32_Format;
1177 } 1166 }
1178 1167
1179 glyph->fWidth = SkToU16(fFace->glyph->bitmap.width); 1168 {
1180 glyph->fHeight = SkToU16(fFace->glyph->bitmap.rows); 1169 SkRect rect = SkRect::MakeXYWH(SkIntToScalar(fFace->glyph->bitmap_le ft),
1181 glyph->fTop = -SkToS16(fFace->glyph->bitmap_top); 1170 -SkIntToScalar(fFace->glyph->bitmap_to p),
1182 glyph->fLeft = SkToS16(fFace->glyph->bitmap_left); 1171 SkIntToScalar(fFace->glyph->bitmap.wi dth),
1172 SkIntToScalar(fFace->glyph->bitmap.ro ws));
1173 fMatrix22Scalar.mapRect(&rect);
1174 SkIRect irect = rect.roundOut();
1175 glyph->fWidth = SkToU16(irect.width());
1176 glyph->fHeight = SkToU16(irect.height());
1177 glyph->fTop = SkToS16(irect.top());
1178 glyph->fLeft = SkToS16(irect.left());
1179 }
1183 break; 1180 break;
1184 1181
1185 default: 1182 default:
1186 SkDEBUGFAIL("unknown glyph format"); 1183 SkDEBUGFAIL("unknown glyph format");
1187 glyph->zeroMetrics(); 1184 glyph->zeroMetrics();
1188 return; 1185 return;
1189 } 1186 }
1190 1187
1191 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 1188 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
1192 if (fDoLinearMetrics) { 1189 if (fDoLinearMetrics) {
1193 const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->line arVertAdvance); 1190 const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->line arVertAdvance);
1194 glyph->fAdvanceX = -SkScalarToFloat(fMatrix22Scalar.getSkewX() * adv anceScalar); 1191 glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getSkewX() * adva nceScalar);
1195 glyph->fAdvanceY = SkScalarToFloat(fMatrix22Scalar.getScaleY() * adv anceScalar); 1192 glyph->fAdvanceY = SkScalarToFloat(fMatrix22Scalar.getScaleY() * adv anceScalar);
1196 } else { 1193 } else {
1197 glyph->fAdvanceX = -SkFDot6ToFloat(fFace->glyph->advance.x); 1194 glyph->fAdvanceX = -SkFDot6ToFloat(fFace->glyph->advance.x);
1198 glyph->fAdvanceY = SkFDot6ToFloat(fFace->glyph->advance.y); 1195 glyph->fAdvanceY = SkFDot6ToFloat(fFace->glyph->advance.y);
1199 } 1196 }
1200 } else { 1197 } else {
1201 if (fDoLinearMetrics) { 1198 if (fDoLinearMetrics) {
1202 const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->line arHoriAdvance); 1199 const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->line arHoriAdvance);
1203 glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getScaleX() * adv anceScalar); 1200 glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getScaleX() * adv anceScalar);
1204 glyph->fAdvanceY = -SkScalarToFloat(fMatrix22Scalar.getSkewY() * adv anceScalar); 1201 glyph->fAdvanceY = SkScalarToFloat(fMatrix22Scalar.getSkewY() * adva nceScalar);
1205 } else { 1202 } else {
1206 glyph->fAdvanceX = SkFDot6ToFloat(fFace->glyph->advance.x); 1203 glyph->fAdvanceX = SkFDot6ToFloat(fFace->glyph->advance.x);
1207 glyph->fAdvanceY = -SkFDot6ToFloat(fFace->glyph->advance.y); 1204 glyph->fAdvanceY = -SkFDot6ToFloat(fFace->glyph->advance.y);
1208 1205
1209 if (fRec.fFlags & kDevKernText_Flag) { 1206 if (fRec.fFlags & kDevKernText_Flag) {
1210 glyph->fRsbDelta = SkToS8(fFace->glyph->rsb_delta); 1207 glyph->fRsbDelta = SkToS8(fFace->glyph->rsb_delta);
1211 glyph->fLsbDelta = SkToS8(fFace->glyph->lsb_delta); 1208 glyph->fLsbDelta = SkToS8(fFace->glyph->lsb_delta);
1212 } 1209 }
1213 } 1210 }
1214 } 1211 }
1215 1212
1216 // If the font isn't scalable, scale the metrics from the non-scalable strik e.
1217 // This means do not try to scale embedded bitmaps; only scale bitmaps in bi tmap only fonts.
1218 if (!FT_IS_SCALABLE(fFace) && !SkScalarNearlyZero(fScale.fY) && fFace->size- >metrics.y_ppem) {
1219 // NOTE: both dimensions are scaled by y_ppem. this is WAI.
1220 scaleGlyphMetrics(*glyph, fScale.fY / fFace->size->metrics.y_ppem);
1221 }
1222
1223 #ifdef ENABLE_GLYPH_SPEW 1213 #ifdef ENABLE_GLYPH_SPEW
1224 SkDEBUGF(("FT_Set_Char_Size(this:%p sx:%x sy:%x ", this, fScaleX, fScaleY));
1225 SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(), fLoadG lyphFlags, glyph->fWidth)); 1214 SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(), fLoadG lyphFlags, glyph->fWidth));
1226 #endif 1215 #endif
1227 } 1216 }
1228 1217
1229 static void clear_glyph_image(const SkGlyph& glyph) { 1218 static void clear_glyph_image(const SkGlyph& glyph) {
1230 sk_bzero(glyph.fImage, glyph.rowBytes() * glyph.fHeight); 1219 sk_bzero(glyph.fImage, glyph.rowBytes() * glyph.fHeight);
1231 } 1220 }
1232 1221
1233 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { 1222 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
1234 SkAutoMutexAcquire ac(gFTMutex); 1223 SkAutoMutexAcquire ac(gFTMutex);
1235 1224
1236 if (this->setupSize()) { 1225 if (this->setupSize()) {
1237 clear_glyph_image(glyph); 1226 clear_glyph_image(glyph);
1238 return; 1227 return;
1239 } 1228 }
1240 1229
1241 FT_Error err = FT_Load_Glyph(fFace, glyph.getGlyphID(), fLoadGlyphFlags); 1230 FT_Error err = FT_Load_Glyph(fFace, glyph.getGlyphID(), fLoadGlyphFlags);
1242 if (err != 0) { 1231 if (err != 0) {
1243 SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph: %d width:%d height:%d rb:%d flags:%d) returned 0x%x\n", 1232 SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph: %d width:%d height:%d rb:%d flags:%d) returned 0x%x\n",
1244 glyph.getGlyphID(), glyph.fWidth, glyph.fHeight, glyph.rowByte s(), fLoadGlyphFlags, err)); 1233 glyph.getGlyphID(), glyph.fWidth, glyph.fHeight, glyph.rowByte s(), fLoadGlyphFlags, err));
1245 clear_glyph_image(glyph); 1234 clear_glyph_image(glyph);
1246 return; 1235 return;
1247 } 1236 }
1248 1237
1249 emboldenIfNeeded(fFace, fFace->glyph); 1238 emboldenIfNeeded(fFace, fFace->glyph);
1250 generateGlyphImage(fFace, glyph); 1239 generateGlyphImage(fFace, glyph, fMatrix22Scalar);
1251 } 1240 }
1252 1241
1253 1242
1254 void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, SkPath* path) { 1243 void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, SkPath* path) {
1255 SkAutoMutexAcquire ac(gFTMutex); 1244 SkAutoMutexAcquire ac(gFTMutex);
1256 1245
1257 SkASSERT(path); 1246 SkASSERT(path);
1258 1247
1259 if (this->setupSize()) { 1248 if (this->setupSize()) {
1260 path->reset(); 1249 path->reset();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1296 SkAutoMutexAcquire ac(gFTMutex); 1285 SkAutoMutexAcquire ac(gFTMutex);
1297 1286
1298 if (this->setupSize()) { 1287 if (this->setupSize()) {
1299 sk_bzero(metrics, sizeof(*metrics)); 1288 sk_bzero(metrics, sizeof(*metrics));
1300 return; 1289 return;
1301 } 1290 }
1302 1291
1303 FT_Face face = fFace; 1292 FT_Face face = fFace;
1304 SkScalar scaleX = fScale.x(); 1293 SkScalar scaleX = fScale.x();
1305 SkScalar scaleY = fScale.y(); 1294 SkScalar scaleY = fScale.y();
1306 SkScalar mxy = fMatrix22Scalar.getSkewX() * scaleY; 1295 SkScalar mxy = -fMatrix22Scalar.getSkewX() * scaleY;
1307 SkScalar myy = fMatrix22Scalar.getScaleY() * scaleY; 1296 SkScalar myy = fMatrix22Scalar.getScaleY() * scaleY;
1308 1297
1309 // fetch units/EM from "head" table if needed (ie for bitmap fonts) 1298 // fetch units/EM from "head" table if needed (ie for bitmap fonts)
1310 SkScalar upem = SkIntToScalar(face->units_per_EM); 1299 SkScalar upem = SkIntToScalar(face->units_per_EM);
1311 if (!upem) { 1300 if (!upem) {
1312 TT_Header* ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head); 1301 TT_Header* ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head);
1313 if (ttHeader) { 1302 if (ttHeader) {
1314 upem = SkIntToScalar(ttHeader->Units_Per_EM); 1303 upem = SkIntToScalar(ttHeader->Units_Per_EM);
1315 } 1304 }
1316 } 1305 }
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1818 SkDEBUGF(("Requested font axis not found: %s '%c%c%c%c'\n", 1807 SkDEBUGF(("Requested font axis not found: %s '%c%c%c%c'\n",
1819 name.c_str(), 1808 name.c_str(),
1820 (skTag >> 24) & 0xFF, 1809 (skTag >> 24) & 0xFF,
1821 (skTag >> 16) & 0xFF, 1810 (skTag >> 16) & 0xFF,
1822 (skTag >> 8) & 0xFF, 1811 (skTag >> 8) & 0xFF,
1823 (skTag) & 0xFF)); 1812 (skTag) & 0xFF));
1824 } 1813 }
1825 } 1814 }
1826 ) 1815 )
1827 } 1816 }
OLDNEW
« no previous file with comments | « no previous file | src/ports/SkFontHost_FreeType_common.h » ('j') | src/ports/SkFontHost_FreeType_common.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698