1cb93a386Sopenharmony_ci/* 2cb93a386Sopenharmony_ci * Copyright 2011 Google Inc. 3cb93a386Sopenharmony_ci * 4cb93a386Sopenharmony_ci * Use of this source code is governed by a BSD-style license that can be 5cb93a386Sopenharmony_ci * found in the LICENSE file. 6cb93a386Sopenharmony_ci */ 7cb93a386Sopenharmony_ci#include "samplecode/Sample.h" 8cb93a386Sopenharmony_ci 9cb93a386Sopenharmony_ci#include "include/core/SkCanvas.h" 10cb93a386Sopenharmony_ci#include "include/core/SkColorFilter.h" 11cb93a386Sopenharmony_ci#include "include/core/SkColorPriv.h" 12cb93a386Sopenharmony_ci#include "include/core/SkGraphics.h" 13cb93a386Sopenharmony_ci#include "include/core/SkPath.h" 14cb93a386Sopenharmony_ci#include "include/core/SkRegion.h" 15cb93a386Sopenharmony_ci#include "include/core/SkShader.h" 16cb93a386Sopenharmony_ci#include "include/core/SkStream.h" 17cb93a386Sopenharmony_ci#include "include/core/SkTextBlob.h" 18cb93a386Sopenharmony_ci#include "include/core/SkTime.h" 19cb93a386Sopenharmony_ci#include "include/core/SkTypeface.h" 20cb93a386Sopenharmony_ci#include "include/effects/SkGradientShader.h" 21cb93a386Sopenharmony_ci#include "include/utils/SkRandom.h" 22cb93a386Sopenharmony_ci#include "modules/skshaper/include/SkShaper.h" 23cb93a386Sopenharmony_ci#include "src/core/SkOSFile.h" 24cb93a386Sopenharmony_ci#include "src/shaders/SkColorShader.h" 25cb93a386Sopenharmony_ci#include "src/utils/SkUTF.h" 26cb93a386Sopenharmony_ci 27cb93a386Sopenharmony_citypedef std::unique_ptr<SkShaper> (*ShaperFactory)(); 28cb93a386Sopenharmony_ci 29cb93a386Sopenharmony_cistatic const char gText[] = 30cb93a386Sopenharmony_ci "When in the Course of human events it becomes necessary for one people " 31cb93a386Sopenharmony_ci "to dissolve the political bands which have connected them with another " 32cb93a386Sopenharmony_ci "and to assume among the powers of the earth, the separate and equal " 33cb93a386Sopenharmony_ci "station to which the Laws of Nature and of Nature's God entitle them, " 34cb93a386Sopenharmony_ci "a decent respect to the opinions of mankind requires that they should " 35cb93a386Sopenharmony_ci "declare the causes which impel them to the separation."; 36cb93a386Sopenharmony_ci 37cb93a386Sopenharmony_ciclass TextBoxView : public Sample { 38cb93a386Sopenharmony_ci SkString fName; 39cb93a386Sopenharmony_cipublic: 40cb93a386Sopenharmony_ci TextBoxView(ShaperFactory fact, const char suffix[]) : fShaper(fact()) { 41cb93a386Sopenharmony_ci fName.printf("TextBox_%s", suffix); 42cb93a386Sopenharmony_ci } 43cb93a386Sopenharmony_ci 44cb93a386Sopenharmony_ciprotected: 45cb93a386Sopenharmony_ci SkString name() override { return fName; } 46cb93a386Sopenharmony_ci 47cb93a386Sopenharmony_ci void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) { 48cb93a386Sopenharmony_ci SkAutoCanvasRestore acr(canvas, true); 49cb93a386Sopenharmony_ci 50cb93a386Sopenharmony_ci canvas->clipRect(SkRect::MakeWH(w, h)); 51cb93a386Sopenharmony_ci canvas->drawColor(bg); 52cb93a386Sopenharmony_ci 53cb93a386Sopenharmony_ci SkScalar margin = 20; 54cb93a386Sopenharmony_ci 55cb93a386Sopenharmony_ci SkPaint paint; 56cb93a386Sopenharmony_ci paint.setColor(fg); 57cb93a386Sopenharmony_ci 58cb93a386Sopenharmony_ci for (int i = 9; i < 24; i += 2) { 59cb93a386Sopenharmony_ci SkShaper::PurgeCaches(); 60cb93a386Sopenharmony_ci SkTextBlobBuilderRunHandler builder(gText, { margin, margin }); 61cb93a386Sopenharmony_ci SkFont srcFont(nullptr, SkIntToScalar(i)); 62cb93a386Sopenharmony_ci srcFont.setEdging(SkFont::Edging::kSubpixelAntiAlias); 63cb93a386Sopenharmony_ci srcFont.setSubpixel(true); 64cb93a386Sopenharmony_ci 65cb93a386Sopenharmony_ci const char* utf8 = gText; 66cb93a386Sopenharmony_ci size_t utf8Bytes = sizeof(gText) - 1; 67cb93a386Sopenharmony_ci 68cb93a386Sopenharmony_ci std::unique_ptr<SkShaper::BiDiRunIterator> bidi( 69cb93a386Sopenharmony_ci SkShaper::MakeBiDiRunIterator(utf8, utf8Bytes, 0xfe)); 70cb93a386Sopenharmony_ci if (!bidi) { 71cb93a386Sopenharmony_ci return; 72cb93a386Sopenharmony_ci } 73cb93a386Sopenharmony_ci 74cb93a386Sopenharmony_ci std::unique_ptr<SkShaper::LanguageRunIterator> language( 75cb93a386Sopenharmony_ci SkShaper::MakeStdLanguageRunIterator(utf8, utf8Bytes)); 76cb93a386Sopenharmony_ci if (!language) { 77cb93a386Sopenharmony_ci return; 78cb93a386Sopenharmony_ci } 79cb93a386Sopenharmony_ci 80cb93a386Sopenharmony_ci SkFourByteTag undeterminedScript = SkSetFourByteTag('Z','y','y','y'); 81cb93a386Sopenharmony_ci std::unique_ptr<SkShaper::ScriptRunIterator> script( 82cb93a386Sopenharmony_ci SkShaper::MakeScriptRunIterator(utf8, utf8Bytes, undeterminedScript)); 83cb93a386Sopenharmony_ci if (!script) { 84cb93a386Sopenharmony_ci return; 85cb93a386Sopenharmony_ci } 86cb93a386Sopenharmony_ci 87cb93a386Sopenharmony_ci std::unique_ptr<SkShaper::FontRunIterator> font( 88cb93a386Sopenharmony_ci SkShaper::MakeFontMgrRunIterator(utf8, utf8Bytes, srcFont, SkFontMgr::RefDefault(), 89cb93a386Sopenharmony_ci "Arial", SkFontStyle::Bold(), &*language)); 90cb93a386Sopenharmony_ci if (!font) { 91cb93a386Sopenharmony_ci return; 92cb93a386Sopenharmony_ci } 93cb93a386Sopenharmony_ci 94cb93a386Sopenharmony_ci fShaper->shape(utf8, utf8Bytes, *font, *bidi, *script, *language, w - margin, &builder); 95cb93a386Sopenharmony_ci canvas->drawTextBlob(builder.makeBlob(), 0, 0, paint); 96cb93a386Sopenharmony_ci 97cb93a386Sopenharmony_ci canvas->translate(0, builder.endPoint().y()); 98cb93a386Sopenharmony_ci } 99cb93a386Sopenharmony_ci } 100cb93a386Sopenharmony_ci 101cb93a386Sopenharmony_ci void onDrawContent(SkCanvas* canvas) override { 102cb93a386Sopenharmony_ci SkScalar width = this->width() / 3; 103cb93a386Sopenharmony_ci drawTest(canvas, width, this->height(), SK_ColorBLACK, SK_ColorWHITE); 104cb93a386Sopenharmony_ci canvas->translate(width, 0); 105cb93a386Sopenharmony_ci drawTest(canvas, width, this->height(), SK_ColorWHITE, SK_ColorBLACK); 106cb93a386Sopenharmony_ci canvas->translate(width, 0); 107cb93a386Sopenharmony_ci drawTest(canvas, width, this->height()/2, SK_ColorGRAY, SK_ColorWHITE); 108cb93a386Sopenharmony_ci canvas->translate(0, this->height()/2); 109cb93a386Sopenharmony_ci drawTest(canvas, width, this->height()/2, SK_ColorGRAY, SK_ColorBLACK); 110cb93a386Sopenharmony_ci } 111cb93a386Sopenharmony_ci 112cb93a386Sopenharmony_ciprivate: 113cb93a386Sopenharmony_ci std::unique_ptr<SkShaper> fShaper; 114cb93a386Sopenharmony_ci using INHERITED = Sample; 115cb93a386Sopenharmony_ci}; 116cb93a386Sopenharmony_ci 117cb93a386Sopenharmony_ciDEF_SAMPLE( return new TextBoxView([](){ return SkShaper::Make(); }, "default"); ); 118cb93a386Sopenharmony_ci#ifdef SK_SHAPER_CORETEXT_AVAILABLE 119cb93a386Sopenharmony_ciDEF_SAMPLE( return new TextBoxView(SkShaper::MakeCoreText, "coretext"); ); 120cb93a386Sopenharmony_ci#endif 121cb93a386Sopenharmony_ci 122cb93a386Sopenharmony_ciclass SampleShaper : public Sample { 123cb93a386Sopenharmony_cipublic: 124cb93a386Sopenharmony_ci SampleShaper() {} 125cb93a386Sopenharmony_ci 126cb93a386Sopenharmony_ciprotected: 127cb93a386Sopenharmony_ci SkString name() override { return SkString("shaper"); } 128cb93a386Sopenharmony_ci 129cb93a386Sopenharmony_ci void drawTest(SkCanvas* canvas, const char str[], SkScalar size, 130cb93a386Sopenharmony_ci std::unique_ptr<SkShaper> shaper) { 131cb93a386Sopenharmony_ci if (!shaper) return; 132cb93a386Sopenharmony_ci 133cb93a386Sopenharmony_ci SkTextBlobBuilderRunHandler builder(str, {0, 0}); 134cb93a386Sopenharmony_ci SkFont srcFont; 135cb93a386Sopenharmony_ci srcFont.setSize(size); 136cb93a386Sopenharmony_ci srcFont.setEdging(SkFont::Edging::kSubpixelAntiAlias); 137cb93a386Sopenharmony_ci srcFont.setSubpixel(true); 138cb93a386Sopenharmony_ci 139cb93a386Sopenharmony_ci size_t len = strlen(str); 140cb93a386Sopenharmony_ci 141cb93a386Sopenharmony_ci std::unique_ptr<SkShaper::BiDiRunIterator> bidi( 142cb93a386Sopenharmony_ci SkShaper::MakeBiDiRunIterator(str, len, 0xfe)); 143cb93a386Sopenharmony_ci if (!bidi) { 144cb93a386Sopenharmony_ci return; 145cb93a386Sopenharmony_ci } 146cb93a386Sopenharmony_ci 147cb93a386Sopenharmony_ci std::unique_ptr<SkShaper::LanguageRunIterator> language( 148cb93a386Sopenharmony_ci SkShaper::MakeStdLanguageRunIterator(str, len)); 149cb93a386Sopenharmony_ci if (!language) { 150cb93a386Sopenharmony_ci return; 151cb93a386Sopenharmony_ci } 152cb93a386Sopenharmony_ci 153cb93a386Sopenharmony_ci SkFourByteTag undeterminedScript = SkSetFourByteTag('Z','y','y','y'); 154cb93a386Sopenharmony_ci std::unique_ptr<SkShaper::ScriptRunIterator> script( 155cb93a386Sopenharmony_ci SkShaper::MakeScriptRunIterator(str, len, undeterminedScript)); 156cb93a386Sopenharmony_ci if (!script) { 157cb93a386Sopenharmony_ci return; 158cb93a386Sopenharmony_ci } 159cb93a386Sopenharmony_ci 160cb93a386Sopenharmony_ci std::unique_ptr<SkShaper::FontRunIterator> font( 161cb93a386Sopenharmony_ci SkShaper::MakeFontMgrRunIterator(str, len, srcFont, SkFontMgr::RefDefault(), 162cb93a386Sopenharmony_ci "Arial", SkFontStyle::Bold(), &*language)); 163cb93a386Sopenharmony_ci if (!font) { 164cb93a386Sopenharmony_ci return; 165cb93a386Sopenharmony_ci } 166cb93a386Sopenharmony_ci 167cb93a386Sopenharmony_ci shaper->shape(str, len, *font, *bidi, *script, *language, 2000, &builder); 168cb93a386Sopenharmony_ci 169cb93a386Sopenharmony_ci canvas->drawTextBlob(builder.makeBlob(), 0, 0, SkPaint()); 170cb93a386Sopenharmony_ci } 171cb93a386Sopenharmony_ci 172cb93a386Sopenharmony_ci void onDrawContent(SkCanvas* canvas) override { 173cb93a386Sopenharmony_ci canvas->translate(10, 30); 174cb93a386Sopenharmony_ci 175cb93a386Sopenharmony_ci const char text[] = "world"; 176cb93a386Sopenharmony_ci 177cb93a386Sopenharmony_ci for (SkScalar size = 30; size <= 30; size += 10) { 178cb93a386Sopenharmony_ci this->drawTest(canvas, text, size, SkShaper::Make()); 179cb93a386Sopenharmony_ci canvas->translate(0, size + 5); 180cb93a386Sopenharmony_ci #ifdef SK_SHAPER_CORETEXT_AVAILABLE 181cb93a386Sopenharmony_ci this->drawTest(canvas, text, size, SkShaper::MakeCoreText()); 182cb93a386Sopenharmony_ci #endif 183cb93a386Sopenharmony_ci canvas->translate(0, size*2); 184cb93a386Sopenharmony_ci } 185cb93a386Sopenharmony_ci } 186cb93a386Sopenharmony_ci 187cb93a386Sopenharmony_ciprivate: 188cb93a386Sopenharmony_ci using INHERITED = Sample; 189cb93a386Sopenharmony_ci}; 190cb93a386Sopenharmony_ciDEF_SAMPLE( return new SampleShaper; ); 191