summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-08 16:02:15 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-04-08 16:02:15 +0000
commit344df572feecf520d16939e52b3a963e998bbc4f (patch)
treecc760592822d295652a6f09cc869fbcd02b0a04e
parent7c70575d509031ed26d3c1c46affb04a7082044c (diff)
parentc3bd9a03ecb1a19393046c522f5b6c91d615f7c5 (diff)
downloadminikin-android12-mainline-tzdata2-release.tar.gz
Change-Id: Ic88d6223a6a5e2373d196bf0c2beb159a82463e8
-rw-r--r--Android.bp10
-rw-r--r--app/Android.bp4
-rw-r--r--include/minikin/BoundsCache.h110
-rw-r--r--include/minikin/Buffer.h151
-rw-r--r--include/minikin/Font.h90
-rw-r--r--include/minikin/FontCollection.h161
-rw-r--r--include/minikin/FontFamily.h50
-rw-r--r--include/minikin/FontFileParser.h53
-rw-r--r--include/minikin/FontStyle.h11
-rw-r--r--include/minikin/FontVariation.h1
-rw-r--r--include/minikin/Hasher.h20
-rw-r--r--include/minikin/Layout.h6
-rw-r--r--include/minikin/LayoutCache.h6
-rw-r--r--include/minikin/LayoutCore.h8
-rw-r--r--include/minikin/LineBreaker.h3
-rw-r--r--include/minikin/LocaleList.h6
-rw-r--r--include/minikin/Measurement.h6
-rw-r--r--include/minikin/MinikinFont.h12
-rw-r--r--include/minikin/MinikinRect.h1
-rw-r--r--include/minikin/SparseBitSet.h17
-rw-r--r--include/minikin/SystemFonts.h56
-rw-r--r--libs/minikin/Android.bp8
-rw-r--r--libs/minikin/BoundsCache.cpp43
-rw-r--r--libs/minikin/Font.cpp125
-rw-r--r--libs/minikin/FontCollection.cpp264
-rw-r--r--libs/minikin/FontFamily.cpp188
-rw-r--r--libs/minikin/FontFileParser.cpp219
-rw-r--r--libs/minikin/GreedyLineBreaker.cpp2
-rw-r--r--libs/minikin/Layout.cpp3
-rw-r--r--libs/minikin/LayoutCore.cpp32
-rw-r--r--libs/minikin/LineBreakerUtil.h2
-rw-r--r--libs/minikin/Locale.cpp12
-rw-r--r--libs/minikin/Locale.h30
-rw-r--r--libs/minikin/LocaleListCache.cpp61
-rw-r--r--libs/minikin/LocaleListCache.h38
-rw-r--r--libs/minikin/MeasuredText.cpp18
-rw-r--r--libs/minikin/Measurement.cpp39
-rw-r--r--libs/minikin/SparseBitSet.cpp43
-rw-r--r--libs/minikin/SystemFonts.cpp21
-rw-r--r--tests/Android.bp8
-rw-r--r--tests/data/Ascii.ttfbin1944 -> 1848 bytes
-rw-r--r--tests/data/Ascii.ttx17
-rw-r--r--tests/data/Bbox.ttfbin2016 -> 0 bytes
-rw-r--r--tests/data/Bbox.ttx265
-rw-r--r--tests/data/EmojiBase.ttfbin1428 -> 0 bytes
-rw-r--r--tests/data/EmojiBase.ttx537
-rw-r--r--tests/data/OverrideEmoji.ttfbin1200 -> 0 bytes
-rw-r--r--tests/data/OverrideEmoji.ttx521
-rw-r--r--tests/data/emoji_itemization.xml28
-rw-r--r--tests/perftests/Android.bp4
-rw-r--r--tests/perftests/main.cpp20
-rw-r--r--tests/stresstest/Android.bp4
-rw-r--r--tests/stresstest/FontFamilyTest.cpp2
-rw-r--r--tests/unittest/Android.bp7
-rw-r--r--tests/unittest/BoundsCacheTest.cpp172
-rw-r--r--tests/unittest/BufferTest.cpp90
-rw-r--r--tests/unittest/FontCollectionItemizeTest.cpp153
-rw-r--r--tests/unittest/FontCollectionTest.cpp160
-rw-r--r--tests/unittest/FontFamilyTest.cpp93
-rw-r--r--tests/unittest/FontFileParserTest.cpp132
-rw-r--r--tests/unittest/FontLanguageListCacheTest.cpp21
-rw-r--r--tests/unittest/FontTest.cpp29
-rw-r--r--tests/unittest/GreedyLineBreakerTest.cpp27
-rw-r--r--tests/unittest/HasherTest.cpp5
-rw-r--r--tests/unittest/ICUEnvironment.h66
-rw-r--r--tests/unittest/LayoutCoreTest.cpp11
-rw-r--r--tests/unittest/LayoutTest.cpp43
-rw-r--r--tests/unittest/MeasuredTextTest.cpp105
-rw-r--r--tests/unittest/OptimalLineBreakerTest.cpp28
-rw-r--r--tests/unittest/SparseBitSetTest.cpp27
-rw-r--r--tests/unittest/SystemFontsTest.cpp50
-rw-r--r--tests/unittest/TestMain.cpp3
-rw-r--r--tests/util/Android.bp4
-rw-r--r--tests/util/BufferUtils.h59
-rw-r--r--tests/util/FontTestUtils.cpp6
-rw-r--r--tests/util/FreeTypeMinikinFontForTest.cpp18
-rw-r--r--tests/util/FreeTypeMinikinFontForTest.h9
77 files changed, 489 insertions, 4165 deletions
diff --git a/Android.bp b/Android.bp
index f5aaf31..adbd4e6 100644
--- a/Android.bp
+++ b/Android.bp
@@ -1,17 +1,7 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library_headers {
name: "libminikin_headers",
host_supported: true,
export_include_dirs: ["include"],
- header_libs: [
- "libgtest_prod_headers",
- ],
- export_header_lib_headers: [
- "libgtest_prod_headers",
- ],
target: {
windows: {
enabled: true,
diff --git a/app/Android.bp b/app/Android.bp
index 9d6c28a..6c7c66b 100644
--- a/app/Android.bp
+++ b/app/Android.bp
@@ -14,10 +14,6 @@
// see how_to_run.txt for instructions on running these tests
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_binary_host {
name: "hyphtool",
diff --git a/include/minikin/BoundsCache.h b/include/minikin/BoundsCache.h
deleted file mode 100644
index 64f2b49..0000000
--- a/include/minikin/BoundsCache.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MINIKIN_BOUNDS_CACHE_H
-#define MINIKIN_BOUNDS_CACHE_H
-
-#include "minikin/LayoutCache.h"
-
-#include <mutex>
-
-#include <utils/LruCache.h>
-
-#include "minikin/BoundsCache.h"
-#include "minikin/FontCollection.h"
-#include "minikin/Hasher.h"
-#include "minikin/MinikinPaint.h"
-
-namespace minikin {
-
-// Cache entry
-struct BoundsValue {
- MinikinRect rect;
- float advance;
-};
-
-// Used for callback for LayoutCache.
-struct ValueExtractor {
- void operator()(const LayoutPiece& layoutPiece, const MinikinPaint& paint);
- std::unique_ptr<BoundsValue> value;
-};
-
-class BoundsCache : private android::OnEntryRemoved<LayoutCacheKey, BoundsValue*> {
-public:
- void clear() {
- std::lock_guard<std::mutex> lock(mMutex);
- mCache.clear();
- }
-
- // Do not use BoundsCache inside the callback function, otherwise dead-lock may happen.
- template <typename F>
- void getOrCreate(const U16StringPiece& text, const Range& range, const MinikinPaint& paint,
- bool dir, StartHyphenEdit startHyphen, EndHyphenEdit endHyphen, F& f) {
- LayoutCacheKey key(text, range, paint, dir, startHyphen, endHyphen);
- if (paint.skipCache() || range.getLength() >= LENGTH_LIMIT_CACHE) {
- LayoutPiece piece = LayoutPiece(text, range, dir, paint, startHyphen, endHyphen);
- f(getBounds(piece, paint), piece.advance());
- return;
- }
- {
- std::lock_guard<std::mutex> lock(mMutex);
- BoundsValue* value = mCache.get(key);
- if (value != nullptr) {
- f(value->rect, value->advance);
- return;
- }
- }
- // Doing text layout takes long time, so releases the mutex during doing layout.
- // Don't care even if we do the same layout in other thread.
- key.copyText();
- ValueExtractor ve;
- LayoutCache::getInstance().getOrCreate(text, range, paint, dir, startHyphen, endHyphen, ve);
- f(ve.value->rect, ve.value->advance);
- {
- std::lock_guard<std::mutex> lock(mMutex);
- mCache.put(key, ve.value.release());
- }
- }
-
- static BoundsCache& getInstance() {
- static BoundsCache cache(kMaxEntries);
- return cache;
- }
-
- // Compute new bounding box for the layout piece.
- static MinikinRect getBounds(const LayoutPiece& layoutPiece, const MinikinPaint& paint);
-
-protected:
- BoundsCache(uint32_t maxEntries) : mCache(maxEntries) {
- mCache.setOnEntryRemovedListener(this);
- }
-
-private:
- // callback for OnEntryRemoved
- void operator()(LayoutCacheKey& key, BoundsValue*& value) {
- key.freeText();
- delete value;
- }
-
- std::mutex mMutex;
- android::LruCache<LayoutCacheKey, BoundsValue*> mCache GUARDED_BY(mMutex) GUARDED_BY(mMutex);
- // LRU cache capacity. Should be fine to be less than LayoutCache#kMaxEntries since bbox
- // calculation happens less than layout calculation.
- static const size_t kMaxEntries = 500;
-};
-
-} // namespace minikin
-#endif // MINIKIN_BOUNDS_CACHE_H
diff --git a/include/minikin/Buffer.h b/include/minikin/Buffer.h
deleted file mode 100644
index 87ba3fd..0000000
--- a/include/minikin/Buffer.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MINIKIN_BUFFER_H
-#define MINIKIN_BUFFER_H
-
-#include <cstring>
-#include <string_view>
-#include <type_traits>
-#include <utility>
-
-namespace minikin {
-
-// This is a helper class to read data from a memory buffer.
-// This class does not copy memory, and may return pointers to parts of the memory buffer.
-// Thus the memory buffer should outlive objects created using this class.
-class BufferReader {
-public:
- BufferReader(const void* buffer) : BufferReader(buffer, 0) {}
- BufferReader(const void* buffer, uint32_t pos)
- : mData(reinterpret_cast<const uint8_t*>(buffer)), mPos(pos) {}
-
- template <typename T>
- static uint32_t align(uint32_t pos) {
- // This should be true for all types, unless custom alignment attributes are set.
- static_assert(sizeof(T) % alignof(T) == 0, "sizeof(T) must be a multiple of alignof(T)");
- // We align to sizeof(T) instead of alignof(T), because the buffer may be shared between
- // 32-bit processes and 64-bit processes. alignof(T) may change between the two.
- // We assume that T is a type whose size is fixed (e.g. uint32_t).
- return (pos + sizeof(T) - 1) / sizeof(T) * sizeof(T);
- }
-
- template <typename T>
- const T& read() {
- static_assert(std::is_pod<T>::value, "T must be a POD");
- mPos = BufferReader::align<T>(mPos);
- const T* data = reinterpret_cast<const T*>(mData + mPos);
- mPos += sizeof(T);
- return *data;
- }
-
- template <typename T>
- void skip() {
- static_assert(std::is_pod<T>::value, "T must be a POD");
- mPos = BufferReader::align<T>(mPos);
- mPos += sizeof(T);
- }
-
- // Return a pointer to an array and its number of elements.
- template <typename T>
- std::pair<const T*, uint32_t> readArray() {
- static_assert(std::is_pod<T>::value, "T must be a POD");
- uint32_t size = read<uint32_t>();
- mPos = BufferReader::align<T>(mPos);
- const T* data = reinterpret_cast<const T*>(mData + mPos);
- mPos += size * sizeof(T);
- return std::make_pair(data, size);
- }
-
- template <typename T>
- void skipArray() {
- static_assert(std::is_pod<T>::value, "T must be a POD");
- uint32_t size = read<uint32_t>();
- mPos = BufferReader::align<T>(mPos);
- mPos += size * sizeof(T);
- }
-
- std::string_view readString() {
- auto [data, size] = readArray<char>();
- return std::string_view(data, size);
- }
-
- void skipString() { skipArray<char>(); }
-
- const void* data() const { return mData; }
- size_t pos() const { return mPos; }
-
-private:
- const uint8_t* mData;
- size_t mPos;
-};
-
-// This is a helper class to write data to a memory buffer.
-class BufferWriter {
-public:
- // Create a buffer writer. Passing nullptr creates a fake writer,
- // which can be used to measure the buffer size needed.
- BufferWriter(void* buffer) : mData(reinterpret_cast<uint8_t*>(buffer)), mPos(0) {}
-
- BufferWriter(BufferWriter&&) = default;
- BufferWriter& operator=(BufferWriter&&) = default;
-
- // Write a single data of type T.
- // Please always specify T explicitly using <>. std::common_type_t<T> resolves to T, but
- // disables template argument deduction.
- // TODO: use std::type_identity_t when C++20 is available.
- template <typename T>
- void write(const std::common_type_t<T>& data) {
- static_assert(std::is_pod<T>::value, "T must be a POD");
- mPos = BufferReader::align<T>(mPos);
- if (mData != nullptr) {
- memcpy(mData + mPos, &data, sizeof(T));
- }
- mPos += sizeof(T);
- }
-
- // Write an array of type T.
- // Please always specify T explicitly using <>. std::common_type_t<T> resolves to T, but
- // disables template argument deduction.
- // TODO: use std::type_identity_t when C++20 is available.
- template <typename T>
- void writeArray(const std::common_type_t<T>* data, uint32_t size) {
- static_assert(std::is_pod<T>::value, "T must be a POD");
- write<uint32_t>(size);
- mPos = BufferReader::align<T>(mPos);
- if (mData != nullptr) {
- memcpy(mData + mPos, data, size * sizeof(T));
- }
- mPos += size * sizeof(T);
- }
-
- void writeString(std::string_view string) { writeArray<char>(string.data(), string.size()); }
-
- // Return the number of bytes written.
- size_t size() const { return mPos; }
-
-private:
- uint8_t* mData;
- size_t mPos;
-
- // Forbid copy and assign.
- BufferWriter(const BufferWriter&) = delete;
- void operator=(const BufferWriter&) = delete;
-};
-
-} // namespace minikin
-
-#endif // MINIKIN_BUFFER_H
diff --git a/include/minikin/Font.h b/include/minikin/Font.h
index 67feecf..eeb074e 100644
--- a/include/minikin/Font.h
+++ b/include/minikin/Font.h
@@ -18,14 +18,11 @@
#define MINIKIN_FONT_H
#include <memory>
-#include <mutex>
#include <unordered_set>
-#include "minikin/Buffer.h"
#include "minikin/FontStyle.h"
#include "minikin/FontVariation.h"
#include "minikin/HbUtils.h"
-#include "minikin/LocaleList.h"
#include "minikin/Macros.h"
#include "minikin/MinikinFont.h"
@@ -58,10 +55,7 @@ struct FakedFont {
inline bool operator!=(const FakedFont& o) const { return !(*this == o); }
// ownership is the enclosing FontCollection
- // FakedFont will be stored in the LayoutCache. It is not a good idea too keep font instance
- // even if the enclosing FontCollection, i.e. Typeface is GC-ed. The layout cache is only
- // purged when it is overflown, thus intentionally keep only reference.
- const std::shared_ptr<Font>& font;
+ const Font* font;
FontFakery fakery;
};
@@ -94,96 +88,44 @@ public:
return *this;
}
- Builder& setLocaleListId(uint32_t id) {
- mLocaleListId = id;
- return *this;
- }
-
- std::shared_ptr<Font> build();
+ Font build();
private:
std::shared_ptr<MinikinFont> mTypeface;
uint16_t mWeight = static_cast<uint16_t>(FontStyle::Weight::NORMAL);
FontStyle::Slant mSlant = FontStyle::Slant::UPRIGHT;
- uint32_t mLocaleListId = kEmptyLocaleListId;
bool mIsWeightSet = false;
bool mIsSlantSet = false;
};
- // Type for functions to load MinikinFont lazily.
- using TypefaceLoader = std::shared_ptr<MinikinFont>(BufferReader reader);
- // Type for functions to read MinikinFont metadata and return
- // TypefaceLoader.
- using TypefaceReader = TypefaceLoader*(BufferReader* reader);
- // Type for functions to write MinikinFont metadata.
- using TypefaceWriter = void(BufferWriter* writer, const MinikinFont* typeface);
-
- template <TypefaceReader typefaceReader>
- static std::shared_ptr<Font> readFrom(BufferReader* reader, uint32_t localeListId) {
- FontStyle style = FontStyle(reader);
- BufferReader typefaceMetadataReader = *reader;
- TypefaceLoader* typefaceLoader = typefaceReader(reader);
- return std::shared_ptr<Font>(
- new Font(style, typefaceMetadataReader, typefaceLoader, localeListId));
- }
+ Font(Font&& o) = default;
+ Font& operator=(Font&& o) = default;
- template <TypefaceWriter typefaceWriter>
- void writeTo(BufferWriter* writer) const {
- mStyle.writeTo(writer);
- typefaceWriter(writer, typeface().get());
+ Font& operator=(const Font& o) {
+ mTypeface = o.mTypeface;
+ mStyle = o.mStyle;
+ mBaseFont = HbFontUniquePtr(hb_font_reference(o.mBaseFont.get()));
+ return *this;
}
+ Font(const Font& o) { *this = o; }
- // This locale list is just for API compatibility. This is not used in font selection or family
- // fallback.
- uint32_t getLocaleListId() const { return mLocaleListId; }
- const std::shared_ptr<MinikinFont>& typeface() const;
+ inline const std::shared_ptr<MinikinFont>& typeface() const { return mTypeface; }
inline FontStyle style() const { return mStyle; }
- const HbFontUniquePtr& baseFont() const;
- BufferReader typefaceMetadataReader() const { return mTypefaceMetadataReader; }
+ inline const HbFontUniquePtr& baseFont() const { return mBaseFont; }
std::unordered_set<AxisTag> getSupportedAxes() const;
private:
// Use Builder instead.
- Font(std::shared_ptr<MinikinFont>&& typeface, FontStyle style, HbFontUniquePtr&& baseFont,
- uint32_t localeListId)
- : mTypeface(std::move(typeface)),
- mStyle(style),
- mBaseFont(std::move(baseFont)),
- mTypefaceLoader(nullptr),
- mTypefaceMetadataReader(nullptr),
- mLocaleListId(localeListId) {}
- Font(FontStyle style, BufferReader typefaceMetadataReader, TypefaceLoader* typefaceLoader,
- uint32_t localeListId)
- : mStyle(style),
- mTypefaceLoader(typefaceLoader),
- mTypefaceMetadataReader(typefaceMetadataReader),
- mLocaleListId(localeListId) {}
-
- void initTypefaceLocked() const EXCLUSIVE_LOCKS_REQUIRED(mTypefaceMutex);
+ Font(std::shared_ptr<MinikinFont>&& typeface, FontStyle style, HbFontUniquePtr&& baseFont)
+ : mTypeface(std::move(typeface)), mStyle(style), mBaseFont(std::move(baseFont)) {}
static HbFontUniquePtr prepareFont(const std::shared_ptr<MinikinFont>& typeface);
static FontStyle analyzeStyle(const HbFontUniquePtr& font);
- // Lazy-initialized if created by readFrom().
- mutable std::shared_ptr<MinikinFont> mTypeface GUARDED_BY(mTypefaceMutex);
+ std::shared_ptr<MinikinFont> mTypeface;
FontStyle mStyle;
- // Lazy-initialized if created by readFrom().
- mutable HbFontUniquePtr mBaseFont GUARDED_BY(mTypefaceMutex);
-
- mutable std::mutex mTypefaceMutex;
- // Non-null if created by readFrom().
- TypefaceLoader* mTypefaceLoader;
- // Non-null if created by readFrom().
- BufferReader mTypefaceMetadataReader;
-
- uint32_t mLocaleListId;
-
- // Stop copying and moving
- Font(Font&& o) = delete;
- Font& operator=(Font&& o) = delete;
- Font(const Font& o) = delete;
- Font& operator=(const Font& o) = delete;
+ HbFontUniquePtr mBaseFont;
};
} // namespace minikin
diff --git a/include/minikin/FontCollection.h b/include/minikin/FontCollection.h
index 98df571..f136384 100644
--- a/include/minikin/FontCollection.h
+++ b/include/minikin/FontCollection.h
@@ -18,14 +18,9 @@
#define MINIKIN_FONT_COLLECTION_H
#include <memory>
-#include <unordered_map>
#include <unordered_set>
#include <vector>
-#include <gtest/gtest_prod.h>
-
-#include "minikin/Buffer.h"
-#include "minikin/Font.h"
#include "minikin/FontFamily.h"
#include "minikin/MinikinFont.h"
#include "minikin/U16StringPiece.h"
@@ -40,134 +35,12 @@ public:
explicit FontCollection(const std::vector<std::shared_ptr<FontFamily>>& typefaces);
explicit FontCollection(std::shared_ptr<FontFamily>&& typeface);
- template <Font::TypefaceReader typefaceReader>
- static std::vector<std::shared_ptr<FontCollection>> readVector(BufferReader* reader) {
- uint32_t allFontFamiliesCount = reader->read<uint32_t>();
- std::vector<std::shared_ptr<FontFamily>> allFontFamilies;
- allFontFamilies.reserve(allFontFamiliesCount);
- for (uint32_t i = 0; i < allFontFamiliesCount; i++) {
- allFontFamilies.push_back(FontFamily::readFrom<typefaceReader>(reader));
- }
- uint32_t fontCollectionsCount = reader->read<uint32_t>();
- std::vector<std::shared_ptr<FontCollection>> fontCollections;
- fontCollections.reserve(fontCollectionsCount);
- for (uint32_t i = 0; i < fontCollectionsCount; i++) {
- fontCollections.emplace_back(new FontCollection(reader, allFontFamilies));
- }
- return fontCollections;
- }
-
- template <Font::TypefaceWriter typefaceWriter>
- static void writeVector(BufferWriter* writer,
- const std::vector<std::shared_ptr<FontCollection>>& fontCollections) {
- std::vector<std::shared_ptr<FontFamily>> allFontFamilies;
- // Note: operator== for shared_ptr compares raw pointer values.
- std::unordered_map<std::shared_ptr<FontFamily>, uint32_t> fontFamilyToIndexMap;
- collectAllFontFamilies(fontCollections, &allFontFamilies, &fontFamilyToIndexMap);
-
- writer->write<uint32_t>(allFontFamilies.size());
- for (const auto& fontFamily : allFontFamilies) {
- fontFamily->writeTo<typefaceWriter>(writer);
- }
- writer->write<uint32_t>(fontCollections.size());
- for (const auto& fontCollection : fontCollections) {
- fontCollection->writeTo(writer, fontFamilyToIndexMap);
- }
- }
-
- // Helper class for representing font family match result in packed bits.
- struct FamilyMatchResult {
- public:
- struct Builder {
- public:
- Builder() : mSize(0), mBits(0) {}
-
- Builder& add(uint8_t x) {
- if (mSize >= 7) [[unlikely]] {
- return *this;
- }
- mBits = mBits | (static_cast<uint64_t>(x) << (8 * mSize));
- mSize++;
- return *this;
- }
-
- Builder& reset() {
- mSize = 0;
- mBits = 0;
- return *this;
- }
-
- uint8_t size() const { return mSize; }
-
- bool empty() const { return size() == 0; }
-
- FamilyMatchResult build() {
- return FamilyMatchResult(mBits | (static_cast<uint64_t>(mSize) << 56));
- }
-
- private:
- uint8_t mSize;
- uint64_t mBits;
- };
-
- // Helper class for iterating FamilyMatchResult
- class iterator {
- public:
- inline bool operator==(const iterator& o) const {
- return mOffset == o.mOffset && mResult == o.mResult;
- }
-
- inline bool operator!=(const iterator& o) const { return !(*this == o); }
- inline uint8_t operator*() const { return mResult[mOffset]; }
- inline iterator& operator++() {
- mOffset++;
- return *this;
- }
-
- private:
- friend struct FamilyMatchResult;
- iterator(const FamilyMatchResult& result, uint32_t offset)
- : mResult(result), mOffset(offset) {}
- const FamilyMatchResult& mResult;
- uint32_t mOffset;
- };
-
- // Create empty FamilyMatchResult.
- FamilyMatchResult() : mBits(0) {}
-
- inline uint8_t size() const { return static_cast<uint8_t>(mBits >> 56); }
-
- inline uint8_t operator[](uint32_t pos) const {
- return static_cast<uint8_t>(mBits >> (pos * 8));
- }
-
- inline bool empty() const { return size() == 0; }
-
- inline bool operator==(const FamilyMatchResult& o) const { return mBits == o.mBits; }
-
- // Returns the common family indices between l and r.
- static FamilyMatchResult intersect(FamilyMatchResult l, FamilyMatchResult r);
-
- // Iterator
- inline iterator begin() const { return iterator(*this, 0); }
- inline iterator end() const { return iterator(*this, size()); }
-
- FamilyMatchResult(const FamilyMatchResult& o) = default;
- FamilyMatchResult& operator=(const FamilyMatchResult& o) = default;
-
- private:
- explicit FamilyMatchResult(uint64_t bits) : mBits(bits) {}
- uint64_t mBits;
- };
-
struct Run {
- FamilyMatchResult familyMatch;
+ FakedFont fakedFont;
int start;
int end;
};
- FakedFont getBestFont(U16StringPiece textBuf, const Run& run, FontStyle style);
-
// Perform the itemization until given max runs.
std::vector<Run> itemize(U16StringPiece text, FontStyle style, uint32_t localeListId,
FamilyVariant familyVariant, uint32_t runMax) const;
@@ -195,23 +68,7 @@ public:
uint32_t getId() const;
- const std::vector<std::shared_ptr<FontFamily>>& getFamilies() const { return mFamilies; }
-
private:
- FRIEND_TEST(FontCollectionTest, bufferTest);
-
- FontCollection(BufferReader* reader,
- const std::vector<std::shared_ptr<FontFamily>>& allFontFamilies);
- // Write fields of the instance, using fontFamilyToIndexMap for finding
- // indices for FontFamily.
- void writeTo(BufferWriter* writer,
- const std::unordered_map<std::shared_ptr<FontFamily>, uint32_t>&
- fontFamilyToIndexMap) const;
- static void collectAllFontFamilies(
- const std::vector<std::shared_ptr<FontCollection>>& fontCollections,
- std::vector<std::shared_ptr<FontFamily>>* outAllFontFamilies,
- std::unordered_map<std::shared_ptr<FontFamily>, uint32_t>* outFontFamilyToIndexMap);
-
static const int kLogCharsPerPage = 8;
static const int kPageMask = (1 << kLogCharsPerPage) - 1;
@@ -228,8 +85,9 @@ private:
// Initialize the FontCollection.
void init(const std::vector<std::shared_ptr<FontFamily>>& typefaces);
- FamilyMatchResult getFamilyForChar(uint32_t ch, uint32_t vs, uint32_t localeListId,
- FamilyVariant variant) const;
+ const std::shared_ptr<FontFamily>& getFamilyForChar(uint32_t ch, uint32_t vs,
+ uint32_t localeListId,
+ FamilyVariant variant) const;
uint32_t calcFamilyScore(uint32_t ch, uint32_t vs, FamilyVariant variant, uint32_t localeListId,
const std::shared_ptr<FontFamily>& fontFamily) const;
@@ -258,21 +116,14 @@ private:
// mFamilyVec[mRange[0xXXYY].end] instead of whole mFamilies.
// This vector contains indices into mFamilies.
// This vector can't be empty.
- uint32_t mRangesCount;
- const Range* mRanges;
- uint32_t mFamilyVecCount;
- const uint8_t* mFamilyVec;
+ std::vector<Range> mRanges;
+ std::vector<uint8_t> mFamilyVec;
// This vector has pointers to the font family instances which have cmap 14 subtables.
std::vector<std::shared_ptr<FontFamily>> mVSFamilyVec;
// Set of supported axes in this collection.
std::unordered_set<AxisTag> mSupportedAxes;
-
- // Owns allocated memory if this class is created from font families, otherwise these are
- // nullptr.
- std::unique_ptr<Range[]> mOwnedRanges;
- std::vector<uint8_t> mOwnedFamilyVec;
};
} // namespace minikin
diff --git a/include/minikin/FontFamily.h b/include/minikin/FontFamily.h
index 6169193..4aafaa0 100644
--- a/include/minikin/FontFamily.h
+++ b/include/minikin/FontFamily.h
@@ -33,32 +33,10 @@ namespace minikin {
class FontFamily {
public:
- explicit FontFamily(std::vector<std::shared_ptr<Font>>&& fonts);
- FontFamily(FamilyVariant variant, std::vector<std::shared_ptr<Font>>&& fonts);
- FontFamily(uint32_t localeListId, FamilyVariant variant,
- std::vector<std::shared_ptr<Font>>&& fonts, bool isCustomFallback);
-
- template <Font::TypefaceReader typefaceReader>
- static std::shared_ptr<FontFamily> readFrom(BufferReader* reader) {
- uint32_t localeListId = readLocaleListInternal(reader);
- uint32_t fontsCount = reader->read<uint32_t>();
- std::vector<std::shared_ptr<Font>> fonts;
- fonts.reserve(fontsCount);
- for (uint32_t i = 0; i < fontsCount; i++) {
- fonts.emplace_back(Font::readFrom<typefaceReader>(reader, localeListId));
- }
- return readFromInternal(reader, std::move(fonts), localeListId);
- }
-
- template <Font::TypefaceWriter typefaceWriter>
- void writeTo(BufferWriter* writer) const {
- writeLocaleListInternal(writer);
- writer->write<uint32_t>(mFonts.size());
- for (const std::shared_ptr<Font>& font : mFonts) {
- font->writeTo<typefaceWriter>(writer);
- }
- writeToInternal(writer);
- }
+ explicit FontFamily(std::vector<Font>&& fonts);
+ FontFamily(FamilyVariant variant, std::vector<Font>&& fonts);
+ FontFamily(uint32_t localeListId, FamilyVariant variant, std::vector<Font>&& fonts,
+ bool isCustomFallback);
FakedFont getClosestMatch(FontStyle style) const;
@@ -67,9 +45,8 @@ public:
// API's for enumerating the fonts in a family. These don't guarantee any particular order
size_t getNumFonts() const { return mFonts.size(); }
- const Font* getFont(size_t index) const { return mFonts[index].get(); }
- const std::shared_ptr<Font>& getFontRef(size_t index) const { return mFonts[index]; }
- FontStyle getStyle(size_t index) const { return mFonts[index]->style(); }
+ const Font* getFont(size_t index) const { return &mFonts[index]; }
+ FontStyle getStyle(size_t index) const { return mFonts[index].style(); }
bool isColorEmojiFamily() const { return mIsColorEmoji; }
const std::unordered_set<AxisTag>& supportedAxes() const { return mSupportedAxes; }
bool isCustomFallback() const { return mIsCustomFallback; }
@@ -90,24 +67,11 @@ public:
const std::vector<FontVariation>& variations) const;
private:
- FontFamily(uint32_t localeListId, FamilyVariant variant,
- std::vector<std::shared_ptr<Font>>&& fonts,
- std::unordered_set<AxisTag>&& supportedAxes, bool isColorEmoji,
- bool isCustomFallback, SparseBitSet&& coverage,
- std::vector<std::unique_ptr<SparseBitSet>>&& cmapFmt14Coverage);
-
- static uint32_t readLocaleListInternal(BufferReader* reader);
- static std::shared_ptr<FontFamily> readFromInternal(BufferReader* reader,
- std::vector<std::shared_ptr<Font>>&& fonts,
- uint32_t localeListId);
- void writeLocaleListInternal(BufferWriter* writer) const;
- void writeToInternal(BufferWriter* writer) const;
-
void computeCoverage();
uint32_t mLocaleListId;
FamilyVariant mVariant;
- std::vector<std::shared_ptr<Font>> mFonts;
+ std::vector<Font> mFonts;
std::unordered_set<AxisTag> mSupportedAxes;
bool mIsColorEmoji;
bool mIsCustomFallback;
diff --git a/include/minikin/FontFileParser.h b/include/minikin/FontFileParser.h
deleted file mode 100644
index 34880a3..0000000
--- a/include/minikin/FontFileParser.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MINIKIN_FONT_FILE_PARSER_H
-#define MINIKIN_FONT_FILE_PARSER_H
-
-#include "minikin/HbUtils.h"
-
-#include <optional>
-#include <string>
-
-namespace minikin {
-
-// FontFileParser provides various parser logic for OpenType font file.
-class FontFileParser {
-public:
- // This class does not take an ownership of buffer. Caller must free it.
- FontFileParser(const void* buffer, size_t size, uint32_t index);
- explicit FontFileParser(const HbFaceUniquePtr& face);
- explicit FontFileParser(const HbFontUniquePtr& font);
-
- virtual ~FontFileParser();
-
- std::optional<uint32_t> getFontRevision() const;
- std::optional<std::string> getPostScriptName() const;
- std::optional<bool> isPostScriptType1Font() const;
-
-protected: // protected for testing purposes.
- static bool analyzeFontRevision(const uint8_t* head_data, size_t head_size, uint32_t* out);
- static bool checkPSName(const std::string& psName);
-
-private:
- HbFaceUniquePtr mFace;
-
- static HbFaceUniquePtr makeHbFace(const void* buffer, size_t size, uint32_t index);
-};
-
-} // namespace minikin
-
-#endif // MINIKIN_FONT_FILE_PARSER_H
diff --git a/include/minikin/FontStyle.h b/include/minikin/FontStyle.h
index 51e4ad8..73cf427 100644
--- a/include/minikin/FontStyle.h
+++ b/include/minikin/FontStyle.h
@@ -17,8 +17,6 @@
#ifndef MINIKIN_FONT_STYLE_H
#define MINIKIN_FONT_STYLE_H
-#include <minikin/Buffer.h>
-
namespace minikin {
// FontStyle represents style information.
@@ -48,15 +46,6 @@ public:
constexpr FontStyle(Weight weight, Slant slant)
: FontStyle(static_cast<uint16_t>(weight), slant) {}
constexpr FontStyle(uint16_t weight, Slant slant) : mWeight(weight), mSlant(slant) {}
- explicit FontStyle(BufferReader* reader) {
- mWeight = reader->read<uint16_t>();
- mSlant = static_cast<Slant>(reader->read<uint8_t>());
- }
-
- void writeTo(BufferWriter* writer) const {
- writer->write<uint16_t>(mWeight);
- writer->write<uint8_t>(static_cast<uint8_t>(mSlant));
- }
constexpr uint16_t weight() const { return mWeight; }
constexpr Slant slant() const { return mSlant; }
diff --git a/include/minikin/FontVariation.h b/include/minikin/FontVariation.h
index e0567c1..0c38d6a 100644
--- a/include/minikin/FontVariation.h
+++ b/include/minikin/FontVariation.h
@@ -24,7 +24,6 @@ namespace minikin {
typedef uint32_t AxisTag;
struct FontVariation {
- FontVariation() = default;
FontVariation(AxisTag axisTag, float value) : axisTag(axisTag), value(value) {}
AxisTag axisTag;
float value;
diff --git a/include/minikin/Hasher.h b/include/minikin/Hasher.h
index 4a76b29..8a79b61 100644
--- a/include/minikin/Hasher.h
+++ b/include/minikin/Hasher.h
@@ -37,26 +37,6 @@ public:
return *this;
}
- inline Hasher& update(int32_t data) {
- update(static_cast<uint32_t>(data));
- return *this;
- }
-
- inline Hasher& update(uint64_t data) {
- update(static_cast<uint32_t>(data));
- update(static_cast<uint32_t>(data >> 32));
- return *this;
- }
-
- inline Hasher& update(float data) {
- union {
- float f;
- uint32_t i;
- } bits;
- bits.f = data;
- return update(bits.i);
- }
-
inline Hasher& updateShorts(const uint16_t* data, uint32_t length) {
update(length);
uint32_t i;
diff --git a/include/minikin/Layout.h b/include/minikin/Layout.h
index 388a7a7..19f3109 100644
--- a/include/minikin/Layout.h
+++ b/include/minikin/Layout.h
@@ -84,8 +84,7 @@ public:
// public accessors
size_t nGlyphs() const { return mGlyphs.size(); }
- const Font* getFont(int i) const { return mGlyphs[i].font.font.get(); }
- const std::shared_ptr<Font>& getFontRef(int i) const { return mGlyphs[i].font.font; }
+ const MinikinFont* getFont(int i) const { return mGlyphs[i].font.font->typeface().get(); }
FontFakery getFakery(int i) const { return mGlyphs[i].font.fakery; }
unsigned int getGlyphId(int i) const { return mGlyphs[i].glyph_id; }
float getX(int i) const { return mGlyphs[i].x; }
@@ -93,6 +92,8 @@ public:
float getAdvance() const { return mAdvance; }
float getCharAdvance(size_t i) const { return mAdvances[i]; }
const std::vector<float>& getAdvances() const { return mAdvances; }
+ void getBounds(MinikinRect* rect) const { rect->set(mBounds); }
+ const MinikinRect& getBounds() const { return mBounds; }
// Purge all caches, useful in low memory conditions
static void purgeCaches();
@@ -134,6 +135,7 @@ private:
std::vector<float> mAdvances;
float mAdvance;
+ MinikinRect mBounds;
};
} // namespace minikin
diff --git a/include/minikin/LayoutCache.h b/include/minikin/LayoutCache.h
index a1cc34a..ee51f11 100644
--- a/include/minikin/LayoutCache.h
+++ b/include/minikin/LayoutCache.h
@@ -83,9 +83,9 @@ public:
private:
const uint16_t* mChars;
- uint32_t mNchars;
- uint32_t mStart;
- uint32_t mCount;
+ size_t mNchars;
+ size_t mStart;
+ size_t mCount;
uint32_t mId; // for the font collection
FontStyle mStyle;
float mSize;
diff --git a/include/minikin/LayoutCore.h b/include/minikin/LayoutCore.h
index cade517..852b985 100644
--- a/include/minikin/LayoutCore.h
+++ b/include/minikin/LayoutCore.h
@@ -49,10 +49,11 @@ public:
// Low level accessors.
const std::vector<uint8_t>& fontIndices() const { return mFontIndices; }
- const std::vector<uint32_t>& glyphIds() const { return mGlyphIds; }
- const std::vector<Point>& points() const { return mPoints; }
- const std::vector<float>& advances() const { return mAdvances; }
+ const std::vector<uint32_t> glyphIds() const { return mGlyphIds; }
+ const std::vector<Point> points() const { return mPoints; }
+ const std::vector<float> advances() const { return mAdvances; }
float advance() const { return mAdvance; }
+ const MinikinRect& bounds() const { return mBounds; }
const MinikinExtent& extent() const { return mExtent; }
const std::vector<FakedFont>& fonts() const { return mFonts; }
@@ -78,6 +79,7 @@ private:
std::vector<float> mAdvances; // per code units
float mAdvance;
+ MinikinRect mBounds;
MinikinExtent mExtent;
std::vector<FakedFont> mFonts;
diff --git a/include/minikin/LineBreaker.h b/include/minikin/LineBreaker.h
index 5d3e752..3410339 100644
--- a/include/minikin/LineBreaker.h
+++ b/include/minikin/LineBreaker.h
@@ -62,9 +62,6 @@ public:
return mStops[i];
}
}
- if (mTabWidth == 0) {
- return 0;
- }
return floor(widthSoFar / mTabWidth + 1) * mTabWidth;
}
diff --git a/include/minikin/LocaleList.h b/include/minikin/LocaleList.h
index d173a46..bfc26c7 100644
--- a/include/minikin/LocaleList.h
+++ b/include/minikin/LocaleList.h
@@ -21,17 +21,11 @@
namespace minikin {
-// A special ID for the empty locale list.
-// This value must be 0 since the empty locale list is inserted into mLocaleLists by default.
-const static uint32_t kEmptyLocaleListId = 0;
-
// Looks up a locale list from an internal cache and returns its ID.
// If the passed locale list is not in the cache, registers it and returns newly assigned ID.
// TODO: Introduce LocaleId type.
uint32_t registerLocaleList(const std::string& locales);
-std::string getLocaleString(uint32_t id);
-
} // namespace minikin
#endif // MINIKIN_LOCALE_H
diff --git a/include/minikin/Measurement.h b/include/minikin/Measurement.h
index d0aaa51..c8b97d1 100644
--- a/include/minikin/Measurement.h
+++ b/include/minikin/Measurement.h
@@ -20,8 +20,6 @@
#include <cstddef>
#include <cstdint>
-#include <minikin/Layout.h>
-
namespace minikin {
float getRunAdvance(const float* advances, const uint16_t* buf, size_t start, size_t count,
@@ -30,10 +28,6 @@ float getRunAdvance(const float* advances, const uint16_t* buf, size_t start, si
size_t getOffsetForAdvance(const float* advances, const uint16_t* buf, size_t start, size_t count,
float advance);
-void getBounds(const U16StringPiece& str, const Range& range, Bidi bidiFlags,
- const MinikinPaint& paint, StartHyphenEdit startHyphen, EndHyphenEdit endHyphen,
- MinikinRect* out);
-
} // namespace minikin
#endif // MINIKIN_MEASUREMENT_H
diff --git a/include/minikin/MinikinFont.h b/include/minikin/MinikinFont.h
index 4d3ba9c..a5ba074 100644
--- a/include/minikin/MinikinFont.h
+++ b/include/minikin/MinikinFont.h
@@ -34,7 +34,7 @@ struct MinikinRect;
// multiple actual implementations of fonts.
class MinikinFont {
public:
- MinikinFont() {}
+ explicit MinikinFont(int32_t uniqueId) : mUniqueId(uniqueId) {}
virtual ~MinikinFont() {}
@@ -54,9 +54,6 @@ public:
virtual void GetFontExtent(MinikinExtent* extent, const MinikinPaint& paint,
const FontFakery& fakery) const = 0;
- // Returns the font path or an empty string.
- virtual const std::string& GetFontPath() const = 0;
-
// Override if font can provide access to raw data
virtual const void* GetFontData() const { return nullptr; }
@@ -67,8 +64,6 @@ public:
// Returns index within OpenType collection
virtual int GetFontIndex() const { return 0; }
- virtual int GetSourceId() const { return 0; }
-
virtual const std::vector<minikin::FontVariation>& GetAxes() const = 0;
virtual std::shared_ptr<MinikinFont> createFontWithVariation(
@@ -79,6 +74,11 @@ public:
static uint32_t MakeTag(char c1, char c2, char c3, char c4) {
return ((uint32_t)c1 << 24) | ((uint32_t)c2 << 16) | ((uint32_t)c3 << 8) | (uint32_t)c4;
}
+
+ int32_t GetUniqueId() const { return mUniqueId; }
+
+private:
+ const int32_t mUniqueId;
};
} // namespace minikin
diff --git a/include/minikin/MinikinRect.h b/include/minikin/MinikinRect.h
index 38c2180..6a3d88b 100644
--- a/include/minikin/MinikinRect.h
+++ b/include/minikin/MinikinRect.h
@@ -28,7 +28,6 @@ struct MinikinRect {
bool operator==(const MinikinRect& o) const {
return mLeft == o.mLeft && mTop == o.mTop && mRight == o.mRight && mBottom == o.mBottom;
}
- bool operator!=(const MinikinRect& o) const { return !(*this == o); }
float mLeft;
float mTop;
float mRight;
diff --git a/include/minikin/SparseBitSet.h b/include/minikin/SparseBitSet.h
index 3034243..9ccef12 100644
--- a/include/minikin/SparseBitSet.h
+++ b/include/minikin/SparseBitSet.h
@@ -17,7 +17,6 @@
#ifndef MINIKIN_SPARSE_BIT_SET_H
#define MINIKIN_SPARSE_BIT_SET_H
-#include <minikin/Buffer.h>
#include <sys/types.h>
#include <cstdint>
#include <memory>
@@ -43,13 +42,9 @@ public:
initFromRanges(ranges, nRanges);
}
- explicit SparseBitSet(BufferReader* reader) : SparseBitSet() { initFromBuffer(reader); }
-
SparseBitSet(SparseBitSet&&) = default;
SparseBitSet& operator=(SparseBitSet&&) = default;
- void writeTo(BufferWriter* writer) const;
-
// Determine whether the value is included in the set
bool get(uint32_t ch) const {
if (ch >= mMaxVal) return false;
@@ -69,7 +64,6 @@ public:
private:
void initFromRanges(const uint32_t* ranges, size_t nRanges);
- void initFromBuffer(BufferReader* reader);
static const uint32_t kMaximumCapacity = 0xFFFFFF;
static const int kLogValuesPerPage = 8;
@@ -87,15 +81,10 @@ private:
static int CountLeadingZeros(element x);
uint32_t mMaxVal;
- uint32_t mIndicesCount;
- const uint16_t* mIndices;
- uint32_t mBitmapsCount;
- const element* mBitmaps;
- uint16_t mZeroPageIndex;
- // Owns allocated memory if this class is created from ranges, otherwise these are nullptr.
- std::unique_ptr<uint16_t[]> mOwnedIndices;
- std::unique_ptr<element[]> mOwnedBitmaps;
+ std::unique_ptr<uint16_t[]> mIndices;
+ std::unique_ptr<element[]> mBitmaps;
+ uint16_t mZeroPageIndex;
// Forbid copy and assign.
SparseBitSet(const SparseBitSet&) = delete;
diff --git a/include/minikin/SystemFonts.h b/include/minikin/SystemFonts.h
index cf4ab75..4108215 100644
--- a/include/minikin/SystemFonts.h
+++ b/include/minikin/SystemFonts.h
@@ -19,7 +19,6 @@
#include <map>
#include <memory>
-#include <mutex>
#include <string>
#include "minikin/FontCollection.h"
@@ -34,78 +33,39 @@ public:
return getInstance().findFontCollectionInternal(familyName);
}
+ // Do not call this function outside Zygote process.
static void registerFallback(const std::string& familyName,
const std::shared_ptr<FontCollection>& fc) {
return getInstance().registerFallbackInternal(familyName, fc);
}
+ // Do not call this function outside Zygote process.
static void registerDefault(const std::shared_ptr<FontCollection>& fc) {
return getInstance().registerDefaultInternal(fc);
}
- using FontMapDeleter = std::function<void()>;
-
- static void addFontMap(std::shared_ptr<FontCollection>&& collections) {
- return getInstance().addFontMapInternal(std::move(collections));
- }
-
- // This obtains a mutex inside, so do not call this method inside callback.
- static void getFontMap(
- std::function<void(const std::vector<std::shared_ptr<FontCollection>>&)> func) {
- return getInstance().getFontMapInternal(func);
- }
-
- static void getFontSet(std::function<void(const std::vector<std::shared_ptr<Font>>&)> func) {
- return getInstance().getFontSetInternal(func);
- }
-
protected:
// Visible for testing purposes.
SystemFonts() {}
virtual ~SystemFonts() {}
- std::shared_ptr<FontCollection> findFontCollectionInternal(const std::string& familyName);
+ std::shared_ptr<FontCollection> findFontCollectionInternal(const std::string& familyName) const;
void registerFallbackInternal(const std::string& familyName,
const std::shared_ptr<FontCollection>& fc) {
- std::lock_guard<std::mutex> lock(mMutex);
- mSystemFallbacks[familyName] = fc;
+ mSystemFallbacks.insert(std::make_pair(familyName, fc));
}
void registerDefaultInternal(const std::shared_ptr<FontCollection>& fc) {
- std::lock_guard<std::mutex> lock(mMutex);
mDefaultFallback = fc;
}
- void addFontMapInternal(std::shared_ptr<FontCollection>&& collections) {
- std::lock_guard<std::mutex> lock(mMutex);
- mCollections.emplace_back(std::move(collections));
- }
-
- void getFontMapInternal(
- std::function<void(const std::vector<std::shared_ptr<FontCollection>>&)> func) {
- std::lock_guard<std::mutex> lock(mMutex);
- func(mCollections);
- }
-
- void getFontSetInternal(std::function<void(const std::vector<std::shared_ptr<Font>>&)> func) {
- std::lock_guard<std::mutex> lock(mMutex);
- if (!mFonts) {
- buildFontSetLocked();
- }
- func(mFonts.value());
- }
-
private:
static SystemFonts& getInstance();
- void buildFontSetLocked() EXCLUSIVE_LOCKS_REQUIRED(mMutex);
-
- std::map<std::string, std::shared_ptr<FontCollection>> mSystemFallbacks GUARDED_BY(mMutex);
- std::shared_ptr<FontCollection> mDefaultFallback GUARDED_BY(mMutex);
- std::vector<std::shared_ptr<FontCollection>> mCollections GUARDED_BY(mMutex);
- std::optional<std::vector<std::shared_ptr<Font>>> mFonts GUARDED_BY(mMutex);
-
- std::mutex mMutex;
+ // There is no mutex guard here since registerFallback is designed to be
+ // called only in Zygote.
+ std::map<std::string, std::shared_ptr<FontCollection>> mSystemFallbacks;
+ std::shared_ptr<FontCollection> mDefaultFallback;
};
} // namespace minikin
diff --git a/libs/minikin/Android.bp b/libs/minikin/Android.bp
index 8356ea4..9c20758 100644
--- a/libs/minikin/Android.bp
+++ b/libs/minikin/Android.bp
@@ -12,10 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library_headers {
name: "libminikin-headers-for-tests",
export_include_dirs: ["."],
@@ -28,13 +24,10 @@ cc_library {
host_supported: true,
srcs: [
"BidiUtils.cpp",
- "BoundsCache.cpp",
"CmapCoverage.cpp",
"Emoji.cpp",
- "Font.cpp",
"FontCollection.cpp",
"FontFamily.cpp",
- "FontFileParser.cpp",
"FontUtils.cpp",
"GraphemeBreak.cpp",
"GreedyLineBreaker.cpp",
@@ -88,6 +81,7 @@ cc_library {
"libutils_headers",
],
export_header_lib_headers: ["libminikin_headers"],
+ whole_static_libs: ["libgtest_prod"],
clang: true,
diff --git a/libs/minikin/BoundsCache.cpp b/libs/minikin/BoundsCache.cpp
deleted file mode 100644
index 1edc853..0000000
--- a/libs/minikin/BoundsCache.cpp
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "minikin/BoundsCache.h"
-
-namespace minikin {
-
-void ValueExtractor::operator()(const LayoutPiece& layoutPiece, const MinikinPaint& paint) {
- value.reset(new BoundsValue);
- value->rect = BoundsCache::getBounds(layoutPiece, paint);
- value->advance = layoutPiece.advance();
-}
-
-// static
-MinikinRect BoundsCache::getBounds(const LayoutPiece& layoutPiece, const MinikinPaint& paint) {
- MinikinRect pieceBounds;
- MinikinRect tmpRect;
- for (uint32_t i = 0; i < layoutPiece.glyphCount(); ++i) {
- const FakedFont& font = layoutPiece.fontAt(i);
- const Point& point = layoutPiece.pointAt(i);
-
- MinikinFont* minikinFont = font.font->typeface().get();
- minikinFont->GetBounds(&tmpRect, layoutPiece.glyphIdAt(i), paint, font.fakery);
- tmpRect.offset(point.x, point.y);
- pieceBounds.join(tmpRect);
- }
- return pieceBounds;
-}
-
-} // namespace minikin
diff --git a/libs/minikin/Font.cpp b/libs/minikin/Font.cpp
deleted file mode 100644
index c2e74b7..0000000
--- a/libs/minikin/Font.cpp
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#define LOG_TAG "Minikin"
-
-#include "minikin/Font.h"
-
-#include <vector>
-
-#include <hb-ot.h>
-#include <hb.h>
-#include <log/log.h>
-
-#include "minikin/HbUtils.h"
-#include "minikin/MinikinFont.h"
-
-#include "FontUtils.h"
-#include "MinikinInternal.h"
-
-namespace minikin {
-
-std::shared_ptr<Font> Font::Builder::build() {
- if (mIsWeightSet && mIsSlantSet) {
- // No need to read OS/2 header of the font file.
- return std::shared_ptr<Font>(new Font(std::move(mTypeface), FontStyle(mWeight, mSlant),
- prepareFont(mTypeface), mLocaleListId));
- }
-
- HbFontUniquePtr font = prepareFont(mTypeface);
- FontStyle styleFromFont = analyzeStyle(font);
- if (!mIsWeightSet) {
- mWeight = styleFromFont.weight();
- }
- if (!mIsSlantSet) {
- mSlant = styleFromFont.slant();
- }
- return std::shared_ptr<Font>(new Font(std::move(mTypeface), FontStyle(mWeight, mSlant),
- std::move(font), mLocaleListId));
-}
-
-const std::shared_ptr<MinikinFont>& Font::typeface() const {
- std::lock_guard lock(mTypefaceMutex);
- if (mTypeface) return mTypeface;
- initTypefaceLocked();
- return mTypeface;
-}
-
-const HbFontUniquePtr& Font::baseFont() const {
- std::lock_guard lock(mTypefaceMutex);
- if (mBaseFont) return mBaseFont;
- initTypefaceLocked();
- mBaseFont = prepareFont(mTypeface);
- return mBaseFont;
-}
-
-void Font::initTypefaceLocked() const {
- if (mTypeface) return;
- MINIKIN_ASSERT(mTypefaceLoader, "mTypefaceLoader should not be empty when mTypeface is null");
- mTypeface = mTypefaceLoader(mTypefaceMetadataReader);
-}
-
-// static
-HbFontUniquePtr Font::prepareFont(const std::shared_ptr<MinikinFont>& typeface) {
- const char* buf = reinterpret_cast<const char*>(typeface->GetFontData());
- size_t size = typeface->GetFontSize();
- uint32_t ttcIndex = typeface->GetFontIndex();
-
- HbBlobUniquePtr blob(hb_blob_create(buf, size, HB_MEMORY_MODE_READONLY, nullptr, nullptr));
- HbFaceUniquePtr face(hb_face_create(blob.get(), ttcIndex));
- HbFontUniquePtr parent(hb_font_create(face.get()));
- hb_ot_font_set_funcs(parent.get());
-
- uint32_t upem = hb_face_get_upem(face.get());
- hb_font_set_scale(parent.get(), upem, upem);
-
- HbFontUniquePtr font(hb_font_create_sub_font(parent.get()));
- std::vector<hb_variation_t> variations;
- variations.reserve(typeface->GetAxes().size());
- for (const FontVariation& variation : typeface->GetAxes()) {
- variations.push_back({variation.axisTag, variation.value});
- }
- hb_font_set_variations(font.get(), variations.data(), variations.size());
- return font;
-}
-
-// static
-FontStyle Font::analyzeStyle(const HbFontUniquePtr& font) {
- HbBlob os2Table(font, MinikinFont::MakeTag('O', 'S', '/', '2'));
- if (!os2Table) {
- return FontStyle();
- }
-
- int weight;
- bool italic;
- if (!::minikin::analyzeStyle(os2Table.get(), os2Table.size(), &weight, &italic)) {
- return FontStyle();
- }
- // TODO: Update weight/italic based on fvar value.
- return FontStyle(static_cast<uint16_t>(weight), static_cast<FontStyle::Slant>(italic));
-}
-
-std::unordered_set<AxisTag> Font::getSupportedAxes() const {
- HbBlob fvarTable(baseFont(), MinikinFont::MakeTag('f', 'v', 'a', 'r'));
- if (!fvarTable) {
- return std::unordered_set<AxisTag>();
- }
- std::unordered_set<AxisTag> supportedAxes;
- analyzeAxes(fvarTable.get(), fvarTable.size(), &supportedAxes);
- return supportedAxes;
-}
-
-} // namespace minikin
diff --git a/libs/minikin/FontCollection.cpp b/libs/minikin/FontCollection.cpp
index 9e4dd3b..6cbabea 100644
--- a/libs/minikin/FontCollection.cpp
+++ b/libs/minikin/FontCollection.cpp
@@ -24,7 +24,6 @@
#include <unicode/unorm2.h>
#include "minikin/Emoji.h"
-#include "minikin/FontFileParser.h"
#include "Locale.h"
#include "LocaleListCache.h"
@@ -44,23 +43,6 @@ const uint32_t TEXT_STYLE_VS = 0xFE0E;
static std::atomic<uint32_t> gNextCollectionId = {0};
-namespace {
-
-uint32_t getGlyphCount(U16StringPiece text, uint32_t start, uint32_t end,
- const HbFontUniquePtr& font) {
- HbBufferUniquePtr buffer(hb_buffer_create());
- hb_buffer_set_direction(buffer.get(), HB_DIRECTION_LTR);
- hb_buffer_add_utf16(buffer.get(), text.data() + start, end - start, 0, end - start);
- hb_buffer_guess_segment_properties(buffer.get());
-
- unsigned int numGlyphs = -1;
- hb_shape(font.get(), buffer.get(), nullptr, 0);
- hb_buffer_get_glyph_infos(buffer.get(), &numGlyphs);
- return numGlyphs;
-}
-
-} // namespace
-
FontCollection::FontCollection(std::shared_ptr<FontFamily>&& typeface) : mMaxChar(0) {
std::vector<std::shared_ptr<FontFamily>> typefaces;
typefaces.push_back(typeface);
@@ -101,91 +83,24 @@ void FontCollection::init(const vector<std::shared_ptr<FontFamily>>& typefaces)
// A font can have a glyph for a base code point and variation selector pair but no glyph for
// the base code point without variation selector. The family won't be listed in the range in
// this case.
- mOwnedRanges = std::make_unique<Range[]>(nPages);
- mRanges = mOwnedRanges.get();
- mRangesCount = nPages;
for (size_t i = 0; i < nPages; i++) {
- Range* range = &mOwnedRanges[i];
- range->start = mOwnedFamilyVec.size();
+ Range dummy;
+ mRanges.push_back(dummy);
+ Range* range = &mRanges.back();
+ range->start = mFamilyVec.size();
for (size_t j = 0; j < nTypefaces; j++) {
if (lastChar[j] < (i + 1) << kLogCharsPerPage) {
const std::shared_ptr<FontFamily>& family = mFamilies[j];
- mOwnedFamilyVec.push_back(static_cast<uint8_t>(j));
+ mFamilyVec.push_back(static_cast<uint8_t>(j));
uint32_t nextChar = family->getCoverage().nextSetBit((i + 1) << kLogCharsPerPage);
lastChar[j] = nextChar;
}
}
- range->end = mOwnedFamilyVec.size();
+ range->end = mFamilyVec.size();
}
// See the comment in Range for more details.
- LOG_ALWAYS_FATAL_IF(mOwnedFamilyVec.size() >= 0xFFFF,
+ LOG_ALWAYS_FATAL_IF(mFamilyVec.size() >= 0xFFFF,
"Exceeded the maximum indexable cmap coverage.");
- mFamilyVec = mOwnedFamilyVec.data();
- mFamilyVecCount = mOwnedFamilyVec.size();
-}
-
-FontCollection::FontCollection(BufferReader* reader,
- const std::vector<std::shared_ptr<FontFamily>>& families) {
- mId = gNextCollectionId++;
- mMaxChar = reader->read<uint32_t>();
- uint32_t familiesCount = reader->read<uint32_t>();
- mFamilies.reserve(familiesCount);
- for (uint32_t i = 0; i < familiesCount; i++) {
- uint32_t index = reader->read<uint32_t>();
- if (index >= families.size()) {
- ALOGE("Invalid FontFamily index: %zu", (size_t)index);
- } else {
- mFamilies.push_back(families[index]);
- if (families[index]->hasVSTable()) {
- mVSFamilyVec.push_back(families[index]);
- }
- }
- }
- // Range is two packed uint16_t
- static_assert(sizeof(Range) == 4);
- std::tie(mRanges, mRangesCount) = reader->readArray<Range>();
- std::tie(mFamilyVec, mFamilyVecCount) = reader->readArray<uint8_t>();
- const auto& [axesPtr, axesCount] = reader->readArray<AxisTag>();
- mSupportedAxes.insert(axesPtr, axesPtr + axesCount);
-}
-
-void FontCollection::writeTo(BufferWriter* writer,
- const std::unordered_map<std::shared_ptr<FontFamily>, uint32_t>&
- fontFamilyToIndexMap) const {
- writer->write<uint32_t>(mMaxChar);
- writer->write<uint32_t>(mFamilies.size());
- for (const std::shared_ptr<FontFamily>& fontFamily : mFamilies) {
- auto it = fontFamilyToIndexMap.find(fontFamily);
- if (it == fontFamilyToIndexMap.end()) {
- ALOGE("fontFamily not found in fontFamilyToIndexMap");
- writer->write<uint32_t>(-1);
- } else {
- writer->write<uint32_t>(it->second);
- }
- }
- writer->writeArray<Range>(mRanges, mRangesCount);
- writer->writeArray<uint8_t>(mFamilyVec, mFamilyVecCount);
- // No need to serialize mVSFamilyVec as it can be reconstructed easily from mFamilies.
- std::vector<AxisTag> axes(mSupportedAxes.begin(), mSupportedAxes.end());
- // Sort axes to be deterministic.
- std::sort(axes.begin(), axes.end());
- writer->writeArray<AxisTag>(axes.data(), axes.size());
-}
-
-// static
-void FontCollection::collectAllFontFamilies(
- const std::vector<std::shared_ptr<FontCollection>>& fontCollections,
- std::vector<std::shared_ptr<FontFamily>>* outAllFontFamilies,
- std::unordered_map<std::shared_ptr<FontFamily>, uint32_t>* outFontFamilyToIndexMap) {
- for (const auto& fontCollection : fontCollections) {
- for (const std::shared_ptr<FontFamily>& fontFamily : fontCollection->mFamilies) {
- bool inserted =
- outFontFamilyToIndexMap->emplace(fontFamily, outAllFontFamilies->size()).second;
- if (inserted) {
- outAllFontFamilies->push_back(fontFamily);
- }
- }
- }
}
// Special scores for the font fallback.
@@ -334,11 +249,11 @@ uint32_t FontCollection::calcVariantMatchingScore(FamilyVariant variant,
// 2. Calculate a score for the font family. See comments in calcFamilyScore for the detail.
// 3. Highest score wins, with ties resolved to the first font.
// This method never returns nullptr.
-FontCollection::FamilyMatchResult FontCollection::getFamilyForChar(uint32_t ch, uint32_t vs,
- uint32_t localeListId,
- FamilyVariant variant) const {
+const std::shared_ptr<FontFamily>& FontCollection::getFamilyForChar(uint32_t ch, uint32_t vs,
+ uint32_t localeListId,
+ FamilyVariant variant) const {
if (ch >= mMaxChar) {
- return FamilyMatchResult::Builder().add(0).build();
+ return mFamilies[0];
}
Range range = mRanges[ch >> kLogCharsPerPage];
@@ -347,27 +262,23 @@ FontCollection::FamilyMatchResult FontCollection::getFamilyForChar(uint32_t ch,
range = {0, static_cast<uint16_t>(mFamilies.size())};
}
+ int bestFamilyIndex = -1;
uint32_t bestScore = kUnsupportedFontScore;
- FamilyMatchResult::Builder builder;
-
for (size_t i = range.start; i < range.end; i++) {
- const uint8_t familyIndex = vs == 0 ? mFamilyVec[i] : i;
- const std::shared_ptr<FontFamily>& family = mFamilies[familyIndex];
+ const std::shared_ptr<FontFamily>& family =
+ vs == 0 ? mFamilies[mFamilyVec[i]] : mFamilies[i];
const uint32_t score = calcFamilyScore(ch, vs, variant, localeListId, family);
if (score == kFirstFontScore) {
// If the first font family supports the given character or variation sequence, always
// use it.
- return builder.add(familyIndex).build();
+ return family;
}
- if (score != kUnsupportedFontScore && score >= bestScore) {
- if (score > bestScore) {
- builder.reset();
- bestScore = score;
- }
- builder.add(familyIndex);
+ if (score > bestScore) {
+ bestScore = score;
+ bestFamilyIndex = i;
}
}
- if (builder.empty()) {
+ if (bestFamilyIndex == -1) {
UErrorCode errorCode = U_ZERO_ERROR;
const UNormalizer2* normalizer = unorm2_getNFDInstance(&errorCode);
if (U_SUCCESS(errorCode)) {
@@ -379,9 +290,9 @@ FontCollection::FamilyMatchResult FontCollection::getFamilyForChar(uint32_t ch,
return getFamilyForChar(ch, vs, localeListId, variant);
}
}
- return FamilyMatchResult::Builder().add(0).build();
+ return mFamilies[0];
}
- return builder.build();
+ return vs == 0 ? mFamilies[mFamilyVec[bestFamilyIndex]] : mFamilies[bestFamilyIndex];
}
// Characters where we want to continue using existing font run for (or stick to the next run if
@@ -401,7 +312,7 @@ static bool doesNotNeedFontSupport(uint32_t c) {
// Characters where we want to continue using existing font run instead of
// recomputing the best match in the fallback list.
-static const uint32_t stickyAllowlist[] = {
+static const uint32_t stickyWhitelist[] = {
'!', ',', '-', '.', ':', ';', '?',
0x00A0, // NBSP
0x2010, // HYPHEN
@@ -412,9 +323,9 @@ static const uint32_t stickyAllowlist[] = {
0x2695, // STAFF_OF_AESCULAPIUS
};
-static bool isStickyAllowlisted(uint32_t c) {
- for (size_t i = 0; i < sizeof(stickyAllowlist) / sizeof(stickyAllowlist[0]); i++) {
- if (stickyAllowlist[i] == c) return true;
+static bool isStickyWhitelisted(uint32_t c) {
+ for (size_t i = 0; i < sizeof(stickyWhitelist) / sizeof(stickyWhitelist[0]); i++) {
+ if (stickyWhitelist[i] == c) return true;
}
return false;
}
@@ -457,45 +368,22 @@ bool FontCollection::hasVariationSelector(uint32_t baseCodepoint,
constexpr uint32_t REPLACEMENT_CHARACTER = 0xFFFD;
-FontCollection::FamilyMatchResult FontCollection::FamilyMatchResult::intersect(
- FontCollection::FamilyMatchResult l, FontCollection::FamilyMatchResult r) {
- if (l == r) {
- return l;
- }
-
- uint32_t li = 0;
- uint32_t ri = 0;
- FamilyMatchResult::Builder b;
- while (li < l.size() && ri < r.size()) {
- if (l[li] < r[ri]) {
- li++;
- } else if (l[li] > r[ri]) {
- ri++;
- } else { // l[li] == r[ri]
- b.add(l[li]);
- li++;
- ri++;
- }
- }
- return b.build();
-}
-
-std::vector<FontCollection::Run> FontCollection::itemize(U16StringPiece text, FontStyle,
+std::vector<FontCollection::Run> FontCollection::itemize(U16StringPiece text, FontStyle style,
uint32_t localeListId,
FamilyVariant familyVariant,
uint32_t runMax) const {
const uint16_t* string = text.data();
const uint32_t string_size = text.size();
+ std::vector<Run> result;
- FamilyMatchResult lastFamilyIndices = FamilyMatchResult();
+ const FontFamily* lastFamily = nullptr;
+ Run* run = nullptr;
if (string_size == 0) {
- return std::vector<Run>();
+ return result;
}
const uint32_t kEndOfString = 0xFFFFFFFF;
- std::vector<Run> result;
- Run* run = nullptr;
uint32_t nextCh = 0;
uint32_t prevCh = 0;
@@ -523,44 +411,15 @@ std::vector<FontCollection::Run> FontCollection::itemize(U16StringPiece text, Fo
if (doesNotNeedFontSupport(ch)) {
// Always continue if the character is a format character not needed to be in the font.
shouldContinueRun = true;
- } else if (!lastFamilyIndices.empty() && (isStickyAllowlisted(ch) || isCombining(ch))) {
+ } else if (lastFamily != nullptr && (isStickyWhitelisted(ch) || isCombining(ch))) {
// Continue using existing font as long as it has coverage and is whitelisted.
-
- const std::shared_ptr<FontFamily>& lastFamily = mFamilies[lastFamilyIndices[0]];
- if (lastFamily->isColorEmojiFamily()) {
- // If the last family is color emoji font, find the longest family.
- shouldContinueRun = false;
- for (uint8_t ix : lastFamilyIndices) {
- shouldContinueRun |= mFamilies[ix]->getCoverage().get(ch);
- }
- } else {
- shouldContinueRun = lastFamily->getCoverage().get(ch);
- }
+ shouldContinueRun = lastFamily->getCoverage().get(ch);
}
if (!shouldContinueRun) {
- FamilyMatchResult familyIndices = getFamilyForChar(
+ const std::shared_ptr<FontFamily>& family = getFamilyForChar(
ch, isVariationSelector(nextCh) ? nextCh : 0, localeListId, familyVariant);
- bool breakRun;
- if (utf16Pos == 0 || lastFamilyIndices.empty()) {
- breakRun = true;
- } else {
- const std::shared_ptr<FontFamily>& lastFamily = mFamilies[lastFamilyIndices[0]];
- if (lastFamily->isColorEmojiFamily()) {
- FamilyMatchResult intersection =
- FamilyMatchResult::intersect(familyIndices, lastFamilyIndices);
- if (intersection.empty()) {
- breakRun = true; // None of last family can draw the given char.
- } else {
- lastFamilyIndices = intersection;
- breakRun = false;
- }
- } else {
- breakRun = familyIndices[0] != lastFamilyIndices[0];
- }
- }
-
- if (breakRun) {
+ if (utf16Pos == 0 || family.get() != lastFamily) {
size_t start = utf16Pos;
// Workaround for combining marks and emoji modifiers until we implement
// per-cluster font selection: if a combining mark or an emoji modifier is found in
@@ -568,31 +427,27 @@ std::vector<FontCollection::Run> FontCollection::itemize(U16StringPiece text, Fo
// character to the new run. U+20E3 COMBINING ENCLOSING KEYCAP, used in emoji, is
// handled properly by this since it's a combining mark too.
if (utf16Pos != 0 &&
- (isCombining(ch) || (isEmojiModifier(ch) && isEmojiBase(prevCh)))) {
- for (uint8_t ix : familyIndices) {
- if (mFamilies[ix]->getCoverage().get(prevCh)) {
- const size_t prevChLength = U16_LENGTH(prevCh);
- if (run != nullptr) {
- run->end -= prevChLength;
- if (run->start == run->end) {
- result.pop_back();
- }
- }
- start -= prevChLength;
- break;
+ (isCombining(ch) || (isEmojiModifier(ch) && isEmojiBase(prevCh))) &&
+ family != nullptr && family->getCoverage().get(prevCh)) {
+ const size_t prevChLength = U16_LENGTH(prevCh);
+ if (run != nullptr) {
+ run->end -= prevChLength;
+ if (run->start == run->end) {
+ result.pop_back();
}
}
+ start -= prevChLength;
}
- if (lastFamilyIndices.empty()) {
+ if (lastFamily == nullptr) {
// This is the first family ever assigned. We are either seeing the very first
// character (which means start would already be zero), or we have only seen
// characters that don't need any font support (which means we need to adjust
// start to be 0 to include those characters).
start = 0;
}
- result.push_back({familyIndices, static_cast<int>(start), 0});
+ result.push_back({family->getClosestMatch(style), static_cast<int>(start), 0});
run = &result.back();
- lastFamilyIndices = run->familyMatch;
+ lastFamily = family.get();
}
}
prevCh = ch;
@@ -610,42 +465,19 @@ std::vector<FontCollection::Run> FontCollection::itemize(U16StringPiece text, Fo
}
} while (nextCh != kEndOfString);
- if (lastFamilyIndices.empty()) {
+ if (lastFamily == nullptr) {
// No character needed any font support, so it doesn't really matter which font they end up
// getting displayed in. We put the whole string in one run, using the first font.
- result.push_back(
- {FamilyMatchResult::Builder().add(0).build(), 0, static_cast<int>(string_size)});
+ result.push_back({mFamilies[0]->getClosestMatch(style), 0, static_cast<int>(string_size)});
}
if (result.size() > runMax) {
// The itemization has terminated since it reaches the runMax. Remove last unfinalized runs.
- return std::vector<Run>(result.begin(), result.begin() + runMax);
+ result.resize(runMax);
}
-
return result;
}
-FakedFont FontCollection::getBestFont(U16StringPiece text, const Run& run, FontStyle style) {
- uint8_t bestIndex = 0;
- uint32_t bestGlyphCount = 0xFFFFFFFF;
-
- const std::shared_ptr<FontFamily>& family = mFamilies[run.familyMatch[0]];
- if (family->isColorEmojiFamily() && run.familyMatch.size() > 1) {
- for (size_t i = 0; i < run.familyMatch.size(); ++i) {
- const std::shared_ptr<FontFamily>& family = mFamilies[run.familyMatch[i]];
- const HbFontUniquePtr& font = family->getFont(0)->baseFont();
- uint32_t glyphCount = getGlyphCount(text, run.start, run.end, font);
- if (glyphCount < bestGlyphCount) {
- bestIndex = run.familyMatch[i];
- bestGlyphCount = glyphCount;
- }
- }
- } else {
- bestIndex = run.familyMatch[0];
- }
- return mFamilies[bestIndex]->getClosestMatch(style);
-}
-
FakedFont FontCollection::baseFontFaked(FontStyle style) {
return mFamilies[0]->getClosestMatch(style);
}
diff --git a/libs/minikin/FontFamily.cpp b/libs/minikin/FontFamily.cpp
index f1fd00a..85a5142 100644
--- a/libs/minikin/FontFamily.cpp
+++ b/libs/minikin/FontFamily.cpp
@@ -18,9 +18,11 @@
#include "minikin/FontFamily.h"
-#include <algorithm>
+#include <cstdint>
#include <vector>
+#include <hb-ot.h>
+#include <hb.h>
#include <log/log.h>
#include "minikin/CmapCoverage.h"
@@ -35,101 +37,92 @@
namespace minikin {
-FontFamily::FontFamily(std::vector<std::shared_ptr<Font>>&& fonts)
- : FontFamily(FamilyVariant::DEFAULT, std::move(fonts)) {}
-
-FontFamily::FontFamily(FamilyVariant variant, std::vector<std::shared_ptr<Font>>&& fonts)
- : FontFamily(kEmptyLocaleListId, variant, std::move(fonts), false /* isCustomFallback */) {}
+Font Font::Builder::build() {
+ if (mIsWeightSet && mIsSlantSet) {
+ // No need to read OS/2 header of the font file.
+ return Font(std::move(mTypeface), FontStyle(mWeight, mSlant), prepareFont(mTypeface));
+ }
-FontFamily::FontFamily(uint32_t localeListId, FamilyVariant variant,
- std::vector<std::shared_ptr<Font>>&& fonts, bool isCustomFallback)
- : mLocaleListId(localeListId),
- mVariant(variant),
- mFonts(std::move(fonts)),
- mIsColorEmoji(LocaleListCache::getById(localeListId).getEmojiStyle() ==
- EmojiStyle::EMOJI),
- mIsCustomFallback(isCustomFallback) {
- MINIKIN_ASSERT(!mFonts.empty(), "FontFamily must contain at least one font.");
- computeCoverage();
+ HbFontUniquePtr font = prepareFont(mTypeface);
+ FontStyle styleFromFont = analyzeStyle(font);
+ if (!mIsWeightSet) {
+ mWeight = styleFromFont.weight();
+ }
+ if (!mIsSlantSet) {
+ mSlant = styleFromFont.slant();
+ }
+ return Font(std::move(mTypeface), FontStyle(mWeight, mSlant), std::move(font));
}
-FontFamily::FontFamily(uint32_t localeListId, FamilyVariant variant,
- std::vector<std::shared_ptr<Font>>&& fonts,
- std::unordered_set<AxisTag>&& supportedAxes, bool isColorEmoji,
- bool isCustomFallback, SparseBitSet&& coverage,
- std::vector<std::unique_ptr<SparseBitSet>>&& cmapFmt14Coverage)
- : mLocaleListId(localeListId),
- mVariant(variant),
- mFonts(std::move(fonts)),
- mSupportedAxes(std::move(supportedAxes)),
- mIsColorEmoji(isColorEmoji),
- mIsCustomFallback(isCustomFallback),
- mCoverage(std::move(coverage)),
- mCmapFmt14Coverage(std::move(cmapFmt14Coverage)) {}
-
-// Read fields other than mFonts, mLocaleList.
// static
-std::shared_ptr<FontFamily> FontFamily::readFromInternal(BufferReader* reader,
- std::vector<std::shared_ptr<Font>>&& fonts,
- uint32_t localeListId) {
- // FamilyVariant is uint8_t
- static_assert(sizeof(FamilyVariant) == 1);
- FamilyVariant variant = reader->read<FamilyVariant>();
- // AxisTag is uint32_t
- static_assert(sizeof(AxisTag) == 4);
- const auto& [axesPtr, axesCount] = reader->readArray<AxisTag>();
- std::unordered_set<AxisTag> supportedAxes(axesPtr, axesPtr + axesCount);
- bool isColorEmoji = static_cast<bool>(reader->read<uint8_t>());
- bool isCustomFallback = static_cast<bool>(reader->read<uint8_t>());
- SparseBitSet coverage(reader);
- // Read mCmapFmt14Coverage. As it can have null entries, it is stored in the buffer as a sparse
- // array (size, non-null entry count, array of (index, entry)).
- uint32_t cmapFmt14CoverageSize = reader->read<uint32_t>();
- std::vector<std::unique_ptr<SparseBitSet>> cmapFmt14Coverage(cmapFmt14CoverageSize);
- uint32_t cmapFmt14CoverageEntryCount = reader->read<uint32_t>();
- for (uint32_t i = 0; i < cmapFmt14CoverageEntryCount; i++) {
- uint32_t index = reader->read<uint32_t>();
- cmapFmt14Coverage[index] = std::make_unique<SparseBitSet>(reader);
- }
- return std::shared_ptr<FontFamily>(new FontFamily(
- localeListId, variant, std::move(fonts), std::move(supportedAxes), isColorEmoji,
- isCustomFallback, std::move(coverage), std::move(cmapFmt14Coverage)));
+HbFontUniquePtr Font::prepareFont(const std::shared_ptr<MinikinFont>& typeface) {
+ const char* buf = reinterpret_cast<const char*>(typeface->GetFontData());
+ size_t size = typeface->GetFontSize();
+ uint32_t ttcIndex = typeface->GetFontIndex();
+
+ HbBlobUniquePtr blob(hb_blob_create(buf, size, HB_MEMORY_MODE_READONLY, nullptr, nullptr));
+ HbFaceUniquePtr face(hb_face_create(blob.get(), ttcIndex));
+ HbFontUniquePtr parent(hb_font_create(face.get()));
+ hb_ot_font_set_funcs(parent.get());
+
+ uint32_t upem = hb_face_get_upem(face.get());
+ hb_font_set_scale(parent.get(), upem, upem);
+
+ HbFontUniquePtr font(hb_font_create_sub_font(parent.get()));
+ std::vector<hb_variation_t> variations;
+ variations.reserve(typeface->GetAxes().size());
+ for (const FontVariation& variation : typeface->GetAxes()) {
+ variations.push_back({variation.axisTag, variation.value});
+ }
+ hb_font_set_variations(font.get(), variations.data(), variations.size());
+ return font;
}
// static
-uint32_t FontFamily::readLocaleListInternal(BufferReader* reader) {
- return LocaleListCache::readFrom(reader);
+FontStyle Font::analyzeStyle(const HbFontUniquePtr& font) {
+ HbBlob os2Table(font, MinikinFont::MakeTag('O', 'S', '/', '2'));
+ if (!os2Table) {
+ return FontStyle();
+ }
+
+ int weight;
+ bool italic;
+ if (!::minikin::analyzeStyle(os2Table.get(), os2Table.size(), &weight, &italic)) {
+ return FontStyle();
+ }
+ // TODO: Update weight/italic based on fvar value.
+ return FontStyle(static_cast<uint16_t>(weight), static_cast<FontStyle::Slant>(italic));
}
-// Write fields other than mFonts.
-void FontFamily::writeToInternal(BufferWriter* writer) const {
- writer->write<FamilyVariant>(mVariant);
- std::vector<AxisTag> axes(mSupportedAxes.begin(), mSupportedAxes.end());
- // Sort axes to be deterministic.
- std::sort(axes.begin(), axes.end());
- writer->writeArray<AxisTag>(axes.data(), axes.size());
- writer->write<uint8_t>(mIsColorEmoji);
- writer->write<uint8_t>(mIsCustomFallback);
- mCoverage.writeTo(writer);
- // Write mCmapFmt14Coverage as a sparse array (size, non-null entry count,
- // array of (index, entry))
- writer->write<uint32_t>(mCmapFmt14Coverage.size());
- uint32_t cmapFmt14CoverageEntryCount = 0;
- for (const std::unique_ptr<SparseBitSet>& coverage : mCmapFmt14Coverage) {
- if (coverage != nullptr) cmapFmt14CoverageEntryCount++;
- }
- writer->write<uint32_t>(cmapFmt14CoverageEntryCount);
- for (size_t i = 0; i < mCmapFmt14Coverage.size(); i++) {
- if (mCmapFmt14Coverage[i] != nullptr) {
- writer->write<uint32_t>(i);
- mCmapFmt14Coverage[i]->writeTo(writer);
- }
+std::unordered_set<AxisTag> Font::getSupportedAxes() const {
+ HbBlob fvarTable(mBaseFont, MinikinFont::MakeTag('f', 'v', 'a', 'r'));
+ if (!fvarTable) {
+ return std::unordered_set<AxisTag>();
}
+ std::unordered_set<AxisTag> supportedAxes;
+ analyzeAxes(fvarTable.get(), fvarTable.size(), &supportedAxes);
+ return supportedAxes;
}
-void FontFamily::writeLocaleListInternal(BufferWriter* writer) const {
- LocaleListCache::writeTo(writer, mLocaleListId);
+FontFamily::FontFamily(std::vector<Font>&& fonts)
+ : FontFamily(FamilyVariant::DEFAULT, std::move(fonts)) {}
+
+FontFamily::FontFamily(FamilyVariant variant, std::vector<Font>&& fonts)
+ : FontFamily(LocaleListCache::kEmptyListId, variant, std::move(fonts),
+ false /* isCustomFallback */) {}
+
+FontFamily::FontFamily(uint32_t localeListId, FamilyVariant variant, std::vector<Font>&& fonts,
+ bool isCustomFallback)
+ : mLocaleListId(localeListId),
+ mVariant(variant),
+ mFonts(std::move(fonts)),
+ mIsColorEmoji(LocaleListCache::getById(localeListId).getEmojiStyle() ==
+ EmojiStyle::EMOJI),
+ mIsCustomFallback(isCustomFallback) {
+ MINIKIN_ASSERT(!mFonts.empty(), "FontFamily must contain at least one font.");
+ computeCoverage();
}
+
// Compute a matching metric between two styles - 0 is an exact match
static int computeMatch(FontStyle style1, FontStyle style2) {
if (style1 == style2) return 0;
@@ -151,23 +144,21 @@ static FontFakery computeFakery(FontStyle wanted, FontStyle actual) {
}
FakedFont FontFamily::getClosestMatch(FontStyle style) const {
- int bestIndex = 0;
- Font* bestFont = mFonts[bestIndex].get();
+ const Font* bestFont = &mFonts[0];
int bestMatch = computeMatch(bestFont->style(), style);
for (size_t i = 1; i < mFonts.size(); i++) {
- Font* font = mFonts[i].get();
- int match = computeMatch(font->style(), style);
+ const Font& font = mFonts[i];
+ int match = computeMatch(font.style(), style);
if (i == 0 || match < bestMatch) {
- bestFont = font;
- bestIndex = i;
+ bestFont = &font;
bestMatch = match;
}
}
- return FakedFont{mFonts[bestIndex], computeFakery(style, bestFont->style())};
+ return FakedFont{bestFont, computeFakery(style, bestFont->style())};
}
void FontFamily::computeCoverage() {
- const std::shared_ptr<Font>& font = getClosestMatch(FontStyle()).font;
+ const Font* font = getClosestMatch(FontStyle()).font;
HbBlob cmapTable(font->baseFont(), MinikinFont::MakeTag('c', 'm', 'a', 'p'));
if (cmapTable.get() == nullptr) {
ALOGE("Could not get cmap table size!\n");
@@ -177,7 +168,7 @@ void FontFamily::computeCoverage() {
mCoverage = CmapCoverage::getCoverage(cmapTable.get(), cmapTable.size(), &mCmapFmt14Coverage);
for (size_t i = 0; i < mFonts.size(); ++i) {
- std::unordered_set<AxisTag> supportedAxes = mFonts[i]->getSupportedAxes();
+ std::unordered_set<AxisTag> supportedAxes = mFonts[i].getSupportedAxes();
mSupportedAxes.insert(supportedAxes.begin(), supportedAxes.end());
}
}
@@ -225,10 +216,10 @@ std::shared_ptr<FontFamily> FontFamily::createFamilyWithVariation(
return nullptr;
}
- std::vector<std::shared_ptr<Font>> fonts;
- for (const auto& font : mFonts) {
+ std::vector<Font> fonts;
+ for (const Font& font : mFonts) {
bool supportedVariations = false;
- std::unordered_set<AxisTag> supportedAxes = font->getSupportedAxes();
+ std::unordered_set<AxisTag> supportedAxes = font.getSupportedAxes();
if (!supportedAxes.empty()) {
for (const FontVariation& variation : variations) {
if (supportedAxes.find(variation.axisTag) != supportedAxes.end()) {
@@ -239,13 +230,12 @@ std::shared_ptr<FontFamily> FontFamily::createFamilyWithVariation(
}
std::shared_ptr<MinikinFont> minikinFont;
if (supportedVariations) {
- minikinFont = font->typeface()->createFontWithVariation(variations);
+ minikinFont = font.typeface()->createFontWithVariation(variations);
}
if (minikinFont == nullptr) {
- fonts.push_back(font);
- } else {
- fonts.push_back(Font::Builder(minikinFont).setStyle(font->style()).build());
+ minikinFont = font.typeface();
}
+ fonts.push_back(Font::Builder(minikinFont).setStyle(font.style()).build());
}
return std::shared_ptr<FontFamily>(
diff --git a/libs/minikin/FontFileParser.cpp b/libs/minikin/FontFileParser.cpp
deleted file mode 100644
index 1bcb711..0000000
--- a/libs/minikin/FontFileParser.cpp
+++ /dev/null
@@ -1,219 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "minikin/FontFileParser.h"
-
-#define LOG_TAG "Minikin"
-
-#include <cstdint>
-#include <optional>
-#include <string>
-#include <vector>
-
-#include <hb-ot.h>
-#include <hb.h>
-
-#include "MinikinInternal.h"
-#include "minikin/MinikinFont.h"
-
-namespace minikin {
-
-namespace {
-
-class SafeFontBufferReader {
-public:
- SafeFontBufferReader(const void* buffer, size_t size)
- : mBuffer(reinterpret_cast<const uint8_t*>(buffer)),
- mSize(size),
- mPos(0),
- mError(false) {}
-
- template <typename T>
- T readBE() {
- if (mError) return T();
-
- if ((mSize - mPos) < sizeof(T)) {
- mError = true;
- return T();
- }
- const T* data = reinterpret_cast<const T*>(mBuffer + mPos);
- mPos += sizeof(T);
- return *data;
- }
-
- uint16_t readU16() {
- if (mError) return 0;
-
- if ((mSize - mPos) < 2) {
- mError = true;
- return 0;
- }
- uint16_t out = ((uint32_t)mBuffer[mPos]) << 8 | ((uint32_t)mBuffer[mPos + 1]);
- mPos += 2;
- return out;
- };
-
- uint32_t readU32() {
- if (mError) return 0;
-
- if ((mSize - mPos) < 4) {
- mError = true;
- return 0;
- }
-
- uint32_t out = ((uint32_t)mBuffer[mPos]) << 24 | ((uint32_t)mBuffer[mPos + 1]) << 16 |
- ((uint32_t)mBuffer[mPos + 2]) << 8 | ((uint32_t)mBuffer[mPos + 3]);
- mPos += 4;
- return out;
- };
-
- void seek(size_t pos) {
- if (mError) return;
-
- if (pos > mSize) {
- mError = true;
- } else {
- mPos = pos;
- }
- }
-
- size_t remaining() const {
- if (mError) return 0;
- return mSize - mPos;
- }
-
- bool error() const { return mError; }
-
-private:
- const uint8_t* mBuffer;
- size_t mSize;
- size_t mPos;
- bool mError;
-};
-
-bool isPostScriptNameAllowedChar(char c) {
- // OpenType spec says only ASCII codes 33 to 126, ecept for the '[', ']', '(', ')', '{', '}',
- // '<', '>', '/', '%'.
- if (!(33 <= c && c <= 126)) {
- return false;
- }
- if (c == '[' || c == ']' || c == '(' || c == ')' || c == '{' || c == '}' || c == '<' ||
- c == '>' || c == '/' || c == '%') {
- return false;
- }
-
- return true;
-}
-
-} // namespace
-
-// static
-bool FontFileParser::analyzeFontRevision(const uint8_t* head_data, size_t head_size,
- uint32_t* out) {
- SafeFontBufferReader reader(head_data, head_size);
-
- if (reader.remaining() < 8) {
- return false; // At least head table has 8 bytes, for version and fontRevision
- }
-
- uint32_t majorVersion = reader.readU16();
- if (reader.error()) return false;
- uint32_t minorVersion = reader.readU16();
- if (reader.error()) return false;
-
- // Invalid head table header.
- if (majorVersion != 1 && minorVersion != 0) return false;
-
- *out = reader.readU32();
- if (reader.error()) return false;
- return true;
-}
-
-// static
-bool FontFileParser::checkPSName(const std::string& psName) {
- if (psName.size() > 63) return false;
-
- for (auto c : psName) {
- if (!isPostScriptNameAllowedChar(c)) {
- return false;
- }
- }
- return true;
-}
-
-FontFileParser::FontFileParser(const void* buffer, size_t size, uint32_t index)
- : mFace(makeHbFace(buffer, size, index)) {}
-
-FontFileParser::FontFileParser(const HbFaceUniquePtr& face)
- : mFace(hb_face_reference(face.get())) {}
-
-FontFileParser::FontFileParser(const HbFontUniquePtr& font)
- : mFace(hb_face_reference(hb_font_get_face(font.get()))) {}
-
-FontFileParser::~FontFileParser() {}
-
-// static
-HbFaceUniquePtr FontFileParser::makeHbFace(const void* buffer, size_t size, uint32_t index) {
- HbBlobUniquePtr blob(hb_blob_create(reinterpret_cast<const char*>(buffer), size,
- HB_MEMORY_MODE_READONLY, nullptr, nullptr));
- return HbFaceUniquePtr(hb_face_create(blob.get(), index));
-}
-
-std::optional<uint32_t> FontFileParser::getFontRevision() const {
- if (!mFace) return std::optional<uint32_t>();
-
- HbBlob headTable(mFace, MinikinFont::MakeTag('h', 'e', 'a', 'd'));
- if (!headTable) return std::optional<uint32_t>();
-
- uint32_t out = 0;
- if (!analyzeFontRevision(headTable.get(), headTable.size(), &out)) {
- return std::optional<uint32_t>();
- }
-
- return out;
-}
-
-std::optional<std::string> FontFileParser::getPostScriptName() const {
- if (!mFace) return std::optional<std::string>();
-
- unsigned int size = 64; // PostScript name is up to 63 characters.
- char buf[64] = {};
-
- uint32_t result = hb_ot_name_get_utf8(mFace.get(), HB_OT_NAME_ID_POSTSCRIPT_NAME,
- HB_LANGUAGE_INVALID, &size, buf);
-
- if (result == 0) { // not found.
- return std::optional<std::string>();
- }
-
- std::string out(buf, size);
-
- if (!checkPSName(out)) { // Contains invalid characters.
- return std::optional<std::string>();
- }
-
- return out;
-}
-
-std::optional<bool> FontFileParser::isPostScriptType1Font() const {
- if (!mFace) return std::optional<bool>();
-
- HbBlob cffTable(mFace, MinikinFont::MakeTag('C', 'F', 'F', ' '));
- HbBlob cff2Table(mFace, MinikinFont::MakeTag('C', 'F', 'F', '2'));
- return cffTable || cff2Table;
-}
-
-} // namespace minikin
diff --git a/libs/minikin/GreedyLineBreaker.cpp b/libs/minikin/GreedyLineBreaker.cpp
index 9bcb22d..f6952a9 100644
--- a/libs/minikin/GreedyLineBreaker.cpp
+++ b/libs/minikin/GreedyLineBreaker.cpp
@@ -255,7 +255,7 @@ bool GreedyLineBreaker::tryLineBreakWithHyphenation(const Range& range, WordBrea
// TODO: Respect trailing line end spaces.
bool GreedyLineBreaker::doLineBreakWithGraphemeBounds(const Range& range) {
- float width = mMeasuredText.widths[range.getStart()];
+ double width = mMeasuredText.widths[range.getStart()];
// Starting from + 1 since at least one character needs to be assigned to a line.
for (uint32_t i = range.getStart() + 1; i < range.getEnd(); ++i) {
diff --git a/libs/minikin/Layout.cpp b/libs/minikin/Layout.cpp
index e7d41c8..b902648 100644
--- a/libs/minikin/Layout.cpp
+++ b/libs/minikin/Layout.cpp
@@ -158,6 +158,9 @@ void Layout::appendLayout(const LayoutPiece& src, size_t start, float extraAdvan
mAdvances[start] += extraAdvance;
}
}
+ MinikinRect srcBounds(src.bounds());
+ srcBounds.offset(mAdvance, 0);
+ mBounds.join(srcBounds);
mAdvance += src.advance() + extraAdvance;
}
diff --git a/libs/minikin/LayoutCore.cpp b/libs/minikin/LayoutCore.cpp
index f1d0de8..6087646 100644
--- a/libs/minikin/LayoutCore.cpp
+++ b/libs/minikin/LayoutCore.cpp
@@ -355,9 +355,8 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool
mPoints.reserve(count);
HbBufferUniquePtr buffer(hb_buffer_create());
- U16StringPiece substr = textBuf.substr(range);
- std::vector<FontCollection::Run> items =
- paint.font->itemize(substr, paint.fontStyle, paint.localeListId, paint.familyVariant);
+ std::vector<FontCollection::Run> items = paint.font->itemize(
+ textBuf.substr(range), paint.fontStyle, paint.localeListId, paint.familyVariant);
std::vector<hb_feature_t> features;
// Disable default-on non-required ligature features if letter-spacing
@@ -385,14 +384,14 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool
isRtl ? run_ix >= 0 : run_ix < static_cast<int>(items.size());
isRtl ? --run_ix : ++run_ix) {
FontCollection::Run& run = items[run_ix];
- FakedFont fakedFont = paint.font->getBestFont(substr, run, paint.fontStyle);
- auto it = fontMap.find(fakedFont.font.get());
+ const FakedFont& fakedFont = run.fakedFont;
+ auto it = fontMap.find(fakedFont.font);
uint8_t font_ix;
if (it == fontMap.end()) {
// First time to see this font.
font_ix = mFonts.size();
mFonts.push_back(fakedFont);
- fontMap.insert(std::make_pair(fakedFont.font.get(), font_ix));
+ fontMap.insert(std::make_pair(fakedFont.font, font_ix));
// We override some functions which are not thread safe.
HbFontUniquePtr font(hb_font_create_sub_font(fakedFont.font->baseFont().get()));
@@ -422,6 +421,8 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool
hb_font_set_ppem(hbFont.get(), size * scaleX, size);
hb_font_set_scale(hbFont.get(), HBFloatToFixed(size * scaleX), HBFloatToFixed(size));
+ const bool is_color_bitmap_font = isColorBitmapFont(hbFont);
+
// TODO: if there are multiple scripts within a font in an RTL run,
// we need to reorder those runs. This is unlikely with our current
// font stack, but should be done for correctness.
@@ -501,6 +502,23 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool
mGlyphIds.push_back(glyph_ix);
mPoints.emplace_back(x + xoff, y + yoff);
float xAdvance = HBFixedToFloat(positions[i].x_advance);
+ MinikinRect glyphBounds;
+ hb_glyph_extents_t extents = {};
+ if (is_color_bitmap_font &&
+ hb_font_get_glyph_extents(hbFont.get(), glyph_ix, &extents)) {
+ // Note that it is technically possible for a TrueType font to have outline and
+ // embedded bitmap at the same time. We ignore modified bbox of hinted outline
+ // glyphs in that case.
+ glyphBounds.mLeft = roundf(HBFixedToFloat(extents.x_bearing));
+ glyphBounds.mTop = roundf(HBFixedToFloat(-extents.y_bearing));
+ glyphBounds.mRight = roundf(HBFixedToFloat(extents.x_bearing + extents.width));
+ glyphBounds.mBottom =
+ roundf(HBFixedToFloat(-extents.y_bearing - extents.height));
+ } else {
+ fakedFont.font->typeface()->GetBounds(&glyphBounds, glyph_ix, paint,
+ fakedFont.fakery);
+ }
+ glyphBounds.offset(xoff, yoff);
if (clusterBaseIndex < count) {
mAdvances[clusterBaseIndex] += xAdvance;
@@ -508,6 +526,8 @@ LayoutPiece::LayoutPiece(const U16StringPiece& textBuf, const Range& range, bool
ALOGE("cluster %zu (start %zu) out of bounds of count %zu", clusterBaseIndex,
start, count);
}
+ glyphBounds.offset(x, y);
+ mBounds.join(glyphBounds);
x += xAdvance;
}
if (numGlyphs) {
diff --git a/libs/minikin/LineBreakerUtil.h b/libs/minikin/LineBreakerUtil.h
index 8b383a4..eb058cc 100644
--- a/libs/minikin/LineBreakerUtil.h
+++ b/libs/minikin/LineBreakerUtil.h
@@ -36,7 +36,7 @@ namespace minikin {
// paragraphs, accuracy could degrade using only 32-bit float. Note however that float is used
// extensively on the Java side for this. This is a typedef so that we can easily change it based
// on performance/accuracy tradeoff.
-typedef float ParaWidth;
+typedef double ParaWidth;
// Hyphenates a string potentially containing non-breaking spaces.
std::vector<HyphenationType> hyphenate(const U16StringPiece& string, const Hyphenator& hypenator);
diff --git a/libs/minikin/Locale.cpp b/libs/minikin/Locale.cpp
index 553f61a..c1ec389 100644
--- a/libs/minikin/Locale.cpp
+++ b/libs/minikin/Locale.cpp
@@ -34,18 +34,6 @@ uint32_t registerLocaleList(const std::string& locales) {
return LocaleListCache::getId(locales);
}
-std::string getLocaleString(uint32_t localeId) {
- const LocaleList& localeList = LocaleListCache::getById(localeId);
- std::string out;
- for (size_t i = 0; i < localeList.size(); ++i) {
- if (i != 0) {
- out += ",";
- }
- out += localeList[i].getString();
- }
- return out;
-}
-
// Check if a language code supports extension such as emoji and line break etc. according to its
// subtag
static bool isSubtag(const char* buf, size_t bufLen, const char* subtag, size_t subtagLen) {
diff --git a/libs/minikin/Locale.h b/libs/minikin/Locale.h
index 7557301..8052d6c 100644
--- a/libs/minikin/Locale.h
+++ b/libs/minikin/Locale.h
@@ -95,17 +95,7 @@ public:
// Parse from string
Locale(const StringPiece& buf);
- // Parse from identifier. See getIdentifier() for the identifier format.
- explicit Locale(uint64_t identifier)
- : mScript(extractBits(identifier, 29, 20)),
- mLanguage(extractBits(identifier, 49, 15)),
- mRegion(extractBits(identifier, 14, 15)),
- mSubScriptBits(scriptToSubScriptBits(mScript)),
- mVariant(static_cast<Variant>(extractBits(identifier, 0, 2))),
- mEmojiStyle(static_cast<EmojiStyle>(extractBits(identifier, 12, 2))),
- mLBStyle(static_cast<LineBreakStyle>(extractBits(identifier, 10, 2))) {}
-
- bool operator==(const Locale& other) const {
+ bool operator==(const Locale other) const {
return !isUnsupported() && isEqualScript(other) && mLanguage == other.mLanguage &&
mRegion == other.mRegion && mVariant == other.mVariant &&
mLBStyle == other.mLBStyle && mEmojiStyle == other.mEmojiStyle;
@@ -144,13 +134,13 @@ public:
// Identifier pattern:
// |-------|-------|-------|-------|-------|-------|-------|-------|
- // lllllllllllllll Language Code (15 bits)
- // ssssssssssssssssssss Script Code (20 bits)
- // rrrrrrrrrrrrrrr Region Code (15 bits)
- // ee Emoji Style (2 bits)
- // bb Line Break Style (2 bits)
- // XXXXXXXX Free (8 bits)
- // vv German Variant (2 bits)
+ // lllllllllllllll Language Code
+ // ssssssssssssssssssss Script Code
+ // rrrrrrrrrrrrrrr Region Code
+ // ee Emoji Style
+ // bb Line Break Style
+ // XXXXXXXX Free
+ // vv German Variant
uint64_t getIdentifier() const {
return ((uint64_t)mLanguage << 49) | ((uint64_t)mScript << 29) | ((uint64_t)mRegion << 14) |
((uint64_t)mEmojiStyle << 12) | ((uint64_t)mLBStyle << 10) | (uint64_t)mVariant;
@@ -191,10 +181,6 @@ private:
void resolveUnicodeExtension(const char* buf, size_t length);
- inline static uint64_t extractBits(uint64_t value, uint8_t shift, uint8_t nBits) {
- return (value >> shift) & ((1 << nBits) - 1);
- }
-
static uint8_t scriptToSubScriptBits(uint32_t rawScript);
static LineBreakStyle resolveLineBreakStyle(const char* buf, size_t length);
diff --git a/libs/minikin/LocaleListCache.cpp b/libs/minikin/LocaleListCache.cpp
index 38800f7..15156cd 100644
--- a/libs/minikin/LocaleListCache.cpp
+++ b/libs/minikin/LocaleListCache.cpp
@@ -21,16 +21,15 @@
#include <unordered_set>
#include <log/log.h>
-#include <minikin/Hasher.h>
-#include <minikin/LocaleList.h>
#include <unicode/uloc.h>
-#include <unicode/umachine.h>
#include "Locale.h"
#include "MinikinInternal.h"
namespace minikin {
+const uint32_t LocaleListCache::kEmptyListId;
+
// Returns the text length of output.
static size_t toLanguageTag(char* output, size_t outSize, const StringPiece& locale) {
output[0] = '\0';
@@ -71,7 +70,7 @@ static size_t toLanguageTag(char* output, size_t outSize, const StringPiece& loc
}
uErr = U_ZERO_ERROR;
- outLength = uloc_toLanguageTag(likelyChars, output, outSize, false, &uErr);
+ outLength = uloc_toLanguageTag(likelyChars, output, outSize, FALSE, &uErr);
if (U_FAILURE(uErr)) {
// unable to build a proper locale identifier
ALOGD("uloc_toLanguageTag(\"%s\") failed: %s", likelyChars, u_errorName(uErr));
@@ -107,39 +106,15 @@ static std::vector<Locale> parseLocaleList(const std::string& input) {
return result;
}
-size_t LocaleListCache::LocaleVectorHash::operator()(const std::vector<Locale>& locales) const {
- Hasher hasher;
- for (const auto& locale : locales) {
- uint64_t id = locale.getIdentifier();
- hasher.update(static_cast<uint32_t>((id >> 32) & 0xFFFFFFFF));
- hasher.update(static_cast<uint32_t>(id & 0xFFFFFFFF));
- }
- return hasher.hash();
-}
-
LocaleListCache::LocaleListCache() {
- // Insert an empty locale list for mapping default locale list to kEmptyLocaleListId.
+ // Insert an empty locale list for mapping default locale list to kEmptyListId.
// The default locale list has only one Locale and it is the unsupported locale.
mLocaleLists.emplace_back();
- mLocaleListLookupTable.emplace(std::vector<Locale>(), kEmptyLocaleListId);
- mLocaleListStringCache.emplace("", kEmptyLocaleListId);
+ mLocaleListLookupTable.insert(std::make_pair("", kEmptyListId));
}
uint32_t LocaleListCache::getIdInternal(const std::string& locales) {
std::lock_guard<std::mutex> lock(mMutex);
- const auto& it = mLocaleListStringCache.find(locales);
- if (it != mLocaleListStringCache.end()) {
- return it->second;
- }
- uint32_t id = getIdInternal(parseLocaleList(locales));
- mLocaleListStringCache.emplace(locales, id);
- return id;
-}
-
-uint32_t LocaleListCache::getIdInternal(std::vector<Locale>&& locales) {
- if (locales.empty()) {
- return kEmptyLocaleListId;
- }
const auto& it = mLocaleListLookupTable.find(locales);
if (it != mLocaleListLookupTable.end()) {
return it->second;
@@ -147,31 +122,15 @@ uint32_t LocaleListCache::getIdInternal(std::vector<Locale>&& locales) {
// Given locale list is not in cache. Insert it and return newly assigned ID.
const uint32_t nextId = mLocaleLists.size();
- mLocaleListLookupTable.emplace(locales, nextId);
- LocaleList fontLocales(std::move(locales));
+ LocaleList fontLocales(parseLocaleList(locales));
+ if (fontLocales.empty()) {
+ return kEmptyListId;
+ }
mLocaleLists.push_back(std::move(fontLocales));
+ mLocaleListLookupTable.insert(std::make_pair(locales, nextId));
return nextId;
}
-uint32_t LocaleListCache::readFromInternal(BufferReader* reader) {
- uint32_t size = reader->read<uint32_t>();
- std::vector<Locale> locales;
- locales.reserve(size);
- for (uint32_t i = 0; i < size; i++) {
- locales.emplace_back(reader->read<uint64_t>());
- }
- std::lock_guard<std::mutex> lock(mMutex);
- return getIdInternal(std::move(locales));
-}
-
-void LocaleListCache::writeToInternal(BufferWriter* writer, uint32_t id) {
- const LocaleList& localeList = getByIdInternal(id);
- writer->write<uint32_t>(localeList.size());
- for (size_t i = 0; i < localeList.size(); i++) {
- writer->write<uint64_t>(localeList[i].getIdentifier());
- }
-}
-
const LocaleList& LocaleListCache::getByIdInternal(uint32_t id) {
std::lock_guard<std::mutex> lock(mMutex);
MINIKIN_ASSERT(id < mLocaleLists.size(), "Lookup by unknown locale list ID.");
diff --git a/libs/minikin/LocaleListCache.h b/libs/minikin/LocaleListCache.h
index a83b1c8..61e3f81 100644
--- a/libs/minikin/LocaleListCache.h
+++ b/libs/minikin/LocaleListCache.h
@@ -20,7 +20,6 @@
#include <mutex>
#include <unordered_map>
-#include "minikin/Buffer.h"
#include "minikin/Macros.h"
#include "Locale.h"
@@ -29,39 +28,30 @@ namespace minikin {
class LocaleListCache {
public:
+ // A special ID for the empty locale list.
+ // This value must be 0 since the empty locale list is inserted into mLocaleLists by
+ // default.
+ const static uint32_t kEmptyListId = 0;
+
// A special ID for the invalid locale list.
const static uint32_t kInvalidListId = (uint32_t)(-1);
// Returns the locale list ID for the given string representation of LocaleList.
+ // Caller should acquire a lock before calling the method.
static inline uint32_t getId(const std::string& locales) {
return getInstance().getIdInternal(locales);
}
- // Returns the locale list ID for the LocaleList serialized in the buffer.
- static inline uint32_t readFrom(BufferReader* reader) {
- return getInstance().readFromInternal(reader);
- }
-
- static inline void writeTo(BufferWriter* writer, uint32_t id) {
- return getInstance().writeToInternal(writer, id);
- }
-
+ // Caller should acquire a lock before calling the method.
static inline const LocaleList& getById(uint32_t id) {
return getInstance().getByIdInternal(id);
}
private:
- struct LocaleVectorHash {
- size_t operator()(const std::vector<Locale>& locales) const;
- };
-
LocaleListCache(); // Singleton
~LocaleListCache() {}
uint32_t getIdInternal(const std::string& locales);
- uint32_t getIdInternal(std::vector<Locale>&& locales) EXCLUSIVE_LOCKS_REQUIRED(mMutex);
- uint32_t readFromInternal(BufferReader* reader);
- void writeToInternal(BufferWriter* writer, uint32_t id);
const LocaleList& getByIdInternal(uint32_t id);
// Caller should acquire a lock before calling the method.
@@ -72,18 +62,8 @@ private:
std::vector<LocaleList> mLocaleLists GUARDED_BY(mMutex);
- // A map from the list of locale identifier to the ID.
- //
- // Locale's operator==() doesn't have reflexivity for unsupported locales,
- // but it won't cause problems because we never store unsupported locales in
- // LocaleListCache. See parseLocaleList() in LocaleListCache.cpp.
- std::unordered_map<std::vector<Locale>, uint32_t, LocaleVectorHash> mLocaleListLookupTable
- GUARDED_BY(mMutex);
-
- // A cache map from the string representation of the font locale list to the ID.
- // This is a mere cache over mLocaleListLookupTable. Some LocaleList objects may be in
- // mLocaleListLookupTable even if they are not in mLocaleListStringCache.
- std::unordered_map<std::string, uint32_t> mLocaleListStringCache GUARDED_BY(mMutex);
+ // A map from the string representation of the font locale list to the ID.
+ std::unordered_map<std::string, uint32_t> mLocaleListLookupTable GUARDED_BY(mMutex);
std::mutex mMutex;
};
diff --git a/libs/minikin/MeasuredText.cpp b/libs/minikin/MeasuredText.cpp
index 1bf3942..af0d0ee 100644
--- a/libs/minikin/MeasuredText.cpp
+++ b/libs/minikin/MeasuredText.cpp
@@ -213,20 +213,10 @@ class BoundsCompositor {
public:
BoundsCompositor() : mAdvance(0) {}
- void operator()(const LayoutPiece& layoutPiece, const MinikinPaint& paint) {
- MinikinRect pieceBounds;
- MinikinRect tmpRect;
- for (uint32_t i = 0; i < layoutPiece.glyphCount(); ++i) {
- const FakedFont& font = layoutPiece.fontAt(i);
- const Point& point = layoutPiece.pointAt(i);
-
- MinikinFont* minikinFont = font.font->typeface().get();
- minikinFont->GetBounds(&tmpRect, layoutPiece.glyphIdAt(i), paint, font.fakery);
- tmpRect.offset(point.x, point.y);
- pieceBounds.join(tmpRect);
- }
- pieceBounds.offset(mAdvance, 0);
- mBounds.join(pieceBounds);
+ void operator()(const LayoutPiece& layoutPiece, const MinikinPaint& /* paint */) {
+ MinikinRect tmpBounds = layoutPiece.bounds();
+ tmpBounds.offset(mAdvance, 0);
+ mBounds.join(tmpBounds);
mAdvance += layoutPiece.advance();
}
diff --git a/libs/minikin/Measurement.cpp b/libs/minikin/Measurement.cpp
index 66886da..5d110c4 100644
--- a/libs/minikin/Measurement.cpp
+++ b/libs/minikin/Measurement.cpp
@@ -19,9 +19,6 @@
#include <cfloat>
#include <cmath>
-#include "BidiUtils.h"
-#include "LayoutSplitter.h"
-#include "minikin/BoundsCache.h"
#include "minikin/GraphemeBreak.h"
namespace minikin {
@@ -121,40 +118,4 @@ size_t getOffsetForAdvance(const float* advances, const uint16_t* buf, size_t st
return best;
}
-struct BoundsComposer {
- BoundsComposer() : mAdvance(0) {}
-
- void operator()(const MinikinRect& rect, float advance) {
- MinikinRect tmp = rect;
- tmp.offset(mAdvance, 0);
- mBounds.join(tmp);
- mAdvance += advance;
- }
-
- float mAdvance;
- MinikinRect mBounds;
-};
-
-void getBounds(const U16StringPiece& str, const Range& range, Bidi bidiFlag,
- const MinikinPaint& paint, StartHyphenEdit startHyphen, EndHyphenEdit endHyphen,
- MinikinRect* out) {
- BoundsComposer bc;
- for (const BidiText::RunInfo info : BidiText(str, range, bidiFlag)) {
- for (const auto [context, piece] : LayoutSplitter(str, info.range, info.isRtl)) {
- const StartHyphenEdit pieceStartHyphen =
- (piece.getStart() == range.getStart()) ? startHyphen : StartHyphenEdit::NO_EDIT;
- const EndHyphenEdit pieceEndHyphen =
- (piece.getEnd() == range.getEnd()) ? endHyphen : EndHyphenEdit::NO_EDIT;
- BoundsCache::getInstance().getOrCreate(str.substr(context), piece - context.getStart(),
- paint, info.isRtl, pieceStartHyphen,
- pieceEndHyphen, bc);
- // Increment word spacing for spacer
- if (piece.getLength() == 1 && isWordSpace(str[piece.getStart()])) {
- bc.mAdvance += paint.wordSpacing;
- }
- }
- }
- *out = bc.mBounds;
-}
-
} // namespace minikin
diff --git a/libs/minikin/SparseBitSet.cpp b/libs/minikin/SparseBitSet.cpp
index 41151f1..66d6c02 100644
--- a/libs/minikin/SparseBitSet.cpp
+++ b/libs/minikin/SparseBitSet.cpp
@@ -55,14 +55,9 @@ void SparseBitSet::initFromRanges(const uint32_t* ranges, size_t nRanges) {
return;
}
mMaxVal = maxVal;
- mIndicesCount = (mMaxVal + kPageMask) >> kLogValuesPerPage;
- // Avoid zero-filling mOwnedIndices.
- mOwnedIndices.reset(new uint16_t[mIndicesCount]);
- mIndices = mOwnedIndices.get();
+ mIndices.reset(new uint16_t[(mMaxVal + kPageMask) >> kLogValuesPerPage]);
uint32_t nPages = calcNumPages(ranges, nRanges);
- mBitmapsCount = nPages << (kLogValuesPerPage - kLogBitsPerEl);
- mOwnedBitmaps = std::make_unique<element[]>(mBitmapsCount);
- mBitmaps = mOwnedBitmaps.get();
+ mBitmaps.reset(new element[nPages << (kLogValuesPerPage - kLogBitsPerEl)]());
mZeroPageIndex = noZeroPage;
uint32_t nonzeroPageEnd = 0;
uint32_t currentPage = 0;
@@ -78,52 +73,32 @@ void SparseBitSet::initFromRanges(const uint32_t* ranges, size_t nRanges) {
mZeroPageIndex = (currentPage++) << (kLogValuesPerPage - kLogBitsPerEl);
}
for (uint32_t j = nonzeroPageEnd; j < startPage; j++) {
- mOwnedIndices[j] = mZeroPageIndex;
+ mIndices[j] = mZeroPageIndex;
}
}
- mOwnedIndices[startPage] = (currentPage++) << (kLogValuesPerPage - kLogBitsPerEl);
+ mIndices[startPage] = (currentPage++) << (kLogValuesPerPage - kLogBitsPerEl);
}
size_t index = ((currentPage - 1) << (kLogValuesPerPage - kLogBitsPerEl)) +
((start & kPageMask) >> kLogBitsPerEl);
size_t nElements = (end - (start & ~kElMask) + kElMask) >> kLogBitsPerEl;
if (nElements == 1) {
- mOwnedBitmaps[index] |=
+ mBitmaps[index] |=
(kElAllOnes >> (start & kElMask)) & (kElAllOnes << ((~end + 1) & kElMask));
} else {
- mOwnedBitmaps[index] |= kElAllOnes >> (start & kElMask);
+ mBitmaps[index] |= kElAllOnes >> (start & kElMask);
for (size_t j = 1; j < nElements - 1; j++) {
- mOwnedBitmaps[index + j] = kElAllOnes;
+ mBitmaps[index + j] = kElAllOnes;
}
- mOwnedBitmaps[index + nElements - 1] |= kElAllOnes << ((~end + 1) & kElMask);
+ mBitmaps[index + nElements - 1] |= kElAllOnes << ((~end + 1) & kElMask);
}
for (size_t j = startPage + 1; j < endPage + 1; j++) {
- mOwnedIndices[j] = (currentPage++) << (kLogValuesPerPage - kLogBitsPerEl);
+ mIndices[j] = (currentPage++) << (kLogValuesPerPage - kLogBitsPerEl);
}
nonzeroPageEnd = endPage + 1;
}
}
-void SparseBitSet::initFromBuffer(BufferReader* reader) {
- mMaxVal = reader->read<uint32_t>();
- // mIndices and mBitmaps are not initialized when mMaxVal == 0
- if (mMaxVal == 0) return;
- std::tie(mIndices, mIndicesCount) = reader->readArray<uint16_t>();
- // element is uint32_t
- static_assert(sizeof(element) == 4);
- std::tie(mBitmaps, mBitmapsCount) = reader->readArray<element>();
- mZeroPageIndex = reader->read<uint16_t>();
-}
-
-void SparseBitSet::writeTo(BufferWriter* writer) const {
- writer->write<uint32_t>(mMaxVal);
- // mIndices and mBitmaps are not initialized when mMaxVal == 0
- if (mMaxVal == 0) return;
- writer->writeArray<uint16_t>(mIndices, mIndicesCount);
- writer->writeArray<element>(mBitmaps, mBitmapsCount);
- writer->write<uint16_t>(mZeroPageIndex);
-}
-
int SparseBitSet::CountLeadingZeros(element x) {
// Note: GCC / clang builtin
return sizeof(element) <= sizeof(int) ? __builtin_clz(x) : __builtin_clzl(x);
diff --git a/libs/minikin/SystemFonts.cpp b/libs/minikin/SystemFonts.cpp
index 9c8fa66..287fc61 100644
--- a/libs/minikin/SystemFonts.cpp
+++ b/libs/minikin/SystemFonts.cpp
@@ -26,8 +26,7 @@ SystemFonts& SystemFonts::getInstance() {
}
std::shared_ptr<FontCollection> SystemFonts::findFontCollectionInternal(
- const std::string& familyName) {
- std::lock_guard<std::mutex> lock(mMutex);
+ const std::string& familyName) const {
auto it = mSystemFallbacks.find(familyName);
if (it != mSystemFallbacks.end()) {
return it->second;
@@ -36,22 +35,4 @@ std::shared_ptr<FontCollection> SystemFonts::findFontCollectionInternal(
return mDefaultFallback;
}
-void SystemFonts::buildFontSetLocked() {
- std::unordered_set<FontFamily*> uniqueFamilies;
-
- for (const auto& collection : mCollections) {
- for (const auto& family : collection->getFamilies()) {
- uniqueFamilies.insert(family.get());
- }
- }
-
- std::vector<std::shared_ptr<Font>> result;
- for (const auto family : uniqueFamilies) {
- for (size_t i = 0; i < family->getNumFonts(); ++i) {
- result.push_back(family->getFontRef(i));
- }
- }
- mFonts = std::move(result);
-}
-
} // namespace minikin
diff --git a/tests/Android.bp b/tests/Android.bp
index 3088ca4..1d8c019 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -1,13 +1,8 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
filegroup {
name: "minikin-test-data",
srcs: [
"data/Arabic.ttf",
"data/Ascii.ttf",
- "data/Bbox.ttf",
"data/Bold.ttf",
"data/BoldItalic.ttf",
"data/Cherokee.ttf",
@@ -15,7 +10,6 @@ filegroup {
"data/ColorTextMixedEmojiFont.ttf",
"data/CustomExtent.ttf",
"data/Emoji.ttf",
- "data/EmojiBase.ttf",
"data/Hiragana.ttf",
"data/Italic.ttf",
"data/Ja.ttf",
@@ -25,7 +19,6 @@ filegroup {
"data/MultiAxis.ttf",
"data/NoCmapFormat14.ttf",
"data/NoGlyphFont.ttf",
- "data/OverrideEmoji.ttf",
"data/Regular.ttf",
"data/TextEmojiFont.ttf",
"data/UnicodeBMPOnly.ttf",
@@ -35,7 +28,6 @@ filegroup {
"data/ZhHans.ttf",
"data/ZhHant.ttf",
"data/emoji.xml",
- "data/emoji_itemization.xml",
"data/itemize.xml",
],
}
diff --git a/tests/data/Ascii.ttf b/tests/data/Ascii.ttf
index 2e6835b..be6d5fe 100644
--- a/tests/data/Ascii.ttf
+++ b/tests/data/Ascii.ttf
Binary files differ
diff --git a/tests/data/Ascii.ttx b/tests/data/Ascii.ttx
index c0a2ef6..74eba96 100644
--- a/tests/data/Ascii.ttx
+++ b/tests/data/Ascii.ttx
@@ -18,7 +18,6 @@
<GlyphOrder>
<GlyphID id="0" name=".notdef"/>
<GlyphID id="1" name="1em"/>
- <GlyphID id="2" name="2em"/>
</GlyphOrder>
<head>
@@ -118,7 +117,6 @@
<hmtx>
<mtx name=".notdef" width="50" lsb="0"/>
<mtx name="1em" width="100" lsb="0"/>
- <mtx name="2em" width="200" lsb="0"/>
</hmtx>
<cmap>
@@ -219,12 +217,6 @@
<map code="0x007C" name="1em" /> <!-- '|' -->
<map code="0x007D" name="1em" /> <!-- '}' -->
<map code="0x007E" name="1em" /> <!-- '~' -->
- <map code="0x02B1" name="2em" /> <!-- 'α' -->
- <map code="0x02B2" name="2em" /> <!-- 'β' -->
- <map code="0x02B3" name="2em" /> <!-- 'γ' -->
- <map code="0x02B4" name="2em" /> <!-- 'δ' -->
- <map code="0x02B5" name="2em" /> <!-- 'ε' -->
- <map code="0x02B6" name="2em" /> <!-- 'ζ' -->
</cmap_format_12>
</cmap>
@@ -243,15 +235,6 @@
</contour>
<instructions><assembly></assembly></instructions>
</TTGlyph>
- <TTGlyph name="2em" xMin="0" yMin="0" xMax="200" yMax="200">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="200" y="0" on="1" />
- <pt x="200" y="200" on="1" />
- <pt x="0" y="200" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
</glyf>
<name>
diff --git a/tests/data/Bbox.ttf b/tests/data/Bbox.ttf
deleted file mode 100644
index c89c59c..0000000
--- a/tests/data/Bbox.ttf
+++ /dev/null
Binary files differ
diff --git a/tests/data/Bbox.ttx b/tests/data/Bbox.ttx
deleted file mode 100644
index e7d34bd..0000000
--- a/tests/data/Bbox.ttx
+++ /dev/null
@@ -1,265 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2020 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.0">
-
- <GlyphOrder>
- <GlyphID id="0" name=".notdef"/>
- <GlyphID id="1" name="1emx1em"/>
- <GlyphID id="2" name="2emx2em"/>
- <GlyphID id="3" name="3emx3em"/>
- <GlyphID id="4" name="2emx2em_lsb_1em"/>
- <GlyphID id="5" name="1emx1em_y1em_origin"/>
- </GlyphOrder>
-
- <head>
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <created value="Fri Mar 17 07:26:00 2017"/>
- <macStyle value="00000000 00000000"/>
- <lowestRecPPEM value="7"/>
- <fontDirectionHint value="2"/>
- <glyphDataFormat value="0"/>
- </head>
-
- <hhea>
- <tableVersion value="1.0"/>
- <ascent value="1000"/>
- <descent value="-200"/>
- <lineGap value="0"/>
- <caretSlopeRise value="1"/>
- <caretSlopeRun value="0"/>
- <caretOffset value="0"/>
- <reserved0 value="0"/>
- <reserved1 value="0"/>
- <reserved2 value="0"/>
- <reserved3 value="0"/>
- <metricDataFormat value="0"/>
- </hhea>
-
- <maxp>
- <tableVersion value="0x10000"/>
- <maxZones value="0"/>
- <maxTwilightPoints value="0"/>
- <maxStorage value="0"/>
- <maxFunctionDefs value="0"/>
- <maxInstructionDefs value="0"/>
- <maxStackElements value="0"/>
- <maxSizeOfInstructions value="0"/>
- <maxComponentElements value="0"/>
- </maxp>
-
- <OS_2>
- <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
- will be recalculated by the compiler -->
- <version value="3"/>
- <xAvgCharWidth value="594"/>
- <usWeightClass value="400"/>
- <usWidthClass value="5"/>
- <fsType value="00000000 00001000"/>
- <ySubscriptXSize value="650"/>
- <ySubscriptYSize value="600"/>
- <ySubscriptXOffset value="0"/>
- <ySubscriptYOffset value="75"/>
- <ySuperscriptXSize value="650"/>
- <ySuperscriptYSize value="600"/>
- <ySuperscriptXOffset value="0"/>
- <ySuperscriptYOffset value="350"/>
- <yStrikeoutSize value="50"/>
- <yStrikeoutPosition value="300"/>
- <sFamilyClass value="0"/>
- <panose>
- <bFamilyType value="0"/>
- <bSerifStyle value="0"/>
- <bWeight value="5"/>
- <bProportion value="0"/>
- <bContrast value="0"/>
- <bStrokeVariation value="0"/>
- <bArmStyle value="0"/>
- <bLetterForm value="0"/>
- <bMidline value="0"/>
- <bXHeight value="0"/>
- </panose>
- <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
- <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
- <achVendID value="UKWN"/>
- <fsSelection value="00000000 01000000"/>
- <usFirstCharIndex value="32"/>
- <usLastCharIndex value="122"/>
- <sTypoAscender value="800"/>
- <sTypoDescender value="-200"/>
- <sTypoLineGap value="200"/>
- <usWinAscent value="1000"/>
- <usWinDescent value="200"/>
- <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
- <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
- <sxHeight value="500"/>
- <sCapHeight value="700"/>
- <usDefaultChar value="0"/>
- <usBreakChar value="32"/>
- <usMaxContext value="0"/>
- </OS_2>
-
- <hmtx>
- <mtx name=".notdef" width="500" lsb="93"/>
- <mtx name="1emx1em" width="1000" lsb="0"/>
- <mtx name="2emx2em" width="2000" lsb="0"/>
- <mtx name="3emx3em" width="3000" lsb="0"/>
- <mtx name="2emx2em_lsb_1em" width="2000" lsb="1000"/>
- <mtx name="1emx1em_y1em_origin" width="1000" lsb="0"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_12 format="12" reserved="0" length="3" nGroups="6" platformID="3" platEncID="1" language="0">
- <map code="0x0028" name="1emx1em" />
- <map code="0x0061" name="1emx1em" />
- <map code="0x0062" name="2emx2em" />
- <map code="0x0063" name="3emx3em" />
- <map code="0x0064" name="2emx2em_lsb_1em" />
- <map code="0x0065" name="1emx1em_y1em_origin" />
- </cmap_format_12>
- </cmap>
-
- <loca>
- <!-- The 'loca' table will be calculated by the compiler -->
- </loca>
-
- <glyf>
- <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="0" yMax="0" />
- <TTGlyph name="1emx1em" xMin="0" yMin="0" xMax="1000" yMax="1000">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="500" y="1000" on="1" />
- <pt x="1000" y="0" on="1" />
- </contour>
- <instructions />
- </TTGlyph>
- <TTGlyph name="2emx2em" xMin="0" yMin="0" xMax="2000" yMax="2000">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="1000" y="2000" on="1" />
- <pt x="2000" y="0" on="1" />
- </contour>
- <instructions />
- </TTGlyph>
- <TTGlyph name="3emx3em" xMin="0" yMin="0" xMax="3000" yMax="3000">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="1500" y="3000" on="1" />
- <pt x="3000" y="0" on="1" />
- </contour>
- <instructions />
- </TTGlyph>
- <TTGlyph name="2emx2em_lsb_1em" xMin="0" yMin="0" xMax="2000" yMax="2000">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="1000" y="2000" on="1" />
- <pt x="2000" y="0" on="1" />
- </contour>
- <instructions />
- </TTGlyph>
- <TTGlyph name="1emx1em_y1em_origin" xMin="0" yMin="1000" xMax="1000" yMax="2000">
- <contour>
- <pt x="0" y="1000" on="1" />
- <pt x="500" y="2000" on="1" />
- <pt x="1000" y="1000" on="1" />
- </contour>
- <instructions />
- </TTGlyph>
- </glyf>
-
- <GSUB>
- <Version value="0x00010000"/>
- <ScriptList>
- <ScriptRecord index="0">
- <ScriptTag value="latn"/>
- <Script>
- <DefaultLangSys>
- <ReqFeatureIndex value="65535"/>
- <FeatureIndex index="0" value="0"/>
- </DefaultLangSys>
- </Script>
- </ScriptRecord>
- </ScriptList>
- <FeatureList>
- <FeatureRecord index="0">
- <FeatureTag value="rtlm"/>
- <Feature>
- <LookupListIndex index="0" value="0"/>
- </Feature>
- </FeatureRecord>
- </FeatureList>
- <LookupList>
- <Lookup index="0">
- <LookupType value="1"/>
- <LookupFlag value="0"/>
- <SingleSubst index="0" Format="2">
- <Substitution in="1emx1em" out="3emx3em" />
- </SingleSubst>
- </Lookup>
- </LookupList>
-
- </GSUB>
-
- <name>
- <namerecord nameID="0" platformID="3" platEncID="1" langID="0x409">
- Copyright (C) 2017 The Android Open Source Project
- </namerecord>
- <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
- Regular
- </namerecord>
- <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
- Sample Font
- </namerecord>
- <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
- SampleFont-Regular
- </namerecord>
- <namerecord nameID="13" platformID="3" platEncID="1" langID="0x409">
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- </namerecord>
- <namerecord nameID="14" platformID="3" platEncID="1" langID="0x409">
- http://www.apache.org/licenses/LICENSE-2.0
- </namerecord>
- </name>
-
- <post>
- <formatType value="3.0"/>
- <italicAngle value="0.0"/>
- <underlinePosition value="-75"/>
- <underlineThickness value="50"/>
- <isFixedPitch value="0"/>
- <minMemType42 value="0"/>
- <maxMemType42 value="0"/>
- <minMemType1 value="0"/>
- <maxMemType1 value="0"/>
- </post>
-
-</ttFont>
diff --git a/tests/data/EmojiBase.ttf b/tests/data/EmojiBase.ttf
deleted file mode 100644
index 659226d..0000000
--- a/tests/data/EmojiBase.ttf
+++ /dev/null
Binary files differ
diff --git a/tests/data/EmojiBase.ttx b/tests/data/EmojiBase.ttx
deleted file mode 100644
index e6e3da8..0000000
--- a/tests/data/EmojiBase.ttx
+++ /dev/null
@@ -1,537 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.9">
-
- <GlyphOrder>
- <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
- <GlyphID id="0" name=".notdef"/>
-
- <!-- Compbining characters for Emoji -->
- <GlyphID id="1" name="U+200D"/>
- <GlyphID id="2" name="U+1F3FB"/>
- <GlyphID id="3" name="U+1F3FC"/>
-
- <!-- Random Emoji -->
- <GlyphID id="4" name="U+1F9B0"/>
- <GlyphID id="5" name="U+1F9B1"/>
- <GlyphID id="6" name="U+1F9B2"/>
- <GlyphID id="7" name="U+1F9B3"/>
- <GlyphID id="8" name="U+1F9B4"/>
- <GlyphID id="9" name="U+1F9B5"/>
- <GlyphID id="10" name="U+1F9B6"/>
- <GlyphID id="11" name="U+1F9B7"/>
- <GlyphID id="12" name="U+1F9B8"/>
- <GlyphID id="13" name="U+1F9B9"/>
-
- <!-- Unassigned Code Points -->
- <GlyphID id="14" name="U+E0000"/>
- <GlyphID id="15" name="U+E0001"/>
-
- <!-- Ligature Form. Not in cmap -->
- <GlyphID id="16" name="LigaForm1"/>
- <GlyphID id="17" name="LigaForm2"/>
- <GlyphID id="18" name="LigaForm3"/>
- <GlyphID id="19" name="LigaForm4"/>
- <GlyphID id="20" name="LigaForm5"/>
- <GlyphID id="21" name="LigaForm6"/>
- <GlyphID id="22" name="LigaForm7"/>
-
- <!-- Regional Indicators -->
- <GlyphID id="23" name="U+1F1E6"/>
- <GlyphID id="24" name="U+1F1E7"/>
-
- </GlyphOrder>
-
- <head>
- <!-- Most of this table will be recalculated by the compiler -->
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <created value="Wed Sep 9 08:01:17 2015"/>
- <modified value="Wed Sep 9 08:48:07 2015"/>
- <xMin value="0"/>
- <yMin value="0"/>
- <xMax value="0"/>
- <yMax value="0"/>
- <macStyle value="00000000 00000000"/>
- <lowestRecPPEM value="7"/>
- <fontDirectionHint value="2"/>
- <indexToLocFormat value="0"/>
- <glyphDataFormat value="0"/>
- </head>
-
- <hhea>
- <tableVersion value="0x00010000"/>
- <ascent value="1000"/>
- <descent value="-200"/>
- <lineGap value="0"/>
- <advanceWidthMax value="500"/>
- <minLeftSideBearing value="0"/>
- <minRightSideBearing value="0"/>
- <xMaxExtent value="0"/>
- <caretSlopeRise value="1"/>
- <caretSlopeRun value="0"/>
- <caretOffset value="0"/>
- <reserved0 value="0"/>
- <reserved1 value="0"/>
- <reserved2 value="0"/>
- <reserved3 value="0"/>
- <metricDataFormat value="0"/>
- <numberOfHMetrics value="1"/>
- </hhea>
-
- <maxp>
- <!-- Most of this table will be recalculated by the compiler -->
- <tableVersion value="0x10000"/>
- <numGlyphs value="8"/>
- <maxPoints value="0"/>
- <maxContours value="0"/>
- <maxCompositePoints value="0"/>
- <maxCompositeContours value="0"/>
- <maxZones value="2"/>
- <maxTwilightPoints value="12"/>
- <maxStorage value="28"/>
- <maxFunctionDefs value="119"/>
- <maxInstructionDefs value="0"/>
- <maxStackElements value="61"/>
- <maxSizeOfInstructions value="2967"/>
- <maxComponentElements value="0"/>
- <maxComponentDepth value="0"/>
- </maxp>
-
- <OS_2>
- <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
- will be recalculated by the compiler -->
- <version value="3"/>
- <xAvgCharWidth value="594"/>
- <usWeightClass value="400"/>
- <usWidthClass value="5"/>
- <fsType value="00000000 00001000"/>
- <ySubscriptXSize value="650"/>
- <ySubscriptYSize value="600"/>
- <ySubscriptXOffset value="0"/>
- <ySubscriptYOffset value="75"/>
- <ySuperscriptXSize value="650"/>
- <ySuperscriptYSize value="600"/>
- <ySuperscriptXOffset value="0"/>
- <ySuperscriptYOffset value="350"/>
- <yStrikeoutSize value="50"/>
- <yStrikeoutPosition value="300"/>
- <sFamilyClass value="0"/>
- <panose>
- <bFamilyType value="0"/>
- <bSerifStyle value="0"/>
- <bWeight value="5"/>
- <bProportion value="0"/>
- <bContrast value="0"/>
- <bStrokeVariation value="0"/>
- <bArmStyle value="0"/>
- <bLetterForm value="0"/>
- <bMidline value="0"/>
- <bXHeight value="0"/>
- </panose>
- <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
- <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
- <achVendID value="UKWN"/>
- <fsSelection value="00000000 01000000"/>
- <usFirstCharIndex value="48"/>
- <usLastCharIndex value="65535"/>
- <sTypoAscender value="800"/>
- <sTypoDescender value="-200"/>
- <sTypoLineGap value="200"/>
- <usWinAscent value="1000"/>
- <usWinDescent value="200"/>
- <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
- <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
- <sxHeight value="500"/>
- <sCapHeight value="700"/>
- <usDefaultChar value="0"/>
- <usBreakChar value="32"/>
- <usMaxContext value="0"/>
- </OS_2>
-
- <hmtx>
- <mtx name=".notdef" width="500" lsb="93"/>
- <mtx name="U+200D" width="500" lsb="93"/>
- <mtx name="U+1F1E6" width="500" lsb="93"/>
- <mtx name="U+1F1E7" width="500" lsb="93"/>
- <mtx name="U+1F3FB" width="500" lsb="93"/>
- <mtx name="U+1F3FC" width="500" lsb="93"/>
- <mtx name="U+1F9B0" width="500" lsb="93"/>
- <mtx name="U+1F9B1" width="500" lsb="93"/>
- <mtx name="U+1F9B2" width="500" lsb="93"/>
- <mtx name="U+1F9B3" width="500" lsb="93"/>
- <mtx name="U+1F9B4" width="500" lsb="93"/>
- <mtx name="U+1F9B5" width="500" lsb="93"/>
- <mtx name="U+1F9B6" width="500" lsb="93"/>
- <mtx name="U+1F9B7" width="500" lsb="93"/>
- <mtx name="U+1F9B8" width="500" lsb="93"/>
- <mtx name="U+1F9B9" width="500" lsb="93"/>
- <mtx name="U+E0000" width="500" lsb="93"/>
- <mtx name="U+E0001" width="500" lsb="93"/>
- <mtx name="LigaForm1" width="500" lsb="93"/>
- <mtx name="LigaForm2" width="500" lsb="93"/>
- <mtx name="LigaForm3" width="500" lsb="93"/>
- <mtx name="LigaForm4" width="500" lsb="93"/>
- <mtx name="LigaForm5" width="500" lsb="93"/>
- <mtx name="LigaForm6" width="500" lsb="93"/>
- <mtx name="LigaForm7" width="500" lsb="93"/>
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_12 format="12" reserved="0" length="3" nGroups="6" platformID="3" platEncID="1" language="0">
- <map code="0x200D" name="U+200D" />
- <map code="0x1F1E6" name="U+1F1E6" />
- <map code="0x1F1E7" name="U+1F1E7" />
- <map code="0x1F3FB" name="U+1F3FB" />
- <map code="0x1F3FC" name="U+1F3FC" />
- <map code="0x1F9B0" name="U+1F9B0" />
- <map code="0x1F9B1" name="U+1F9B1" />
- <map code="0x1F9B2" name="U+1F9B2" />
- <map code="0x1F9B3" name="U+1F9B3" />
- <map code="0x1F9B4" name="U+1F9B4" />
- <map code="0x1F9B5" name="U+1F9B5" />
- <map code="0x1F9B6" name="U+1F9B6" />
- <map code="0x1F9B7" name="U+1F9B7" />
- <map code="0x1F9B8" name="U+1F9B8" />
- <map code="0x1F9B9" name="U+1F9B9" />
- <map code="0xE0000" name="U+E0000" />
- <map code="0xE0001" name="U+E0001" />
- </cmap_format_12>
- </cmap>
-
- <loca>
- <!-- The 'loca' table will be calculated by the compiler -->
- </loca>
-
- <glyf>
-
- <!-- The xMin, yMin, xMax and yMax values
- will be recalculated by the compiler. -->
-
- <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+200D" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F1E6" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F1E7" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F3FB" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F3FC" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B0" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B1" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B2" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B3" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B4" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B5" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B6" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B7" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B8" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B9" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+E0000" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+E0001" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="LigaForm1" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="LigaForm2" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="LigaForm3" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="LigaForm4" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="LigaForm5" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="LigaForm6" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="LigaForm7" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- </glyf>
-
- <name>
- <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
- EmojiBaseFont
- </namerecord>
- <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
- Regular
- </namerecord>
- <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
- EmojiBaseFont
- </namerecord>
- <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
- EmojiBaseFont
- </namerecord>
- </name>
-
- <post>
- <formatType value="3.0"/>
- <italicAngle value="0.0"/>
- <underlinePosition value="-75"/>
- <underlineThickness value="50"/>
- <isFixedPitch value="0"/>
- <minMemType42 value="0"/>
- <maxMemType42 value="0"/>
- <minMemType1 value="0"/>
- <maxMemType1 value="0"/>
- </post>
-
- <GSUB>
- <Version value="0x00010000"/>
- <ScriptList>
- <ScriptRecord index="0">
- <ScriptTag value="DFLT"/>
- <Script>
- <DefaultLangSys>
- <ReqFeatureIndex value="65535"/>
- <FeatureIndex index="0" value="0"/>
- </DefaultLangSys>
- </Script>
- </ScriptRecord>
- </ScriptList>
- <FeatureList>
- <FeatureRecord index="0">
- <FeatureTag value="ccmp"/>
- <Feature>
- <LookupListIndex index="0" value="0"/>
- </Feature>
- </FeatureRecord>
- </FeatureList>
- <LookupList>
- <Lookup index="0">
- <LookupType value="4"/>
- <LookupFlag value="0"/>
- <LigatureSubst index="0" Format="1">
- <LigatureSet glyph="U+1F9B0">
- <!-- U+1F9B0 U+1F3FB -> LigaForm1 -->
- <Ligature components="U+1F3FB" glyph="LigaForm1"/>
-
- <!-- U+1F9B0 U+1F3FC -> LigaForm2 -->
- <Ligature components="U+1F3FC" glyph="LigaForm2"/>
- </LigatureSet>
- <LigatureSet glyph="U+1F9B1">
- <!-- U+1F9B1 U+1F3FB -> LigaForm3 -->
- <Ligature components="U+1F3FB" glyph="LigaForm3"/>
- </LigatureSet>
- <LigatureSet glyph="U+1F9B2">
- <Ligature components="U+200D,U+1F9B3,U+200D,U+1F9B4" glyph="LigaForm4"/>
- </LigatureSet>
- <LigatureSet glyph="U+1F9B6">
- <!-- U+1F9B6 U+1F3FB -> LigaForm3 -->
- <Ligature components="U+1F3FB" glyph="LigaForm3"/>
- </LigatureSet>
- <LigatureSet glyph="U+1F1E6">
- <Ligature components="U+1F1E6" glyph="LigaForm6"/>
- <Ligature components="U+1F1E7" glyph="LigaForm7"/>
- </LigatureSet>
- </LigatureSubst>
- </Lookup>
- </LookupList>
- </GSUB>
-</ttFont>
diff --git a/tests/data/OverrideEmoji.ttf b/tests/data/OverrideEmoji.ttf
deleted file mode 100644
index 890796b..0000000
--- a/tests/data/OverrideEmoji.ttf
+++ /dev/null
Binary files differ
diff --git a/tests/data/OverrideEmoji.ttx b/tests/data/OverrideEmoji.ttx
deleted file mode 100644
index d5d4091..0000000
--- a/tests/data/OverrideEmoji.ttx
+++ /dev/null
@@ -1,521 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Copyright (C) 2021 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<ttFont sfntVersion="\x00\x01\x00\x00" ttLibVersion="3.9">
-
- <GlyphOrder>
- <!-- The 'id' attribute is only for humans; it is ignored when parsed. -->
- <GlyphID id="0" name=".notdef"/>
-
- <!-- Compbining characters for Emoji -->
- <GlyphID id="1" name="U+200D"/>
- <GlyphID id="2" name="U+1F3FB"/>
- <GlyphID id="3" name="U+1F3FC"/>
-
- <!-- Random Emoji -->
- <GlyphID id="4" name="U+1F9B0"/>
- <GlyphID id="5" name="U+1F9B1"/>
- <GlyphID id="6" name="U+1F9B2"/>
- <GlyphID id="7" name="U+1F9B3"/>
- <GlyphID id="8" name="U+1F9B4"/>
- <GlyphID id="9" name="U+1F9B5"/>
- <!--
- Following four glyphs are removed from EmojiBase.ttf for verifying fallback.
- <GlyphID id="10" name="U+1F9B6"/>
- <GlyphID id="11" name="U+1F9B7"/>
- <GlyphID id="12" name="U+1F9B8"/>
- <GlyphID id="13" name="U+1F9B9"/>
- -->
-
- <!-- Unassigned Code Points -->
- <GlyphID id="14" name="U+E0000"/>
- <!--
- Following glyph is removed from EmojiBase.ttf for verifying fallback.
- <GlyphID id="15" name="U+E0001"/>
- -->
-
- <!-- Ligature Form. Not in cmap -->
- <GlyphID id="16" name="LigaForm1"/>
- <GlyphID id="17" name="LigaForm2"/>
- <GlyphID id="18" name="LigaForm3"/>
- <!--
- Following glyphs are removed from EmojiBase.ttf for verifying fallback.
- <GlyphID id="19" name="LigaForm4"/>
- <GlyphID id="20" name="LigaForm5"/>
- -->
- <GlyphID id="21" name="LigaForm6"/>
- <!--
- Following glyph is removed from EmojiBase.ttf for verifying fallback.
- <GlyphID id="22" name="LigaForm7"/>
- -->
-
- <GlyphID id="23" name="U+1F1E6"/>
- <GlyphID id="24" name="U+1F1E7"/>
- </GlyphOrder>
-
- <head>
- <!-- Most of this table will be recalculated by the compiler -->
- <tableVersion value="1.0"/>
- <fontRevision value="1.0"/>
- <checkSumAdjustment value="0x640cdb2f"/>
- <magicNumber value="0x5f0f3cf5"/>
- <flags value="00000000 00000011"/>
- <unitsPerEm value="1000"/>
- <created value="Wed Sep 9 08:01:17 2015"/>
- <modified value="Wed Sep 9 08:48:07 2015"/>
- <xMin value="0"/>
- <yMin value="0"/>
- <xMax value="0"/>
- <yMax value="0"/>
- <macStyle value="00000000 00000000"/>
- <lowestRecPPEM value="7"/>
- <fontDirectionHint value="2"/>
- <indexToLocFormat value="0"/>
- <glyphDataFormat value="0"/>
- </head>
-
- <hhea>
- <tableVersion value="0x00010000"/>
- <ascent value="1000"/>
- <descent value="-200"/>
- <lineGap value="0"/>
- <advanceWidthMax value="500"/>
- <minLeftSideBearing value="0"/>
- <minRightSideBearing value="0"/>
- <xMaxExtent value="0"/>
- <caretSlopeRise value="1"/>
- <caretSlopeRun value="0"/>
- <caretOffset value="0"/>
- <reserved0 value="0"/>
- <reserved1 value="0"/>
- <reserved2 value="0"/>
- <reserved3 value="0"/>
- <metricDataFormat value="0"/>
- <numberOfHMetrics value="1"/>
- </hhea>
-
- <maxp>
- <!-- Most of this table will be recalculated by the compiler -->
- <tableVersion value="0x10000"/>
- <numGlyphs value="8"/>
- <maxPoints value="0"/>
- <maxContours value="0"/>
- <maxCompositePoints value="0"/>
- <maxCompositeContours value="0"/>
- <maxZones value="2"/>
- <maxTwilightPoints value="12"/>
- <maxStorage value="28"/>
- <maxFunctionDefs value="119"/>
- <maxInstructionDefs value="0"/>
- <maxStackElements value="61"/>
- <maxSizeOfInstructions value="2967"/>
- <maxComponentElements value="0"/>
- <maxComponentDepth value="0"/>
- </maxp>
-
- <OS_2>
- <!-- The fields 'usFirstCharIndex' and 'usLastCharIndex'
- will be recalculated by the compiler -->
- <version value="3"/>
- <xAvgCharWidth value="594"/>
- <usWeightClass value="400"/>
- <usWidthClass value="5"/>
- <fsType value="00000000 00001000"/>
- <ySubscriptXSize value="650"/>
- <ySubscriptYSize value="600"/>
- <ySubscriptXOffset value="0"/>
- <ySubscriptYOffset value="75"/>
- <ySuperscriptXSize value="650"/>
- <ySuperscriptYSize value="600"/>
- <ySuperscriptXOffset value="0"/>
- <ySuperscriptYOffset value="350"/>
- <yStrikeoutSize value="50"/>
- <yStrikeoutPosition value="300"/>
- <sFamilyClass value="0"/>
- <panose>
- <bFamilyType value="0"/>
- <bSerifStyle value="0"/>
- <bWeight value="5"/>
- <bProportion value="0"/>
- <bContrast value="0"/>
- <bStrokeVariation value="0"/>
- <bArmStyle value="0"/>
- <bLetterForm value="0"/>
- <bMidline value="0"/>
- <bXHeight value="0"/>
- </panose>
- <ulUnicodeRange1 value="00000000 00000000 00000000 00000001"/>
- <ulUnicodeRange2 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange3 value="00000000 00000000 00000000 00000000"/>
- <ulUnicodeRange4 value="00000000 00000000 00000000 00000000"/>
- <achVendID value="UKWN"/>
- <fsSelection value="00000000 01000000"/>
- <usFirstCharIndex value="48"/>
- <usLastCharIndex value="65535"/>
- <sTypoAscender value="800"/>
- <sTypoDescender value="-200"/>
- <sTypoLineGap value="200"/>
- <usWinAscent value="1000"/>
- <usWinDescent value="200"/>
- <ulCodePageRange1 value="00000000 00000000 00000000 00000001"/>
- <ulCodePageRange2 value="00000000 00000000 00000000 00000000"/>
- <sxHeight value="500"/>
- <sCapHeight value="700"/>
- <usDefaultChar value="0"/>
- <usBreakChar value="32"/>
- <usMaxContext value="0"/>
- </OS_2>
-
- <hmtx>
- <mtx name=".notdef" width="500" lsb="93"/>
- <mtx name="U+200D" width="500" lsb="93"/>
- <mtx name="U+1F1E6" width="500" lsb="93"/>
- <mtx name="U+1F1E7" width="500" lsb="93"/>
- <mtx name="U+1F3FB" width="500" lsb="93"/>
- <mtx name="U+1F3FC" width="500" lsb="93"/>
- <mtx name="U+1F9B0" width="500" lsb="93"/>
- <mtx name="U+1F9B1" width="500" lsb="93"/>
- <mtx name="U+1F9B2" width="500" lsb="93"/>
- <mtx name="U+1F9B3" width="500" lsb="93"/>
- <mtx name="U+1F9B4" width="500" lsb="93"/>
- <mtx name="U+1F9B5" width="500" lsb="93"/>
- <!--
- Following four glyphs are removed from EmojiBase.ttf for verifying fallback.
- <mtx name="U+1F9B6" width="500" lsb="93"/>
- <mtx name="U+1F9B7" width="500" lsb="93"/>
- <mtx name="U+1F9B8" width="500" lsb="93"/>
- <mtx name="U+1F9B9" width="500" lsb="93"/>
- -->
- <mtx name="U+E0000" width="500" lsb="93"/>
- <!--
- Following glyph is removed from EmojiBase.ttf for verifying fallback.
- <mtx name="U+1F9B6" width="500" lsb="93"/>
- -->
- <mtx name="U+E0001" width="500" lsb="93"/>
- <mtx name="LigaForm1" width="500" lsb="93"/>
- <mtx name="LigaForm2" width="500" lsb="93"/>
- <mtx name="LigaForm3" width="500" lsb="93"/>
- <!--
- Following two glyphs are removed from EmojiBase.ttf for verifying fallback.
- <mtx name="LigaForm4" width="500" lsb="93"/>
- <mtx name="LigaForm5" width="500" lsb="93"/>
- -->
- <mtx name="LigaForm6" width="500" lsb="93"/>
- <!--
- Following glyph is removed from EmojiBase.ttf for verifying fallback.
- <mtx name="LigaForm7" width="500" lsb="93"/>
- -->
- </hmtx>
-
- <cmap>
- <tableVersion version="0"/>
- <cmap_format_12 format="12" reserved="0" length="3" nGroups="6" platformID="3" platEncID="1" language="0">
- <map code="0x200D" name="U+200D" />
- <map code="0x1F1E6" name="U+1F1E6" />
- <map code="0x1F1E7" name="U+1F1E7" />
- <map code="0x1F3FB" name="U+1F3FB" />
- <map code="0x1F3FC" name="U+1F3FC" />
- <map code="0x1F9B0" name="U+1F9B0" />
- <map code="0x1F9B1" name="U+1F9B1" />
- <map code="0x1F9B2" name="U+1F9B2" />
- <map code="0x1F9B3" name="U+1F9B3" />
- <map code="0x1F9B4" name="U+1F9B4" />
- <map code="0x1F9B5" name="U+1F9B5" />
- <!--
- Following four glyphs are removed from EmojiBase.ttf for verifying fallback.
- <map code="0x1F9B6" name="U+1F9B6" />
- <map code="0x1F9B7" name="U+1F9B7" />
- <map code="0x1F9B8" name="U+1F9B8" />
- <map code="0x1F9B9" name="U+1F9B9" />
- -->
- <map code="0xE0000" name="U+E0000" />
- <!--
- Following glyph is removed from EmojiBase.ttf for verifying fallback.
- <map code="0xE0001" name="U+E0001" />
- -->
- </cmap_format_12>
- </cmap>
-
- <loca>
- <!-- The 'loca' table will be calculated by the compiler -->
- </loca>
-
- <glyf>
-
- <!-- The xMin, yMin, xMax and yMax values
- will be recalculated by the compiler. -->
-
- <TTGlyph name=".notdef" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+200D" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F1E6" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F1E7" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F3FB" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F3FC" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B0" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B1" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B2" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B3" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B4" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="U+1F9B5" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <!--
- Following four glyphs are removed from EmojiBase.ttf for verifying fallback.
- <TTGlyph name="U+1F9B6">
- <TTGlyph name="U+1F9B7">
- <TTGlyph name="U+1F9B8">
- <TTGlyph name="U+1F9B9">
- -->
- <TTGlyph name="U+E0000" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <!--
- Following glyph is removed from EmojiBase.ttf for verifying fallback.
- <TTGlyph name="U+E0001"/>
- -->
- <TTGlyph name="LigaForm1" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="LigaForm2" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <TTGlyph name="LigaForm3" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <!--
- Following two glyphs are removed from EmojiBase.ttf for verifying fallback.
- <TTGlyph name="LigaForm4">
- <TTGlyph name="LigaForm5">
- -->
- <TTGlyph name="LigaForm6" xMin="0" yMin="0" xMax="100" yMax="100">
- <contour>
- <pt x="0" y="0" on="1" />
- <pt x="100" y="0" on="1" />
- <pt x="100" y="100" on="1" />
- <pt x="0" y="100" on="1" />
- </contour>
- <instructions><assembly></assembly></instructions>
- </TTGlyph>
- <!--
- Following glyph is removed from EmojiBase.ttf for verifying fallback.
- <TTGlyph name="LigaForm7">
- -->
- </glyf>
-
- <name>
- <namerecord nameID="1" platformID="3" platEncID="1" langID="0x409">
- OverrideEmojiFont
- </namerecord>
- <namerecord nameID="2" platformID="3" platEncID="1" langID="0x409">
- Regular
- </namerecord>
- <namerecord nameID="4" platformID="3" platEncID="1" langID="0x409">
- OverrideEmojiFont
- </namerecord>
- <namerecord nameID="6" platformID="3" platEncID="1" langID="0x409">
- OverrideEmojiFont
- </namerecord>
- </name>
-
- <post>
- <formatType value="3.0"/>
- <italicAngle value="0.0"/>
- <underlinePosition value="-75"/>
- <underlineThickness value="50"/>
- <isFixedPitch value="0"/>
- <minMemType42 value="0"/>
- <maxMemType42 value="0"/>
- <minMemType1 value="0"/>
- <maxMemType1 value="0"/>
- </post>
-
- <GSUB>
- <Version value="0x00010000"/>
- <ScriptList>
- <ScriptRecord index="0">
- <ScriptTag value="DFLT"/>
- <Script>
- <DefaultLangSys>
- <ReqFeatureIndex value="65535"/>
- <FeatureIndex index="0" value="0"/>
- </DefaultLangSys>
- </Script>
- </ScriptRecord>
- </ScriptList>
- <FeatureList>
- <FeatureRecord index="0">
- <FeatureTag value="ccmp"/>
- <Feature>
- <LookupListIndex index="0" value="0"/>
- </Feature>
- </FeatureRecord>
- </FeatureList>
- <LookupList>
- <Lookup index="0">
- <LookupType value="4"/>
- <LookupFlag value="0"/>
- <LigatureSubst index="0" Format="1">
- <LigatureSet glyph="U+1F9B0">
- <!-- U+1F9B0 U+1F3FB -> LigaForm0 -->
- <Ligature components="U+1F3FB" glyph="LigaForm1"/>
-
- <!-- U+1F9B0 U+1F3FC -> LigaForm1 -->
- <!--
- Following ligature is removed from the EmojiBase.ttf for verifying fallback
- <Ligature components="U+1F3FC" glyph="LigaForm2"/>
- -->
- </LigatureSet>
- <!--
- Following ligature is removed from the EmojiBase.ttf for verifying fallback
- <LigatureSet glyph="U+1F9B1">
- <Ligature components="U+1F3FB" glyph="LigaForm3"/>
- </LigatureSet>
- -->
- <LigatureSet glyph="U+1F9B2">
- <Ligature components="U+200D,U+1F9B3" glyph="LigaForm3"/>
- </LigatureSet>
- <!--
- Following ligature is removed from the EmojIBase.ttf for verifying fallback.
- <LigatureSet glyph="U+1F9B6">
- <Ligature components="U+1F3FB" glyph="LigaForm3"/>
- </LigatureSet>
- -->
- <LigatureSet glyph="U+1F1E6">
- <Ligature components="U+1F1E6" glyph="LigaForm6"/>
- <Ligature components="U+1F1E7" glyph=".notdef"/>
- </LigatureSet>
- </LigatureSubst>
- </Lookup>
- </LookupList>
- </GSUB>
-</ttFont>
diff --git a/tests/data/emoji_itemization.xml b/tests/data/emoji_itemization.xml
deleted file mode 100644
index d4213f9..0000000
--- a/tests/data/emoji_itemization.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-<familyset version="22">
- <!-- Place NoGlyphFont here since the first font can be chosen if no font is
- available for the code point. -->
- <family>
- <font weight="400" style="normal">Ascii.ttf</font>
- </family>
- <family lang="und-Zsye">
- <font weight="400" style="normal">EmojiSubset.ttf</font>
- </family>
- <family lang="und-Zsye">
- <font weight="400" style="normal">EmojiBase.ttf</font>
- </family>
-</familyset>
diff --git a/tests/perftests/Android.bp b/tests/perftests/Android.bp
index 19ed8eb..83db1c5 100644
--- a/tests/perftests/Android.bp
+++ b/tests/perftests/Android.bp
@@ -14,10 +14,6 @@
// limitations under the License.
//
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_benchmark {
name: "minikin_perftests",
test_suites: ["device-tests"],
diff --git a/tests/perftests/main.cpp b/tests/perftests/main.cpp
index 88e1900..11904e9 100644
--- a/tests/perftests/main.cpp
+++ b/tests/perftests/main.cpp
@@ -13,12 +13,32 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
#include <benchmark/benchmark.h>
+#include <cutils/log.h>
+#include <unicode/uclean.h>
+#include <unicode/udata.h>
int main(int argc, char** argv) {
+ const char* fn = "/apex/com.android.i18n/etc/icu/" U_ICUDATA_NAME ".dat";
+ int fd = open(fn, O_RDONLY);
+ LOG_ALWAYS_FATAL_IF(fd == -1);
+ struct stat st;
+ LOG_ALWAYS_FATAL_IF(fstat(fd, &st) != 0);
+ void* data = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+
+ UErrorCode errorCode = U_ZERO_ERROR;
+ udata_setCommonData(data, &errorCode);
+ LOG_ALWAYS_FATAL_IF(U_FAILURE(errorCode));
+ u_init(&errorCode);
+ LOG_ALWAYS_FATAL_IF(U_FAILURE(errorCode));
+
benchmark::Initialize(&argc, argv);
benchmark::RunSpecifiedBenchmarks();
+ u_cleanup();
return 0;
}
diff --git a/tests/stresstest/Android.bp b/tests/stresstest/Android.bp
index 784dc6a..fb73e09 100644
--- a/tests/stresstest/Android.bp
+++ b/tests/stresstest/Android.bp
@@ -14,10 +14,6 @@
// see how_to_run.txt for instructions on running these tests
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_test {
name: "minikin_stress_tests",
diff --git a/tests/stresstest/FontFamilyTest.cpp b/tests/stresstest/FontFamilyTest.cpp
index 7a9813e..7554314 100644
--- a/tests/stresstest/FontFamilyTest.cpp
+++ b/tests/stresstest/FontFamilyTest.cpp
@@ -36,7 +36,7 @@ TEST_P(FontFamilyHarfBuzzCompatibilityTest, CoverageTest) {
int ttcIndex = GetParam().second;
auto font = std::make_shared<FreeTypeMinikinFontForTest>(fontPath);
- std::vector<std::shared_ptr<Font>> fonts;
+ std::vector<Font> fonts;
fonts.push_back(Font::Builder(font).build());
std::shared_ptr<FontFamily> family = std::make_shared<FontFamily>(std::move(fonts));
diff --git a/tests/unittest/Android.bp b/tests/unittest/Android.bp
index cae9003..0971a06 100644
--- a/tests/unittest/Android.bp
+++ b/tests/unittest/Android.bp
@@ -14,10 +14,6 @@
// see how_to_run.txt for instructions on running these tests
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_test {
name: "minikin_tests",
test_suites: ["device-tests"],
@@ -45,15 +41,12 @@ cc_test {
srcs: [
"AndroidLineBreakerHelperTest.cpp",
"BidiUtilsTest.cpp",
- "BufferTest.cpp",
- "BoundsCacheTest.cpp",
"CmapCoverageTest.cpp",
"EmojiTest.cpp",
"FontTest.cpp",
"FontCollectionTest.cpp",
"FontCollectionItemizeTest.cpp",
"FontFamilyTest.cpp",
- "FontFileParserTest.cpp",
"FontLanguageListCacheTest.cpp",
"FontUtilsTest.cpp",
"HasherTest.cpp",
diff --git a/tests/unittest/BoundsCacheTest.cpp b/tests/unittest/BoundsCacheTest.cpp
deleted file mode 100644
index 8c727f9..0000000
--- a/tests/unittest/BoundsCacheTest.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * Copyright (C) 2018 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <gtest/gtest.h>
-
-#include "minikin/BoundsCache.h"
-
-#include "FontTestUtils.h"
-#include "LocaleListCache.h"
-#include "UnicodeUtils.h"
-
-namespace minikin {
-
-class TestableBoundsCache : public BoundsCache {
-public:
- TestableBoundsCache(uint32_t maxEntries) : BoundsCache(maxEntries) {}
-};
-
-class BoundsCapture {
-public:
- BoundsCapture() {}
-
- void operator()(const MinikinRect& rect, float advance) {
- mRect = rect;
- mAdvance = advance;
- }
-
- const MinikinRect& rect() const { return mRect; }
- float advance() const { return mAdvance; }
-
-private:
- MinikinRect mRect;
- float mAdvance;
-};
-
-TEST(BoundsCacheTest, cacheHitTest) {
- auto text = utf8ToUtf16("android");
- Range range(0, text.size());
- MinikinPaint paint(buildFontCollection("Ascii.ttf"));
-
- TestableBoundsCache boundsCache(10);
-
- BoundsCapture bounds1;
- boundsCache.getOrCreate(text, range, paint, false /* LTR */, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, bounds1);
-
- BoundsCapture bounds2;
- boundsCache.getOrCreate(text, range, paint, false /* LTR */, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, bounds2);
-
- EXPECT_EQ(bounds1.rect(), bounds2.rect());
- EXPECT_EQ(bounds1.advance(), bounds2.advance());
-}
-
-TEST(BoundsCacheTest, cacheMissTest) {
- auto text1 = utf8ToUtf16("android");
- auto text2 = utf8ToUtf16("αβγδζ");
- MinikinPaint paint(buildFontCollection("Ascii.ttf"));
-
- TestableBoundsCache boundsCache(10);
-
- BoundsCapture bounds1;
- BoundsCapture bounds2;
-
- {
- SCOPED_TRACE("Different text");
- boundsCache.getOrCreate(text1, Range(0, text1.size()), paint, false /* LTR */,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, bounds1);
- boundsCache.getOrCreate(text2, Range(0, text2.size()), paint, false /* LTR */,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, bounds2);
- EXPECT_NE(bounds1.rect(), bounds2.rect());
- EXPECT_NE(bounds1.advance(), bounds2.advance());
- }
- {
- SCOPED_TRACE("Different range");
- boundsCache.getOrCreate(text1, Range(0, text1.size()), paint, false /* LTR */,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, bounds1);
- boundsCache.getOrCreate(text1, Range(1, text1.size()), paint, false /* LTR */,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, bounds2);
- EXPECT_NE(bounds1.rect(), bounds2.rect());
- EXPECT_NE(bounds1.advance(), bounds2.advance());
- }
- {
- SCOPED_TRACE("Different collection");
- MinikinPaint paint1(buildFontCollection("Ascii.ttf"));
- paint1.size = 10.0f;
- paint1.scaleX = 1.0f;
- boundsCache.getOrCreate(text1, Range(0, text1.size()), paint1, false /* LTR */,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, bounds1);
- MinikinPaint paint2(buildFontCollection("Emoji.ttf"));
- paint2.size = 10.0f;
- paint2.scaleX = 1.0f;
- boundsCache.getOrCreate(text1, Range(0, text1.size()), paint2, false /* LTR */,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, bounds2);
- EXPECT_NE(bounds1.rect(), bounds2.rect());
- EXPECT_NE(bounds1.advance(), bounds2.advance());
- }
- {
- SCOPED_TRACE("Different size");
- auto collection = buildFontCollection("Ascii.ttf");
- MinikinPaint paint1(collection);
- paint1.size = 10.0f;
- paint1.scaleX = 1.0f;
- boundsCache.getOrCreate(text1, Range(0, text1.size()), paint1, false /* LTR */,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, bounds1);
- MinikinPaint paint2(collection);
- paint2.size = 20.0f;
- paint2.scaleX = 1.0f;
- boundsCache.getOrCreate(text1, Range(0, text1.size()), paint2, false /* LTR */,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, bounds2);
- EXPECT_NE(bounds1.rect(), bounds2.rect());
- EXPECT_NE(bounds1.advance(), bounds2.advance());
- }
- {
- SCOPED_TRACE("Different letter spacing");
- auto collection = buildFontCollection("Ascii.ttf");
- MinikinPaint paint1(collection);
- paint1.letterSpacing = 0.0f;
- paint1.size = 10.0f;
- paint1.scaleX = 1.0f;
- boundsCache.getOrCreate(text1, Range(0, text1.size()), paint1, false /* LTR */,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, bounds1);
- MinikinPaint paint2(collection);
- paint2.letterSpacing = 1.0f;
- paint2.size = 10.0f;
- paint2.scaleX = 1.0f;
- boundsCache.getOrCreate(text1, Range(0, text1.size()), paint2, false /* LTR */,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, bounds2);
- EXPECT_NE(bounds1.rect(), bounds2.rect());
- EXPECT_NE(bounds1.advance(), bounds2.advance());
- }
-}
-
-TEST(BoundsCacheTest, cacheOverflowTest) {
- auto text = utf8ToUtf16("android");
- Range range(0, text.size());
- MinikinPaint paint(buildFontCollection("Ascii.ttf"));
-
- TestableBoundsCache boundsCache(5);
-
- BoundsCapture bounds1;
- boundsCache.getOrCreate(text, range, paint, false /* LTR */, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, bounds1);
-
- for (char c = 'a'; c <= 'z'; c++) {
- auto text1 = utf8ToUtf16(std::string(10, c));
- BoundsCapture bounds2;
- boundsCache.getOrCreate(text1, Range(0, text1.size()), paint, false /* LTR */,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, bounds2);
- }
-
- BoundsCapture bounds3;
- boundsCache.getOrCreate(text, range, paint, false /* LTR */, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, bounds3);
- EXPECT_EQ(bounds1.rect(), bounds3.rect());
- EXPECT_EQ(bounds1.advance(), bounds3.advance());
-}
-
-} // namespace minikin
diff --git a/tests/unittest/BufferTest.cpp b/tests/unittest/BufferTest.cpp
deleted file mode 100644
index 8b1db33..0000000
--- a/tests/unittest/BufferTest.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "minikin/Buffer.h"
-
-#include <gtest/gtest.h>
-
-namespace minikin {
-
-class TestObject {
-public:
- void writeTo(BufferWriter* writer) const {
- // Total size = 20
- // uint8_t (1)
- writer->write<uint8_t>(0xAB);
- // padding (1), uint16_t (2)
- writer->write<uint16_t>(0xCDEF);
- // uint8_t(1)
- writer->write<uint8_t>(0x01);
- // padding (3), array size (4), uint32_t (4) * 2
- uint32_t uint32Array[] = {0x98765432, 0x98765433};
- writer->writeArray<uint32_t>(uint32Array, 2);
- }
-};
-
-TEST(BufferTest, testMeasureWriteRead) {
- TestObject testObject;
- BufferWriter fakeWriter(nullptr);
- testObject.writeTo(&fakeWriter);
- ASSERT_EQ(fakeWriter.size(), 20u);
- std::vector<uint8_t> buffer(fakeWriter.size());
-
- BufferWriter writer(buffer.data());
- testObject.writeTo(&writer);
- ASSERT_EQ(writer.size(), buffer.size());
-
- BufferReader reader(buffer.data());
- ASSERT_EQ(reader.data(), buffer.data());
- ASSERT_EQ(reader.pos(), 0u);
- ASSERT_EQ(reader.read<uint8_t>(), 0xABu);
- ASSERT_EQ(reader.pos(), 1u);
- ASSERT_EQ(reader.read<uint16_t>(), 0xCDEFu);
- ASSERT_EQ(reader.pos(), 4u);
- ASSERT_EQ(reader.read<uint8_t>(), 0x01u);
- ASSERT_EQ(reader.pos(), 5u);
- auto [uint32Array, size] = reader.readArray<uint32_t>();
- ASSERT_EQ(size, 2u);
- ASSERT_EQ(uint32Array[0], 0x98765432u);
- ASSERT_EQ(uint32Array[1], 0x98765433u);
- ASSERT_EQ(reader.pos(), 20u);
-}
-
-TEST(BufferTest, testSkip) {
- TestObject testObject;
- BufferWriter fakeWriter(nullptr);
- testObject.writeTo(&fakeWriter);
- ASSERT_EQ(fakeWriter.size(), 20u);
- std::vector<uint8_t> buffer(fakeWriter.size());
-
- BufferWriter writer(buffer.data());
- testObject.writeTo(&writer);
- ASSERT_EQ(writer.size(), buffer.size());
-
- BufferReader reader(buffer.data());
- ASSERT_EQ(reader.data(), buffer.data());
- ASSERT_EQ(reader.pos(), 0u);
- reader.skip<uint8_t>();
- ASSERT_EQ(reader.pos(), 1u);
- reader.read<uint16_t>();
- ASSERT_EQ(reader.pos(), 4u);
- reader.skip<uint8_t>();
- ASSERT_EQ(reader.pos(), 5u);
- reader.skipArray<uint32_t>();
- ASSERT_EQ(reader.pos(), 20u);
-}
-
-} // namespace minikin
diff --git a/tests/unittest/FontCollectionItemizeTest.cpp b/tests/unittest/FontCollectionItemizeTest.cpp
index 6f1e194..8cd95aa 100644
--- a/tests/unittest/FontCollectionItemizeTest.cpp
+++ b/tests/unittest/FontCollectionItemizeTest.cpp
@@ -21,7 +21,6 @@
#include <gtest/gtest.h>
#include "minikin/FontFamily.h"
-#include "minikin/FontFileParser.h"
#include "minikin/LocaleList.h"
#include "minikin/MinikinPaint.h"
@@ -56,15 +55,10 @@ const char kMixedEmojiFont[] = "ColorTextMixedEmojiFont.ttf";
const char kHasCmapFormat14Font[] = "NoCmapFormat14.ttf";
const char kNoCmapFormat14Font[] = "VariationSelectorTest-Regular.ttf";
-struct Run {
- FakedFont fakedFont;
- int start;
- int end;
-};
-
// Utility functions for calling itemize function.
-std::vector<Run> itemize(const std::shared_ptr<FontCollection>& collection, const char* str,
- FontStyle style, const std::string& localeList) {
+std::vector<FontCollection::Run> itemize(const std::shared_ptr<FontCollection>& collection,
+ const char* str, FontStyle style,
+ const std::string& localeList) {
const size_t BUF_SIZE = 256;
uint16_t buf[BUF_SIZE];
size_t len;
@@ -82,38 +76,35 @@ std::vector<Run> itemize(const std::shared_ptr<FontCollection>& collection, cons
for (uint32_t i = 0; i < runMax; ++i) {
EXPECT_EQ(result[i].start, resultWithRunMax[i].start);
EXPECT_EQ(result[i].end, resultWithRunMax[i].end);
- EXPECT_EQ(result[i].familyMatch, resultWithRunMax[i].familyMatch);
+ EXPECT_EQ(result[i].fakedFont, resultWithRunMax[i].fakedFont);
}
}
- std::vector<Run> runs;
- for (const auto& r : result) {
- runs.push_back(
- {collection->getBestFont(U16StringPiece(buf, len), r, style), r.start, r.end});
- }
- return runs;
+ return result;
}
// Overloaded version for default font style.
-std::vector<Run> itemize(const std::shared_ptr<FontCollection>& collection, const char* str,
- const std::string& localeList) {
+std::vector<FontCollection::Run> itemize(const std::shared_ptr<FontCollection>& collection,
+ const char* str, const std::string& localeList) {
return itemize(collection, str, FontStyle(), localeList);
}
// Overloaded version for empty locale list id.
-std::vector<Run> itemize(const std::shared_ptr<FontCollection>& collection, const char* str,
- FontStyle style) {
+std::vector<FontCollection::Run> itemize(const std::shared_ptr<FontCollection>& collection,
+ const char* str, FontStyle style) {
return itemize(collection, str, style, "");
}
// Overloaded version for default font style and empty locale list id.
-std::vector<Run> itemize(const std::shared_ptr<FontCollection>& collection, const char* str) {
+std::vector<FontCollection::Run> itemize(const std::shared_ptr<FontCollection>& collection,
+ const char* str) {
return itemize(collection, str, FontStyle(), "");
}
// Utility function to obtain font path associated with run.
-std::string getFontName(const Run& run) {
- EXPECT_NE(nullptr, run.fakedFont.font.get());
- return getBasename(run.fakedFont.font.get()->typeface()->GetFontPath());
+std::string getFontName(const FontCollection::Run& run) {
+ EXPECT_NE(nullptr, run.fakedFont.font);
+ return getBasename(
+ ((FreeTypeMinikinFontForTest*)run.fakedFont.font->typeface().get())->fontPath());
}
// Utility function to obtain LocaleList from string.
@@ -524,13 +515,13 @@ TEST(FontCollectionItemizeTest, itemize_variationSelector) {
ASSERT_EQ(1U, runs.size());
EXPECT_EQ(0, runs[0].start);
EXPECT_EQ(1, runs[0].end);
- EXPECT_TRUE(runs[0].fakedFont.font.get() == nullptr || kLatinFont == getFontName(runs[0]));
+ EXPECT_TRUE(runs[0].fakedFont.font == nullptr || kLatinFont == getFontName(runs[0]));
runs = itemize(collection, "U+FE00", "zh-Hant");
ASSERT_EQ(1U, runs.size());
EXPECT_EQ(0, runs[0].start);
EXPECT_EQ(1, runs[0].end);
- EXPECT_TRUE(runs[0].fakedFont.font.get() == nullptr || kLatinFont == getFontName(runs[0]));
+ EXPECT_TRUE(runs[0].fakedFont.font == nullptr || kLatinFont == getFontName(runs[0]));
// First font family (Regular.ttf) supports U+203C but doesn't support U+203C U+FE0F.
// Emoji.ttf font supports U+203C U+FE0F. Emoji.ttf should be selected.
@@ -661,13 +652,13 @@ TEST(FontCollectionItemizeTest, itemize_variationSelectorSupplement) {
ASSERT_EQ(1U, runs.size());
EXPECT_EQ(0, runs[0].start);
EXPECT_EQ(2, runs[0].end);
- EXPECT_TRUE(runs[0].fakedFont.font.get() == nullptr || kLatinFont == getFontName(runs[0]));
+ EXPECT_TRUE(runs[0].fakedFont.font == nullptr || kLatinFont == getFontName(runs[0]));
runs = itemize(collection, "U+E0100", "zh-Hant");
ASSERT_EQ(1U, runs.size());
EXPECT_EQ(0, runs[0].start);
EXPECT_EQ(2, runs[0].end);
- EXPECT_TRUE(runs[0].fakedFont.font.get() == nullptr || kLatinFont == getFontName(runs[0]));
+ EXPECT_TRUE(runs[0].fakedFont.font == nullptr || kLatinFont == getFontName(runs[0]));
}
TEST(FontCollectionItemizeTest, itemize_no_crash) {
@@ -935,7 +926,7 @@ TEST(FontCollectionItemizeTest, itemize_LocaleScore) {
// Prepare first font which doesn't supports U+9AA8
auto firstFamilyMinikinFont =
std::make_shared<FreeTypeMinikinFontForTest>(getTestFontPath(kNoGlyphFont));
- std::vector<std::shared_ptr<Font>> fonts;
+ std::vector<Font> fonts;
fonts.push_back(Font::Builder(firstFamilyMinikinFont).build());
auto firstFamily =
std::make_shared<FontFamily>(registerLocaleList("und"), FamilyVariant::DEFAULT,
@@ -950,7 +941,7 @@ TEST(FontCollectionItemizeTest, itemize_LocaleScore) {
for (size_t i = 0; i < testCase.fontLocales.size(); ++i) {
auto minikinFont =
std::make_shared<FreeTypeMinikinFontForTest>(getTestFontPath(kJAFont));
- std::vector<std::shared_ptr<Font>> fonts;
+ std::vector<Font> fonts;
fonts.push_back(Font::Builder(minikinFont).build());
auto family = std::make_shared<FontFamily>(registerLocaleList(testCase.fontLocales[i]),
FamilyVariant::DEFAULT, std::move(fonts),
@@ -962,15 +953,14 @@ TEST(FontCollectionItemizeTest, itemize_LocaleScore) {
// Do itemize
auto runs = itemize(collection, "U+9AA8", testCase.userPreferredLocale);
ASSERT_EQ(1U, runs.size());
- ASSERT_NE(nullptr, runs[0].fakedFont.font.get());
+ ASSERT_NE(nullptr, runs[0].fakedFont.font);
// First family doesn't support U+9AA8 and others support it, so the first font should not
// be selected.
- EXPECT_NE(firstFamilyMinikinFont.get(), runs[0].fakedFont.font.get()->typeface().get());
+ EXPECT_NE(firstFamilyMinikinFont.get(), runs[0].fakedFont.font->typeface().get());
// Lookup used font family by MinikinFont*.
- const int usedLocaleIndex =
- fontLocaleIdxMap[runs[0].fakedFont.font.get()->typeface().get()];
+ const int usedLocaleIndex = fontLocaleIdxMap[runs[0].fakedFont.font->typeface().get()];
EXPECT_EQ(testCase.selectedFontIndex, usedLocaleIndex);
}
}
@@ -1531,10 +1521,10 @@ TEST(FontCollectionItemizeTest, itemizeShouldKeepOrderForVS) {
// Both fontA/fontB support U+35A8 but don't support U+35A8 U+E0100. The first font should be
// selected.
auto runs = itemize(collection, "U+35A8 U+E0100");
- EXPECT_EQ(familyA->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(familyA->getFont(0), runs[0].fakedFont.font);
runs = itemize(reversedCollection, "U+35A8 U+E0100");
- EXPECT_EQ(familyB->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(familyB->getFont(0), runs[0].fakedFont.font);
}
// For b/29585939
@@ -1554,10 +1544,10 @@ TEST(FontCollectionItemizeTest, itemizeShouldKeepOrderForVS2) {
// Both hasCmapFormat14Font/noCmapFormat14Font support U+5380 but don't support U+5380 U+E0100.
// The first font should be selected.
auto runs = itemize(collection, "U+5380 U+E0100");
- EXPECT_EQ(hasCmapFormat14Family->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(hasCmapFormat14Family->getFont(0), runs[0].fakedFont.font);
runs = itemize(reversedCollection, "U+5380 U+E0100");
- EXPECT_EQ(noCmapFormat14Family->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(noCmapFormat14Family->getFont(0), runs[0].fakedFont.font);
}
TEST(FontCollectionItemizeTest, colorEmojiSelectionTest) {
@@ -1571,44 +1561,44 @@ TEST(FontCollectionItemizeTest, colorEmojiSelectionTest) {
// Both textEmojiFamily and colorEmojiFamily supports U+203C and U+23E9.
// U+203C is text default emoji, and U+23E9 is color default emoji.
auto runs = itemize(collection, "U+203C", "en-US,en-Zsym");
- EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+23E9", "en-US,en-Zsym");
- EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+203C", "en-US,en-Zsye");
- EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+23E9", "en-US,en-Zsye");
- EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+203C", "ja-Zsym-JP");
- EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+23E9", "ja-Zsym-JP");
- EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+203C", "ja-Zsye-JP");
- EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+23E9", "ja-Zsye-JP");
- EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+203C", "ja-JP-u-em-text");
- EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+23E9", "ja-JP-u-em-text");
- EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+203C", "ja-JP-u-em-emoji");
- EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+23E9", "ja-JP-u-em-emoji");
- EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+203C", "ja-JP,und-Zsym");
- EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+23E9", "ja-JP,und-Zsym");
- EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(textEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+203C", "ja-JP,und-Zsye");
- EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "U+23E9", "ja-JP,und-Zsye");
- EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(colorEmojiFamily->getFont(0), runs[0].fakedFont.font);
}
TEST(FontCollectionItemizeTest, customFallbackTest) {
@@ -1622,60 +1612,11 @@ TEST(FontCollectionItemizeTest, customFallbackTest) {
auto collection = std::make_shared<FontCollection>(families);
auto runs = itemize(collection, "'a'", "");
- EXPECT_EQ(customFallbackFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(customFallbackFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "'a'", "en-US");
- EXPECT_EQ(customFallbackFamily->getFont(0), runs[0].fakedFont.font.get());
+ EXPECT_EQ(customFallbackFamily->getFont(0), runs[0].fakedFont.font);
runs = itemize(collection, "'a'", "ja-JP");
- EXPECT_EQ(customFallbackFamily->getFont(0), runs[0].fakedFont.font.get());
-}
-
-std::string itemizeEmojiAndFontPostScriptName(const std::string& txt) {
- auto firstFamily = buildFontFamily(kAsciiFont);
- auto OverrideEmojiFamily = buildFontFamily("OverrideEmoji.ttf", "und-Zsye");
- auto emojiBaseFamily = buildFontFamily("EmojiBase.ttf", "und-Zsye");
-
- std::vector<std::shared_ptr<FontFamily>> families = {firstFamily, OverrideEmojiFamily,
- emojiBaseFamily};
-
- auto collection = std::make_shared<FontCollection>(families);
- auto runs = itemize(collection, txt.c_str());
-
- EXPECT_EQ(1u, runs.size());
- return FontFileParser(runs[0].fakedFont.font->baseFont()).getPostScriptName().value();
-}
-
-TEST(FontCollectionItemizeTest, emojiFallback) {
- // OverrideEmojiFont supports U+1F9B0, U+E0000, U+1F3FB and U+1F9B0 U+1F3FB sequence.
- // Use Override font.
- EXPECT_EQ("OverrideEmojiFont", itemizeEmojiAndFontPostScriptName("U+1F9B0"));
- EXPECT_EQ("OverrideEmojiFont", itemizeEmojiAndFontPostScriptName("U+E0000"));
- EXPECT_EQ("OverrideEmojiFont", itemizeEmojiAndFontPostScriptName("U+1F9B0 U+1F3FB"));
- EXPECT_EQ("OverrideEmojiFont", itemizeEmojiAndFontPostScriptName("U+1F9B0 U+FE0F U+1F3FB"));
-
- // OverrideEmojiFont doesn't suppot U+1F9B6 U+E0001 and U+1F3FC.
- EXPECT_EQ("EmojiBaseFont", itemizeEmojiAndFontPostScriptName("U+1F9B6"));
- EXPECT_EQ("EmojiBaseFont", itemizeEmojiAndFontPostScriptName("U+E0001"));
- EXPECT_EQ("EmojiBaseFont", itemizeEmojiAndFontPostScriptName("U+1F9B6 U+1F3FC"));
- EXPECT_EQ("EmojiBaseFont", itemizeEmojiAndFontPostScriptName("U+1F9B6 U+FE0F U+1F3FC"));
-
- // OverrideEmojiFont support U+1F9B1, U+1F3FB but doesn't support the sequence U+1F9B1 U+1F3FB.
- EXPECT_EQ("OverrideEmojiFont", itemizeEmojiAndFontPostScriptName("U+1F9B1"));
- EXPECT_EQ("OverrideEmojiFont", itemizeEmojiAndFontPostScriptName("U+1F3FB"));
- EXPECT_EQ("EmojiBaseFont", itemizeEmojiAndFontPostScriptName("U+1F9B1 U+1F3FB"));
- EXPECT_EQ("EmojiBaseFont", itemizeEmojiAndFontPostScriptName("U+1F9B1 U+FE0F U+1F3FB"));
-
- // Find the longest sequence if two sequences are supported.
- EXPECT_EQ("OverrideEmojiFont", itemizeEmojiAndFontPostScriptName("U+1F9B2 U+200D U+1F9B3"));
- EXPECT_EQ("EmojiBaseFont",
- itemizeEmojiAndFontPostScriptName("U+1F9B2 U+200D U+1F9B3 U+200D U+1F9B4"));
-}
-
-TEST(FontCollectionItemizeTest, emojiFlagFallback) {
- // If the OverrideEmojiFont supports U+1F1E6 U+1F1E6, use that font.
- EXPECT_EQ("OverrideEmojiFont", itemizeEmojiAndFontPostScriptName("U+1F1E6 U+1F1E6"));
-
- // Even if the OverrideEmojiFont directs to .notdef (i.e. Tofu glyph) for the sequence, use it.
- EXPECT_EQ("OverrideEmojiFont", itemizeEmojiAndFontPostScriptName("U+1F1E6 U+1F1E7"));
+ EXPECT_EQ(customFallbackFamily->getFont(0), runs[0].fakedFont.font);
}
} // namespace minikin
diff --git a/tests/unittest/FontCollectionTest.cpp b/tests/unittest/FontCollectionTest.cpp
index aa9d4a8..6b39508 100644
--- a/tests/unittest/FontCollectionTest.cpp
+++ b/tests/unittest/FontCollectionTest.cpp
@@ -19,7 +19,6 @@
#include <gtest/gtest.h>
#include "FontTestUtils.h"
-#include "FreeTypeMinikinFontForTest.h"
#include "MinikinInternal.h"
namespace minikin {
@@ -57,23 +56,22 @@ void expectVSGlyphs(const FontCollection* fc, uint32_t codepoint, const std::set
}
}
-void expectVSGlyphsForVsTestFont(const FontCollection* fc) {
+TEST(FontCollectionTest, hasVariationSelectorTest) {
+ auto fc = buildFontCollection(kVsTestFont);
+
EXPECT_FALSE(fc->hasVariationSelector(0x82A6, 0));
- expectVSGlyphs(fc, 0x82A6, std::set<uint32_t>({0xFE00, 0xFE0E, 0xE0100, 0xE0101, 0xE0102}));
+ expectVSGlyphs(fc.get(), 0x82A6,
+ std::set<uint32_t>({0xFE00, 0xFE0E, 0xE0100, 0xE0101, 0xE0102}));
EXPECT_FALSE(fc->hasVariationSelector(0x845B, 0));
- expectVSGlyphs(fc, 0x845B, std::set<uint32_t>({0xFE01, 0xFE0E, 0xE0101, 0xE0102, 0xE0103}));
+ expectVSGlyphs(fc.get(), 0x845B,
+ std::set<uint32_t>({0xFE01, 0xFE0E, 0xE0101, 0xE0102, 0xE0103}));
EXPECT_FALSE(fc->hasVariationSelector(0x537F, 0));
- expectVSGlyphs(fc, 0x537F, std::set<uint32_t>({0xFE0E}));
+ expectVSGlyphs(fc.get(), 0x537F, std::set<uint32_t>({0xFE0E}));
EXPECT_FALSE(fc->hasVariationSelector(0x717D, 0));
- expectVSGlyphs(fc, 0x717D, std::set<uint32_t>({0xFE02, 0xE0102, 0xE0103}));
-}
-
-TEST(FontCollectionTest, hasVariationSelectorTest) {
- auto fc = buildFontCollection(kVsTestFont);
- expectVSGlyphsForVsTestFont(fc.get());
+ expectVSGlyphs(fc.get(), 0x717D, std::set<uint32_t>({0xFE02, 0xE0102, 0xE0103}));
}
const char kEmojiXmlFile[] = "emoji.xml";
@@ -177,144 +175,4 @@ TEST(FontCollectionTest, createWithVariations) {
}
}
-std::vector<uint8_t> writeToBuffer(
- const std::vector<std::shared_ptr<FontCollection>>& collections) {
- BufferWriter fakeWriter(nullptr);
- FontCollection::writeVector<writeFreeTypeMinikinFontForTest>(&fakeWriter, collections);
- std::vector<uint8_t> buffer(fakeWriter.size());
- BufferWriter writer(buffer.data());
- FontCollection::writeVector<writeFreeTypeMinikinFontForTest>(&writer, collections);
- return buffer;
-}
-
-TEST(FontCollectionTest, bufferTest) {
- {
- std::vector<std::shared_ptr<FontCollection>> original({buildFontCollection(kVsTestFont)});
- std::vector<uint8_t> buffer = writeToBuffer(original);
- BufferReader reader(buffer.data());
- auto copied = FontCollection::readVector<readFreeTypeMinikinFontForTest>(&reader);
- EXPECT_EQ(1u, copied.size());
- expectVSGlyphsForVsTestFont(copied[0].get());
- EXPECT_EQ(original[0]->getSupportedTags(), copied[0]->getSupportedTags());
- // Id will be different.
- EXPECT_NE(original[0]->getId(), copied[0]->getId());
- std::vector<uint8_t> newBuffer = writeToBuffer(copied);
- EXPECT_EQ(buffer, newBuffer);
- }
- {
- // Test that FontFamily instances are shared.
- std::vector<std::shared_ptr<FontFamily>> families = {buildFontFamily(kVsTestFont)};
- auto fc1 = std::make_shared<FontCollection>(families);
- auto fc2 = std::make_shared<FontCollection>(families);
- std::vector<std::shared_ptr<FontCollection>> original({fc1, fc2});
- std::vector<uint8_t> buffer = writeToBuffer(original);
- BufferReader reader(buffer.data());
- auto copied = FontCollection::readVector<readFreeTypeMinikinFontForTest>(&reader);
- EXPECT_EQ(2u, copied.size());
- EXPECT_EQ(copied[0]->mFamilies[0], copied[1]->mFamilies[0]);
- std::vector<uint8_t> newBuffer = writeToBuffer(copied);
- EXPECT_EQ(buffer, newBuffer);
- }
- {
- // Test axes.
- // This font has 'wdth' and 'wght' axes.
- const char kMultiAxisFont[] = "MultiAxis.ttf";
- std::vector<std::shared_ptr<FontCollection>> original(
- {buildFontCollection(kMultiAxisFont)});
- std::vector<uint8_t> buffer = writeToBuffer(original);
- BufferReader reader(buffer.data());
- auto copied = FontCollection::readVector<readFreeTypeMinikinFontForTest>(&reader);
- EXPECT_EQ(1u, copied.size());
- EXPECT_EQ(1u,
- copied[0]->getSupportedTags().count(MinikinFont::MakeTag('w', 'd', 't', 'h')));
- EXPECT_EQ(1u,
- copied[0]->getSupportedTags().count(MinikinFont::MakeTag('w', 'g', 'h', 't')));
- std::vector<uint8_t> newBuffer = writeToBuffer(copied);
- EXPECT_EQ(buffer, newBuffer);
- }
-}
-
-TEST(FontCollectionTest, FamilyMatchResultBuilderTest) {
- using Builder = FontCollection::FamilyMatchResult::Builder;
- EXPECT_TRUE(Builder().empty());
- EXPECT_EQ(0u, Builder().size());
- EXPECT_EQ(1u, Builder().add(5).size());
- EXPECT_EQ(2u, Builder().add(5).add(4).size());
-
- // Reset
- EXPECT_TRUE(Builder().add(5).reset().empty());
- EXPECT_EQ(0u, Builder().add(5).reset().size());
-}
-
-TEST(FontCollectionTest, FamilyMatchResultTest) {
- using Builder = FontCollection::FamilyMatchResult::Builder;
-
- auto r = Builder().build();
- EXPECT_EQ(0u, r.size());
- EXPECT_TRUE(r.empty());
-
- r = Builder().add(1).build();
- EXPECT_EQ(1u, r.size());
- EXPECT_FALSE(r.empty());
- EXPECT_EQ(1u, r[0]);
-
- r = Builder().add(1).add(2).build();
- EXPECT_EQ(2u, r.size());
- EXPECT_FALSE(r.empty());
- EXPECT_EQ(1u, r[0]);
- EXPECT_EQ(2u, r[1]);
-}
-
-TEST(FontCollectionTest, FamilyMatchResultTest_BuilderHoldeFirst7) {
- auto b = FontCollection::FamilyMatchResult::Builder();
- for (uint8_t i = 0; i < 128; ++i) {
- b.add(i);
- }
- auto r = b.build();
- EXPECT_EQ(7u, r.size());
- EXPECT_FALSE(r.empty());
- EXPECT_EQ(0u, r[0]);
- EXPECT_EQ(1u, r[1]);
- EXPECT_EQ(2u, r[2]);
- EXPECT_EQ(3u, r[3]);
- EXPECT_EQ(4u, r[4]);
- EXPECT_EQ(5u, r[5]);
- EXPECT_EQ(6u, r[6]);
-}
-
-TEST(FontCollectionTest, FamilyMatchResultTest_iterator) {
- auto b = FontCollection::FamilyMatchResult::Builder();
- for (uint8_t i = 0; i < 7; ++i) {
- b.add(i);
- }
- auto r = b.build();
- EXPECT_EQ(7u, r.size());
- EXPECT_FALSE(r.empty());
- int i = 0;
- for (auto v : r) {
- EXPECT_EQ(i, v);
- i++;
- }
-}
-
-TEST(FontCollectionTest, FamilyMatchResultTest_intersect) {
- using Builder = FontCollection::FamilyMatchResult::Builder;
-
- EXPECT_EQ(Builder().add(1).add(2).add(3).build(),
- FontCollection::FamilyMatchResult::intersect(Builder().add(1).add(2).add(3).build(),
- Builder().add(1).add(2).add(3).build()));
-
- EXPECT_EQ(Builder().build(),
- FontCollection::FamilyMatchResult::intersect(Builder().add(1).add(2).add(3).build(),
- Builder().build()));
-
- EXPECT_EQ(Builder().build(),
- FontCollection::FamilyMatchResult::intersect(Builder().add(2).add(4).add(6).build(),
- Builder().add(1).add(3).add(5).build()));
-
- EXPECT_EQ(Builder().add(1).add(3).build(),
- FontCollection::FamilyMatchResult::intersect(Builder().add(1).add(2).add(3).build(),
- Builder().add(1).add(3).add(5).build()));
-}
-
} // namespace minikin
diff --git a/tests/unittest/FontFamilyTest.cpp b/tests/unittest/FontFamilyTest.cpp
index fd2fc9a..2b70faf 100644
--- a/tests/unittest/FontFamilyTest.cpp
+++ b/tests/unittest/FontFamilyTest.cpp
@@ -20,7 +20,6 @@
#include "minikin/LocaleList.h"
-#include "BufferUtils.h"
#include "FontTestUtils.h"
#include "FreeTypeMinikinFontForTest.h"
#include "LocaleListCache.h"
@@ -157,40 +156,6 @@ TEST(LocaleTest, testReconstruction) {
EXPECT_EQ("zzz-Zzzz-999", createLocaleWithoutICUSanitization("zzz-Zzzz-999").getString());
}
-TEST(LocaleTest, ReconstructFromIdentifierTest) {
- std::string locales[] = {
- // Language
- "en",
- "fil",
- "und",
- // Script
- "en-Latn",
- "fil-Taga",
- "und-Zsye",
- // Region
- "en-US",
- "fil-PH",
- "es-419",
- // Variant
- "de-Latn-DE",
- "de-Latn-DE-1901",
- "de-Latn-DE-1996",
- // Line break style
- "ja-JP-u-lb-loose",
- "ja-JP-u-lb-normal",
- "ja-JP-u-lb-strict",
- // Emoji subtag
- "es-Latn-419-u-em-emoji",
- // Everything
- "de-Latn-DE-1996-u-lb-loose-u-em-emoji",
- };
- for (const std::string& locale : locales) {
- EXPECT_EQ(createLocaleWithoutICUSanitization(locale),
- Locale(createLocaleWithoutICUSanitization(locale).getIdentifier()))
- << "locale = " << locale;
- }
-}
-
TEST(LocaleTest, ScriptEqualTest) {
EXPECT_TRUE(createLocale("en").isEqualScript(createLocale("en")));
EXPECT_TRUE(createLocale("en-Latn").isEqualScript(createLocale("en")));
@@ -550,7 +515,9 @@ void expectVSGlyphs(FontFamily* family, uint32_t codepoint, const std::set<uint3
}
}
-void expectVSGlyphsForVsTestFont(FontFamily* family) {
+TEST_F(FontFamilyTest, hasVariationSelectorTest) {
+ std::shared_ptr<FontFamily> family = buildFontFamily(kVsTestFont);
+
const uint32_t kVS1 = 0xFE00;
const uint32_t kVS2 = 0xFE01;
const uint32_t kVS3 = 0xFE02;
@@ -561,28 +528,23 @@ void expectVSGlyphsForVsTestFont(FontFamily* family) {
const uint32_t kSupportedChar1 = 0x82A6;
EXPECT_TRUE(family->getCoverage().get(kSupportedChar1));
- expectVSGlyphs(family, kSupportedChar1, std::set<uint32_t>({kVS1, kVS17, kVS18, kVS19}));
+ expectVSGlyphs(family.get(), kSupportedChar1, std::set<uint32_t>({kVS1, kVS17, kVS18, kVS19}));
const uint32_t kSupportedChar2 = 0x845B;
EXPECT_TRUE(family->getCoverage().get(kSupportedChar2));
- expectVSGlyphs(family, kSupportedChar2, std::set<uint32_t>({kVS2, kVS18, kVS19, kVS20}));
+ expectVSGlyphs(family.get(), kSupportedChar2, std::set<uint32_t>({kVS2, kVS18, kVS19, kVS20}));
const uint32_t kNoVsSupportedChar = 0x537F;
EXPECT_TRUE(family->getCoverage().get(kNoVsSupportedChar));
- expectVSGlyphs(family, kNoVsSupportedChar, std::set<uint32_t>());
+ expectVSGlyphs(family.get(), kNoVsSupportedChar, std::set<uint32_t>());
const uint32_t kVsOnlySupportedChar = 0x717D;
EXPECT_FALSE(family->getCoverage().get(kVsOnlySupportedChar));
- expectVSGlyphs(family, kVsOnlySupportedChar, std::set<uint32_t>({kVS3, kVS19, kVS20}));
+ expectVSGlyphs(family.get(), kVsOnlySupportedChar, std::set<uint32_t>({kVS3, kVS19, kVS20}));
const uint32_t kNotSupportedChar = 0x845C;
EXPECT_FALSE(family->getCoverage().get(kNotSupportedChar));
- expectVSGlyphs(family, kNotSupportedChar, std::set<uint32_t>());
-}
-
-TEST_F(FontFamilyTest, hasVariationSelectorTest) {
- std::shared_ptr<FontFamily> family = buildFontFamily(kVsTestFont);
- expectVSGlyphsForVsTestFont(family.get());
+ expectVSGlyphs(family.get(), kNotSupportedChar, std::set<uint32_t>());
}
TEST_F(FontFamilyTest, hasVSTableTest) {
@@ -766,7 +728,7 @@ TEST_F(FontFamilyTest, closestMatch) {
for (const TestCase& testCase : testCases) {
std::vector<std::shared_ptr<MinikinFont>> dummyFonts;
- std::vector<std::shared_ptr<Font>> fonts;
+ std::vector<Font> fonts;
for (auto familyStyle : testCase.familyStyles) {
std::shared_ptr<MinikinFont> dummyFont(
new FreeTypeMinikinFontForTest(getTestFontPath(kTestFont)));
@@ -794,41 +756,4 @@ TEST_F(FontFamilyTest, closestMatch) {
}
}
-TEST_F(FontFamilyTest, bufferTest) {
- {
- // Font with variation selectors
- std::shared_ptr<FontFamily> original = buildFontFamily(kVsTestFont);
- std::vector<uint8_t> buffer =
- writeToBuffer<FontFamily, writeFreeTypeMinikinFontForTest>(*original);
- BufferReader reader(buffer.data());
- std::shared_ptr<FontFamily> copied =
- FontFamily::readFrom<readFreeTypeMinikinFontForTest>(&reader);
- ASSERT_EQ(original->localeListId(), copied->localeListId());
- ASSERT_EQ(original->variant(), copied->variant());
- ASSERT_EQ(original->getNumFonts(), copied->getNumFonts());
- ASSERT_EQ(original->supportedAxes(), copied->supportedAxes());
- ASSERT_EQ(original->isColorEmojiFamily(), copied->isColorEmojiFamily());
- ASSERT_EQ(original->isCustomFallback(), copied->isCustomFallback());
- ASSERT_EQ(original->hasVSTable(), copied->hasVSTable());
- expectVSGlyphsForVsTestFont(copied.get());
- std::vector<uint8_t> newBuffer =
- writeToBuffer<FontFamily, writeFreeTypeMinikinFontForTest>(*copied);
- ASSERT_EQ(buffer, newBuffer);
- }
- {
- // Font with axes
- constexpr char kMultiAxisFont[] = "MultiAxis.ttf";
- std::shared_ptr<FontFamily> original = buildFontFamily(kMultiAxisFont);
- std::vector<uint8_t> buffer =
- writeToBuffer<FontFamily, writeFreeTypeMinikinFontForTest>(*original);
- BufferReader reader(buffer.data());
- std::shared_ptr<FontFamily> copied =
- FontFamily::readFrom<readFreeTypeMinikinFontForTest>(&reader);
- ASSERT_EQ(original->supportedAxes(), copied->supportedAxes());
- std::vector<uint8_t> newBuffer =
- writeToBuffer<FontFamily, writeFreeTypeMinikinFontForTest>(*copied);
- ASSERT_EQ(buffer, newBuffer);
- }
-}
-
} // namespace minikin
diff --git a/tests/unittest/FontFileParserTest.cpp b/tests/unittest/FontFileParserTest.cpp
deleted file mode 100644
index d960217..0000000
--- a/tests/unittest/FontFileParserTest.cpp
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "minikin/FontFileParser.h"
-
-#include <gtest/gtest.h>
-
-#include "FontTestUtils.h"
-#include "FreeTypeMinikinFontForTest.h"
-#include "PathUtils.h"
-
-namespace minikin {
-namespace {
-
-static size_t writeU16(uint16_t x, uint8_t* out, size_t offset) {
- out[offset] = x >> 8;
- out[offset + 1] = x;
- return offset + 2;
-}
-
-static size_t writeU32(uint32_t x, uint8_t* out, size_t offset) {
- out[offset] = x >> 24;
- out[offset + 1] = x >> 16;
- out[offset + 2] = x >> 8;
- out[offset + 3] = x;
- return offset + 4;
-}
-
-class TestableFontFileParser : public FontFileParser {
-public:
- using FontFileParser::analyzeFontRevision;
- using FontFileParser::checkPSName;
-};
-
-// Returns valid head table contents.
-static std::vector<uint8_t> buildHeadTable(uint32_t fontRevision) {
- std::vector<uint8_t> out(46);
- size_t head = writeU16(1, out.data(), 0); // major version
- head = writeU16(0, out.data(), head); // minor version
- head = writeU32(fontRevision, out.data(), head); // fontRevision
- head = writeU32(0xB1B0AFBA, out.data(), head); // checksum. (random value)
- head = writeU32(0x5F0F3CF5, out.data(), head); // magicNumber
- head = writeU16(0, out.data(), head); // flasgs
- head = writeU16(1024, out.data(), head); // unitsPerEm
- head = writeU32(123457890, out.data(), head); // created (random value)
- head = writeU32(123457890, out.data(), head); // modified (random value)
- head = writeU16(0, out.data(), head); // xMin
- head = writeU16(100, out.data(), head); // yMin
- head = writeU16(1024, out.data(), head); // xMax
- head = writeU16(2048, out.data(), head); // yMax
- head = writeU16(0, out.data(), head); // macStyle
- head = writeU16(10, out.data(), head); // lowestRecPPEM
- head = writeU16(1, out.data(), head); // fontDirectionHint
- head = writeU16(1, out.data(), head); // indexToLocFormat
- head = writeU16(0, out.data(), head); // glyphDataFormat;
-
- return out;
-}
-
-TEST(FontFileParserTest, analyzeFontRevision) {
- uint32_t rev = 0x12345678;
- std::vector<uint8_t> head = buildHeadTable(rev);
-
- uint32_t out = 0;
- EXPECT_TRUE(TestableFontFileParser::analyzeFontRevision(head.data(), head.size(), &out));
- EXPECT_EQ(rev, out);
-}
-
-TEST(FontFileParserTest, headInvalidLength) {
- uint32_t rev = 0x12345678;
- std::vector<uint8_t> head = buildHeadTable(rev);
-
- uint32_t out = 0;
- EXPECT_FALSE(TestableFontFileParser::analyzeFontRevision(head.data(), 6, &out));
-}
-
-TEST(FontFileParserTest, parseFontForRev) {
- auto minikinFont = std::make_shared<FreeTypeMinikinFontForTest>(getTestFontPath("Ascii.ttf"));
- auto parser = FontFileParser(minikinFont->GetFontData(), minikinFont->GetFontSize(), 0);
-
- auto revision = parser.getFontRevision();
- EXPECT_TRUE(revision.has_value());
- EXPECT_EQ(0x00010000u, revision.value());
-}
-
-TEST(FontFileParser, checkPSName) {
- EXPECT_TRUE(TestableFontFileParser::checkPSName("Roboto-Regular"));
- EXPECT_TRUE(TestableFontFileParser::checkPSName("NotoColorEmoji"));
-
- // Space character is not allowed.
- EXPECT_FALSE(TestableFontFileParser::checkPSName("Roboto Regular"));
- EXPECT_FALSE(TestableFontFileParser::checkPSName("Noto Color Emoji"));
-
- // parens are not not allowed.
- EXPECT_FALSE(TestableFontFileParser::checkPSName("Roboto (Regular)"));
- EXPECT_FALSE(TestableFontFileParser::checkPSName("Noto <Color> {Emoji}"));
-
- // control characters are not allowed
- EXPECT_FALSE(TestableFontFileParser::checkPSName("Roboto-Regular\b"));
- EXPECT_FALSE(TestableFontFileParser::checkPSName("NotoColorEmoji\t"));
-
- // Up to 63 character is allowed.
- EXPECT_FALSE(TestableFontFileParser::checkPSName(std::string(64, 'a')));
-
- // Only printable ASCII is allowed.
- EXPECT_FALSE(TestableFontFileParser::checkPSName("ろぼとふぉんと"));
-}
-
-TEST(FontFileParserTest, parseFontForPSName) {
- auto minikinFont = std::make_shared<FreeTypeMinikinFontForTest>(getTestFontPath("Ascii.ttf"));
- auto parser = FontFileParser(minikinFont->GetFontData(), minikinFont->GetFontSize(), 0);
-
- auto psName = parser.getPostScriptName();
- EXPECT_TRUE(psName.has_value());
- EXPECT_EQ("SampleFont-Regular", psName.value());
-}
-
-} // namespace
-} // namespace minikin
diff --git a/tests/unittest/FontLanguageListCacheTest.cpp b/tests/unittest/FontLanguageListCacheTest.cpp
index e68922d..e957cfc 100644
--- a/tests/unittest/FontLanguageListCacheTest.cpp
+++ b/tests/unittest/FontLanguageListCacheTest.cpp
@@ -61,25 +61,4 @@ TEST(LocaleListCacheTest, getById) {
EXPECT_EQ(japanese, locales2[1]);
}
-TEST(LocaleListCacheTest, buffer) {
- std::string locales[] = {"en", "jp", "en,zh-Hans"};
- // Measure
- BufferWriter fakeWriter(nullptr);
- for (const std::string& locale : locales) {
- LocaleListCache::writeTo(&fakeWriter, LocaleListCache::getId(locale));
- }
- // Write
- std::vector<uint8_t> buffer(fakeWriter.size());
- BufferWriter writer(buffer.data());
- for (const std::string& locale : locales) {
- LocaleListCache::writeTo(&writer, LocaleListCache::getId(locale));
- }
- // Read
- BufferReader reader(buffer.data());
- for (const std::string& locale : locales) {
- EXPECT_EQ(LocaleListCache::getId(locale), LocaleListCache::readFrom(&reader))
- << "locale = " << locale;
- }
-}
-
} // namespace minikin
diff --git a/tests/unittest/FontTest.cpp b/tests/unittest/FontTest.cpp
index 68f5b51..ff2f9bc 100644
--- a/tests/unittest/FontTest.cpp
+++ b/tests/unittest/FontTest.cpp
@@ -18,25 +18,28 @@
#include <gtest/gtest.h>
-#include "BufferUtils.h"
#include "FontTestUtils.h"
#include "FreeTypeMinikinFontForTest.h"
namespace minikin {
-TEST(FontTest, BufferTest) {
+TEST(FontTest, CopyTest) {
auto minikinFont = std::make_shared<FreeTypeMinikinFontForTest>(getTestFontPath("Ascii.ttf"));
- std::shared_ptr<Font> original = Font::Builder(minikinFont).build();
- std::vector<uint8_t> buffer = writeToBuffer<Font, writeFreeTypeMinikinFontForTest>(*original);
-
- BufferReader reader(buffer.data());
- std::shared_ptr<Font> font =
- Font::readFrom<readFreeTypeMinikinFontForTest>(&reader, kEmptyLocaleListId);
- EXPECT_EQ(minikinFont->GetFontPath(), font->typeface()->GetFontPath());
- EXPECT_EQ(original->style(), font->style());
- EXPECT_NE(nullptr, font->baseFont());
- std::vector<uint8_t> newBuffer = writeToBuffer<Font, writeFreeTypeMinikinFontForTest>(*font);
- EXPECT_EQ(buffer, newBuffer);
+ {
+ Font font = Font::Builder(minikinFont).build();
+ {
+ Font copied(font);
+ EXPECT_EQ(font.typeface(), copied.typeface());
+ EXPECT_EQ(font.style(), copied.style());
+ EXPECT_EQ(font.baseFont(), copied.baseFont());
+ }
+ {
+ Font copied = font;
+ EXPECT_EQ(font.typeface(), copied.typeface());
+ EXPECT_EQ(font.style(), copied.style());
+ EXPECT_EQ(font.baseFont(), copied.baseFont());
+ }
+ }
}
} // namespace minikin
diff --git a/tests/unittest/GreedyLineBreakerTest.cpp b/tests/unittest/GreedyLineBreakerTest.cpp
index e9da1a1..13cc03c 100644
--- a/tests/unittest/GreedyLineBreakerTest.cpp
+++ b/tests/unittest/GreedyLineBreakerTest.cpp
@@ -93,33 +93,6 @@ private:
std::vector<uint8_t> mHyphenationPattern;
};
-TEST_F(GreedyLineBreakerTest, roundingError) {
- MeasuredTextBuilder builder;
- auto family1 = buildFontFamily("Ascii.ttf");
- std::vector<std::shared_ptr<FontFamily>> families = {family1};
- auto fc = std::make_shared<FontCollection>(families);
- MinikinPaint paint(fc);
- paint.size = 56.0f; // Make 1em=56px
- paint.scaleX = 1;
- paint.letterSpacing = -0.093f;
- paint.localeListId = LocaleListCache::getId("en-US");
- const std::vector<uint16_t> textBuffer = utf8ToUtf16("8888888888888888888");
-
- float measured = Layout::measureText(textBuffer, Range(0, textBuffer.size()), Bidi::LTR, paint,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, nullptr);
-
- builder.addStyleRun(0, textBuffer.size(), std::move(paint), false);
- std::unique_ptr<MeasuredText> measuredText =
- builder.build(textBuffer, false /* compute hyphenation */,
- false /* compute full layout */, nullptr /* no hint */);
- RectangleLineWidth rectangleLineWidth(measured);
- TabStops tabStops(nullptr, 0, 10);
- LineBreakResult r = breakLineGreedy(textBuffer, *measuredText, rectangleLineWidth, tabStops,
- false /* do hyphenation */);
-
- EXPECT_EQ(1u, r.breakPoints.size());
-}
-
TEST_F(GreedyLineBreakerTest, testBreakWithoutHyphenation) {
constexpr bool NO_HYPHEN = false; // No hyphenation in this test case.
const std::vector<uint16_t> textBuf = utf8ToUtf16("This is an example text.");
diff --git a/tests/unittest/HasherTest.cpp b/tests/unittest/HasherTest.cpp
index 02cbda8..8e11cc6 100644
--- a/tests/unittest/HasherTest.cpp
+++ b/tests/unittest/HasherTest.cpp
@@ -35,9 +35,4 @@ TEST(HasherTest, hasherTest) {
EXPECT_EQ(hasher.hash(), hasher.hash());
}
-TEST(HasherTest, hasherTestFloat) {
- float x = 1.1f;
- EXPECT_NE(Hasher().update(x).hash(), Hasher().update(1).hash());
-}
-
} // namespace minikin
diff --git a/tests/unittest/ICUEnvironment.h b/tests/unittest/ICUEnvironment.h
new file mode 100644
index 0000000..8fd285f
--- /dev/null
+++ b/tests/unittest/ICUEnvironment.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef MINIKIN_TEST_ICU_ENVIRONMENT_H
+#define MINIKIN_TEST_ICU_ENVIRONMENT_H
+
+// low level file access for mapping ICU data
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/stat.h>
+
+#include <cutils/log.h>
+#include <gtest/gtest.h>
+#include <unicode/uclean.h>
+#include <unicode/udata.h>
+
+namespace minikin {
+
+class ICUEnvironment : public testing::Environment {
+public:
+ ICUEnvironment() : testing::Environment(), mData(nullptr), mSize(0) {}
+
+ void* mData;
+ size_t mSize;
+
+ virtual void SetUp() override {
+ const char* fn = "/apex/com.android.i18n/etc/icu/" U_ICUDATA_NAME ".dat";
+ int fd = open(fn, O_RDONLY);
+ LOG_ALWAYS_FATAL_IF(fd == -1);
+ struct stat sb;
+ LOG_ALWAYS_FATAL_IF(fstat(fd, &sb) != 0);
+
+ mSize = sb.st_size;
+ void* mData = mmap(nullptr, mSize, PROT_READ, MAP_SHARED, fd, 0);
+ close(fd);
+
+ UErrorCode errorCode = U_ZERO_ERROR;
+ udata_setCommonData(mData, &errorCode);
+ LOG_ALWAYS_FATAL_IF(U_FAILURE(errorCode));
+
+ errorCode = U_ZERO_ERROR;
+ u_init(&errorCode);
+ LOG_ALWAYS_FATAL_IF(U_FAILURE(errorCode));
+ }
+
+ virtual void TearDown() override {
+ u_cleanup();
+ munmap(mData, mSize);
+ }
+};
+
+} // namespace minikin
+#endif // MINIKIN_TEST_ICU_ENVIRONMENT_H
diff --git a/tests/unittest/LayoutCoreTest.cpp b/tests/unittest/LayoutCoreTest.cpp
index 2ab7543..ef972a0 100644
--- a/tests/unittest/LayoutCoreTest.cpp
+++ b/tests/unittest/LayoutCoreTest.cpp
@@ -74,6 +74,7 @@ TEST(LayoutPieceTest, doLayoutTest) {
auto layout = buildLayout("I", {"LayoutTestFont.ttf"});
EXPECT_EQ(1u, layout.glyphCount());
EXPECT_EQ(Point(0, 0), layout.pointAt(0));
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.bounds());
EXPECT_EQ(MinikinExtent(-100.0f, 20.0f), layout.extent());
EXPECT_EQ(1u, layout.fonts().size());
EXPECT_TRUE(layout.fontAt(0).font);
@@ -86,6 +87,7 @@ TEST(LayoutPieceTest, doLayoutTest) {
EXPECT_EQ(2u, layout.glyphCount());
EXPECT_EQ(Point(0, 0), layout.pointAt(0));
EXPECT_EQ(Point(10.0f, 0), layout.pointAt(1));
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), layout.bounds());
EXPECT_EQ(MinikinExtent(-100.0f, 20.0f), layout.extent());
EXPECT_EQ(1u, layout.fonts().size());
EXPECT_TRUE(layout.fontAt(0).font);
@@ -101,6 +103,7 @@ TEST(LayoutPieceTest, doLayoutTest) {
EXPECT_EQ(2u, layout.glyphCount());
EXPECT_EQ(Point(0, 0), layout.pointAt(0));
EXPECT_EQ(Point(10.0f, 0), layout.pointAt(1));
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 60.0f, 0.0f), layout.bounds());
EXPECT_EQ(MinikinExtent(-100.0f, 20.0f), layout.extent());
EXPECT_EQ(1u, layout.fonts().size());
EXPECT_TRUE(layout.fontAt(0).font);
@@ -127,6 +130,7 @@ TEST(LayoutPieceTest, doLayoutTest_MultiFont) {
EXPECT_EQ(2u, layout.glyphCount());
EXPECT_EQ(Point(0, 0), layout.pointAt(0));
EXPECT_EQ(Point(10.0f, 0), layout.pointAt(1));
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 30.0f, 0.0f), layout.bounds());
EXPECT_EQ(MinikinExtent(-160.0f, 40.0f), layout.extent());
EXPECT_EQ(2u, layout.fonts().size());
EXPECT_TRUE(layout.fontAt(0).font);
@@ -142,6 +146,7 @@ TEST(LayoutPieceTest, doLayoutTest_MultiFont) {
EXPECT_EQ(2u, layout.glyphCount());
EXPECT_EQ(Point(0, 0), layout.pointAt(0));
EXPECT_EQ(Point(20.0f, 0), layout.pointAt(1));
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 30.0f, 0.0f), layout.bounds());
EXPECT_EQ(MinikinExtent(-160.0f, 40.0f), layout.extent());
EXPECT_EQ(2u, layout.fonts().size());
EXPECT_TRUE(layout.fontAt(0).font);
@@ -163,6 +168,7 @@ TEST(LayoutPieceTest, doLayoutTest_Ligature) {
auto layout = buildLayout("fi", {"Ligature.ttf"});
EXPECT_EQ(1u, layout.glyphCount());
EXPECT_EQ(Point(0, 0), layout.pointAt(0));
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.bounds());
EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), layout.extent());
EXPECT_EQ(1u, layout.fonts().size());
EXPECT_TRUE(layout.fontAt(0).font);
@@ -175,6 +181,7 @@ TEST(LayoutPieceTest, doLayoutTest_Ligature) {
auto layout = buildLayout("ff", {"Ligature.ttf"});
EXPECT_EQ(1u, layout.glyphCount());
EXPECT_EQ(Point(0, 0), layout.pointAt(0));
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.bounds());
EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), layout.extent());
EXPECT_EQ(1u, layout.fonts().size());
EXPECT_TRUE(layout.fontAt(0).font);
@@ -187,6 +194,7 @@ TEST(LayoutPieceTest, doLayoutTest_Ligature) {
auto layout = buildLayout("fi", {"Ligature.ttf"}, "'liga' off");
EXPECT_EQ(1u, layout.glyphCount());
EXPECT_EQ(Point(0, 0), layout.pointAt(0));
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.bounds());
EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), layout.extent());
EXPECT_EQ(1u, layout.fonts().size());
EXPECT_TRUE(layout.fontAt(0).font);
@@ -199,6 +207,7 @@ TEST(LayoutPieceTest, doLayoutTest_Ligature) {
auto layout = buildLayout("ff", {"Ligature.ttf"}, "'liga' off");
EXPECT_EQ(2u, layout.glyphCount());
EXPECT_EQ(Point(0, 0), layout.pointAt(0));
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), layout.bounds());
EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), layout.extent());
EXPECT_EQ(1u, layout.fonts().size());
EXPECT_TRUE(layout.fontAt(0).font);
@@ -213,6 +222,7 @@ TEST(LayoutPieceTest, doLayoutTest_Ligature) {
auto layout = buildLayout("fii", {"Ligature.ttf"});
EXPECT_EQ(2u, layout.glyphCount());
EXPECT_EQ(Point(0, 0), layout.pointAt(0));
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), layout.bounds());
EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), layout.extent());
EXPECT_EQ(1u, layout.fonts().size());
EXPECT_TRUE(layout.fontAt(0).font);
@@ -228,6 +238,7 @@ TEST(LayoutPieceTest, doLayoutTest_Ligature) {
auto layout = buildLayout("if", {"Ligature.ttf"});
EXPECT_EQ(2u, layout.glyphCount());
EXPECT_EQ(Point(0, 0), layout.pointAt(0));
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), layout.bounds());
EXPECT_EQ(MinikinExtent(-80.0f, 20.0f), layout.extent());
EXPECT_EQ(1u, layout.fonts().size());
EXPECT_TRUE(layout.fontAt(0).font);
diff --git a/tests/unittest/LayoutTest.cpp b/tests/unittest/LayoutTest.cpp
index 7771051..4b97cee 100644
--- a/tests/unittest/LayoutTest.cpp
+++ b/tests/unittest/LayoutTest.cpp
@@ -20,7 +20,6 @@
#include "minikin/FontCollection.h"
#include "minikin/LayoutPieces.h"
-#include "minikin/Measurement.h"
#include "FontTestUtils.h"
#include "UnicodeUtils.h"
@@ -36,12 +35,6 @@ static void expectAdvances(const std::vector<float>& expected, const std::vector
}
}
-static void getBounds(const U16StringPiece& text, Bidi bidiFlags, const MinikinPaint& paint,
- MinikinRect* out) {
- getBounds(text, Range(0, text.size()), bidiFlags, paint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, out);
-}
-
class LayoutTest : public testing::Test {
protected:
LayoutTest() : mCollection(nullptr) {}
@@ -71,8 +64,7 @@ TEST_F(LayoutTest, doLayoutTest) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(70.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(70.0f, rect.mRight);
@@ -90,8 +82,7 @@ TEST_F(LayoutTest, doLayoutTest) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(90.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(90.0f, rect.mRight);
@@ -109,8 +100,7 @@ TEST_F(LayoutTest, doLayoutTest) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(160.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(160.0f, rect.mRight);
@@ -128,8 +118,7 @@ TEST_F(LayoutTest, doLayoutTest) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(110.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(110.0f, rect.mRight);
@@ -159,8 +148,7 @@ TEST_F(LayoutTest, doLayoutTest_wordSpacing) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(70.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(70.0f, rect.mRight);
@@ -178,8 +166,7 @@ TEST_F(LayoutTest, doLayoutTest_wordSpacing) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(95.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(95.0f, rect.mRight);
@@ -198,8 +185,7 @@ TEST_F(LayoutTest, doLayoutTest_wordSpacing) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(170.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(170.0f, rect.mRight);
@@ -219,8 +205,7 @@ TEST_F(LayoutTest, doLayoutTest_wordSpacing) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(120.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(120.0f, rect.mRight);
@@ -253,8 +238,7 @@ TEST_F(LayoutTest, doLayoutTest_negativeWordSpacing) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(70.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(70.0f, rect.mRight);
@@ -272,8 +256,7 @@ TEST_F(LayoutTest, doLayoutTest_negativeWordSpacing) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(85.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(85.0f, rect.mRight);
@@ -292,8 +275,7 @@ TEST_F(LayoutTest, doLayoutTest_negativeWordSpacing) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(140.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(140.0f, rect.mRight);
@@ -313,8 +295,7 @@ TEST_F(LayoutTest, doLayoutTest_negativeWordSpacing) {
Layout layout(text, range, Bidi::LTR, paint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
EXPECT_EQ(100.0f, layout.getAdvance());
-
- getBounds(text, Bidi::LTR, paint, &rect);
+ layout.getBounds(&rect);
EXPECT_EQ(0.0f, rect.mLeft);
EXPECT_EQ(10.0f, rect.mTop);
EXPECT_EQ(100.0f, rect.mRight);
diff --git a/tests/unittest/MeasuredTextTest.cpp b/tests/unittest/MeasuredTextTest.cpp
index e5766a1..1934ed8 100644
--- a/tests/unittest/MeasuredTextTest.cpp
+++ b/tests/unittest/MeasuredTextTest.cpp
@@ -19,7 +19,6 @@
#include <gtest/gtest.h>
#include "minikin/LineBreaker.h"
-#include "minikin/Measurement.h"
#include "FontTestUtils.h"
#include "UnicodeUtils.h"
@@ -76,34 +75,6 @@ TEST(MeasuredTextTest, getBoundsTest) {
EXPECT_EQ(MinikinRect(0.0f, 10.0f, 130.0f, 0.0f), mt->getBounds(text, Range(0, text.size())));
}
-TEST(MeasuredTextTest, getBoundsTest_LTR) {
- auto text = utf8ToUtf16("\u0028"); // U+0028 has 1em in LTR, 3em in RTL.
- auto font = buildFontCollection("Bbox.ttf");
-
- MeasuredTextBuilder builder;
- MinikinPaint paint(font);
- paint.size = 10.0f;
- builder.addStyleRun(0, text.size(), std::move(paint), false /* is RTL */);
- auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
- nullptr /* no hint */);
-
- EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), mt->getBounds(text, Range(0, 1)));
-}
-
-TEST(MeasuredTextTest, getBoundsTest_RTL) {
- auto text = utf8ToUtf16("\u0028"); // U+0028 has 1em in LTR, 3em in RTL.
- auto font = buildFontCollection("Bbox.ttf");
-
- MeasuredTextBuilder builder;
- MinikinPaint paint(font);
- paint.size = 10.0f;
- builder.addStyleRun(0, text.size(), std::move(paint), true /* is RTL */);
- auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
- nullptr /* no hint */);
-
- EXPECT_EQ(MinikinRect(0.0f, 30.0f, 30.0f, 0.0f), mt->getBounds(text, Range(0, 2)));
-}
-
TEST(MeasuredTextTest, getBoundsTest_multiStyle) {
auto text = utf8ToUtf16("Hello, World!");
auto font = buildFontCollection("Ascii.ttf");
@@ -184,7 +155,6 @@ TEST(MeasuredTextTest, buildLayoutTest) {
auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
nullptr /* no hint */);
- MinikinRect rect;
MinikinPaint samePaint(font);
samePaint.size = 10.0f;
@@ -201,9 +171,7 @@ TEST(MeasuredTextTest, buildLayoutTest) {
EXPECT_EQ(10.0f, layout.getAdvance());
EXPECT_EQ(10.0f, layout.getCharAdvance(0));
EXPECT_EQ(1u, layout.getAdvances().size());
- getBounds(text, Range(0, 1), Bidi::LTR, samePaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(0, 2), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
@@ -217,9 +185,7 @@ TEST(MeasuredTextTest, buildLayoutTest) {
EXPECT_EQ(10.0f, layout.getCharAdvance(0));
EXPECT_EQ(10.0f, layout.getCharAdvance(1));
EXPECT_EQ(2u, layout.getAdvances().size());
- getBounds(text, Range(0, 2), Bidi::LTR, samePaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(1, 2), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
@@ -230,9 +196,7 @@ TEST(MeasuredTextTest, buildLayoutTest) {
EXPECT_EQ(10.0f, layout.getAdvance());
EXPECT_EQ(10.0f, layout.getCharAdvance(0));
EXPECT_EQ(1u, layout.getAdvances().size());
- getBounds(text, Range(1, 2), Bidi::LTR, samePaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(0, text.size()), fullContext, samePaint,
StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
@@ -246,9 +210,7 @@ TEST(MeasuredTextTest, buildLayoutTest) {
}
EXPECT_EQ(130.0f, layout.getAdvance());
EXPECT_EQ(text.size(), layout.getAdvances().size());
- getBounds(text, Range(0, text.size()), Bidi::LTR, samePaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 10.0f, 130.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 130.0f, 0.0f), layout.getBounds());
}
TEST(MeasuredTextTest, buildLayoutTest_multiStyle) {
@@ -267,7 +229,6 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle) {
auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
nullptr /* no hint */);
- MinikinRect rect;
MinikinPaint samePaint(font);
samePaint.size = 10.0f;
@@ -284,9 +245,7 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle) {
EXPECT_EQ(10.0f, layout.getAdvance());
EXPECT_EQ(10.0f, layout.getCharAdvance(0));
EXPECT_EQ(1u, layout.getAdvances().size());
- getBounds(text, Range(0, 1), Bidi::LTR, samePaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(0, 2), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
@@ -300,9 +259,7 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle) {
EXPECT_EQ(10.0f, layout.getCharAdvance(0));
EXPECT_EQ(10.0f, layout.getCharAdvance(1));
EXPECT_EQ(2u, layout.getAdvances().size());
- getBounds(text, Range(0, 2), Bidi::LTR, samePaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 20.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(1, 2), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
@@ -313,9 +270,7 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle) {
EXPECT_EQ(10.0f, layout.getAdvance());
EXPECT_EQ(10.0f, layout.getCharAdvance(0));
EXPECT_EQ(1u, layout.getAdvances().size());
- getBounds(text, Range(1, 2), Bidi::LTR, samePaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 10.0f, 10.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(7, 7), fullContext, samePaint, StartHyphenEdit::NO_EDIT,
EndHyphenEdit::NO_EDIT);
@@ -332,9 +287,7 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle) {
EXPECT_EQ(20.0f, layout.getAdvance());
EXPECT_EQ(20.0f, layout.getCharAdvance(0));
EXPECT_EQ(1u, layout.getAdvances().size());
- getBounds(text, Range(7, 8), Bidi::LTR, samePaint2, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 20.0f, 20.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 20.0f, 20.0f, 0.0f), layout.getBounds());
}
TEST(MeasuredTextTest, buildLayoutTest_differentPaint) {
@@ -349,7 +302,6 @@ TEST(MeasuredTextTest, buildLayoutTest_differentPaint) {
auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
nullptr /* no hint */);
- MinikinRect rect;
MinikinPaint differentPaint(font);
differentPaint.size = 20.0f;
@@ -366,9 +318,7 @@ TEST(MeasuredTextTest, buildLayoutTest_differentPaint) {
EXPECT_EQ(20.0f, layout.getAdvance());
EXPECT_EQ(20.0f, layout.getCharAdvance(0));
EXPECT_EQ(1u, layout.getAdvances().size());
- getBounds(text, Range(0, 1), Bidi::LTR, differentPaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 20.0f, 20.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 20.0f, 20.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(0, 2), fullContext, differentPaint,
StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
@@ -382,9 +332,7 @@ TEST(MeasuredTextTest, buildLayoutTest_differentPaint) {
EXPECT_EQ(20.0f, layout.getCharAdvance(0));
EXPECT_EQ(20.0f, layout.getCharAdvance(1));
EXPECT_EQ(2u, layout.getAdvances().size());
- getBounds(text, Range(0, 2), Bidi::LTR, differentPaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 20.0f, 40.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 20.0f, 40.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(1, 2), fullContext, differentPaint,
StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
@@ -395,9 +343,7 @@ TEST(MeasuredTextTest, buildLayoutTest_differentPaint) {
EXPECT_EQ(20.0f, layout.getAdvance());
EXPECT_EQ(20.0f, layout.getCharAdvance(0));
EXPECT_EQ(1u, layout.getAdvances().size());
- getBounds(text, Range(1, 2), Bidi::LTR, differentPaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 20.0f, 20.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 20.0f, 20.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(0, text.size()), fullContext, differentPaint,
StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
@@ -411,9 +357,7 @@ TEST(MeasuredTextTest, buildLayoutTest_differentPaint) {
}
EXPECT_EQ(260.0f, layout.getAdvance());
EXPECT_EQ(text.size(), layout.getAdvances().size());
- getBounds(text, Range(0, text.size()), Bidi::LTR, differentPaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 20.0f, 260.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 20.0f, 260.0f, 0.0f), layout.getBounds());
}
TEST(MeasuredTextTest, buildLayoutTest_multiStyle_differentPaint) {
@@ -432,7 +376,6 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle_differentPaint) {
auto mt = builder.build(text, true /* hyphenation */, true /* full layout */,
nullptr /* no hint */);
- MinikinRect rect;
MinikinPaint differentPaint(font);
differentPaint.size = 30.0f;
@@ -449,9 +392,7 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle_differentPaint) {
EXPECT_EQ(30.0f, layout.getAdvance());
EXPECT_EQ(30.0f, layout.getCharAdvance(0));
EXPECT_EQ(1u, layout.getAdvances().size());
- getBounds(text, Range(0, 1), Bidi::LTR, differentPaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 30.0f, 30.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 30.0f, 30.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(0, 2), fullContext, differentPaint,
StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
@@ -465,9 +406,7 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle_differentPaint) {
EXPECT_EQ(30.0f, layout.getCharAdvance(0));
EXPECT_EQ(30.0f, layout.getCharAdvance(1));
EXPECT_EQ(2u, layout.getAdvances().size());
- getBounds(text, Range(0, 2), Bidi::LTR, differentPaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 30.0f, 60.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 30.0f, 60.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(1, 2), fullContext, differentPaint,
StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
@@ -478,9 +417,7 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle_differentPaint) {
EXPECT_EQ(30.0f, layout.getAdvance());
EXPECT_EQ(30.0f, layout.getCharAdvance(0));
EXPECT_EQ(1u, layout.getAdvances().size());
- getBounds(text, Range(1, 2), Bidi::LTR, differentPaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 30.0f, 30.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 30.0f, 30.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(7, 7), fullContext, differentPaint,
StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
@@ -495,9 +432,7 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle_differentPaint) {
EXPECT_EQ(30.0f, layout.getAdvance());
EXPECT_EQ(30.0f, layout.getCharAdvance(0));
EXPECT_EQ(1u, layout.getAdvances().size());
- getBounds(text, Range(7, 8), Bidi::LTR, differentPaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 30.0f, 30.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 30.0f, 30.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(6, 8), fullContext, differentPaint,
StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
@@ -511,9 +446,7 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle_differentPaint) {
EXPECT_EQ(30.0f, layout.getCharAdvance(0));
EXPECT_EQ(30.0f, layout.getCharAdvance(1));
EXPECT_EQ(2u, layout.getAdvances().size());
- getBounds(text, Range(6, 8), Bidi::LTR, differentPaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 30.0f, 60.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 30.0f, 60.0f, 0.0f), layout.getBounds());
layout = mt->buildLayout(text, Range(0, text.size()), fullContext, differentPaint,
StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT);
@@ -527,9 +460,7 @@ TEST(MeasuredTextTest, buildLayoutTest_multiStyle_differentPaint) {
}
EXPECT_EQ(390.0f, layout.getAdvance());
EXPECT_EQ(text.size(), layout.getAdvances().size());
- getBounds(text, Range(0, text.size()), Bidi::LTR, differentPaint, StartHyphenEdit::NO_EDIT,
- EndHyphenEdit::NO_EDIT, &rect);
- EXPECT_EQ(MinikinRect(0.0f, 30.0f, 390.0f, 0.0f), rect);
+ EXPECT_EQ(MinikinRect(0.0f, 30.0f, 390.0f, 0.0f), layout.getBounds());
}
} // namespace minikin
diff --git a/tests/unittest/OptimalLineBreakerTest.cpp b/tests/unittest/OptimalLineBreakerTest.cpp
index d6801cc..51aab60 100644
--- a/tests/unittest/OptimalLineBreakerTest.cpp
+++ b/tests/unittest/OptimalLineBreakerTest.cpp
@@ -2080,33 +2080,5 @@ TEST_F(OptimalLineBreakerTest, testControllCharAfterSpace) {
<< toString(textBuf, actual);
}
}
-
-TEST_F(OptimalLineBreakerTest, roundingError) {
- MeasuredTextBuilder builder;
- auto family1 = buildFontFamily("Ascii.ttf");
- std::vector<std::shared_ptr<FontFamily>> families = {family1};
- auto fc = std::make_shared<FontCollection>(families);
- MinikinPaint paint(fc);
- paint.size = 56.0f; // Make 1em=56px
- paint.scaleX = 1;
- paint.letterSpacing = -0.093f;
- paint.localeListId = LocaleListCache::getId("en-US");
- const std::vector<uint16_t> textBuffer = utf8ToUtf16("8888888888888888888");
-
- float measured = Layout::measureText(textBuffer, Range(0, textBuffer.size()), Bidi::LTR, paint,
- StartHyphenEdit::NO_EDIT, EndHyphenEdit::NO_EDIT, nullptr);
-
- builder.addStyleRun(0, textBuffer.size(), std::move(paint), false);
- std::unique_ptr<MeasuredText> measuredText =
- builder.build(textBuffer, false /* compute hyphenation */,
- false /* compute full layout */, nullptr /* no hint */);
- RectangleLineWidth rectangleLineWidth(measured);
- TabStops tabStops(nullptr, 0, 10);
- LineBreakResult r = doLineBreak(textBuffer, *measuredText, BreakStrategy::Balanced,
- HyphenationFrequency::None, measured);
-
- EXPECT_EQ(1u, r.breakPoints.size());
-}
-
} // namespace
} // namespace minikin
diff --git a/tests/unittest/SparseBitSetTest.cpp b/tests/unittest/SparseBitSetTest.cpp
index 8c67964..03a14d9 100644
--- a/tests/unittest/SparseBitSetTest.cpp
+++ b/tests/unittest/SparseBitSetTest.cpp
@@ -20,8 +20,6 @@
#include <gtest/gtest.h>
-#include "BufferUtils.h"
-
namespace minikin {
TEST(SparseBitSetTest, randomTest) {
@@ -54,29 +52,4 @@ TEST(SparseBitSetTest, randomTest) {
}
}
-TEST(SparseBitSetTest, bufferTest) {
- std::vector<uint32_t> range({10, 20});
- SparseBitSet originalBitset(range.data(), range.size() / 2);
- std::vector<uint8_t> buffer = writeToBuffer(originalBitset);
- BufferReader reader(buffer.data());
- SparseBitSet bitset(&reader);
-
- for (size_t i = 0; i < 10; ++i) ASSERT_FALSE(bitset.get(i)) << i;
- for (size_t i = 10; i < 20; ++i) ASSERT_TRUE(bitset.get(i)) << i;
- for (size_t i = 20; i < 30; ++i) ASSERT_FALSE(bitset.get(i)) << i;
- std::vector<uint8_t> newBuffer = writeToBuffer(bitset);
- ASSERT_EQ(buffer, newBuffer);
-}
-
-TEST(SparseBitSetTest, emptyBitSetBufferTest) {
- SparseBitSet empty;
- std::vector<uint8_t> buffer = writeToBuffer(empty);
- BufferReader reader(buffer.data());
- SparseBitSet bitset(&reader);
-
- ASSERT_FALSE(bitset.get(0));
- std::vector<uint8_t> newBuffer = writeToBuffer(bitset);
- ASSERT_EQ(buffer, newBuffer);
-}
-
} // namespace minikin
diff --git a/tests/unittest/SystemFontsTest.cpp b/tests/unittest/SystemFontsTest.cpp
index f1b0109..fe603a9 100644
--- a/tests/unittest/SystemFontsTest.cpp
+++ b/tests/unittest/SystemFontsTest.cpp
@@ -21,7 +21,6 @@
#include "minikin/FontCollection.h"
#include "FontTestUtils.h"
-#include "PathUtils.h"
namespace minikin {
namespace {
@@ -31,18 +30,10 @@ public:
TestableSystemFonts() : SystemFonts() {}
virtual ~TestableSystemFonts() {}
- std::shared_ptr<FontCollection> findFontCollection(const std::string& familyName) {
+ std::shared_ptr<FontCollection> findFontCollection(const std::string& familyName) const {
return findFontCollectionInternal(familyName);
}
- void addFontMap(std::shared_ptr<FontCollection>&& collections) {
- addFontMapInternal(std::move(collections));
- }
-
- void getFontSet(std::function<void(const std::vector<std::shared_ptr<Font>>&)> func) {
- getFontSetInternal(func);
- }
-
void registerFallback(const std::string& familyName,
const std::shared_ptr<FontCollection>& fc) {
registerFallbackInternal(familyName, fc);
@@ -75,44 +66,5 @@ TEST(SystemFontsTest, registerDefaultAndFallback) {
EXPECT_EQ(fc2, systemFonts.findFontCollection("sans"));
}
-TEST(SystemFontsTest, updateDefaultAndFallback) {
- TestableSystemFonts systemFonts;
- auto fc1 = buildFontCollection("Ascii.ttf");
- auto fc2 = buildFontCollection("Bold.ttf");
- systemFonts.registerDefault(fc1);
- systemFonts.registerFallback("sans", fc2);
- systemFonts.registerDefault(fc2);
- systemFonts.registerFallback("sans", fc1);
- EXPECT_EQ(fc2, systemFonts.findFontCollection("unknown-name"));
- EXPECT_EQ(fc1, systemFonts.findFontCollection("sans"));
-}
-
-TEST(SystemFontTest, getAvailableFont_dedupFonts) {
- TestableSystemFonts systemFonts;
- auto asciiFamily = buildFontFamily("Ascii.ttf");
- auto boldFamily = buildFontFamily("Bold.ttf");
- auto boldItalicFamily = buildFontFamily("BoldItalic.ttf");
-
- auto fc1Families = std::vector<std::shared_ptr<FontFamily>>{asciiFamily, boldItalicFamily};
- auto fc2Families = std::vector<std::shared_ptr<FontFamily>>{boldFamily, boldItalicFamily};
- auto fc1 = std::make_shared<FontCollection>(std::move(fc1Families));
- auto fc2 = std::make_shared<FontCollection>(std::move(fc2Families));
-
- systemFonts.addFontMap(std::move(fc1));
- systemFonts.addFontMap(std::move(fc2));
-
- systemFonts.getFontSet([](const std::vector<std::shared_ptr<Font>>& fonts) {
- EXPECT_EQ(3u, fonts.size()); // Ascii, Bold and BoldItalic
- std::unordered_set<std::string> fontPaths;
- for (const auto& font : fonts) {
- fontPaths.insert(getBasename(font->typeface()->GetFontPath()));
- }
-
- EXPECT_TRUE(fontPaths.find("Ascii.ttf") != fontPaths.end());
- EXPECT_TRUE(fontPaths.find("Bold.ttf") != fontPaths.end());
- EXPECT_TRUE(fontPaths.find("BoldItalic.ttf") != fontPaths.end());
- });
-}
-
} // namespace
} // namespace minikin
diff --git a/tests/unittest/TestMain.cpp b/tests/unittest/TestMain.cpp
index 05e3da4..6680fbd 100644
--- a/tests/unittest/TestMain.cpp
+++ b/tests/unittest/TestMain.cpp
@@ -14,9 +14,12 @@
* limitations under the License.
*/
+#include "ICUEnvironment.h"
+
#include <gtest/gtest.h>
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
+ ::testing::AddGlobalTestEnvironment(new minikin::ICUEnvironment);
return RUN_ALL_TESTS();
}
diff --git a/tests/util/Android.bp b/tests/util/Android.bp
index 1d3d8cf..8bf125b 100644
--- a/tests/util/Android.bp
+++ b/tests/util/Android.bp
@@ -1,7 +1,3 @@
-package {
- default_applicable_licenses: ["Android-Apache-2.0"],
-}
-
cc_library_static {
name: "libminikin-tests-util",
srcs: [
diff --git a/tests/util/BufferUtils.h b/tests/util/BufferUtils.h
deleted file mode 100644
index 355e74e..0000000
--- a/tests/util/BufferUtils.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (C) 2020 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef MINIKIN_TEST_BUFFER_UTILS_H
-#define MINIKIN_TEST_BUFFER_UTILS_H
-
-#include <minikin/Buffer.h>
-#include <vector>
-
-namespace minikin {
-
-template <class T>
-std::vector<uint8_t> allocateBuffer(const T& t) {
- BufferWriter writer(nullptr);
- t.writeTo(&writer);
- // Fill with 0xFF for debugging.
- return std::vector<uint8_t>(writer.size(), 0xFFu);
-}
-
-template <class T, auto arg>
-std::vector<uint8_t> allocateBuffer(const T& t) {
- BufferWriter writer(nullptr);
- t.template writeTo<arg>(&writer);
- // Fill with 0xFF for debugging.
- return std::vector<uint8_t>(writer.size(), 0xFFu);
-}
-
-template <class T>
-std::vector<uint8_t> writeToBuffer(const T& t) {
- std::vector<uint8_t> buffer = allocateBuffer(t);
- BufferWriter writer(buffer.data());
- t.writeTo(&writer);
- return buffer;
-}
-
-template <class T, auto arg>
-std::vector<uint8_t> writeToBuffer(const T& t) {
- std::vector<uint8_t> buffer = allocateBuffer<T, arg>(t);
- BufferWriter writer(buffer.data());
- t.template writeTo<arg>(&writer);
- return buffer;
-}
-
-} // namespace minikin
-
-#endif // MINIKIN_TEST_BUFFER_UTILS_H
diff --git a/tests/util/FontTestUtils.cpp b/tests/util/FontTestUtils.cpp
index 5370ab6..4143c04 100644
--- a/tests/util/FontTestUtils.cpp
+++ b/tests/util/FontTestUtils.cpp
@@ -67,7 +67,7 @@ std::vector<std::shared_ptr<FontFamily>> getFontFamilies(const std::string& font
}
}
- std::vector<std::shared_ptr<Font>> fonts;
+ std::vector<Font> fonts;
for (xmlNode* fontNode = familyNode->children; fontNode; fontNode = fontNode->next) {
if (xmlStrcmp(fontNode->name, (const xmlChar*)"font") != 0) {
continue;
@@ -124,7 +124,7 @@ std::shared_ptr<FontCollection> buildFontCollection(const std::string& filePath)
std::shared_ptr<FontFamily> buildFontFamily(const std::string& filePath) {
auto font = std::make_shared<FreeTypeMinikinFontForTest>(getTestFontPath(filePath));
- std::vector<std::shared_ptr<Font>> fonts;
+ std::vector<Font> fonts;
fonts.push_back(Font::Builder(font).build());
return std::make_shared<FontFamily>(std::move(fonts));
}
@@ -132,7 +132,7 @@ std::shared_ptr<FontFamily> buildFontFamily(const std::string& filePath) {
std::shared_ptr<FontFamily> buildFontFamily(const std::string& filePath, const std::string& lang,
bool isCustomFallback) {
auto font = std::make_shared<FreeTypeMinikinFontForTest>(getTestFontPath(filePath));
- std::vector<std::shared_ptr<Font>> fonts;
+ std::vector<Font> fonts;
fonts.push_back(Font::Builder(font).build());
return std::make_shared<FontFamily>(LocaleListCache::getId(lang), FamilyVariant::DEFAULT,
std::move(fonts), isCustomFallback);
diff --git a/tests/util/FreeTypeMinikinFontForTest.cpp b/tests/util/FreeTypeMinikinFontForTest.cpp
index 1be466a..1ea0631 100644
--- a/tests/util/FreeTypeMinikinFontForTest.cpp
+++ b/tests/util/FreeTypeMinikinFontForTest.cpp
@@ -37,6 +37,8 @@
namespace minikin {
namespace {
+static int uniqueId = 0;
+
constexpr FT_Int32 LOAD_FLAG =
FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
@@ -60,7 +62,7 @@ void loadGlyphOrDie(uint32_t glyphId, float size, FT_Face face) {
} // namespace
FreeTypeMinikinFontForTest::FreeTypeMinikinFontForTest(const std::string& font_path, int index)
- : mFontPath(font_path), mFontIndex(index) {
+ : MinikinFont(uniqueId++), mFontPath(font_path), mFontIndex(index) {
int fd = open(font_path.c_str(), O_RDONLY);
LOG_ALWAYS_FATAL_IF(fd == -1, "Open failed: %s", font_path.c_str());
struct stat st = {};
@@ -112,18 +114,4 @@ void FreeTypeMinikinFontForTest::GetFontExtent(MinikinExtent* extent, const Mini
extent->descent = -static_cast<float>(mFtFace->descender) * paint.size / upem;
}
-void writeFreeTypeMinikinFontForTest(BufferWriter* writer, const MinikinFont* typeface) {
- writer->writeString(typeface->GetFontPath());
-}
-
-std::shared_ptr<MinikinFont> loadFreeTypeMinikinFontForTest(BufferReader reader) {
- std::string fontPath(reader.readString());
- return std::make_shared<FreeTypeMinikinFontForTest>(fontPath);
-}
-
-Font::TypefaceLoader* readFreeTypeMinikinFontForTest(BufferReader* reader) {
- reader->skipString(); // fontPath
- return &loadFreeTypeMinikinFontForTest;
-}
-
} // namespace minikin
diff --git a/tests/util/FreeTypeMinikinFontForTest.h b/tests/util/FreeTypeMinikinFontForTest.h
index 4cdb6d8..4b6ea05 100644
--- a/tests/util/FreeTypeMinikinFontForTest.h
+++ b/tests/util/FreeTypeMinikinFontForTest.h
@@ -19,8 +19,6 @@
#include <string>
-#include "minikin/Buffer.h"
-#include "minikin/Font.h"
#include "minikin/MinikinFont.h"
#include <ft2build.h>
@@ -45,7 +43,8 @@ public:
void GetFontExtent(MinikinExtent* extent, const MinikinPaint& paint,
const FontFakery& fakery) const override;
- const std::string& GetFontPath() const override { return mFontPath; }
+ const std::string& fontPath() const { return mFontPath; }
+
const void* GetFontData() const { return mFontData; }
size_t GetFontSize() const { return mFontSize; }
int GetFontIndex() const { return mFontIndex; }
@@ -64,10 +63,6 @@ private:
MINIKIN_PREVENT_COPY_AND_ASSIGN(FreeTypeMinikinFontForTest);
};
-void writeFreeTypeMinikinFontForTest(BufferWriter* writer, const MinikinFont* typeface);
-
-Font::TypefaceLoader* readFreeTypeMinikinFontForTest(BufferReader* reader);
-
} // namespace minikin
#endif // MINIKIN_TEST_FREE_TYPE_MINIKIN_FONT_FOR_TEST_H