TextBuilder.h
Go to the documentation of this file.
1 /****
2  * TextBuilder.h
3  *
4  * Copyright 2021 mikee47 <mike@sillyhouse.net>
5  *
6  * This file is part of the Sming-Graphics Library
7  *
8  * This library is free software: you can redistribute it and/or modify it under the terms of the
9  * GNU General Public License as published by the Free Software Foundation, version 3 or later.
10  *
11  * This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
12  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13  * See the GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License along with this library.
16  * If not, see <https://www.gnu.org/licenses/>.
17  *
18  * @author: May 2021 - mikee47 <mike@sillyhouse.net>
19  *
20  ****/
21 
22 #pragma once
23 
24 #include "Scene.h"
25 #include "LcdFont.h"
26 
27 namespace Graphics
28 {
33 {
34 public:
35  TextParser(const Rect& bounds) : bounds(bounds)
36  {
37  resetClip();
38  }
39 
40  const Rect& getBounds() const
41  {
42  return bounds;
43  }
44 
46  {
47  endRun();
48  curAsset = nullptr;
49  curFont = nullptr;
50  curColor = nullptr;
51  return object.release();
52  }
53 
55  {
56  return scene.addObject(release());
57  }
58 
59  static void setDefaultFont(Font* font)
60  {
61  defaultFont = font;
62  }
63 
64  void setFont(const Font* font)
65  {
66  if(font == nullptr) {
67  font = defaultFont;
68  }
69  if(this->font != font) {
70  curSeg = nullptr;
71  curFont = nullptr;
72  typeface = nullptr;
73  this->font = font;
74  }
75  }
76 
77  void setFont(const Font& font)
78  {
79  setFont(&font);
80  }
81 
82  const Font& getFont() const;
83 
84  const TypeFace& getTypeFace() const;
85 
86  void setScale(Scale scale)
87  {
88  if(scale != options.scale) {
89  curSeg = nullptr;
90  curFont = nullptr;
91  options.scale = scale;
92  }
93  }
94 
95  void setScale(uint8_t sx, uint8_t sy)
96  {
97  setScale(Scale(sx, sy));
98  }
99 
100  void setScale(uint8_t size)
101  {
102  setScale(size, size);
103  }
104 
105  uint16_t getTextHeight() const
106  {
107  return options.scale.scaleY(getTypeFace().height());
108  }
109 
110  const TextOptions& getOptions() const
111  {
112  return options;
113  }
114 
115  void setStyle(FontStyles style)
116  {
117  if(options.style != style) {
118  curSeg = nullptr;
119  curFont = nullptr;
120  typeface = nullptr;
121  options.style = style;
122  }
123  }
124 
125  void addStyle(FontStyles style)
126  {
127  setStyle(options.style + style);
128  }
129 
131  {
132  setStyle(options.style - style);
133  }
134 
135  void setTextAlign(Align align)
136  {
137  if(align != textAlign) {
138  endRun();
139  textAlign = align;
140  }
141  }
142 
144  {
145  return textAlign;
146  }
147 
148  void setLineAlign(Align align)
149  {
150  if(align != lineAlign) {
151  endRun();
152  lineAlign = align;
153  }
154  }
155 
157  {
158  return lineAlign;
159  }
160 
161  Point getCursor() const
162  {
163  return cursor;
164  }
165 
169  void setCursor(Point pt)
170  {
171  if(pt != cursor) {
172  endRun();
173  cursor = pt;
174  }
175  }
176 
177  void setCursor(int16_t x, int16_t y)
178  {
179  setCursor({x, y});
180  }
181 
182  void moveCursor(Point offset)
183  {
184  setCursor(cursor + offset);
185  }
186 
187  void moveCursor(int16_t x, int16_t y)
188  {
189  moveCursor({x, y});
190  }
191 
192  void setColor(const Brush& fore, const Brush& back = {})
193  {
194  if(options.fore == fore && options.back == back) {
195  return;
196  }
197  curSeg = nullptr;
198  curColor = nullptr;
199  options.fore = fore;
200  options.back = back;
201  }
202 
203  void setForeColor(const Brush& color)
204  {
205  setColor(color, options.back);
206  }
207 
208  void setBackColor(const Brush& color)
209  {
210  setColor(options.fore, color);
211  }
212 
213  void setClip(const Rect& r)
214  {
215  endRun();
216  clip = intersect(r, bounds.size());
217  cursor = Point{};
218  }
219 
220  const Rect& getClip() const
221  {
222  return clip;
223  }
224 
225  void resetClip()
226  {
227  endRun();
228  clip = bounds.size();
229  cursor = Point{};
230  }
231 
232  void setWrap(bool wrap)
233  {
234  this->wrap = wrap;
235  }
236 
237  void parse(const TextAsset& asset, uint32_t start, size_t size);
238 
239 private:
240  void newLine()
241  {
242  curSeg = breakSeg = lineSeg = nullptr;
243  textHeight += lineHeight;
244  cursor.y += lineHeight;
245  breakIndex = lineHeight = 0;
246  }
247 
248  void endRun()
249  {
250  curSeg = breakSeg = lineSeg = startSeg = nullptr;
251  breakIndex = lineHeight = textHeight = ystart = 0;
252  overflow = false;
253  }
254 
255  void addTextSegment(Point textpos, uint16_t endx, const TextAsset& asset, uint16_t start, uint8_t length);
256 
257  Rect bounds;
258  Rect clip;
259  uint32_t breakIndex{0};
260  const TextAsset* curAsset{nullptr};
261  TextObject::FontElement* curFont{nullptr};
262  TextObject::ColorElement* curColor{nullptr};
263  TextObject::RunElement* breakSeg{nullptr};
264  uint16_t breakx{0};
265  uint8_t breakw{0};
266  char breakChar{'\0'};
267  std::unique_ptr<TextObject> object;
268  bool wrap{true};
269  bool overflow{false};
270  mutable const Font* font{nullptr};
271  mutable const TypeFace* typeface{nullptr};
272  TextOptions options{};
273  uint16_t lineHeight{0};
274  uint16_t textHeight{0};
275  uint16_t ystart{0};
276  TextObject::RunElement* startSeg{nullptr}; // First segment in block
277  TextObject::RunElement* lineSeg{nullptr}; // First segment on this line
278  TextObject::RunElement* curSeg{nullptr}; // Current segment on this line
279  Align textAlign{};
280  Align lineAlign{};
281  Point cursor{};
282  static Font* defaultFont;
283 };
284 
288 class TextBuilder : public TextParser, public Print
289 {
290 public:
291  TextBuilder(AssetList& assets, const Rect& bounds)
292  : TextParser(bounds), stream(new MemoryDataStream), text(*new TextAsset(stream))
293  {
294  assets.add(&text);
295  resetClip();
296  }
297 
298  TextBuilder(SceneObject& scene) : TextBuilder(scene.assets, scene.getSize())
299  {
300  }
301 
302  using Print::write;
303 
304  size_t write(uint8_t c) override
305  {
306  return write(&c, 1);
307  }
308 
309  size_t write(const uint8_t* buffer, size_t size) override
310  {
311  auto pos = text.getLength();
312  stream->write(buffer, size);
313  parse(text, pos, size);
314  return size;
315  }
316 
317 private:
318  MemoryDataStream* stream;
319  TextAsset& text;
320 };
321 
322 } // namespace Graphics
Definition: Asset.h:753
The source of colour for drawing.
Definition: Asset.h:253
Base class for a loaded font.
Definition: Asset.h:572
Definition: Libraries/Graphics/src/include/Graphics/Types.h:733
constexpr uint8_t scaleY() const
Definition: Libraries/Graphics/src/include/Graphics/Types.h:772
A Scene containing multiple objects.
Definition: Scene.h:32
T * addObject(T *obj)
Add a new object to the scene.
Definition: Scene.h:70
Definition: Asset.h:666
size_t getLength() const
Definition: Asset.h:701
Simplifies construction of TextObject instances.
Definition: TextBuilder.h:289
size_t write(uint8_t c) override
Writes a single character to output stream.
Definition: TextBuilder.h:304
TextBuilder(SceneObject &scene)
Definition: TextBuilder.h:298
virtual size_t write(uint8_t c)=0
Writes a single character to output stream.
size_t write(const uint8_t *buffer, size_t size) override
Writes characters from a buffer to output stream.
Definition: TextBuilder.h:309
TextBuilder(AssetList &assets, const Rect &bounds)
Definition: TextBuilder.h:291
A block of text consisting of zero or more segments.
Definition: Libraries/Graphics/src/include/Graphics/Object.h:902
Definition: Asset.h:453
Brush back
Definition: Asset.h:456
FontStyles style
Definition: Asset.h:458
Brush fore
Definition: Asset.h:455
Scale scale
Definition: Asset.h:457
Simplifies construction of TextObject instances.
Definition: TextBuilder.h:33
static void setDefaultFont(Font *font)
Definition: TextBuilder.h:59
Align getTextAlign() const
Definition: TextBuilder.h:143
const Rect & getBounds() const
Definition: TextBuilder.h:40
void setScale(Scale scale)
Definition: TextBuilder.h:86
void setFont(const Font &font)
Definition: TextBuilder.h:77
void setClip(const Rect &r)
Definition: TextBuilder.h:213
TextParser(const Rect &bounds)
Definition: TextBuilder.h:35
Point getCursor() const
Definition: TextBuilder.h:161
void setCursor(int16_t x, int16_t y)
Definition: TextBuilder.h:177
void setForeColor(const Brush &color)
Definition: TextBuilder.h:203
void moveCursor(Point offset)
Definition: TextBuilder.h:182
void setScale(uint8_t size)
Definition: TextBuilder.h:100
void resetClip()
Definition: TextBuilder.h:225
void moveCursor(int16_t x, int16_t y)
Definition: TextBuilder.h:187
void addStyle(FontStyles style)
Definition: TextBuilder.h:125
const Font & getFont() const
void setStyle(FontStyles style)
Definition: TextBuilder.h:115
void setBackColor(const Brush &color)
Definition: TextBuilder.h:208
void setScale(uint8_t sx, uint8_t sy)
Definition: TextBuilder.h:95
uint16_t getTextHeight() const
Definition: TextBuilder.h:105
void parse(const TextAsset &asset, uint32_t start, size_t size)
void removeStyle(FontStyles style)
Definition: TextBuilder.h:130
const TextOptions & getOptions() const
Definition: TextBuilder.h:110
Align getLineAlign() const
Definition: TextBuilder.h:156
void setTextAlign(Align align)
Definition: TextBuilder.h:135
TextObject * commit(SceneObject &scene)
Definition: TextBuilder.h:54
const TypeFace & getTypeFace() const
const Rect & getClip() const
Definition: TextBuilder.h:220
void setWrap(bool wrap)
Definition: TextBuilder.h:232
void setFont(const Font *font)
Definition: TextBuilder.h:64
TextObject * release()
Definition: TextBuilder.h:45
void setColor(const Brush &fore, const Brush &back={})
Definition: TextBuilder.h:192
void setLineAlign(Align align)
Definition: TextBuilder.h:148
void setCursor(Point pt)
Set location to start new text segment.
Definition: TextBuilder.h:169
Base class for a loaded typeface, e.g. Sans 16pt bold.
Definition: Asset.h:506
bool add(ObjectType *object)
Definition: LinkedObjectList.h:134
Read/write stream using expandable memory buffer.
Definition: MemoryDataStream.h:27
size_t write(const uint8_t *buffer, size_t size) override
Write chars to end of stream.
Provides formatted output to stream.
Definition: Print.h:37
virtual size_t write(uint8_t c)=0
Writes a single character to output stream.
Definition: Virtual.h:31
Rect intersect(Rect r1, const Rect &r2)
Definition: Libraries/Graphics/src/include/Graphics/Types.h:582
Align
Definition: Libraries/Graphics/src/include/Graphics/Types.h:55
TPoint< int16_t > Point
Definition: Libraries/Graphics/src/include/Graphics/Types.h:280
Location and size of rectangular area (x, y, w, h)
Definition: Libraries/Graphics/src/include/Graphics/Types.h:287
Size size() const
Definition: Libraries/Graphics/src/include/Graphics/Types.h:447
T y
Definition: Libraries/Graphics/src/include/Graphics/Types.h:135