Skip to content

Commit

Permalink
Merge pull request #450 from ndw/svg-in
Browse files Browse the repository at this point in the history
Support SVG height and width properties with units
  • Loading branch information
ndw authored Jan 16, 2024
2 parents 32dacdf + 296a236 commit 7a50833
Show file tree
Hide file tree
Showing 4 changed files with 1,058 additions and 12 deletions.
67 changes: 55 additions & 12 deletions buildSrc/src/main/java/org/docbook/xsltng/extensions/ImageCall.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,13 @@
import java.io.InputStreamReader;
import java.net.URL;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

abstract public class ImageCall extends ExtensionFunctionCall {
public static final double SVG_DPI = 96.0;
private final static String svgNamespace = "http://www.w3.org/2000/svg";
private final static Pattern dimension = Pattern.compile("^\\s*([-+]?[0-9]*(\\.[0-9]*))\\s*([a-zA-Z]+)\\s*$");

protected DebuggingLogger logger = null;
protected XPathContext context = null;
Expand Down Expand Up @@ -121,23 +125,15 @@ protected XdmMap parseProperty(XdmMap map, String name, String value, int tagTyp
}
break;
case "width":
// This property must be returned as an integer; round if necessary
try {
float fwidth = Float.parseFloat(value);
int width = Math.round(fwidth);
Integer width = convertDimension(value);
if (width != null) {
map = map.put(new XdmAtomicValue("width"), new XdmAtomicValue(width));
} catch (NumberFormatException nfe) {
// nevermind
}
break;
case "height":
// This property must be returned as an integer; round if necessary
try {
float fheight = Float.parseFloat(value);
int height = Math.round(fheight);
Integer height = convertDimension(value);
if (height != null) {
map = map.put(new XdmAtomicValue("height"), new XdmAtomicValue(height));
} catch (NumberFormatException nfe) {
// nevermind
}
break;
default:
Expand All @@ -153,6 +149,53 @@ protected XdmMap parseProperty(XdmMap map, String name, String value, int tagTyp
return map;
}

private Integer convertDimension(String value) {
// This property must be returned as an integer; round if necessary
// What if we have units?
String unit = null;
double dwidth = 0.0;

try {
Matcher matches = dimension.matcher(value);
if (matches.find()) {
dwidth = Double.parseDouble(matches.group(1));
unit = matches.group(3).toLowerCase();
} else {
dwidth = Double.parseDouble(value);
}

if (unit != null) {
switch (unit) {
case "in":
dwidth = dwidth * SVG_DPI;
break;
case "cm":
dwidth = dwidth * SVG_DPI / 2.54;
break;
case "mm":
dwidth = dwidth * SVG_DPI / 25.4;
break;
case "pt":
dwidth = dwidth * SVG_DPI / 72.0;
break;
case "pc":
dwidth = dwidth * SVG_DPI / 6.0;
break;
case "px":
break;
default:
System.err.printf("Unrecognized SVG unit '%s'. Assuming pixels.%n", unit);
}
}

return Math.round((float) dwidth);
} catch (NumberFormatException nfe) {
// nevermind
}

return null;
}

private XdmMap parseBox(XdmMap map, String line) {
int [] corners = new int [4];
int count = 0;
Expand Down
8 changes: 8 additions & 0 deletions src/test/resources/expected/mediaobject.006.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" class="no-js"><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><script>(function(H){H.className=H.className.replace(/\bno-js\b/,'js')})(document.documentElement)</script><title>SVG Graphic Dimensions</title><meta name="viewport" content="width=device-width, initial-scale=1.0"/><link href="https://purl.org/dc/elements/1.1/" rel="schema.dc"/><meta content="2011-04-22T17:02:00-06:00" name="dc.modified"/><meta content="DocBook xslTNG" name="generator"/><link href="./css/docbook.css" rel="stylesheet" media="screen"/></head><body class="home"><nav class="top"></nav><main><article class="article component"><header><h1>SVG Graphic Dimensions</h1><div class="author"><h3><span class="first-last personname"><span class="firstname">Frank</span> <span class="surname">Steimke</span></span></h3></div></header><p>Check scaling an svg image where Dimensions are given in SVG file in Inches: <code>&lt;sgv
width="24.09375in" height="9.40625in"&gt;</code>. The image is created by the
<span class="productname">MagicDraw</span> UML Software.</p><p><a href="https://github.com/docbook/xslTNG/issues/432" class="link">Issue 432</a> is that
the generated HTML creates an <code>img</code> with wrong size:
<code>style="width:144px;height:96px;"</code> (which is <code>1.5in x 1.0in</code>). </p><p>Function <code>f:object-properties</code> in <code class="filename">objects.xsl</code> uses the
external function <code>ext:image-metadata</code>, which seems to fail when dimensions in an
SVG file are given as value with units.</p><div id="R_informaltable1" class="informalobject informaltable"><table><colgroup><col style="width: 40%"/><col style="width: 20%"/><col style="width: 20%"/><col style="width: 20%"/></colgroup><thead><tr><th class="bleft btop colsep left rowsep"></th><th class="btop center colsep rowsep" colspan="2">Original Size</th><th class="btop colsep right rowsep">Scaled 25%</th></tr><tr><th class="bleft colsep left rowsep"></th><th class="colsep right rowsep">Inch</th><th class="colsep right rowsep">px</th><th class="colsep right rowsep">px</th></tr></thead><tbody><tr><td class="bleft btop colsep left rowsep">Height</td><td class="btop colsep right rowsep">9,40625</td><td class="btop colsep right rowsep">903</td><td class="btop colsep right rowsep">226</td></tr><tr><td class="bleft colsep left rowsep">Width</td><td class="colsep right rowsep">24,09375</td><td class="colsep right rowsep">2313</td><td class="colsep right rowsep">578</td></tr></tbody></table></div><div id="R_fig1" class="figure formalobject"><div class="mediaobject"><div class="media image"><span class="viewport-table"><span class="viewport-row"><span class="viewport-cell" style="vertical-align:middle;"><span><span class="viewport"><picture class="imageobject"><img src="media/EvidenceRequest.svg" style="width:578px;height:226px;"/></picture></span></span></span></span></span></div><div class="caption"><p>This is an SVG Image scaled by 25%. Expected Dimensions are 578px x 226
px</p></div></div><header><div class="title">Figure <span class="label">1</span><span class="sep"></span>SVG Image scaled by 25%</div></header></div></article></main><nav class="bottom"></nav></body></html>
Loading

0 comments on commit 7a50833

Please sign in to comment.