<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[173739] trunk/Source/WebCore</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/173739">173739</a></dd>
<dt>Author</dt> <dd>mmaxfield@apple.com</dd>
<dt>Date</dt> <dd>2014-09-18 15:52:21 -0700 (Thu, 18 Sep 2014)</dd>
</dl>

<h3>Log Message</h3>
<pre>Text laid out with the SVG -&gt; OTF font converter does not have the same metrics as with the SVG font code path
https://bugs.webkit.org/show_bug.cgi?id=136907

Reviewed by Darin Adler.

There are three things that are causing text laid out with the SVG -&gt; OTF font converter to not have metrics that
measure our existing SVG codepath. They are:

1. Creating a font with a 0 ascent or descent makes OS X think that something is wrong with the font, and take
a different codepath when trying to parse ascent and descent information. This patch checks for this condition
and sets the ascent/descent to 1 FUnit instead (which is generally much smaller than a pixel).
2. Our SVG font codepath hardcodes a line gap of 1/10th of the font size for every font. This patch makes the
font converter obey this.
3. The converter was not allowing for default glyph advances as per the SVG font specification. This patch
does so.

No new tests yet, but they will come soon! I promise!

* svg/SVGToOTFFontConversion.cpp:
(WebCore::SVGToOTFFontConverter::appendHHEATable):
(WebCore::SVGToOTFFontConverter::SVGToOTFFontConverter):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoresvgSVGToOTFFontConversioncpp">trunk/Source/WebCore/svg/SVGToOTFFontConversion.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (173738 => 173739)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2014-09-18 22:49:24 UTC (rev 173738)
+++ trunk/Source/WebCore/ChangeLog        2014-09-18 22:52:21 UTC (rev 173739)
</span><span class="lines">@@ -1,3 +1,27 @@
</span><ins>+2014-09-17  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        Text laid out with the SVG -&gt; OTF font converter does not have the same metrics as with the SVG font code path
+        https://bugs.webkit.org/show_bug.cgi?id=136907
+
+        Reviewed by Darin Adler.
+
+        There are three things that are causing text laid out with the SVG -&gt; OTF font converter to not have metrics that
+        measure our existing SVG codepath. They are:
+
+        1. Creating a font with a 0 ascent or descent makes OS X think that something is wrong with the font, and take
+        a different codepath when trying to parse ascent and descent information. This patch checks for this condition
+        and sets the ascent/descent to 1 FUnit instead (which is generally much smaller than a pixel).
+        2. Our SVG font codepath hardcodes a line gap of 1/10th of the font size for every font. This patch makes the
+        font converter obey this.
+        3. The converter was not allowing for default glyph advances as per the SVG font specification. This patch
+        does so.
+
+        No new tests yet, but they will come soon! I promise!
+
+        * svg/SVGToOTFFontConversion.cpp:
+        (WebCore::SVGToOTFFontConverter::appendHHEATable):
+        (WebCore::SVGToOTFFontConverter::SVGToOTFFontConverter):
+
</ins><span class="cx"> 2014-09-18  Daniel Bates  &lt;dabates@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         REGRESSION (r168921): SVG elements may be unnecessarily rebuilt
</span></span></pre></div>
<a id="trunkSourceWebCoresvgSVGToOTFFontConversioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/svg/SVGToOTFFontConversion.cpp (173738 => 173739)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/svg/SVGToOTFFontConversion.cpp        2014-09-18 22:49:24 UTC (rev 173738)
+++ trunk/Source/WebCore/svg/SVGToOTFFontConversion.cpp        2014-09-18 22:52:21 UTC (rev 173739)
</span><span class="lines">@@ -213,10 +213,21 @@
</span><span class="cx">         descent = m_fontFaceElement-&gt;descent();
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    // Many platforms will assume that a 0 ascent or descent means that the platform should synthesize a font
+    // based on a heuristic. However, many SVG fonts legitimitely have a 0 ascent or descent. Therefore,
+    // we should specify a single FUnit instead, which is as close as we can get to 0 without actually being
+    // it.
+    if (!ascent)
+        ascent = 1;
+    if (!descent)
+        descent = 1;
+
</ins><span class="cx">     write32(result, 0x00010000); // Version
</span><span class="cx">     write16(result, ascent);
</span><span class="cx">     write16(result, descent);
</span><del>-    write16(result, 0); // Line gap
</del><ins>+    // WebKit's SVG codepath hardcodes the line gap to be 1/10th of the font size (see r29719). Matching that
+    // allows us to have consistent renderings between the two paths.
+    write16(result, unitsPerEm / 10); // Line gap
</ins><span class="cx">     write16(result, clampTo&lt;uint16_t, float&gt;(m_advanceWidthMax));
</span><span class="cx">     write16(result, clampTo&lt;int16_t, float&gt;(m_boundingBox.x())); // Minimum left side bearing
</span><span class="cx">     write16(result, clampTo&lt;int16_t, float&gt;(m_minRightSideBearing)); // Minimum right side bearing
</span><span class="lines">@@ -670,6 +681,12 @@
</span><span class="cx">     , m_weight(5)
</span><span class="cx">     , m_italic(false)
</span><span class="cx"> {
</span><ins>+    bool ok = true;
+    float defaultAdvance = fontElement.fastGetAttribute(SVGNames::horiz_adv_xAttr).toFloat(&amp;ok);
+    if (!ok)
+        defaultAdvance = 0;
+    m_advanceWidthMax = std::max(m_advanceWidthMax, defaultAdvance);
+
</ins><span class="cx">     // FIXME: Use the missingGlyph info
</span><span class="cx">     Vector&lt;char, 1&gt; notdefCharString;
</span><span class="cx">     notdefCharString.append(endChar);
</span><span class="lines">@@ -679,16 +696,11 @@
</span><span class="cx">         auto&amp; unicodeAttribute = glyph.fastGetAttribute(SVGNames::unicodeAttr);
</span><span class="cx">         // Only support Basic Multilingual Plane w/o ligatures for now
</span><span class="cx">         if (unicodeAttribute.length() == 1) {
</span><del>-            float effectiveAdvance = 0;
-            auto&amp; advanceAttribute = glyph.fastGetAttribute(SVGNames::horiz_adv_xAttr);
-            if (!advanceAttribute.isEmpty()) {
-                bool ok = true;
-                float advance = advanceAttribute.toFloat(&amp;ok);
-                if (ok) {
-                    effectiveAdvance = advance;
-                    m_advanceWidthMax = std::max(m_advanceWidthMax, advance);
-                }
-            }
</del><ins>+            bool ok = true;
+            float effectiveAdvance = glyph.fastGetAttribute(SVGNames::horiz_adv_xAttr).toFloat(&amp;ok);
+            if (!ok)
+                effectiveAdvance = defaultAdvance;
+            m_advanceWidthMax = std::max(m_advanceWidthMax, effectiveAdvance);
</ins><span class="cx"> 
</span><span class="cx">             FloatRect glyphBoundingBox;
</span><span class="cx">             const auto&amp; path = transcodeGlyphPaths(effectiveAdvance, glyph, glyphBoundingBox);
</span></span></pre>
</div>
</div>

</body>
</html>