skia2/gm/textblobshader.cpp
Mike Reed 5f50f5776d New plan -- aa and lcd DO belong on SkFont
edging settings are needed for metrics calls, as well as drawing, hence
we really have to include them in almost every SkFont call/usage, so I
guess we can just accept them as real.

This seems to imply that we have to document what happens in drawTextBlob,
since it has a bunch of SkFonts (runs) AND a paint. This is the situation
today of course, and I had hoped to simplify it, but I think I've failed.

Proposal dox for drawTextBlob.

drawTextBlob respects the paint when drawing the blog, but it IGNORES the
paint's antialias (and lcdrender) flags, as these are already specified in
the blob's runs.

Bug: skia:2664, skia:8494
Change-Id: I8f69186c9c337d98d058919f53b7901ff830a16e
Reviewed-on: https://skia-review.googlesource.com/c/170352
Auto-Submit: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Ben Wagner <bungeman@google.com>
Commit-Queue: Mike Reed <reed@google.com>
Commit-Queue: Ben Wagner <bungeman@google.com>
2018-11-12 19:30:16 +00:00

114 lines
3.5 KiB
C++

/*
* Copyright 2014 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "gm.h"
#include "sk_tool_utils.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkPoint.h"
#include "SkShader.h"
#include "SkTextBlob.h"
#include "SkTDArray.h"
#include "SkTypeface.h"
// This GM exercises drawTextBlob offset vs. shader space behavior.
class TextBlobShaderGM : public skiagm::GM {
public:
TextBlobShaderGM(const char* txt) {
SkPaint p;
sk_tool_utils::set_portable_typeface(&p);
size_t txtLen = strlen(txt);
fGlyphs.append(p.textToGlyphs(txt, txtLen, nullptr));
p.textToGlyphs(txt, txtLen, fGlyphs.begin());
}
protected:
void onOnceBeforeDraw() override {
SkFont font;
font.setSubpixel(true);
font.setEdging(SkFont::Edging::kAntiAlias);
font.setSize(30);
font.setTypeface(sk_tool_utils::create_portable_typeface());
SkTextBlobBuilder builder;
int glyphCount = fGlyphs.count();
const SkTextBlobBuilder::RunBuffer* run;
run = &builder.allocRun(font, glyphCount, 10, 10, nullptr);
memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));
run = &builder.allocRunPosH(font, glyphCount, 80, nullptr);
memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));
for (int i = 0; i < glyphCount; ++i) {
run->pos[i] = font.getSize() * i * .75f;
}
run = &builder.allocRunPos(font, glyphCount, nullptr);
memcpy(run->glyphs, fGlyphs.begin(), glyphCount * sizeof(uint16_t));
for (int i = 0; i < glyphCount; ++i) {
run->pos[i * 2] = font.getSize() * i * .75f;
run->pos[i * 2 + 1] = 150 + 5 * sinf((float)i * 8 / glyphCount);
}
fBlob = builder.make();
SkColor colors[2];
colors[0] = SK_ColorRED;
colors[1] = SK_ColorGREEN;
SkScalar pos[SK_ARRAY_COUNT(colors)];
for (unsigned i = 0; i < SK_ARRAY_COUNT(pos); ++i) {
pos[i] = (float)i / (SK_ARRAY_COUNT(pos) - 1);
}
SkISize sz = this->onISize();
fShader = SkGradientShader::MakeRadial(SkPoint::Make(SkIntToScalar(sz.width() / 2),
SkIntToScalar(sz.height() / 2)),
sz.width() * .66f, colors, pos,
SK_ARRAY_COUNT(colors),
SkShader::kRepeat_TileMode);
}
SkString onShortName() override {
return SkString("textblobshader");
}
SkISize onISize() override {
return SkISize::Make(640, 480);
}
void onDraw(SkCanvas* canvas) override {
SkPaint p;
p.setAntiAlias(true);
p.setStyle(SkPaint::kFill_Style);
p.setShader(fShader);
SkISize sz = this->onISize();
constexpr int kXCount = 4;
constexpr int kYCount = 3;
for (int i = 0; i < kXCount; ++i) {
for (int j = 0; j < kYCount; ++j) {
canvas->drawTextBlob(fBlob,
SkIntToScalar(i * sz.width() / kXCount),
SkIntToScalar(j * sz.height() / kYCount),
p);
}
}
}
private:
SkTDArray<uint16_t> fGlyphs;
sk_sp<SkTextBlob> fBlob;
sk_sp<SkShader> fShader;
typedef skiagm::GM INHERITED;
};
DEF_GM(return new TextBlobShaderGM("Blobber");)