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

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

Issue 2149253005: Revert of Rotate emoji with FreeType. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: 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
« no previous file with comments | « no previous file | src/ports/SkFontHost_FreeType_common.h » ('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 * 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; // Shared face from gFaceRecHead. 200 FT_Face fFace; // reference to shared face in gFaceRecHead
201 FT_Size fFTSize; // The size on the fFace for this scaler. 201 FT_Size fFTSize; // our own copy
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;
203 208
204 /** The rest of the matrix after FreeType handles the size. 209 // Need scalar versions for generateFontMetrics
205 * With outline font rasterization this is handled by FreeType with FT_Set_ Transform. 210 SkVector fScale;
206 * With bitmap only fonts this matrix must be applied to scale the bitmap. 211 SkMatrix fMatrix22Scalar;
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;
217 212
218 FT_Error setupSize(); 213 FT_Error setupSize();
219 void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox, 214 void getBBoxForCurrentGlyph(SkGlyph* glyph, FT_BBox* bbox,
220 bool snapToPixelBoundary = false); 215 bool snapToPixelBoundary = false);
221 bool getCBoxForLetter(char letter, FT_BBox* bbox); 216 bool getCBoxForLetter(char letter, FT_BBox* bbox);
222 // Caller must lock gFTMutex before calling this function. 217 // Caller must lock gFTMutex before calling this function.
223 void updateGlyphIfLCD(SkGlyph* glyph); 218 void updateGlyphIfLCD(SkGlyph* glyph);
224 // Caller must lock gFTMutex before calling this function. 219 // Caller must lock gFTMutex before calling this function.
225 // update FreeType2 glyph slot with glyph emboldened 220 // update FreeType2 glyph slot with glyph emboldened
226 void emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph); 221 void emboldenIfNeeded(FT_Face face, FT_GlyphSlot glyph);
227 bool shouldSubpixelBitmap(const SkGlyph&, const SkMatrix&);
228 }; 222 };
229 223
230 /////////////////////////////////////////////////////////////////////////// 224 ///////////////////////////////////////////////////////////////////////////
231 /////////////////////////////////////////////////////////////////////////// 225 ///////////////////////////////////////////////////////////////////////////
232 226
233 struct SkFaceRec { 227 struct SkFaceRec {
234 SkFaceRec* fNext; 228 SkFaceRec* fNext;
235 FT_Face fFace; 229 FT_Face fFace;
236 FT_StreamRec fFTStream; 230 FT_StreamRec fFTStream;
237 SkAutoTDelete<SkStreamAsset> fSkStream; 231 SkAutoTDelete<SkStreamAsset> fSkStream;
(...skipping 508 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 FT_Error err = FT_Get_Kerning(face, glyphs[i], glyphs[i+1], 740 FT_Error err = FT_Get_Kerning(face, glyphs[i], glyphs[i+1],
747 FT_KERNING_UNSCALED, &delta); 741 FT_KERNING_UNSCALED, &delta);
748 if (err) { 742 if (err) {
749 return false; 743 return false;
750 } 744 }
751 adjustments[i] = delta.x; 745 adjustments[i] = delta.x;
752 } 746 }
753 return true; 747 return true;
754 } 748 }
755 749
756 /** Returns the bitmap strike equal to or just larger than the requested size. * /
757 static FT_Int chooseBitmapStrike(FT_Face face, FT_F26Dot6 scaleY) { 750 static FT_Int chooseBitmapStrike(FT_Face face, FT_F26Dot6 scaleY) {
751 // early out if face is bad
758 if (face == nullptr) { 752 if (face == nullptr) {
759 SkDEBUGF(("chooseBitmapStrike aborted due to nullptr face.\n")); 753 SkDEBUGF(("chooseBitmapStrike aborted due to nullptr face\n"));
760 return -1; 754 return -1;
761 } 755 }
762 756 // determine target ppem
763 FT_Pos requestedPPEM = scaleY; // FT_Bitmap_Size::y_ppem is in 26.6 format. 757 FT_Pos targetPPEM = scaleY;
758 // find a bitmap strike equal to or just larger than the requested size
764 FT_Int chosenStrikeIndex = -1; 759 FT_Int chosenStrikeIndex = -1;
765 FT_Pos chosenPPEM = 0; 760 FT_Pos chosenPPEM = 0;
766 for (FT_Int strikeIndex = 0; strikeIndex < face->num_fixed_sizes; ++strikeIn dex) { 761 for (FT_Int strikeIndex = 0; strikeIndex < face->num_fixed_sizes; ++strikeIn dex) {
767 FT_Pos strikePPEM = face->available_sizes[strikeIndex].y_ppem; 762 FT_Pos thisPPEM = face->available_sizes[strikeIndex].y_ppem;
768 if (strikePPEM == requestedPPEM) { 763 if (thisPPEM == targetPPEM) {
769 // exact match - our search stops here 764 // exact match - our search stops here
770 return strikeIndex; 765 chosenPPEM = thisPPEM;
771 } else if (chosenPPEM < requestedPPEM) { 766 chosenStrikeIndex = strikeIndex;
767 break;
768 } else if (chosenPPEM < targetPPEM) {
772 // attempt to increase chosenPPEM 769 // attempt to increase chosenPPEM
773 if (chosenPPEM < strikePPEM) { 770 if (thisPPEM > chosenPPEM) {
774 chosenPPEM = strikePPEM; 771 chosenPPEM = thisPPEM;
775 chosenStrikeIndex = strikeIndex; 772 chosenStrikeIndex = strikeIndex;
776 } 773 }
777 } else { 774 } else {
778 // attempt to decrease chosenPPEM, but not below requestedPPEM 775 // attempt to decrease chosenPPEM, but not below targetPPEM
779 if (requestedPPEM < strikePPEM && strikePPEM < chosenPPEM) { 776 if (thisPPEM < chosenPPEM && thisPPEM > targetPPEM) {
780 chosenPPEM = strikePPEM; 777 chosenPPEM = thisPPEM;
781 chosenStrikeIndex = strikeIndex; 778 chosenStrikeIndex = strikeIndex;
782 } 779 }
783 } 780 }
784 } 781 }
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 }
785 return chosenStrikeIndex; 791 return chosenStrikeIndex;
786 } 792 }
787 793
788 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, 794 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface,
789 const SkScalerContextEffects& effects, 795 const SkScalerContextEffects& effects,
790 const SkDescriptor* desc) 796 const SkDescriptor* desc)
791 : SkScalerContext_FreeType_Base(typeface, effects, desc) 797 : SkScalerContext_FreeType_Base(typeface, effects, desc)
792 , fFace(nullptr) 798 , fFace(nullptr)
793 , fFTSize(nullptr) 799 , fFTSize(nullptr)
794 , fStrikeIndex(-1) 800 , fStrikeIndex(-1)
795 { 801 {
796 SkAutoMutexAcquire ac(gFTMutex); 802 SkAutoMutexAcquire ac(gFTMutex);
797 803
798 if (!ref_ft_library()) { 804 if (!ref_ft_library()) {
799 sk_throw(); 805 sk_throw();
800 } 806 }
801 807
802 // load the font file 808 // load the font file
803 using UnrefFTFace = SkFunctionWrapper<void, skstd::remove_pointer_t<FT_Face> , unref_ft_face>; 809 using UnrefFTFace = SkFunctionWrapper<void, skstd::remove_pointer_t<FT_Face> , unref_ft_face>;
804 std::unique_ptr<skstd::remove_pointer_t<FT_Face>, UnrefFTFace> ftFace(ref_ft _face(typeface)); 810 std::unique_ptr<skstd::remove_pointer_t<FT_Face>, UnrefFTFace> ftFace(ref_ft _face(typeface));
805 if (nullptr == ftFace) { 811 if (nullptr == ftFace) {
806 SkDEBUGF(("Could not create FT_Face.\n")); 812 SkDEBUGF(("Could not create FT_Face.\n"));
807 return; 813 return;
808 } 814 }
809 815
810 fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMa trix22Scalar); 816 fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMa trix22Scalar);
817 fMatrix22Scalar.setSkewX(-fMatrix22Scalar.getSkewX());
818 fMatrix22Scalar.setSkewY(-fMatrix22Scalar.getSkewY());
811 819
812 FT_F26Dot6 scaleX = SkScalarToFDot6(fScale.fX); 820 fScaleX = SkScalarToFDot6(fScale.fX);
813 FT_F26Dot6 scaleY = SkScalarToFDot6(fScale.fY); 821 fScaleY = SkScalarToFDot6(fScale.fY);
814 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX()); 822 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
815 fMatrix22.xy = SkScalarToFixed(-fMatrix22Scalar.getSkewX()); 823 fMatrix22.xy = SkScalarToFixed(fMatrix22Scalar.getSkewX());
816 fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY()); 824 fMatrix22.yx = SkScalarToFixed(fMatrix22Scalar.getSkewY());
817 fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY()); 825 fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
818 826
819 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag); 827 fLCDIsVert = SkToBool(fRec.fFlags & SkScalerContext::kLCD_Vertical_Flag);
820 828
821 // compute the flags we send to Load_Glyph 829 // compute the flags we send to Load_Glyph
822 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPositi oning_Flag); 830 bool linearMetrics = SkToBool(fRec.fFlags & SkScalerContext::kSubpixelPositi oning_Flag);
823 { 831 {
824 FT_Int32 loadFlags = FT_LOAD_DEFAULT; 832 FT_Int32 loadFlags = FT_LOAD_DEFAULT;
825 833
826 if (SkMask::kBW_Format == fRec.fMaskFormat) { 834 if (SkMask::kBW_Format == fRec.fMaskFormat) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
885 loadFlags |= FT_LOAD_COLOR; 893 loadFlags |= FT_LOAD_COLOR;
886 894
887 fLoadGlyphFlags = loadFlags; 895 fLoadGlyphFlags = loadFlags;
888 } 896 }
889 897
890 using DoneFTSize = SkFunctionWrapper<FT_Error, skstd::remove_pointer_t<FT_Si ze>, FT_Done_Size>; 898 using DoneFTSize = SkFunctionWrapper<FT_Error, skstd::remove_pointer_t<FT_Si ze>, FT_Done_Size>;
891 std::unique_ptr<skstd::remove_pointer_t<FT_Size>, DoneFTSize> ftSize([&ftFac e]() -> FT_Size { 899 std::unique_ptr<skstd::remove_pointer_t<FT_Size>, DoneFTSize> ftSize([&ftFac e]() -> FT_Size {
892 FT_Size size; 900 FT_Size size;
893 FT_Error err = FT_New_Size(ftFace.get(), &size); 901 FT_Error err = FT_New_Size(ftFace.get(), &size);
894 if (err != 0) { 902 if (err != 0) {
895 SkDEBUGF(("FT_New_Size(%s) returned 0x%x.\n", ftFace->family_name, e rr)); 903 SkDEBUGF(("FT_New_Size returned %x for face %s\n", err, ftFace->fami ly_name));
896 return nullptr; 904 return nullptr;
897 } 905 }
898 return size; 906 return size;
899 }()); 907 }());
900 if (nullptr == ftSize) { 908 if (nullptr == ftSize) {
901 SkDEBUGF(("Could not create FT_Size.\n")); 909 SkDEBUGF(("Could not create FT_Size.\n"));
902 return; 910 return;
903 } 911 }
904 912
905 FT_Error err = FT_Activate_Size(ftSize.get()); 913 FT_Error err = FT_Activate_Size(ftSize.get());
906 if (err != 0) { 914 if (err != 0) {
907 SkDEBUGF(("FT_Activate_Size(%s) returned 0x%x.\n", ftFace->family_name, err)); 915 SkDEBUGF(("FT_Activate_Size(%08x, 0x%x, 0x%x) returned 0x%x\n",
916 ftFace.get(), fScaleX, fScaleY, err));
908 return; 917 return;
909 } 918 }
910 919
911 if (FT_IS_SCALABLE(ftFace)) { 920 if (FT_IS_SCALABLE(ftFace)) {
912 err = FT_Set_Char_Size(ftFace.get(), scaleX, scaleY, 72, 72); 921 err = FT_Set_Char_Size(ftFace.get(), fScaleX, fScaleY, 72, 72);
913 if (err != 0) { 922 if (err != 0) {
914 SkDEBUGF(("FT_Set_CharSize(%s, %f, %f) returned 0x%x.\n", 923 SkDEBUGF(("FT_Set_CharSize(%08x, 0x%x, 0x%x) returned 0x%x\n",
915 ftFace->family_name, fScale.fX, fScale.fY, err)); 924 ftFace.get(), fScaleX, fScaleY, err));
916 return; 925 return;
917 } 926 }
927 FT_Set_Transform(ftFace.get(), &fMatrix22, nullptr);
918 } else if (FT_HAS_FIXED_SIZES(ftFace)) { 928 } else if (FT_HAS_FIXED_SIZES(ftFace)) {
919 fStrikeIndex = chooseBitmapStrike(ftFace.get(), scaleY); 929 fStrikeIndex = chooseBitmapStrike(ftFace.get(), fScaleY);
920 if (fStrikeIndex == -1) { 930 if (fStrikeIndex == -1) {
921 SkDEBUGF(("No glyphs for font \"%s\" size %f.\n", ftFace->family_nam e, fScale.fY)); 931 SkDEBUGF(("no glyphs for font \"%s\" size %f?\n",
922 return; 932 ftFace->family_name, SkFDot6ToScalar(fScaleY))) ;
933 } else {
934 // FreeType does no provide linear metrics for bitmap fonts.
935 linearMetrics = false;
936
937 // FreeType documentation says:
938 // FT_LOAD_NO_BITMAP -- Ignore bitmap strikes when loading.
939 // Bitmap-only fonts ignore this flag.
940 //
941 // However, in FreeType 2.5.1 color bitmap only fonts do not ignore this flag.
942 // Force this flag off for bitmap only fonts.
943 fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP;
923 } 944 }
924
925 err = FT_Select_Size(ftFace.get(), fStrikeIndex);
926 if (err != 0) {
927 SkDEBUGF(("FT_Select_Size(%s, %d) returned 0x%x.\n",
928 ftFace->family_name, fStrikeIndex, err));
929 fStrikeIndex = -1;
930 return;
931 }
932
933 // A non-ideal size was picked, so recompute the matrix.
934 // This adjusts for the difference between FT_Set_Char_Size and FT_Selec t_Size.
935 fMatrix22Scalar.preScale(fScale.x() / ftFace->size->metrics.x_ppem,
936 fScale.y() / ftFace->size->metrics.y_ppem);
937 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
938 fMatrix22.xy = SkScalarToFixed(-fMatrix22Scalar.getSkewX());
939 fMatrix22.yx = SkScalarToFixed(-fMatrix22Scalar.getSkewY());
940 fMatrix22.yy = SkScalarToFixed(fMatrix22Scalar.getScaleY());
941
942 // FreeType does not provide linear metrics for bitmap fonts.
943 linearMetrics = false;
944
945 // FreeType documentation says:
946 // FT_LOAD_NO_BITMAP -- Ignore bitmap strikes when loading.
947 // Bitmap-only fonts ignore this flag.
948 //
949 // However, in FreeType 2.5.1 color bitmap only fonts do not ignore this flag.
950 // Force this flag off for bitmap only fonts.
951 fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP;
952 } else { 945 } else {
953 SkDEBUGF(("Unknown kind of font \"%s\" size %f.\n", fFace->family_name, fScale.fY)); 946 SkDEBUGF(("unknown kind of font \"%s\" size %f?\n",
954 return; 947 fFace->family_name, SkFDot6ToScalar(fScaleY)));
955 } 948 }
956 949
957 fFTSize = ftSize.release(); 950 fFTSize = ftSize.release();
958 fFace = ftFace.release(); 951 fFace = ftFace.release();
959 fDoLinearMetrics = linearMetrics; 952 fDoLinearMetrics = linearMetrics;
960 } 953 }
961 954
962 SkScalerContext_FreeType::~SkScalerContext_FreeType() { 955 SkScalerContext_FreeType::~SkScalerContext_FreeType() {
963 SkAutoMutexAcquire ac(gFTMutex); 956 SkAutoMutexAcquire ac(gFTMutex);
964 957
965 if (fFTSize != nullptr) { 958 if (fFTSize != nullptr) {
966 FT_Done_Size(fFTSize); 959 FT_Done_Size(fFTSize);
967 } 960 }
968 961
969 if (fFace != nullptr) { 962 if (fFace != nullptr) {
970 unref_ft_face(fFace); 963 unref_ft_face(fFace);
971 } 964 }
972 965
973 unref_ft_library(); 966 unref_ft_library();
974 } 967 }
975 968
976 /* We call this before each use of the fFace, since we may be sharing 969 /* We call this before each use of the fFace, since we may be sharing
977 this face with other context (at different sizes). 970 this face with other context (at different sizes).
978 */ 971 */
979 FT_Error SkScalerContext_FreeType::setupSize() { 972 FT_Error SkScalerContext_FreeType::setupSize() {
980 gFTMutex.assertHeld(); 973 gFTMutex.assertHeld();
981 FT_Error err = FT_Activate_Size(fFTSize); 974 FT_Error err = FT_Activate_Size(fFTSize);
982 if (err != 0) { 975 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;
983 return err; 979 return err;
984 } 980 }
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)
985 FT_Set_Transform(fFace, &fMatrix22, nullptr); 984 FT_Set_Transform(fFace, &fMatrix22, nullptr);
986 return 0; 985 return 0;
987 } 986 }
988 987
989 unsigned SkScalerContext_FreeType::generateGlyphCount() { 988 unsigned SkScalerContext_FreeType::generateGlyphCount() {
990 return fFace->num_glyphs; 989 return fFace->num_glyphs;
991 } 990 }
992 991
993 uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) { 992 uint16_t SkScalerContext_FreeType::generateCharToGlyph(SkUnichar uni) {
994 SkAutoMutexAcquire ac(gFTMutex); 993 SkAutoMutexAcquire ac(gFTMutex);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1031 FT_Fixed advance; 1030 FT_Fixed advance;
1032 1031
1033 error = FT_Get_Advance( fFace, glyph->getGlyphID(), 1032 error = FT_Get_Advance( fFace, glyph->getGlyphID(),
1034 fLoadGlyphFlags | FT_ADVANCE_FLAG_FAST_ONLY, 1033 fLoadGlyphFlags | FT_ADVANCE_FLAG_FAST_ONLY,
1035 &advance ); 1034 &advance );
1036 if (0 == error) { 1035 if (0 == error) {
1037 glyph->fRsbDelta = 0; 1036 glyph->fRsbDelta = 0;
1038 glyph->fLsbDelta = 0; 1037 glyph->fLsbDelta = 0;
1039 const SkScalar advanceScalar = SkFT_FixedToScalar(advance); 1038 const SkScalar advanceScalar = SkFT_FixedToScalar(advance);
1040 glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getScaleX() * adv anceScalar); 1039 glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getScaleX() * adv anceScalar);
1041 glyph->fAdvanceY = SkScalarToFloat(fMatrix22Scalar.getSkewY() * adva nceScalar); 1040 glyph->fAdvanceY = -SkScalarToFloat(fMatrix22Scalar.getSkewY() * adv anceScalar);
1042 return; 1041 return;
1043 } 1042 }
1044 } 1043 }
1045 1044
1046 /* otherwise, we need to load/hint the glyph, which is slower */ 1045 /* otherwise, we need to load/hint the glyph, which is slower */
1047 this->generateMetrics(glyph); 1046 this->generateMetrics(glyph);
1048 return; 1047 return;
1049 } 1048 }
1050 1049
1051 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
1105 if (fLCDIsVert) { 1104 if (fLCDIsVert) {
1106 glyph->fHeight += gFTLibrary->lcdExtra(); 1105 glyph->fHeight += gFTLibrary->lcdExtra();
1107 glyph->fTop -= gFTLibrary->lcdExtra() >> 1; 1106 glyph->fTop -= gFTLibrary->lcdExtra() >> 1;
1108 } else { 1107 } else {
1109 glyph->fWidth += gFTLibrary->lcdExtra(); 1108 glyph->fWidth += gFTLibrary->lcdExtra();
1110 glyph->fLeft -= gFTLibrary->lcdExtra() >> 1; 1109 glyph->fLeft -= gFTLibrary->lcdExtra() >> 1;
1111 } 1110 }
1112 } 1111 }
1113 } 1112 }
1114 1113
1115 bool SkScalerContext_FreeType::shouldSubpixelBitmap(const SkGlyph& glyph, const SkMatrix& matrix) { 1114 inline void scaleGlyphMetrics(SkGlyph& glyph, SkScalar scale) {
1116 // If subpixel rendering of a bitmap *can* be done. 1115 glyph.fWidth *= scale;
1117 bool mechanism = fFace->glyph->format == FT_GLYPH_FORMAT_BITMAP && 1116 glyph.fHeight *= scale;
1118 fRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag && 1117 glyph.fTop *= scale;
1119 (glyph.getSubXFixed() || glyph.getSubYFixed()); 1118 glyph.fLeft *= scale;
1120 1119
1121 // If subpixel rendering of a bitmap *should* be done. 1120 float floatScale = SkScalarToFloat(scale);
1122 // 1. If the face is not scalable then always allow subpixel rendering. 1121 glyph.fAdvanceX *= floatScale;
1123 // Otherwise, if the font has an 8ppem strike 7 will subpixel render but 8 won't. 1122 glyph.fAdvanceY *= floatScale;
1124 // 2. If the matrix is already not identity the bitmap will already be resam pled,
1125 // so resampling slightly differently shouldn't make much difference.
1126 bool policy = !FT_IS_SCALABLE(fFace) || !matrix.isIdentity();
1127
1128 return mechanism && policy;
1129 } 1123 }
1130 1124
1131 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) { 1125 void SkScalerContext_FreeType::generateMetrics(SkGlyph* glyph) {
1132 SkAutoMutexAcquire ac(gFTMutex); 1126 SkAutoMutexAcquire ac(gFTMutex);
1133 1127
1134 glyph->fRsbDelta = 0; 1128 glyph->fRsbDelta = 0;
1135 glyph->fLsbDelta = 0; 1129 glyph->fLsbDelta = 0;
1136 1130
1137 FT_Error err; 1131 FT_Error err;
1138 1132
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1175 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY; 1169 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metri cs.horiBearingY;
1176 FT_Vector_Transform(&vector, &fMatrix22); 1170 FT_Vector_Transform(&vector, &fMatrix22);
1177 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x); 1171 fFace->glyph->bitmap_left += SkFDot6Floor(vector.x);
1178 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y); 1172 fFace->glyph->bitmap_top += SkFDot6Floor(vector.y);
1179 } 1173 }
1180 1174
1181 if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) { 1175 if (fFace->glyph->bitmap.pixel_mode == FT_PIXEL_MODE_BGRA) {
1182 glyph->fMaskFormat = SkMask::kARGB32_Format; 1176 glyph->fMaskFormat = SkMask::kARGB32_Format;
1183 } 1177 }
1184 1178
1185 { 1179 glyph->fWidth = SkToU16(fFace->glyph->bitmap.width);
1186 SkRect rect = SkRect::MakeXYWH(SkIntToScalar(fFace->glyph->bitmap_le ft), 1180 glyph->fHeight = SkToU16(fFace->glyph->bitmap.rows);
1187 -SkIntToScalar(fFace->glyph->bitmap_to p), 1181 glyph->fTop = -SkToS16(fFace->glyph->bitmap_top);
1188 SkIntToScalar(fFace->glyph->bitmap.wi dth), 1182 glyph->fLeft = SkToS16(fFace->glyph->bitmap_left);
1189 SkIntToScalar(fFace->glyph->bitmap.ro ws));
1190 fMatrix22Scalar.mapRect(&rect);
1191 if (this->shouldSubpixelBitmap(*glyph, fMatrix22Scalar)) {
1192 rect.offset(SkFixedToScalar(glyph->getSubXFixed()),
1193 SkFixedToScalar(glyph->getSubYFixed()));
1194 }
1195 SkIRect irect = rect.roundOut();
1196 glyph->fWidth = SkToU16(irect.width());
1197 glyph->fHeight = SkToU16(irect.height());
1198 glyph->fTop = SkToS16(irect.top());
1199 glyph->fLeft = SkToS16(irect.left());
1200 }
1201 break; 1183 break;
1202 1184
1203 default: 1185 default:
1204 SkDEBUGFAIL("unknown glyph format"); 1186 SkDEBUGFAIL("unknown glyph format");
1205 glyph->zeroMetrics(); 1187 glyph->zeroMetrics();
1206 return; 1188 return;
1207 } 1189 }
1208 1190
1209 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 1191 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
1210 if (fDoLinearMetrics) { 1192 if (fDoLinearMetrics) {
1211 const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->line arVertAdvance); 1193 const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->line arVertAdvance);
1212 glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getSkewX() * adva nceScalar); 1194 glyph->fAdvanceX = -SkScalarToFloat(fMatrix22Scalar.getSkewX() * adv anceScalar);
1213 glyph->fAdvanceY = SkScalarToFloat(fMatrix22Scalar.getScaleY() * adv anceScalar); 1195 glyph->fAdvanceY = SkScalarToFloat(fMatrix22Scalar.getScaleY() * adv anceScalar);
1214 } else { 1196 } else {
1215 glyph->fAdvanceX = -SkFDot6ToFloat(fFace->glyph->advance.x); 1197 glyph->fAdvanceX = -SkFDot6ToFloat(fFace->glyph->advance.x);
1216 glyph->fAdvanceY = SkFDot6ToFloat(fFace->glyph->advance.y); 1198 glyph->fAdvanceY = SkFDot6ToFloat(fFace->glyph->advance.y);
1217 } 1199 }
1218 } else { 1200 } else {
1219 if (fDoLinearMetrics) { 1201 if (fDoLinearMetrics) {
1220 const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->line arHoriAdvance); 1202 const SkScalar advanceScalar = SkFT_FixedToScalar(fFace->glyph->line arHoriAdvance);
1221 glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getScaleX() * adv anceScalar); 1203 glyph->fAdvanceX = SkScalarToFloat(fMatrix22Scalar.getScaleX() * adv anceScalar);
1222 glyph->fAdvanceY = SkScalarToFloat(fMatrix22Scalar.getSkewY() * adva nceScalar); 1204 glyph->fAdvanceY = -SkScalarToFloat(fMatrix22Scalar.getSkewY() * adv anceScalar);
1223 } else { 1205 } else {
1224 glyph->fAdvanceX = SkFDot6ToFloat(fFace->glyph->advance.x); 1206 glyph->fAdvanceX = SkFDot6ToFloat(fFace->glyph->advance.x);
1225 glyph->fAdvanceY = -SkFDot6ToFloat(fFace->glyph->advance.y); 1207 glyph->fAdvanceY = -SkFDot6ToFloat(fFace->glyph->advance.y);
1226 1208
1227 if (fRec.fFlags & kDevKernText_Flag) { 1209 if (fRec.fFlags & kDevKernText_Flag) {
1228 glyph->fRsbDelta = SkToS8(fFace->glyph->rsb_delta); 1210 glyph->fRsbDelta = SkToS8(fFace->glyph->rsb_delta);
1229 glyph->fLsbDelta = SkToS8(fFace->glyph->lsb_delta); 1211 glyph->fLsbDelta = SkToS8(fFace->glyph->lsb_delta);
1230 } 1212 }
1231 } 1213 }
1232 } 1214 }
1233 1215
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
1234 #ifdef ENABLE_GLYPH_SPEW 1223 #ifdef ENABLE_GLYPH_SPEW
1224 SkDEBUGF(("FT_Set_Char_Size(this:%p sx:%x sy:%x ", this, fScaleX, fScaleY));
1235 SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(), fLoadG lyphFlags, glyph->fWidth)); 1225 SkDEBUGF(("Metrics(glyph:%d flags:0x%x) w:%d\n", glyph->getGlyphID(), fLoadG lyphFlags, glyph->fWidth));
1236 #endif 1226 #endif
1237 } 1227 }
1238 1228
1239 static void clear_glyph_image(const SkGlyph& glyph) { 1229 static void clear_glyph_image(const SkGlyph& glyph) {
1240 sk_bzero(glyph.fImage, glyph.rowBytes() * glyph.fHeight); 1230 sk_bzero(glyph.fImage, glyph.rowBytes() * glyph.fHeight);
1241 } 1231 }
1242 1232
1243 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) { 1233 void SkScalerContext_FreeType::generateImage(const SkGlyph& glyph) {
1244 SkAutoMutexAcquire ac(gFTMutex); 1234 SkAutoMutexAcquire ac(gFTMutex);
1245 1235
1246 if (this->setupSize()) { 1236 if (this->setupSize()) {
1247 clear_glyph_image(glyph); 1237 clear_glyph_image(glyph);
1248 return; 1238 return;
1249 } 1239 }
1250 1240
1251 FT_Error err = FT_Load_Glyph(fFace, glyph.getGlyphID(), fLoadGlyphFlags); 1241 FT_Error err = FT_Load_Glyph(fFace, glyph.getGlyphID(), fLoadGlyphFlags);
1252 if (err != 0) { 1242 if (err != 0) {
1253 SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph: %d width:%d height:%d rb:%d flags:%d) returned 0x%x\n", 1243 SkDEBUGF(("SkScalerContext_FreeType::generateImage: FT_Load_Glyph(glyph: %d width:%d height:%d rb:%d flags:%d) returned 0x%x\n",
1254 glyph.getGlyphID(), glyph.fWidth, glyph.fHeight, glyph.rowByte s(), fLoadGlyphFlags, err)); 1244 glyph.getGlyphID(), glyph.fWidth, glyph.fHeight, glyph.rowByte s(), fLoadGlyphFlags, err));
1255 clear_glyph_image(glyph); 1245 clear_glyph_image(glyph);
1256 return; 1246 return;
1257 } 1247 }
1258 1248
1259 emboldenIfNeeded(fFace, fFace->glyph); 1249 emboldenIfNeeded(fFace, fFace->glyph);
1260 SkMatrix* bitmapMatrix = &fMatrix22Scalar; 1250 generateGlyphImage(fFace, glyph);
1261 SkMatrix subpixelBitmapMatrix;
1262 if (this->shouldSubpixelBitmap(glyph, *bitmapMatrix)) {
1263 subpixelBitmapMatrix = fMatrix22Scalar;
1264 subpixelBitmapMatrix.postTranslate(SkFixedToScalar(glyph.getSubXFixed()) ,
1265 SkFixedToScalar(glyph.getSubYFixed()) );
1266 bitmapMatrix = &subpixelBitmapMatrix;
1267 }
1268 generateGlyphImage(fFace, glyph, *bitmapMatrix);
1269 } 1251 }
1270 1252
1271 1253
1272 void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, SkPath* path) { 1254 void SkScalerContext_FreeType::generatePath(const SkGlyph& glyph, SkPath* path) {
1273 SkAutoMutexAcquire ac(gFTMutex); 1255 SkAutoMutexAcquire ac(gFTMutex);
1274 1256
1275 SkASSERT(path); 1257 SkASSERT(path);
1276 1258
1277 if (this->setupSize()) { 1259 if (this->setupSize()) {
1278 path->reset(); 1260 path->reset();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 SkAutoMutexAcquire ac(gFTMutex); 1296 SkAutoMutexAcquire ac(gFTMutex);
1315 1297
1316 if (this->setupSize()) { 1298 if (this->setupSize()) {
1317 sk_bzero(metrics, sizeof(*metrics)); 1299 sk_bzero(metrics, sizeof(*metrics));
1318 return; 1300 return;
1319 } 1301 }
1320 1302
1321 FT_Face face = fFace; 1303 FT_Face face = fFace;
1322 SkScalar scaleX = fScale.x(); 1304 SkScalar scaleX = fScale.x();
1323 SkScalar scaleY = fScale.y(); 1305 SkScalar scaleY = fScale.y();
1324 SkScalar mxy = -fMatrix22Scalar.getSkewX() * scaleY; 1306 SkScalar mxy = fMatrix22Scalar.getSkewX() * scaleY;
1325 SkScalar myy = fMatrix22Scalar.getScaleY() * scaleY; 1307 SkScalar myy = fMatrix22Scalar.getScaleY() * scaleY;
1326 1308
1327 // fetch units/EM from "head" table if needed (ie for bitmap fonts) 1309 // fetch units/EM from "head" table if needed (ie for bitmap fonts)
1328 SkScalar upem = SkIntToScalar(face->units_per_EM); 1310 SkScalar upem = SkIntToScalar(face->units_per_EM);
1329 if (!upem) { 1311 if (!upem) {
1330 TT_Header* ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head); 1312 TT_Header* ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head);
1331 if (ttHeader) { 1313 if (ttHeader) {
1332 upem = SkIntToScalar(ttHeader->Units_Per_EM); 1314 upem = SkIntToScalar(ttHeader->Units_Per_EM);
1333 } 1315 }
1334 } 1316 }
(...skipping 501 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 SkDEBUGF(("Requested font axis not found: %s '%c%c%c%c'\n", 1818 SkDEBUGF(("Requested font axis not found: %s '%c%c%c%c'\n",
1837 name.c_str(), 1819 name.c_str(),
1838 (skTag >> 24) & 0xFF, 1820 (skTag >> 24) & 0xFF,
1839 (skTag >> 16) & 0xFF, 1821 (skTag >> 16) & 0xFF,
1840 (skTag >> 8) & 0xFF, 1822 (skTag >> 8) & 0xFF,
1841 (skTag) & 0xFF)); 1823 (skTag) & 0xFF));
1842 } 1824 }
1843 } 1825 }
1844 ) 1826 )
1845 } 1827 }
OLDNEW
« no previous file with comments | « no previous file | src/ports/SkFontHost_FreeType_common.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698