Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
DrawingState.cs
1using SkiaSharp;
2using System;
3using System.Collections.Generic;
5using Waher.Script;
6
8{
12 public delegate string ElementToString(ILayoutElement Element);
13
17 public class DrawingState : IDisposable
18 {
19 private Dictionary<ILayoutElement, bool> relativeElements = null;
20 private readonly Variables session;
21 private readonly SKPaint textRoot;
22 private readonly SKPaint defaultPen;
23 private SKCanvas canvas;
24 private SKPaint shapePen;
25 private SKPaint shapeFill;
26 private SKFont font;
27 private SKPaint text;
28 private float? width_0;
29 private float? height_x;
30 private SKSize areaSize;
31 private SKSize viewportSize;
32 private readonly float pixelsPerInch;
33 private bool logRelativeElements = false;
34
41 public DrawingState(SKCanvas Canvas, RenderSettings Settings, Variables Session)
42 {
43 this.canvas = Canvas;
44 this.session = Session;
45 this.pixelsPerInch = Settings.PixelsPerInch;
46 this.areaSize = this.viewportSize = new SKSize(Settings.Width, Settings.Height);
47
48 this.font = new SKFont()
49 {
50 Edging = SKFontEdging.SubpixelAntialias,
51 Hinting = SKFontHinting.Full,
52 Subpixel = true,
53 Size = (float)(Settings.FontSize * this.pixelsPerInch / 72),
54 Typeface = SKTypeface.FromFamilyName(Settings.FontName, SKFontStyle.Normal)
55 };
56
57 this.text = this.textRoot = new SKPaint()
58 {
59 FilterQuality = SKFilterQuality.High,
60 HintingLevel = SKPaintHinting.Full,
61 SubpixelText = true,
62 IsAntialias = true,
63 Style = SKPaintStyle.Fill,
64 Color = Settings.TextColor,
65 Typeface = this.font.Typeface,
66 TextSize = this.font.Size
67 };
68
69 this.defaultPen = new SKPaint()
70 {
71 FilterQuality = SKFilterQuality.High,
72 IsAntialias = true,
73 Style = SKPaintStyle.Stroke,
74 Color = Settings.PenColor
75 };
76 }
77
81 public void Dispose()
82 {
83 this.text?.Dispose();
84 this.font?.Dispose();
85 this.defaultPen?.Dispose();
86 }
87
91 public Variables Session => this.session;
92
96 public float PixelsPerInch => this.pixelsPerInch;
97
101 public SKCanvas Canvas
102 {
103 get => this.canvas;
104 internal set => this.canvas = value;
105 }
106
110 public SKPaint Text
111 {
112 get => this.text;
113 set => this.text = value;
114 }
115
119 public SKFont Font
120 {
121 get => this.font;
122 set => this.font = value;
123 }
124
128 public SKPaint DefaultPen => this.defaultPen;
129
133 public SKPaint ShapePen
134 {
135 get => this.shapePen;
136 set => this.shapePen = value;
137 }
138
142 public SKPaint ShapeFill
143 {
144 get => this.shapeFill;
145 set => this.shapeFill = value;
146 }
147
151 public float AreaWidth => this.areaSize.Width;
152
156 public float AreaHeight => this.areaSize.Height;
157
165 public void CalcDrawingSize(Length L, ref float Size, bool Horizontal, ILayoutElement Element)
166 {
167 switch (L.Unit)
168 {
169 // pixels (1px = 1/96th of 1in) (absolute)
170 case LengthUnit.Px:
171 Size = L.Value * this.pixelsPerInch / 96;
172 break;
173
174 // points (1pt = 1/72 of 1in) (absolute)
175 case LengthUnit.Pt:
176 Size = L.Value * this.pixelsPerInch / 72;
177 break;
178
179 // picas (1pc = 12 pt) (absolute)
180 case LengthUnit.Pc:
181 Size = L.Value * this.pixelsPerInch / 12;
182 break;
183
184 // centimeters (absolute)
185 case LengthUnit.Cm:
186 Size = L.Value * this.pixelsPerInch / 2.54f;
187 break;
188
189 // inches (1in = 96px = 2.54cm)
190 case LengthUnit.In:
191 Size = L.Value * this.pixelsPerInch;
192 break;
193
194 // millimeters (absolute)
195 case LengthUnit.Mm:
196 Size = L.Value * this.pixelsPerInch / 25.4f;
197 break;
198
199 // Relative to the font-size of the element (2em means 2 times the size of the current font)
200 case LengthUnit.Em:
201 float Size2 = L.Value * this.text.TextSize;
202 if (Size != Size2)
203 {
204 this.ReportMeasureRelative(Element);
205 Size = Size2;
206 }
207 break;
208
209 // Relative to the x-height of the current font (rarely used)
210 case LengthUnit.Ex:
211 if (!this.height_x.HasValue)
212 {
213 SKRect Bounds = new SKRect();
214 this.text.MeasureText("x", ref Bounds);
215 this.height_x = Bounds.Height;
216 }
217
218 Size2 = L.Value * this.height_x.Value;
219 if (Size != Size2)
220 {
221 this.ReportMeasureRelative(Element);
222 Size = Size2;
223 }
224 break;
225
226 // Relative to the width of the "0" (zero)
227 case LengthUnit.Ch:
228 if (!this.width_0.HasValue)
229 this.width_0 = this.text.MeasureText("0");
230
231 Size2 = L.Value * this.width_0.Value;
232 if (Size != Size2)
233 {
234 this.ReportMeasureRelative(Element);
235 Size = Size2;
236 }
237 break;
238
239 // Relative to font-size of the root element
240 case LengthUnit.Rem:
241 Size2 = L.Value * this.textRoot.TextSize;
242 if (Size != Size2)
243 {
244 this.ReportMeasureRelative(Element);
245 Size = Size2;
246 }
247 break;
248
249 // Relative to 1% of the width of the viewport
250 case LengthUnit.Vw:
251 Size2 = L.Value * this.viewportSize.Width / 100;
252 if (Size != Size2)
253 {
254 this.ReportMeasureRelative(Element);
255 Size = Size2;
256 }
257 break;
258
259 // Relative to 1% of the height of the viewport
260 case LengthUnit.Vh:
261 Size2 = L.Value * this.viewportSize.Height / 100;
262 if (Size != Size2)
263 {
264 this.ReportMeasureRelative(Element);
265 Size = Size2;
266 }
267 break;
268
269 // Relative to 1% of viewport's* smaller dimension
270 case LengthUnit.Vmin:
271 if (this.viewportSize.Width < this.viewportSize.Height)
272 Size2 = L.Value * this.viewportSize.Width / 100;
273 else
274 Size2 = L.Value * this.viewportSize.Height / 100;
275
276 if (Size != Size2)
277 {
278 this.ReportMeasureRelative(Element);
279 Size = Size2;
280 }
281 break;
282
283 // Relative to 1% of viewport's* larger dimension
284 case LengthUnit.Vmax:
285 if (this.viewportSize.Width > this.viewportSize.Height)
286 Size2 = L.Value * this.viewportSize.Width / 100;
287 else
288 Size2 = L.Value * this.viewportSize.Height / 100;
289
290 if (Size != Size2)
291 {
292 this.ReportMeasureRelative(Element);
293 Size = Size2;
294 }
295 break;
296
297 // Relative to the parent element
298 case LengthUnit.Percent:
299 if (Horizontal)
300 Size2 = L.Value * this.areaSize.Width / 100;
301 else
302 Size2 = L.Value * this.areaSize.Height / 100;
303
304 if (Size != Size2)
305 {
306 this.ReportMeasureRelative(Element);
307 Size = Size2;
308 }
309 break;
310
311 default:
312 Size = L.Value;
313 break;
314 }
315 }
316
322 public SKSize SetAreaSize(SKSize AreaSize)
323 {
324 SKSize Prev = this.areaSize;
325 this.areaSize = AreaSize;
326 return Prev;
327 }
328
335 {
336 if (Font is null)
337 return null;
338 else
339 return new FontState(Font.Text, Font.FontDef);
340 }
341
347 {
348 if (!(FontState is null))
349 {
350 this.text = FontState.Paint;
351 this.font = FontState.Font;
352 }
353 }
354
358 public bool MeasureRelative
359 {
360 get;
361 private set;
362 }
363
367 public IEnumerable<ILayoutElement> RelativeElements => this.relativeElements.Keys;
368
373 {
374 this.MeasureRelative = true;
375 if (this.logRelativeElements)
376 this.relativeElements[Element] = true;
377 }
378
383 public void ClearRelativeMeasurement(bool LogRelativeElements)
384 {
385 this.MeasureRelative = false;
386 this.logRelativeElements = LogRelativeElements;
387 if (this.logRelativeElements)
388 {
389 if (this.relativeElements is null)
390 this.relativeElements = new Dictionary<ILayoutElement, bool>();
391 else
392 this.relativeElements.Clear();
393 }
394 }
395
400 public string GetShortestRelativeMeasurement(ElementToString Map)
401 {
402 string Best = string.Empty;
403 int BestLen = int.MaxValue;
404
405 foreach (ILayoutElement Element in this.relativeElements.Keys)
406 {
407 string Item = Map(Element);
408 int Len = Item.Length;
409
410 if (Len < BestLen)
411 {
412 Best = Item;
413 BestLen = Len;
414 }
415 }
416
417 return Best;
418 }
419
424 {
425 return this.GetShortestRelativeMeasurement((E) => E.ToXml());
426 }
427
432 {
433 return this.GetShortestRelativeMeasurement((E) => E.ExportState());
434 }
435 }
436}
Contains information about an actionable area in a generated image.
Definition: Map.cs:7
SKPaint Text
Current text paint settings
SKCanvas Canvas
Current drawing canvas.
void Restore(FontState FontState)
Restores font settings, from a previous call to Push
float AreaWidth
Width of current area
FontState Push(Font Font)
Pushes new font settings.
float AreaHeight
Height of current area
SKSize SetAreaSize(SKSize AreaSize)
Sets the current area size.
string GetShortestRelativeMeasurement(ElementToString Map)
Gets the shortest relative measurements element, given an element to string mapping.
Variables Session
Current session.
Definition: DrawingState.cs:91
string GetShortestRelativeMeasurementXml()
Gets the shortest subtree XML of an element with relative measurements.
IEnumerable< ILayoutElement > RelativeElements
Relative elements.
SKPaint ShapeFill
Fill to use for shape, if no other is specified in the shape.
void Dispose()
IDisposable.Dispose
Definition: DrawingState.cs:81
DrawingState(SKCanvas Canvas, RenderSettings Settings, Variables Session)
Current drawing state.
Definition: DrawingState.cs:41
SKPaint ShapePen
Pen to use for shape, if no other is specified in the shape.
void ReportMeasureRelative(ILayoutElement Element)
Reports an element as having relative measurements.
void CalcDrawingSize(Length L, ref float Size, bool Horizontal, ILayoutElement Element)
Converts a defined length to drawing size.
string GetShortestRelativeMeasurementStateXml()
Gets the shortest subtree State XML of an element with relative measurements.
void ClearRelativeMeasurement(bool LogRelativeElements)
Clears information about first relative measurement.
bool MeasureRelative
If layout contains relative sizes and dimensions should be recalculated.
Drawing state for text.
Definition: FontState.cs:9
Abstract base class for fonts.
Definition: Font.cs:12
SKFont FontDef
Measured Font
Definition: Font.cs:245
SKPaint Text
Measured Text
Definition: Font.cs:250
LengthUnit Unit
Unit of length.
Definition: Length.cs:113
float Value
Value of length
Definition: Length.cs:104
float PixelsPerInch
Pixels per inch (default=96 pixels/inch)
float FontSize
Font size, in points
Collection of variables.
Definition: Variables.cs:25
Base interface for all layout elements.
LengthUnit
Unit of length
Definition: Length.cs:7
delegate string ElementToString(ILayoutElement Element)
Delegate to methods that return a string from a layout element.