Browse Source

Implemented DashStyle

pull/131/head
Nelson Carrillo 11 years ago
parent
commit
57e27cb96e
  1. 29
      src/Gtk/Perspex.Cairo/Media/DrawingContext.cs
  2. 2
      src/Perspex.Controls/Shapes/Shape.cs
  3. 84
      src/Perspex.SceneGraph/Media/DashStyle.cs
  4. 47
      src/Perspex.SceneGraph/Media/Pen.cs
  5. 16
      src/Perspex.SceneGraph/Media/PenLineCap.cs
  6. 15
      src/Perspex.SceneGraph/Media/PenLineJoin.cs
  7. 3
      src/Perspex.SceneGraph/Perspex.SceneGraph.csproj
  8. 48
      src/Windows/Perspex.Direct2D1/PrimitiveExtensions.cs

29
src/Gtk/Perspex.Cairo/Media/DrawingContext.cs

@ -2,13 +2,14 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Linq;
using System.Reactive.Disposables;
using Perspex.Cairo.Media.Imaging;
using Perspex.Media;
using IBitmap = Perspex.Media.Imaging.IBitmap;
namespace Perspex.Cairo.Media
{
using Perspex.Media.Imaging;
using Cairo = global::Cairo;
/// <summary>
@ -77,9 +78,9 @@ namespace Perspex.Cairo.Media
public void DrawLine(Pen pen, Point p1, Point p2)
{
var size = new Rect(p1, p2).Size;
SetPen(pen, size);
SetBrush(pen.Brush, size);
_context.LineWidth = pen.Thickness;
_context.MoveTo(p1.ToCairo());
_context.LineTo(p2.ToCairo());
_context.Stroke();
@ -139,9 +140,9 @@ namespace Perspex.Cairo.Media
public void DrawText(Brush foreground, Point origin, FormattedText text)
{
var layout = ((FormattedTextImpl)text.PlatformImpl).Layout;
SetBrush(foreground, new Size(0, 0));
_context.MoveTo(origin.X, origin.Y);
SetBrush(foreground, new Size(0, 0));
Pango.CairoHelper.ShowLayout(_context, layout);
}
@ -195,7 +196,7 @@ namespace Perspex.Cairo.Media
_context.Transform(matrix.Invert().ToCairo());
});
}
private void SetBrush(Brush brush, Size destinationSize)
{
var solid = brush as SolidColorBrush;
@ -225,7 +226,23 @@ namespace Perspex.Cairo.Media
private void SetPen(Pen pen, Size destinationSize)
{
SetBrush(pen.Brush, destinationSize);
if (pen.DashStyle != null)
{
if (pen.DashStyle.Dashes != null && pen.DashStyle.Dashes.Count > 0)
{
var cray = pen.DashStyle.Dashes.ToArray();
_context.SetDash(cray, pen.DashStyle.Offset);
}
}
_context.LineWidth = pen.Thickness;
_context.MiterLimit = pen.MiterLimit;
// Line caps and joins are currently broken on Cairo. I've defaulted them to sensible defaults for now.
// Cairo does not have StartLineCap, EndLineCap, and DashCap properties, whereas Direct2D does.
// TODO: Figure out a solution for this.
_context.LineJoin = Cairo.LineJoin.Miter;
_context.LineCap = Cairo.LineCap.Butt;
}
}
}

2
src/Perspex.Controls/Shapes/Shape.cs

@ -96,7 +96,7 @@ namespace Perspex.Controls.Shapes
if (geometry != null)
{
var pen = new Pen(Stroke, StrokeThickness, StrokeDashArray);
var pen = new Pen(Stroke, StrokeThickness, new DashStyle(StrokeDashArray));
context.DrawGeometry(Fill, pen, geometry);
}
}

84
src/Perspex.SceneGraph/Media/DashStyle.cs

