<!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>[187527] trunk</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/187527">187527</a></dd>
<dt>Author</dt> <dd>mcatanzaro@igalia.com</dd>
<dt>Date</dt> <dd>2015-07-28 16:37:10 -0700 (Tue, 28 Jul 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>[Freetype] Always allow font matching for strong aliases
https://bugs.webkit.org/show_bug.cgi?id=147057

Reviewed by Martin Robinson.

Source/WebCore:

Tests: platform/gtk/fonts/font-family-fallback-ignores-weak-aliases.html
       platform/gtk/fonts/font-family-fallback-respects-strong-aliases.html

Treat fonts that are strongly-aliased to each other as if they were identical for the
purposes of CSS font fallback. This improves the layout of many web pages by allowing
fontconfig to replace fonts with metric-compatible equivalents (e.g. Arial -&gt; Liberation
Sans) instead of rejecting the metric-compatible font as unsuitable.

* platform/graphics/cairo/RefPtrCairo.cpp:
(WTF::refIfNotNull):
(WTF::derefIfNotNull):
* platform/graphics/cairo/RefPtrCairo.h:
* platform/graphics/freetype/FcUniquePtr.h: Added.
(WebCore::FcPtrDeleter&lt;FcFontSet&gt;::operator()):
(WebCore::FcPtrDeleter&lt;FcLangSet&gt;::operator()):
(WebCore::FcPtrDeleter&lt;FcObjectSet&gt;::operator()):
* platform/graphics/freetype/FontCacheFreeType.cpp:
(WebCore::strengthOfFirstAlias):
(WebCore::strongAliasesForFamily):
(WebCore::areStronglyAliased):
(WebCore::FontCache::createFontPlatformData):

Tools:

Create family aliases needed for the new layout tests.

* WebKitTestRunner/gtk/fonts/fonts.conf:

LayoutTests:

* platform/gtk/fonts/font-family-fallback-ignores-weak-aliases-expected.html: Added.
* platform/gtk/fonts/font-family-fallback-ignores-weak-aliases.html: Added.
* platform/gtk/fonts/font-family-fallback-respects-strong-aliases-expected.html: Added.
* platform/gtk/fonts/font-family-fallback-respects-strong-aliases.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscairoRefPtrCairocpp">trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscairoRefPtrCairoh">trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfreetypeFontCacheFreeTypecpp">trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsWebKitTestRunnergtkfontsfontsconf">trunk/Tools/WebKitTestRunner/gtk/fonts/fonts.conf</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsplatformgtkfontsfontfamilyfallbackignoresweakaliasesexpectedhtml">trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-ignores-weak-aliases-expected.html</a></li>
<li><a href="#trunkLayoutTestsplatformgtkfontsfontfamilyfallbackignoresweakaliaseshtml">trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-ignores-weak-aliases.html</a></li>
<li><a href="#trunkLayoutTestsplatformgtkfontsfontfamilyfallbackrespectsstrongaliasesexpectedhtml">trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-respects-strong-aliases-expected.html</a></li>
<li><a href="#trunkLayoutTestsplatformgtkfontsfontfamilyfallbackrespectsstrongaliaseshtml">trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-respects-strong-aliases.html</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsfreetypeFcUniquePtrh">trunk/Source/WebCore/platform/graphics/freetype/FcUniquePtr.h</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (187526 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-07-28 23:21:15 UTC (rev 187526)
+++ trunk/LayoutTests/ChangeLog        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-07-28  Michael Catanzaro  &lt;mcatanzaro@igalia.com&gt;
+
+        [Freetype] Always allow font matching for strong aliases
+        https://bugs.webkit.org/show_bug.cgi?id=147057
+
+        Reviewed by Martin Robinson.
+
+        * platform/gtk/fonts/font-family-fallback-ignores-weak-aliases-expected.html: Added.
+        * platform/gtk/fonts/font-family-fallback-ignores-weak-aliases.html: Added.
+        * platform/gtk/fonts/font-family-fallback-respects-strong-aliases-expected.html: Added.
+        * platform/gtk/fonts/font-family-fallback-respects-strong-aliases.html: Added.
+
</ins><span class="cx"> 2015-07-28  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Crash when encountering characters whose natural font is one we can't look up
</span></span></pre></div>
<a id="trunkLayoutTestsplatformgtkfontsfontfamilyfallbackignoresweakaliasesexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-ignores-weak-aliases-expected.html (0 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-ignores-weak-aliases-expected.html                                (rev 0)
+++ trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-ignores-weak-aliases-expected.html        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;body style=&quot;font-family:serif;&quot;&gt;
+This test ensures that if a font is weakly aliased to another, the alias is
+ignored for the purposes of CSS font fallback. This test passes if it is
+displayed in a serif font and fails if it is displayed in FreeMono.
+&lt;/body&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformgtkfontsfontfamilyfallbackignoresweakaliaseshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-ignores-weak-aliases.html (0 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-ignores-weak-aliases.html                                (rev 0)
+++ trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-ignores-weak-aliases.html        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;body style=&quot;font-family:FamilyWeakAliasedToFreeMono,serif;&quot;&gt;
+This test ensures that if a font is weakly aliased to another, the alias is
+ignored for the purposes of CSS font fallback. This test passes if it is
+displayed in a serif font and fails if it is displayed in FreeMono.
+&lt;/body&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformgtkfontsfontfamilyfallbackrespectsstrongaliasesexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-respects-strong-aliases-expected.html (0 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-respects-strong-aliases-expected.html                                (rev 0)
+++ trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-respects-strong-aliases-expected.html        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;body style=&quot;font-family:FreeMono;&quot;&gt;
+This test ensures that if a font is strongly aliased to another, those fonts are
+treated as identical for the purposes of CSS font fallback. This test passes if
+it is displayed in FreeMono and fails if it is displayed in a serif font.
+&lt;/body&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsplatformgtkfontsfontfamilyfallbackrespectsstrongaliaseshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-respects-strong-aliases.html (0 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-respects-strong-aliases.html                                (rev 0)
+++ trunk/LayoutTests/platform/gtk/fonts/font-family-fallback-respects-strong-aliases.html        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -0,0 +1,5 @@
</span><ins>+&lt;body style=&quot;font-family:FamilyStrongAliasedToFreeMono,serif;&quot;&gt;
+This test ensures that if a font is strongly aliased to another, those fonts are
+treated as identical for the purposes of CSS font fallback. This test passes if
+it is displayed in FreeMono and fails if it is displayed in a serif font.
+&lt;/body&gt;
</ins></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (187526 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-07-28 23:21:15 UTC (rev 187526)
+++ trunk/Source/WebCore/ChangeLog        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -1,3 +1,32 @@
</span><ins>+2015-07-28  Michael Catanzaro  &lt;mcatanzaro@igalia.com&gt;
+
+        [Freetype] Always allow font matching for strong aliases
+        https://bugs.webkit.org/show_bug.cgi?id=147057
+
+        Reviewed by Martin Robinson.
+
+        Tests: platform/gtk/fonts/font-family-fallback-ignores-weak-aliases.html
+               platform/gtk/fonts/font-family-fallback-respects-strong-aliases.html
+
+        Treat fonts that are strongly-aliased to each other as if they were identical for the
+        purposes of CSS font fallback. This improves the layout of many web pages by allowing
+        fontconfig to replace fonts with metric-compatible equivalents (e.g. Arial -&gt; Liberation
+        Sans) instead of rejecting the metric-compatible font as unsuitable.
+
+        * platform/graphics/cairo/RefPtrCairo.cpp:
+        (WTF::refIfNotNull):
+        (WTF::derefIfNotNull):
+        * platform/graphics/cairo/RefPtrCairo.h:
+        * platform/graphics/freetype/FcUniquePtr.h: Added.
+        (WebCore::FcPtrDeleter&lt;FcFontSet&gt;::operator()):
+        (WebCore::FcPtrDeleter&lt;FcLangSet&gt;::operator()):
+        (WebCore::FcPtrDeleter&lt;FcObjectSet&gt;::operator()):
+        * platform/graphics/freetype/FontCacheFreeType.cpp:
+        (WebCore::strengthOfFirstAlias):
+        (WebCore::strongAliasesForFamily):
+        (WebCore::areStronglyAliased):
+        (WebCore::FontCache::createFontPlatformData):
+
</ins><span class="cx"> 2015-07-28  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         [iOS] Crash when encountering characters whose natural font is one we can't look up
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscairoRefPtrCairocpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp (187526 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp        2015-07-28 23:21:15 UTC (rev 187526)
+++ trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.cpp        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -115,6 +115,17 @@
</span><span class="cx">         FcPatternDestroy(ptr);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template&lt;&gt; void refIfNotNull(FcConfig* ptr)
+{
+    if (LIKELY(ptr != nullptr))
+        FcConfigReference(ptr);
+}
+
+template&lt;&gt; void derefIfNotNull(FcConfig* ptr)
+{
+    if (LIKELY(ptr != nullptr))
+        FcConfigDestroy(ptr);
+}
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTF
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscairoRefPtrCairoh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h (187526 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h        2015-07-28 23:21:15 UTC (rev 187526)
+++ trunk/Source/WebCore/platform/graphics/cairo/RefPtrCairo.h        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -33,6 +33,7 @@
</span><span class="cx"> 
</span><span class="cx"> #if USE(FREETYPE)
</span><span class="cx"> typedef struct _FcPattern FcPattern;
</span><ins>+typedef struct _FcConfig FcConfig;
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> namespace WTF {
</span><span class="lines">@@ -58,6 +59,9 @@
</span><span class="cx"> #if USE(FREETYPE)
</span><span class="cx"> template&lt;&gt; void refIfNotNull(FcPattern* ptr);
</span><span class="cx"> template&lt;&gt; void derefIfNotNull(FcPattern* ptr);
</span><ins>+
+template&lt;&gt; void refIfNotNull(FcConfig* ptr);
+template&lt;&gt; void derefIfNotNull(FcConfig* ptr);
</ins><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="cx"> } // namespace WTF
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfreetypeFcUniquePtrh"></a>
<div class="addfile"><h4>Added: trunk/Source/WebCore/platform/graphics/freetype/FcUniquePtr.h (0 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/freetype/FcUniquePtr.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/freetype/FcUniquePtr.h        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -0,0 +1,69 @@
</span><ins>+/*
+ * Copyright (C) 2015 Igalia S.L
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1.  Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ * 2.  Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS &quot;AS IS&quot; AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef FcUniquePtr_h
+#define FcUniquePtr_h
+
+#if USE(FREETYPE)
+
+#include &lt;fontconfig/fontconfig.h&gt;
+#include &lt;memory&gt;
+
+namespace WebCore {
+
+template&lt;typename T&gt;
+struct FcPtrDeleter {
+    void operator()(T* ptr) const = delete;
+};
+
+template&lt;typename T&gt;
+using FcUniquePtr = std::unique_ptr&lt;T, FcPtrDeleter&lt;T&gt;&gt;;
+
+template&lt;&gt; struct FcPtrDeleter&lt;FcFontSet&gt; {
+    void operator()(FcFontSet* ptr) const
+    {
+        FcFontSetDestroy(ptr);
+    }
+};
+
+template&lt;&gt; struct FcPtrDeleter&lt;FcLangSet&gt; {
+    void operator()(FcLangSet* ptr) const
+    {
+        FcLangSetDestroy(ptr);
+    }
+};
+
+template&lt;&gt; struct FcPtrDeleter&lt;FcObjectSet&gt; {
+    void operator()(FcObjectSet* ptr) const
+    {
+        FcObjectSetDestroy(ptr);
+    }
+};
+
+} // namespace WebCore
+
+#endif // USE(FREETYPE)
+
+#endif // FcUniquePtr_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsfreetypeFontCacheFreeTypecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp (187526 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp        2015-07-28 23:21:15 UTC (rev 187526)
+++ trunk/Source/WebCore/platform/graphics/freetype/FontCacheFreeType.cpp        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -22,6 +22,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;FontCache.h&quot;
</span><span class="cx"> 
</span><ins>+#include &quot;FcUniquePtr.h&quot;
</ins><span class="cx"> #include &quot;Font.h&quot;
</span><span class="cx"> #include &quot;RefPtrCairo.h&quot;
</span><span class="cx"> #include &quot;UTF16UChar32Iterator.h&quot;
</span><span class="lines">@@ -164,6 +165,141 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+// This is based on Chromium BSD code from Skia (src/ports/SkFontMgr_fontconfig.cpp). It is a
+// hack for lack of API in Fontconfig: https://bugs.freedesktop.org/show_bug.cgi?id=19375
+// FIXME: This is horrible. It should be deleted once Fontconfig can do this itself.
+enum class AliasStrength {
+    Weak,
+    Strong,
+    Done
+};
+
+static AliasStrength strengthOfFirstAlias(const FcPattern&amp; original)
+{
+    // Ideally there would exist a call like
+    // FcResult FcPatternIsWeak(pattern, object, id, FcBool* isWeak);
+    //
+    // However, there is no such call and as of Fc 2.11.0 even FcPatternEquals ignores the weak bit.
+    // Currently, the only reliable way of finding the weak bit is by its effect on matching.
+    // The weak bit only affects the matching of FC_FAMILY and FC_POSTSCRIPT_NAME object values.
+    // A element with the weak bit is scored after FC_LANG, without the weak bit is scored before.
+    // Note that the weak bit is stored on the element, not on the value it holds.
+    FcValue value;
+    FcResult result = FcPatternGet(&amp;original, FC_FAMILY, 0, &amp;value);
+    if (result != FcResultMatch)
+        return AliasStrength::Done;
+
+    RefPtr&lt;FcPattern&gt; pattern = adoptRef(FcPatternDuplicate(&amp;original));
+    FcBool hasMultipleFamilies = true;
+    while (hasMultipleFamilies)
+        hasMultipleFamilies = FcPatternRemove(pattern.get(), FC_FAMILY, 1);
+
+    // Create a font set with two patterns.
+    // 1. the same FC_FAMILY as pattern and a lang object with only 'nomatchlang'.
+    // 2. a different FC_FAMILY from pattern and a lang object with only 'matchlang'.
+    FcUniquePtr&lt;FcFontSet&gt; fontSet(FcFontSetCreate());
+
+    FcUniquePtr&lt;FcLangSet&gt; strongLangSet(FcLangSetCreate());
+    FcLangSetAdd(strongLangSet.get(), reinterpret_cast&lt;const FcChar8*&gt;(&quot;nomatchlang&quot;));
+    RefPtr&lt;FcPattern&gt; strong = adoptRef(FcPatternDuplicate(pattern.get()));
+    FcPatternAddLangSet(strong.get(), FC_LANG, strongLangSet.get());
+
+    FcUniquePtr&lt;FcLangSet&gt; weakLangSet(FcLangSetCreate());
+    FcLangSetAdd(weakLangSet.get(), reinterpret_cast&lt;const FcChar8*&gt;(&quot;matchlang&quot;));
+    RefPtr&lt;FcPattern&gt; weak(FcPatternCreate());
+    FcPatternAddString(weak.get(), FC_FAMILY, reinterpret_cast&lt;const FcChar8*&gt;(&quot;nomatchstring&quot;));
+    FcPatternAddLangSet(weak.get(), FC_LANG, weakLangSet.get());
+
+    FcFontSetAdd(fontSet.get(), strong.leakRef());
+    FcFontSetAdd(fontSet.get(), weak.leakRef());
+
+    // Add 'matchlang' to the copy of the pattern.
+    FcPatternAddLangSet(pattern.get(), FC_LANG, weakLangSet.get());
+
+    // Run a match against the copy of the pattern.
+    // If the first element was weak, then we should match the pattern with 'matchlang'.
+    // If the first element was strong, then we should match the pattern with 'nomatchlang'.
+
+    // Note that this config is only used for FcFontRenderPrepare, which we don't even want.
+    // However, there appears to be no way to match/sort without it.
+    RefPtr&lt;FcConfig&gt; config = adoptRef(FcConfigCreate());
+    FcFontSet* fontSets[1] = { fontSet.get() };
+    RefPtr&lt;FcPattern&gt; match = adoptRef(FcFontSetMatch(config.get(), fontSets, 1, pattern.get(), &amp;result));
+
+    FcLangSet* matchLangSet;
+    FcPatternGetLangSet(match.get(), FC_LANG, 0, &amp;matchLangSet);
+    return FcLangEqual == FcLangSetHasLang(matchLangSet, reinterpret_cast&lt;const FcChar8*&gt;(&quot;matchlang&quot;))
+        ? AliasStrength::Weak : AliasStrength::Strong;
+}
+
+static Vector&lt;String&gt; strongAliasesForFamily(const String&amp; family)
+{
+    RefPtr&lt;FcPattern&gt; pattern = adoptRef(FcPatternCreate());
+    if (!FcPatternAddString(pattern.get(), FC_FAMILY, reinterpret_cast&lt;const FcChar8*&gt;(family.utf8().data())))
+        return Vector&lt;String&gt;();
+
+    FcConfigSubstitute(nullptr, pattern.get(), FcMatchPattern);
+    FcDefaultSubstitute(pattern.get());
+
+    FcUniquePtr&lt;FcObjectSet&gt; familiesOnly(FcObjectSetBuild(FC_FAMILY, nullptr));
+    RefPtr&lt;FcPattern&gt; minimal = adoptRef(FcPatternFilter(pattern.get(), familiesOnly.get()));
+
+    // We really want to match strong (preferred) and same (acceptable) only here.
+    // If a family name was specified, assume that any weak matches after the last strong match
+    // are weak (default) and ignore them.
+    // The reason for is that after substitution the pattern for 'sans-serif' looks like
+    // &quot;wwwwwwwwwwwwwwswww&quot; where there are many weak but preferred names, followed by defaults.
+    // So it is possible to have weakly matching but preferred names.
+    // In aliases, bindings are weak by default, so this is easy and common.
+    // If no family name was specified, we'll probably only get weak matches, but that's ok.
+    int lastStrongId = -1;
+    int numIds = 0;
+    for (int id = 0; ; ++id) {
+        AliasStrength result = strengthOfFirstAlias(*minimal);
+        if (result == AliasStrength::Done) {
+            numIds = id;
+            break;
+        }
+        if (result == AliasStrength::Strong)
+            lastStrongId = id;
+        if (!FcPatternRemove(minimal.get(), FC_FAMILY, 0))
+            return Vector&lt;String&gt;();
+    }
+
+    // If they were all weak, then leave the pattern alone.
+    if (lastStrongId &lt; 0)
+        return Vector&lt;String&gt;();
+
+    // Remove everything after the last strong.
+    for (int id = lastStrongId + 1; id &lt; numIds; ++id) {
+        if (!FcPatternRemove(pattern.get(), FC_FAMILY, lastStrongId + 1)) {
+            ASSERT_NOT_REACHED();
+            return Vector&lt;String&gt;();
+        }
+    }
+
+    // Take the resulting pattern and remove everything but the families.
+    minimal = adoptRef(FcPatternFilter(pattern.get(), familiesOnly.get()));
+    // Convert the pattern to a string, and cut out the non-family junk that gets added to the end.
+    char* patternChars = reinterpret_cast&lt;char*&gt;(FcPatternFormat(pattern.get(), reinterpret_cast&lt;const FcChar8*&gt;(&quot;%{family}&quot;)));
+    String patternString = String::fromUTF8(patternChars);
+    free(patternChars);
+
+    Vector&lt;String&gt; results;
+    patternString.split(',', results);
+    return results;
+}
+
+static bool areStronglyAliased(const String&amp; familyA, const String&amp; familyB)
+{
+    for (auto&amp; family : strongAliasesForFamily(familyA)) {
+        if (family == familyB)
+            return true;
+    }
+    return false;
+}
+
+
</ins><span class="cx"> std::unique_ptr&lt;FontPlatformData&gt; FontCache::createFontPlatformData(const FontDescription&amp; fontDescription, const AtomicString&amp; family)
</span><span class="cx"> {
</span><span class="cx">     // The CSS font matching algorithm (http://www.w3.org/TR/css3-fonts/#font-matching-algorithm)
</span><span class="lines">@@ -185,10 +321,17 @@
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="cx">     // The strategy is originally from Skia (src/ports/SkFontHost_fontconfig.cpp):
</span><del>-
-    // Allow Fontconfig to do pre-match substitution. Unless we are accessing a &quot;fallback&quot;
-    // family like &quot;sans,&quot; this is the only time we allow Fontconfig to substitute one
-    // family name for another (i.e. if the fonts are aliased to each other).
</del><ins>+    //
+    // We do not normally allow fontconfig to substitute one font family for another, since this
+    // would break CSS font family fallback: the website should be in control of fallback. During
+    // normal font matching, the only font family substitution permitted is for generic families
+    // (sans, serif, monospace) or for strongly-aliased fonts (which are to be treated as
+    // effectively identical). This is because the font matching step is designed to always find a
+    // match for the font, which we don't want.
+    //
+    // Fontconfig is used in two stages: (1) configuration and (2) matching. During the
+    // configuration step, before any matching occurs, we allow arbitrary family substitutions,
+    // since this is an exact matter of respecting the user's font configuration.
</ins><span class="cx">     FcConfigSubstitute(0, pattern.get(), FcMatchPattern);
</span><span class="cx">     FcDefaultSubstitute(pattern.get());
</span><span class="cx"> 
</span><span class="lines">@@ -205,13 +348,15 @@
</span><span class="cx">     FcPatternGetString(resultPattern.get(), FC_FAMILY, 0, &amp;fontConfigFamilyNameAfterMatching);
</span><span class="cx">     String familyNameAfterMatching = String::fromUTF8(reinterpret_cast&lt;char*&gt;(fontConfigFamilyNameAfterMatching));
</span><span class="cx"> 
</span><del>-    // If Fontconfig gave use a different font family than the one we requested, we should ignore it
-    // and allow WebCore to give us the next font on the CSS fallback list. The only exception is if
-    // this family name is a commonly used generic family.
</del><ins>+    // If Fontconfig gave us a different font family than the one we requested, we should ignore it
+    // and allow WebCore to give us the next font on the CSS fallback list. The exceptions are if
+    // this family name is a commonly-used generic family, or if the families are strongly-aliased.
+    // Checking for a strong alias comes last, since it is slow.
</ins><span class="cx">     if (!equalIgnoringCase(familyNameAfterConfiguration, familyNameAfterMatching)
</span><span class="cx">         &amp;&amp; !(equalIgnoringCase(familyNameString, &quot;sans&quot;) || equalIgnoringCase(familyNameString, &quot;sans-serif&quot;)
</span><span class="cx">           || equalIgnoringCase(familyNameString, &quot;serif&quot;) || equalIgnoringCase(familyNameString, &quot;monospace&quot;)
</span><del>-          || equalIgnoringCase(familyNameString, &quot;fantasy&quot;) || equalIgnoringCase(familyNameString, &quot;cursive&quot;)))
</del><ins>+          || equalIgnoringCase(familyNameString, &quot;fantasy&quot;) || equalIgnoringCase(familyNameString, &quot;cursive&quot;))
+        &amp;&amp; !areStronglyAliased(familyNameAfterConfiguration, familyNameAfterMatching))
</ins><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="cx">     // Verify that this font has an encoding compatible with Fontconfig. Fontconfig currently
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (187526 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-07-28 23:21:15 UTC (rev 187526)
+++ trunk/Tools/ChangeLog        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -1,3 +1,14 @@
</span><ins>+2015-07-28  Michael Catanzaro  &lt;mcatanzaro@igalia.com&gt;
+
+        [Freetype] Always allow font matching for strong aliases
+        https://bugs.webkit.org/show_bug.cgi?id=147057
+
+        Reviewed by Martin Robinson.
+
+        Create family aliases needed for the new layout tests.
+
+        * WebKitTestRunner/gtk/fonts/fonts.conf:
+
</ins><span class="cx"> 2015-07-28  Alexey Proskuryakov  &lt;ap@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         webkitbot and WKR unnecessarily rely on webkit-queues.appspot.com
</span></span></pre></div>
<a id="trunkToolsWebKitTestRunnergtkfontsfontsconf"></a>
<div class="modfile"><h4>Modified: trunk/Tools/WebKitTestRunner/gtk/fonts/fonts.conf (187526 => 187527)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/WebKitTestRunner/gtk/fonts/fonts.conf        2015-07-28 23:21:15 UTC (rev 187526)
+++ trunk/Tools/WebKitTestRunner/gtk/fonts/fonts.conf        2015-07-28 23:37:10 UTC (rev 187527)
</span><span class="lines">@@ -337,6 +337,22 @@
</span><span class="cx">         &lt;/edit&gt;
</span><span class="cx">     &lt;/match&gt;
</span><span class="cx"> 
</span><ins>+    &lt;!-- These fonts should be treated as identical by CSS font fallback. --&gt;
+    &lt;alias binding=&quot;same&quot;&gt;
+      &lt;family&gt;FamilyStrongAliasedToFreeMono&lt;/family&gt;
+      &lt;accept&gt;
+        &lt;family&gt;FreeMono&lt;/family&gt;
+      &lt;/accept&gt;
+    &lt;/alias&gt;
+
+    &lt;!-- These fonts should NOT be treated as identical by CSS font fallback. --&gt;
+    &lt;alias&gt;
+      &lt;family&gt;FamilyWeakAliasedToFreeMono&lt;/family&gt;
+      &lt;accept&gt;
+        &lt;family&gt;FreeMono&lt;/family&gt;
+      &lt;/accept&gt;
+    &lt;/alias&gt;
+
</ins><span class="cx">     &lt;!-- If this font doesn't have a family name we are falling back. The fallback
</span><span class="cx">          font will certainly be one of the DejaVu fonts that we have in our
</span><span class="cx">          collection since they have a wide range of characters. Fontconfig might
</span></span></pre>
</div>
</div>

</body>
</html>