blob: 1a4287b8f84a7adfdb8e3c1f98cfc8a1b9902dda [file] [log] [blame]
/*
* Copyright 2023 Google LLC
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "include/core/SkEncodedImageFormat.h"
#include "include/core/SkSpan.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkTypeface.h"
#include "modules/skunicode/include/SkUnicode.h"
#include "tests/Test.h"
#include <vector>
using namespace skia_private;
#ifdef SK_UNICODE_CLIENT_IMPLEMENTATION
UNIX_ONLY_TEST(SkUnicode_Client, reporter) {
std::u16string text = u"\U000f2008";
auto utf8 = SkUnicode::convertUtf16ToUtf8(text.data(), text.size());
auto client = SkUnicode::MakeClientBasedUnicode
(SkSpan<char>(&utf8[0], utf8.size()), {}, {}, {});
skia_private::TArray<SkUnicode::CodeUnitFlags, true> results;
client->computeCodeUnitFlags(utf8.data(), utf8.size(), false, &results);
for (auto flag : results) {
REPORTER_ASSERT(reporter, !SkUnicode::isPartOfWhiteSpaceBreak(flag));
}
}
#endif
#ifdef SK_UNICODE_ICU_IMPLEMENTATION
UNIX_ONLY_TEST(SkUnicode_Native, reporter) {
std::u16string text = u"\U000f2008";
auto utf8 = SkUnicode::convertUtf16ToUtf8(text.data(), text.size());
auto icu = SkUnicode::Make();
skia_private::TArray<SkUnicode::CodeUnitFlags, true> results;
icu->computeCodeUnitFlags(utf8.data(), utf8.size(), false, &results);
for (auto flag : results) {
REPORTER_ASSERT(reporter, !SkUnicode::isPartOfWhiteSpaceBreak(flag));
}
}
#endif
UNIX_ONLY_TEST(SkUnicode_GetWords, reporter) {
SkString text("1 22 333 4444 55555 666666 7777777");
std::vector<SkUnicode::Position> expected = { 0, 1, 2, 4, 5, 8, 9, 13, 14, 19, 20, 26, 27, 34 };
auto icu = SkUnicode::Make();
std::vector<SkUnicode::Position> results;
auto result = icu->getWords(text.data(), text.size(), "en", &results);
REPORTER_ASSERT(reporter, result);
REPORTER_ASSERT(reporter, results.size() == expected.size());
for (auto i = 0ul; i < results.size(); ++i) {
REPORTER_ASSERT(reporter, results[i] == expected[i]);
}
}
UNIX_ONLY_TEST(SkUnicode_GetBidiRegionsLTR, reporter) {
SkString text("1 22 333 4444 55555 666666 7777777");
auto icu = SkUnicode::Make();
std::vector<SkUnicode::BidiRegion> results;
auto result = icu->getBidiRegions(text.data(),
text.size(),
SkUnicode::TextDirection::kLTR,
&results);
REPORTER_ASSERT(reporter, result);
REPORTER_ASSERT(reporter, results.size() == 1);
REPORTER_ASSERT(reporter, results[0].start == 0 &&
results[0].end == text.size() &&
results[0].level == 0);
}
UNIX_ONLY_TEST(SkUnicode_GetBidiRegionsRTL, reporter) {
SkString text("الهيمنة على العالم عبارة قبيحة ، أفضل أن أسميها تحسين العالم.");
auto icu = SkUnicode::Make();
std::vector<SkUnicode::BidiRegion> results;
auto result = icu->getBidiRegions(text.data(),
text.size(),
SkUnicode::TextDirection::kRTL,
&results);
REPORTER_ASSERT(reporter, result);
REPORTER_ASSERT(reporter, results.size() == 1);
REPORTER_ASSERT(reporter, results[0].start == 0 &&
results[0].end == text.size() &&
results[0].level == 1);
}
UNIX_ONLY_TEST(SkUnicode_GetBidiRegionsMix1, reporter) {
// Spaces become Arabic (RTL) but numbers remain English (LTR)
SkString text("1 22 333 4444 55555 666666 7777777");
std::vector<SkUnicode::BidiRegion> expected = {
{0, 1, 2},
{1, 2, 1},
{2, 4, 2},
{4, 5, 1},
{5, 8, 2},
{8, 9, 1},
{9, 13, 2},
{13, 14, 1},
{14, 19, 2},
{19, 20, 1},
{20, 26, 2},
{26, 27, 1},
{27, 34, 2},
};
auto icu = SkUnicode::Make();
std::vector<SkUnicode::BidiRegion> results;
auto result = icu->getBidiRegions(text.data(),
text.size(),
SkUnicode::TextDirection::kRTL,
&results);
REPORTER_ASSERT(reporter, result);
REPORTER_ASSERT(reporter, results.size() == expected.size());
for (auto i = 0ul; i < results.size(); ++i) {
REPORTER_ASSERT(reporter, results[i].start == expected[i].start &&
results[i].end == expected[i].end &&
results[i].level == expected[i].level);
}
}
UNIX_ONLY_TEST(SkUnicode_GetBidiRegionsMix2, reporter) {
// Few Russian/English words (ЛТР) in the mix
SkString text("World ЛТР Domination هي عبارة قبيحة ، أفضل أن أسميها World ЛТР Optimization.");
std::vector<SkUnicode::BidiRegion> expected = {
{ 0, 24, 0},
{ 24, 80, 1},
{ 80, 107, 0},
};
auto icu = SkUnicode::Make();
std::vector<SkUnicode::BidiRegion> results;
auto result = icu->getBidiRegions(text.data(),
text.size(),
SkUnicode::TextDirection::kLTR,
&results);
REPORTER_ASSERT(reporter, result);
REPORTER_ASSERT(reporter, results.size() == expected.size());
for (auto i = 0ul; i < results.size(); ++i) {
REPORTER_ASSERT(reporter, results[i].start == expected[i].start &&
results[i].end == expected[i].end &&
results[i].level == expected[i].level);
}
}
UNIX_ONLY_TEST(SkUnicode_ToUpper, reporter) {
SkString lower("abcdefghijklmnopqrstuvwxyz");
SkString upper("ABCDEFGHIJKLMNOPQRSTUVWXYZ");
auto icu = SkUnicode::Make();
auto icu_result1 = icu->toUpper(lower);
REPORTER_ASSERT(reporter, icu_result1.equals(upper));
auto icu_result2 = icu->toUpper(upper);
REPORTER_ASSERT(reporter, icu_result2.equals(upper));
}
UNIX_ONLY_TEST(SkUnicode_ComputeCodeUnitFlags, reporter) {
//SkString text("World domination is such an ugly phrase - I prefer to call it world optimisation");
SkString text("1\n22 333 4444 55555 666666 7777777");
// 4 8 13 19 24
auto icu = SkUnicode::Make();
TArray<SkUnicode::CodeUnitFlags> results;
auto result = icu->computeCodeUnitFlags(text.data(),
text.size(),
/*replaceTabs=*/true,
&results);
REPORTER_ASSERT(reporter, result);
REPORTER_ASSERT(reporter, results.size() == SkToS16(text.size() + 1));
for (auto i = 0; i < results.size(); ++i) {
auto flags = results[i];
auto expected = SkUnicode::CodeUnitFlags::kGraphemeStart;
if (i == 1) {
expected |= SkUnicode::CodeUnitFlags::kControl;
}
if (i == 2) {
expected |= SkUnicode::CodeUnitFlags::kHardLineBreakBefore;
}
if (i == 1 || i == 4 || i == 8 || i == 13 || i == 19 || i == 26) {
expected |= SkUnicode::CodeUnitFlags::kPartOfWhiteSpaceBreak;
expected |= SkUnicode::CodeUnitFlags::kPartOfIntraWordBreak;
}
if (i == 0 || i == 2 || i == 5 || i == 9 || i == 14 || i == 20
|| i == 27 || i == 34) {
expected |= SkUnicode::CodeUnitFlags::kSoftLineBreakBefore;
}
REPORTER_ASSERT(reporter, flags == expected);
}
}
UNIX_ONLY_TEST(SkUnicode_ReorderVisual, reporter) {
auto icu = SkUnicode::Make();
auto reorder = [&](std::vector<SkUnicode::BidiLevel> levels,
std::vector<int32_t> expected) {
std::vector<int32_t> logicalOrder(levels.size());
icu->reorderVisual(levels.data(), levels.size(), logicalOrder.data());
for (auto i = 0ul; i < levels.size(); ++i) {
REPORTER_ASSERT(reporter, expected[i] == logicalOrder[i]);
}
};
reorder({}, {});
reorder({0}, {0});
reorder({1}, {0});
reorder({0, 1, 0, 1}, {0, 1, 2, 3});
}