@ -0,0 +1,84 @@
namespace Perspex.Media
{
using Perspex.Animation;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
public class DashStyle : Animatable
{
private static DashStyle dash;
public static DashStyle Dash
{
get
{
if (dashDotDot == null)
{
dash = new DashStyle(new double[] { 2, 2 }, 1);
}
return dash;
}
}
private static DashStyle dot;
public static DashStyle Dot
{
get
{
if (dot == null)
{
dot = new DashStyle(new double[] { 0, 2 }, 0);
}
return dot;
}
}
private static DashStyle dashDot;
public static DashStyle DashDot
{
get
{
if (dashDot == null)
{
dashDot = new DashStyle(new double[] { 2, 2, 0, 2 }, 1);
}
return dashDot;
}
}
private static DashStyle dashDotDot;
public static DashStyle DashDotDot
{
get
{
if (dashDotDot == null)
{
dashDotDot = new DashStyle(new double[] { 2, 2, 0, 2, 0, 2 }, 1);
}
return dashDotDot;
}
}
public DashStyle(IReadOnlyList<double> dashes = null, double offset = 0.0)
{
this.Dashes = dashes;
this.Offset = offset;
}
/// <summary>
/// Gets and sets the length of alternating dashes and gaps.
/// </summary>
public IReadOnlyList<double> Dashes { get; }
public double Offset { get; }
}
}

47
src/Perspex.SceneGraph/Media/Pen.cs

@ -15,12 +15,20 @@ namespace Perspex.Media
/// </summary>
/// <param name="brush">The brush used to draw.</param>
/// <param name="thickness">The stroke thickness.</param>
/// <param name="dashArray">The length of alternating dashes and gaps.</param>
public Pen(Brush brush, double thickness, IReadOnlyList<double> dashArray = null)
public Pen(
Brush brush,
double thickness = 1.0,
DashStyle dashStyle = null, PenLineCap dashCap = PenLineCap.Flat, PenLineCap startLineCap = PenLineCap.Flat,
PenLineCap endLineCap = PenLineCap.Flat, PenLineJoin lineJoin = PenLineJoin.Miter, double miterLimit = 10.0)
{
Brush = brush;
Thickness = thickness;
DashArray = dashArray;
StartLineCap = startLineCap;
EndLineCap = endLineCap;
LineJoin = lineJoin;
MiterLimit = miterLimit;
DashStyle = dashStyle;
DashCap = dashCap;
}
/// <summary>
@ -28,12 +36,20 @@ namespace Perspex.Media
/// </summary>
/// <param name="color">The stroke color.</param>
/// <param name="thickness">The stroke thickness.</param>
/// <param name="dashArray">The length of alternating dashes and gaps.</param>
public Pen(uint color, double thickness, IReadOnlyList<double> dashArray = null)
public Pen(
uint color,
double thickness = 1.0,
DashStyle dashStyle = null, PenLineCap dashCap = PenLineCap.Flat, PenLineCap startLineCap = PenLineCap.Flat,
PenLineCap endLineCap = PenLineCap.Flat, PenLineJoin lineJoin = PenLineJoin.Miter, double miterLimit = 10.0)
{
Brush = new SolidColorBrush(color);
Thickness = thickness;
DashArray = dashArray;
StartLineCap = startLineCap;
EndLineCap = endLineCap;
LineJoin = lineJoin;
MiterLimit = miterLimit;
DashStyle = dashStyle;
DashCap = dashCap;
}
/// <summary>
@ -41,14 +57,21 @@ namespace Perspex.Media
/// </summary>
public Brush Brush { get; }
/// <summary>
/// Gets the length of alternating dashes and gaps.
/// </summary>
public IReadOnlyList<double> DashArray { get; }
/// <summary>
/// Gets the stroke thickness.
/// </summary>
public double Thickness { get; }
public double Thickness { get; } = 1.0;
public DashStyle DashStyle { get; }
public PenLineCap DashCap { get; }
public PenLineCap StartLineCap { get; } = PenLineCap.Flat;
public PenLineCap EndLineCap { get; } = PenLineCap.Flat;
public PenLineJoin LineJoin { get; } = PenLineJoin.Miter;
public double MiterLimit { get; } = 10.0;
}
}

