Browse Source

Fixed scaling for Paths.

Will no doubt need revisiting as mentioned in the comments in
Shape.MeasureOverride.
pull/16/head
Steven Kirk 12 years ago
parent
commit
f158c3e399
  1. 36
      Perspex.Controls/Shapes/Shape.cs
  2. BIN
      TestFiles/Direct2D1/Shapes/Path/Path_100px_Triangle_Centered.expected.png
  3. BIN
      TestFiles/Direct2D1/Shapes/Path/Path_Expander_With_Border.expected.png
  4. 28
      Windows/Perspex.Direct2D1.RenderTests/Shapes/PathTests.cs
  5. 12
      Windows/Perspex.Direct2D1/Media/GeometryImpl.cs
  6. 5
      Windows/Perspex.Direct2D1/Media/StreamGeometryImpl.cs

36
Perspex.Controls/Shapes/Shape.cs

@ -26,6 +26,8 @@ namespace Perspex.Controls.Shapes
private Matrix transform = Matrix.Identity; private Matrix transform = Matrix.Identity;
private Geometry renderedGeometry;
public abstract Geometry DefiningGeometry public abstract Geometry DefiningGeometry
{ {
get; get;
@ -41,15 +43,17 @@ namespace Perspex.Controls.Shapes
{ {
get get
{ {
var result = this.DefiningGeometry; if (this.renderedGeometry == null)
if (result != null)
{ {
result = result.Clone(); if (this.DefiningGeometry != null)
result.Transform = new MatrixTransform(this.transform); {
this.renderedGeometry = this.DefiningGeometry.Clone();
this.renderedGeometry.Transform = new MatrixTransform(this.transform);
}
} }
return result; return this.renderedGeometry;
} }
} }
@ -83,7 +87,9 @@ namespace Perspex.Controls.Shapes
protected override Size MeasureOverride(Size availableSize) protected override Size MeasureOverride(Size availableSize)
{ {
Rect shapeBounds = this.DefiningGeometry.GetRenderBounds(this.StrokeThickness); // This should probably use GetRenderBounds(strokeThickness) but then the calculations
// will multiply the stroke thickness as well, which isn't correct.
Rect shapeBounds = this.DefiningGeometry.Bounds;
Size shapeSize = new Size(shapeBounds.Right, shapeBounds.Bottom); Size shapeSize = new Size(shapeBounds.Right, shapeBounds.Bottom);
Matrix translate = Matrix.Identity; Matrix translate = Matrix.Identity;
double width = this.Width; double width = this.Width;
@ -111,12 +117,12 @@ namespace Perspex.Controls.Shapes
if (shapeBounds.Width > 0) if (shapeBounds.Width > 0)
{ {
sx = desiredX / shapeBounds.Width; sx = desiredX / shapeSize.Width;
} }
if (shapeBounds.Height > 0) if (shapeBounds.Height > 0)
{ {
sy = desiredY / shapeBounds.Height; sy = desiredY / shapeSize.Height;
} }
if (double.IsInfinity(availableSize.Width)) if (double.IsInfinity(availableSize.Width))
@ -154,11 +160,15 @@ namespace Perspex.Controls.Shapes
break; break;
} }
this.transform = translate * Matrix.Scaling(sx, sy); var t = translate * Matrix.Scaling(sx, sy);
if (this.transform != t)
{
this.transform = t;
this.renderedGeometry = null;
}
double finalX = (width > 0) ? width : shapeSize.Width * sx; return new Size(shapeSize.Width * sx, shapeSize.Height * sy);
double finalY = (height > 0) ? height : shapeSize.Width * sy;
return new Size(finalX, finalY);
} }
} }
} }

BIN
TestFiles/Direct2D1/Shapes/Path/Path_100px_Triangle_Centered.expected.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

BIN
TestFiles/Direct2D1/Shapes/Path/Path_Expander_With_Border.expected.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

28
Windows/Perspex.Direct2D1.RenderTests/Shapes/PathTests.cs

@ -65,5 +65,33 @@ namespace Perspex.Direct2D1.RenderTests.Shapes
this.RenderToFile(target); this.RenderToFile(target);
this.CompareImages(); this.CompareImages();
} }
[TestMethod]
public void Path_Expander_With_Border()
{
Decorator target = new Decorator
{
Width = 200,
Height = 200,
Content = new Border
{
BorderBrush = Brushes.Red,
BorderThickness = 1,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Content = new Path
{
Fill = Brushes.Black,
Stroke = Brushes.Black,
StrokeThickness = 1,
Stretch = Stretch.Uniform,
Data = StreamGeometry.Parse("M 0 2 L 4 6 L 0 10 Z"),
}
}
};
this.RenderToFile(target);
this.CompareImages();
}
} }
} }

12
Windows/Perspex.Direct2D1/Media/GeometryImpl.cs

@ -60,6 +60,16 @@ namespace Perspex.Direct2D1.Media
} }
} }
public abstract Rect GetRenderBounds(double strokeThickness); public Rect GetRenderBounds(double strokeThickness)
{
if (this.transformed != null)
{
return this.transformed.GetWidenedBounds((float)strokeThickness).ToPerspex();
}
else
{
return this.DefiningGeometry.GetWidenedBounds((float)strokeThickness).ToPerspex();
}
}
} }
} }

5
Windows/Perspex.Direct2D1/Media/StreamGeometryImpl.cs

@ -44,11 +44,6 @@ namespace Perspex.Direct2D1.Media
return new StreamGeometryImpl(result); return new StreamGeometryImpl(result);
} }
public override Rect GetRenderBounds(double strokeThickness)
{
return this.path.GetWidenedBounds((float)strokeThickness).ToPerspex();
}
public IStreamGeometryContextImpl Open() public IStreamGeometryContextImpl Open()
{ {
return new StreamGeometryContextImpl(this.path.Open()); return new StreamGeometryContextImpl(this.path.Open());

Loading…
Cancel
Save