/// <summary> /// Create an anti-inversion transform from the inversion flags. /// The result is used to correct glyph bitmap on an output to /// a drawing surface with the specified inversions applied on. /// </summary> internal static MatrixTransform CreateAntiInversionTransform( InvertAxes inversion, double paragraphWidth, double lineHeight ) { if (inversion == InvertAxes.None) { // avoid creating unncessary pressure on GC when anti-transform is not needed. return(null); } double m11 = 1; double m22 = 1; double offsetX = 0; double offsetY = 0; if ((inversion & InvertAxes.Horizontal) != 0) { m11 = -m11; offsetX = paragraphWidth; } if ((inversion & InvertAxes.Vertical) != 0) { m22 = -m22; offsetY = lineHeight; } return(new MatrixTransform(m11, 0, 0, m22, offsetX, offsetY)); }
public override void Draw(DrawingContext drawingContext, Point origin, InvertAxes inversion) { foreach (var entry in entries) { if (entry.Item2 == null) { continue; } if (entry.Item3 == entry.Item1.Length) // All whitespace, no need to render { continue; } var textRun = entry.Item1; var glyphRun = entry.Item2; var textProps = textRun.Properties; var newRun = Clone(glyphRun, new Point { X = origin.X + glyphRun.BaselineOrigin.X, Y = (int)(origin.Y + glyphRun.GlyphTypeface.Baseline * textProps.FontRenderingEmSize) }); if (_textFormattingMode != null) { _textFormattingMode.SetValue(glyphRun, mode); } var box = newRun.ComputeAlignmentBox(); if (textProps.BackgroundBrush != null) { drawingContext.DrawRectangle( textProps.BackgroundBrush, null, new Rect(origin, box.Size)); } drawingContext.DrawGlyphRun(textProps.ForegroundBrush, newRun); if (textProps.TextDecorations != null) { foreach (var deco in textProps.TextDecorations) { var thickness = Math.Round(glyphRun.GlyphTypeface.UnderlineThickness * textProps.FontRenderingEmSize); var pos = glyphRun.GlyphTypeface.UnderlinePosition - glyphRun.GlyphTypeface.Baseline + glyphRun.GlyphTypeface.Height; pos = Math.Round(pos * textProps.FontRenderingEmSize) + thickness / 2; var pen = new Pen(textProps.ForegroundBrush, thickness); drawingContext.DrawLine(pen, new Point(newRun.BaselineOrigin.X, newRun.BaselineOrigin.Y + pos), new Point(newRun.BaselineOrigin.X + box.Width, newRun.BaselineOrigin.Y + pos)); } } } }
public override void Draw(DrawingContext drawingContext, Point origin, InvertAxes inversion) { if (drawingContext == null) { throw new ArgumentNullException("drawingContext"); } if ((_statusFlags & StatusFlags.IsDisposed) != 0) { throw new ObjectDisposedException(SR.Get(SRID.TextLineHasBeenDisposed)); } MatrixTransform antiInversion = TextFormatterImp.CreateAntiInversionTransform( inversion, _metrics._formatter.IdealToReal(_paragraphWidth, PixelsPerDip), _metrics._formatter.IdealToReal(_metrics._height, PixelsPerDip) ); origin = AdjustOffset(origin); if (antiInversion == null) { DrawTextLine(drawingContext, origin, null); } else { // Apply anti-inversion transform to correct the visual drawingContext.PushTransform(antiInversion); try { DrawTextLine(drawingContext, origin, antiInversion); } finally { drawingContext.Pop(); } } }
/// <summary> /// Client to draw the line /// </summary> /// <param name="drawingContext">drawing context</param> /// <param name="origin">drawing origin</param> /// <param name="inversion">indicate the inversion of the drawing surface</param> public abstract void Draw( DrawingContext drawingContext, Point origin, InvertAxes inversion );
/// <summary> /// Draw line /// </summary> /// <param name="drawingContext">drawing context</param> /// <param name="origin">drawing origin</param> /// <param name="inversion">indicate the inversion of the drawing surface</param> public override void Draw( DrawingContext drawingContext, Point origin, InvertAxes inversion ) { if (drawingContext == null) { throw new ArgumentNullException("drawingContext"); } if ((_statusFlags & StatusFlags.IsDisposed) != 0) { throw new ObjectDisposedException(SR.Get(SRID.TextLineHasBeenDisposed)); } MatrixTransform antiInversion = TextFormatterImp.CreateAntiInversionTransform( inversion, _metrics._formatter.IdealToReal(_paragraphWidth), _metrics._formatter.IdealToReal(_metrics._height) ); if (antiInversion == null) { DrawTextLine(drawingContext, origin, null); } else { // Apply anti-inversion transform to correct the visual drawingContext.PushTransform(antiInversion); try { DrawTextLine(drawingContext, origin, antiInversion); } finally { drawingContext.Pop(); } } }
/// <summary> /// Draw line /// </summary> /// <param name="drawingContext">drawing context</param> /// <param name="origin">drawing origin</param> /// <param name="inversion">indicate the inversion of the drawing surface</param> public override void Draw( DrawingContext drawingContext, Point origin, InvertAxes inversion ) { if (drawingContext == null) { throw new ArgumentNullException("drawingContext"); } MatrixTransform antiInversion = TextFormatterImp.CreateAntiInversionTransform( inversion, _paragraphWidth, _height ); if (antiInversion == null) { DrawTextLine(drawingContext, origin); } else { // Apply anti-inversion transform to correct the visual drawingContext.PushTransform(antiInversion); try { DrawTextLine(drawingContext, origin); } finally { drawingContext.Pop(); } } }
/// <summary> /// Create an anti-inversion transform from the inversion flags. /// The result is used to correct glyph bitmap on an output to /// a drawing surface with the specified inversions applied on. /// </summary> internal static MatrixTransform CreateAntiInversionTransform( InvertAxes inversion, double paragraphWidth, double lineHeight ) { if (inversion == InvertAxes.None) { // avoid creating unncessary pressure on GC when anti-transform is not needed. return null; } double m11 = 1; double m22 = 1; double offsetX = 0; double offsetY = 0; if ((inversion & InvertAxes.Horizontal) != 0) { m11 = -m11; offsetX = paragraphWidth; } if ((inversion & InvertAxes.Vertical) != 0) { m22 = -m22; offsetY = lineHeight; } return new MatrixTransform(m11, 0, 0, m22, offsetX, offsetY); }
public abstract void Draw(System.Windows.Media.DrawingContext drawingContext, System.Windows.Point origin, InvertAxes inversion);
public override void Draw(DrawingContext drawingContext, Point origin, InvertAxes inversion) { foreach (var entry in entries) { if (entry.Item2 == null) continue; if (entry.Item3 == entry.Item1.Length) // All whitespace, no need to render continue; var textRun = entry.Item1; var glyphRun = entry.Item2; var textProps = textRun.Properties; var newRun = Clone(glyphRun, new Point { X = origin.X + glyphRun.BaselineOrigin.X, Y = (int)(origin.Y + glyphRun.GlyphTypeface.Baseline * textProps.FontRenderingEmSize) }); if (_textFormattingMode != null) _textFormattingMode.SetValue(glyphRun, mode); var box = newRun.ComputeAlignmentBox(); if (textProps.BackgroundBrush != null) { drawingContext.DrawRectangle( textProps.BackgroundBrush, null, new Rect(origin, box.Size)); } drawingContext.DrawGlyphRun(textProps.ForegroundBrush, newRun); if (textProps.TextDecorations != null) foreach (var deco in textProps.TextDecorations) { var thickness = Math.Round(glyphRun.GlyphTypeface.UnderlineThickness * textProps.FontRenderingEmSize); var pos = glyphRun.GlyphTypeface.UnderlinePosition - glyphRun.GlyphTypeface.Baseline + glyphRun.GlyphTypeface.Height; pos = Math.Round(pos * textProps.FontRenderingEmSize) + thickness / 2; var pen = new Pen(textProps.ForegroundBrush, thickness); drawingContext.DrawLine(pen, new Point(newRun.BaselineOrigin.X, newRun.BaselineOrigin.Y + pos), new Point(newRun.BaselineOrigin.X + box.Width, newRun.BaselineOrigin.Y + pos)); } } }