Commit 7894ea9e authored by HeinrichAD's avatar HeinrichAD
Browse files

Add: shape-rendering; Fix: CurrentCulture

Fix:
Now the application make sure to set back the old culture even an error
occurred.
SvgColourConverter.ConvertFrom
SvgPathBuilder.ConvertTo
SvgDocument.Write
SvgExtentions.GetXML

Add:
Attribute: "shape-rendering"

Change:
- Many other properties were unknowingly overloaded. I changed them to
override.
- Some methods or structures need the [CLSCompliant(false)] Attribute.
For example the Enums.TryParse extension. This extension has the where
condition IConvertible. IConvertible is [CLSCompliant(false)] and that
the reason why it is correct to mark the Enums.TryParse extension also
as [CLSCompliant(false)].
- Property "float Opacity" in SvgElement was unknowingly overloaded in
SvgGradientStop as string [stop-opacity]. In the end this property was
only used as float. I changed the SvgGradientStop.Opacity property from
string to float and to override.
parent a1ff72df
...@@ -30,8 +30,6 @@ namespace SVGViewer ...@@ -30,8 +30,6 @@ namespace SVGViewer
} }
} }
private string FXML = "";
private void textBox1_TextChanged(object sender, EventArgs e) private void textBox1_TextChanged(object sender, EventArgs e)
{ {
using(var s = new MemoryStream(UTF8Encoding.Default.GetBytes(textBox1.Text))) using(var s = new MemoryStream(UTF8Encoding.Default.GetBytes(textBox1.Text)))
......
...@@ -84,17 +84,6 @@ namespace Svg ...@@ -84,17 +84,6 @@ namespace Svg
get { return this.Path(null).GetBounds(); } get { return this.Path(null).GetBounds(); }
} }
/// <summary>
/// Gets a value indicating whether the circle requires anti-aliasing when being rendered.
/// </summary>
/// <value>
/// <c>true</c> if the circle requires anti-aliasing; otherwise, <c>false</c>.
/// </value>
protected override bool RequiresSmoothRendering
{
get { return true; }
}
/// <summary> /// <summary>
/// Gets the <see cref="GraphicsPath"/> representing this element. /// Gets the <see cref="GraphicsPath"/> representing this element.
/// </summary> /// </summary>
......
...@@ -80,15 +80,6 @@ namespace Svg ...@@ -80,15 +80,6 @@ namespace Svg
} }
} }
/// <summary>
/// Gets or sets a value to determine if anti-aliasing should occur when the element is being rendered.
/// </summary>
/// <value></value>
protected override bool RequiresSmoothRendering
{
get { return true; }
}
/// <summary> /// <summary>
/// Gets the bounds of the element. /// Gets the bounds of the element.
/// </summary> /// </summary>
......
...@@ -31,7 +31,7 @@ namespace Svg ...@@ -31,7 +31,7 @@ namespace Svg
/// Gets or sets the marker (end cap) of the path. /// Gets or sets the marker (end cap) of the path.
/// </summary> /// </summary>
[SvgAttribute("marker-end")] [SvgAttribute("marker-end")]
public Uri MarkerEnd public virtual Uri MarkerEnd
{ {
get { return this.Attributes.GetAttribute<Uri>("marker-end").ReplaceWithNullIfNone(); } get { return this.Attributes.GetAttribute<Uri>("marker-end").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-end"] = value; } set { this.Attributes["marker-end"] = value; }
...@@ -42,7 +42,7 @@ namespace Svg ...@@ -42,7 +42,7 @@ namespace Svg
/// Gets or sets the marker (start cap) of the path. /// Gets or sets the marker (start cap) of the path.
/// </summary> /// </summary>
[SvgAttribute("marker-mid")] [SvgAttribute("marker-mid")]
public Uri MarkerMid public virtual Uri MarkerMid
{ {
get { return this.Attributes.GetAttribute<Uri>("marker-mid").ReplaceWithNullIfNone(); } get { return this.Attributes.GetAttribute<Uri>("marker-mid").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-mid"] = value; } set { this.Attributes["marker-mid"] = value; }
...@@ -53,17 +53,12 @@ namespace Svg ...@@ -53,17 +53,12 @@ namespace Svg
/// Gets or sets the marker (start cap) of the path. /// Gets or sets the marker (start cap) of the path.
/// </summary> /// </summary>
[SvgAttribute("marker-start")] [SvgAttribute("marker-start")]
public Uri MarkerStart public virtual Uri MarkerStart
{ {
get { return this.Attributes.GetAttribute<Uri>("marker-start").ReplaceWithNullIfNone(); } get { return this.Attributes.GetAttribute<Uri>("marker-start").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-start"] = value; } set { this.Attributes["marker-start"] = value; }
} }
protected override bool RequiresSmoothRendering
{
get { return true; }
}
public override GraphicsPath Path(ISvgRenderer renderer) public override GraphicsPath Path(ISvgRenderer renderer)
{ {
if ((this._path == null || this.IsPathDirty) && base.StrokeWidth > 0) if ((this._path == null || this.IsPathDirty) && base.StrokeWidth > 0)
......
...@@ -18,7 +18,7 @@ namespace Svg ...@@ -18,7 +18,7 @@ namespace Svg
/// Gets or sets the marker (end cap) of the path. /// Gets or sets the marker (end cap) of the path.
/// </summary> /// </summary>
[SvgAttribute("marker-end")] [SvgAttribute("marker-end")]
public Uri MarkerEnd public override Uri MarkerEnd
{ {
get { return this.Attributes.GetAttribute<Uri>("marker-end").ReplaceWithNullIfNone(); } get { return this.Attributes.GetAttribute<Uri>("marker-end").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-end"] = value; } set { this.Attributes["marker-end"] = value; }
...@@ -29,7 +29,7 @@ namespace Svg ...@@ -29,7 +29,7 @@ namespace Svg
/// Gets or sets the marker (start cap) of the path. /// Gets or sets the marker (start cap) of the path.
/// </summary> /// </summary>
[SvgAttribute("marker-mid")] [SvgAttribute("marker-mid")]
public Uri MarkerMid public override Uri MarkerMid
{ {
get { return this.Attributes.GetAttribute<Uri>("marker-mid").ReplaceWithNullIfNone(); } get { return this.Attributes.GetAttribute<Uri>("marker-mid").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-mid"] = value; } set { this.Attributes["marker-mid"] = value; }
...@@ -40,7 +40,7 @@ namespace Svg ...@@ -40,7 +40,7 @@ namespace Svg
/// Gets or sets the marker (start cap) of the path. /// Gets or sets the marker (start cap) of the path.
/// </summary> /// </summary>
[SvgAttribute("marker-start")] [SvgAttribute("marker-start")]
public Uri MarkerStart public override Uri MarkerStart
{ {
get { return this.Attributes.GetAttribute<Uri>("marker-start").ReplaceWithNullIfNone(); } get { return this.Attributes.GetAttribute<Uri>("marker-start").ReplaceWithNullIfNone(); }
set { this.Attributes["marker-start"] = value; } set { this.Attributes["marker-start"] = value; }
......
...@@ -159,7 +159,13 @@ namespace Svg ...@@ -159,7 +159,13 @@ namespace Svg
/// </summary> /// </summary>
protected override bool RequiresSmoothRendering protected override bool RequiresSmoothRendering
{ {
get { return (CornerRadiusX.Value > 0 || CornerRadiusY.Value > 0); } get
{
if (base.RequiresSmoothRendering)
return (CornerRadiusX.Value > 0 || CornerRadiusY.Value > 0);
else
return false;
}
} }
/// <summary> /// <summary>
......
...@@ -11,7 +11,7 @@ namespace Svg ...@@ -11,7 +11,7 @@ namespace Svg
/// </summary> /// </summary>
public abstract partial class SvgVisualElement : SvgElement, ISvgBoundable, ISvgStylable, ISvgClipable public abstract partial class SvgVisualElement : SvgElement, ISvgBoundable, ISvgStylable, ISvgClipable
{ {
private bool _requiresSmoothRendering; private bool? _requiresSmoothRendering;
private Region _previousClip; private Region _previousClip;
/// <summary> /// <summary>
...@@ -86,7 +86,28 @@ namespace Svg ...@@ -86,7 +86,28 @@ namespace Svg
/// </summary> /// </summary>
protected virtual bool RequiresSmoothRendering protected virtual bool RequiresSmoothRendering
{ {
get { return this._requiresSmoothRendering; } get
{
if (_requiresSmoothRendering == null)
_requiresSmoothRendering = ConvertShapeRendering2AntiAlias(ShapeRendering);
return _requiresSmoothRendering.Value;
}
}
private bool ConvertShapeRendering2AntiAlias(SvgShapeRendering shapeRendering)
{
switch (shapeRendering)
{
case SvgShapeRendering.OptimizeSpeed:
case SvgShapeRendering.CrispEdges:
case SvgShapeRendering.GeometricPrecision:
return false;
default:
// SvgShapeRendering.Auto
// SvgShapeRendering.Inherit
return true;
}
} }
/// <summary> /// <summary>
...@@ -95,7 +116,6 @@ namespace Svg ...@@ -95,7 +116,6 @@ namespace Svg
public SvgVisualElement() public SvgVisualElement()
{ {
this.IsPathDirty = true; this.IsPathDirty = true;
this._requiresSmoothRendering = false;
} }
protected virtual bool Renderable { get { return true; } } protected virtual bool Renderable { get { return true; } }
......
...@@ -132,7 +132,7 @@ namespace Svg ...@@ -132,7 +132,7 @@ namespace Svg
/// Refers to the size of the font from baseline to baseline when multiple lines of text are set solid in a multiline layout environment. /// Refers to the size of the font from baseline to baseline when multiple lines of text are set solid in a multiline layout environment.
/// </summary> /// </summary>
[SvgAttribute("font-size")] [SvgAttribute("font-size")]
public virtual SvgUnit FontSize public override SvgUnit FontSize
{ {
get { return (this.Attributes["font-size"] == null) ? SvgUnit.Empty : (SvgUnit)this.Attributes["font-size"]; } get { return (this.Attributes["font-size"] == null) ? SvgUnit.Empty : (SvgUnit)this.Attributes["font-size"]; }
set { this.Attributes["font-size"] = value; } set { this.Attributes["font-size"] = value; }
...@@ -142,7 +142,7 @@ namespace Svg ...@@ -142,7 +142,7 @@ namespace Svg
/// Indicates which font family is to be used to render the text. /// Indicates which font family is to be used to render the text.
/// </summary> /// </summary>
[SvgAttribute("font-family")] [SvgAttribute("font-family")]
public virtual string FontFamily public override string FontFamily
{ {
get { return this.Attributes["font-family"] as string; } get { return this.Attributes["font-family"] as string; }
set { this.Attributes["font-family"] = value; } set { this.Attributes["font-family"] = value; }
......
...@@ -183,6 +183,21 @@ namespace Svg ...@@ -183,6 +183,21 @@ namespace Svg
public SvgTextPathSpacingConverter() : base(SvgTextPathSpacing.Exact) { } public SvgTextPathSpacingConverter() : base(SvgTextPathSpacing.Exact) { }
} }
public sealed class SvgShapeRenderingConverter : EnumBaseConverter<SvgShapeRendering>
{
public SvgShapeRenderingConverter() : base(SvgShapeRendering.Inherit) { }
}
public sealed class SvgTextRenderingConverter : EnumBaseConverter<SvgTextRendering>
{
public SvgTextRenderingConverter() : base(SvgTextRendering.Inherit) { }
}
public sealed class SvgImageRenderingConverter : EnumBaseConverter<SvgImageRendering>
{
public SvgImageRenderingConverter() : base(SvgImageRendering.Inherit) { }
}
public sealed class SvgFontVariantConverter : EnumBaseConverter<SvgFontVariant> public sealed class SvgFontVariantConverter : EnumBaseConverter<SvgFontVariant>
{ {
public SvgFontVariantConverter() : base(SvgFontVariant.Normal) { } public SvgFontVariantConverter() : base(SvgFontVariant.Normal) { }
...@@ -287,6 +302,7 @@ namespace Svg ...@@ -287,6 +302,7 @@ namespace Svg
public static class Enums public static class Enums
{ {
[CLSCompliant(false)]
public static bool TryParse<TEnum>(string value, out TEnum result) where TEnum : struct, IConvertible public static bool TryParse<TEnum>(string value, out TEnum result) where TEnum : struct, IConvertible
{ {
var retValue = value == null ? var retValue = value == null ?
......
...@@ -33,6 +33,7 @@ namespace Svg ...@@ -33,6 +33,7 @@ namespace Svg
if (colour != null) if (colour != null)
{ {
var oldCulture = Thread.CurrentThread.CurrentCulture; var oldCulture = Thread.CurrentThread.CurrentCulture;
try {
Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
colour = colour.Trim(); colour = colour.Trim();
...@@ -44,7 +45,7 @@ namespace Svg ...@@ -44,7 +45,7 @@ namespace Svg
int start = colour.IndexOf("(") + 1; int start = colour.IndexOf("(") + 1;
//get the values from the RGB string //get the values from the RGB string
string[] values = colour.Substring(start, colour.IndexOf(")") - start).Split(new char[]{',', ' '}, StringSplitOptions.RemoveEmptyEntries); string[] values = colour.Substring(start, colour.IndexOf(")") - start).Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
//determine the alpha value if this is an RGBA (it will be the 4th value if there is one) //determine the alpha value if this is an RGBA (it will be the 4th value if there is one)
int alphaValue = 255; int alphaValue = 255;
...@@ -53,14 +54,14 @@ namespace Svg ...@@ -53,14 +54,14 @@ namespace Svg
//the alpha portion of the rgba is not an int 0-255 it is a decimal between 0 and 1 //the alpha portion of the rgba is not an int 0-255 it is a decimal between 0 and 1
//so we have to determine the corosponding byte value //so we have to determine the corosponding byte value
var alphastring = values[3]; var alphastring = values[3];
if(alphastring.StartsWith(".")) if (alphastring.StartsWith("."))
{ {
alphastring = "0" + alphastring; alphastring = "0" + alphastring;
} }
var alphaDecimal = decimal.Parse(alphastring); var alphaDecimal = decimal.Parse(alphastring);
if(alphaDecimal <= 1) if (alphaDecimal <= 1)
{ {
alphaValue = (int)(alphaDecimal * 255); alphaValue = (int)(alphaDecimal * 255);
} }
...@@ -90,27 +91,27 @@ namespace Svg ...@@ -90,27 +91,27 @@ namespace Svg
} }
} }
// HSL support // HSL support
else if ( colour.StartsWith( "hsl" ) ) { else if (colour.StartsWith("hsl")) {
try try
{ {
int start = colour.IndexOf("(") + 1; int start = colour.IndexOf("(") + 1;
//get the values from the RGB string //get the values from the RGB string
string[] values = colour.Substring(start, colour.IndexOf(")") - start).Split(new char[]{',', ' '}, StringSplitOptions.RemoveEmptyEntries); string[] values = colour.Substring(start, colour.IndexOf(")") - start).Split(new char[] { ',', ' ' }, StringSplitOptions.RemoveEmptyEntries);
if ( values[1].EndsWith( "%" ) ) if (values[1].EndsWith("%"))
{ {
values[1] = values[1].TrimEnd( '%' ); values[1] = values[1].TrimEnd('%');
} }
if ( values[2].EndsWith( "%" ) ) if (values[2].EndsWith("%"))
{ {
values[2] = values[2].TrimEnd( '%' ); values[2] = values[2].TrimEnd('%');
} }
// Get the HSL values in a range from 0 to 1. // Get the HSL values in a range from 0 to 1.
double h = double.Parse( values[0] ) / 360.0; double h = double.Parse(values[0]) / 360.0;
double s = double.Parse( values[1] ) / 100.0; double s = double.Parse(values[1]) / 100.0;
double l = double.Parse( values[2] ) / 100.0; double l = double.Parse(values[2]) / 100.0;
// Convert the HSL color to an RGB color // Convert the HSL color to an RGB color
Color colorpart = Hsl2Rgb( h, s, l ); Color colorpart = Hsl2Rgb(h, s, l);
return colorpart; return colorpart;
} }
catch catch
...@@ -155,8 +156,13 @@ namespace Svg ...@@ -155,8 +156,13 @@ namespace Svg
case "windowtext": return SystemColors.WindowText; case "windowtext": return SystemColors.WindowText;
} }
}
finally
{
// Make sure to set back the old culture even an error occurred.
Thread.CurrentThread.CurrentCulture = oldCulture; Thread.CurrentThread.CurrentCulture = oldCulture;
} }
}
return base.ConvertFrom(context, culture, value); return base.ConvertFrom(context, culture, value);
} }
......
...@@ -180,7 +180,7 @@ namespace Svg ...@@ -180,7 +180,7 @@ namespace Svg
var currentStop = this.Stops[radial ? this.Stops.Count - 1 - actualStops : actualStops]; var currentStop = this.Stops[radial ? this.Stops.Count - 1 - actualStops : actualStops];
var boundWidth = renderer.GetBoundable().Bounds.Width; var boundWidth = renderer.GetBoundable().Bounds.Width;
mergedOpacity = opacity * currentStop.GetOpacity(); mergedOpacity = opacity * currentStop.Opacity;
position = position =
radial radial
? 1 - (currentStop.Offset.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this) / boundWidth) ? 1 - (currentStop.Offset.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this) / boundWidth)
......
...@@ -57,7 +57,7 @@ namespace Svg ...@@ -57,7 +57,7 @@ namespace Svg
/// </summary> /// </summary>
[SvgAttribute("stop-color")] [SvgAttribute("stop-color")]
[TypeConverter(typeof(SvgPaintServerFactory))] [TypeConverter(typeof(SvgPaintServerFactory))]
public SvgPaintServer StopColor public override SvgPaintServer StopColor
{ {
get get
{ {
...@@ -72,16 +72,10 @@ namespace Svg ...@@ -72,16 +72,10 @@ namespace Svg
/// Gets or sets the opacity of the gradient stop (0-1). /// Gets or sets the opacity of the gradient stop (0-1).
/// </summary> /// </summary>
[SvgAttribute("stop-opacity")] [SvgAttribute("stop-opacity")]
public string Opacity public override float Opacity
{ {
get { return this.Attributes["stop-opacity"] as string; } get { return (this.Attributes["stop-opacity"] == null) ? 1.0f : (float)this.Attributes["stop-opacity"]; }
set { this.Attributes["stop-opacity"] = value; } set { this.Attributes["stop-opacity"] = FixOpacityValue(value); }
}
public float GetOpacity()
{
var opacity = this.Opacity;
return string.IsNullOrEmpty(opacity) ? 1.0f : float.Parse(opacity);
} }
/// <summary> /// <summary>
......
...@@ -135,7 +135,7 @@ namespace Svg ...@@ -135,7 +135,7 @@ namespace Svg
set { this.Attributes["gradientTransform"] = value; } set { this.Attributes["gradientTransform"] = value; }
} }
protected Matrix EffectivePatternTransform private Matrix EffectivePatternTransform
{ {
get get
{ {
......
...@@ -147,7 +147,7 @@ namespace Svg ...@@ -147,7 +147,7 @@ namespace Svg
{ {
var stop = Stops.Last(); var stop = Stops.Last();
var origColor = stop.GetColor(renderingElement); var origColor = stop.GetColor(renderingElement);
var renderColor = System.Drawing.Color.FromArgb((int)(opacity * stop.GetOpacity() * 255), origColor); var renderColor = System.Drawing.Color.FromArgb((int)(opacity * stop.Opacity * 255), origColor);
var origClip = renderer.GetClip(); var origClip = renderer.GetClip();
try try
......
...@@ -104,14 +104,6 @@ namespace Svg ...@@ -104,14 +104,6 @@ namespace Svg
OnAttributeChanged(new AttributeEventArgs{ Attribute = "d", Value = this.Attributes.GetAttribute<SvgPathSegmentList>("d") }); OnAttributeChanged(new AttributeEventArgs{ Attribute = "d", Value = this.Attributes.GetAttribute<SvgPathSegmentList>("d") });
} }
/// <summary>
/// Gets or sets a value to determine if anti-aliasing should occur when the element is being rendered.
/// </summary>
protected override bool RequiresSmoothRendering
{
get { return true; }
}
/// <summary> /// <summary>
/// Gets the bounds of the element. /// Gets the bounds of the element.
/// </summary> /// </summary>
......
...@@ -522,11 +522,17 @@ namespace Svg ...@@ -522,11 +522,17 @@ namespace Svg
if (paths != null) if (paths != null)
{ {
var curretCulture = CultureInfo.CurrentCulture; var curretCulture = CultureInfo.CurrentCulture;
try {
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
var s = string.Join(" ", paths.Select(p => p.ToString()).ToArray()); var s = string.Join(" ", paths.Select(p => p.ToString()).ToArray());
Thread.CurrentThread.CurrentCulture = curretCulture;
return s; return s;
} }
finally
{
// Make sure to set back the old culture even an error occurred.
Thread.CurrentThread.CurrentCulture = curretCulture;
}
}
} }
return base.ConvertTo(context, culture, value, destinationType); return base.ConvertTo(context, culture, value, destinationType);
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Svg
{
/// <summary>
/// The creator of SVG content might want to provide a hint about what tradeoffs to make as the browser renders <path> element or basic shapes. The shape-rendering attribute provides these hints.
/// </summary>
/// <references>https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/shape-rendering</references>
/// <remarks>
/// Default is <see cref="Inherit"/>. That means the value comes from the parent element. If parents are also not set, then the value is <see cref="Auto"/>.
/// </remarks>
[TypeConverter(typeof(SvgShapeRenderingConverter))]
public enum SvgShapeRendering
{
/// <summary>
/// Indicates that the SVG shape rendering properties from the parent will be used.
/// </summary>
/// <AnitAlias>Based of parent. If parents are also not set, then <see cref="Auto"/></AnitAlias>
Inherit,
/// <summary>
/// Indicates that the user agent shall make appropriate tradeoffs to balance speed, crisp edges and geometric precision, but with geometric precision given more importance than speed and crisp edges.
/// </summary>
/// <AnitAlias>true</AnitAlias>
Auto,
/// <summary>
/// Indicates that the user agent shall emphasize rendering speed over geometric precision and crisp edges. This option will sometimes cause the user agent to turn off shape anti-aliasing.
/// </summary>
/// <AnitAlias>false</AnitAlias>
OptimizeSpeed,
/// <summary>
/// Indicates that the user agent shall attempt to emphasize the contrast between clean edges of artwork over rendering speed and geometric precision. To achieve crisp edges, the user agent might turn off anti-aliasing for all lines and curves or possibly just for straight lines which are close to vertical or horizontal. Also, the user agent might adjust line positions and line widths to align edges with device pixels.
/// </summary>
/// <AnitAlias>false</AnitAlias>
CrispEdges,
/// <summary>
/// Indicates that the user agent shall emphasize geometric precision over speed and crisp edges.
/// </summary>
/// <AnitAlias>false</AnitAlias>
GeometricPrecision
}
/// <summary>
/// The creator of SVG content might want to provide a hint about what tradeoffs to make as the browser renders text. The text-rendering attribute provides these hints.
/// </summary>
/// <references>https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/text-rendering</references>
/// <remarks>Not Implemented yet.</remarks>
[TypeConverter(typeof(SvgTextRenderingConverter))]
public enum SvgTextRendering
{
/// <summary>
/// Indicates that the SVG shape rendering properties from the parent will be used.
/// </summary>
Inherit,
/// <summary>
/// Indicates that the browser shall make appropriate tradeoffs to balance speed, legibility and geometric precision, but with legibility given more importance than speed and geometric precision.
/// </summary>
Auto,
/// <summary>
/// Indicates that the user agent shall emphasize rendering speed over legibility and geometric precision. This option will sometimes cause some browsers to turn off text anti-aliasing.
/// </summary>
OptimizeSpeed,
/// <summary>
/// Indicates that the browser shall emphasize legibility over rendering speed and geometric precision. The user agent will often choose whether to apply anti-aliasing techniques, built-in font hinting or both to produce the most legible text.
/// </summary>
OptimizeLegibility,
/// <summary>
/// Indicates that the browser shall emphasize geometric precision over legibility and rendering speed. This option will usually cause the user agent to suspend the use of hinting so that glyph outlines are drawn with comparable geometric precision to the rendering of path data.
/// </summary>
GeometricPrecision
}
/// <summary>
/// The image-rendering attribute provides a hint to the browser about how to make speed vs. quality tradeoffs as it performs image processing.
/// </summary>
/// <references>https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/image-rendering</references>
/// <remarks>Not Implemented yet.</remarks>
[TypeConverter(typeof(SvgImageRenderingConverter))]
public enum SvgImageRendering
{
/// <summary>
/// Indicates that the SVG shape rendering properties from the parent will be used.
/// </summary>
Inherit,
/// <summary>
/// Indicates that the user agent shall make appropriate tradeoffs to balance speed and quality, but quality shall be given more importance than speed.
/// </summary>
Auto,
/// <summary>
/// Indicates that the user agent shall emphasize rendering speed over quality.
/// </summary>
OptimizeSpeed,
/// <summary>
/// Indicates that the user agent shall emphasize quality over rendering speed.
/// </summary>
OptimizeQuality
}
}
...@@ -115,6 +115,7 @@ ...@@ -115,6 +115,7 @@
<Compile Include="Paths\CoordinateParser.cs" /> <Compile Include="Paths\CoordinateParser.cs" />
<Compile Include="Rendering\IGraphicsProvider.cs" /> <Compile Include="Rendering\IGraphicsProvider.cs" />
<Compile Include="Rendering\ISvgRenderer.cs" /> <Compile Include="Rendering\ISvgRenderer.cs" />
<Compile Include="Rendering\SvgRendering.cs" />
<Compile Include="SvgElementStyle.cs" /> <Compile Include="SvgElementStyle.cs" />
<Compile Include="SvgNodeReader.cs" /> <Compile Include="SvgNodeReader.cs" />
<Compile Include="Css\CssQuery.cs" /> <Compile Include="Css\CssQuery.cs" />
......
...@@ -563,13 +563,17 @@ namespace Svg ...@@ -563,13 +563,17 @@ namespace Svg
{ {
//Save previous culture and switch to invariant for writing //Save previous culture and switch to invariant for writing
var previousCulture = Thread.CurrentThread.CurrentCulture; var previousCulture = Thread.CurrentThread.CurrentCulture;
try {
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
base.Write(writer); base.Write(writer);
}
finally
{
// Make sure to set back the old culture even an error occurred.
//Switch culture back //Switch culture back
Thread.CurrentThread.CurrentCulture = previousCulture; Thread.CurrentThread.CurrentCulture = previousCulture;
} }
}
public void Write(Stream stream) public void Write(Stream stream)
{ {
......
...@@ -26,7 +26,7 @@ namespace Svg ...@@ -26,7 +26,7 @@ namespace Svg
set { this._dirty = value; } set { this._dirty = value; }
} }
private static float FixOpacityValue(float value) protected static float FixOpacityValue(float value)
{ {
const float max = 1.0f; const float max = 1.0f;
const float min = 0.0f; const float min = 0.0f;
...@@ -131,7 +131,7 @@ namespace Svg ...@@ -131,7 +131,7 @@ namespace Svg
/// <remarks>Apparently this can be set on non-sensical elements. Don't ask; just check the tests.</remarks> /// <remarks>Apparently this can be set on non-sensical elements. Don't ask; just check the tests.</remarks>
[SvgAttribute("stop-color", true)] [SvgAttribute("stop-color", true)]
[TypeConverter(typeof(SvgPaintServerFactory))] [TypeConverter(typeof(SvgPaintServerFactory))]
public SvgPaintServer StopColor public virtual SvgPaintServer StopColor
{ {
get { return this.Attributes["stop-color"] as SvgPaintServer; } get { return this.Attributes["stop-color"] as SvgPaintServer; }
set { this.Attributes["stop-color"] = value; } set { this.Attributes["stop-color"] = value; }
...@@ -147,6 +147,16 @@ namespace Svg ...@@ -147,6 +147,16 @@ namespace Svg
set { this.Attributes["opacity"] = FixOpacityValue(value); } set { this.Attributes["opacity"] = FixOpacityValue(value); }
} }
/// <summary>
/// Refers to the AnitAlias rendering of shapes.
/// </summary>
[SvgAttribute("shape-rendering")]
public virtual SvgShapeRendering ShapeRendering
{
get { return this.Attributes.GetInheritedAttribute<SvgShapeRendering>("shape-rendering"); }
set { this.Attributes["shape-rendering"] = value; }
}
/// <summary> /// <summary>
/// Indicates which font family is to be used to render the text. /// Indicates which font family is to be used to render the text.
/// </summary> /// </summary>
......
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