Commit 6998823a authored by Tebjan Halm's avatar Tebjan Halm
Browse files

* implemented fill modes

* fill can be null -> none in XML
* added type converters for enums
* added type converter for unitcollection
* fixes several viewbox bugs
* document can now draw into a given bitmap
* content of SVG tag is written (used by the text tag)
* changed font handling in text element, still need proper alignment
* changed intersparse character of SvgTransformConverter.cs to space, because inkscape couldn't parse comma
* added class diagram for basic shapes
parent 28333a39
<?xml version="1.0" encoding="utf-8"?>
<ClassDiagram MajorVersion="1" MinorVersion="1">
<Class Name="Svg.SvgCircle" Collapsed="true">
<Position X="0.5" Y="4.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAIAAAAAAACAAIAGAAAAAAAAAAAAAQAABAAAAAIAgA=</HashCode>
<FileName>Basic Shapes\SvgCircle.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Svg.SvgEllipse" Collapsed="true">
<Position X="5" Y="4.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAABAAgAAAACAAIAGAAgGQAAAAAAAAQAABAAAAAAAgA=</HashCode>
<FileName>Basic Shapes\SvgEllipse.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Svg.SvgLine" Collapsed="true">
<Position X="7.25" Y="4.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAyAiAAIAAAAAAAAAAAAADAAAAADAAAAAAgA=</HashCode>
<FileName>Basic Shapes\SvgLine.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Svg.SvgPolygon" Collapsed="true">
<Position X="2.75" Y="4.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAACgAIAgAAAAAAAAAAAAAQAAAAAAAAAAgA=</HashCode>
<FileName>Basic Shapes\SvgPolygon.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Svg.SvgPolyline" Collapsed="true">
<Position X="2.75" Y="6" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAIAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Basic Shapes\SvgPolyline.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Svg.SvgRectangle" Collapsed="true">
<Position X="9.5" Y="4.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAIBASCAAIAAAIAAEDAABAAAAQAABAAEAAAYgA=</HashCode>
<FileName>Basic Shapes\SvgRectangle.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Svg.SvgVisualElement">
<Position X="11.25" Y="1.25" Width="1.5" />
<TypeIdentifier>
<HashCode>AACCEAAFAYAAgAKAAABAACABEAgBSsUIABAAAACAIgA=</HashCode>
<FileName>Basic Shapes\SvgVisualElement.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Property Name="FillOpacity" />
<Property Name="FillRule" />
<Property Name="ClipRule" />
<Property Name="Opacity" />
<Property Name="StrokeLineCap" />
<Property Name="StrokeWidth" />
</ShowAsAssociation>
<Lollipop Position="1.003" />
</Class>
<Class Name="Svg.SvgGroup">
<Position X="9" Y="1.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAAAAAAAIAAAAAAAAAAAAACAAAABAAAAAAAgA=</HashCode>
<FileName>Document Structure\SvgGroup.cs</FileName>
</TypeIdentifier>
</Class>
<Class Name="Svg.SvgElement">
<Position X="6.25" Y="7.25" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAUiAAQAggRkAECBABEQAAREgACAQAAgBIAIAECIBI=</HashCode>
<FileName>SvgElement.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Class Name="Svg.SvgDocument">
<Position X="10.5" Y="10.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAQAgAgACQIwQAAAQAAAAAQEAAAAAQCAAAAAEAAMA=</HashCode>
<FileName>SvgDocument.cs</FileName>
</TypeIdentifier>
<Lollipop Position="0.2" />
</Class>
<Struct Name="System.Single" Collapsed="true">
<Position X="16.25" Y="3" Width="1.5" />
<TypeIdentifier />
<Lollipop Position="0.2" />
</Struct>
<Struct Name="Svg.SvgUnit">
<Position X="18.25" Y="1.75" Width="1.5" />
<TypeIdentifier>
<HashCode>ABBAACAAAAAIAAYcgAIAAAAAAEAAAIAQAQAgAAEAAAA=</HashCode>
<FileName>DataTypes\SvgUnit.cs</FileName>
</TypeIdentifier>
<ShowAsAssociation>
<Property Name="Type" />
<Property Name="Value" />
</ShowAsAssociation>
</Struct>
<Enum Name="Svg.SvgFillRule">
<Position X="14" Y="1.25" Width="1.5" />
<TypeIdentifier>
<HashCode>AABAAAACAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Painting\SvgFillRule.cs</FileName>
</TypeIdentifier>
</Enum>
<Enum Name="Svg.SvgClipRule">
<Position X="14" Y="3.5" Width="1.5" />
<TypeIdentifier>
<HashCode>AABAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=</HashCode>
<FileName>Clipping and Masking\SvgClipRule.cs</FileName>
</TypeIdentifier>
</Enum>
<Enum Name="Svg.SvgStrokeLineCap">
<Position X="14" Y="4.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAAAAAAAACAAAAAAAAAABAAAAAAAAAAAAAAgAAIAAAA=</HashCode>
<FileName>Painting\SvgStrokeLineCap.cs</FileName>
</TypeIdentifier>
</Enum>
<Enum Name="Svg.SvgUnitType">
<Position X="20.25" Y="1.75" Width="1.5" />
<TypeIdentifier>
<HashCode>AAABAAAAAAEAgAAAAAABAAAAAAgAAEAAAAAAACEAAAA=</HashCode>
<FileName>DataTypes\SvgUnit.cs</FileName>
</TypeIdentifier>
</Enum>
<Font Name="Segoe UI" Size="9" />
</ClassDiagram>
\ No newline at end of file
......@@ -76,6 +76,7 @@ namespace Svg
{
this._dirty = true;
this._requiresSmoothRendering = false;
this.Fill = new SvgColourServer(); //in case fill attribute is not set by xml, default fill is black
}
/// <summary>
......@@ -121,6 +122,7 @@ namespace Svg
{
if (brush != null)
{
this.Path.FillMode = this.FillRule == SvgFillRule.NonZero ? FillMode.Winding : FillMode.Alternate;
renderer.FillPath(brush, this.Path);
}
}
......
......@@ -18,6 +18,7 @@ namespace Svg
/// <summary>
/// Gets or sets a value to determine whether the element will be rendered.
/// </summary>
[TypeConverter(typeof(SvgBoolConverter))]
[SvgAttribute("visibility")]
public virtual bool Visible
{
......@@ -31,7 +32,7 @@ namespace Svg
[SvgAttribute("fill")]
public virtual SvgPaintServer Fill
{
get { return (this.Attributes["Fill"] == null) ? new SvgColourServer() : (SvgPaintServer)this.Attributes["Fill"]; }
get { return (this.Attributes["Fill"] == null) ? null : (SvgPaintServer)this.Attributes["Fill"]; }
set { this.Attributes["Fill"] = value; }
}
......
......@@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
namespace Svg
{
......@@ -13,6 +14,7 @@ namespace Svg
/// that point to infinity in any direction and then examining the places where a segment of the
/// shape crosses the ray.</para>
/// </remarks>
[TypeConverter(typeof(SvgClipRuleConverter))]
public enum SvgClipRule
{
/// <summary>
......
......@@ -3,6 +3,7 @@ using System.ComponentModel;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
namespace Svg
{
......@@ -12,6 +13,16 @@ namespace Svg
[TypeConverter(typeof(SvgUnitCollectionConverter))]
public class SvgUnitCollection : List<SvgUnit>
{
public override string ToString()
{
string ret = "";
foreach (var unit in this)
{
ret += unit.ToString() + " ";
}
return ret;
}
}
/// <summary>
......@@ -49,5 +60,24 @@ namespace Svg
return base.ConvertFrom(context, culture, value);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
return ((SvgUnitCollection)value).ToString();
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
}
\ No newline at end of file
......@@ -137,7 +137,7 @@ namespace Svg
return string.Format("{0}, {1}, {2}, {3}",
viewBox.MinX.ToString(CultureInfo.InvariantCulture), viewBox.MinY.ToString(CultureInfo.InvariantCulture),
viewBox.MinX.ToString(CultureInfo.InvariantCulture), viewBox.MinY.ToString(CultureInfo.InvariantCulture));
viewBox.Width.ToString(CultureInfo.InvariantCulture), viewBox.Height.ToString(CultureInfo.InvariantCulture));
}
return base.ConvertTo(context, culture, value, destinationType);
......
......@@ -66,10 +66,7 @@ namespace Svg
if (!this.ViewBox.Equals(SvgViewBox.Empty))
{
if (this.ViewBox.MinX > 0 || this.ViewBox.MinY > 0)
{
renderer.TranslateTransform(this.ViewBox.MinX, this.ViewBox.MinY, MatrixOrder.Append);
}
renderer.TranslateTransform(-this.ViewBox.MinX, -this.ViewBox.MinY, MatrixOrder.Append);
renderer.ScaleTransform(this.Width.ToDeviceValue() / this.ViewBox.Width, this.Height.ToDeviceValue() / this.ViewBox.Height, MatrixOrder.Append);
}
......
using System;
using System.ComponentModel;
using System.Globalization;
namespace Svg
{
//just overrrides canconvert and returns true
public class BaseConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(string))
{
return true;
}
return base.CanConvertTo(context, destinationType);
}
}
public sealed class SvgBoolConverter : BaseConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value == null)
{
return true;
}
if (!(value is string))
{
throw new ArgumentOutOfRangeException("value must be a string.");
}
return (string)value == "visible" ? true : false;
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
return ((bool)value) ? "visible" : "hidden";
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
//converts enums to lower case strings
public class EnumBaseConverter<T> : BaseConverter
{
public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value == null)
{
return Activator.CreateInstance(typeof(T));
}
if (!(value is string))
{
throw new ArgumentOutOfRangeException("value must be a string.");
}
return (T)Enum.Parse(typeof(T), (string)value, true);
}
public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(string))
{
return ((T)value).ToString().ToLower();
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
//implementation for fill-rule
public sealed class SvgFillRuleConverter : EnumBaseConverter<SvgFillRule>
{
}
//implementaton for clip rule
public sealed class SvgClipRuleConverter : EnumBaseConverter<SvgClipRule>
{
}
}
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace Svg
{
[TypeConverter(typeof(SvgFillRuleConverter))]
public enum SvgFillRule
{
NonZero,
......
......@@ -48,7 +48,11 @@ namespace Svg
{
if (value is string)
{
return SvgPaintServerFactory.Create((string)value, (SvgDocument)context);
var s = (string) value;
if(s == "none")
return null;
else
return SvgPaintServerFactory.Create(s, (SvgDocument)context);
}
return base.ConvertFrom(context, culture, value);
......@@ -89,6 +93,10 @@ namespace Svg
{
return string.Format(CultureInfo.InvariantCulture, "url(#{0})", ((SvgPaintServer)value).ID);
}
else
{
return "none";
}
}
return base.ConvertTo(context, culture, value, destinationType);
......
......@@ -16,12 +16,16 @@
<OldToolsVersion>3.5</OldToolsVersion>
<UpgradeBackupLocation>
</UpgradeBackupLocation>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<IsWebBootstrapper>false</IsWebBootstrapper>
<SccProjectName>SAK</SccProjectName>
<SccLocalPath>SAK</SccLocalPath>
<SccAuxPath>SAK</SccAuxPath>
<SccProvider>SAK</SccProvider>
<SccProjectName>
</SccProjectName>
<SccLocalPath>
</SccLocalPath>
<SccAuxPath>
</SccAuxPath>
<SccProvider>
</SccProvider>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
......@@ -36,12 +40,13 @@
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<OutputPath>..\..\..\..\..\..\Dev\vvvv\vvvv\public\common\src\thirdparty\</OutputPath>
<DefineConstants>TRACE;DEBUG;REFLECTION</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
......@@ -50,7 +55,7 @@
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<OutputPath>..\..\..\..\..\..\Dev\vvvv\vvvv\public\common\src\thirdparty\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
......@@ -97,6 +102,7 @@
<Compile Include="Filter Effects\SvgFilterPrimitive.cs" />
<Compile Include="Filter Effects\feGaussianBlur\SvgGaussianBlur.cs" />
<Compile Include="Filter Effects\feMerge\SvgMerge.cs" />
<Compile Include="Painting\EnumConverters.cs" />
<Compile Include="SvgElementAttribute.cs" />
<Compile Include="SvgRenderer.cs" />
<Compile Include="Painting\SvgColourConverter.cs" />
......@@ -187,6 +193,9 @@
<ItemGroup>
<Folder Include="Web\Resources\" />
</ItemGroup>
<ItemGroup>
<None Include="Basic Shapes\DOM.cd" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
......
......@@ -8,6 +8,8 @@ using System.Drawing.Text;
using System.IO;
using System.Text;
using System.Xml;
using System.Threading;
using System.Globalization;
namespace Svg
{
......@@ -325,6 +327,27 @@ namespace Svg
var size = GetDimensions();
var bitmap = new Bitmap((int)Math.Ceiling(size.Width), (int)Math.Ceiling(size.Height));
try
{
Draw(bitmap);
}
catch
{
bitmap.Dispose();
throw;
}
//Trace.TraceInformation("End Render");
return bitmap;
}
/// <summary>
/// Renders the <see cref="SvgDocument"/> into a given Bitmap <see cref="Bitmap"/>.
/// </summary>
public virtual void Draw(Bitmap bitmap)
{
//Trace.TraceInformation("Begin Render");
try
{
using (var renderer = SvgRenderer.FromImage(bitmap))
......@@ -338,22 +361,36 @@ namespace Svg
}
catch
{
bitmap.Dispose();
throw;
}
//Trace.TraceInformation("End Render");
return bitmap;
}
public void Write(Stream stream)
{
//Save previous culture and switch to invariant for writing
var previousCulture = Thread.CurrentThread.CurrentCulture;
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
var xmlWriter = new XmlTextWriter(stream, Encoding.UTF8);
xmlWriter.Formatting = Formatting.Indented;
xmlWriter.WriteDocType("svg", "-//W3C//DTD SVG 1.1//EN", "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd", null);
this.WriteElement(xmlWriter);
xmlWriter.Close();
Thread.CurrentThread.CurrentCulture = previousCulture;
}
public void Write(string path)
{
using(var fs = new FileStream(path, FileMode.Create, FileAccess.Write))
{
this.Write(fs);
}
}
}
}
\ No newline at end of file
......@@ -297,6 +297,11 @@ namespace Svg
if (this.ElementName != String.Empty)
{
writer.WriteStartElement(this.ElementName);
if (this.ElementName == "svg")
{
writer.WriteAttributeString("xmlns", "http://www.w3.org/2000/svg");
writer.WriteAttributeString("version", "1.1");
}
}
this.WriteAttributes(writer);
}
......@@ -324,9 +329,23 @@ namespace Svg
if (propertyValue != null)
{
string value = (string)attr.Property.Converter.ConvertTo(propertyValue, typeof(string));
var type = propertyValue.GetType();
object defaultValue = null;
if(type.IsValueType)
defaultValue = Activator.CreateInstance(type);
if (!propertyValue.Equals(defaultValue) || type == typeof(float) || type == typeof(bool) || type == typeof(SvgColourServer))
{
string value = (string)attr.Property.Converter.ConvertTo(propertyValue, typeof(string));
writer.WriteAttributeString(attr.Attribute.Name, attr.Attribute.NameSpace, value);
writer.WriteAttributeString(attr.Attribute.Name, value);
}
}
else if(attr.Attribute.Name == "fill") //if fill equals null, write 'none'
{
string value = (string)attr.Property.Converter.ConvertTo(propertyValue, typeof(string));
writer.WriteAttributeString(attr.Attribute.Name, value);
}
}
}
......@@ -344,6 +363,11 @@ namespace Svg
protected virtual void WriteChildren(XmlTextWriter writer)
{
//write the content
if(!String.IsNullOrEmpty(this.Content))
writer.WriteString(this.Content);
//write all children
foreach (SvgElement child in this.Children)
{
child.Write(writer);
......
......@@ -19,7 +19,8 @@ namespace Svg
private SvgUnit _letterSpacing;
private SvgUnit _wordSpacing;
private SvgUnit _fontSize;
private Font _font;
private string _font;
private string _fontFamily;
private GraphicsPath _path;
private SvgTextAnchor _textAnchor = SvgTextAnchor.Start;
private static readonly SvgRenderer _stringMeasure;
......@@ -39,7 +40,7 @@ namespace Svg
/// </summary>
public SvgText()
{
this._font = new Font(new FontFamily("Times New Roman"), 1.0f);
this._fontFamily = "Times New Roman";
this._fontSize = new SvgUnit(0.0f);
}
......@@ -58,7 +59,7 @@ namespace Svg
public virtual string Text
{
get { return base.Content; }
set { base.Content = value; this.IsPathDirty = true; }
set { base.Content = value; this.IsPathDirty = true; this.Content = value; }
}
/// <summary>
......@@ -118,10 +119,10 @@ namespace Svg
/// Indicates which font family is to be used to render the text.
/// </summary>
[SvgAttribute("font-family")]
public virtual Font FontFamily
public virtual string FontFamily
{
get { return this._font; }
set { this._font = value; this.IsPathDirty = true; }
get { return this._fontFamily; }
set { this._fontFamily = value; this.IsPathDirty = true; }
}
/// <summary>
......@@ -138,7 +139,7 @@ namespace Svg
/// Set all font information.
/// </summary>
[SvgAttribute("font")]
public virtual Font Font
public virtual string Font
{
get { return this._font; }
set { this._font = value; this.IsPathDirty = true; }
......@@ -186,12 +187,12 @@ namespace Svg
get { return this.Path.GetBounds(); }
}
static private int MeasureString(SvgRenderer renderer, string text, Font font)
static private RectangleF MeasureString(SvgRenderer renderer, string text, Font font)
{
GraphicsPath p = new GraphicsPath();
p.AddString(text, font.FontFamily, 0, font.Size, new PointF(0.0f, 0.0f), StringFormat.GenericTypographic);
p.Transform(renderer.Transform);
return (int)(p.GetBounds().Width + 1.0f);
return p.GetBounds();
}
/// <summary>
......@@ -210,22 +211,23 @@ namespace Svg
{
fontSize = 1.0f;
}
int stringWidth;
RectangleF stringBounds;
PointF location = PointF.Empty;
Font font = new Font(this._fontFamily, fontSize, FontStyle.Regular, GraphicsUnit.Pixel);
// Minus FontSize because the x/y coords mark the bottom left, not bottom top.
switch (this.TextAnchor)
{
case SvgTextAnchor.Start:
location = new PointF(this.X.ToDeviceValue(this), this.Y.ToDeviceValue(this, true) - fontSize);
location = new PointF(this.X.ToDeviceValue(this), this.Y.ToDeviceValue(this, true) - this._fontSize);
break;
case SvgTextAnchor.Middle:
stringWidth = SvgText.MeasureString(_stringMeasure, this.Text, new Font(this._font.FontFamily, fontSize));
location = new PointF(this.X.ToDeviceValue(this) - (stringWidth / 2), this.Y.ToDeviceValue(this, true) - fontSize);
stringBounds = SvgText.MeasureString(_stringMeasure, this.Text, font);
location = new PointF(this.X.ToDeviceValue(this) - (stringBounds.Width / 2), this.Y.ToDeviceValue(this, true) - this._fontSize);
break;
case SvgTextAnchor.End:
stringWidth = SvgText.MeasureString(_stringMeasure, this.Text, new Font(this._font.FontFamily, fontSize));
location = new PointF(this.X.ToDeviceValue(this) - stringWidth, this.Y.ToDeviceValue(this, true) - fontSize);
stringBounds = SvgText.MeasureString(_stringMeasure, this.Text, font);
location = new PointF(this.X.ToDeviceValue(this) - stringBounds.Width, this.Y.ToDeviceValue(this, true) - this._fontSize);
break;
}
......@@ -249,13 +251,13 @@ namespace Svg
char[] characters = word.ToCharArray();
foreach (char currentCharacter in characters)
{
_path.AddString(currentCharacter.ToString(), this._font.FontFamily, 0, fontSize, location, StringFormat.GenericTypographic);
_path.AddString(currentCharacter.ToString(), new FontFamily(this._fontFamily), 0, fontSize, location, StringFormat.GenericTypographic);
location = new PointF(_path.GetBounds().Width + start + letterSpacing, location.Y);
}
}
else
{
_path.AddString(word, this._font.FontFamily, 0, fontSize, location, StringFormat.GenericTypographic);
_path.AddString(word, new FontFamily(this._fontFamily), 0, fontSize, location, StringFormat.GenericTypographic);
}
// Move the location of the word to be written along
......@@ -266,7 +268,7 @@ namespace Svg
{
if (!string.IsNullOrEmpty(this.Text))
{
_path.AddString(this.Text, this._font.FontFamily, 0, fontSize, location, StringFormat.GenericTypographic);
_path.AddString(this.Text, new FontFamily(this._fontFamily), 0, fontSize, location, StringFormat.GenericTypographic);
}
}
......
......@@ -194,7 +194,7 @@ namespace Svg.Transforms
if (transforms != null)
{
return string.Join(",", transforms.Select(t => t.WriteToString()).ToArray());
return string.Join(" ", transforms.Select(t => t.WriteToString()).ToArray());
}
}
......
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