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 <gtest/gtest_prod.h> 21 22 #include <atomic> 23 #include <memory> 24 #include <unordered_set> 25 26 #include "minikin/Buffer.h" 27 #include "minikin/FontStyle.h" 28 #include "minikin/FontVariation.h" 29 #include "minikin/HbUtils.h" 30 #include "minikin/LocaleList.h" 31 #include "minikin/Macros.h" 32 #include "minikin/MinikinFont.h" 33 34 namespace minikin { 35 36 class Font; 37 38 // attributes representing transforms (fake bold, fake italic) to match styles 39 class FontFakery { 40 public: FontFakery()41 FontFakery() : mFakeBold(false), mFakeItalic(false) {} FontFakery(bool fakeBold,bool fakeItalic)42 FontFakery(bool fakeBold, bool fakeItalic) : mFakeBold(fakeBold), mFakeItalic(fakeItalic) {} 43 // TODO: want to support graded fake bolding isFakeBold()44 bool isFakeBold() { return mFakeBold; } isFakeItalic()45 bool isFakeItalic() { return mFakeItalic; } 46 inline bool operator==(const FontFakery& o) const { 47 return mFakeBold == o.mFakeBold && mFakeItalic == o.mFakeItalic; 48 } 49 inline bool operator!=(const FontFakery& o) const { return !(*this == o); } 50 51 private: 52 bool mFakeBold; 53 bool mFakeItalic; 54 }; 55 56 struct FakedFont { 57 inline bool operator==(const FakedFont& o) const { 58 return font == o.font && fakery == o.fakery; 59 } 60 inline bool operator!=(const FakedFont& o) const { return !(*this == o); } 61 62 // ownership is the enclosing FontCollection 63 // FakedFont will be stored in the LayoutCache. It is not a good idea too keep font instance 64 // even if the enclosing FontCollection, i.e. Typeface is GC-ed. The layout cache is only 65 // purged when it is overflown, thus intentionally keep only reference. 66 const std::shared_ptr<Font>& font; 67 FontFakery fakery; 68 }; 69 70 // Represents a single font file. 71 class Font { 72 public: 73 class Builder { 74 public: Builder(const std::shared_ptr<MinikinFont> & typeface)75 Builder(const std::shared_ptr<MinikinFont>& typeface) : mTypeface(typeface) {} 76 77 // Override the font style. If not called, info from OS/2 table is used. setStyle(FontStyle style)78 Builder& setStyle(FontStyle style) { 79 mWeight = style.weight(); 80 mSlant = style.slant(); 81 mIsWeightSet = mIsSlantSet = true; 82 return *this; 83 } 84 85 // Override the font weight. If not called, info from OS/2 table is used. setWeight(uint16_t weight)86 Builder& setWeight(uint16_t weight) { 87 mWeight = weight; 88 mIsWeightSet = true; 89 return *this; 90 } 91 92 // Override the font slant. If not called, info from OS/2 table is used. setSlant(FontStyle::Slant slant)93 Builder& setSlant(FontStyle::Slant slant) { 94 mSlant = slant; 95 mIsSlantSet = true; 96 return *this; 97 } 98 setLocaleListId(uint32_t id)99 Builder& setLocaleListId(uint32_t id) { 100 mLocaleListId = id; 101 return *this; 102 } 103 104 std::shared_ptr<Font> build(); 105 106 private: 107 std::shared_ptr<MinikinFont> mTypeface; 108 uint16_t mWeight = static_cast<uint16_t>(FontStyle::Weight::NORMAL); 109 FontStyle::Slant mSlant = FontStyle::Slant::UPRIGHT; 110 uint32_t mLocaleListId = kEmptyLocaleListId; 111 bool mIsWeightSet = false; 112 bool mIsSlantSet = false; 113 }; 114 115 explicit Font(BufferReader* reader); 116 void writeTo(BufferWriter* writer) const; 117 118 Font(Font&& o) noexcept; 119 Font& operator=(Font&& o) noexcept; 120 ~Font(); 121 // This locale list is just for API compatibility. This is not used in font selection or family 122 // fallback. getLocaleListId()123 uint32_t getLocaleListId() const { return mLocaleListId; } 124 const std::shared_ptr<MinikinFont>& typeface() const; style()125 inline FontStyle style() const { return mStyle; } 126 const HbFontUniquePtr& baseFont() const; typefaceMetadataReader()127 BufferReader typefaceMetadataReader() const { return mTypefaceMetadataReader; } 128 129 std::unordered_set<AxisTag> getSupportedAxes() const; 130 131 private: 132 // ExternalRefs holds references to objects provided by external libraries. 133 // Because creating these external objects is costly, 134 // ExternalRefs is lazily created if Font was created by readFrom(). 135 class ExternalRefs { 136 public: ExternalRefs(std::shared_ptr<MinikinFont> && typeface,HbFontUniquePtr && baseFont)137 ExternalRefs(std::shared_ptr<MinikinFont>&& typeface, HbFontUniquePtr&& baseFont) 138 : mTypeface(std::move(typeface)), mBaseFont(std::move(baseFont)) {} 139 140 std::shared_ptr<MinikinFont> mTypeface; 141 HbFontUniquePtr mBaseFont; 142 }; 143 144 // Use Builder instead. Font(std::shared_ptr<MinikinFont> && typeface,FontStyle style,HbFontUniquePtr && baseFont,uint32_t localeListId)145 Font(std::shared_ptr<MinikinFont>&& typeface, FontStyle style, HbFontUniquePtr&& baseFont, 146 uint32_t localeListId) 147 : mExternalRefsHolder(new ExternalRefs(std::move(typeface), std::move(baseFont))), 148 mStyle(style), 149 mLocaleListId(localeListId), 150 mTypefaceMetadataReader(nullptr) {} 151 152 void resetExternalRefs(ExternalRefs* refs); 153 154 const ExternalRefs* getExternalRefs() const; 155 156 static HbFontUniquePtr prepareFont(const std::shared_ptr<MinikinFont>& typeface); 157 static FontStyle analyzeStyle(const HbFontUniquePtr& font); 158 159 // Lazy-initialized if created by readFrom(). 160 mutable std::atomic<ExternalRefs*> mExternalRefsHolder; 161 FontStyle mStyle; 162 uint32_t mLocaleListId; 163 164 // Non-null if created by readFrom(). 165 BufferReader mTypefaceMetadataReader; 166 167 // Stop copying. 168 Font(const Font& o) = delete; 169 Font& operator=(const Font& o) = delete; 170 171 FRIEND_TEST(FontTest, MoveConstructorTest); 172 FRIEND_TEST(FontTest, MoveAssignmentTest); 173 }; 174 175 } // namespace minikin 176 177 #endif // MINIKIN_FONT_H 178