Hal Canary | fd24b1f | 2019-05-02 17:00:22 -0400 | [diff] [blame] | 1 | // Copyright 2019 Google LLC. |
| 2 | // Use of this source code is governed by a BSD-style license that can be found in the LICENSE file. |
| 3 | |
| 4 | #include "tests/Test.h" |
| 5 | |
Hal Canary | 70aab82 | 2019-05-03 13:18:44 -0400 | [diff] [blame] | 6 | #if !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && !defined(SK_BUILD_FOR_GOOGLE3) |
Hal Canary | fd24b1f | 2019-05-02 17:00:22 -0400 | [diff] [blame] | 7 | |
Ben Wagner | e8db325 | 2019-05-29 18:54:26 -0400 | [diff] [blame] | 8 | #include "include/core/SkData.h" |
| 9 | #include "include/core/SkFont.h" |
| 10 | #include "include/core/SkPoint.h" |
| 11 | #include "include/core/SkRefCnt.h" |
| 12 | #include "include/core/SkTypeface.h" |
| 13 | #include "include/core/SkTypes.h" |
| 14 | #include "include/private/SkTo.h" |
Hal Canary | fd24b1f | 2019-05-02 17:00:22 -0400 | [diff] [blame] | 15 | #include "modules/skshaper/include/SkShaper.h" |
| 16 | #include "tools/Resources.h" |
| 17 | |
Ben Wagner | e8db325 | 2019-05-29 18:54:26 -0400 | [diff] [blame] | 18 | #include <cstdint> |
| 19 | #include <memory> |
| 20 | |
Hal Canary | fd24b1f | 2019-05-02 17:00:22 -0400 | [diff] [blame] | 21 | namespace { |
| 22 | struct RunHandler final : public SkShaper::RunHandler { |
| 23 | const char* fResource; |
| 24 | skiatest::Reporter* fReporter; |
| 25 | std::unique_ptr<SkGlyphID[]> fGlyphs; |
| 26 | std::unique_ptr<SkPoint[]> fPositions; |
| 27 | std::unique_ptr<uint32_t[]> fClusters; |
| 28 | SkShaper::RunHandler::Range fRange; |
| 29 | unsigned fGlyphCount = 0; |
| 30 | |
| 31 | RunHandler(const char* resource, skiatest::Reporter* reporter) |
| 32 | : fResource(resource), fReporter(reporter) {} |
| 33 | |
| 34 | void beginLine() override {} |
| 35 | void runInfo(const SkShaper::RunHandler::RunInfo& info) override {} |
| 36 | void commitRunInfo() override {} |
| 37 | SkShaper::RunHandler::Buffer runBuffer(const SkShaper::RunHandler::RunInfo& info) override { |
| 38 | fGlyphCount = SkToUInt(info.glyphCount); |
| 39 | fRange = info.utf8Range; |
John Stiles | fbd050b | 2020-08-03 13:21:46 -0400 | [diff] [blame] | 40 | fGlyphs = std::make_unique<SkGlyphID[]>(info.glyphCount); |
| 41 | fPositions = std::make_unique<SkPoint[]>(info.glyphCount); |
| 42 | fClusters = std::make_unique<uint32_t[]>(info.glyphCount); |
Hal Canary | fd24b1f | 2019-05-02 17:00:22 -0400 | [diff] [blame] | 43 | return SkShaper::RunHandler::Buffer{fGlyphs.get(), |
| 44 | fPositions.get(), |
| 45 | nullptr, |
| 46 | fClusters.get(), |
| 47 | {0, 0}}; |
| 48 | } |
| 49 | void commitRunBuffer(const RunInfo& info) override { |
| 50 | REPORTER_ASSERT(fReporter, fGlyphCount == info.glyphCount, "%s", fResource); |
| 51 | REPORTER_ASSERT(fReporter, fRange.begin() == info.utf8Range.begin(), "%s", fResource); |
| 52 | REPORTER_ASSERT(fReporter, fRange.size() == info.utf8Range.size(), "%s", fResource); |
| 53 | for (unsigned i = 0; i < fGlyphCount; ++i) { |
| 54 | REPORTER_ASSERT(fReporter, fClusters[i] >= fRange.begin(), |
| 55 | "%s %u %u", fResource, i, fGlyphCount); |
| 56 | REPORTER_ASSERT(fReporter, fClusters[i] < fRange.end(), |
| 57 | "%s %u %u", fResource, i, fGlyphCount); |
| 58 | } |
| 59 | } |
| 60 | void commitLine() override {} |
| 61 | }; |
Hal Canary | fd24b1f | 2019-05-02 17:00:22 -0400 | [diff] [blame] | 62 | |
Ben Wagner | da53dd5 | 2019-11-05 17:29:16 -0500 | [diff] [blame] | 63 | void shaper_test(skiatest::Reporter* reporter, const char* name, SkData* data) { |
Ben Wagner | e8db325 | 2019-05-29 18:54:26 -0400 | [diff] [blame] | 64 | auto shaper = SkShaper::Make(); |
| 65 | if (!shaper) { |
| 66 | ERRORF(reporter, "Could not create shaper."); |
| 67 | return; |
Hal Canary | fd24b1f | 2019-05-02 17:00:22 -0400 | [diff] [blame] | 68 | } |
Ben Wagner | e8db325 | 2019-05-29 18:54:26 -0400 | [diff] [blame] | 69 | |
Ben Wagner | e8db325 | 2019-05-29 18:54:26 -0400 | [diff] [blame] | 70 | constexpr float kWidth = 400; |
| 71 | SkFont font(SkTypeface::MakeDefault()); |
Ben Wagner | da53dd5 | 2019-11-05 17:29:16 -0500 | [diff] [blame] | 72 | RunHandler rh(name, reporter); |
Ben Wagner | e8db325 | 2019-05-29 18:54:26 -0400 | [diff] [blame] | 73 | shaper->shape((const char*)data->data(), data->size(), font, true, kWidth, &rh); |
| 74 | |
| 75 | constexpr SkFourByteTag latn = SkSetFourByteTag('l','a','t','n'); |
| 76 | auto fontIterator = SkShaper::TrivialFontRunIterator(font, data->size()); |
| 77 | auto bidiIterator = SkShaper::TrivialBiDiRunIterator(0, data->size()); |
| 78 | auto scriptIterator = SkShaper::TrivialScriptRunIterator(latn, data->size()); |
| 79 | auto languageIterator = SkShaper::TrivialLanguageRunIterator("en-US", data->size()); |
| 80 | shaper->shape((const char*)data->data(), data->size(), |
| 81 | fontIterator, bidiIterator, scriptIterator, languageIterator, kWidth, &rh); |
Hal Canary | fd24b1f | 2019-05-02 17:00:22 -0400 | [diff] [blame] | 82 | } |
| 83 | |
Ben Wagner | da53dd5 | 2019-11-05 17:29:16 -0500 | [diff] [blame] | 84 | void cluster_test(skiatest::Reporter* reporter, const char* resource) { |
| 85 | auto data = GetResourceAsData(resource); |
| 86 | if (!data) { |
| 87 | ERRORF(reporter, "Could not get resource %s.", resource); |
| 88 | return; |
| 89 | } |
| 90 | |
| 91 | shaper_test(reporter, resource, data.get()); |
| 92 | } |
| 93 | |
| 94 | } // namespace |
| 95 | |
| 96 | DEF_TEST(Shaper_cluster_empty, r) { shaper_test(r, "empty", SkData::MakeEmpty().get()); } |
| 97 | |
Hal Canary | 56947a7 | 2019-05-03 09:49:27 -0400 | [diff] [blame] | 98 | #define SHAPER_TEST(X) DEF_TEST(Shaper_cluster_ ## X, r) { cluster_test(r, "text/" #X ".txt"); } |
| 99 | SHAPER_TEST(arabic) |
| 100 | SHAPER_TEST(armenian) |
| 101 | SHAPER_TEST(balinese) |
| 102 | SHAPER_TEST(buginese) |
| 103 | SHAPER_TEST(cherokee) |
| 104 | SHAPER_TEST(cyrillic) |
| 105 | SHAPER_TEST(emoji) |
| 106 | SHAPER_TEST(english) |
| 107 | SHAPER_TEST(ethiopic) |
| 108 | SHAPER_TEST(greek) |
| 109 | SHAPER_TEST(hangul) |
| 110 | SHAPER_TEST(han_simplified) |
| 111 | SHAPER_TEST(han_traditional) |
| 112 | SHAPER_TEST(hebrew) |
| 113 | SHAPER_TEST(javanese) |
| 114 | SHAPER_TEST(kana) |
| 115 | SHAPER_TEST(lao) |
| 116 | SHAPER_TEST(mandaic) |
| 117 | SHAPER_TEST(newtailue) |
| 118 | SHAPER_TEST(nko) |
| 119 | SHAPER_TEST(sinhala) |
| 120 | SHAPER_TEST(sundanese) |
| 121 | SHAPER_TEST(syriac) |
| 122 | SHAPER_TEST(thaana) |
| 123 | SHAPER_TEST(thai) |
| 124 | SHAPER_TEST(tibetan) |
| 125 | SHAPER_TEST(tifnagh) |
| 126 | SHAPER_TEST(vai) |
Hal Canary | fd24b1f | 2019-05-02 17:00:22 -0400 | [diff] [blame] | 127 | |
| 128 | // TODO(bungeman): fix these broken tests. (https://bugs.skia.org/9050) |
Hal Canary | 56947a7 | 2019-05-03 09:49:27 -0400 | [diff] [blame] | 129 | //SHAPER_TEST(bengali) |
| 130 | //SHAPER_TEST(devanagari) |
| 131 | //SHAPER_TEST(khmer) |
| 132 | //SHAPER_TEST(myanmar) |
| 133 | //SHAPER_TEST(taitham) |
| 134 | //SHAPER_TEST(tamil) |
| 135 | #undef SHAPER_TEST |
Hal Canary | fd24b1f | 2019-05-02 17:00:22 -0400 | [diff] [blame] | 136 | |
Hal Canary | 70aab82 | 2019-05-03 13:18:44 -0400 | [diff] [blame] | 137 | #endif // !defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) && !defined(SK_BUILD_FOR_GOOGLE3) |