aboutsummaryrefslogtreecommitdiffhomepage
path: root/tests
diff options
context:
space:
mode:
authorGravatar bungeman <bungeman@google.com>2016-07-25 15:11:49 -0700
committerGravatar Commit bot <commit-bot@chromium.org>2016-07-25 15:11:49 -0700
commit6e45bda29edef867468cbdd7c062d0d99e884656 (patch)
tree7902ff9ad3fdcb1c9417eaafdca60a4caae5a8b0 /tests
parent4e90e3eb5e43ffa8f347570578f5a538793b0cc7 (diff)
Add test for typeface style round trip.
This also fixes the CG and GDI ports so they pass the test. GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2171163002 Review-Url: https://codereview.chromium.org/2171163002
Diffstat (limited to 'tests')
-rw-r--r--tests/TypefaceTest.cpp78
1 files changed, 78 insertions, 0 deletions
diff --git a/tests/TypefaceTest.cpp b/tests/TypefaceTest.cpp
index 4c65fa3f9d..33fa887f52 100644
--- a/tests/TypefaceTest.cpp
+++ b/tests/TypefaceTest.cpp
@@ -5,11 +5,89 @@
* found in the LICENSE file.
*/
+#include "SkData.h"
+#include "SkOTTable_OS_2.h"
+#include "SkSFNTHeader.h"
+#include "SkStream.h"
#include "SkRefCnt.h"
#include "SkTypeface.h"
#include "SkTypefaceCache.h"
+#include "Resources.h"
#include "Test.h"
+#include <memory>
+
+static void TypefaceStyle_test(skiatest::Reporter* reporter,
+ uint16_t weight, uint16_t width, SkData* data)
+{
+ sk_sp<SkData> dataCopy;
+ SkData* dataToUse = data;
+ if (!dataToUse->unique()) {
+ dataCopy = SkData::MakeWithCopy(data->data(), data->size());
+ dataToUse = dataCopy.get();
+ }
+ SkSFNTHeader* sfntHeader = static_cast<SkSFNTHeader*>(dataToUse->writable_data());
+
+ SkSFNTHeader::TableDirectoryEntry* tableEntry =
+ SkTAfter<SkSFNTHeader::TableDirectoryEntry>(sfntHeader);
+ SkSFNTHeader::TableDirectoryEntry* os2TableEntry = nullptr;
+ int numTables = SkEndian_SwapBE16(sfntHeader->numTables);
+ for (int tableEntryIndex = 0; tableEntryIndex < numTables; ++tableEntryIndex) {
+ if (SkOTTableOS2::TAG == tableEntry[tableEntryIndex].tag) {
+ os2TableEntry = tableEntry + tableEntryIndex;
+ break;
+ }
+ }
+ SkASSERT_RELEASE(os2TableEntry);
+
+ size_t os2TableOffset = SkEndian_SwapBE32(os2TableEntry->offset);
+ SkOTTableOS2_V0* os2Table = SkTAddOffset<SkOTTableOS2_V0>(sfntHeader, os2TableOffset);
+ os2Table->usWeightClass.value = SkEndian_SwapBE16(weight);
+ using WidthType = SkOTTableOS2_V0::WidthClass::Value;
+ os2Table->usWidthClass.value = static_cast<WidthType>(SkEndian_SwapBE16(width));
+
+ sk_sp<SkTypeface> newTypeface(SkTypeface::MakeFromStream(new SkMemoryStream(dataToUse)));
+ SkASSERT_RELEASE(newTypeface);
+
+ SkFontStyle newStyle = newTypeface->fontStyle();
+
+ //printf("%d, %f\n", weight, (newStyle.weight() - (float)0x7FFF) / (float)0x7FFF);
+ //printf("%d, %f\n", width , (newStyle.width() - (float)0x7F) / (float)0x7F);
+ //printf("%d, %d\n", weight, newStyle.weight());
+ //printf("%d, %d\n", width , newStyle.width());
+
+ // Some back-ends (CG, GDI, DW) support OS/2 version A which uses 0 - 10 (but all differently).
+ REPORTER_ASSERT(reporter,
+ newStyle.weight() == weight ||
+ (weight <= 10 && newStyle.weight() == 100 * weight) ||
+ (weight == 4 && newStyle.weight() == 350) || // GDI weirdness
+ (weight == 5 && newStyle.weight() == 400) || // GDI weirdness
+ (weight == 0 && newStyle.weight() == 1) || // DW weirdness
+ (weight == 1000 && newStyle.weight() == 999) // DW weirdness
+ );
+
+ // Some back-ends (GDI) don't support width, ensure these always report 'medium'.
+ REPORTER_ASSERT(reporter,
+ newStyle.width() == width ||
+ newStyle.width() == 5);
+}
+DEF_TEST(TypefaceStyle, reporter) {
+ std::unique_ptr<SkStreamAsset> stream(GetResourceAsStream("/fonts/Em.ttf"));
+ if (!stream) {
+ REPORT_FAILURE(reporter, "/fonts/Em.ttf", SkString("Cannot load resource"));
+ return;
+ }
+ sk_sp<SkData> data(SkData::MakeFromStream(stream.get(), stream->getLength()));
+
+ using SkFS = SkFontStyle;
+ for (int weight = SkFS::kInvisible_Weight; weight <= SkFS::kExtraBlack_Weight; ++weight) {
+ TypefaceStyle_test(reporter, weight, 5, data.get());
+ }
+ for (int width = SkFS::kUltraCondensed_Width; width <= SkFS::kUltaExpanded_Width; ++width) {
+ TypefaceStyle_test(reporter, 400, width, data.get());
+ }
+}
+
DEF_TEST(Typeface, reporter) {
sk_sp<SkTypeface> t1(SkTypeface::MakeFromName(nullptr, SkFontStyle()));