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