diff options
author | Brian Salomon <bsalomon@google.com> | 2017-11-17 14:18:12 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2017-11-17 20:35:06 +0000 |
commit | 39631f3df172feb385527a5d125bc53b0bded7e6 (patch) | |
tree | f63361075ecc24f709d379c976b080d4d54949aa /gm/atlastext.cpp | |
parent | e686cc4efadec7606b3df0f1e4133011d68b10b3 (diff) |
Add Atlas Text interface for rendering SDF glyphs.
This new API is built upon SDF text atlas code from the GPU backend. Unlike using the GPU
backend to draw text, this set of interfaces allows the client to render the SDF glyphs. The
client issues text draws to potentially multiple targets and then the client flushes. The
client then gets commands from Skia with data to put into a texture atlas and vertices to
draw that reference the texture. The client is responsible for creating the texture, uploading
the SDF data to the texture, and drawing the vertices provided by Skia.
Change-Id: Ie9447e19b85f0ce1c2b942e5216c787a74f335d3
Reviewed-on: https://skia-review.googlesource.com/59360
Commit-Queue: Brian Salomon <bsalomon@google.com>
Reviewed-by: Robert Phillips <robertphillips@google.com>
Diffstat (limited to 'gm/atlastext.cpp')
-rw-r--r-- | gm/atlastext.cpp | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/gm/atlastext.cpp b/gm/atlastext.cpp new file mode 100644 index 0000000000..b8acb0fcc7 --- /dev/null +++ b/gm/atlastext.cpp @@ -0,0 +1,123 @@ +/* + * Copyright 2017 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" + +#if SK_SUPPORT_ATLAS_TEXT + +#include "SkAtlasTextContext.h" +#include "SkAtlasTextFont.h" +#include "SkAtlasTextTarget.h" +#include "SkBitmap.h" +#include "SkCanvas.h" +#include "SkTypeface.h" +#include "gpu/TestContext.h" +#include "gpu/atlastext/GLTestAtlasTextRenderer.h" +#include "gpu/atlastext/TestAtlasTextRenderer.h" +#include "sk_tool_utils.h" + +// GM that draws text using the Atlas Text interface offscreen and then blits that to the canvas. + +static SkScalar draw_string(SkAtlasTextTarget* target, const SkString& text, SkScalar x, SkScalar y, + uint32_t color, sk_sp<SkTypeface> typeface, float size) { + auto font = SkAtlasTextFont::Make(std::move(typeface), size); + target->drawText(text.c_str(), text.size(), x, y, color, *font); + SkPaint paint; + paint.setTextSize(size); + return x + paint.measureText(text.c_str(), text.size()); +} + +class AtlasTextGM : public skiagm::GM { +public: + AtlasTextGM() = default; + +protected: + SkString onShortName() override { return SkString("atlastext"); } + + SkISize onISize() override { return SkISize::Make(kSize, kSize); } + + void onOnceBeforeDraw() override { + fRenderer = sk_gpu_test::MakeGLTestAtlasTextRenderer(); + if (!fRenderer) { + return; + } + fContext = SkAtlasTextContext::Make(fRenderer); + auto targetHandle = fRenderer->makeTargetHandle(kSize, kSize); + fTarget = SkAtlasTextTarget::Make(fContext, kSize, kSize, targetHandle); + + fTypefaces[0] = sk_tool_utils::create_portable_typeface("serif", SkFontStyle::Italic()); + fTypefaces[1] = + sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Italic()); + fTypefaces[2] = sk_tool_utils::create_portable_typeface("serif", SkFontStyle::Normal()); + fTypefaces[3] = + sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Normal()); + fTypefaces[4] = sk_tool_utils::create_portable_typeface("serif", SkFontStyle::Bold()); + fTypefaces[5] = sk_tool_utils::create_portable_typeface("sans-serif", SkFontStyle::Bold()); + } + + void onDraw(SkCanvas* canvas) override { + if (!fRenderer) { + canvas->clear(SK_ColorRED); + return; + } + auto bmp = this->drawText(); + SkPaint paint; + paint.setBlendMode(SkBlendMode::kSrc); + canvas->drawBitmap(bmp, 0, 0); + } + +private: + SkBitmap drawText() { + static const int kSizes[] = {8, 13, 18, 23, 30}; + + static const SkString kTexts[] = {SkString("ABCDEFGHIJKLMNOPQRSTUVWXYZ"), + SkString("abcdefghijklmnopqrstuvwxyz"), + SkString("0123456789"), + SkString("!@#$%^&*()<>[]{}")}; + SkScalar x = 0; + SkScalar y = 10; + + SkRandom random; + do { + for (auto s : kSizes) { + auto size = 2 * s; + for (const auto& typeface : fTypefaces) { + for (const auto& text : kTexts) { + uint32_t color = random.nextU(); + x = size + draw_string(fTarget.get(), text, x, y, color, typeface, size); + x = SkScalarCeilToScalar(x); + if (x + 100 > kSize) { + x = 0; + y += SkScalarCeilToScalar(size + 3); + if (y > kSize) { + fTarget->flush(); + return fRenderer->readTargetHandle(fTarget->handle()); + } + } + } + } + } + } while (true); + } + + static constexpr int kSize = 1280; + + sk_sp<SkTypeface> fTypefaces[6]; + sk_sp<sk_gpu_test::TestAtlasTextRenderer> fRenderer; + std::unique_ptr<SkAtlasTextTarget> fTarget; + sk_sp<SkAtlasTextContext> fContext; + + typedef GM INHERITED; +}; + +constexpr int AtlasTextGM::kSize; + +////////////////////////////////////////////////////////////////////////////// + +DEF_GM(return new AtlasTextGM;) + +#endif |