SampleTextEffects.cpp 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. /*
  2. * Copyright 2011 Google Inc.
  3. *
  4. * Use of this source code is governed by a BSD-style license that can be
  5. * found in the LICENSE file.
  6. */
  7. #include "include/core/SkCanvas.h"
  8. #include "include/core/SkColorFilter.h"
  9. #include "include/core/SkColorPriv.h"
  10. #include "include/core/SkPath.h"
  11. #include "include/core/SkRegion.h"
  12. #include "include/core/SkShader.h"
  13. #include "include/core/SkStrokeRec.h"
  14. #include "include/core/SkTypeface.h"
  15. #include "include/effects/SkGradientShader.h"
  16. #include "include/utils/SkTextUtils.h"
  17. #include "samplecode/Sample.h"
  18. #include "src/core/SkReadBuffer.h"
  19. #include "src/core/SkWriteBuffer.h"
  20. #include "src/utils/SkUTF.h"
  21. #include "include/effects/SkBlurMaskFilter.h"
  22. #include "include/effects/SkGradientShader.h"
  23. #include "include/effects/Sk2DPathEffect.h"
  24. class Dot2DPathEffect : public Sk2DPathEffect {
  25. public:
  26. Dot2DPathEffect(SkScalar radius, const SkMatrix& matrix,
  27. SkTDArray<SkPoint>* pts)
  28. : Sk2DPathEffect(matrix), fRadius(radius), fPts(pts) {}
  29. SK_FLATTENABLE_HOOKS(Dot2DPathEffect)
  30. protected:
  31. void begin(const SkIRect& uvBounds, SkPath* dst) const override {
  32. if (fPts) {
  33. fPts->reset();
  34. }
  35. this->INHERITED::begin(uvBounds, dst);
  36. }
  37. virtual void next(const SkPoint& loc, int u, int v,
  38. SkPath* dst) const override {
  39. if (fPts) {
  40. *fPts->append() = loc;
  41. }
  42. dst->addCircle(loc.fX, loc.fY, fRadius);
  43. }
  44. void flatten(SkWriteBuffer& buffer) const override {
  45. buffer.writeMatrix(this->getMatrix());
  46. buffer.writeScalar(fRadius);
  47. }
  48. private:
  49. SkScalar fRadius;
  50. SkTDArray<SkPoint>* fPts;
  51. typedef Sk2DPathEffect INHERITED;
  52. };
  53. // Register this path effect as deserializable before main().
  54. namespace {
  55. static struct Initializer {
  56. Initializer() {
  57. SK_REGISTER_FLATTENABLE(Dot2DPathEffect);
  58. }
  59. } initializer;
  60. }
  61. sk_sp<SkFlattenable> Dot2DPathEffect::CreateProc(SkReadBuffer& buffer) {
  62. SkMatrix matrix;
  63. buffer.readMatrix(&matrix);
  64. return sk_make_sp<Dot2DPathEffect>(buffer.readScalar(), matrix, nullptr);
  65. }
  66. class InverseFillPE : public SkPathEffect {
  67. public:
  68. InverseFillPE() {}
  69. virtual bool onFilterPath(SkPath* dst, const SkPath& src,
  70. SkStrokeRec*, const SkRect*) const override {
  71. *dst = src;
  72. dst->setFillType(SkPath::kInverseWinding_FillType);
  73. return true;
  74. }
  75. private:
  76. SK_FLATTENABLE_HOOKS(InverseFillPE)
  77. typedef SkPathEffect INHERITED;
  78. };
  79. sk_sp<SkFlattenable> InverseFillPE::CreateProc(SkReadBuffer& buffer) {
  80. return sk_make_sp<InverseFillPE>();
  81. }
  82. static sk_sp<SkPathEffect> makepe(float interp, SkTDArray<SkPoint>* pts) {
  83. SkMatrix lattice;
  84. SkScalar rad = 3 + SkIntToScalar(4) * (1 - interp);
  85. lattice.setScale(rad*2, rad*2, 0, 0);
  86. lattice.postSkew(SK_Scalar1/3, 0, 0, 0);
  87. return sk_make_sp<Dot2DPathEffect>(rad, lattice, pts);
  88. }
  89. class TextEffectsView : public Sample {
  90. sk_sp<SkTypeface> fFace;
  91. SkScalar fInterp;
  92. SkScalar fDx;
  93. public:
  94. TextEffectsView() {
  95. fFace = SkTypeface::MakeFromFile("/Users/reed/Downloads/p052024l.pfb");
  96. fInterp = 0;
  97. fDx = SK_Scalar1/64;
  98. }
  99. protected:
  100. SkString name() override { return SkString("Text Effects"); }
  101. void drawBG(SkCanvas* canvas) {
  102. canvas->drawColor(SK_ColorWHITE);
  103. }
  104. void drawdots(SkCanvas* canvas, SkString s, SkScalar x, SkScalar y, const SkFont& font) {
  105. SkTDArray<SkPoint> pts;
  106. auto pe = makepe(fInterp, &pts);
  107. SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
  108. SkPath path, dstPath;
  109. SkTextUtils::GetPath(s.c_str(), s.size(), SkTextEncoding::kUTF8, x, y, font, &path);
  110. pe->filterPath(&dstPath, path, &rec, nullptr);
  111. SkPaint paint;
  112. paint.setAntiAlias(true);
  113. paint.setStrokeWidth(10);
  114. paint.setColor(SK_ColorRED);
  115. canvas->drawPoints(SkCanvas::kPoints_PointMode, pts.count(), pts.begin(), paint);
  116. }
  117. void onDrawContent(SkCanvas* canvas) override {
  118. this->drawBG(canvas);
  119. SkScalar x = SkIntToScalar(20);
  120. SkScalar y = SkIntToScalar(300);
  121. SkFont font(SkTypeface::MakeFromName("sans-serif", SkFontStyle::Bold()), 240);
  122. SkString str("9");
  123. canvas->drawString(str, x, y, font, SkPaint());
  124. drawdots(canvas, str, x, y, font);
  125. if (false) {
  126. fInterp += fDx;
  127. if (fInterp > 1) {
  128. fInterp = 1;
  129. fDx = -fDx;
  130. } else if (fInterp < 0) {
  131. fInterp = 0;
  132. fDx = -fDx;
  133. }
  134. }
  135. }
  136. private:
  137. typedef Sample INHERITED;
  138. };
  139. //////////////////////////////////////////////////////////////////////////////
  140. DEF_SAMPLE( return new TextEffectsView(); )