| /* | |
| * 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/gm.h" | |
| #include "include/core/SkBitmap.h" | |
| #include "include/core/SkBlendMode.h" | |
| #include "include/core/SkCanvas.h" | |
| #include "include/core/SkColor.h" | |
| #include "include/core/SkFont.h" | |
| #include "include/core/SkFontStyle.h" | |
| #include "include/core/SkFontTypes.h" | |
| #include "include/core/SkImageInfo.h" | |
| #include "include/core/SkMatrix.h" | |
| #include "include/core/SkPaint.h" | |
| #include "include/core/SkRect.h" | |
| #include "include/core/SkRefCnt.h" | |
| #include "include/core/SkScalar.h" | |
| #include "include/core/SkShader.h" | |
| #include "include/core/SkSize.h" | |
| #include "include/core/SkString.h" | |
| #include "include/core/SkTileMode.h" | |
| #include "include/core/SkTypeface.h" | |
| #include "include/core/SkTypes.h" | |
| #include "include/effects/SkGradient.h" | |
| #include "include/utils/SkTextUtils.h" | |
| #include "src/core/SkUTF.h" | |
| #include "tools/ToolUtils.h" | |
| #include "tools/fonts/FontToolUtils.h" | |
| #include <array> | |
| #include <string.h> | |
| namespace { | |
| static uint32_t gData[] = { 0xFFFFFFFF, 0xFFCCCCCC, 0xFFCCCCCC, 0xFFFFFFFF }; | |
| class ColorEmojiBlendModesGM : public skiagm::GM { | |
| public: | |
| const static int W = 64; | |
| const static int H = 64; | |
| ColorEmojiBlendModesGM(ToolUtils::EmojiFontFormat format) : fFormat(format) {} | |
| protected: | |
| void onOnceBeforeDraw() override { | |
| const SkColor4f colors[] = { | |
| SkColors::kRed, SkColors::kGreen, SkColors::kBlue, | |
| SkColors::kMagenta, SkColors::kCyan, SkColors::kYellow | |
| }; | |
| SkMatrix local; | |
| local.setRotate(180); | |
| SkPaint paint; | |
| paint.setAntiAlias(true); | |
| paint.setShader(SkShaders::SweepGradient({0, 0}, | |
| {{colors, {}, SkTileMode::kClamp}, {}}, &local)); | |
| sk_sp<SkTypeface> orig(ToolUtils::CreatePortableTypeface("serif", SkFontStyle::Bold())); | |
| SkASSERT(orig); | |
| fColorSample = ToolUtils::EmojiSample(fFormat); | |
| fBG.installPixels(SkImageInfo::Make(2, 2, kRGBA_8888_SkColorType, kOpaque_SkAlphaType), | |
| gData, 8); | |
| } | |
| SkString getName() const override { | |
| return SkString("coloremoji_blendmodes_") += ToolUtils::NameForFontFormat(fFormat); | |
| } | |
| SkISize getISize() override { return {400, 640}; } | |
| DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override { | |
| if (!fColorSample.typeface) { | |
| *errorMsg = SkStringPrintf("Unable to instantiate emoji test font of format %s.", | |
| ToolUtils::NameForFontFormat(fFormat).c_str()); | |
| return DrawResult::kSkip; | |
| } | |
| canvas->translate(SkIntToScalar(10), SkIntToScalar(20)); | |
| static constexpr auto gModes = std::to_array<SkBlendMode>({ | |
| SkBlendMode::kClear, | |
| SkBlendMode::kSrc, | |
| SkBlendMode::kDst, | |
| SkBlendMode::kSrcOver, | |
| SkBlendMode::kDstOver, | |
| SkBlendMode::kSrcIn, | |
| SkBlendMode::kDstIn, | |
| SkBlendMode::kSrcOut, | |
| SkBlendMode::kDstOut, | |
| SkBlendMode::kSrcATop, | |
| SkBlendMode::kDstATop, | |
| SkBlendMode::kXor, | |
| SkBlendMode::kPlus, | |
| SkBlendMode::kModulate, | |
| SkBlendMode::kScreen, | |
| SkBlendMode::kOverlay, | |
| SkBlendMode::kDarken, | |
| SkBlendMode::kLighten, | |
| SkBlendMode::kColorDodge, | |
| SkBlendMode::kColorBurn, | |
| SkBlendMode::kHardLight, | |
| SkBlendMode::kSoftLight, | |
| SkBlendMode::kDifference, | |
| SkBlendMode::kExclusion, | |
| SkBlendMode::kMultiply, | |
| SkBlendMode::kHue, | |
| SkBlendMode::kSaturation, | |
| SkBlendMode::kColor, | |
| SkBlendMode::kLuminosity, | |
| }); | |
| const SkScalar w = SkIntToScalar(W); | |
| const SkScalar h = SkIntToScalar(H); | |
| SkMatrix m; | |
| m.setScale(SkIntToScalar(6), SkIntToScalar(6)); | |
| auto s = fBG.makeShader(SkTileMode::kRepeat, SkTileMode::kRepeat, SkSamplingOptions(), m); | |
| SkFont labelFont(ToolUtils::DefaultPortableTypeface()); | |
| SkPaint textP; | |
| textP.setAntiAlias(true); | |
| SkFont textFont(fColorSample.typeface, 70); | |
| const int kWrap = 5; | |
| SkScalar x0 = 0; | |
| SkScalar y0 = 0; | |
| SkScalar x = x0, y = y0; | |
| for (size_t i = 0; i < std::size(gModes); i++) { | |
| SkRect r; | |
| r.setLTRB(x, y, x+w, y+h); | |
| SkPaint p; | |
| p.setStyle(SkPaint::kFill_Style); | |
| p.setShader(s); | |
| canvas->drawRect(r, p); | |
| r.inset(-SK_ScalarHalf, -SK_ScalarHalf); | |
| p.setStyle(SkPaint::kStroke_Style); | |
| p.setShader(nullptr); | |
| canvas->drawRect(r, p); | |
| { | |
| SkAutoCanvasRestore arc(canvas, true); | |
| canvas->clipRect(r); | |
| textP.setBlendMode(gModes[i]); | |
| const char* text = fColorSample.sampleText; | |
| SkUnichar unichar = SkUTF::NextUTF8(&text, text + strlen(text)); | |
| SkASSERT(unichar >= 0); | |
| canvas->drawSimpleText(&unichar, 4, SkTextEncoding::kUTF32, | |
| x+ w/10.f, y + 7.f*h/8.f, textFont, textP); | |
| } | |
| #if 1 | |
| const char* label = SkBlendMode_Name(gModes[i]); | |
| SkTextUtils::DrawString(canvas, label, x + w/2, y - labelFont.getSize()/2, | |
| labelFont, SkPaint(), SkTextUtils::kCenter_Align); | |
| #endif | |
| x += w + SkIntToScalar(10); | |
| if ((i % kWrap) == kWrap - 1) { | |
| x = x0; | |
| y += h + SkIntToScalar(30); | |
| } | |
| } | |
| return DrawResult::kOk; | |
| } | |
| private: | |
| SkBitmap fBG; | |
| ToolUtils::EmojiFontFormat fFormat; | |
| ToolUtils::EmojiTestSample fColorSample; | |
| using INHERITED = GM; | |
| }; | |
| } // namespace | |
| DEF_GM(return new ColorEmojiBlendModesGM(ToolUtils::EmojiFontFormat::ColrV0);) | |
| DEF_GM(return new ColorEmojiBlendModesGM(ToolUtils::EmojiFontFormat::Sbix);) | |
| DEF_GM(return new ColorEmojiBlendModesGM(ToolUtils::EmojiFontFormat::Cbdt);) | |
| DEF_GM(return new ColorEmojiBlendModesGM(ToolUtils::EmojiFontFormat::Test);) | |
| DEF_GM(return new ColorEmojiBlendModesGM(ToolUtils::EmojiFontFormat::Svg);) |