Commit 04d48a36 authored by Tebjan Halm's avatar Tebjan Halm
Browse files

Merge pull request #56 from andreichuk/changes

Changes
parents fe32d9ae 3caaf475
using System;
using System.Collections.Generic;
using System.Collections;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
......@@ -104,15 +101,16 @@ namespace Svg
/// </summary>
/// <param name="owner">The parent <see cref="SvgVisualElement"/>.</param>
/// <param name="opacity">The opacity of the colour blend.</param>
protected ColorBlend GetColourBlend(SvgVisualElement owner, float opacity)
protected ColorBlend GetColourBlend(SvgVisualElement owner, float opacity, bool radial)
{
ColorBlend blend = new ColorBlend();
int colourBlends = this.Stops.Count;
bool insertStart = false;
bool insertEnd = false;
//gradient.Transform = renderingElement.Transforms.Matrix;
//stops should be processed in reverse order if it's a radial gradient
// May need to increase the number of colour blends because the range *must* be from 0.0 to 1.0.
// E.g. 0.5 - 0.8 isn't valid therefore the rest need to be calculated.
......@@ -120,21 +118,33 @@ namespace Svg
if (this.Stops[0].Offset.Value > 0)
{
colourBlends++;
// Indicate that a colour has to be dynamically added at the start
if (radial)
{
insertEnd = true;
}
else
{
insertStart = true;
}
}
// If the last stop doesn't end at 1 a stop
float lastValue = this.Stops[this.Stops.Count - 1].Offset.Value;
if (lastValue < 100 || lastValue < 1)
{
colourBlends++;
// Indicate that a colour has to be dynamically added at the end
if (radial)
{
insertStart = true;
}
else
{
insertEnd = true;
}
}
blend.Positions = new float[colourBlends];
blend.Colors = new Color[colourBlends];
ColorBlend blend = new ColorBlend(colourBlends);
// Set positions and colour values
int actualStops = 0;
......@@ -144,15 +154,24 @@ namespace Svg
for (int i = 0; i < colourBlends; i++)
{
mergedOpacity = opacity * this.Stops[actualStops].Opacity;
position = (this.Stops[actualStops].Offset.ToDeviceValue(owner) / owner.Bounds.Width);
colour = Color.FromArgb((int)(mergedOpacity * 255), this.Stops[actualStops++].Colour);
var currentStop = this.Stops[radial ? this.Stops.Count - 1 - actualStops : actualStops];
mergedOpacity = opacity * currentStop.Opacity;
position =
radial
? 1 - (currentStop.Offset.ToDeviceValue(owner) / owner.Bounds.Width)
: (currentStop.Offset.ToDeviceValue(owner) / owner.Bounds.Width);
colour = Color.FromArgb((int)(mergedOpacity * 255), currentStop.Colour);
actualStops++;
// Insert this colour before itself at position 0
if (insertStart && i == 0)
{
blend.Positions[i] = 0.0f;
blend.Colors[i++] = colour;
blend.Colors[i] = colour;
i++;
}
blend.Positions[i] = position;
......@@ -161,8 +180,10 @@ namespace Svg
// Insert this colour after itself at position 0
if (insertEnd && i == colourBlends - 2)
{
blend.Positions[i + 1] = 1.0f;
blend.Colors[++i] = colour;
i++;
blend.Positions[i] = 1.0f;
blend.Colors[i] = colour;
}
}
......@@ -184,12 +205,12 @@ namespace Svg
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgGradientServer;
newObj.SpreadMethod = this.SpreadMethod;
newObj.GradientUnits = this.GradientUnits;
newObj.InheritGradient = this.InheritGradient;
return newObj;
return newObj;
}
}
}
\ No newline at end of file
......@@ -109,7 +109,7 @@ namespace Svg
}
LinearGradientBrush gradient = new LinearGradientBrush(start, end, Color.Transparent, Color.Transparent);
gradient.InterpolationColors = base.GetColourBlend(owner, opacity);
gradient.InterpolationColors = base.GetColourBlend(owner, opacity, false);
// Needed to fix an issue where the gradient was being wrapped when though it had the correct bounds
gradient.WrapMode = WrapMode.TileFlipX;
......
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Drawing2D;
......@@ -33,14 +30,36 @@ namespace Svg
[SvgAttribute("fx")]
public SvgUnit FocalX
{
get { return this.Attributes.GetAttribute<SvgUnit>("fx"); }
get
{
var value = this.Attributes.GetAttribute<SvgUnit>("fx");
if (value.IsEmpty || value.IsNone)
{
value = this.CenterX;
}
return value;
}
set { this.Attributes["fx"] = value; }
}
[SvgAttribute("fy")]
public SvgUnit FocalY
{
get { return this.Attributes.GetAttribute<SvgUnit>("fy"); }
get
{
var value = this.Attributes.GetAttribute<SvgUnit>("fy");
if (value.IsEmpty || value.IsNone)
{
value = this.CenterY;
}
return value;
}
set { this.Attributes["fy"] = value; }
}
......@@ -57,28 +76,37 @@ namespace Svg
public override Brush GetBrush(SvgVisualElement renderingElement, float opacity)
{
float radius = this.Radius.ToDeviceValue(renderingElement);
if (radius <= 0)
{
return null;
}
GraphicsPath path = new GraphicsPath();
float left = this.CenterX.ToDeviceValue(renderingElement);
float top = this.CenterY.ToDeviceValue(renderingElement, true);
float radius = this.Radius.ToDeviceValue(renderingElement);
RectangleF boundingBox = (this.GradientUnits == SvgCoordinateUnits.ObjectBoundingBox) ? renderingElement.Bounds : renderingElement.OwnerDocument.GetDimensions();
if (radius > 0)
{
path.AddEllipse(left - radius, top - radius, radius * 2, radius * 2);
path.AddEllipse(
boundingBox.Left + left - radius,
boundingBox.Top + top - radius,
radius * 2,
radius * 2);
PathGradientBrush brush = new PathGradientBrush(path);
ColorBlend blend = base.GetColourBlend(renderingElement, opacity);
ColorBlend blend = base.GetColourBlend(renderingElement, opacity, true);
brush.InterpolationColors = blend;
brush.CenterPoint = new PointF(this.FocalX.ToDeviceValue(renderingElement), this.FocalY.ToDeviceValue(renderingElement, true));
brush.CenterPoint =
new PointF(
boundingBox.Left + this.FocalX.ToDeviceValue(renderingElement),
boundingBox.Top + this.FocalY.ToDeviceValue(renderingElement, true));
return brush;
}
return null;
}
public override SvgElement DeepCopy()
{
......@@ -89,13 +117,14 @@ namespace Svg
public override SvgElement DeepCopy<T>()
{
var newObj = base.DeepCopy<T>() as SvgRadialGradientServer;
newObj.CenterX = this.CenterX;
newObj.CenterY = this.CenterY;
newObj.Radius = this.Radius;
newObj.FocalX = this.FocalX;
newObj.FocalY = this.FocalY;
return newObj;
return newObj;
}
}
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment