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

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

Issue 1751883004: SkFontHost_FreeType constructor to correctly release resources. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 4 years, 9 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 | no next file » | 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"
11 #include "SkColorPriv.h" 11 #include "SkColorPriv.h"
12 #include "SkDescriptor.h" 12 #include "SkDescriptor.h"
13 #include "SkFDot6.h" 13 #include "SkFDot6.h"
14 #include "SkFontDescriptor.h" 14 #include "SkFontDescriptor.h"
15 #include "SkFontHost_FreeType_common.h" 15 #include "SkFontHost_FreeType_common.h"
16 #include "SkGlyph.h" 16 #include "SkGlyph.h"
17 #include "SkMask.h" 17 #include "SkMask.h"
18 #include "SkMaskGamma.h" 18 #include "SkMaskGamma.h"
19 #include "SkMatrix22.h" 19 #include "SkMatrix22.h"
20 #include "SkMutex.h" 20 #include "SkMutex.h"
21 #include "SkOTUtils.h" 21 #include "SkOTUtils.h"
22 #include "SkPath.h" 22 #include "SkPath.h"
23 #include "SkScalerContext.h" 23 #include "SkScalerContext.h"
24 #include "SkStream.h" 24 #include "SkStream.h"
25 #include "SkString.h" 25 #include "SkString.h"
26 #include "SkTemplates.h" 26 #include "SkTemplates.h"
27 #include "SkTypes.h" 27 #include "SkTypes.h"
28 #include "SkUniquePtr.h"
28 29
29 #if defined(SK_CAN_USE_DLOPEN) 30 #if defined(SK_CAN_USE_DLOPEN)
30 #include <dlfcn.h> 31 #include <dlfcn.h>
31 #endif 32 #endif
32 #include <ft2build.h> 33 #include <ft2build.h>
33 #include FT_ADVANCES_H 34 #include FT_ADVANCES_H
34 #include FT_BITMAP_H 35 #include FT_BITMAP_H
35 #include FT_FREETYPE_H 36 #include FT_FREETYPE_H
36 #include FT_LCD_FILTER_H 37 #include FT_LCD_FILTER_H
37 #include FT_MODULE_H 38 #include FT_MODULE_H
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after
141 // Android >= Gingerbread (good) 142 // Android >= Gingerbread (good)
142 typedef FT_Error (*FT_Library_SetLcdFilterWeightsProc)(FT_Library, unsigned char*); 143 typedef FT_Error (*FT_Library_SetLcdFilterWeightsProc)(FT_Library, unsigned char*);
143 }; 144 };
144 145
145 struct SkFaceRec; 146 struct SkFaceRec;
146 147
147 SK_DECLARE_STATIC_MUTEX(gFTMutex); 148 SK_DECLARE_STATIC_MUTEX(gFTMutex);
148 static FreeTypeLibrary* gFTLibrary; 149 static FreeTypeLibrary* gFTLibrary;
149 static SkFaceRec* gFaceRecHead; 150 static SkFaceRec* gFaceRecHead;
150 151
151 // Private to RefFreeType and UnrefFreeType 152 // Private to ref_ft_library and unref_ft_library
152 static int gFTCount; 153 static int gFTCount;
153 154
154 // Caller must lock gFTMutex before calling this function. 155 // Caller must lock gFTMutex before calling this function.
155 static bool ref_ft_library() { 156 static bool ref_ft_library() {
156 gFTMutex.assertHeld(); 157 gFTMutex.assertHeld();
157 SkASSERT(gFTCount >= 0); 158 SkASSERT(gFTCount >= 0);
158 159
159 if (0 == gFTCount) { 160 if (0 == gFTCount) {
160 SkASSERT(nullptr == gFTLibrary); 161 SkASSERT(nullptr == gFTLibrary);
161 gFTLibrary = new FreeTypeLibrary; 162 gFTLibrary = new FreeTypeLibrary;
162 } 163 }
163 ++gFTCount; 164 ++gFTCount;
164 return gFTLibrary->library(); 165 return gFTLibrary->library();
165 } 166 }
166 167
167 // Caller must lock gFTMutex before calling this function. 168 // Caller must lock gFTMutex before calling this function.
168 static void unref_ft_library() { 169 static void unref_ft_library() {
169 gFTMutex.assertHeld(); 170 gFTMutex.assertHeld();
170 SkASSERT(gFTCount > 0); 171 SkASSERT(gFTCount > 0);
171 172
172 --gFTCount; 173 --gFTCount;
173 if (0 == gFTCount) { 174 if (0 == gFTCount) {
175 SkASSERT(nullptr == gFaceRecHead);
bungeman-skia 2016/03/01 22:28:06 Adding this assert would have helped find this a b
174 SkASSERT(nullptr != gFTLibrary); 176 SkASSERT(nullptr != gFTLibrary);
175 delete gFTLibrary; 177 delete gFTLibrary;
176 SkDEBUGCODE(gFTLibrary = nullptr;) 178 SkDEBUGCODE(gFTLibrary = nullptr;)
177 } 179 }
178 } 180 }
179 181
180 class SkScalerContext_FreeType : public SkScalerContext_FreeType_Base { 182 class SkScalerContext_FreeType : public SkScalerContext_FreeType_Base {
181 public: 183 public:
182 SkScalerContext_FreeType(SkTypeface*, const SkDescriptor* desc); 184 SkScalerContext_FreeType(SkTypeface*, const SkDescriptor* desc);
183 virtual ~SkScalerContext_FreeType(); 185 virtual ~SkScalerContext_FreeType();
(...skipping 484 matching lines...) Expand 10 before | Expand all | Expand 10 after
668 delete c; 670 delete c;
669 c = nullptr; 671 c = nullptr;
670 } 672 }
671 return c; 673 return c;
672 } 674 }
673 675
674 void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const { 676 void SkTypeface_FreeType::onFilterRec(SkScalerContextRec* rec) const {
675 //BOGUS: http://code.google.com/p/chromium/issues/detail?id=121119 677 //BOGUS: http://code.google.com/p/chromium/issues/detail?id=121119
676 //Cap the requested size as larger sizes give bogus values. 678 //Cap the requested size as larger sizes give bogus values.
677 //Remove when http://code.google.com/p/skia/issues/detail?id=554 is fixed. 679 //Remove when http://code.google.com/p/skia/issues/detail?id=554 is fixed.
680 //Note that this also currently only protects against large text size reques ts,
681 //the total matrix is not taken into account here.
bungeman-skia 2016/03/01 22:28:06 All of the 'onFilterRec' implementations should be
678 if (rec->fTextSize > SkIntToScalar(1 << 14)) { 682 if (rec->fTextSize > SkIntToScalar(1 << 14)) {
679 rec->fTextSize = SkIntToScalar(1 << 14); 683 rec->fTextSize = SkIntToScalar(1 << 14);
680 } 684 }
681 685
682 if (isLCD(*rec)) { 686 if (isLCD(*rec)) {
683 // TODO: re-work so that FreeType is set-up and selected by the SkFontMg r. 687 // TODO: re-work so that FreeType is set-up and selected by the SkFontMg r.
684 SkAutoMutexAcquire ama(gFTMutex); 688 SkAutoMutexAcquire ama(gFTMutex);
685 ref_ft_library(); 689 ref_ft_library();
686 if (!gFTLibrary->isLCDSupported()) { 690 if (!gFTLibrary->isLCDSupported()) {
687 // If the runtime Freetype library doesn't support LCD, disable it h ere. 691 // If the runtime Freetype library doesn't support LCD, disable it h ere.
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after
779 SkDEBUGF(("FT_Select_Size(%s, %d) returned 0x%x\n", face->family_nam e, 783 SkDEBUGF(("FT_Select_Size(%s, %d) returned 0x%x\n", face->family_nam e,
780 chosenStrikeIndex, err)); 784 chosenStrikeIndex, err));
781 chosenStrikeIndex = -1; 785 chosenStrikeIndex = -1;
782 } 786 }
783 } 787 }
784 return chosenStrikeIndex; 788 return chosenStrikeIndex;
785 } 789 }
786 790
787 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, const S kDescriptor* desc) 791 SkScalerContext_FreeType::SkScalerContext_FreeType(SkTypeface* typeface, const S kDescriptor* desc)
788 : SkScalerContext_FreeType_Base(typeface, desc) 792 : SkScalerContext_FreeType_Base(typeface, desc)
793 , fFace(nullptr)
794 , fFTSize(nullptr)
795 , fStrikeIndex(-1)
789 { 796 {
790 SkAutoMutexAcquire ac(gFTMutex); 797 SkAutoMutexAcquire ac(gFTMutex);
791 798
792 if (!ref_ft_library()) { 799 if (!ref_ft_library()) {
793 sk_throw(); 800 sk_throw();
794 } 801 }
795 802
796 // load the font file 803 // load the font file
797 fStrikeIndex = -1; 804 using UnrefFTFace = SkFunctionWrapper<void, skstd::remove_pointer_t<FT_Face> , unref_ft_face>;
798 fFTSize = nullptr; 805 skstd::unique_ptr<skstd::remove_pointer_t<FT_Face>, UnrefFTFace> ftFace(ref_ ft_face(typeface));
799 fFace = ref_ft_face(typeface); 806 if (nullptr == ftFace) {
800 if (nullptr == fFace) { 807 SkDEBUGF(("Could not create FT_Face.\n"));
801 return; 808 return;
802 } 809 }
803 810
804 fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMa trix22Scalar); 811 fRec.computeMatrices(SkScalerContextRec::kFull_PreMatrixScale, &fScale, &fMa trix22Scalar);
805 fMatrix22Scalar.setSkewX(-fMatrix22Scalar.getSkewX()); 812 fMatrix22Scalar.setSkewX(-fMatrix22Scalar.getSkewX());
806 fMatrix22Scalar.setSkewY(-fMatrix22Scalar.getSkewY()); 813 fMatrix22Scalar.setSkewY(-fMatrix22Scalar.getSkewY());
807 814
808 fScaleX = SkScalarToFDot6(fScale.fX); 815 fScaleX = SkScalarToFDot6(fScale.fX);
809 fScaleY = SkScalarToFDot6(fScale.fY); 816 fScaleY = SkScalarToFDot6(fScale.fY);
810 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX()); 817 fMatrix22.xx = SkScalarToFixed(fMatrix22Scalar.getScaleX());
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 // Use vertical layout if requested. 883 // Use vertical layout if requested.
877 if (fRec.fFlags & SkScalerContext::kVertical_Flag) { 884 if (fRec.fFlags & SkScalerContext::kVertical_Flag) {
878 loadFlags |= FT_LOAD_VERTICAL_LAYOUT; 885 loadFlags |= FT_LOAD_VERTICAL_LAYOUT;
879 } 886 }
880 887
881 loadFlags |= FT_LOAD_COLOR; 888 loadFlags |= FT_LOAD_COLOR;
882 889
883 fLoadGlyphFlags = loadFlags; 890 fLoadGlyphFlags = loadFlags;
884 } 891 }
885 892
886 FT_Error err = FT_New_Size(fFace, &fFTSize); 893 using DoneFTSize = SkFunctionWrapper<FT_Error, skstd::remove_pointer_t<FT_Si ze>, FT_Done_Size>;
887 if (err != 0) { 894 skstd::unique_ptr<skstd::remove_pointer_t<FT_Size>, DoneFTSize> ftSize([&ftF ace]() -> FT_Size {
888 SkDEBUGF(("FT_New_Size returned %x for face %s\n", err, fFace->family_na me)); 895 FT_Size size;
889 fFace = nullptr; 896 FT_Error err = FT_New_Size(ftFace.get(), &size);
890 return; 897 if (err != 0) {
891 } 898 SkDEBUGF(("FT_New_Size returned %x for face %s\n", err, ftFace->fami ly_name));
892 err = FT_Activate_Size(fFTSize); 899 return nullptr;
893 if (err != 0) { 900 }
894 SkDEBUGF(("FT_Activate_Size(%08x, 0x%x, 0x%x) returned 0x%x\n", fFace, f ScaleX, fScaleY, 901 return size;
dogben 2016/03/02 00:55:22 ignorable nit: Seems like it would be simpler to d
895 err)); 902 }());
896 fFTSize = nullptr; 903 if (nullptr == ftSize) {
904 SkDEBUGF(("Could not create FT_Size.\n"));
897 return; 905 return;
898 } 906 }
899 907
900 if (FT_IS_SCALABLE(fFace)) { 908 FT_Error err = FT_Activate_Size(ftSize.get());
901 err = FT_Set_Char_Size(fFace, fScaleX, fScaleY, 72, 72); 909 if (err != 0) {
910 SkDEBUGF(("FT_Activate_Size(%08x, 0x%x, 0x%x) returned 0x%x\n",
911 ftFace.get(), fScaleX, fScaleY, err));
912 return;
913 }
914
915 if (FT_IS_SCALABLE(ftFace)) {
916 err = FT_Set_Char_Size(ftFace.get(), fScaleX, fScaleY, 72, 72);
902 if (err != 0) { 917 if (err != 0) {
903 SkDEBUGF(("FT_Set_CharSize(%08x, 0x%x, 0x%x) returned 0x%x\n", 918 SkDEBUGF(("FT_Set_CharSize(%08x, 0x%x, 0x%x) returned 0x%x\n",
904 fFace, fScaleX, fScaleY, err)); 919 ftFace.get(), fScaleX, fScaleY, err));
905 fFace = nullptr;
bungeman-skia 2016/03/01 22:28:06 The related bug was because we went down this path
906 return; 920 return;
907 } 921 }
908 FT_Set_Transform(fFace, &fMatrix22, nullptr); 922 FT_Set_Transform(ftFace.get(), &fMatrix22, nullptr);
909 } else if (FT_HAS_FIXED_SIZES(fFace)) { 923 } else if (FT_HAS_FIXED_SIZES(ftFace)) {
910 fStrikeIndex = chooseBitmapStrike(fFace, fScaleY); 924 fStrikeIndex = chooseBitmapStrike(ftFace.get(), fScaleY);
911 if (fStrikeIndex == -1) { 925 if (fStrikeIndex == -1) {
912 SkDEBUGF(("no glyphs for font \"%s\" size %f?\n", 926 SkDEBUGF(("no glyphs for font \"%s\" size %f?\n",
913 fFace->family_name, SkFDot6ToScalar(fScaleY))) ; 927 ftFace->family_name, SkFDot6ToScalar(fScaleY))) ;
914 } else { 928 } else {
915 // FreeType does no provide linear metrics for bitmap fonts. 929 // FreeType does no provide linear metrics for bitmap fonts.
916 linearMetrics = false; 930 linearMetrics = false;
917 931
918 // FreeType documentation says: 932 // FreeType documentation says:
919 // FT_LOAD_NO_BITMAP -- Ignore bitmap strikes when loading. 933 // FT_LOAD_NO_BITMAP -- Ignore bitmap strikes when loading.
920 // Bitmap-only fonts ignore this flag. 934 // Bitmap-only fonts ignore this flag.
921 // 935 //
922 // However, in FreeType 2.5.1 color bitmap only fonts do not ignore this flag. 936 // However, in FreeType 2.5.1 color bitmap only fonts do not ignore this flag.
923 // Force this flag off for bitmap only fonts. 937 // Force this flag off for bitmap only fonts.
924 fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP; 938 fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP;
925 } 939 }
926 } else { 940 } else {
927 SkDEBUGF(("unknown kind of font \"%s\" size %f?\n", 941 SkDEBUGF(("unknown kind of font \"%s\" size %f?\n",
928 fFace->family_name, SkFDot6ToScalar(fScaleY))); 942 fFace->family_name, SkFDot6ToScalar(fScaleY)));
929 } 943 }
930 944
945 fFTSize = ftSize.release();
946 fFace = ftFace.release();
931 fDoLinearMetrics = linearMetrics; 947 fDoLinearMetrics = linearMetrics;
932 } 948 }
933 949
934 SkScalerContext_FreeType::~SkScalerContext_FreeType() { 950 SkScalerContext_FreeType::~SkScalerContext_FreeType() {
935 SkAutoMutexAcquire ac(gFTMutex); 951 SkAutoMutexAcquire ac(gFTMutex);
936 952
937 if (fFTSize != nullptr) { 953 if (fFTSize != nullptr) {
938 FT_Done_Size(fFTSize); 954 FT_Done_Size(fFTSize);
939 } 955 }
940 956
(...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after
1790 SkDEBUGF(("Requested font axis not found: %s '%c%c%c%c'\n", 1806 SkDEBUGF(("Requested font axis not found: %s '%c%c%c%c'\n",
1791 name.c_str(), 1807 name.c_str(),
1792 (skTag >> 24) & 0xFF, 1808 (skTag >> 24) & 0xFF,
1793 (skTag >> 16) & 0xFF, 1809 (skTag >> 16) & 0xFF,
1794 (skTag >> 8) & 0xFF, 1810 (skTag >> 8) & 0xFF,
1795 (skTag) & 0xFF)); 1811 (skTag) & 0xFF));
1796 } 1812 }
1797 } 1813 }
1798 ) 1814 )
1799 } 1815 }
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698