16
src/Perspex.SceneGraph/Media/PenLineCap.cs

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Perspex.Media
{
public enum PenLineCap
{
Flat,
Round,
Square,
Triangle
}
}

15
src/Perspex.SceneGraph/Media/PenLineJoin.cs

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Perspex.Media
{
public enum PenLineJoin
{
Bevel,
Miter,
Round
}
}

3
src/Perspex.SceneGraph/Perspex.SceneGraph.csproj

@ -63,11 +63,14 @@
<Compile Include="Media\BrushMappingMode.cs" />
<Compile Include="Media\Color.cs" />
<Compile Include="Media\Colors.cs" />
<Compile Include="Media\DashStyle.cs" />
<Compile Include="Media\MediaExtensions.cs" />
<Compile Include="Media\GradientBrush.cs" />
<Compile Include="Media\GradientSpreadMethod.cs" />
<Compile Include="Media\GradientStop.cs" />
<Compile Include="Media\LinearGradientBrush.cs" />
<Compile Include="Media\PenLineCap.cs" />
<Compile Include="Media\PenLineJoin.cs" />
<Compile Include="Media\TextAlignment.cs" />
<Compile Include="Media\FontWeight.cs" />
<Compile Include="Media\FontStyle.cs" />

48
src/Windows/Perspex.Direct2D1/PrimitiveExtensions.cs

@ -40,6 +40,29 @@ namespace Perspex.Direct2D1
else
return ExtendMode.Wrap;
}
public static SharpDX.Direct2D1.LineJoin ToDirect2D(this Perspex.Media.PenLineJoin lineJoin)
{
if (lineJoin == Perspex.Media.PenLineJoin.Round)
return LineJoin.Round;
else if (lineJoin == Perspex.Media.PenLineJoin.Miter)
return LineJoin.Miter;
else
return LineJoin.Bevel;
}
public static SharpDX.Direct2D1.CapStyle ToDirect2D(this Perspex.Media.PenLineCap lineCap)
{
if (lineCap == Perspex.Media.PenLineCap.Flat)
return CapStyle.Flat;
else if (lineCap == Perspex.Media.PenLineCap.Round)
return CapStyle.Round;
else if (lineCap == Perspex.Media.PenLineCap.Square)
return CapStyle.Square;
else
return CapStyle.Triangle;
}
/// <summary>
/// Converts a pen to a Direct2D stroke style.
/// </summary>
@ -48,19 +71,26 @@ namespace Perspex.Direct2D1
/// <returns>The Direct2D brush.</returns>
public static StrokeStyle ToDirect2DStrokeStyle(this Perspex.Media.Pen pen, RenderTarget target)
{
if (pen.DashArray != null && pen.DashArray.Count > 0)
if (pen.DashStyle != null)
{
var properties = new StrokeStyleProperties
if (pen.DashStyle.Dashes != null && pen.DashStyle.Dashes.Count > 0)
{
DashStyle = DashStyle.Custom,
};
var properties = new StrokeStyleProperties
{
DashStyle = DashStyle.Custom,
DashOffset = (float)pen.DashStyle.Offset,
MiterLimit = (float)pen.MiterLimit,
LineJoin = pen.LineJoin.ToDirect2D(),
StartCap = pen.StartLineCap.ToDirect2D(),
EndCap = pen.EndLineCap.ToDirect2D(),
DashCap = pen.DashCap.ToDirect2D()
};
return new StrokeStyle(target.Factory, properties, pen.DashArray.Select(x => (float)x).ToArray());
}
else
{
return null;
return new StrokeStyle(target.Factory, properties, pen.DashStyle?.Dashes.Select(x => (float)x).ToArray());
}
}
return null;
}
/// <summary>

Loading…
Cancel
Save