11f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com/* 21f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com * Copyright 2013 Google Inc. 31f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com * 41f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com * Use of this source code is governed by a BSD-style license that can be 51f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com * found in the LICENSE file. 61f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com */ 71f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com 8209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary#include "SkAdvancedTypefaceMetrics.h" 96e45bda29edef867468cbdd7c062d0d99e884656bungeman#include "SkData.h" 10fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner#include "SkFixed.h" 11fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner#include "SkFontMgr.h" 12fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner#include "SkMakeUnique.h" 136e45bda29edef867468cbdd7c062d0d99e884656bungeman#include "SkOTTable_OS_2.h" 146e45bda29edef867468cbdd7c062d0d99e884656bungeman#include "SkSFNTHeader.h" 156e45bda29edef867468cbdd7c062d0d99e884656bungeman#include "SkStream.h" 1682a455f0e9a7a50a399a58be906b48c24aeec056bungeman#include "SkRefCnt.h" 171f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com#include "SkTypeface.h" 1882a455f0e9a7a50a399a58be906b48c24aeec056bungeman#include "SkTypefaceCache.h" 196e45bda29edef867468cbdd7c062d0d99e884656bungeman#include "Resources.h" 208f6884aab8aecd7657cf3f9cdbc682f0deca29c5tfarina@chromium.org#include "Test.h" 211f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com 226e45bda29edef867468cbdd7c062d0d99e884656bungeman#include <memory> 236e45bda29edef867468cbdd7c062d0d99e884656bungeman 246e45bda29edef867468cbdd7c062d0d99e884656bungemanstatic void TypefaceStyle_test(skiatest::Reporter* reporter, 256e45bda29edef867468cbdd7c062d0d99e884656bungeman uint16_t weight, uint16_t width, SkData* data) 266e45bda29edef867468cbdd7c062d0d99e884656bungeman{ 276e45bda29edef867468cbdd7c062d0d99e884656bungeman sk_sp<SkData> dataCopy; 2842943c8aa9c611c18ad0f1a30a27669f3d82239creed if (!data->unique()) { 296e45bda29edef867468cbdd7c062d0d99e884656bungeman dataCopy = SkData::MakeWithCopy(data->data(), data->size()); 3042943c8aa9c611c18ad0f1a30a27669f3d82239creed data = dataCopy.get(); 316e45bda29edef867468cbdd7c062d0d99e884656bungeman } 3242943c8aa9c611c18ad0f1a30a27669f3d82239creed SkSFNTHeader* sfntHeader = static_cast<SkSFNTHeader*>(data->writable_data()); 336e45bda29edef867468cbdd7c062d0d99e884656bungeman 346e45bda29edef867468cbdd7c062d0d99e884656bungeman SkSFNTHeader::TableDirectoryEntry* tableEntry = 356e45bda29edef867468cbdd7c062d0d99e884656bungeman SkTAfter<SkSFNTHeader::TableDirectoryEntry>(sfntHeader); 366e45bda29edef867468cbdd7c062d0d99e884656bungeman SkSFNTHeader::TableDirectoryEntry* os2TableEntry = nullptr; 376e45bda29edef867468cbdd7c062d0d99e884656bungeman int numTables = SkEndian_SwapBE16(sfntHeader->numTables); 386e45bda29edef867468cbdd7c062d0d99e884656bungeman for (int tableEntryIndex = 0; tableEntryIndex < numTables; ++tableEntryIndex) { 396e45bda29edef867468cbdd7c062d0d99e884656bungeman if (SkOTTableOS2::TAG == tableEntry[tableEntryIndex].tag) { 406e45bda29edef867468cbdd7c062d0d99e884656bungeman os2TableEntry = tableEntry + tableEntryIndex; 416e45bda29edef867468cbdd7c062d0d99e884656bungeman break; 426e45bda29edef867468cbdd7c062d0d99e884656bungeman } 436e45bda29edef867468cbdd7c062d0d99e884656bungeman } 446e45bda29edef867468cbdd7c062d0d99e884656bungeman SkASSERT_RELEASE(os2TableEntry); 456e45bda29edef867468cbdd7c062d0d99e884656bungeman 466e45bda29edef867468cbdd7c062d0d99e884656bungeman size_t os2TableOffset = SkEndian_SwapBE32(os2TableEntry->offset); 476e45bda29edef867468cbdd7c062d0d99e884656bungeman SkOTTableOS2_V0* os2Table = SkTAddOffset<SkOTTableOS2_V0>(sfntHeader, os2TableOffset); 486e45bda29edef867468cbdd7c062d0d99e884656bungeman os2Table->usWeightClass.value = SkEndian_SwapBE16(weight); 496e45bda29edef867468cbdd7c062d0d99e884656bungeman using WidthType = SkOTTableOS2_V0::WidthClass::Value; 506e45bda29edef867468cbdd7c062d0d99e884656bungeman os2Table->usWidthClass.value = static_cast<WidthType>(SkEndian_SwapBE16(width)); 516e45bda29edef867468cbdd7c062d0d99e884656bungeman 5242943c8aa9c611c18ad0f1a30a27669f3d82239creed sk_sp<SkTypeface> newTypeface(SkTypeface::MakeFromStream(new SkMemoryStream(sk_ref_sp(data)))); 53cb6940bf42e39271afe0fb3c2bfdd9e28d12f504Mike Klein if (!newTypeface) { 54cb6940bf42e39271afe0fb3c2bfdd9e28d12f504Mike Klein // Not all SkFontMgr can MakeFromStream(). 55cb6940bf42e39271afe0fb3c2bfdd9e28d12f504Mike Klein return; 56cb6940bf42e39271afe0fb3c2bfdd9e28d12f504Mike Klein } 576e45bda29edef867468cbdd7c062d0d99e884656bungeman 586e45bda29edef867468cbdd7c062d0d99e884656bungeman SkFontStyle newStyle = newTypeface->fontStyle(); 596e45bda29edef867468cbdd7c062d0d99e884656bungeman 606e45bda29edef867468cbdd7c062d0d99e884656bungeman //printf("%d, %f\n", weight, (newStyle.weight() - (float)0x7FFF) / (float)0x7FFF); 616e45bda29edef867468cbdd7c062d0d99e884656bungeman //printf("%d, %f\n", width , (newStyle.width() - (float)0x7F) / (float)0x7F); 626e45bda29edef867468cbdd7c062d0d99e884656bungeman //printf("%d, %d\n", weight, newStyle.weight()); 636e45bda29edef867468cbdd7c062d0d99e884656bungeman //printf("%d, %d\n", width , newStyle.width()); 646e45bda29edef867468cbdd7c062d0d99e884656bungeman 656e45bda29edef867468cbdd7c062d0d99e884656bungeman // Some back-ends (CG, GDI, DW) support OS/2 version A which uses 0 - 10 (but all differently). 666e45bda29edef867468cbdd7c062d0d99e884656bungeman REPORTER_ASSERT(reporter, 676e45bda29edef867468cbdd7c062d0d99e884656bungeman newStyle.weight() == weight || 686e45bda29edef867468cbdd7c062d0d99e884656bungeman (weight <= 10 && newStyle.weight() == 100 * weight) || 696e45bda29edef867468cbdd7c062d0d99e884656bungeman (weight == 4 && newStyle.weight() == 350) || // GDI weirdness 706e45bda29edef867468cbdd7c062d0d99e884656bungeman (weight == 5 && newStyle.weight() == 400) || // GDI weirdness 716e45bda29edef867468cbdd7c062d0d99e884656bungeman (weight == 0 && newStyle.weight() == 1) || // DW weirdness 726e45bda29edef867468cbdd7c062d0d99e884656bungeman (weight == 1000 && newStyle.weight() == 999) // DW weirdness 736e45bda29edef867468cbdd7c062d0d99e884656bungeman ); 746e45bda29edef867468cbdd7c062d0d99e884656bungeman 756e45bda29edef867468cbdd7c062d0d99e884656bungeman // Some back-ends (GDI) don't support width, ensure these always report 'medium'. 766e45bda29edef867468cbdd7c062d0d99e884656bungeman REPORTER_ASSERT(reporter, 776e45bda29edef867468cbdd7c062d0d99e884656bungeman newStyle.width() == width || 786e45bda29edef867468cbdd7c062d0d99e884656bungeman newStyle.width() == 5); 796e45bda29edef867468cbdd7c062d0d99e884656bungeman} 806e45bda29edef867468cbdd7c062d0d99e884656bungemanDEF_TEST(TypefaceStyle, reporter) { 8153e5e7d4ce9d203fadc36b6349bcbb68862f0d22Hal Canary std::unique_ptr<SkStreamAsset> stream(GetResourceAsStream("fonts/Em.ttf")); 826e45bda29edef867468cbdd7c062d0d99e884656bungeman if (!stream) { 8353e5e7d4ce9d203fadc36b6349bcbb68862f0d22Hal Canary REPORT_FAILURE(reporter, "fonts/Em.ttf", SkString("Cannot load resource")); 846e45bda29edef867468cbdd7c062d0d99e884656bungeman return; 856e45bda29edef867468cbdd7c062d0d99e884656bungeman } 866e45bda29edef867468cbdd7c062d0d99e884656bungeman sk_sp<SkData> data(SkData::MakeFromStream(stream.get(), stream->getLength())); 876e45bda29edef867468cbdd7c062d0d99e884656bungeman 886e45bda29edef867468cbdd7c062d0d99e884656bungeman using SkFS = SkFontStyle; 896e45bda29edef867468cbdd7c062d0d99e884656bungeman for (int weight = SkFS::kInvisible_Weight; weight <= SkFS::kExtraBlack_Weight; ++weight) { 906e45bda29edef867468cbdd7c062d0d99e884656bungeman TypefaceStyle_test(reporter, weight, 5, data.get()); 916e45bda29edef867468cbdd7c062d0d99e884656bungeman } 92d783e08004e2daace50dfcfebb66727b4c13794ebungeman for (int width = SkFS::kUltraCondensed_Width; width <= SkFS::kUltraExpanded_Width; ++width) { 936e45bda29edef867468cbdd7c062d0d99e884656bungeman TypefaceStyle_test(reporter, 400, width, data.get()); 946e45bda29edef867468cbdd7c062d0d99e884656bungeman } 956e45bda29edef867468cbdd7c062d0d99e884656bungeman} 966e45bda29edef867468cbdd7c062d0d99e884656bungeman 97fc497343cbcbd526f77da913ae2feca0e1b1b866Ben WagnerDEF_TEST(TypefaceAxes, reporter) { 9853e5e7d4ce9d203fadc36b6349bcbb68862f0d22Hal Canary std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("fonts/Distortable.ttf")); 99fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner if (!distortable) { 100fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner REPORT_FAILURE(reporter, "distortable", SkString()); 101fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner return; 102fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner } 1039aec8945f0e0cc88c33c2440f2163d36c7198bf6bungeman constexpr int numberOfAxesInDistortable = 1; 104fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner 105fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault(); 1069aec8945f0e0cc88c33c2440f2163d36c7198bf6bungeman // The position may be over specified. If there are multiple values for a given axis, 1079aec8945f0e0cc88c33c2440f2163d36c7198bf6bungeman // ensure the last one since that's what css-fonts-4 requires. 108fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner const SkFontArguments::VariationPosition::Coordinate position[] = { 1099aec8945f0e0cc88c33c2440f2163d36c7198bf6bungeman { SkSetFourByteTag('w','g','h','t'), 1.618033988749895f }, 1109aec8945f0e0cc88c33c2440f2163d36c7198bf6bungeman { SkSetFourByteTag('w','g','h','t'), SK_ScalarSqrt2 }, 111fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner }; 112fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner SkFontArguments params; 113fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner params.setVariationDesignPosition({position, SK_ARRAY_COUNT(position)}); 114fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner // TODO: if axes are set and the back-end doesn't support them, should we create the typeface? 115592273965a7fc7fc403252e420d15f6555b8f25dMike Reed sk_sp<SkTypeface> typeface = fm->makeFromStream(std::move(distortable), params); 116fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner 117cb6940bf42e39271afe0fb3c2bfdd9e28d12f504Mike Klein if (!typeface) { 118cb6940bf42e39271afe0fb3c2bfdd9e28d12f504Mike Klein // Not all SkFontMgr can makeFromStream(). 119cb6940bf42e39271afe0fb3c2bfdd9e28d12f504Mike Klein return; 120cb6940bf42e39271afe0fb3c2bfdd9e28d12f504Mike Klein } 121cb6940bf42e39271afe0fb3c2bfdd9e28d12f504Mike Klein 122fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner int count = typeface->getVariationDesignPosition(nullptr, 0); 123fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner if (count == -1) { 124fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner return; 125fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner } 1269aec8945f0e0cc88c33c2440f2163d36c7198bf6bungeman REPORTER_ASSERT(reporter, count == numberOfAxesInDistortable); 127fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner 1289aec8945f0e0cc88c33c2440f2163d36c7198bf6bungeman SkFontArguments::VariationPosition::Coordinate positionRead[numberOfAxesInDistortable]; 129fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner count = typeface->getVariationDesignPosition(positionRead, SK_ARRAY_COUNT(positionRead)); 1309aec8945f0e0cc88c33c2440f2163d36c7198bf6bungeman REPORTER_ASSERT(reporter, count == SK_ARRAY_COUNT(positionRead)); 131fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner 1329aec8945f0e0cc88c33c2440f2163d36c7198bf6bungeman REPORTER_ASSERT(reporter, positionRead[0].axis == position[1].axis); 133fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner 134fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner // Convert to fixed for "almost equal". 135fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner SkFixed fixedRead = SkScalarToFixed(positionRead[0].value); 1369aec8945f0e0cc88c33c2440f2163d36c7198bf6bungeman SkFixed fixedOriginal = SkScalarToFixed(position[1].value); 137fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner REPORTER_ASSERT(reporter, fixedRead == fixedOriginal); 138fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner} 139fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner 140fc497343cbcbd526f77da913ae2feca0e1b1b866Ben WagnerDEF_TEST(TypefaceVariationIndex, reporter) { 14153e5e7d4ce9d203fadc36b6349bcbb68862f0d22Hal Canary std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("fonts/Distortable.ttf")); 142fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner if (!distortable) { 143fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner REPORT_FAILURE(reporter, "distortable", SkString()); 144fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner return; 145fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner } 146fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner 147fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault(); 148fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner SkFontArguments params; 149fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner // The first named variation position in Distortable is 'Thin'. 150fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner params.setCollectionIndex(0x00010000); 151592273965a7fc7fc403252e420d15f6555b8f25dMike Reed sk_sp<SkTypeface> typeface = fm->makeFromStream(std::move(distortable), params); 152fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner if (!typeface) { 153fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner // FreeType is the only weird thing that supports this, Skia just needs to make sure if it 154fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner // gets one of these things make sense. 155fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner return; 156fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner } 157fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner 158fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner int count = typeface->getVariationDesignPosition(nullptr, 0); 159fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner if (!(count == 1)) { 160fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner REPORT_FAILURE(reporter, "count == 1", SkString()); 161fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner return; 162fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner } 163fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner 164fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner SkFontArguments::VariationPosition::Coordinate positionRead[1]; 165fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner count = typeface->getVariationDesignPosition(positionRead, SK_ARRAY_COUNT(positionRead)); 166fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner if (count == -1) { 167fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner return; 168fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner } 169fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner if (!(count == 1)) { 170fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner REPORT_FAILURE(reporter, "count == 1", SkString()); 171fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner return; 172fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner } 173fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner REPORTER_ASSERT(reporter, positionRead[0].axis == SkSetFourByteTag('w','g','h','t')); 174fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner REPORTER_ASSERT(reporter, positionRead[0].value == 0.5); 175fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner} 176fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner 177e4fafb146e85cdfcf9d5418597b6818aa0754adatfarina@chromium.orgDEF_TEST(Typeface, reporter) { 1781f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com 179ee6a9919a362e16c1d84a870ce867d1ad7b8a141mboc sk_sp<SkTypeface> t1(SkTypeface::MakeFromName(nullptr, SkFontStyle())); 18067ef5d76406d702e7afe4ec5b490a75d9bcaba10Ben Wagner sk_sp<SkTypeface> t2(SkTypeface::MakeDefault()); 1811f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com 1821f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com REPORTER_ASSERT(reporter, SkTypeface::Equal(t1.get(), t2.get())); 183a93a14a99816d25b773f0b12868143702baf44bfBen Wagner REPORTER_ASSERT(reporter, SkTypeface::Equal(nullptr, t1.get())); 184a93a14a99816d25b773f0b12868143702baf44bfBen Wagner REPORTER_ASSERT(reporter, SkTypeface::Equal(nullptr, t2.get())); 185a93a14a99816d25b773f0b12868143702baf44bfBen Wagner REPORTER_ASSERT(reporter, SkTypeface::Equal(t1.get(), nullptr)); 186a93a14a99816d25b773f0b12868143702baf44bfBen Wagner REPORTER_ASSERT(reporter, SkTypeface::Equal(t2.get(), nullptr)); 1871f584ed3f43037e85bae3019d48e793ae28ebbd5djsollen@google.com} 18882a455f0e9a7a50a399a58be906b48c24aeec056bungeman 189a821af83890d3b365c7b871f939737d47c48139cbungemannamespace { 190a821af83890d3b365c7b871f939737d47c48139cbungeman 19182a455f0e9a7a50a399a58be906b48c24aeec056bungemanclass SkEmptyTypeface : public SkTypeface { 19282a455f0e9a7a50a399a58be906b48c24aeec056bungemanpublic: 193e3aea10428d1597838fd563c92340beaf969a9b4bungeman static sk_sp<SkTypeface> Create() { return sk_sp<SkTypeface>(new SkEmptyTypeface()); } 19482a455f0e9a7a50a399a58be906b48c24aeec056bungemanprotected: 195e3aea10428d1597838fd563c92340beaf969a9b4bungeman SkEmptyTypeface() : SkTypeface(SkFontStyle(), true) { } 19682a455f0e9a7a50a399a58be906b48c24aeec056bungeman 19782a455f0e9a7a50a399a58be906b48c24aeec056bungeman SkStreamAsset* onOpenStream(int* ttcIndex) const override { return nullptr; } 19882a455f0e9a7a50a399a58be906b48c24aeec056bungeman SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&, 19982a455f0e9a7a50a399a58be906b48c24aeec056bungeman const SkDescriptor*) const override { 20082a455f0e9a7a50a399a58be906b48c24aeec056bungeman return nullptr; 20182a455f0e9a7a50a399a58be906b48c24aeec056bungeman } 20282a455f0e9a7a50a399a58be906b48c24aeec056bungeman void onFilterRec(SkScalerContextRec*) const override { } 203209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override { 204209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary return nullptr; 205209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary } 20682a455f0e9a7a50a399a58be906b48c24aeec056bungeman void onGetFontDescriptor(SkFontDescriptor*, bool*) const override { } 20782a455f0e9a7a50a399a58be906b48c24aeec056bungeman virtual int onCharsToGlyphs(const void* chars, Encoding encoding, 20882a455f0e9a7a50a399a58be906b48c24aeec056bungeman uint16_t glyphs[], int glyphCount) const override { 20982a455f0e9a7a50a399a58be906b48c24aeec056bungeman SK_ABORT("unimplemented"); 21082a455f0e9a7a50a399a58be906b48c24aeec056bungeman return 0; 21182a455f0e9a7a50a399a58be906b48c24aeec056bungeman } 212fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein int onCountGlyphs() const override { return 0; } 213fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein int onGetUPEM() const override { return 0; } 21482a455f0e9a7a50a399a58be906b48c24aeec056bungeman void onGetFamilyName(SkString* familyName) const override { familyName->reset(); } 21582a455f0e9a7a50a399a58be906b48c24aeec056bungeman SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override { 21682a455f0e9a7a50a399a58be906b48c24aeec056bungeman SK_ABORT("unimplemented"); 21782a455f0e9a7a50a399a58be906b48c24aeec056bungeman return nullptr; 218fc6c37b981daeece7474ce61070c707c37eefa62Mike Klein } 219fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], 220fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner int coordinateCount) const override 221fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner { 222fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner return 0; 223fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner } 22482a455f0e9a7a50a399a58be906b48c24aeec056bungeman int onGetTableTags(SkFontTableTag tags[]) const override { return 0; } 22582a455f0e9a7a50a399a58be906b48c24aeec056bungeman size_t onGetTableData(SkFontTableTag, size_t, size_t, void*) const override { return 0; } 22682a455f0e9a7a50a399a58be906b48c24aeec056bungeman}; 22782a455f0e9a7a50a399a58be906b48c24aeec056bungeman 228a821af83890d3b365c7b871f939737d47c48139cbungeman} 229a821af83890d3b365c7b871f939737d47c48139cbungeman 23082a455f0e9a7a50a399a58be906b48c24aeec056bungemanstatic bool count_proc(SkTypeface* face, void* ctx) { 23182a455f0e9a7a50a399a58be906b48c24aeec056bungeman int* count = static_cast<int*>(ctx); 23282a455f0e9a7a50a399a58be906b48c24aeec056bungeman *count = *count + 1; 23382a455f0e9a7a50a399a58be906b48c24aeec056bungeman return false; 23482a455f0e9a7a50a399a58be906b48c24aeec056bungeman} 23582a455f0e9a7a50a399a58be906b48c24aeec056bungemanstatic int count(skiatest::Reporter* reporter, const SkTypefaceCache& cache) { 23682a455f0e9a7a50a399a58be906b48c24aeec056bungeman int count = 0; 23782a455f0e9a7a50a399a58be906b48c24aeec056bungeman SkTypeface* none = cache.findByProcAndRef(count_proc, &count); 23882a455f0e9a7a50a399a58be906b48c24aeec056bungeman REPORTER_ASSERT(reporter, none == nullptr); 23982a455f0e9a7a50a399a58be906b48c24aeec056bungeman return count; 24082a455f0e9a7a50a399a58be906b48c24aeec056bungeman} 24182a455f0e9a7a50a399a58be906b48c24aeec056bungeman 24282a455f0e9a7a50a399a58be906b48c24aeec056bungemanDEF_TEST(TypefaceCache, reporter) { 243e3aea10428d1597838fd563c92340beaf969a9b4bungeman sk_sp<SkTypeface> t1(SkEmptyTypeface::Create()); 24482a455f0e9a7a50a399a58be906b48c24aeec056bungeman { 24582a455f0e9a7a50a399a58be906b48c24aeec056bungeman SkTypefaceCache cache; 24682a455f0e9a7a50a399a58be906b48c24aeec056bungeman REPORTER_ASSERT(reporter, count(reporter, cache) == 0); 24782a455f0e9a7a50a399a58be906b48c24aeec056bungeman { 248e3aea10428d1597838fd563c92340beaf969a9b4bungeman sk_sp<SkTypeface> t0(SkEmptyTypeface::Create()); 24982a455f0e9a7a50a399a58be906b48c24aeec056bungeman cache.add(t0.get()); 25082a455f0e9a7a50a399a58be906b48c24aeec056bungeman REPORTER_ASSERT(reporter, count(reporter, cache) == 1); 25182a455f0e9a7a50a399a58be906b48c24aeec056bungeman cache.add(t1.get()); 25282a455f0e9a7a50a399a58be906b48c24aeec056bungeman REPORTER_ASSERT(reporter, count(reporter, cache) == 2); 25382a455f0e9a7a50a399a58be906b48c24aeec056bungeman cache.purgeAll(); 25482a455f0e9a7a50a399a58be906b48c24aeec056bungeman REPORTER_ASSERT(reporter, count(reporter, cache) == 2); 25582a455f0e9a7a50a399a58be906b48c24aeec056bungeman } 25682a455f0e9a7a50a399a58be906b48c24aeec056bungeman REPORTER_ASSERT(reporter, count(reporter, cache) == 2); 25782a455f0e9a7a50a399a58be906b48c24aeec056bungeman cache.purgeAll(); 25882a455f0e9a7a50a399a58be906b48c24aeec056bungeman REPORTER_ASSERT(reporter, count(reporter, cache) == 1); 25982a455f0e9a7a50a399a58be906b48c24aeec056bungeman } 26082a455f0e9a7a50a399a58be906b48c24aeec056bungeman REPORTER_ASSERT(reporter, t1->unique()); 26182a455f0e9a7a50a399a58be906b48c24aeec056bungeman} 262