1c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita/* 2c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita * Copyright 2014 Google Inc. 3c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita * 4c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita * Use of this source code is governed by a BSD-style license that can be 5c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita * found in the LICENSE file. 6c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita */ 7c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 8c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita#include "SkPaint.h" 9c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita#include "SkPoint.h" 10337797580de42cdb722caab4bed121311ed7d0d2halcanary#include "SkTextBlobRunIterator.h" 1132d6b876163580711a07e96d9f29c9c1490a7271fmalita#include "SkTypeface.h" 12c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 13c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita#include "Test.h" 144bcef3c40ad8d3a16bbca4ab74fa15256fb4b125Mike Reed#include "sk_tool_utils.h" 15c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 16c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalitaclass TextBlobTester { 17c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalitapublic: 1851bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita // This unit test feeds an SkTextBlobBuilder various runs then checks to see if 1951bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita // the result contains the provided data and merges runs when appropriate. 2051bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita static void TestBuilder(skiatest::Reporter* reporter) { 21c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita SkTextBlobBuilder builder; 22c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 23c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita // empty run set 2496fcdcc219d2a0d3579719b84b28bede76efba64halcanary RunBuilderTest(reporter, builder, nullptr, 0, nullptr, 0); 25c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 2651bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunDef set1[] = { 27c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 100 }, 28c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita }; 2951bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunBuilderTest(reporter, builder, set1, SK_ARRAY_COUNT(set1), set1, SK_ARRAY_COUNT(set1)); 30c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 3151bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunDef set2[] = { 32c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kHorizontal_Positioning, 100, 100 }, 33c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita }; 3451bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunBuilderTest(reporter, builder, set2, SK_ARRAY_COUNT(set2), set2, SK_ARRAY_COUNT(set2)); 35c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 3651bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunDef set3[] = { 37c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kFull_Positioning, 100, 100 }, 38c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita }; 3951bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunBuilderTest(reporter, builder, set3, SK_ARRAY_COUNT(set3), set3, SK_ARRAY_COUNT(set3)); 40c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 4151bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunDef set4[] = { 42c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 150 }, 43c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 150 }, 44c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 150 }, 45c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita }; 4651bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunBuilderTest(reporter, builder, set4, SK_ARRAY_COUNT(set4), set4, SK_ARRAY_COUNT(set4)); 47c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 4851bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunDef set5[] = { 49c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kHorizontal_Positioning, 100, 150 }, 50c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kHorizontal_Positioning, 200, 150 }, 51c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kHorizontal_Positioning, 300, 250 }, 52c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita }; 5351bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunDef mergedSet5[] = { 54c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 256, SkTextBlob::kHorizontal_Positioning, 0, 150 }, 55c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kHorizontal_Positioning, 0, 250 }, 56c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita }; 5751bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunBuilderTest(reporter, builder, set5, SK_ARRAY_COUNT(set5), mergedSet5, 5851bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SK_ARRAY_COUNT(mergedSet5)); 59c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 6051bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunDef set6[] = { 61c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kFull_Positioning, 100, 100 }, 62c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kFull_Positioning, 200, 200 }, 63c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kFull_Positioning, 300, 300 }, 64c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita }; 6551bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunDef mergedSet6[] = { 66c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 384, SkTextBlob::kFull_Positioning, 0, 0 }, 67c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita }; 6851bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunBuilderTest(reporter, builder, set6, SK_ARRAY_COUNT(set6), mergedSet6, 6951bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SK_ARRAY_COUNT(mergedSet6)); 70c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 7151bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunDef set7[] = { 72c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 150 }, 73c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 150 }, 74c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kHorizontal_Positioning, 100, 150 }, 75c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kHorizontal_Positioning, 200, 150 }, 76c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kFull_Positioning, 400, 350 }, 77c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kFull_Positioning, 400, 350 }, 78c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 450 }, 79c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 450 }, 80c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kHorizontal_Positioning, 100, 550 }, 81c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kHorizontal_Positioning, 200, 650 }, 82c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kFull_Positioning, 400, 750 }, 83c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kFull_Positioning, 400, 850 }, 84c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita }; 8551bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunDef mergedSet7[] = { 86c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 150 }, 87c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 150 }, 88c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 256, SkTextBlob::kHorizontal_Positioning, 0, 150 }, 89c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 256, SkTextBlob::kFull_Positioning, 0, 0 }, 90c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 450 }, 91c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kDefault_Positioning, 100, 450 }, 92c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kHorizontal_Positioning, 0, 550 }, 93c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 128, SkTextBlob::kHorizontal_Positioning, 0, 650 }, 94c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita { 256, SkTextBlob::kFull_Positioning, 0, 0 }, 95c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita }; 9651bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita RunBuilderTest(reporter, builder, set7, SK_ARRAY_COUNT(set7), mergedSet7, 9751bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SK_ARRAY_COUNT(mergedSet7)); 9851bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita } 9951bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita 10051bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita // This unit test verifies blob bounds computation. 10151bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita static void TestBounds(skiatest::Reporter* reporter) { 10251bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SkTextBlobBuilder builder; 10351bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SkPaint font; 10451bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita font.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 10551bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita 10651bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita // Explicit bounds. 10751bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita { 10837283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> blob(builder.make()); 1093a9a7a310c5cff72bc1c2388a496af1b82326355Florin Malita REPORTER_ASSERT(reporter, !blob); 11051bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita } 11151bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita 11251bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita { 11351bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20); 11451bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita builder.allocRun(font, 16, 0, 0, &r1); 11537283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> blob(builder.make()); 11651bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita REPORTER_ASSERT(reporter, blob->bounds() == r1); 11751bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita } 11851bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita 11951bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita { 12051bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20); 12151bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita builder.allocRunPosH(font, 16, 0, &r1); 12237283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> blob(builder.make()); 12351bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita REPORTER_ASSERT(reporter, blob->bounds() == r1); 12451bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita } 12551bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita 12651bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita { 12751bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20); 12851bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita builder.allocRunPos(font, 16, &r1); 12937283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> blob(builder.make()); 13051bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita REPORTER_ASSERT(reporter, blob->bounds() == r1); 13151bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita } 13251bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita 13351bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita { 13451bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SkRect r1 = SkRect::MakeXYWH(10, 10, 20, 20); 13551bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SkRect r2 = SkRect::MakeXYWH(15, 20, 50, 50); 13651bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SkRect r3 = SkRect::MakeXYWH(0, 5, 10, 5); 13751bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita 13851bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita builder.allocRun(font, 16, 0, 0, &r1); 13951bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita builder.allocRunPosH(font, 16, 0, &r2); 14051bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita builder.allocRunPos(font, 16, &r3); 14151bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita 14237283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> blob(builder.make()); 14351bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita REPORTER_ASSERT(reporter, blob->bounds() == SkRect::MakeXYWH(0, 5, 65, 65)); 14451bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita } 14551bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita 14651bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita { 14737283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> blob(builder.make()); 1483a9a7a310c5cff72bc1c2388a496af1b82326355Florin Malita REPORTER_ASSERT(reporter, !blob); 14951bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita } 15051bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita 15151bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita // Implicit bounds 1529ae8fe1c601ecb7fef9962f9eb1adf11032378e4fmalita 1539ae8fe1c601ecb7fef9962f9eb1adf11032378e4fmalita { 1549ae8fe1c601ecb7fef9962f9eb1adf11032378e4fmalita // Exercise the empty bounds path, and ensure that RunRecord-aligned pos buffers 1559ae8fe1c601ecb7fef9962f9eb1adf11032378e4fmalita // don't trigger asserts (http://crbug.com/542643). 1569ae8fe1c601ecb7fef9962f9eb1adf11032378e4fmalita SkPaint p; 1579ae8fe1c601ecb7fef9962f9eb1adf11032378e4fmalita p.setTextSize(0); 1580b01da7bca9dacdd58affe5d5433860cb3d59194fmalita p.setTextEncoding(SkPaint::kUTF8_TextEncoding); 1599ae8fe1c601ecb7fef9962f9eb1adf11032378e4fmalita 1609ae8fe1c601ecb7fef9962f9eb1adf11032378e4fmalita const char* txt = "BOOO"; 1610b01da7bca9dacdd58affe5d5433860cb3d59194fmalita const size_t txtLen = strlen(txt); 1620b01da7bca9dacdd58affe5d5433860cb3d59194fmalita const int glyphCount = p.textToGlyphs(txt, txtLen, nullptr); 1630b01da7bca9dacdd58affe5d5433860cb3d59194fmalita 1640b01da7bca9dacdd58affe5d5433860cb3d59194fmalita p.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 1650b01da7bca9dacdd58affe5d5433860cb3d59194fmalita const SkTextBlobBuilder::RunBuffer& buffer = builder.allocRunPos(p, glyphCount); 1660b01da7bca9dacdd58affe5d5433860cb3d59194fmalita 1670b01da7bca9dacdd58affe5d5433860cb3d59194fmalita p.setTextEncoding(SkPaint::kUTF8_TextEncoding); 1680b01da7bca9dacdd58affe5d5433860cb3d59194fmalita p.textToGlyphs(txt, txtLen, buffer.glyphs); 1690b01da7bca9dacdd58affe5d5433860cb3d59194fmalita 1700b01da7bca9dacdd58affe5d5433860cb3d59194fmalita memset(buffer.pos, 0, sizeof(SkScalar) * glyphCount * 2); 17137283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> blob(builder.make()); 1729ae8fe1c601ecb7fef9962f9eb1adf11032378e4fmalita REPORTER_ASSERT(reporter, blob->bounds().isEmpty()); 1739ae8fe1c601ecb7fef9962f9eb1adf11032378e4fmalita } 174c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 175c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 17632d6b876163580711a07e96d9f29c9c1490a7271fmalita // Verify that text-related properties are captured in run paints. 17732d6b876163580711a07e96d9f29c9c1490a7271fmalita static void TestPaintProps(skiatest::Reporter* reporter) { 17832d6b876163580711a07e96d9f29c9c1490a7271fmalita SkPaint font; 17932d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 18032d6b876163580711a07e96d9f29c9c1490a7271fmalita 18132d6b876163580711a07e96d9f29c9c1490a7271fmalita // Kitchen sink font. 18232d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setTextSize(42); 18332d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setTextScaleX(4.2f); 18413b9c95295f4c5732e34574789e721a6bc08f7b4bungeman font.setTypeface(SkTypeface::MakeDefault()); 18532d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setTextSkewX(0.42f); 18632d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setTextAlign(SkPaint::kCenter_Align); 18732d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setHinting(SkPaint::kFull_Hinting); 18832d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setAntiAlias(true); 18932d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setFakeBoldText(true); 19032d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setLinearText(true); 19132d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setSubpixelText(true); 19232d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setDevKernText(true); 19332d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setLCDRenderText(true); 19432d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setEmbeddedBitmapText(true); 19532d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setAutohinted(true); 19632d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setVerticalText(true); 19732d6b876163580711a07e96d9f29c9c1490a7271fmalita font.setFlags(font.getFlags() | SkPaint::kGenA8FromLCD_Flag); 19832d6b876163580711a07e96d9f29c9c1490a7271fmalita 19932d6b876163580711a07e96d9f29c9c1490a7271fmalita // Ensure we didn't pick default values by mistake. 20032d6b876163580711a07e96d9f29c9c1490a7271fmalita SkPaint defaultPaint; 20132d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.getTextSize() != font.getTextSize()); 20232d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.getTextScaleX() != font.getTextScaleX()); 20332d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.getTypeface() != font.getTypeface()); 20432d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.getTextSkewX() != font.getTextSkewX()); 20532d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.getTextAlign() != font.getTextAlign()); 20632d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.getHinting() != font.getHinting()); 20732d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.isAntiAlias() != font.isAntiAlias()); 20832d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.isFakeBoldText() != font.isFakeBoldText()); 20932d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.isLinearText() != font.isLinearText()); 21032d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.isSubpixelText() != font.isSubpixelText()); 21132d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.isDevKernText() != font.isDevKernText()); 21232d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.isLCDRenderText() != font.isLCDRenderText()); 21332d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.isEmbeddedBitmapText() != font.isEmbeddedBitmapText()); 21432d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.isAutohinted() != font.isAutohinted()); 21532d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, defaultPaint.isVerticalText() != font.isVerticalText()); 21632d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, (defaultPaint.getFlags() & SkPaint::kGenA8FromLCD_Flag) != 21732d6b876163580711a07e96d9f29c9c1490a7271fmalita (font.getFlags() & SkPaint::kGenA8FromLCD_Flag)); 21832d6b876163580711a07e96d9f29c9c1490a7271fmalita 21932d6b876163580711a07e96d9f29c9c1490a7271fmalita SkTextBlobBuilder builder; 22032d6b876163580711a07e96d9f29c9c1490a7271fmalita AddRun(font, 1, SkTextBlob::kDefault_Positioning, SkPoint::Make(0, 0), builder); 22132d6b876163580711a07e96d9f29c9c1490a7271fmalita AddRun(font, 1, SkTextBlob::kHorizontal_Positioning, SkPoint::Make(0, 0), builder); 22232d6b876163580711a07e96d9f29c9c1490a7271fmalita AddRun(font, 1, SkTextBlob::kFull_Positioning, SkPoint::Make(0, 0), builder); 22337283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> blob(builder.make()); 22432d6b876163580711a07e96d9f29c9c1490a7271fmalita 22537283c28aa5bea2204c18956e74f83b238d7a891fmalita SkTextBlobRunIterator it(blob.get()); 22632d6b876163580711a07e96d9f29c9c1490a7271fmalita while (!it.done()) { 22732d6b876163580711a07e96d9f29c9c1490a7271fmalita SkPaint paint; 22832d6b876163580711a07e96d9f29c9c1490a7271fmalita it.applyFontToPaint(&paint); 22932d6b876163580711a07e96d9f29c9c1490a7271fmalita 23032d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.getTextSize() == font.getTextSize()); 23132d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.getTextScaleX() == font.getTextScaleX()); 23232d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.getTypeface() == font.getTypeface()); 23332d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.getTextSkewX() == font.getTextSkewX()); 23432d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.getTextAlign() == font.getTextAlign()); 23532d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.getHinting() == font.getHinting()); 23632d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.isAntiAlias() == font.isAntiAlias()); 23732d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.isFakeBoldText() == font.isFakeBoldText()); 23832d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.isLinearText() == font.isLinearText()); 23932d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.isSubpixelText() == font.isSubpixelText()); 24032d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.isDevKernText() == font.isDevKernText()); 24132d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.isLCDRenderText() == font.isLCDRenderText()); 24232d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.isEmbeddedBitmapText() == font.isEmbeddedBitmapText()); 24332d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.isAutohinted() == font.isAutohinted()); 24432d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, paint.isVerticalText() == font.isVerticalText()); 24532d6b876163580711a07e96d9f29c9c1490a7271fmalita REPORTER_ASSERT(reporter, (paint.getFlags() & SkPaint::kGenA8FromLCD_Flag) == 24632d6b876163580711a07e96d9f29c9c1490a7271fmalita (font.getFlags() & SkPaint::kGenA8FromLCD_Flag)); 24732d6b876163580711a07e96d9f29c9c1490a7271fmalita 24832d6b876163580711a07e96d9f29c9c1490a7271fmalita it.next(); 24932d6b876163580711a07e96d9f29c9c1490a7271fmalita } 25032d6b876163580711a07e96d9f29c9c1490a7271fmalita 25132d6b876163580711a07e96d9f29c9c1490a7271fmalita } 25232d6b876163580711a07e96d9f29c9c1490a7271fmalita 253c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalitaprivate: 254c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita struct RunDef { 255c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita unsigned count; 256c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita SkTextBlob::GlyphPositioning pos; 257c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita SkScalar x, y; 258c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita }; 259c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 26051bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita static void RunBuilderTest(skiatest::Reporter* reporter, SkTextBlobBuilder& builder, 261c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita const RunDef in[], unsigned inCount, 262c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita const RunDef out[], unsigned outCount) { 26351bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita SkPaint font; 26451bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita font.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 26551bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita 266c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita unsigned glyphCount = 0; 267c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita unsigned posCount = 0; 268c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 269c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita for (unsigned i = 0; i < inCount; ++i) { 27051bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita AddRun(font, in[i].count, in[i].pos, SkPoint::Make(in[i].x, in[i].y), builder); 271c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita glyphCount += in[i].count; 272c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita posCount += in[i].count * in[i].pos; 273c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 274c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 27537283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> blob(builder.make()); 2763a9a7a310c5cff72bc1c2388a496af1b82326355Florin Malita REPORTER_ASSERT(reporter, (inCount > 0) == SkToBool(blob)); 2773a9a7a310c5cff72bc1c2388a496af1b82326355Florin Malita if (!blob) { 2783a9a7a310c5cff72bc1c2388a496af1b82326355Florin Malita return; 2793a9a7a310c5cff72bc1c2388a496af1b82326355Florin Malita } 280c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 28137283c28aa5bea2204c18956e74f83b238d7a891fmalita SkTextBlobRunIterator it(blob.get()); 282c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita for (unsigned i = 0; i < outCount; ++i) { 283c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita REPORTER_ASSERT(reporter, !it.done()); 284c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita REPORTER_ASSERT(reporter, out[i].pos == it.positioning()); 285c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita REPORTER_ASSERT(reporter, out[i].count == it.glyphCount()); 286c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita if (SkTextBlob::kDefault_Positioning == out[i].pos) { 287c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita REPORTER_ASSERT(reporter, out[i].x == it.offset().x()); 288c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita REPORTER_ASSERT(reporter, out[i].y == it.offset().y()); 289c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } else if (SkTextBlob::kHorizontal_Positioning == out[i].pos) { 290c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita REPORTER_ASSERT(reporter, out[i].y == it.offset().y()); 291c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 292c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 293c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita for (unsigned k = 0; k < it.glyphCount(); ++k) { 294c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita REPORTER_ASSERT(reporter, k % 128 == it.glyphs()[k]); 295c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita if (SkTextBlob::kHorizontal_Positioning == it.positioning()) { 296c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita REPORTER_ASSERT(reporter, SkIntToScalar(k % 128) == it.pos()[k]); 297c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } else if (SkTextBlob::kFull_Positioning == it.positioning()) { 298c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita REPORTER_ASSERT(reporter, SkIntToScalar(k % 128) == it.pos()[k * 2]); 299c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita REPORTER_ASSERT(reporter, -SkIntToScalar(k % 128) == it.pos()[k * 2 + 1]); 300c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 301c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 302c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 303c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita it.next(); 304c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 305c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 306c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita REPORTER_ASSERT(reporter, it.done()); 307c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 308c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 30951bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita static void AddRun(const SkPaint& font, int count, SkTextBlob::GlyphPositioning pos, 310c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita const SkPoint& offset, SkTextBlobBuilder& builder, 31196fcdcc219d2a0d3579719b84b28bede76efba64halcanary const SkRect* bounds = nullptr) { 312c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita switch (pos) { 313c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita case SkTextBlob::kDefault_Positioning: { 314c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita const SkTextBlobBuilder::RunBuffer& rb = builder.allocRun(font, count, offset.x(), 315c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita offset.y(), bounds); 316c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita for (int i = 0; i < count; ++i) { 317c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita rb.glyphs[i] = i; 318c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 319c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } break; 320c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita case SkTextBlob::kHorizontal_Positioning: { 321c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita const SkTextBlobBuilder::RunBuffer& rb = builder.allocRunPosH(font, count, offset.y(), 322c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita bounds); 323c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita for (int i = 0; i < count; ++i) { 324c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita rb.glyphs[i] = i; 325c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita rb.pos[i] = SkIntToScalar(i); 326c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 327c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } break; 328c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita case SkTextBlob::kFull_Positioning: { 329c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita const SkTextBlobBuilder::RunBuffer& rb = builder.allocRunPos(font, count, bounds); 330c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita for (int i = 0; i < count; ++i) { 331c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita rb.glyphs[i] = i; 332c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita rb.pos[i * 2] = SkIntToScalar(i); 333c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita rb.pos[i * 2 + 1] = -SkIntToScalar(i); 334c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 335c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } break; 336c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita default: 337b4aab9ae6d27c446af8302b79d15b832c816c633Ben Wagner SK_ABORT("unhandled positioning value"); 338c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 339c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita } 340c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita}; 341c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita 342c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalitaDEF_TEST(TextBlob_builder, reporter) { 34351bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita TextBlobTester::TestBuilder(reporter); 34451bf9573b8b875aec47cbeb9f4649f58bcbf56b7fmalita TextBlobTester::TestBounds(reporter); 345c6765d69e3aceaa316fe2d2ef00a7f0d138def2ffmalita} 34632d6b876163580711a07e96d9f29c9c1490a7271fmalita 34732d6b876163580711a07e96d9f29c9c1490a7271fmalitaDEF_TEST(TextBlob_paint, reporter) { 34832d6b876163580711a07e96d9f29c9c1490a7271fmalita TextBlobTester::TestPaintProps(reporter); 34932d6b876163580711a07e96d9f29c9c1490a7271fmalita} 3504f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary 3514f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanaryDEF_TEST(TextBlob_extended, reporter) { 3524f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary SkTextBlobBuilder textBlobBuilder; 3534f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary SkPaint paint; 3544f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary const char text1[] = "Foo"; 3554f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary const char text2[] = "Bar"; 3564f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary 3574f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary int glyphCount = paint.textToGlyphs(text1, strlen(text1), nullptr); 3584f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary SkAutoTMalloc<uint16_t> glyphs(glyphCount); 3594f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary (void)paint.textToGlyphs(text1, strlen(text1), glyphs.get()); 3604f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 3614f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary 3624f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary auto run = textBlobBuilder.allocRunText( 3634f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary paint, glyphCount, 0, 0, SkToInt(strlen(text2)), SkString(), nullptr); 3644f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary memcpy(run.glyphs, glyphs.get(), sizeof(uint16_t) * glyphCount); 3654f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary memcpy(run.utf8text, text2, strlen(text2)); 3664f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary for (int i = 0; i < glyphCount; ++i) { 3674f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary run.clusters[i] = SkTMin(SkToU32(i), SkToU32(strlen(text2))); 3684f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary } 36937283c28aa5bea2204c18956e74f83b238d7a891fmalita sk_sp<SkTextBlob> blob(textBlobBuilder.make()); 3704f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary REPORTER_ASSERT(reporter, blob); 3714f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary 3724f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary for (SkTextBlobRunIterator it(blob.get()); !it.done(); it.next()) { 3734f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary REPORTER_ASSERT(reporter, it.glyphCount() == (uint32_t)glyphCount); 3744f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary for (uint32_t i = 0; i < it.glyphCount(); ++i) { 3754f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary REPORTER_ASSERT(reporter, it.glyphs()[i] == glyphs[i]); 3764f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary } 3774f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary REPORTER_ASSERT(reporter, SkTextBlob::kDefault_Positioning == it.positioning()); 3784f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary REPORTER_ASSERT(reporter, (SkPoint{0.0f, 0.0f}) == it.offset()); 3794f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary REPORTER_ASSERT(reporter, it.textSize() > 0); 3804f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary REPORTER_ASSERT(reporter, it.clusters()); 3814f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary for (uint32_t i = 0; i < it.glyphCount(); ++i) { 3824f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary REPORTER_ASSERT(reporter, i == it.clusters()[i]); 3834f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary } 3844f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary REPORTER_ASSERT(reporter, 0 == strncmp(text2, it.text(), it.textSize())); 3854f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary } 3864f0a23a8d54f5eb0fdacfff7c109b9045b548978halcanary} 387b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed 388b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed/////////////////////////////////////////////////////////////////////////////////////////////////// 389b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed#include "SkCanvas.h" 390b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed#include "SkSurface.h" 391b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed#include "SkTDArray.h" 392b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed 393b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reedstatic void add_run(SkTextBlobBuilder* builder, const char text[], SkScalar x, SkScalar y, 394b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed sk_sp<SkTypeface> tf) { 395b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed SkPaint paint; 396b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed paint.setAntiAlias(true); 397b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed paint.setSubpixelText(true); 398b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed paint.setTextSize(16); 399b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed paint.setTypeface(tf); 400b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed 401b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed int glyphCount = paint.textToGlyphs(text, strlen(text), nullptr); 402b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed 403b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed paint.setTextEncoding(SkPaint::kGlyphID_TextEncoding); 404b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed SkTextBlobBuilder::RunBuffer buffer = builder->allocRun(paint, glyphCount, x, y); 405b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed 406b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed paint.setTextEncoding(SkPaint::kUTF8_TextEncoding); 407b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed (void)paint.textToGlyphs(text, strlen(text), buffer.glyphs); 408b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed} 409b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed 410b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reedstatic sk_sp<SkImage> render(const SkTextBlob* blob) { 411b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed auto surf = SkSurface::MakeRasterN32Premul(SkScalarRoundToInt(blob->bounds().width()), 412b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed SkScalarRoundToInt(blob->bounds().height())); 4137e49d534d71d3e7b053fe6f23dfe018ddbceb45bMike Reed if (!surf) { 4147e49d534d71d3e7b053fe6f23dfe018ddbceb45bMike Reed return nullptr; // bounds are empty? 4157e49d534d71d3e7b053fe6f23dfe018ddbceb45bMike Reed } 416b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed surf->getCanvas()->clear(SK_ColorWHITE); 417b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed surf->getCanvas()->drawTextBlob(blob, -blob->bounds().left(), -blob->bounds().top(), SkPaint()); 418b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed return surf->makeImageSnapshot(); 419b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed} 420b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed 421b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed/* 422b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed * Build a blob with more than one typeface. 423b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed * Draw it into an offscreen, 424b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed * then serialize and deserialize, 425b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed * Then draw the new instance and assert it draws the same as the original. 426b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed */ 427b99beddc7a0f6003d6dd88119e7f2734fc508322Mike ReedDEF_TEST(TextBlob_serialize, reporter) { 4284bcef3c40ad8d3a16bbca4ab74fa15256fb4b125Mike Reed sk_sp<SkTextBlob> blob0 = []() { 4298e74cbcd6526a7542b9f704b9e40b0c60d475849Mike Reed sk_sp<SkTypeface> tf = SkTypeface::MakeDefault(); 430b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed 4314bcef3c40ad8d3a16bbca4ab74fa15256fb4b125Mike Reed SkTextBlobBuilder builder; 4328e74cbcd6526a7542b9f704b9e40b0c60d475849Mike Reed add_run(&builder, "Hello", 10, 20, nullptr); // we don't flatten this in the paint 4338e74cbcd6526a7542b9f704b9e40b0c60d475849Mike Reed add_run(&builder, "World", 10, 40, tf); // we will flatten this in the paint 4344bcef3c40ad8d3a16bbca4ab74fa15256fb4b125Mike Reed return builder.make(); 4354bcef3c40ad8d3a16bbca4ab74fa15256fb4b125Mike Reed }(); 436b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed 437b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed SkTDArray<SkTypeface*> array; 438aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed sk_sp<SkData> data = blob0->serialize([](SkTypeface* tf, void* ctx) { 439aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed auto array = (SkTDArray<SkTypeface*>*)ctx; 440aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed if (array->find(tf) < 0) { 441aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed *array->append() = tf; 442b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed } 443aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed }, &array); 4448e74cbcd6526a7542b9f704b9e40b0c60d475849Mike Reed // we only expect 1, since null would not have been serialized, but the default would 4458e74cbcd6526a7542b9f704b9e40b0c60d475849Mike Reed REPORTER_ASSERT(reporter, array.count() == 1); 446b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed 447b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed sk_sp<SkTextBlob> blob1 = SkTextBlob::Deserialize(data->data(), data->size(), 448aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed [](uint32_t uniqueID, void* ctx) { 449aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed auto array = (SkTDArray<SkTypeface*>*)ctx; 450aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed for (int i = 0; i < array->count(); ++i) { 451aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed if ((*array)[i]->uniqueID() == uniqueID) { 452aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed return sk_ref_sp((*array)[i]); 453b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed } 454b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed } 455aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed SkASSERT(false); 456b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed return sk_sp<SkTypeface>(nullptr); 457aaa3056e46ed9004097dc784db94c3a97d070569Mike Reed }, &array); 458b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed 4597e49d534d71d3e7b053fe6f23dfe018ddbceb45bMike Reed sk_sp<SkImage> img0 = render(blob0.get()); 4607e49d534d71d3e7b053fe6f23dfe018ddbceb45bMike Reed sk_sp<SkImage> img1 = render(blob1.get()); 4617e49d534d71d3e7b053fe6f23dfe018ddbceb45bMike Reed if (img0 && img1) { 4624bcef3c40ad8d3a16bbca4ab74fa15256fb4b125Mike Reed REPORTER_ASSERT(reporter, sk_tool_utils::equal_pixels(img0.get(), img1.get())); 463b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed } 464b99beddc7a0f6003d6dd88119e7f2734fc508322Mike Reed} 465