skia2/samplecode/SampleTextBox.cpp
Ben Wagner 1ca50524c4 Allow better font fallback.
The intent is to allow the creation of a MakeFontMgrRunIterator which
uses the passed font's typeface as the primary typeface, but uses a
given family name and style as for the request for fallback fonts. This
allows the user to provide the actual request for the primary typeface
as opposed to making a request based on the resolved primary typeface
(which may not be the right thing to do).

To support this, the selection of language for fallback is also added.
Since this information is already in the language iterator, this change
makes the font iterator the lowest priority iterator for consume,
allowing the font iterator to rely on the current value of the language
iterator to provide the language.

In order to allow these changes to be exercised, this also adds a few
generic 'Make' methods for bidi and script. These new methods will use
the best available implementation. These are needed since the most
capable implementations may not always be available (such as on our
testing ios builds).

Change-Id: I1b8d9c9007058adcb2a26e0581d903b835a6118f
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/245460
Commit-Queue: Ben Wagner <bungeman@google.com>
Reviewed-by: Herb Derby <herb@google.com>
2019-10-02 22:19:13 +00:00

114 lines
4.0 KiB
C++

/*
* Copyright 2011 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "samplecode/Sample.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkColorPriv.h"
#include "include/core/SkGraphics.h"
#include "include/core/SkPath.h"
#include "include/core/SkRegion.h"
#include "include/core/SkShader.h"
#include "include/core/SkStream.h"
#include "include/core/SkTextBlob.h"
#include "include/core/SkTime.h"
#include "include/core/SkTypeface.h"
#include "include/effects/SkBlurMaskFilter.h"
#include "include/effects/SkGradientShader.h"
#include "include/utils/SkRandom.h"
#include "modules/skshaper/include/SkShaper.h"
#include "src/core/SkOSFile.h"
#include "src/shaders/SkColorShader.h"
#include "src/utils/SkUTF.h"
static const char gText[] =
"When in the Course of human events it becomes necessary for one people "
"to dissolve the political bands which have connected them with another "
"and to assume among the powers of the earth, the separate and equal "
"station to which the Laws of Nature and of Nature's God entitle them, "
"a decent respect to the opinions of mankind requires that they should "
"declare the causes which impel them to the separation.";
class TextBoxView : public Sample {
public:
TextBoxView() : fShaper(SkShaper::Make()) {}
protected:
SkString name() override { return SkString("TextBox"); }
void drawTest(SkCanvas* canvas, SkScalar w, SkScalar h, SkColor fg, SkColor bg) {
SkAutoCanvasRestore acr(canvas, true);
canvas->clipRect(SkRect::MakeWH(w, h));
canvas->drawColor(bg);
SkScalar margin = 20;
SkPaint paint;
paint.setColor(fg);
for (int i = 9; i < 24; i += 2) {
SkTextBlobBuilderRunHandler builder(gText, { margin, margin });
SkFont srcFont(nullptr, SkIntToScalar(i));
srcFont.setEdging(SkFont::Edging::kSubpixelAntiAlias);
const char* utf8 = gText;
size_t utf8Bytes = sizeof(gText) - 1;
std::unique_ptr<SkShaper::BiDiRunIterator> bidi(
SkShaper::MakeBiDiRunIterator(utf8, utf8Bytes, 0xfe));
if (!bidi) {
return;
}
std::unique_ptr<SkShaper::LanguageRunIterator> language(
SkShaper::MakeStdLanguageRunIterator(utf8, utf8Bytes));
if (!language) {
return;
}
SkFourByteTag undeterminedScript = SkSetFourByteTag('Z','y','y','y');
std::unique_ptr<SkShaper::ScriptRunIterator> script(
SkShaper::MakeScriptRunIterator(utf8, utf8Bytes, undeterminedScript));
if (!script) {
return;
}
std::unique_ptr<SkShaper::FontRunIterator> font(
SkShaper::MakeFontMgrRunIterator(utf8, utf8Bytes, srcFont, SkFontMgr::RefDefault(),
"Arial", SkFontStyle::Bold(), &*language));
if (!font) {
return;
}
fShaper->shape(utf8, utf8Bytes, *font, *bidi, *script, *language, w - margin, &builder);
canvas->drawTextBlob(builder.makeBlob(), 0, 0, paint);
canvas->translate(0, builder.endPoint().y());
}
}
void onDrawContent(SkCanvas* canvas) override {
SkScalar width = this->width() / 3;
drawTest(canvas, width, this->height(), SK_ColorBLACK, SK_ColorWHITE);
canvas->translate(width, 0);
drawTest(canvas, width, this->height(), SK_ColorWHITE, SK_ColorBLACK);
canvas->translate(width, 0);
drawTest(canvas, width, this->height()/2, SK_ColorGRAY, SK_ColorWHITE);
canvas->translate(0, this->height()/2);
drawTest(canvas, width, this->height()/2, SK_ColorGRAY, SK_ColorBLACK);
}
private:
std::unique_ptr<SkShaper> fShaper;
typedef Sample INHERITED;
};
//////////////////////////////////////////////////////////////////////////////
DEF_SAMPLE( return new TextBoxView(); )