19 using System.Collections.Generic;
22 using static System.Net.Mime.MediaTypeNames;
26 public partial class Graphics
39 Actions.Add(
new TextAction(origin, text, font, textBaseline, fillColour,
null, 0,
LineCaps.Butt,
LineJoins.Miter,
LineDash.
SolidLine, tag));
59 Actions.Add(
new TextAction(
new Point(originX, originY), text, font, textBaseline, fillColour,
null, 0,
LineCaps.Butt,
LineJoins.Miter,
LineDash.
SolidLine, tag));
82 Actions.Add(
new TextAction(origin, text, font, textBaseline,
null, strokeColour, lineWidth, lineCap, lineJoin, lineDash ??
LineDash.
SolidLine, tag));
86 StrokeTextUnderline(origin, text, font, strokeColour, textBaseline, lineWidth, lineCap, lineJoin, lineDash, tag);
104 public void StrokeText(
double originX,
double originY,
string text,
Font font,
Brush strokeColour,
TextBaselines textBaseline =
TextBaselines.Top,
double lineWidth = 1,
LineCaps lineCap =
LineCaps.Butt,
LineJoins lineJoin =
LineJoins.Miter,
LineDash? lineDash =
null,
string tag =
null)
106 Actions.Add(
new TextAction(
new Point(originX, originY), text, font, textBaseline,
null, strokeColour, lineWidth, lineCap, lineJoin, lineDash ??
LineDash.
SolidLine, tag));
110 StrokeTextUnderline(originX, originY, text, font, strokeColour, textBaseline, lineWidth, lineCap, lineJoin, lineDash, tag);
132 double currDelta = 0;
142 currDelta = -fullMetrics.
Width * 0.5 / pathLength;
145 currDelta = -fullMetrics.Width / pathLength;
149 Point currentGlyphPlacementDelta =
new Point();
154 for (
int i = 0; i < text.Length; i++)
156 string c = text.Substring(i, 1);
160 currentGlyphPlacementDelta = nextGlyphPlacementDelta;
161 currentGlyphAdvanceDelta = nextGlyphAdvanceDelta;
162 nextGlyphAdvanceDelta =
new Point();
163 nextGlyphPlacementDelta =
new Point();
169 currentGlyphPlacementDelta =
new Point(currentGlyphPlacementDelta.
X + kerning.Glyph1Placement.X, currentGlyphPlacementDelta.
Y + kerning.Glyph1Placement.Y);
170 currentGlyphAdvanceDelta =
new Point(currentGlyphAdvanceDelta.
X + kerning.Glyph1Advance.X, currentGlyphAdvanceDelta.
Y + kerning.Glyph1Advance.Y);
172 nextGlyphPlacementDelta =
new Point(nextGlyphPlacementDelta.
X + kerning.Glyph2Placement.X, nextGlyphPlacementDelta.
Y + kerning.Glyph2Placement.Y);
173 nextGlyphAdvanceDelta =
new Point(nextGlyphAdvanceDelta.
X + kerning.Glyph2Advance.X, nextGlyphAdvanceDelta.
Y + kerning.Glyph2Advance.Y);
181 Point tangent = path.
GetTangentAtRelative(reference + currDelta + currentGlyphPlacementDelta.
X * font.
FontSize / 1000 + (metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing) / pathLength * 0.5);
183 origin =
new Point(origin.
X - tangent.
Y * currentGlyphPlacementDelta.
Y * font.
FontSize / 1000, origin.
Y + tangent.
X * currentGlyphPlacementDelta.
Y * font.
FontSize / 1000);
188 this.
Rotate(Math.Atan2(tangent.
Y, tangent.
X));
190 switch (textBaseline)
195 this.
FillText(
new Point(metrics.LeftSideBearing, fullMetrics.Top), c, font, fillColour, textBaseline:
TextBaselines.Baseline, tag);
215 this.
FillText(
new Point(metrics.LeftSideBearing, fullMetrics.Bottom), c, font, fillColour, textBaseline:
TextBaselines.Baseline, tag);
225 this.
FillText(
new Point(metrics.LeftSideBearing, fullMetrics.Bottom + fullMetrics.Height / 2), c, font, fillColour, textBaseline:
TextBaselines.Baseline, tag);
229 this.
FillText(
new Point(0, fullMetrics.Bottom + fullMetrics.Height / 2), c, font, fillColour, textBaseline:
TextBaselines.Baseline, tag);
238 currDelta += (metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing + currentGlyphAdvanceDelta.
X * font.
FontSize / 1000) / pathLength;
242 currDelta += (metrics.Width + metrics.RightSideBearing + currentGlyphAdvanceDelta.
X * font.
FontSize / 1000) / pathLength;
262 public void StrokeTextOnPath(
GraphicsPath path,
string text,
Font font,
Brush strokeColour,
double reference = 0,
TextAnchors anchor =
TextAnchors.Left,
TextBaselines textBaseline =
TextBaselines.Top,
double lineWidth = 1,
LineCaps lineCap =
LineCaps.Butt,
LineJoins lineJoin =
LineJoins.Miter,
LineDash? lineDash =
null,
string tag =
null)
269 double currDelta = 0;
279 currDelta = -fullMetrics.
Width * 0.5 / pathLength;
282 currDelta = -fullMetrics.Width / pathLength;
286 Point currentGlyphPlacementDelta =
new Point();
291 for (
int i = 0; i < text.Length; i++)
293 string c = text.Substring(i, 1);
297 currentGlyphPlacementDelta = nextGlyphPlacementDelta;
298 currentGlyphAdvanceDelta = nextGlyphAdvanceDelta;
299 nextGlyphAdvanceDelta =
new Point();
300 nextGlyphPlacementDelta =
new Point();
306 currentGlyphPlacementDelta =
new Point(currentGlyphPlacementDelta.
X + kerning.Glyph1Placement.X, currentGlyphPlacementDelta.
Y + kerning.Glyph1Placement.Y);
307 currentGlyphAdvanceDelta =
new Point(currentGlyphAdvanceDelta.
X + kerning.Glyph1Advance.X, currentGlyphAdvanceDelta.
Y + kerning.Glyph1Advance.Y);
309 nextGlyphPlacementDelta =
new Point(nextGlyphPlacementDelta.
X + kerning.Glyph2Placement.X, nextGlyphPlacementDelta.
Y + kerning.Glyph2Placement.Y);
310 nextGlyphAdvanceDelta =
new Point(nextGlyphAdvanceDelta.
X + kerning.Glyph2Advance.X, nextGlyphAdvanceDelta.
Y + kerning.Glyph2Advance.Y);
318 Point tangent = path.
GetTangentAtRelative(reference + currDelta + currentGlyphPlacementDelta.
X * font.
FontSize / 1000 + (metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing) / pathLength * 0.5);
320 origin =
new Point(origin.
X - tangent.
Y * currentGlyphPlacementDelta.
Y * font.
FontSize / 1000, origin.
Y + tangent.
X * currentGlyphPlacementDelta.
Y * font.
FontSize / 1000);
325 this.
Rotate(Math.Atan2(tangent.
Y, tangent.
X));
327 switch (textBaseline)
332 this.
StrokeText(
new Point(metrics.LeftSideBearing, fullMetrics.Top), c, font, strokeColour, textBaseline:
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
336 this.
StrokeText(
new Point(0, fullMetrics.Top), c, font, strokeColour, textBaseline:
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
342 this.
StrokeText(
new Point(metrics.LeftSideBearing, 0), c, font, strokeColour, textBaseline:
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
346 this.
StrokeText(
new Point(0, 0), c, font, strokeColour, textBaseline:
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
352 this.
StrokeText(
new Point(metrics.LeftSideBearing, fullMetrics.Bottom), c, font, strokeColour, textBaseline:
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
356 this.
StrokeText(
new Point(0, fullMetrics.Bottom), c, font, strokeColour, textBaseline:
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
362 this.
StrokeText(
new Point(metrics.LeftSideBearing, fullMetrics.Bottom + fullMetrics.Height / 2), c, font, strokeColour, textBaseline:
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
366 this.
StrokeText(
new Point(0, fullMetrics.Bottom + fullMetrics.Height / 2), c, font, strokeColour, textBaseline:
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
375 currDelta += (metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing + currentGlyphAdvanceDelta.
X * font.
FontSize / 1000) / pathLength;
379 currDelta += (metrics.Width + metrics.RightSideBearing + currentGlyphAdvanceDelta.
X * font.
FontSize / 1000) / pathLength;
394 List<FormattedText> enumeratedText =
new List<FormattedText>();
399 Point baselineOrigin = origin;
401 switch (textBaseline)
404 baselineOrigin = origin;
407 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Top);
410 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Bottom);
413 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Top * 0.5 + fullMetrics.Bottom * 0.5);
417 for (
int i = 0; i < enumeratedText.Count; i++)
436 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing, baselineOrigin.
Y);
440 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing, baselineOrigin.
Y);
451 baselineOrigin =
new Point(baselineOrigin.
X - metrics.LeftSideBearing, baselineOrigin.
Y);
466 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing, baselineOrigin.
Y);
470 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing, baselineOrigin.
Y);
487 FillText(
new Point(originX, originY), text, fillColour, textBaseline, tag);
504 List<FormattedText> enumeratedText =
new List<FormattedText>();
509 Point baselineOrigin = origin;
511 switch (textBaseline)
514 baselineOrigin = origin;
517 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Top);
520 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Bottom);
523 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Top * 0.5 + fullMetrics.Bottom * 0.5);
527 for (
int i = 0; i < enumeratedText.Count; i++)
537 StrokeText(baselineOrigin.
X + metrics.LeftSideBearing, baselineOrigin.
Y, txt.
Text, txt.
Font, txt.
Brush ?? strokeColour,
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
546 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing, baselineOrigin.
Y);
550 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing, baselineOrigin.
Y);
561 baselineOrigin =
new Point(baselineOrigin.
X - metrics.LeftSideBearing, baselineOrigin.
Y);
566 StrokeText(baselineOrigin.
X + metrics.LeftSideBearing, baselineOrigin.
Y + txt.
Font.
FontSize * 0.14, txt.
Text, newFont, txt.
Brush ?? strokeColour,
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
570 StrokeText(baselineOrigin.
X + metrics.LeftSideBearing, baselineOrigin.
Y - txt.
Font.
FontSize * 0.33, txt.
Text, newFont, txt.
Brush ?? strokeColour,
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
576 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing, baselineOrigin.
Y);
580 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing, baselineOrigin.
Y);
601 StrokeText(
new Point(originX, originY), text, strokeColour, textBaseline, lineWidth, lineCap, lineJoin, lineDash, tag);
626 return new Size(metrics.Width, metrics.Height);
656 FillPath(underline, fillColour, tag);
673 public void StrokeTextUnderline(
double originX,
double originY,
string text,
Font font,
Brush strokeColour,
TextBaselines textBaseline =
TextBaselines.Top,
double lineWidth = 1,
LineCaps lineCap =
LineCaps.Butt,
LineJoins lineJoin =
LineJoins.Miter,
LineDash? lineDash =
null,
string tag =
null)
675 StrokeTextUnderline(
new Point(originX, originY), text, font, strokeColour, textBaseline, lineWidth, lineCap, lineJoin, lineDash, tag);
694 StrokePath(underline, strokeColour, lineWidth, lineCap, lineJoin, lineDash, tag);
722 List<FormattedText> enumeratedText =
new List<FormattedText>();
727 Point baselineOrigin = origin;
729 switch (textBaseline)
732 baselineOrigin = origin;
735 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Top);
738 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Bottom);
741 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Top * 0.5 + fullMetrics.Bottom * 0.5);
745 for (
int i = 0; i < enumeratedText.Count; i++)
764 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing, baselineOrigin.
Y);
768 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing, baselineOrigin.
Y);
779 baselineOrigin =
new Point(baselineOrigin.
X - metrics.LeftSideBearing, baselineOrigin.
Y);
794 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing, baselineOrigin.
Y);
798 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing, baselineOrigin.
Y);
819 StrokeTextUnderline(
new Point(originX, originY), text, strokeColour, textBaseline, lineWidth, lineCap, lineJoin, lineDash, tag);
836 List<FormattedText> enumeratedText =
new List<FormattedText>();
841 Point baselineOrigin = origin;
843 switch (textBaseline)
846 baselineOrigin = origin;
849 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Top);
852 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Bottom);
855 baselineOrigin =
new Point(origin.
X, origin.
Y + fullMetrics.Top * 0.5 + fullMetrics.Bottom * 0.5);
859 for (
int i = 0; i < enumeratedText.Count; i++)
869 StrokeTextUnderline(baselineOrigin.
X + metrics.LeftSideBearing, baselineOrigin.
Y, txt.
Text, txt.
Font, txt.
Brush ?? strokeColour,
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
878 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing, baselineOrigin.
Y);
882 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing, baselineOrigin.
Y);
893 baselineOrigin =
new Point(baselineOrigin.
X - metrics.LeftSideBearing, baselineOrigin.
Y);
898 StrokeTextUnderline(baselineOrigin.
X + metrics.LeftSideBearing, baselineOrigin.
Y + txt.
Font.
FontSize * 0.14, txt.
Text, newFont, txt.
Brush ?? strokeColour,
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
902 StrokeTextUnderline(baselineOrigin.
X + metrics.LeftSideBearing, baselineOrigin.
Y - txt.
Font.
FontSize * 0.33, txt.
Text, newFont, txt.
Brush ?? strokeColour,
TextBaselines.Baseline, lineWidth, lineCap, lineJoin, lineDash, tag);
908 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing + metrics.LeftSideBearing, baselineOrigin.
Y);
912 baselineOrigin =
new Point(baselineOrigin.
X + metrics.Width + metrics.RightSideBearing, baselineOrigin.
Y);