Commit 32e70005 authored by peracto's avatar peracto Committed by mrbean-bremen
Browse files

Use element applies referenced viewBox scaling, added FontManager (#414)

* use element applies referenced viewBox scaling
* created FontManager
parent f7c5fb06
......@@ -16,3 +16,4 @@ Tests/**/*.suo
*.trx
Source/TestResults/
Source/.vs
/Source/Svg.sln.DotSettings.user
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
namespace Svg
......@@ -79,6 +80,21 @@ namespace Svg
set { this.Attributes["y"] = value; }
}
[SvgAttribute("width")]
public virtual SvgUnit Width
{
get { return this.Attributes.GetAttribute<SvgUnit>("width"); }
set { this.Attributes["width"] = value; }
}
[SvgAttribute("height")]
public virtual SvgUnit Height
{
get { return this.Attributes.GetAttribute<SvgUnit>("height"); }
set { this.Attributes["height"] = value; }
}
/// <summary>
/// Applies the required transforms to <see cref="ISvgRenderer"/>.
/// </summary>
......@@ -99,6 +115,8 @@ namespace Svg
{
this.X = 0;
this.Y = 0;
this.Width = 0;
this.Height = 0;
}
public override System.Drawing.Drawing2D.GraphicsPath Path(ISvgRenderer renderer)
......@@ -107,15 +125,33 @@ namespace Svg
return (element != null && !this.HasRecursiveReference()) ? element.Path(renderer) : null;
}
/// <summary>
/// Gets an <see cref="SvgPoint"/> representing the top left point of the rectangle.
/// </summary>
public SvgPoint Location
{
get { return new SvgPoint(X, Y); }
}
/// <summary>
/// Gets the bounds of the element.
/// </summary>
/// <value>The bounds.</value>
public override System.Drawing.RectangleF Bounds
{
get
{
var ew = this.Width.ToDeviceValue(null, UnitRenderingType.Horizontal, this);
var eh = this.Height.ToDeviceValue(null, UnitRenderingType.Vertical, this);
if (ew > 0 && eh > 0)
return TransformedBounds(new RectangleF(this.Location.ToDeviceValue(null, this),
new SizeF(ew, eh)));
var element = this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement) as SvgVisualElement;
if (element != null)
{
return element.Bounds;
}
return new System.Drawing.RectangleF();
}
}
......@@ -131,6 +167,19 @@ namespace Svg
var element = this.OwnerDocument.IdManager.GetElementById(this.ReferencedElement) as SvgVisualElement;
if (element != null)
{
var ew = Width.ToDeviceValue(renderer, UnitRenderingType.Horizontal, this);
var eh = Height.ToDeviceValue(renderer, UnitRenderingType.Vertical, this);
if (ew > 0 && eh > 0)
{
var viewBox = element.Attributes.GetAttribute<SvgViewBox>("viewBox");
if (viewBox!=SvgViewBox.Empty && Math.Abs(ew - viewBox.Width) > float.Epsilon && Math.Abs(eh - viewBox.Height) > float.Epsilon)
{
var sw = ew / viewBox.Width;
var sh = eh / viewBox.Height;
renderer.ScaleTransform(sw, sh, MatrixOrder.Prepend);
}
}
var origParent = element.Parent;
element._parent = this;
// as the new parent may have other styles that are inherited,
......
......@@ -122,6 +122,7 @@
<Compile Include="Rendering\ISvgRenderer.cs" />
<Compile Include="Rendering\SvgRendering.cs" />
<Compile Include="SvgElementStyle.cs" />
<Compile Include="SvgFontManager.cs" />
<Compile Include="SvgNodeReader.cs" />
<Compile Include="Css\CssQuery.cs" />
<Compile Include="Css\SvgElementOps.cs" />
......
......@@ -434,8 +434,6 @@ namespace Svg
{
// Split font family list on "," and then trim start and end spaces and quotes.
var fontParts = (fontFamilyList ?? string.Empty).Split(new[] { ',' }).Select(fontName => fontName.Trim(new[] { '"', ' ', '\'' }));
var families = System.Drawing.FontFamily.Families;
Func<FontFamily, bool> getFamily;
FontFamily family;
IEnumerable<SvgFontFace> sFaces;
......@@ -444,13 +442,10 @@ namespace Svg
foreach (var f in fontParts)
{
if (doc != null && doc.FontDefns().TryGetValue(f, out sFaces)) return sFaces;
getFamily = new Func<FontFamily, bool>(ff => string.Equals(ff.Name, f, StringComparison.OrdinalIgnoreCase));
family = families.FirstOrDefault(getFamily);
family = SvgFontManager.FindFont(f);
if (family != null) return family;
family = PrivateFonts.Families.FirstOrDefault(getFamily);
family = PrivateFonts.Families.FirstOrDefault(ff => string.Equals(ff.Name, f, StringComparison.OrdinalIgnoreCase));
if (family != null) return family;
switch (f.ToLower())
{
case "serif":
......@@ -466,4 +461,4 @@ namespace Svg
return System.Drawing.FontFamily.GenericSansSerif;
}
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Text;
using System.IO;
using System.Linq;
namespace Svg
{
/// <summary>
/// Manages access to <see cref="SystemFonts"/> and any privately loaded fonts.
/// When a font is requested in the render process, if the font is not found as an embedded SvgFont, the render
/// process will SvgFontManager.FindFont method.
/// </summary>
public static class SvgFontManager
{
private static readonly Dictionary<string, FontFamily> SystemFonts;
public static Func<string, FontFamily> FontLoaderCallback;
static SvgFontManager()
{
SystemFonts = FontFamily.Families.ToDictionary(ff => ff.Name.ToLower());
}
/// <summary>
/// Loads a font from the given path.
/// </summary>
/// <param name="path">A <see cref="string"/> containing the full path to the font file.</param>
/// <returns>An <see cref="FontFamily"/> of the loaded font.</returns>
public static FontFamily LoadFontFamily(string path)
{
var pfc = new PrivateFontCollection();
var fp = Path.GetFullPath(path);
pfc.AddFontFile(fp);
return pfc.Families.Length == 0 ? null : pfc.Families[0];
}
/// <summary>
/// This method searches a dictionary of fonts (pre loaded with the system fonts). If a
/// font can't be found and a callback has been provided - then the callback should perform
/// any validation and return a font (or null if not found/error).
/// Where a font can't be located it is the responsibility of the caller to perform any
/// exception handling.
/// </summary>
/// <param name="name">A <see cref="string"/> containing the FamilyName of the font.</param>
/// <returns>An <see cref="FontFamily"/> of the loaded font or null is not located.</returns>
public static FontFamily FindFont(string name)
{
if (name == null) return null;
FontFamily ff = null;
if (SystemFonts.TryGetValue(name.ToLower(), out ff)) return ff;
if (FontLoaderCallback == null) return null;
var ff2 = FontLoaderCallback(name);
SystemFonts.Add(name.ToLower(), ff2);
return ff2;
}
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -199,5 +199,6 @@ __issue-385-01_Test_text-anchor-middle
__issue-398-01
__pull_request-373-01
__pull_request-374-01
__pull_request-414-01
__Telefunken_FuBK_test_pattern
__title
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="flag-icon-css-eu-small" viewBox="0 0 640 480">
<defs>
<symbol id="s" viewBox="0 0 640 480">
<image href="./__issue-323-02.svg" width="640" height="480" />
</symbol>
</defs>
<use x="0" y="0" href="#s" width="320" height="240" />
<image x="0" y="240" width="320" height="240" href="./__issue-323-02.svg" />
<rect x="0" y="0" width="320" height="240" fill="red" opacity="0.25" />
</svg>
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