1 /* 2 * Copyright 2020 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkTypeface_mac_ct_DEFINED 9 #define SkTypeface_mac_ct_DEFINED 10 11 #include "include/core/SkTypes.h" 12 #if defined(SK_BUILD_FOR_MAC) || defined(SK_BUILD_FOR_IOS) 13 14 #include "include/core/SkFontArguments.h" 15 #include "include/core/SkFontParameters.h" 16 #include "include/core/SkFontStyle.h" 17 #include "include/core/SkRefCnt.h" 18 #include "include/core/SkScalar.h" 19 #include "include/core/SkStream.h" 20 #include "include/core/SkTypeface.h" 21 #include "include/private/base/SkOnce.h" 22 #include "src/utils/mac/SkUniqueCFRef.h" 23 24 #ifdef SK_BUILD_FOR_MAC 25 #import <ApplicationServices/ApplicationServices.h> 26 #endif 27 28 #ifdef SK_BUILD_FOR_IOS 29 #include <CoreText/CoreText.h> 30 #include <CoreText/CTFontManager.h> 31 #include <CoreGraphics/CoreGraphics.h> 32 #include <CoreFoundation/CoreFoundation.h> 33 #endif 34 35 #include <memory> 36 37 class SkData; 38 class SkDescriptor; 39 class SkFontData; 40 class SkFontDescriptor; 41 class SkScalerContext; 42 class SkString; 43 struct SkAdvancedTypefaceMetrics; 44 struct SkScalerContextEffects; 45 struct SkScalerContextRec; 46 47 struct OpszVariation { 48 bool isSet = false; 49 double value = 0; 50 }; 51 52 struct CTFontVariation { 53 SkUniqueCFRef<CFDictionaryRef> variation; 54 SkUniqueCFRef<CFDictionaryRef> wrongOpszVariation; 55 OpszVariation opsz; 56 }; 57 58 SkUniqueCFRef<CTFontRef> SkCTFontCreateExactCopy(CTFontRef baseFont, CGFloat textSize, 59 OpszVariation opsz); 60 61 SkFontStyle SkCTFontDescriptorGetSkFontStyle(CTFontDescriptorRef desc, bool fromDataProvider); 62 63 CGFloat SkCTFontCTWeightForCSSWeight(int fontstyleWeight); 64 CGFloat SkCTFontCTWidthForCSSWidth(int fontstyleWidth); 65 66 void SkStringFromCFString(CFStringRef src, SkString* dst); 67 68 class SkTypeface_Mac : public SkTypeface { 69 private: SkTypeface_Mac(SkUniqueCFRef<CTFontRef> fontRef,const SkFontStyle & fs,bool isFixedPitch,OpszVariation opszVariation,std::unique_ptr<SkStreamAsset> providedData)70 SkTypeface_Mac(SkUniqueCFRef<CTFontRef> fontRef, const SkFontStyle& fs, bool isFixedPitch, 71 OpszVariation opszVariation, std::unique_ptr<SkStreamAsset> providedData) 72 : SkTypeface(fs, isFixedPitch) 73 , fFontRef(std::move(fontRef)) 74 , fOpszVariation(opszVariation) 75 , fHasColorGlyphs( 76 SkToBool(CTFontGetSymbolicTraits(fFontRef.get()) & kCTFontColorGlyphsTrait)) 77 , fStream(std::move(providedData)) 78 , fIsFromStream(fStream) 79 { 80 SkASSERT(fFontRef); 81 } 82 83 public: 84 static sk_sp<SkTypeface> Make(SkUniqueCFRef<CTFontRef> font, 85 OpszVariation opszVariation, 86 std::unique_ptr<SkStreamAsset> providedData); 87 88 static constexpr SkTypeface::FactoryId FactoryId = SkSetFourByteTag('c','t','x','t'); 89 static sk_sp<SkTypeface> MakeFromStream(std::unique_ptr<SkStreamAsset>, const SkFontArguments&); 90 91 SkUniqueCFRef<CTFontRef> fFontRef; 92 const OpszVariation fOpszVariation; 93 const bool fHasColorGlyphs; 94 95 /** 96 * CTFontCopyVariationAxes provides the localized name of all axes, making it very slow. 97 * This is unfortunate, its result is needed just to see if there are any axes at all. 98 * To avoid calling internal APIs cache the result of CTFontCopyVariationAxes. 99 * https://github.com/WebKit/WebKit/commit/1842365d413ed87868e7d33d4fad1691fa3a8129 100 * https://bugs.webkit.org/show_bug.cgi?id=232690 101 */ 102 CFArrayRef getVariationAxes() const; 103 104 protected: 105 int onGetUPEM() const override; 106 std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override; 107 std::unique_ptr<SkStreamAsset> onOpenExistingStream(int* ttcIndex) const override; 108 bool onGlyphMaskNeedsCurrentColor() const override; 109 int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], 110 int coordinateCount) const override; 111 void onGetFamilyName(SkString* familyName) const override; 112 bool onGetPostScriptName(SkString*) const override; 113 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; 114 int onGetTableTags(SkFontTableTag tags[]) const override; 115 size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override; 116 sk_sp<SkData> onCopyTableData(SkFontTableTag) const override; 117 std::unique_ptr<SkScalerContext> onCreateScalerContext(const SkScalerContextEffects&, 118 const SkDescriptor*) const override; 119 void onFilterRec(SkScalerContextRec*) const override; 120 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; 121 void getGlyphToUnicodeMap(SkUnichar*) const override; 122 std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override; 123 void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override; 124 int onCountGlyphs() const override; getPostScriptGlyphNames(SkString *)125 void getPostScriptGlyphNames(SkString*) const override {} 126 int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], 127 int parameterCount) const override; 128 sk_sp<SkTypeface> onMakeClone(const SkFontArguments&) const override; 129 onGetCTFontRef()130 void* onGetCTFontRef() const override { return (void*)fFontRef.get(); } 131 132 private: 133 mutable std::unique_ptr<SkStreamAsset> fStream; 134 mutable SkUniqueCFRef<CFArrayRef> fVariationAxes; 135 bool fIsFromStream; 136 mutable SkOnce fInitStream; 137 mutable SkOnce fInitVariationAxes; 138 139 using INHERITED = SkTypeface; 140 }; 141 142 #endif 143 #endif //SkTypeface_mac_ct_DEFINED 144