/* * Copyright 2019 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "include/core/SkFont.h" #include "include/utils/SkCustomTypeface.h" #include "src/core/SkAutoMalloc.h" #include "src/core/SkFontPriv.h" #include "src/core/SkPtrRecorder.h" #include "src/core/SkReadBuffer.h" #include "src/core/SkWriteBuffer.h" #include "tests/Test.h" #include "tools/ToolUtils.h" static SkFont serialize_deserialize(const SkFont& font, skiatest::Reporter* reporter) { sk_sp typefaces = sk_make_sp(); SkBinaryWriteBuffer wb; wb.setTypefaceRecorder(typefaces); SkFontPriv::Flatten(font, wb); size_t size = wb.bytesWritten(); SkAutoMalloc storage(size); wb.writeToMemory(storage.get()); int count = typefaces->count(); SkASSERT((!font.getTypeface() && count == 0) || ( font.getTypeface() && count == 1)); if (count) { SkTypeface* typeface; typefaces->copyToArray((SkRefCnt**)&typeface); SkASSERT(typeface == font.getTypeface()); } SkReadBuffer rb(storage.get(), size); sk_sp cloneTypeface = font.refTypeface(); if (count) { rb.setTypefaceArray(&cloneTypeface, 1); } SkFont clone; REPORTER_ASSERT(reporter, SkFontPriv::Unflatten(&clone, rb)); return clone; } enum { kForceAutoHinting = 1 << 0, kEmbeddedBitmaps = 1 << 1, kSubpixel = 1 << 2, kLinearMetrics = 1 << 3, kEmbolden = 1 << 4, kBaselineSnap = 1 << 5, kAllBits = 0x3F, }; static void apply_flags(SkFont* font, unsigned flags) { font->setForceAutoHinting(SkToBool(flags & kForceAutoHinting)); font->setEmbeddedBitmaps( SkToBool(flags & kEmbeddedBitmaps)); font->setSubpixel( SkToBool(flags & kSubpixel)); font->setLinearMetrics( SkToBool(flags & kLinearMetrics)); font->setEmbolden( SkToBool(flags & kEmbolden)); font->setBaselineSnap( SkToBool(flags & kBaselineSnap)); } DEF_TEST(Font_flatten, reporter) { const float sizes[] = {0, 0.001f, 1, 10, 10.001f, 100000.01f}; const float scales[] = {-5, 0, 1, 5}; const float skews[] = {-5, 0, 5}; const SkFont::Edging edges[] = { SkFont::Edging::kAlias, SkFont::Edging::kSubpixelAntiAlias }; const SkFontHinting hints[] = { SkFontHinting::kNone, SkFontHinting::kFull }; const unsigned int flags[] = { kForceAutoHinting, kEmbeddedBitmaps, kSubpixel, kLinearMetrics, kEmbolden, kBaselineSnap, kAllBits, }; const sk_sp typefaces[] = { nullptr, ToolUtils::sample_user_typeface() }; SkFont font; for (float size : sizes) { font.setSize(size); for (float scale : scales) { font.setScaleX(scale); for (float skew : skews) { font.setSkewX(skew); for (auto edge : edges) { font.setEdging(edge); for (auto hint : hints) { font.setHinting(hint); for (auto flag : flags) { apply_flags(&font, flag); for (const sk_sp& typeface : typefaces) { font.setTypeface(typeface); SkFont clone = serialize_deserialize(font, reporter); REPORTER_ASSERT(reporter, font == clone); } } } } } } } }