Skip to content

Commit

Permalink
Svg image preview is displayed unscaled and uncentered (#8996)
Browse files Browse the repository at this point in the history
* Fixed screen centering and scaling problem with SVG files

* Little shorter code.

* Improved exception caching

* typo

* fixed upscaling problem

* add CSS that IE6 can support it

* typo

* adding in spelling

Co-authored-by: Clint Rutkas <clint@rutkas.com>
  • Loading branch information
Drakula44 and crutkas committed Feb 22, 2021
1 parent a786fd3 commit 2b0e329
Show file tree
Hide file tree
Showing 3 changed files with 112 additions and 1 deletion.
4 changes: 4 additions & 0 deletions .github/actions/spell-check/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2335,6 +2335,8 @@ vk
VKey
VKTAB
vm
vmax
vmin
Voicemail
VOS
VREDRAW
Expand All @@ -2348,6 +2350,7 @@ VSTS
VSTT
VTABLE
Vtbl
vw
Vx
watsonportal
wav
Expand Down Expand Up @@ -2480,6 +2483,7 @@ xa
xamarin
xaml
XAngle
XAttribute
xbf
XBind
XBUTTON
Expand Down
14 changes: 13 additions & 1 deletion src/modules/previewpane/SvgPreviewHandler/SvgPreviewControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,18 @@ public override void DoPreview<T>(T dataSource)
return;
}

try
{
svgData = SvgPreviewHandlerHelper.AddStyleSVG(svgData);
}
#pragma warning disable CA1031 // Do not catch general exception types
catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
{
_browser.ScrollBarsEnabled = true;
PowerToysTelemetry.Log.WriteEvent(new SvgFilePreviewError { Message = ex.Message });
}

InvokeOnControlThread(() =>
{
try
Expand Down Expand Up @@ -127,7 +139,7 @@ private void AddBrowserControl(string svgData)
_browser.Dock = DockStyle.Fill;
_browser.IsWebBrowserContextMenuEnabled = false;
_browser.ScriptErrorsSuppressed = true;
_browser.ScrollBarsEnabled = true;
_browser.ScrollBarsEnabled = false;
_browser.AllowNavigation = false;
Controls.Add(_browser);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,5 +68,100 @@ public static bool CheckBlockedElements(string svgData)

return foundBlockedElement;
}

/// <summary>
/// Add proper
/// </summary>
/// <param name="stringSvgData">Input Svg</param>
/// <returns>Returns modified svgData with added style</returns>
public static string AddStyleSVG(string stringSvgData)
{
XElement svgData = XElement.Parse(stringSvgData);

var attributes = svgData.Attributes();
string width = string.Empty;
string height = string.Empty;
string widthR = string.Empty;
string heightR = string.Empty;
string oldStyle = string.Empty;

// Get width and height of element and remove it afterwards because it will be added inside style attribute
for (int i = 0; i < attributes.Count(); i++)
{
if (attributes.ElementAt(i).Name == "height")
{
height = attributes.ElementAt(i).Value;
attributes.ElementAt(i).Remove();
i--;
}
else if (attributes.ElementAt(i).Name == "width")
{
width = attributes.ElementAt(i).Value;
attributes.ElementAt(i).Remove();
i--;
}
else if (attributes.ElementAt(i).Name == "style")
{
oldStyle = attributes.ElementAt(i).Value;
attributes.ElementAt(i).Remove();
i--;
}
}

svgData.ReplaceAttributes(attributes);

height = CheckUnit(height);
width = CheckUnit(width);
heightR = RemoveUnit(height);
widthR = RemoveUnit(width);

string centering = "position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%);";

// Because WebBrowser class is based on IE version that do not support max-width and max-height extra CSS is needed for it to work.
string scaling = $"max-width: {width} ; max-height: {height} ;";
scaling += $" _height:expression(this.scrollHeight > {heightR} ? \" {height}\" : \"auto\"); _width:expression(this.scrollWidth > {widthR} ? \"{width}\" : \"auto\");";

svgData.Add(new XAttribute("style", scaling + centering + oldStyle));
return svgData.ToString();
}

/// <summary>
/// If there is a CSS unit at the end return the same string, else return the string with a px unit at the end
/// </summary>
/// <param name="length">CSS length</param>
/// <returns>Returns modified length</returns>
private static string CheckUnit(string length)
{
string[] cssUnits = { "cm", "mm", "in", "px", "pt", "pc", "em", "ex", "ch", "rem", "vw", "vh", "vmin", "vmax", "%" };
foreach (var unit in cssUnits)
{
if (length.EndsWith(unit, System.StringComparison.CurrentCultureIgnoreCase))
{
return length;
}
}

return length + "px";
}

/// <summary>
/// Remove a CSS unit from the end of the string
/// </summary>
/// <param name="length">CSS length</param>
/// <returns>Returns modified length</returns>
private static string RemoveUnit(string length)
{
string[] cssUnits = { "cm", "mm", "in", "px", "pt", "pc", "em", "ex", "ch", "rem", "vw", "vh", "vmin", "vmax", "%" };
foreach (var unit in cssUnits)
{
if (length.EndsWith(unit, System.StringComparison.CurrentCultureIgnoreCase))
{
length = length.Remove(length.Length - unit.Length);
return length;
}
}

return length;
}
}
}

0 comments on commit 2b0e329

Please sign in to comment.