Reland "Test mac system font variations."

This reverts commit 4c0b9b90d6.

Reason for revert: Work around broken -Wrange-loop-analysis

Original change's description:
> Revert "Test mac system font variations."
>
> This reverts commit a612dc77d7.
>
> Reason for revert: Breaking iOS builds.
>
> Original change's description:
> > Test mac system font variations.
> >
> > On macOS system fonts are special and sometimes have different behavior
> > from fonts generated from data. Add a test which exercises several
> > expectations about changing the variation on the system ui font.
> >
> > Bug: skia:10968
> > Change-Id: Ia10dfbf7f4f0ff099f9bfebf95481c95c7d3715f
> > Reviewed-on: https://skia-review.googlesource.com/c/skia/+/372218
> > Commit-Queue: Ben Wagner <bungeman@google.com>
> > Reviewed-by: Herb Derby <herb@google.com>
>
> TBR=bungeman@google.com,herb@google.com,drott@google.com
>
> Change-Id: Iccc05f25d827ab85c507b5f3bde936561349e2b8
> No-Presubmit: true
> No-Tree-Checks: true
> No-Try: true
> Bug: skia:10968
> Reviewed-on: https://skia-review.googlesource.com/c/skia/+/372678
> Reviewed-by: Jim Van Verth <jvanverth@google.com>
> Commit-Queue: Jim Van Verth <jvanverth@google.com>

# Not skipping CQ checks because this is a reland.

Bug: skia:10968
Change-Id: Ifddc6c5ada335d97f7796df7f6ea10577f6bc252
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/372776
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Ben Wagner <bungeman@google.com>
This commit is contained in:
Ben Wagner 2021-02-20 03:10:32 +00:00 committed by Skia Commit-Bot
parent 3830714320
commit ba55be671d
2 changed files with 185 additions and 0 deletions

View File

