1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef MINIKIN_FONT_H 18 #define MINIKIN_FONT_H 19 20 #include <memory> 21 #include <mutex> 22 #include <unordered_set> 23 24 #include "minikin/Buffer.h" 25 #include "minikin/FontStyle.h" 26 #include "minikin/FontVariation.h" 27 #include "minikin/HbUtils.h" 28 #include "minikin/LocaleList.h" 29 #include "minikin/Macros.h" 30 #include "minikin/MinikinFont.h" 31 32 namespace minikin { 33 34 class Font; 35 36 // attributes representing transforms (fake bold, fake italic) to match styles 37 class FontFakery { 38 public: FontFakery()39 FontFakery() : mFakeBold(false), mFakeItalic(false) {} FontFakery(bool fakeBold,bool fakeItalic)40 FontFakery(bool fakeBold, bool fakeItalic) : mFakeBold(fakeBold), mFakeItalic(fakeItalic) {} 41 // TODO: want to support graded fake bolding isFakeBold()42 bool isFakeBold() { return mFakeBold; } isFakeItalic()43 bool isFakeItalic() { return mFakeItalic; } 44 inline bool operator==(const FontFakery& o) const { 45 return mFakeBold == o.mFakeBold && mFakeItalic == o.mFakeItalic; 46 } 47 inline bool operator!=(const FontFakery& o) const { return !(*this == o); } 48 49 private: 50 bool mFakeBold; 51 bool mFakeItalic; 52 }; 53 54 struct FakedFont { 55 inline bool operator==(const FakedFont& o) const { 56 return font == o.font && fakery == o.fakery; 57 } 58 inline bool operator!=(const FakedFont& o) const { return !(*this == o); } 59 60 // ownership is the enclosing FontCollection 61 // FakedFont will be stored in the LayoutCache. It is not a good idea too keep font instance 62 // even if the enclosing FontCollection, i.e. Typeface is GC-ed. The layout cache is only 63 // purged when it is overflown, thus intentionally keep only reference. 64 const std::shared_ptr<Font>& font; 65 FontFakery fakery; 66 }; 67 68 // Represents a single font file. 69 class Font { 70 public: 71 class Builder { 72 public: Builder(const std::shared_ptr<MinikinFont> & typeface)73 Builder(const std::shared_ptr<MinikinFont>& typeface) : mTypeface(typeface) {} 74 75 // Override the font style. If not called, info from OS/2 table is used. setStyle(FontStyle style)76 Builder& setStyle(FontStyle style) { 77 mWeight = style.weight(); 78 mSlant = style.slant(); 79 mIsWeightSet = mIsSlantSet = true; 80 return *this; 81 } 82 83 // Override the font weight. If not called, info from OS/2 table is used. setWeight(uint16_t weight)84 Builder& setWeight(uint16_t weight) { 85 mWeight = weight; 86 mIsWeightSet = true; 87 return *this; 88 } 89 90 // Override the font slant. If not called, info from OS/2 table is used. setSlant(FontStyle::Slant slant)91 Builder& setSlant(FontStyle::Slant slant) { 92 mSlant = slant; 93 mIsSlantSet = true; 94 return *this; 95 } 96 setLocaleListId(uint32_t id)97 Builder& setLocaleListId(uint32_t id) { 98 mLocaleListId = id; 99 return *this; 100 } 101 102 std::shared_ptr<Font> build(); 103 104 private: 105 std::shared_ptr<MinikinFont> mTypeface; 106 uint16_t mWeight = static_cast<uint16_t>(FontStyle::Weight::NORMAL); 107 FontStyle::Slant mSlant = FontStyle::Slant::UPRIGHT; 108 uint32_t mLocaleListId = kEmptyLocaleListId; 109 bool mIsWeightSet = false; 110 bool mIsSlantSet = false; 111 }; 112 113 // Type for functions to load MinikinFont lazily. 114 using TypefaceLoader = std::shared_ptr<MinikinFont>(BufferReader reader); 115 // Type for functions to read MinikinFont metadata and return 116 // TypefaceLoader. 117 using TypefaceReader = TypefaceLoader*(BufferReader* reader); 118 // Type for functions to write MinikinFont metadata. 119 using TypefaceWriter = void(BufferWriter* writer, const MinikinFont* typeface); 120 121 template <TypefaceReader typefaceReader> readFrom(BufferReader * reader,uint32_t localeListId)122 static std::shared_ptr<Font> readFrom(BufferReader* reader, uint32_t localeListId) { 123 FontStyle style = FontStyle(reader); 124 BufferReader typefaceMetadataReader = *reader; 125 TypefaceLoader* typefaceLoader = typefaceReader(reader); 126 return std::shared_ptr<Font>( 127 new Font(style, typefaceMetadataReader, typefaceLoader, localeListId)); 128 } 129 130 template <TypefaceWriter typefaceWriter> writeTo(BufferWriter * writer)131 void writeTo(BufferWriter* writer) const { 132 mStyle.writeTo(writer); 133 typefaceWriter(writer, typeface().get()); 134 } 135 136 // This locale list is just for API compatibility. This is not used in font selection or family 137 // fallback. getLocaleListId()138 uint32_t getLocaleListId() const { return mLocaleListId; } 139 const std::shared_ptr<MinikinFont>& typeface() const; style()140 inline FontStyle style() const { return mStyle; } 141 const HbFontUniquePtr& baseFont() const; typefaceMetadataReader()142 BufferReader typefaceMetadataReader() const { return mTypefaceMetadataReader; } 143 144 std::unordered_set<AxisTag> getSupportedAxes() const; 145 146 private: 147 // Use Builder instead. Font(std::shared_ptr<MinikinFont> && typeface,FontStyle style,HbFontUniquePtr && baseFont,uint32_t localeListId)148 Font(std::shared_ptr<MinikinFont>&& typeface, FontStyle style, HbFontUniquePtr&& baseFont, 149 uint32_t localeListId) 150 : mTypeface(std::move(typeface)), 151 mStyle(style), 152 mBaseFont(std::move(baseFont)), 153 mTypefaceLoader(nullptr), 154 mTypefaceMetadataReader(nullptr), 155 mLocaleListId(localeListId) {} Font(FontStyle style,BufferReader typefaceMetadataReader,TypefaceLoader * typefaceLoader,uint32_t localeListId)156 Font(FontStyle style, BufferReader typefaceMetadataReader, TypefaceLoader* typefaceLoader, 157 uint32_t localeListId) 158 : mStyle(style), 159 mTypefaceLoader(typefaceLoader), 160 mTypefaceMetadataReader(typefaceMetadataReader), 161 mLocaleListId(localeListId) {} 162 163 void initTypefaceLocked() const EXCLUSIVE_LOCKS_REQUIRED(mTypefaceMutex); 164 165 static HbFontUniquePtr prepareFont(const std::shared_ptr<MinikinFont>& typeface); 166 static FontStyle analyzeStyle(const HbFontUniquePtr& font); 167 168 // Lazy-initialized if created by readFrom(). 169 mutable std::shared_ptr<MinikinFont> mTypeface GUARDED_BY(mTypefaceMutex); 170 FontStyle mStyle; 171 // Lazy-initialized if created by readFrom(). 172 mutable HbFontUniquePtr mBaseFont GUARDED_BY(mTypefaceMutex); 173 174 mutable std::mutex mTypefaceMutex; 175 // Non-null if created by readFrom(). 176 TypefaceLoader* mTypefaceLoader; 177 // Non-null if created by readFrom(). 178 BufferReader mTypefaceMetadataReader; 179 180 uint32_t mLocaleListId; 181 182 // Stop copying and moving 183 Font(Font&& o) = delete; 184 Font& operator=(Font&& o) = delete; 185 Font(const Font& o) = delete; 186 Font& operator=(const Font& o) = delete; 187 }; 188 189 } // namespace minikin 190 191 #endif // MINIKIN_FONT_H 192