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 SkFontStyle SkCTFontDescriptorGetSkFontStyle(CTFontDescriptorRef desc, bool fromDataProvider); 59 60 CGFloat SkCTFontCTWeightForCSSWeight(int fontstyleWeight); 61 CGFloat SkCTFontCTWidthForCSSWidth(int fontstyleWidth); 62 63 void SkStringFromCFString(CFStringRef src, SkString* dst); 64 65 class SkTypeface_Mac : public SkTypeface { 66 private: SkTypeface_Mac(SkUniqueCFRef<CTFontRef> fontRef,const SkFontStyle & fs,bool isFixedPitch,OpszVariation opszVariation,std::unique_ptr<SkStreamAsset> providedData)67 SkTypeface_Mac(SkUniqueCFRef<CTFontRef> fontRef, const SkFontStyle& fs, bool isFixedPitch, 68 OpszVariation opszVariation, std::unique_ptr<SkStreamAsset> providedData) 69 : SkTypeface(fs, isFixedPitch) 70 , fFontRef(std::move(fontRef)) 71 , fOpszVariation(opszVariation) 72 , fHasColorGlyphs( 73 SkToBool(CTFontGetSymbolicTraits(fFontRef.get()) & kCTFontColorGlyphsTrait)) 74 , fStream(std::move(providedData)) 75 , fIsFromStream(fStream) 76 { 77 SkASSERT(fFontRef); 78 } 79 80 public: 81 static sk_sp<SkTypeface> Make(SkUniqueCFRef<CTFontRef> font, 82 OpszVariation opszVariation, 83 std::unique_ptr<SkStreamAsset> providedData); 84 85 static constexpr SkTypeface::FactoryId FactoryId = SkSetFourByteTag('c','t','x','t'); 86 static sk_sp<SkTypeface> SK_SPI MakeFromStream(std::unique_ptr<SkStreamAsset>, 87 const SkFontArguments&); 88 89 SkUniqueCFRef<CTFontRef> fFontRef; 90 const OpszVariation fOpszVariation; 91 const bool fHasColorGlyphs; 92 93 /** 94 * CTFontCopyVariationAxes provides the localized name of all axes, making it very slow. 95 * This is unfortunate, its result is needed just to see if there are any axes at all. 96 * To avoid calling internal APIs cache the result of CTFontCopyVariationAxes. 97 * https://github.com/WebKit/WebKit/commit/1842365d413ed87868e7d33d4fad1691fa3a8129 98 * https://bugs.webkit.org/show_bug.cgi?id=232690 99 */ 100 CFArrayRef getVariationAxes() const; 101 102 protected: 103 int onGetUPEM() const override; 104 std::unique_ptr<SkStreamAsset> onOpenStream(int* ttcIndex) const override; 105 std::unique_ptr<SkStreamAsset> onOpenExistingStream(int* ttcIndex) const override; 106 bool onGlyphMaskNeedsCurrentColor() const override; 107 int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], 108 int coordinateCount) const override; 109 void onGetFamilyName(SkString* familyName) const override; 110 bool onGetPostScriptName(SkString*) const override; 111 SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override; 112 int onGetTableTags(SkFontTableTag tags[]) const override; 113 size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override; 114 sk_sp<SkData> onCopyTableData(SkFontTableTag) const override; 115 std::unique_ptr<SkScalerContext> onCreateScalerContext(const SkScalerContextEffects&, 116 const SkDescriptor*) const override; 117 void onFilterRec(SkScalerContextRec*) const override; 118 void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; 119 void getGlyphToUnicodeMap(SkUnichar*) const override; 120 std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override; 121 void onCharsToGlyphs(const SkUnichar* chars, int count, SkGlyphID glyphs[]) const override; 122 int onCountGlyphs() const override; getPostScriptGlyphNames(SkString *)123 void getPostScriptGlyphNames(SkString*) const override {} 124 int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], 125 int parameterCount) const override; 126 sk_sp<SkTypeface> onMakeClone(const SkFontArguments&) const override; 127 onGetCTFontRef()128 void* onGetCTFontRef() const override { return (void*)fFontRef.get(); } 129 130 private: 131 mutable std::unique_ptr<SkStreamAsset> fStream; 132 mutable SkUniqueCFRef<CFArrayRef> fVariationAxes; 133 bool fIsFromStream; 134 mutable SkOnce fInitStream; 135 mutable SkOnce fInitVariationAxes; 136 137 using INHERITED = SkTypeface; 138 }; 139 140 #endif 141 #endif //SkTypeface_mac_ct_DEFINED 142