@ -492,6 +492,7 @@ optional("fontmgr_mac_ct") {
"src/ports/SkTypeface_mac_ct.cpp", "src/ports/SkTypeface_mac_ct.cpp",
"src/ports/SkTypeface_mac_ct.h", "src/ports/SkTypeface_mac_ct.h",
] ]
sources_for_tests = [ "tests/TypefaceMacTest.cpp" ]
if (is_mac) { if (is_mac) {
frameworks = [ frameworks = [
@ -1964,6 +1965,7 @@ if (skia_enable_tools) {
":flags", ":flags",
":fontmgr_android_tests", ":fontmgr_android_tests",
":fontmgr_fontconfig_tests", ":fontmgr_fontconfig_tests",
":fontmgr_mac_ct_tests",
":skia", ":skia",
":test", ":test",
":tool_utils", ":tool_utils",

183
tests/TypefaceMacTest.cpp Normal file
View File

@ -0,0 +1,183 @@
/*
* Copyright 2021 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/SkFontMgr.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkTypeface.h"
#include "include/ports/SkTypeface_mac.h"
#include "src/core/SkZip.h"
#include "tests/Test.h"
#include <stdarg.h>
#include <string>
#include <vector>
#if 0
static void SkMaybeDebugf(const char format[], ...) {
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
#else
static void SkMaybeDebugf(const char format[], ...) { }
#endif
DEF_TEST(TypefaceMacVariation, reporter) {
auto makeSystemFont = [](float size) -> CTFontRef {
// kCTFontUIFontSystem, kCTFontUIFontMessage
return CTFontCreateUIFontForLanguage(kCTFontUIFontSystem, size, nullptr);
};
auto tagToString = [](SkFourByteTag tag) -> std::string {
char buffer[5];
buffer[0] = (tag & 0xff000000) >> 24;
buffer[1] = (tag & 0xff0000) >> 16;
buffer[2] = (tag & 0xff00) >> 8;
buffer[3] = tag & 0xff;
buffer[4] = 0;
return std::string(buffer);
};
// This typeface has the issue.
sk_sp<SkTypeface> typeface(SkMakeTypefaceFromCTFont(makeSystemFont(30)));
// Since MakeFromFile creates at default size 12, these two are more comparable.
// The first one has the issue and the second does not.
//typeface = SkMakeTypefaceFromCTFont(makeSystemFont(12));
//typeface = SkTypeface::MakeFromFile("/System/Library/Fonts/SFNS.ttf");
// Setting the initila opsz <= min, the reported wght axis is strange, but draws the same?
//typeface = SkMakeTypefaceFromCTFont(makeSystemFont(17));
//typeface = SkMakeTypefaceFromCTFont(makeSystemFont(17.01));
// Setting the initial opsz >= max, the requested variation doesn't take effect?
//typeface = SkMakeTypefaceFromCTFont(makeSystemFont(95.9));
//typeface = SkMakeTypefaceFromCTFont(makeSystemFont(96));
if (!typeface) {
REPORTER_ASSERT(reporter, typeface);
return;
}
using Coordinate = SkFontArguments::VariationPosition::Coordinate;
using Axis = SkFontParameters::Variation::Axis;
const int originalPositionCount = typeface->getVariationDesignPosition(nullptr, 0);
std::vector<Coordinate> originalPosition(originalPositionCount);
const int retrievedOriginalPositionCount =
typeface->getVariationDesignPosition(originalPosition.data(), originalPosition.size());
if (!(retrievedOriginalPositionCount == originalPositionCount)) {
REPORTER_ASSERT(reporter, retrievedOriginalPositionCount == originalPositionCount);
return;
}
constexpr SkFourByteTag kGRADTag = SkSetFourByteTag('G', 'R', 'A', 'D');
constexpr SkFourByteTag kWghtTag = SkSetFourByteTag('w', 'g', 'h', 't');
constexpr SkFourByteTag kWdthTag = SkSetFourByteTag('w', 'd', 't', 'h');
constexpr SkFourByteTag kOpszTag = SkSetFourByteTag('o', 'p', 's', 'z');
SkMaybeDebugf("Original: ");
for (auto& originalCoordinate : originalPosition) {
SkMaybeDebugf("(%s: %f) ", tagToString(originalCoordinate.axis).c_str(),
originalCoordinate.value);
}
SkMaybeDebugf("\n\n");
const int originalAxisCount = typeface->getVariationDesignParameters(nullptr, 0);
std::vector<Axis> originalAxes(originalAxisCount);
const int returnedOriginalAxisCount =
typeface->getVariationDesignParameters(originalAxes.data(), originalAxes.size());
if (!(returnedOriginalAxisCount == originalAxisCount)) {
REPORTER_ASSERT(reporter, returnedOriginalAxisCount == originalAxisCount);
return;
}
for (bool omitOpsz : {false, true}) {
for (SkFourByteTag axisToBump : { 0u, kOpszTag, kWdthTag, kGRADTag }) {
for (float testCoordinate : {100, 300, 400, 500, 700, 900}) {
std::vector<Coordinate> expectedPosition;
std::vector<Coordinate> requestPosition;
SkMaybeDebugf("Request : ");
for (auto& originalCoordinate : originalPosition) {
float requestValue = originalCoordinate.value;
if (originalCoordinate.axis == kOpszTag && omitOpsz) {
SkMaybeDebugf("#%s: %f# ", tagToString(originalCoordinate.axis).c_str(),
requestValue);
} else {
if (originalCoordinate.axis == axisToBump) {
// CoreText floats for the variation coordinates have limited precision.
// 'opsz' sems to have more precision since it is set somewhat independently.
//requestValue = nextafter(requestValue, HUGE_VALF); // Does not work.
requestValue += requestValue / 1024.0f; // Expect at least 10 bits.
}
if (originalCoordinate.axis == kWghtTag) {
requestValue = testCoordinate;
}
SkMaybeDebugf("(%s: %f) ", tagToString(originalCoordinate.axis).c_str(),
requestValue);
requestPosition.push_back({originalCoordinate.axis, requestValue});
}
float expectedValue = requestValue;
for (auto& originalAxis : originalAxes) {
if (originalAxis.tag == originalCoordinate.axis) {
expectedValue = std::min(expectedValue, originalAxis.max);
expectedValue = std::max(expectedValue, originalAxis.min);
}
}
expectedPosition.push_back({originalCoordinate.axis, expectedValue});
}
SkMaybeDebugf("\n");
SkMaybeDebugf("Expected: ");
for (auto& expectedCoordinate : expectedPosition) {
SkMaybeDebugf("(%s: %f) ", tagToString(expectedCoordinate.axis).c_str(),
expectedCoordinate.value);
}
SkMaybeDebugf("\n");
SkFontArguments::VariationPosition variationPosition =
{ requestPosition.data(), (int)requestPosition.size() };
sk_sp<SkTypeface> cloneTypeface(
typeface->makeClone(SkFontArguments().setVariationDesignPosition(variationPosition)));
const int cloneAxisCount = cloneTypeface->getVariationDesignPosition(nullptr, 0);
std::vector<Coordinate> clonePosition(cloneAxisCount);
const int retrievedCloneAxisCount =
cloneTypeface->getVariationDesignPosition(clonePosition.data(), clonePosition.size());
if (!(retrievedCloneAxisCount == cloneAxisCount)) {
REPORTER_ASSERT(reporter, retrievedCloneAxisCount == cloneAxisCount);
continue;
}
SkMaybeDebugf("Result : ");
for (auto& cloneCoordinate : clonePosition) {
SkMaybeDebugf("(%s: %f) ", tagToString(cloneCoordinate.axis).c_str(),
cloneCoordinate.value);
}
SkMaybeDebugf("\n");
if (clonePosition.size() != expectedPosition.size()) {
REPORTER_ASSERT(reporter, clonePosition.size() == expectedPosition.size());
continue;
}
auto compareCoordinate = [](const Coordinate& a, const Coordinate& b) -> bool {
return a.axis < b.axis;
};
std::sort(clonePosition.begin(), clonePosition.end(), compareCoordinate);
std::sort(expectedPosition.begin(), expectedPosition.end(), compareCoordinate);
for (const auto&& [clone, expected] : SkMakeZip(clonePosition, expectedPosition)) {
REPORTER_ASSERT(reporter, clone.axis == expected.axis);
REPORTER_ASSERT(reporter, clone.value == expected.value);
}
SkMaybeDebugf("\n");
}
}
}
}