iPlug2 - C++ Audio Plug-in Framework
ISkParagraphControl.h
Go to the documentation of this file.
1 /*
2  ==============================================================================
3 
4  This file is part of the iPlug 2 library. Copyright (C) the iPlug 2 developers.
5 
6  See LICENSE.txt for more info.
7 
8  ==============================================================================
9 */
10 
11 #pragma once
12 
13 #ifndef IGRAPHICS_SKIA
14 #error This IControl only works with the Skia graphics backend
15 #endif
16 
22 #include "IControl.h"
23 #include "IGraphicsSkia.h"
24 #include "include/core/SkCanvas.h"
25 #include "include/core/SkColorFilter.h"
26 #include "include/core/SkColorPriv.h"
27 #include "include/core/SkFontMgr.h"
28 #include "include/core/SkGraphics.h"
29 #include "include/core/SkPath.h"
30 #include "include/core/SkRegion.h"
31 #include "include/core/SkShader.h"
32 #include "include/core/SkStream.h"
33 #include "include/core/SkTextBlob.h"
34 #include "include/core/SkTime.h"
35 #include "include/core/SkTypeface.h"
36 #include "include/effects/SkGradientShader.h"
37 #include "include/utils/SkRandom.h"
38 #include "modules/skparagraph/include/Paragraph.h"
39 #include "modules/skparagraph/include/TypefaceFontProvider.h"
40 #include "modules/skparagraph/src/ParagraphBuilderImpl.h"
41 #include "modules/skparagraph/src/ParagraphImpl.h"
42 #include "modules/skparagraph/src/TextLine.h"
43 #include "modules/skparagraph/utils/TestFontCollection.h"
44 
45 #ifdef OS_WIN
46  #pragma comment(lib, "skparagraph.lib")
47  #pragma comment(lib, "skshaper.lib")
48 #endif
49 
50 BEGIN_IPLUG_NAMESPACE
51 BEGIN_IGRAPHICS_NAMESPACE
52 
53 using namespace skia::textlayout;
54 
55 
59 {
60 public:
61  ISkParagraphControl(const IRECT& bounds)
62  : IControl(bounds)
63  {
64  }
65 
66  void Draw(IGraphics& g) override
67  {
68  g.FillRect(COLOR_GREEN, mRECT);
69  SkCanvas* canvas = (SkCanvas*) g.GetDrawContext();
70  DoDrawContent(canvas);
71  }
72 
73  void DoDrawContent(SkCanvas* canvas)
74  {
75  float w = mRECT.W();
76 // float h = mRECT.H();
77 
78  const std::vector<
79  std::tuple<std::string, bool, bool, int, SkColor, SkColor, bool, TextDecorationStyle>>
80  gParagraph = { {"monospace", true, false, 14, SK_ColorWHITE, SK_ColorRED, true,
81  TextDecorationStyle::kDashed},
82  {"Assyrian", false, false, 20, SK_ColorWHITE, SK_ColorBLUE, false,
83  TextDecorationStyle::kDotted},
84  {"serif", true, true, 10, SK_ColorWHITE, SK_ColorRED, true,
85  TextDecorationStyle::kDouble},
86  {"Arial", false, true, 16, SK_ColorGRAY, SK_ColorGREEN, true,
87  TextDecorationStyle::kSolid},
88  {"sans-serif", false, false, 8, SK_ColorWHITE, SK_ColorRED, false,
89  TextDecorationStyle::kWavy} };
90  SkAutoCanvasRestore acr(canvas, true);
91 
92 // canvas->clipRect(SkRect::MakeWH(w, h));
93  canvas->drawColor(SK_ColorWHITE);
94 
95  SkScalar margin = 20;
96 
97  SkPaint paint;
98  paint.setAntiAlias(true);
99  paint.setColor(SK_ColorWHITE);
100 
101  SkPaint blue;
102  blue.setColor(SK_ColorBLUE);
103 
104  TextStyle defaultStyle;
105  defaultStyle.setBackgroundColor(blue);
106  defaultStyle.setForegroundColor(paint);
107  ParagraphStyle paraStyle;
108 
109  auto fontCollection = sk_make_sp<FontCollection>();
110  fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
111  for (auto i = 1; i < 5; ++i) {
112  defaultStyle.setFontSize(24 * i);
113  paraStyle.setTextStyle(defaultStyle);
114  ParagraphBuilderImpl builder(paraStyle, fontCollection);
115  std::string name = "Paragraph: " + std::to_string(24 * i);
116  builder.addText(name.c_str(), name.length());
117  for (auto para : gParagraph) {
118  TextStyle style;
119  style.setFontFamilies({ SkString(std::get<0>(para).c_str()) });
120  SkFontStyle fontStyle(std::get<1>(para) ? SkFontStyle::Weight::kBold_Weight
121  : SkFontStyle::Weight::kNormal_Weight,
122  SkFontStyle::Width::kNormal_Width,
123  std::get<2>(para) ? SkFontStyle::Slant::kItalic_Slant
124  : SkFontStyle::Slant::kUpright_Slant);
125  style.setFontStyle(fontStyle);
126  style.setFontSize(std::get<3>(para) * i);
127  SkPaint background;
128  background.setColor(std::get<4>(para));
129  style.setBackgroundColor(background);
130  SkPaint foreground;
131  foreground.setColor(std::get<5>(para));
132  foreground.setAntiAlias(true);
133  style.setForegroundColor(foreground);
134  if (std::get<6>(para)) {
135  style.addShadow(TextShadow(SK_ColorBLACK, SkPoint::Make(5, 5), 2));
136  }
137 
138  auto decoration = (i % 4);
139  if (decoration == 3) {
140  decoration = 4;
141  }
142 
143  bool test = (TextDecoration)decoration != TextDecoration::kNoDecoration;
144  std::string deco = std::to_string((int)decoration);
145  if (test) {
146  style.setDecoration((TextDecoration)decoration);
147  style.setDecorationStyle(std::get<7>(para));
148  style.setDecorationColor(std::get<5>(para));
149  }
150  builder.pushStyle(style);
151  std::string name = " " + std::get<0>(para) + " " +
152  (std::get<1>(para) ? ", bold" : "") +
153  (std::get<2>(para) ? ", italic" : "") + " " +
154  std::to_string(std::get<3>(para) * i) +
155  (std::get<4>(para) != SK_ColorRED ? ", background" : "") +
156  (std::get<5>(para) != SK_ColorWHITE ? ", foreground" : "") +
157  (std::get<6>(para) ? ", shadow" : "") +
158  (test ? ", decorations " + deco : "") + ";";
159  builder.addText(name.c_str(), name.length());
160  builder.pop();
161  }
162 
163  auto paragraph = builder.Build();
164  paragraph->layout(w - margin * 2);
165  paragraph->paint(canvas, mRECT.L + margin, mRECT.T + margin);
166 
167  canvas->translate(0, paragraph->getHeight());
168  }
169  }
170 
171 // void DoDrawContent(SkCanvas* canvas)
172 // {
173 // const std::u16string text = u"The quick brown fox \U0001f98a ate a zesty ham burger fons \U0001f354."
174 // "The \U0001f469\u200D\U0001f469\u200D\U0001f467\u200D\U0001f467 laughed.";
175 // canvas->drawColor(SK_ColorWHITE);
176 //
177 // auto fontCollection = getFontCollection();
178 // fontCollection->setDefaultFontManager(SkFontMgr::RefDefault());
179 // fontCollection->enableFontFallback();
180 //
181 // ParagraphStyle paragraph_style;
182 // paragraph_style.setMaxLines(7);
183 // paragraph_style.setEllipsis(u"\u2026");
184 // ParagraphBuilderImpl builder(paragraph_style, fontCollection);
185 // TextStyle text_style;
186 // text_style.setColor(SK_ColorBLACK);
187 // text_style.setFontFamilies({ SkString("Roboto"), SkString("Noto Color Emoji") });
188 // text_style.setFontSize(60);
189 // builder.pushStyle(text_style);
190 // builder.addText(text);
191 // auto paragraph = builder.Build();
192 // assert(paragraph);
193 // paragraph->layout(mRECT.W());
194 // paragraph->paint(canvas, mRECT.L, mRECT.T);
195 // }
196 };
197 
198 END_IGRAPHICS_NAMESPACE
199 END_IPLUG_NAMESPACE
The lowest level base class of an IGraphics control.
Definition: IControl.h:42
Used to manage a rectangular area, independent of draw class/platform.
This file contains the base IControl implementation, along with some base classes for specific types ...
The lowest level base class of an IGraphics context.
Definition: IGraphics.h:86
virtual void FillRect(const IColor &color, const IRECT &bounds, const IBlend *pBlend=0)
Fill a rectangular region of the graphics context with a color.
Definition: IGraphics.cpp:2547
virtual void * GetDrawContext()=0
Gets a void pointer to underlying drawing context, for the IGraphics backend See draw class implement...
void Draw(IGraphics &g) override
Draw the control to the graphics context.
A control that demonstrates how to draw rich text using SkParagraph.