<!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>[178518] 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/178518">178518</a></dd>
<dt>Author</dt> <dd>antti@apple.com</dd>
<dt>Date</dt> <dd>2015-01-15 11:29:05 -0800 (Thu, 15 Jan 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Try to fix windows build.

* platform/graphics/Font.cpp: Copied from Source/WebCore/platform/graphics/SimpleFontData.cpp.
* platform/graphics/Font.h: Copied from Source/WebCore/platform/graphics/SimpleFontData.h.
* platform/graphics/FontCascadeFastPath.cpp: Copied from Source/WebCore/platform/graphics/FontFastPath.cpp.
* platform/graphics/ca/win/PlatformCALayerWin.cpp:
* platform/graphics/ca/win/PlatformCALayerWinInternal.cpp:
(PlatformCALayerWinInternal::displayCallback):
* platform/graphics/ios/FontIOS.mm: Copied from Source/WebCore/platform/graphics/ios/SimpleFontDataIOS.mm.
* platform/graphics/mac/FontCascadeComplexTextMac.cpp: Copied from Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp.
* platform/graphics/mac/FontCascadeMac.mm: Copied from Source/WebCore/platform/graphics/mac/FontMac.mm.
* platform/graphics/mac/FontCoreText.cpp: Copied from Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp.
* platform/graphics/mac/FontMac.mm: Replaced with Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm.
* platform/win/DragImageWin.cpp:
(WebCore::dragLabelFont):
(WebCore::createDragImageForLink):
* platform/win/PopupMenuWin.cpp:
(WebCore::PopupMenuWin::calculatePositionAndSize):
(WebCore::PopupMenuWin::paint):
* platform/win/WebCoreTextRenderer.cpp:
(WebCore::doDrawTextAtPoint):
(WebCore::WebCoreDrawDoubledTextAtPoint):
(WebCore::WebCoreTextFloatWidth):
(WebCore::WebCoreSetAlwaysUsesComplexTextCodePath):
(WebCore::WebCoreAlwaysUsesComplexTextCodePath):
* rendering/RenderThemeSafari.cpp:
(WebCore::RenderThemeSafari::setFontFromControlSize):</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscawinPlatformCALayerWincpp">trunk/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscawinPlatformCALayerWinInternalcpp">trunk/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformwinDragImageWincpp">trunk/Source/WebCore/platform/win/DragImageWin.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformwinPopupMenuWincpp">trunk/Source/WebCore/platform/win/PopupMenuWin.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformwinWebCoreTextRenderercpp">trunk/Source/WebCore/platform/win/WebCoreTextRenderer.cpp</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderThemeSafaricpp">trunk/Source/WebCore/rendering/RenderThemeSafari.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontcpp">trunk/Source/WebCore/platform/graphics/Font.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFonth">trunk/Source/WebCore/platform/graphics/Font.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontCascadeFastPathcpp">trunk/Source/WebCore/platform/graphics/FontCascadeFastPath.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsiosFontIOSmm">trunk/Source/WebCore/platform/graphics/ios/FontIOS.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacFontCascadeComplexTextMaccpp">trunk/Source/WebCore/platform/graphics/mac/FontCascadeComplexTextMac.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacFontCascadeMacmm">trunk/Source/WebCore/platform/graphics/mac/FontCascadeMac.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacFontCoreTextcpp">trunk/Source/WebCore/platform/graphics/mac/FontCoreText.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacFontMacmm">trunk/Source/WebCore/platform/graphics/mac/FontMac.mm</a></li>
</ul>

<h3>Removed Paths</h3>
<ul>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacFontMacmm">trunk/Source/WebCore/platform/graphics/mac/FontMac.mm</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (178517 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-01-15 19:20:03 UTC (rev 178517)
+++ trunk/Source/WebCore/ChangeLog        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -1,3 +1,33 @@
</span><ins>+2015-01-15  Antti Koivisto  &lt;antti@apple.com&gt;
+
+        Try to fix windows build.
+
+        * platform/graphics/Font.cpp: Copied from Source/WebCore/platform/graphics/SimpleFontData.cpp.
+        * platform/graphics/Font.h: Copied from Source/WebCore/platform/graphics/SimpleFontData.h.
+        * platform/graphics/FontCascadeFastPath.cpp: Copied from Source/WebCore/platform/graphics/FontFastPath.cpp.
+        * platform/graphics/ca/win/PlatformCALayerWin.cpp:
+        * platform/graphics/ca/win/PlatformCALayerWinInternal.cpp:
+        (PlatformCALayerWinInternal::displayCallback):
+        * platform/graphics/ios/FontIOS.mm: Copied from Source/WebCore/platform/graphics/ios/SimpleFontDataIOS.mm.
+        * platform/graphics/mac/FontCascadeComplexTextMac.cpp: Copied from Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp.
+        * platform/graphics/mac/FontCascadeMac.mm: Copied from Source/WebCore/platform/graphics/mac/FontMac.mm.
+        * platform/graphics/mac/FontCoreText.cpp: Copied from Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp.
+        * platform/graphics/mac/FontMac.mm: Replaced with Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm.
+        * platform/win/DragImageWin.cpp:
+        (WebCore::dragLabelFont):
+        (WebCore::createDragImageForLink):
+        * platform/win/PopupMenuWin.cpp:
+        (WebCore::PopupMenuWin::calculatePositionAndSize):
+        (WebCore::PopupMenuWin::paint):
+        * platform/win/WebCoreTextRenderer.cpp:
+        (WebCore::doDrawTextAtPoint):
+        (WebCore::WebCoreDrawDoubledTextAtPoint):
+        (WebCore::WebCoreTextFloatWidth):
+        (WebCore::WebCoreSetAlwaysUsesComplexTextCodePath):
+        (WebCore::WebCoreAlwaysUsesComplexTextCodePath):
+        * rendering/RenderThemeSafari.cpp:
+        (WebCore::RenderThemeSafari::setFontFromControlSize):
+
</ins><span class="cx"> 2015-01-15  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         http/tests/misc/acid3.html is flakey on Mavericks
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontcppfromrev178515trunkSourceWebCoreplatformgraphicsSimpleFontDatacpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/Font.cpp (from rev 178515, trunk/Source/WebCore/platform/graphics/SimpleFontData.cpp) (0 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/Font.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/Font.cpp        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -0,0 +1,456 @@
</span><ins>+/*
+ * Copyright (C) 2005, 2008, 2010, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov
+ *
+ * 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. 
+ * 3.  Neither the name of Apple Inc. (&quot;Apple&quot;) nor the names of
+ *     its contributors may be used to endorse or promote products derived
+ *     from this software without specific prior written permission. 
+ *
+ * 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;SimpleFontData.h&quot;
+
+#if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt; 1080)
+#include &quot;CoreTextSPI.h&quot;
+#endif
+#include &quot;FontCache.h&quot;
+#include &quot;FontCascade.h&quot;
+#include &quot;OpenTypeMathData.h&quot;
+#include &lt;wtf/MathExtras.h&gt;
+#include &lt;wtf/NeverDestroyed.h&gt;
+
+#if ENABLE(OPENTYPE_VERTICAL)
+#include &quot;OpenTypeVerticalData.h&quot;
+#endif
+
+namespace WebCore {
+
+unsigned GlyphPage::s_count = 0;
+
+const float smallCapsFontSizeMultiplier = 0.7f;
+const float emphasisMarkFontSizeMultiplier = 0.5f;
+
+SimpleFontData::SimpleFontData(const FontPlatformData&amp; platformData, bool isCustomFont, bool isLoading, bool isTextOrientationFallback)
+    : m_maxCharWidth(-1)
+    , m_avgCharWidth(-1)
+    , m_platformData(platformData)
+    , m_treatAsFixedPitch(false)
+    , m_isCustomFont(isCustomFont)
+    , m_isLoading(isLoading)
+    , m_isTextOrientationFallback(isTextOrientationFallback)
+    , m_isBrokenIdeographFallback(false)
+    , m_mathData(nullptr)
+#if ENABLE(OPENTYPE_VERTICAL)
+    , m_verticalData(0)
+#endif
+    , m_hasVerticalGlyphs(false)
+{
+    platformInit();
+    platformGlyphInit();
+    platformCharWidthInit();
+#if ENABLE(OPENTYPE_VERTICAL)
+    if (platformData.orientation() == Vertical &amp;&amp; !isTextOrientationFallback) {
+        m_verticalData = platformData.verticalData();
+        m_hasVerticalGlyphs = m_verticalData.get() &amp;&amp; m_verticalData-&gt;hasVerticalMetrics();
+    }
+#endif
+}
+
+SimpleFontData::SimpleFontData(std::unique_ptr&lt;SVGData&gt; svgData, float fontSize, bool syntheticBold, bool syntheticItalic)
+    : m_platformData(FontPlatformData(fontSize, syntheticBold, syntheticItalic))
+    , m_svgData(WTF::move(svgData))
+    , m_treatAsFixedPitch(false)
+    , m_isCustomFont(true)
+    , m_isLoading(false)
+    , m_isTextOrientationFallback(false)
+    , m_isBrokenIdeographFallback(false)
+    , m_mathData(nullptr)
+#if ENABLE(OPENTYPE_VERTICAL)
+    , m_verticalData(0)
+#endif
+    , m_hasVerticalGlyphs(false)
+#if PLATFORM(IOS)
+    , m_shouldNotBeUsedForArabic(false)
+#endif
+{
+    m_svgData-&gt;initializeFontData(this, fontSize);
+}
+
+// Estimates of avgCharWidth and maxCharWidth for platforms that don't support accessing these values from the font.
+void SimpleFontData::initCharWidths()
+{
+    auto* glyphPageZero = glyphPage(0);
+
+    // Treat the width of a '0' as the avgCharWidth.
+    if (m_avgCharWidth &lt;= 0.f &amp;&amp; glyphPageZero) {
+        static const UChar32 digitZeroChar = '0';
+        Glyph digitZeroGlyph = glyphPageZero-&gt;glyphDataForCharacter(digitZeroChar).glyph;
+        if (digitZeroGlyph)
+            m_avgCharWidth = widthForGlyph(digitZeroGlyph);
+    }
+
+    // If we can't retrieve the width of a '0', fall back to the x height.
+    if (m_avgCharWidth &lt;= 0.f)
+        m_avgCharWidth = m_fontMetrics.xHeight();
+
+    if (m_maxCharWidth &lt;= 0.f)
+        m_maxCharWidth = std::max(m_avgCharWidth, m_fontMetrics.floatAscent());
+}
+
+void SimpleFontData::platformGlyphInit()
+{
+    auto* glyphPageZero = glyphPage(0);
+    if (!glyphPageZero) {
+        m_spaceGlyph = 0;
+        m_spaceWidth = 0;
+        m_zeroGlyph = 0;
+        m_adjustedSpaceWidth = 0;
+        determinePitch();
+        m_zeroWidthSpaceGlyph = 0;
+        return;
+    }
+
+    // Ask for the glyph for 0 to avoid paging in ZERO WIDTH SPACE. Control characters, including 0,
+    // are mapped to the ZERO WIDTH SPACE glyph.
+    m_zeroWidthSpaceGlyph = glyphPageZero-&gt;glyphDataForCharacter(0).glyph;
+
+    // Nasty hack to determine if we should round or ceil space widths.
+    // If the font is monospace or fake monospace we ceil to ensure that 
+    // every character and the space are the same width.  Otherwise we round.
+    m_spaceGlyph = glyphPageZero-&gt;glyphDataForCharacter(' ').glyph;
+    float width = widthForGlyph(m_spaceGlyph);
+    m_spaceWidth = width;
+    m_zeroGlyph = glyphPageZero-&gt;glyphDataForCharacter('0').glyph;
+    m_fontMetrics.setZeroWidth(widthForGlyph(m_zeroGlyph));
+    determinePitch();
+    m_adjustedSpaceWidth = m_treatAsFixedPitch ? ceilf(width) : roundf(width);
+
+    // Force the glyph for ZERO WIDTH SPACE to have zero width, unless it is shared with SPACE.
+    // Helvetica is an example of a non-zero width ZERO WIDTH SPACE glyph.
+    // See &lt;http://bugs.webkit.org/show_bug.cgi?id=13178&gt; and SimpleFontData::isZeroWidthSpaceGlyph()
+    if (m_zeroWidthSpaceGlyph == m_spaceGlyph)
+        m_zeroWidthSpaceGlyph = 0;
+}
+
+SimpleFontData::~SimpleFontData()
+{
+    removeFromSystemFallbackCache();
+}
+
+static bool fillGlyphPage(GlyphPage&amp; pageToFill, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData* fontData)
+{
+#if ENABLE(SVG_FONTS)
+    if (auto* svgData = fontData-&gt;svgData())
+        return svgData-&gt;fillSVGGlyphPage(&amp;pageToFill, offset, length, buffer, bufferLength, fontData);
+#endif
+    bool hasGlyphs = pageToFill.fill(offset, length, buffer, bufferLength, fontData);
+#if ENABLE(OPENTYPE_VERTICAL)
+    if (hasGlyphs &amp;&amp; fontData-&gt;verticalData())
+        fontData-&gt;verticalData()-&gt;substituteWithVerticalGlyphs(fontData, &amp;pageToFill, offset, length);
+#endif
+    return hasGlyphs;
+}
+
+static RefPtr&lt;GlyphPage&gt; createAndFillGlyphPage(unsigned pageNumber, const SimpleFontData* fontData)
+{
+#if PLATFORM(IOS)
+    // FIXME: Times New Roman contains Arabic glyphs, but Core Text doesn't know how to shape them. See &lt;rdar://problem/9823975&gt;.
+    // Once we have the fix for &lt;rdar://problem/9823975&gt; then remove this code together with SimpleFontData::shouldNotBeUsedForArabic()
+    // in &lt;rdar://problem/12096835&gt;.
+    if (pageNumber == 6 &amp;&amp; fontData-&gt;shouldNotBeUsedForArabic())
+        return nullptr;
+#endif
+
+    unsigned start = pageNumber * GlyphPage::size;
+    UChar buffer[GlyphPage::size * 2 + 2];
+    unsigned bufferLength;
+    // Fill in a buffer with the entire &quot;page&quot; of characters that we want to look up glyphs for.
+    if (U_IS_BMP(start)) {
+        bufferLength = GlyphPage::size;
+        for (unsigned i = 0; i &lt; GlyphPage::size; i++)
+            buffer[i] = start + i;
+
+        if (start == 0) {
+            // Control characters must not render at all.
+            for (unsigned i = 0; i &lt; 0x20; ++i)
+                buffer[i] = zeroWidthSpace;
+            for (unsigned i = 0x7F; i &lt; 0xA0; i++)
+                buffer[i] = zeroWidthSpace;
+            buffer[softHyphen] = zeroWidthSpace;
+
+            // \n, \t, and nonbreaking space must render as a space.
+            buffer[(int)'\n'] = ' ';
+            buffer[(int)'\t'] = ' ';
+            buffer[noBreakSpace] = ' ';
+        } else if (start == (leftToRightMark &amp; ~(GlyphPage::size - 1))) {
+            // LRM, RLM, LRE, RLE, ZWNJ, ZWJ, and PDF must not render at all.
+            buffer[leftToRightMark - start] = zeroWidthSpace;
+            buffer[rightToLeftMark - start] = zeroWidthSpace;
+            buffer[leftToRightEmbed - start] = zeroWidthSpace;
+            buffer[rightToLeftEmbed - start] = zeroWidthSpace;
+            buffer[leftToRightOverride - start] = zeroWidthSpace;
+            buffer[rightToLeftOverride - start] = zeroWidthSpace;
+            buffer[zeroWidthNonJoiner - start] = zeroWidthSpace;
+            buffer[zeroWidthJoiner - start] = zeroWidthSpace;
+            buffer[popDirectionalFormatting - start] = zeroWidthSpace;
+        } else if (start == (objectReplacementCharacter &amp; ~(GlyphPage::size - 1))) {
+            // Object replacement character must not render at all.
+            buffer[objectReplacementCharacter - start] = zeroWidthSpace;
+        } else if (start == (zeroWidthNoBreakSpace &amp; ~(GlyphPage::size - 1))) {
+            // ZWNBS/BOM must not render at all.
+            buffer[zeroWidthNoBreakSpace - start] = zeroWidthSpace;
+        }
+    } else {
+        bufferLength = GlyphPage::size * 2;
+        for (unsigned i = 0; i &lt; GlyphPage::size; i++) {
+            int c = i + start;
+            buffer[i * 2] = U16_LEAD(c);
+            buffer[i * 2 + 1] = U16_TRAIL(c);
+        }
+    }
+
+    // Now that we have a buffer full of characters, we want to get back an array
+    // of glyph indices. This part involves calling into the platform-specific
+    // routine of our glyph map for actually filling in the page with the glyphs.
+    // Success is not guaranteed. For example, Times fails to fill page 260, giving glyph data
+    // for only 128 out of 256 characters.
+    RefPtr&lt;GlyphPage&gt; glyphPage;
+    if (GlyphPage::mayUseMixedFontDataWhenFilling(buffer, bufferLength, fontData))
+        glyphPage = GlyphPage::createForMixedFontData();
+    else
+        glyphPage = GlyphPage::createForSingleFontData(fontData);
+
+    bool haveGlyphs = fillGlyphPage(*glyphPage, 0, GlyphPage::size, buffer, bufferLength, fontData);
+    if (!haveGlyphs)
+        return nullptr;
+
+    glyphPage-&gt;setImmutable();
+    return glyphPage;
+}
+
+const GlyphPage* SimpleFontData::glyphPage(unsigned pageNumber) const
+{
+    if (pageNumber == 0) {
+        if (!m_glyphPageZero)
+            m_glyphPageZero = createAndFillGlyphPage(0, this);
+        return m_glyphPageZero.get();
+    }
+    auto addResult = m_glyphPages.add(pageNumber, nullptr);
+    if (addResult.isNewEntry)
+        addResult.iterator-&gt;value = createAndFillGlyphPage(pageNumber, this);
+
+    return addResult.iterator-&gt;value.get();
+}
+
+Glyph SimpleFontData::glyphForCharacter(UChar32 character) const
+{
+    auto* page = glyphPage(character / GlyphPage::size);
+    if (!page)
+        return 0;
+    return page-&gt;glyphAt(character % GlyphPage::size);
+}
+
+GlyphData SimpleFontData::glyphDataForCharacter(UChar32 character) const
+{
+    auto* page = glyphPage(character / GlyphPage::size);
+    if (!page)
+        return GlyphData();
+    return page-&gt;glyphDataForCharacter(character);
+}
+
+PassRefPtr&lt;SimpleFontData&gt; SimpleFontData::verticalRightOrientationFontData() const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = std::make_unique&lt;DerivedFontData&gt;(isCustomFont());
+    if (!m_derivedFontData-&gt;verticalRightOrientation) {
+        FontPlatformData verticalRightPlatformData(m_platformData);
+        verticalRightPlatformData.setOrientation(Horizontal);
+        m_derivedFontData-&gt;verticalRightOrientation = create(verticalRightPlatformData, isCustomFont(), false, true);
+    }
+    return m_derivedFontData-&gt;verticalRightOrientation;
+}
+
+PassRefPtr&lt;SimpleFontData&gt; SimpleFontData::uprightOrientationFontData() const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = std::make_unique&lt;DerivedFontData&gt;(isCustomFont());
+    if (!m_derivedFontData-&gt;uprightOrientation)
+        m_derivedFontData-&gt;uprightOrientation = create(m_platformData, isCustomFont(), false, true);
+    return m_derivedFontData-&gt;uprightOrientation;
+}
+
+PassRefPtr&lt;SimpleFontData&gt; SimpleFontData::smallCapsFontData(const FontDescription&amp; fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = std::make_unique&lt;DerivedFontData&gt;(isCustomFont());
+    if (!m_derivedFontData-&gt;smallCaps)
+        m_derivedFontData-&gt;smallCaps = createScaledFontData(fontDescription, smallCapsFontSizeMultiplier);
+
+    return m_derivedFontData-&gt;smallCaps;
+}
+
+PassRefPtr&lt;SimpleFontData&gt; SimpleFontData::emphasisMarkFontData(const FontDescription&amp; fontDescription) const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = std::make_unique&lt;DerivedFontData&gt;(isCustomFont());
+    if (!m_derivedFontData-&gt;emphasisMark)
+        m_derivedFontData-&gt;emphasisMark = createScaledFontData(fontDescription, emphasisMarkFontSizeMultiplier);
+
+    return m_derivedFontData-&gt;emphasisMark;
+}
+
+PassRefPtr&lt;SimpleFontData&gt; SimpleFontData::brokenIdeographFontData() const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = std::make_unique&lt;DerivedFontData&gt;(isCustomFont());
+    if (!m_derivedFontData-&gt;brokenIdeograph) {
+        m_derivedFontData-&gt;brokenIdeograph = create(m_platformData, isCustomFont(), false);
+        m_derivedFontData-&gt;brokenIdeograph-&gt;m_isBrokenIdeographFallback = true;
+    }
+    return m_derivedFontData-&gt;brokenIdeograph;
+}
+
+PassRefPtr&lt;SimpleFontData&gt; SimpleFontData::nonSyntheticItalicFontData() const
+{
+    if (!m_derivedFontData)
+        m_derivedFontData = std::make_unique&lt;DerivedFontData&gt;(isCustomFont());
+    if (!m_derivedFontData-&gt;nonSyntheticItalic) {
+        FontPlatformData nonSyntheticItalicFontPlatformData(m_platformData);
+#if PLATFORM(COCOA)
+        nonSyntheticItalicFontPlatformData.m_syntheticOblique = false;
+#endif
+        m_derivedFontData-&gt;nonSyntheticItalic = create(nonSyntheticItalicFontPlatformData, isCustomFont());
+    }
+    return m_derivedFontData-&gt;nonSyntheticItalic;
+}
+
+#ifndef NDEBUG
+String SimpleFontData::description() const
+{
+    if (isSVGFont())
+        return &quot;[SVG font]&quot;;
+    if (isCustomFont())
+        return &quot;[custom font]&quot;;
+
+    return platformData().description();
+}
+#endif
+
+const OpenTypeMathData* SimpleFontData::mathData() const
+{
+    if (m_isLoading)
+        return nullptr;
+    if (!m_mathData) {
+        m_mathData = OpenTypeMathData::create(m_platformData);
+        if (!m_mathData-&gt;hasMathData())
+            m_mathData.clear();
+    }
+    return m_mathData.get();
+}
+
+SimpleFontData::DerivedFontData::~DerivedFontData()
+{
+}
+
+PassRefPtr&lt;SimpleFontData&gt; SimpleFontData::createScaledFontData(const FontDescription&amp; fontDescription, float scaleFactor) const
+{
+    if (isSVGFont())
+        return nullptr;
+
+    return platformCreateScaledFontData(fontDescription, scaleFactor);
+}
+
+bool SimpleFontData::applyTransforms(GlyphBufferGlyph* glyphs, GlyphBufferAdvance* advances, size_t glyphCount, TypesettingFeatures typesettingFeatures) const
+{
+    // We need to handle transforms on SVG fonts internally, since they are rendered internally.
+    ASSERT(!isSVGFont());
+#if PLATFORM(IOS) || (PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt; 1080)
+    CTFontTransformOptions options = (typesettingFeatures &amp; Kerning ? kCTFontTransformApplyPositioning : 0) | (typesettingFeatures &amp; Ligatures ? kCTFontTransformApplyShaping : 0);
+    return CTFontTransformGlyphs(m_platformData.ctFont(), glyphs, reinterpret_cast&lt;CGSize*&gt;(advances), glyphCount, options);
+#else
+    UNUSED_PARAM(glyphs);
+    UNUSED_PARAM(advances);
+    UNUSED_PARAM(glyphCount);
+    UNUSED_PARAM(typesettingFeatures);
+    return false;
+#endif
+}
+
+// FontDatas are not refcounted to avoid cycles.
+typedef HashMap&lt;std::pair&lt;UChar32, unsigned&gt;, SimpleFontData*&gt; CharacterFallbackMap;
+typedef HashMap&lt;const SimpleFontData*, CharacterFallbackMap&gt; SystemFallbackCache;
+
+static SystemFallbackCache&amp; systemFallbackCache()
+{
+    static NeverDestroyed&lt;SystemFallbackCache&gt; map;
+    return map.get();
+}
+
+RefPtr&lt;SimpleFontData&gt; SimpleFontData::systemFallbackFontDataForCharacter(UChar32 character, const FontDescription&amp; description, bool isForPlatformFont) const
+{
+    auto fontAddResult = systemFallbackCache().add(this, CharacterFallbackMap());
+
+    auto key = std::make_pair(character, isForPlatformFont);
+    auto characterAddResult = fontAddResult.iterator-&gt;value.add(key, nullptr);
+
+    SimpleFontData*&amp; fallbackFontData = characterAddResult.iterator-&gt;value;
+
+    if (!fallbackFontData) {
+        UChar codeUnits[2];
+        int codeUnitsLength;
+        if (U_IS_BMP(character)) {
+            codeUnits[0] = FontCascade::normalizeSpaces(character);
+            codeUnitsLength = 1;
+        } else {
+            codeUnits[0] = U16_LEAD(character);
+            codeUnits[1] = U16_TRAIL(character);
+            codeUnitsLength = 2;
+        }
+
+        fallbackFontData = fontCache().systemFallbackForCharacters(description, this, isForPlatformFont, codeUnits, codeUnitsLength).get();
+        if (fallbackFontData)
+            fallbackFontData-&gt;m_isUsedInSystemFallbackCache = true;
+    }
+
+    return fallbackFontData;
+}
+
+void SimpleFontData::removeFromSystemFallbackCache()
+{
+    systemFallbackCache().remove(this);
+
+    if (!m_isUsedInSystemFallbackCache)
+        return;
+
+    for (auto&amp; characterMap : systemFallbackCache().values()) {
+        Vector&lt;std::pair&lt;UChar32, unsigned&gt;, 512&gt; toRemove;
+        for (auto&amp; entry : characterMap) {
+            if (entry.value == this)
+                toRemove.append(entry.key);
+        }
+        for (auto&amp; key : toRemove)
+            characterMap.remove(key);
+    }
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFonthfromrev178515trunkSourceWebCoreplatformgraphicsSimpleFontDatah"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/Font.h (from rev 178515, trunk/Source/WebCore/platform/graphics/SimpleFontData.h) (0 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/Font.h                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/Font.h        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -0,0 +1,369 @@
</span><ins>+/*
+ * This file is part of the internal font implementation.
+ *
+ * Copyright (C) 2006, 2008, 2010, 2015 Apple Inc. All rights reserved.
+ * Copyright (C) 2007-2008 Torch Mobile, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SimpleFontData_h
+#define SimpleFontData_h
+
+#include &quot;FontBaseline.h&quot;
+#include &quot;FontMetrics.h&quot;
+#include &quot;FontPlatformData.h&quot;
+#include &quot;FloatRect.h&quot;
+#include &quot;GlyphBuffer.h&quot;
+#include &quot;GlyphMetricsMap.h&quot;
+#include &quot;GlyphPage.h&quot;
+#include &quot;OpenTypeMathData.h&quot;
+#if ENABLE(OPENTYPE_VERTICAL)
+#include &quot;OpenTypeVerticalData.h&quot;
+#endif
+#include &quot;TypesettingFeatures.h&quot;
+#include &lt;wtf/TypeCasts.h&gt;
+#include &lt;wtf/text/StringHash.h&gt;
+
+#if PLATFORM(COCOA)
+#include &quot;WebCoreSystemInterface.h&quot;
+#include &lt;wtf/RetainPtr.h&gt;
+#endif
+
+#if PLATFORM(WIN)
+#include &lt;usp10.h&gt;
+#endif
+
+#if USE(CAIRO)
+#include &lt;cairo.h&gt;
+#endif
+
+#if USE(CG)
+#include &lt;WebCore/CoreGraphicsSPI.h&gt;
+#endif
+
+namespace WebCore {
+
+class GlyphPage;
+class FontDescription;
+class SharedBuffer;
+struct GlyphData;
+struct WidthIterator;
+
+enum FontDataVariant { AutoVariant, NormalVariant, SmallCapsVariant, EmphasisMarkVariant, BrokenIdeographVariant };
+enum Pitch { UnknownPitch, FixedPitch, VariablePitch };
+
+class SimpleFontData : public RefCounted&lt;SimpleFontData&gt; {
+public:
+    class SVGData {
+        WTF_MAKE_FAST_ALLOCATED;
+    public:
+        virtual ~SVGData() { }
+
+        virtual void initializeFontData(SimpleFontData*, float fontSize) = 0;
+        virtual float widthForSVGGlyph(Glyph, float fontSize) const = 0;
+        virtual bool fillSVGGlyphPage(GlyphPage*, unsigned offset, unsigned length, UChar* buffer, unsigned bufferLength, const SimpleFontData*) const = 0;
+    };
+
+    // Used to create platform fonts.
+    static Ref&lt;SimpleFontData&gt; create(const FontPlatformData&amp; platformData, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false)
+    {
+        return adoptRef(*new SimpleFontData(platformData, isCustomFont, isLoading, isTextOrientationFallback));
+    }
+
+    // Used to create SVG Fonts.
+    static Ref&lt;SimpleFontData&gt; create(std::unique_ptr&lt;SVGData&gt; svgData, float fontSize, bool syntheticBold, bool syntheticItalic)
+    {
+        return adoptRef(*new SimpleFontData(WTF::move(svgData), fontSize, syntheticBold, syntheticItalic));
+    }
+
+    ~SimpleFontData();
+
+    static const SimpleFontData* systemFallback() { return reinterpret_cast&lt;const SimpleFontData*&gt;(-1); }
+
+    const FontPlatformData&amp; platformData() const { return m_platformData; }
+    const OpenTypeMathData* mathData() const;
+#if ENABLE(OPENTYPE_VERTICAL)
+    const OpenTypeVerticalData* verticalData() const { return m_verticalData.get(); }
+#endif
+
+    PassRefPtr&lt;SimpleFontData&gt; smallCapsFontData(const FontDescription&amp;) const;
+    PassRefPtr&lt;SimpleFontData&gt; emphasisMarkFontData(const FontDescription&amp;) const;
+    PassRefPtr&lt;SimpleFontData&gt; brokenIdeographFontData() const;
+    PassRefPtr&lt;SimpleFontData&gt; nonSyntheticItalicFontData() const;
+
+    PassRefPtr&lt;SimpleFontData&gt; variantFontData(const FontDescription&amp; description, FontDataVariant variant) const
+    {
+        switch (variant) {
+        case SmallCapsVariant:
+            return smallCapsFontData(description);
+        case EmphasisMarkVariant:
+            return emphasisMarkFontData(description);
+        case BrokenIdeographVariant:
+            return brokenIdeographFontData();
+        case AutoVariant:
+        case NormalVariant:
+            break;
+        }
+        ASSERT_NOT_REACHED();
+        return const_cast&lt;SimpleFontData*&gt;(this);
+    }
+
+    PassRefPtr&lt;SimpleFontData&gt; verticalRightOrientationFontData() const;
+    PassRefPtr&lt;SimpleFontData&gt; uprightOrientationFontData() const;
+
+    bool hasVerticalGlyphs() const { return m_hasVerticalGlyphs; }
+    bool isTextOrientationFallback() const { return m_isTextOrientationFallback; }
+
+    FontMetrics&amp; fontMetrics() { return m_fontMetrics; }
+    const FontMetrics&amp; fontMetrics() const { return m_fontMetrics; }
+    float sizePerUnit() const { return platformData().size() / (fontMetrics().unitsPerEm() ? fontMetrics().unitsPerEm() : 1); }
+
+    float maxCharWidth() const { return m_maxCharWidth; }
+    void setMaxCharWidth(float maxCharWidth) { m_maxCharWidth = maxCharWidth; }
+
+    float avgCharWidth() const { return m_avgCharWidth; }
+    void setAvgCharWidth(float avgCharWidth) { m_avgCharWidth = avgCharWidth; }
+
+    FloatRect boundsForGlyph(Glyph) const;
+    float widthForGlyph(Glyph glyph) const;
+    FloatRect platformBoundsForGlyph(Glyph) const;
+    float platformWidthForGlyph(Glyph) const;
+
+    float spaceWidth() const { return m_spaceWidth; }
+    float adjustedSpaceWidth() const { return m_adjustedSpaceWidth; }
+    void setSpaceWidths(float spaceWidth)
+    {
+        m_spaceWidth = spaceWidth;
+        m_adjustedSpaceWidth = spaceWidth;
+    }
+
+#if USE(CG) || USE(CAIRO)
+    float syntheticBoldOffset() const { return m_syntheticBoldOffset; }
+#endif
+
+    Glyph spaceGlyph() const { return m_spaceGlyph; }
+    void setSpaceGlyph(Glyph spaceGlyph) { m_spaceGlyph = spaceGlyph; }
+    Glyph zeroWidthSpaceGlyph() const { return m_zeroWidthSpaceGlyph; }
+    void setZeroWidthSpaceGlyph(Glyph spaceGlyph) { m_zeroWidthSpaceGlyph = spaceGlyph; }
+    bool isZeroWidthSpaceGlyph(Glyph glyph) const { return glyph == m_zeroWidthSpaceGlyph &amp;&amp; glyph; }
+    Glyph zeroGlyph() const { return m_zeroGlyph; }
+    void setZeroGlyph(Glyph zeroGlyph) { m_zeroGlyph = zeroGlyph; }
+
+    GlyphData glyphDataForCharacter(UChar32) const;
+    Glyph glyphForCharacter(UChar32) const;
+
+    RefPtr&lt;SimpleFontData&gt; systemFallbackFontDataForCharacter(UChar32, const FontDescription&amp;, bool isForPlatformFont) const;
+
+    const GlyphPage* glyphPage(unsigned pageNumber) const;
+
+    void determinePitch();
+    Pitch pitch() const { return m_treatAsFixedPitch ? FixedPitch : VariablePitch; }
+
+    const SVGData* svgData() const { return m_svgData.get(); }
+    bool isSVGFont() const { return !!m_svgData; }
+
+    bool isCustomFont() const { return m_isCustomFont; }
+    bool isLoading() const { return m_isLoading; }
+
+#ifndef NDEBUG
+    String description() const;
+#endif
+
+#if USE(APPKIT)
+    const SimpleFontData* compositeFontReferenceFontData(NSFont *key) const;
+    NSFont* getNSFont() const { return m_platformData.nsFont(); }
+#endif
+
+#if PLATFORM(IOS)
+    CTFontRef getCTFont() const { return m_platformData.font(); }
+    bool shouldNotBeUsedForArabic() const { return m_shouldNotBeUsedForArabic; };
+#endif
+#if PLATFORM(COCOA)
+    CFDictionaryRef getCFStringAttributes(TypesettingFeatures, FontOrientation) const;
+#endif
+
+#if PLATFORM(COCOA) || USE(HARFBUZZ)
+    bool canRenderCombiningCharacterSequence(const UChar*, size_t) const;
+#endif
+
+    bool applyTransforms(GlyphBufferGlyph*, GlyphBufferAdvance*, size_t glyphCount, TypesettingFeatures) const;
+
+#if PLATFORM(WIN)
+    bool isSystemFont() const { return m_isSystemFont; }
+    SCRIPT_FONTPROPERTIES* scriptFontProperties() const;
+    SCRIPT_CACHE* scriptCache() const { return &amp;m_scriptCache; }
+    static void setShouldApplyMacAscentHack(bool);
+    static bool shouldApplyMacAscentHack();
+    static float ascentConsideringMacAscentHack(const WCHAR*, float ascent, float descent);
+#endif
+
+private:
+    SimpleFontData(const FontPlatformData&amp;, bool isCustomFont = false, bool isLoading = false, bool isTextOrientationFallback = false);
+
+    SimpleFontData(std::unique_ptr&lt;SVGData&gt;, float fontSize, bool syntheticBold, bool syntheticItalic);
+
+    void platformInit();
+    void platformGlyphInit();
+    void platformCharWidthInit();
+    void platformDestroy();
+
+    void initCharWidths();
+
+    PassRefPtr&lt;SimpleFontData&gt; createScaledFontData(const FontDescription&amp;, float scaleFactor) const;
+    PassRefPtr&lt;SimpleFontData&gt; platformCreateScaledFontData(const FontDescription&amp;, float scaleFactor) const;
+
+    void removeFromSystemFallbackCache();
+
+#if PLATFORM(WIN)
+    void initGDIFont();
+    void platformCommonDestroy();
+    FloatRect boundsForGDIGlyph(Glyph glyph) const;
+    float widthForGDIGlyph(Glyph glyph) const;
+#endif
+
+#if USE(CG)
+    bool canUseFastGlyphAdvanceGetter(Glyph glyph, CGSize&amp; advance, bool&amp; populatedAdvance) const;
+    CGFontRenderingStyle renderingStyle() const;
+    bool advanceForColorBitmapFont(Glyph, CGSize&amp; result) const; // Returns true if the font is a color bitmap font
+#endif
+
+    FontMetrics m_fontMetrics;
+    float m_maxCharWidth;
+    float m_avgCharWidth;
+
+    FontPlatformData m_platformData;
+    std::unique_ptr&lt;SVGData&gt; m_svgData;
+
+    mutable RefPtr&lt;GlyphPage&gt; m_glyphPageZero;
+    mutable HashMap&lt;unsigned, RefPtr&lt;GlyphPage&gt;&gt; m_glyphPages;
+    mutable std::unique_ptr&lt;GlyphMetricsMap&lt;FloatRect&gt;&gt; m_glyphToBoundsMap;
+    mutable GlyphMetricsMap&lt;float&gt; m_glyphToWidthMap;
+
+    bool m_treatAsFixedPitch;
+    bool m_isCustomFont;  // Whether or not we are custom font loaded via @font-face
+    bool m_isLoading; // Whether or not this custom font is still in the act of loading.
+
+    bool m_isTextOrientationFallback;
+    bool m_isBrokenIdeographFallback;
+
+    bool m_isUsedInSystemFallbackCache { false };
+
+    mutable RefPtr&lt;OpenTypeMathData&gt; m_mathData;
+#if ENABLE(OPENTYPE_VERTICAL)
+    RefPtr&lt;OpenTypeVerticalData&gt; m_verticalData;
+#endif
+    bool m_hasVerticalGlyphs;
+
+    Glyph m_spaceGlyph;
+    float m_spaceWidth;
+    Glyph m_zeroGlyph;
+    float m_adjustedSpaceWidth;
+
+    Glyph m_zeroWidthSpaceGlyph;
+
+    struct DerivedFontData {
+        explicit DerivedFontData(bool custom)
+            : forCustomFont(custom)
+        {
+        }
+        ~DerivedFontData();
+
+        bool forCustomFont;
+        RefPtr&lt;SimpleFontData&gt; smallCaps;
+        RefPtr&lt;SimpleFontData&gt; emphasisMark;
+        RefPtr&lt;SimpleFontData&gt; brokenIdeograph;
+        RefPtr&lt;SimpleFontData&gt; verticalRightOrientation;
+        RefPtr&lt;SimpleFontData&gt; uprightOrientation;
+        RefPtr&lt;SimpleFontData&gt; nonSyntheticItalic;
+#if USE(APPKIT)
+        HashMap&lt;NSFont*, RefPtr&lt;SimpleFontData&gt;&gt; compositeFontReferences;
+#endif
+    };
+
+    mutable std::unique_ptr&lt;DerivedFontData&gt; m_derivedFontData;
+
+#if USE(CG) || USE(CAIRO)
+    float m_syntheticBoldOffset;
+#endif
+
+#if PLATFORM(COCOA)
+    mutable HashMap&lt;unsigned, RetainPtr&lt;CFDictionaryRef&gt;&gt; m_CFStringAttributes;
+#endif
+
+#if PLATFORM(COCOA) || USE(HARFBUZZ)
+    mutable std::unique_ptr&lt;HashMap&lt;String, bool&gt;&gt; m_combiningCharacterSequenceSupport;
+#endif
+
+#if PLATFORM(WIN)
+    bool m_isSystemFont;
+    mutable SCRIPT_CACHE m_scriptCache;
+    mutable SCRIPT_FONTPROPERTIES* m_scriptFontProperties;
+#endif
+#if PLATFORM(IOS)
+    bool m_shouldNotBeUsedForArabic;
+#endif
+};
+
+ALWAYS_INLINE FloatRect SimpleFontData::boundsForGlyph(Glyph glyph) const
+{
+    if (isZeroWidthSpaceGlyph(glyph))
+        return FloatRect();
+
+    FloatRect bounds;
+    if (m_glyphToBoundsMap) {
+        bounds = m_glyphToBoundsMap-&gt;metricsForGlyph(glyph);
+        if (bounds.width() != cGlyphSizeUnknown)
+            return bounds;
+    }
+
+    bounds = platformBoundsForGlyph(glyph);
+    if (!m_glyphToBoundsMap)
+        m_glyphToBoundsMap = std::make_unique&lt;GlyphMetricsMap&lt;FloatRect&gt;&gt;();
+    m_glyphToBoundsMap-&gt;setMetricsForGlyph(glyph, bounds);
+    return bounds;
+}
+
+ALWAYS_INLINE float SimpleFontData::widthForGlyph(Glyph glyph) const
+{
+    if (isZeroWidthSpaceGlyph(glyph))
+        return 0;
+
+    float width = m_glyphToWidthMap.metricsForGlyph(glyph);
+    if (width != cGlyphSizeUnknown)
+        return width;
+
+    if (isSVGFont())
+        width = m_svgData-&gt;widthForSVGGlyph(glyph, m_platformData.size());
+#if ENABLE(OPENTYPE_VERTICAL)
+    else if (m_verticalData)
+#if USE(CG) || USE(CAIRO)
+        width = m_verticalData-&gt;advanceHeight(this, glyph) + m_syntheticBoldOffset;
+#else
+        width = m_verticalData-&gt;advanceHeight(this, glyph);
+#endif
+#endif
+    else
+        width = platformWidthForGlyph(glyph);
+
+    m_glyphToWidthMap.setMetricsForGlyph(glyph, width);
+    return width;
+}
+
+} // namespace WebCore
+
+#endif // SimpleFontData_h
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontCascadeFastPathcppfromrev178510trunkSourceWebCoreplatformgraphicsFontFastPathcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/FontCascadeFastPath.cpp (from rev 178510, trunk/Source/WebCore/platform/graphics/FontFastPath.cpp) (0 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/FontCascadeFastPath.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/FontCascadeFastPath.cpp        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -0,0 +1,341 @@
</span><ins>+/**
+ * Copyright (C) 2003, 2006, 2010 Apple Inc. All rights reserved.
+ * Copyright (C) 2008 Holger Hans Peter Freyther
+ * Copyright (C) 2009 Torch Mobile, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include &quot;config.h&quot;
+#include &quot;FontCascade.h&quot;
+
+#include &quot;FloatRect.h&quot;
+#include &quot;FontGlyphs.h&quot;
+#include &quot;GlyphBuffer.h&quot;
+#include &quot;LayoutRect.h&quot;
+#include &quot;SimpleFontData.h&quot;
+#include &quot;TextRun.h&quot;
+#include &quot;WidthIterator.h&quot;
+#include &lt;wtf/MainThread.h&gt;
+#include &lt;wtf/MathExtras.h&gt;
+#include &lt;wtf/unicode/CharacterNames.h&gt;
+
+using namespace WTF;
+using namespace Unicode;
+
+namespace WebCore {
+
+// FIXME: This function may not work if the emphasis mark uses a complex script, but none of the
+// standard emphasis marks do so.
+bool FontCascade::getEmphasisMarkGlyphData(const AtomicString&amp; mark, GlyphData&amp; glyphData) const
+{
+    if (mark.isEmpty())
+        return false;
+
+    UChar32 character = mark[0];
+
+    if (U16_IS_SURROGATE(character)) {
+        if (!U16_IS_SURROGATE_LEAD(character))
+            return false;
+
+        if (mark.length() &lt; 2)
+            return false;
+
+        UChar low = mark[1];
+        if (!U16_IS_TRAIL(low))
+            return false;
+
+        character = U16_GET_SUPPLEMENTARY(character, low);
+    }
+
+    glyphData = glyphDataForCharacter(character, false, EmphasisMarkVariant);
+    return true;
+}
+
+int FontCascade::emphasisMarkAscent(const AtomicString&amp; mark) const
+{
+    GlyphData markGlyphData;
+    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
+        return 0;
+
+    const SimpleFontData* markFontData = markGlyphData.fontData;
+    ASSERT(markFontData);
+    if (!markFontData)
+        return 0;
+
+    return markFontData-&gt;fontMetrics().ascent();
+}
+
+int FontCascade::emphasisMarkDescent(const AtomicString&amp; mark) const
+{
+    GlyphData markGlyphData;
+    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
+        return 0;
+
+    const SimpleFontData* markFontData = markGlyphData.fontData;
+    ASSERT(markFontData);
+    if (!markFontData)
+        return 0;
+
+    return markFontData-&gt;fontMetrics().descent();
+}
+
+int FontCascade::emphasisMarkHeight(const AtomicString&amp; mark) const
+{
+    GlyphData markGlyphData;
+    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
+        return 0;
+
+    const SimpleFontData* markFontData = markGlyphData.fontData;
+    ASSERT(markFontData);
+    if (!markFontData)
+        return 0;
+
+    return markFontData-&gt;fontMetrics().height();
+}
+
+float FontCascade::getGlyphsAndAdvancesForSimpleText(const TextRun&amp; run, int from, int to, GlyphBuffer&amp; glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
+{
+    float initialAdvance;
+
+    WidthIterator it(this, run, 0, false, forTextEmphasis);
+    // FIXME: Using separate glyph buffers for the prefix and the suffix is incorrect when kerning or
+    // ligatures are enabled.
+    GlyphBuffer localGlyphBuffer;
+    it.advance(from, &amp;localGlyphBuffer);
+    float beforeWidth = it.m_runWidthSoFar;
+    it.advance(to, &amp;glyphBuffer);
+
+    if (glyphBuffer.isEmpty())
+        return 0;
+
+    float afterWidth = it.m_runWidthSoFar;
+
+    if (run.rtl()) {
+        float finalRoundingWidth = it.m_finalRoundingWidth;
+        it.advance(run.length(), &amp;localGlyphBuffer);
+        initialAdvance = finalRoundingWidth + it.m_runWidthSoFar - afterWidth;
+    } else
+        initialAdvance = beforeWidth;
+
+    if (run.rtl())
+        glyphBuffer.reverse(0, glyphBuffer.size());
+
+    return initialAdvance;
+}
+
+float FontCascade::drawSimpleText(GraphicsContext* context, const TextRun&amp; run, const FloatPoint&amp; point, int from, int to) const
+{
+    // This glyph buffer holds our glyphs+advances+font data for each glyph.
+    GlyphBuffer glyphBuffer;
+
+    float startX = point.x() + getGlyphsAndAdvancesForSimpleText(run, from, to, glyphBuffer);
+
+    if (glyphBuffer.isEmpty())
+        return 0;
+
+    FloatPoint startPoint(startX, point.y());
+    drawGlyphBuffer(context, run, glyphBuffer, startPoint);
+
+    return startPoint.x() - startX;
+}
+
+void FontCascade::drawEmphasisMarksForSimpleText(GraphicsContext* context, const TextRun&amp; run, const AtomicString&amp; mark, const FloatPoint&amp; point, int from, int to) const
+{
+    GlyphBuffer glyphBuffer;
+    float initialAdvance = getGlyphsAndAdvancesForSimpleText(run, from, to, glyphBuffer, ForTextEmphasis);
+
+    if (glyphBuffer.isEmpty())
+        return;
+
+    drawEmphasisMarks(context, run, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
+}
+
+void FontCascade::drawGlyphBuffer(GraphicsContext* context, const TextRun&amp; run, const GlyphBuffer&amp; glyphBuffer, FloatPoint&amp; point) const
+{
+#if !ENABLE(SVG_FONTS)
+    UNUSED_PARAM(run);
+#endif
+
+    // Draw each contiguous run of glyphs that use the same font data.
+    const SimpleFontData* fontData = glyphBuffer.fontDataAt(0);
+    FloatSize offset = glyphBuffer.offsetAt(0);
+    FloatPoint startPoint(point.x(), point.y() - glyphBuffer.initialAdvance().height());
+    float nextX = startPoint.x() + glyphBuffer.advanceAt(0).width();
+    float nextY = startPoint.y() + glyphBuffer.advanceAt(0).height();
+    int lastFrom = 0;
+    int nextGlyph = 1;
+#if ENABLE(SVG_FONTS)
+    TextRun::RenderingContext* renderingContext = run.renderingContext();
+#endif
+    while (nextGlyph &lt; glyphBuffer.size()) {
+        const SimpleFontData* nextFontData = glyphBuffer.fontDataAt(nextGlyph);
+        FloatSize nextOffset = glyphBuffer.offsetAt(nextGlyph);
+
+        if (nextFontData != fontData || nextOffset != offset) {
+#if ENABLE(SVG_FONTS)
+            if (renderingContext &amp;&amp; fontData-&gt;isSVGFont())
+                renderingContext-&gt;drawSVGGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint);
+            else
+#endif
+                drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint);
+
+            lastFrom = nextGlyph;
+            fontData = nextFontData;
+            offset = nextOffset;
+            startPoint.setX(nextX);
+            startPoint.setY(nextY);
+        }
+        nextX += glyphBuffer.advanceAt(nextGlyph).width();
+        nextY += glyphBuffer.advanceAt(nextGlyph).height();
+        nextGlyph++;
+    }
+
+#if ENABLE(SVG_FONTS)
+    if (renderingContext &amp;&amp; fontData-&gt;isSVGFont())
+        renderingContext-&gt;drawSVGGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint);
+    else
+#endif
+    {
+        drawGlyphs(context, fontData, glyphBuffer, lastFrom, nextGlyph - lastFrom, startPoint);
+        point.setX(nextX);
+    }
+}
+
+inline static float offsetToMiddleOfGlyph(const SimpleFontData* fontData, Glyph glyph)
+{
+    if (fontData-&gt;platformData().orientation() == Horizontal) {
+        FloatRect bounds = fontData-&gt;boundsForGlyph(glyph);
+        return bounds.x() + bounds.width() / 2;
+    }
+    // FIXME: Use glyph bounds once they make sense for vertical fonts.
+    return fontData-&gt;widthForGlyph(glyph) / 2;
+}
+
+inline static float offsetToMiddleOfGlyphAtIndex(const GlyphBuffer&amp; glyphBuffer, size_t i)
+{
+    return offsetToMiddleOfGlyph(glyphBuffer.fontDataAt(i), glyphBuffer.glyphAt(i));
+}
+
+void FontCascade::drawEmphasisMarks(GraphicsContext* context, const TextRun&amp; run, const GlyphBuffer&amp; glyphBuffer, const AtomicString&amp; mark, const FloatPoint&amp; point) const
+{
+    GlyphData markGlyphData;
+    if (!getEmphasisMarkGlyphData(mark, markGlyphData))
+        return;
+
+    const SimpleFontData* markFontData = markGlyphData.fontData;
+    ASSERT(markFontData);
+    if (!markFontData)
+        return;
+
+    Glyph markGlyph = markGlyphData.glyph;
+    Glyph spaceGlyph = markFontData-&gt;spaceGlyph();
+
+    float middleOfLastGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, 0);
+    FloatPoint startPoint(point.x() + middleOfLastGlyph - offsetToMiddleOfGlyph(markFontData, markGlyph), point.y());
+
+    GlyphBuffer markBuffer;
+    for (int i = 0; i + 1 &lt; glyphBuffer.size(); ++i) {
+        float middleOfNextGlyph = offsetToMiddleOfGlyphAtIndex(glyphBuffer, i + 1);
+        float advance = glyphBuffer.advanceAt(i).width() - middleOfLastGlyph + middleOfNextGlyph;
+        markBuffer.add(glyphBuffer.glyphAt(i) ? markGlyph : spaceGlyph, markFontData, advance);
+        middleOfLastGlyph = middleOfNextGlyph;
+    }
+    markBuffer.add(glyphBuffer.glyphAt(glyphBuffer.size() - 1) ? markGlyph : spaceGlyph, markFontData, 0);
+
+    drawGlyphBuffer(context, run, markBuffer, startPoint);
+}
+
+float FontCascade::floatWidthForSimpleText(const TextRun&amp; run, HashSet&lt;const SimpleFontData*&gt;* fallbackFonts, GlyphOverflow* glyphOverflow) const
+{
+    WidthIterator it(this, run, fallbackFonts, glyphOverflow);
+    GlyphBuffer glyphBuffer;
+    it.advance(run.length(), (typesettingFeatures() &amp; (Kerning | Ligatures)) ? &amp;glyphBuffer : 0);
+
+    if (glyphOverflow) {
+        glyphOverflow-&gt;top = std::max&lt;int&gt;(glyphOverflow-&gt;top, ceilf(-it.minGlyphBoundingBoxY()) - (glyphOverflow-&gt;computeBounds ? 0 : fontMetrics().ascent()));
+        glyphOverflow-&gt;bottom = std::max&lt;int&gt;(glyphOverflow-&gt;bottom, ceilf(it.maxGlyphBoundingBoxY()) - (glyphOverflow-&gt;computeBounds ? 0 : fontMetrics().descent()));
+        glyphOverflow-&gt;left = ceilf(it.firstGlyphOverflow());
+        glyphOverflow-&gt;right = ceilf(it.lastGlyphOverflow());
+    }
+
+    return it.m_runWidthSoFar;
+}
+
+void FontCascade::adjustSelectionRectForSimpleText(const TextRun&amp; run, LayoutRect&amp; selectionRect, int from, int to) const
+{
+    GlyphBuffer glyphBuffer;
+    WidthIterator it(this, run);
+    it.advance(from, &amp;glyphBuffer);
+    float beforeWidth = it.m_runWidthSoFar;
+    it.advance(to, &amp;glyphBuffer);
+    float afterWidth = it.m_runWidthSoFar;
+    float totalWidth = -1;
+
+    if (run.rtl()) {
+        it.advance(run.length(), &amp;glyphBuffer);
+        totalWidth = it.m_runWidthSoFar;
+        selectionRect.move(totalWidth - afterWidth, 0);
+    } else
+        selectionRect.move(beforeWidth, 0);
+    selectionRect.setWidth(afterWidth - beforeWidth);
+}
+
+int FontCascade::offsetForPositionForSimpleText(const TextRun&amp; run, float x, bool includePartialGlyphs) const
+{
+    float delta = x;
+
+    WidthIterator it(this, run);
+    GlyphBuffer localGlyphBuffer;
+    unsigned offset;
+    if (run.rtl()) {
+        delta -= floatWidthForSimpleText(run);
+        while (1) {
+            offset = it.m_currentCharacter;
+            float w;
+            if (!it.advanceOneCharacter(w, localGlyphBuffer))
+                break;
+            delta += w;
+            if (includePartialGlyphs) {
+                if (delta - w / 2 &gt;= 0)
+                    break;
+            } else {
+                if (delta &gt;= 0)
+                    break;
+            }
+        }
+    } else {
+        while (1) {
+            offset = it.m_currentCharacter;
+            float w;
+            if (!it.advanceOneCharacter(w, localGlyphBuffer))
+                break;
+            delta -= w;
+            if (includePartialGlyphs) {
+                if (delta + w / 2 &lt;= 0)
+                    break;
+            } else {
+                if (delta &lt;= 0)
+                    break;
+            }
+        }
+    }
+
+    return offset;
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscawinPlatformCALayerWincpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp (178517 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp        2015-01-15 19:20:03 UTC (rev 178517)
+++ trunk/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWin.cpp        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -28,7 +28,7 @@
</span><span class="cx"> #include &quot;PlatformCALayerWin.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;AbstractCACFLayerTreeHost.h&quot;
</span><del>-#include &quot;Font.h&quot;
</del><ins>+#include &quot;FontCascade.h&quot;
</ins><span class="cx"> #include &quot;GraphicsContext.h&quot;
</span><span class="cx"> #include &quot;PlatformCAAnimationWin.h&quot;
</span><span class="cx"> #include &quot;PlatformCALayerWinInternal.h&quot;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscawinPlatformCALayerWinInternalcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp (178517 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp        2015-01-15 19:20:03 UTC (rev 178517)
+++ trunk/Source/WebCore/platform/graphics/ca/win/PlatformCALayerWinInternal.cpp        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -27,7 +27,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;PlatformCALayerWinInternal.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;Font.h&quot;
</del><ins>+#include &quot;FontCascade.h&quot;
</ins><span class="cx"> #include &quot;GraphicsContext.h&quot;
</span><span class="cx"> #include &quot;PlatformCALayer.h&quot;
</span><span class="cx"> #include &quot;TextRun.h&quot;
</span><span class="lines">@@ -159,7 +159,7 @@
</span><span class="cx"> 
</span><span class="cx">         desc.setComputedSize(18);
</span><span class="cx">         
</span><del>-        Font font = Font(desc, 0, 0);
</del><ins>+        FontCascade font = FontCascade(desc, 0, 0);
</ins><span class="cx">         font.update(0);
</span><span class="cx"> 
</span><span class="cx">         GraphicsContext cg(context);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsiosFontIOSmmfromrev178510trunkSourceWebCoreplatformgraphicsiosSimpleFontDataIOSmm"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/ios/FontIOS.mm (from rev 178510, trunk/Source/WebCore/platform/graphics/ios/SimpleFontDataIOS.mm) (0 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/ios/FontIOS.mm                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/ios/FontIOS.mm        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -0,0 +1,197 @@
</span><ins>+/*
+ * Copyright (C) 2005, 2006, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov
+ *
+ * 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 INC. AND ITS CONTRIBUTORS ``AS IS''
+ * 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 INC. 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.
+ */
+
+#import &quot;config.h&quot;
+#import &quot;SimpleFontData.h&quot;
+
+#import &quot;BlockExceptions.h&quot;
+#import &quot;CoreGraphicsSPI.h&quot;
+#import &quot;FontCache.h&quot;
+#import &quot;FontCascade.h&quot;
+#import &quot;FontDescription.h&quot;
+#import &quot;FontServicesIOS.h&quot;
+#import &lt;CoreText/CoreText.h&gt;
+#import &lt;float.h&gt;
+#import &lt;unicode/uchar.h&gt;
+#import &lt;wtf/Assertions.h&gt;
+#import &lt;wtf/StdLibExtras.h&gt;
+
+namespace WebCore {
+
+static bool fontFamilyShouldNotBeUsedForArabic(CFStringRef fontFamilyName)
+{
+    if (!fontFamilyName)
+        return false;
+
+    // Times New Roman contains Arabic glyphs, but Core Text doesn't know how to shape them. &lt;rdar://problem/9823975&gt;
+    // FIXME &lt;rdar://problem/12096835&gt; remove this function once the above bug is fixed.
+    // Arial and Tahoma are have performance issues so don't use them as well.
+    return (CFStringCompare(CFSTR(&quot;Times New Roman&quot;), fontFamilyName, 0) == kCFCompareEqualTo)
+           || (CFStringCompare(CFSTR(&quot;Arial&quot;), fontFamilyName, 0) == kCFCompareEqualTo)
+           || (CFStringCompare(CFSTR(&quot;Tahoma&quot;), fontFamilyName, 0) == kCFCompareEqualTo);
+}
+
+static bool fontHasVerticalGlyphs(CTFontRef ctFont)
+{
+    // The check doesn't look neat but this is what AppKit does for vertical writing...
+    RetainPtr&lt;CFArrayRef&gt; tableTags = adoptCF(CTFontCopyAvailableTables(ctFont, kCTFontTableOptionNoOptions));
+    CFIndex numTables = CFArrayGetCount(tableTags.get());
+    for (CFIndex index = 0; index &lt; numTables; ++index) {
+        CTFontTableTag tag = (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tableTags.get(), index);
+        if (tag == kCTFontTableVhea || tag == kCTFontTableVORG)
+            return true;
+    }
+    return false;
+}
+
+void SimpleFontData::platformInit()
+{
+    m_syntheticBoldOffset = m_platformData.m_syntheticBold ? ceilf(m_platformData.size()  / 24.0f) : 0.f;
+    m_spaceGlyph = 0;
+    m_spaceWidth = 0;
+    unsigned unitsPerEm;
+    float ascent;
+    float descent;
+    float capHeight;
+    float lineGap;
+    float lineSpacing;
+    float xHeight;
+    RetainPtr&lt;CFStringRef&gt; familyName;
+    if (CTFontRef ctFont = m_platformData.font()) {
+        FontServicesIOS fontService(ctFont);
+        ascent = ceilf(fontService.ascent());
+        descent = ceilf(fontService.descent());
+        lineSpacing = fontService.lineSpacing();
+        lineGap = fontService.lineGap();
+        xHeight = fontService.xHeight();
+        capHeight = fontService.capHeight();
+        unitsPerEm = fontService.unitsPerEm();
+        familyName = adoptCF(CTFontCopyFamilyName(ctFont));
+    } else {
+        CGFontRef cgFont = m_platformData.cgFont();
+
+        unitsPerEm = CGFontGetUnitsPerEm(cgFont);
+
+        float pointSize = m_platformData.size();
+        ascent = lroundf(scaleEmToUnits(CGFontGetAscent(cgFont), unitsPerEm) * pointSize);
+        descent = lroundf(-scaleEmToUnits(-abs(CGFontGetDescent(cgFont)), unitsPerEm) * pointSize);
+        lineGap = lroundf(scaleEmToUnits(CGFontGetLeading(cgFont), unitsPerEm) * pointSize);
+        xHeight = scaleEmToUnits(CGFontGetXHeight(cgFont), unitsPerEm) * pointSize;
+        capHeight = scaleEmToUnits(CGFontGetCapHeight(cgFont), unitsPerEm) * pointSize;
+
+        lineSpacing = ascent + descent + lineGap;
+        familyName = adoptCF(CGFontCopyFamilyName(cgFont));
+    }
+
+    m_fontMetrics.setUnitsPerEm(unitsPerEm);
+    m_fontMetrics.setAscent(ascent);
+    m_fontMetrics.setDescent(descent);
+    m_fontMetrics.setLineGap(lineGap);
+    m_fontMetrics.setLineSpacing(lineSpacing);
+    m_fontMetrics.setXHeight(xHeight);
+    m_fontMetrics.setCapHeight(capHeight);
+    m_shouldNotBeUsedForArabic = fontFamilyShouldNotBeUsedForArabic(familyName.get());
+
+    if (platformData().orientation() == Vertical &amp;&amp; !isTextOrientationFallback())
+        m_hasVerticalGlyphs = fontHasVerticalGlyphs(m_platformData.ctFont());
+
+    if (!m_platformData.m_isEmoji)
+        return;
+
+    int thirdOfSize = m_platformData.size() / 3;
+    m_fontMetrics.setAscent(thirdOfSize);
+    m_fontMetrics.setDescent(thirdOfSize);
+    m_fontMetrics.setLineGap(thirdOfSize);
+    m_fontMetrics.setLineSpacing(0);
+}
+
+void SimpleFontData::platformCharWidthInit()
+{
+    m_avgCharWidth = 0;
+    m_maxCharWidth = 0;
+
+    // Fallback to a cross-platform estimate, which will populate these values if they are non-positive.
+    initCharWidths();
+}
+
+PassRefPtr&lt;SimpleFontData&gt; SimpleFontData::platformCreateScaledFontData(const FontDescription&amp;, float scaleFactor) const
+{
+    if (isCustomFont()) {
+        FontPlatformData scaledFontData(m_platformData);
+        scaledFontData.m_size = scaledFontData.m_size * scaleFactor;
+        return SimpleFontData::create(scaledFontData, true, false);
+    }
+
+    float size = m_platformData.size() * scaleFactor;
+    CTFontSymbolicTraits fontTraits = CTFontGetSymbolicTraits(m_platformData.font());
+    RetainPtr&lt;CTFontDescriptorRef&gt; fontDescriptor = adoptCF(CTFontCopyFontDescriptor(m_platformData.font()));
+    RetainPtr&lt;CTFontRef&gt; scaledFont = adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), size, nullptr));
+    FontPlatformData scaledFontData(scaledFont.get(), size, m_platformData.isPrinterFont(), false, false, m_platformData.orientation());
+
+    if (scaledFontData.font()) {
+        if (m_platformData.m_syntheticBold)
+            fontTraits |= kCTFontBoldTrait;
+        if (m_platformData.m_syntheticOblique)
+            fontTraits |= kCTFontItalicTrait;
+
+        CTFontSymbolicTraits scaledFontTraits = CTFontGetSymbolicTraits(scaledFontData.font());
+        scaledFontData.m_syntheticBold = (fontTraits &amp; kCTFontBoldTrait) &amp;&amp; !(scaledFontTraits &amp; kCTFontTraitBold);
+        scaledFontData.m_syntheticOblique = (fontTraits &amp; kCTFontItalicTrait) &amp;&amp; !(scaledFontTraits &amp; kCTFontTraitItalic);
+
+        return fontCache().fontForPlatformData(scaledFontData);
+    }
+
+    return nullptr;
+}
+
+void SimpleFontData::determinePitch()
+{
+    CTFontRef ctFont = m_platformData.font();
+    m_treatAsFixedPitch = false;
+    if (!ctFont)
+        return; // CTFont is null in the case of SVG fonts for example.
+
+    RetainPtr&lt;CFStringRef&gt; fullName = adoptCF(CTFontCopyFullName(ctFont));
+    RetainPtr&lt;CFStringRef&gt; familyName = adoptCF(CTFontCopyFamilyName(ctFont));
+
+    m_treatAsFixedPitch = CGFontIsFixedPitch(m_platformData.cgFont()) || (fullName &amp;&amp; (CFStringCompare(fullName.get(), CFSTR(&quot;Osaka-Mono&quot;), kCFCompareCaseInsensitive) == kCFCompareEqualTo || CFStringCompare(fullName.get(), CFSTR(&quot;MS-PGothic&quot;), kCFCompareCaseInsensitive) == kCFCompareEqualTo));
+    if (familyName &amp;&amp; CFStringCompare(familyName.get(), CFSTR(&quot;Courier New&quot;), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
+        // Special case Courier New to not be treated as fixed pitch, as this will make use of a hacked space width which is undesireable for iPhone (see rdar://6269783).
+        m_treatAsFixedPitch = false;
+    }
+}
+
+CGFontRenderingStyle SimpleFontData::renderingStyle() const
+{
+    return kCGFontRenderingStyleAntialiasing | kCGFontRenderingStyleSubpixelPositioning | kCGFontRenderingStyleSubpixelQuantization | kCGFontAntialiasingStyleUnfiltered;
+}
+
+bool SimpleFontData::advanceForColorBitmapFont(Glyph, CGSize&amp;) const
+{
+    return false;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacFontCascadeComplexTextMaccppfromrev178510trunkSourceWebCoreplatformgraphicsmacFontComplexTextMaccpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/mac/FontCascadeComplexTextMac.cpp (from rev 178510, trunk/Source/WebCore/platform/graphics/mac/FontComplexTextMac.cpp) (0 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/FontCascadeComplexTextMac.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/mac/FontCascadeComplexTextMac.cpp        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -0,0 +1,184 @@
</span><ins>+/*
+ * Copyright (C) 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
+ *
+ * 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 INC. AND ITS CONTRIBUTORS ``AS IS'' 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 INC. 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;FontCascade.h&quot;
+
+#include &quot;ComplexTextController.h&quot;
+#include &quot;FontGlyphs.h&quot;
+#include &quot;GlyphBuffer.h&quot;
+#include &quot;GraphicsContext.h&quot;
+#include &quot;IntRect.h&quot;
+#include &quot;LayoutRect.h&quot;
+#include &quot;SimpleFontData.h&quot;
+#include &quot;TextRun.h&quot;
+#include &lt;wtf/MathExtras.h&gt;
+
+namespace WebCore {
+
+void FontCascade::adjustSelectionRectForComplexText(const TextRun&amp; run, LayoutRect&amp; selectionRect, int from, int to) const
+{
+    ComplexTextController controller(this, run);
+    controller.advance(from);
+    float beforeWidth = controller.runWidthSoFar();
+    controller.advance(to);
+    float afterWidth = controller.runWidthSoFar();
+
+    if (run.rtl())
+        selectionRect.move(controller.totalWidth() - afterWidth, 0);
+    else
+        selectionRect.move(beforeWidth, 0);
+    selectionRect.setWidth(afterWidth - beforeWidth);
+}
+
+float FontCascade::getGlyphsAndAdvancesForComplexText(const TextRun&amp; run, int from, int to, GlyphBuffer&amp; glyphBuffer, ForTextEmphasisOrNot forTextEmphasis) const
+{
+    float initialAdvance;
+
+    ComplexTextController controller(this, run, false, 0, forTextEmphasis);
+    controller.advance(from);
+    float beforeWidth = controller.runWidthSoFar();
+    controller.advance(to, &amp;glyphBuffer);
+
+    if (glyphBuffer.isEmpty())
+        return 0;
+
+    float afterWidth = controller.runWidthSoFar();
+
+    if (run.rtl()) {
+        initialAdvance = controller.totalWidth() + controller.finalRoundingWidth() - afterWidth;
+        glyphBuffer.reverse(0, glyphBuffer.size());
+    } else
+        initialAdvance = beforeWidth;
+
+    return initialAdvance;
+}
+
+float FontCascade::drawComplexText(GraphicsContext* context, const TextRun&amp; run, const FloatPoint&amp; point, int from, int to) const
+{
+    // This glyph buffer holds our glyphs + advances + font data for each glyph.
+    GlyphBuffer glyphBuffer;
+
+    float startX = point.x() + getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer);
+
+    // We couldn't generate any glyphs for the run.  Give up.
+    if (glyphBuffer.isEmpty())
+        return 0;
+
+    // Draw the glyph buffer now at the starting point returned in startX.
+    FloatPoint startPoint(startX, point.y());
+    drawGlyphBuffer(context, run, glyphBuffer, startPoint);
+
+    return startPoint.x() - startX;
+}
+
+void FontCascade::drawEmphasisMarksForComplexText(GraphicsContext* context, const TextRun&amp; run, const AtomicString&amp; mark, const FloatPoint&amp; point, int from, int to) const
+{
+    GlyphBuffer glyphBuffer;
+    float initialAdvance = getGlyphsAndAdvancesForComplexText(run, from, to, glyphBuffer, ForTextEmphasis);
+
+    if (glyphBuffer.isEmpty())
+        return;
+
+    drawEmphasisMarks(context, run, glyphBuffer, mark, FloatPoint(point.x() + initialAdvance, point.y()));
+}
+
+float FontCascade::floatWidthForComplexText(const TextRun&amp; run, HashSet&lt;const SimpleFontData*&gt;* fallbackFonts, GlyphOverflow* glyphOverflow) const
+{
+    ComplexTextController controller(this, run, true, fallbackFonts);
+    if (glyphOverflow) {
+        glyphOverflow-&gt;top = std::max&lt;int&gt;(glyphOverflow-&gt;top, ceilf(-controller.minGlyphBoundingBoxY()) - (glyphOverflow-&gt;computeBounds ? 0 : fontMetrics().ascent()));
+        glyphOverflow-&gt;bottom = std::max&lt;int&gt;(glyphOverflow-&gt;bottom, ceilf(controller.maxGlyphBoundingBoxY()) - (glyphOverflow-&gt;computeBounds ? 0 : fontMetrics().descent()));
+        glyphOverflow-&gt;left = std::max&lt;int&gt;(0, ceilf(-controller.minGlyphBoundingBoxX()));
+        glyphOverflow-&gt;right = std::max&lt;int&gt;(0, ceilf(controller.maxGlyphBoundingBoxX() - controller.totalWidth()));
+    }
+    return controller.totalWidth();
+}
+
+int FontCascade::offsetForPositionForComplexText(const TextRun&amp; run, float x, bool includePartialGlyphs) const
+{
+    ComplexTextController controller(this, run);
+    return controller.offsetForPosition(x, includePartialGlyphs);
+}
+
+const SimpleFontData* FontCascade::fontDataForCombiningCharacterSequence(const UChar* characters, size_t length, FontDataVariant variant) const
+{
+    UChar32 baseCharacter;
+    size_t baseCharacterLength = 0;
+    U16_NEXT(characters, baseCharacterLength, length, baseCharacter);
+
+    GlyphData baseCharacterGlyphData = glyphDataForCharacter(baseCharacter, false, variant);
+
+    if (!baseCharacterGlyphData.glyph)
+        return 0;
+
+    if (length == baseCharacterLength)
+        return baseCharacterGlyphData.fontData;
+
+    bool triedBaseCharacterFontData = false;
+
+    for (unsigned i = 0; !fallbackRangesAt(i).isNull(); ++i) {
+        const SimpleFontData* simpleFontData = fallbackRangesAt(i).fontDataForCharacter(baseCharacter);
+        if (!simpleFontData)
+            continue;
+#if PLATFORM(IOS)
+        if (baseCharacter &gt;= 0x0600 &amp;&amp; baseCharacter &lt;= 0x06ff &amp;&amp; simpleFontData-&gt;shouldNotBeUsedForArabic())
+            continue;
+#endif
+        if (variant == NormalVariant) {
+            if (simpleFontData-&gt;platformData().orientation() == Vertical) {
+                if (isCJKIdeographOrSymbol(baseCharacter) &amp;&amp; !simpleFontData-&gt;hasVerticalGlyphs()) {
+                    variant = BrokenIdeographVariant;
+                    simpleFontData = simpleFontData-&gt;brokenIdeographFontData().get();
+                } else if (m_fontDescription.nonCJKGlyphOrientation() == NonCJKGlyphOrientationVerticalRight) {
+                    SimpleFontData* verticalRightFontData = simpleFontData-&gt;verticalRightOrientationFontData().get();
+                    Glyph verticalRightGlyph = verticalRightFontData-&gt;glyphForCharacter(baseCharacter);
+                    if (verticalRightGlyph == baseCharacterGlyphData.glyph)
+                        simpleFontData = verticalRightFontData;
+                } else {
+                    SimpleFontData* uprightFontData = simpleFontData-&gt;uprightOrientationFontData().get();
+                    Glyph uprightGlyph = uprightFontData-&gt;glyphForCharacter(baseCharacter);
+                    if (uprightGlyph != baseCharacterGlyphData.glyph)
+                        simpleFontData = uprightFontData;
+                }
+            }
+        } else {
+            if (const SimpleFontData* variantFontData = simpleFontData-&gt;variantFontData(m_fontDescription, variant).get())
+                simpleFontData = variantFontData;
+        }
+
+        if (simpleFontData == baseCharacterGlyphData.fontData)
+            triedBaseCharacterFontData = true;
+
+        if (simpleFontData-&gt;canRenderCombiningCharacterSequence(characters, length))
+            return simpleFontData;
+    }
+
+    if (!triedBaseCharacterFontData &amp;&amp; baseCharacterGlyphData.fontData &amp;&amp; baseCharacterGlyphData.fontData-&gt;canRenderCombiningCharacterSequence(characters, length))
+        return baseCharacterGlyphData.fontData;
+
+    return SimpleFontData::systemFallback();
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacFontCascadeMacmmfromrev178510trunkSourceWebCoreplatformgraphicsmacFontMacmm"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/mac/FontCascadeMac.mm (from rev 178510, trunk/Source/WebCore/platform/graphics/mac/FontMac.mm) (0 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/FontCascadeMac.mm                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/mac/FontCascadeMac.mm        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -0,0 +1,605 @@
</span><ins>+/*
+ * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
+ *           (C) 1999 Antti Koivisto (koivisto@kde.org)
+ *           (C) 2000 Dirk Mueller (mueller@kde.org)
+ * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#import &quot;config.h&quot;
+#import &quot;FontCascade.h&quot;
+
+#import &quot;CoreGraphicsSPI.h&quot;
+#import &quot;CoreTextSPI.h&quot;
+#import &quot;DashArray.h&quot;
+#import &quot;GlyphBuffer.h&quot;
+#import &quot;GraphicsContext.h&quot;
+#import &quot;Logging.h&quot;
+#import &quot;SimpleFontData.h&quot;
+#import &quot;WebCoreSystemInterface.h&quot;
+#if USE(APPKIT)
+#import &lt;AppKit/AppKit.h&gt;
+#endif
+#import &lt;wtf/MathExtras.h&gt;
+
+#if ENABLE(LETTERPRESS)
+#import &quot;CoreUISPI.h&quot;
+#import &quot;SoftLinking.h&quot;
+
+SOFT_LINK_PRIVATE_FRAMEWORK(CoreUI)
+SOFT_LINK_CLASS(CoreUI, CUICatalog)
+SOFT_LINK_CLASS(CoreUI, CUIStyleEffectConfiguration)
+
+SOFT_LINK_FRAMEWORK(UIKit)
+SOFT_LINK(UIKit, _UIKitGetTextEffectsCatalog, CUICatalog *, (void), ())
+#endif
+
+#define SYNTHETIC_OBLIQUE_ANGLE 14
+
+#ifdef __LP64__
+#define URefCon void*
+#else
+#define URefCon UInt32
+#endif
+
+namespace WebCore {
+
+bool FontCascade::canReturnFallbackFontsForComplexText()
+{
+    return true;
+}
+
+bool FontCascade::canExpandAroundIdeographsInComplexText()
+{
+    return true;
+}
+
+static inline void fillVectorWithHorizontalGlyphPositions(Vector&lt;CGPoint, 256&gt;&amp; positions, CGContextRef context, const CGSize* advances, size_t count)
+{
+    CGAffineTransform matrix = CGAffineTransformInvert(CGContextGetTextMatrix(context));
+    positions[0] = CGPointZero;
+    for (size_t i = 1; i &lt; count; ++i) {
+        CGSize advance = CGSizeApplyAffineTransform(advances[i - 1], matrix);
+        positions[i].x = positions[i - 1].x + advance.width;
+        positions[i].y = positions[i - 1].y + advance.height;
+    }
+}
+
+static inline bool shouldUseLetterpressEffect(const GraphicsContext&amp; context)
+{
+#if ENABLE(LETTERPRESS)
+    return context.textDrawingMode() &amp; TextModeLetterpress;
+#else
+    UNUSED_PARAM(context);
+    return false;
+#endif
+}
+
+static void showLetterpressedGlyphsWithAdvances(const FloatPoint&amp; point, const SimpleFontData* font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
+{
+#if ENABLE(LETTERPRESS)
+    if (!count)
+        return;
+
+    const FontPlatformData&amp; platformData = font-&gt;platformData();
+    if (platformData.orientation() == Vertical) {
+        // FIXME: Implement support for vertical text. See &lt;rdar://problem/13737298&gt;.
+        return;
+    }
+
+    CGContextSetTextPosition(context, point.x(), point.y());
+    Vector&lt;CGPoint, 256&gt; positions(count);
+    fillVectorWithHorizontalGlyphPositions(positions, context, advances, count);
+
+    CTFontRef ctFont = platformData.ctFont();
+    CGContextSetFontSize(context, CTFontGetSize(ctFont));
+
+    static CUICatalog *catalog = _UIKitGetTextEffectsCatalog();
+    if (!catalog)
+        return;
+
+    static CUIStyleEffectConfiguration *styleConfiguration;
+    if (!styleConfiguration) {
+        styleConfiguration = [allocCUIStyleEffectConfigurationInstance() init];
+        styleConfiguration.useSimplifiedEffect = YES;
+    }
+
+    [catalog drawGlyphs:glyphs atPositions:positions.data() inContext:context withFont:ctFont count:count stylePresetName:@&quot;_UIKitNewLetterpressStyle&quot; styleConfiguration:styleConfiguration foregroundColor:CGContextGetFillColorAsColor(context)];
+#else
+    UNUSED_PARAM(point);
+    UNUSED_PARAM(font);
+    UNUSED_PARAM(context);
+    UNUSED_PARAM(glyphs);
+    UNUSED_PARAM(advances);
+    UNUSED_PARAM(count);
+#endif
+}
+
+static void showGlyphsWithAdvances(const FloatPoint&amp; point, const SimpleFontData* font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
+{
+    if (!count)
+        return;
+
+    CGContextSetTextPosition(context, point.x(), point.y());
+
+    const FontPlatformData&amp; platformData = font-&gt;platformData();
+    Vector&lt;CGPoint, 256&gt; positions(count);
+    if (platformData.isColorBitmapFont())
+        fillVectorWithHorizontalGlyphPositions(positions, context, advances, count);
+    if (platformData.orientation() == Vertical) {
+        CGAffineTransform savedMatrix;
+        CGAffineTransform rotateLeftTransform = CGAffineTransformMake(0, -1, 1, 0, 0, 0);
+        savedMatrix = CGContextGetTextMatrix(context);
+        CGAffineTransform runMatrix = CGAffineTransformConcat(savedMatrix, rotateLeftTransform);
+        CGContextSetTextMatrix(context, runMatrix);
+
+        Vector&lt;CGSize, 256&gt; translations(count);
+        CTFontGetVerticalTranslationsForGlyphs(platformData.ctFont(), glyphs, translations.data(), count);
+
+        CGAffineTransform transform = CGAffineTransformInvert(CGContextGetTextMatrix(context));
+
+        CGPoint position = FloatPoint(point.x(), point.y() + font-&gt;fontMetrics().floatAscent(IdeographicBaseline) - font-&gt;fontMetrics().floatAscent());
+        for (size_t i = 0; i &lt; count; ++i) {
+            CGSize translation = CGSizeApplyAffineTransform(translations[i], rotateLeftTransform);
+            positions[i] = CGPointApplyAffineTransform(CGPointMake(position.x - translation.width, position.y + translation.height), transform);
+            position.x += advances[i].width;
+            position.y += advances[i].height;
+        }
+        if (!platformData.isColorBitmapFont())
+            CGContextShowGlyphsAtPositions(context, glyphs, positions.data(), count);
+        else
+            CTFontDrawGlyphs(platformData.ctFont(), glyphs, positions.data(), count, context);
+        CGContextSetTextMatrix(context, savedMatrix);
+    } else {
+        if (!platformData.isColorBitmapFont())
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored &quot;-Wdeprecated-declarations&quot;
+            CGContextShowGlyphsWithAdvances(context, glyphs, advances, count);
+#pragma clang diagnostic pop
+        else
+            CTFontDrawGlyphs(platformData.ctFont(), glyphs, positions.data(), count, context);
+    }
+}
+
+#if PLATFORM(MAC)
+static void setCGFontRenderingMode(CGContextRef cgContext, NSFontRenderingMode renderingMode, BOOL shouldSubpixelQuantize)
+{
+    if (renderingMode == NSFontIntegerAdvancementsRenderingMode) {
+        CGContextSetShouldAntialiasFonts(cgContext, false);
+        return;
+    }
+
+    CGContextSetShouldAntialiasFonts(cgContext, true);
+
+    CGAffineTransform contextTransform = CGContextGetCTM(cgContext);
+    BOOL isTranslationOrIntegralScale = WTF::isIntegral(contextTransform.a) &amp;&amp; WTF::isIntegral(contextTransform.d) &amp;&amp; contextTransform.b == 0.f &amp;&amp; contextTransform.c == 0.f;
+    BOOL isRotated = ((contextTransform.b || contextTransform.c) &amp;&amp; (contextTransform.a || contextTransform.d));
+    BOOL doSubpixelQuantization = isTranslationOrIntegralScale || (!isRotated &amp;&amp; shouldSubpixelQuantize);
+
+    CGContextSetShouldSubpixelPositionFonts(cgContext, renderingMode != NSFontAntialiasedIntegerAdvancementsRenderingMode || !isTranslationOrIntegralScale);
+    CGContextSetShouldSubpixelQuantizeFonts(cgContext, doSubpixelQuantization);
+}
+#endif
+
+void FontCascade::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer&amp; glyphBuffer, int from, int numGlyphs, const FloatPoint&amp; anchorPoint) const
+{
+    const FontPlatformData&amp; platformData = font-&gt;platformData();
+    if (!platformData.size())
+        return;
+
+    CGContextRef cgContext = context-&gt;platformContext();
+
+    bool shouldSmoothFonts;
+    bool changeFontSmoothing;
+    
+    switch(fontDescription().fontSmoothing()) {
+    case Antialiased: {
+        context-&gt;setShouldAntialias(true);
+        shouldSmoothFonts = false;
+        changeFontSmoothing = true;
+        break;
+    }
+    case SubpixelAntialiased: {
+        context-&gt;setShouldAntialias(true);
+        shouldSmoothFonts = true;
+        changeFontSmoothing = true;
+        break;
+    }
+    case NoSmoothing: {
+        context-&gt;setShouldAntialias(false);
+        shouldSmoothFonts = false;
+        changeFontSmoothing = true;
+        break;
+    }
+    case AutoSmoothing: {
+        shouldSmoothFonts = true;
+        changeFontSmoothing = false;
+        break;
+    }
+    }
+    
+    if (!shouldUseSmoothing()) {
+        shouldSmoothFonts = false;
+        changeFontSmoothing = true;
+    }
+
+#if !PLATFORM(IOS)
+    bool originalShouldUseFontSmoothing = false;
+    if (changeFontSmoothing) {
+        originalShouldUseFontSmoothing = CGContextGetShouldSmoothFonts(cgContext);
+        CGContextSetShouldSmoothFonts(cgContext, shouldSmoothFonts);
+    }
+#endif
+
+#if !PLATFORM(IOS)
+    NSFont* drawFont;
+    if (!isPrinterFont()) {
+        drawFont = [platformData.nsFont() screenFont];
+        if (drawFont != platformData.nsFont()) {
+            // We are getting this in too many places (3406411); use ERROR so it only prints on debug versions for now. (We should debug this also, eventually).
+            LOG_ERROR(&quot;Attempting to set non-screen font (%@) when drawing to screen.  Using screen font anyway, may result in incorrect metrics.&quot;,
+                [[[platformData.nsFont() fontDescriptor] fontAttributes] objectForKey:NSFontNameAttribute]);
+        }
+    } else {
+        drawFont = [platformData.nsFont() printerFont];
+        if (drawFont != platformData.nsFont()) {
+            NSLog(@&quot;Attempting to set non-printer font (%@) when printing.  Using printer font anyway, may result in incorrect metrics.&quot;,
+                [[[platformData.nsFont() fontDescriptor] fontAttributes] objectForKey:NSFontNameAttribute]);
+        }
+    }
+#endif
+    
+    CGContextSetFont(cgContext, platformData.cgFont());
+
+    bool useLetterpressEffect = shouldUseLetterpressEffect(*context);
+    FloatPoint point = anchorPoint;
+#if PLATFORM(IOS)
+    float fontSize = platformData.size();
+    CGAffineTransform matrix = useLetterpressEffect || platformData.isColorBitmapFont() ? CGAffineTransformIdentity : CGAffineTransformMakeScale(fontSize, fontSize);
+    if (platformData.m_isEmoji) {
+        if (!context-&gt;emojiDrawingEnabled())
+            return;
+
+        // Mimic the positioining of non-bitmap glyphs, which are not subpixel-positioned.
+        point.setY(ceilf(point.y()));
+
+        // Emoji glyphs snap to the CSS pixel grid.
+        point.setX(floorf(point.x()));
+
+        // Emoji glyphs are offset one CSS pixel to the right.
+        point.move(1, 0);
+
+        // Emoji glyphs are offset vertically based on font size.
+        float y = point.y();
+        if (fontSize &lt;= 15) {
+            // Undo Core Text's y adjustment.
+            static float yAdjustmentFactor = iosExecutableWasLinkedOnOrAfterVersion(wkIOSSystemVersion_6_0) ? .19 : .1;
+            point.setY(floorf(y - yAdjustmentFactor * (fontSize + 2) + 2));
+        } else {
+            if (fontSize &lt; 26)
+                y -= .35f * fontSize - 10;
+
+            // Undo Core Text's y adjustment.
+            static float yAdjustment = iosExecutableWasLinkedOnOrAfterVersion(wkIOSSystemVersion_6_0) ? 3.8 : 2;
+            point.setY(floorf(y - yAdjustment));
+        }
+    }
+#else
+    CGAffineTransform matrix = CGAffineTransformIdentity;
+    if (drawFont &amp;&amp; !platformData.isColorBitmapFont())
+        memcpy(&amp;matrix, [drawFont matrix], sizeof(matrix));
+#endif
+    matrix.b = -matrix.b;
+    matrix.d = -matrix.d;
+    if (platformData.m_syntheticOblique) {
+        static float obliqueSkew = tanf(SYNTHETIC_OBLIQUE_ANGLE * piFloat / 180);
+        if (platformData.orientation() == Vertical)
+            matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, obliqueSkew, 0, 1, 0, 0));
+        else
+            matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, -obliqueSkew, 1, 0, 0));
+    }
+    CGContextSetTextMatrix(cgContext, matrix);
+
+#if PLATFORM(IOS)
+    CGContextSetFontSize(cgContext, 1);
+    CGContextSetShouldSubpixelQuantizeFonts(cgContext, context-&gt;shouldSubpixelQuantizeFonts());
+#else
+    setCGFontRenderingMode(cgContext, [drawFont renderingMode], context-&gt;shouldSubpixelQuantizeFonts());
+    if (drawFont)
+        CGContextSetFontSize(cgContext, 1);
+    else
+        CGContextSetFontSize(cgContext, platformData.m_size);
+#endif
+
+
+    FloatSize shadowOffset;
+    float shadowBlur;
+    Color shadowColor;
+    ColorSpace shadowColorSpace;
+    ColorSpace fillColorSpace = context-&gt;fillColorSpace();
+    context-&gt;getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
+
+    AffineTransform contextCTM = context-&gt;getCTM();
+    float syntheticBoldOffset = font-&gt;syntheticBoldOffset();
+    if (syntheticBoldOffset &amp;&amp; !contextCTM.isIdentityOrTranslationOrFlipped()) {
+        FloatSize horizontalUnitSizeInDevicePixels = contextCTM.mapSize(FloatSize(1, 0));
+        float horizontalUnitLengthInDevicePixels = sqrtf(horizontalUnitSizeInDevicePixels.width() * horizontalUnitSizeInDevicePixels.width() + horizontalUnitSizeInDevicePixels.height() * horizontalUnitSizeInDevicePixels.height());
+        if (horizontalUnitLengthInDevicePixels)
+            syntheticBoldOffset /= horizontalUnitLengthInDevicePixels;
+    };
+
+    bool hasSimpleShadow = context-&gt;textDrawingMode() == TextModeFill &amp;&amp; shadowColor.isValid() &amp;&amp; !shadowBlur &amp;&amp; !platformData.isColorBitmapFont() &amp;&amp; (!context-&gt;shadowsIgnoreTransforms() || contextCTM.isIdentityOrTranslationOrFlipped()) &amp;&amp; !context-&gt;isInTransparencyLayer();
+    if (hasSimpleShadow) {
+        // Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing.
+        context-&gt;clearShadow();
+        Color fillColor = context-&gt;fillColor();
+        Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
+        context-&gt;setFillColor(shadowFillColor, shadowColorSpace);
+        float shadowTextX = point.x() + shadowOffset.width();
+        // If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
+        float shadowTextY = point.y() + shadowOffset.height() * (context-&gt;shadowsIgnoreTransforms() ? -1 : 1);
+        showGlyphsWithAdvances(FloatPoint(shadowTextX, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), static_cast&lt;const CGSize*&gt;(glyphBuffer.advances(from)), numGlyphs);
+#if !PLATFORM(IOS)
+        if (syntheticBoldOffset)
+#else
+        if (syntheticBoldOffset &amp;&amp; !platformData.m_isEmoji)
+#endif
+            showGlyphsWithAdvances(FloatPoint(shadowTextX + syntheticBoldOffset, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), static_cast&lt;const CGSize*&gt;(glyphBuffer.advances(from)), numGlyphs);
+        context-&gt;setFillColor(fillColor, fillColorSpace);
+    }
+
+    if (useLetterpressEffect)
+        showLetterpressedGlyphsWithAdvances(point, font, cgContext, glyphBuffer.glyphs(from), static_cast&lt;const CGSize*&gt;(glyphBuffer.advances(from)), numGlyphs);
+    else
+        showGlyphsWithAdvances(point, font, cgContext, glyphBuffer.glyphs(from), static_cast&lt;const CGSize*&gt;(glyphBuffer.advances(from)), numGlyphs);
+#if !PLATFORM(IOS)
+    if (syntheticBoldOffset)
+#else
+    if (syntheticBoldOffset &amp;&amp; !platformData.m_isEmoji)
+#endif
+        showGlyphsWithAdvances(FloatPoint(point.x() + syntheticBoldOffset, point.y()), font, cgContext, glyphBuffer.glyphs(from), static_cast&lt;const CGSize*&gt;(glyphBuffer.advances(from)), numGlyphs);
+
+    if (hasSimpleShadow)
+        context-&gt;setShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
+
+#if !PLATFORM(IOS)
+    if (changeFontSmoothing)
+        CGContextSetShouldSmoothFonts(cgContext, originalShouldUseFontSmoothing);
+#endif
+}
+
+#if ENABLE(CSS3_TEXT_DECORATION_SKIP_INK)
+struct GlyphIterationState {
+    GlyphIterationState(CGPoint startingPoint, CGPoint currentPoint, CGFloat y1, CGFloat y2, CGFloat minX, CGFloat maxX)
+        : startingPoint(startingPoint)
+        , currentPoint(currentPoint)
+        , y1(y1)
+        , y2(y2)
+        , minX(minX)
+        , maxX(maxX)
+    {
+    }
+    CGPoint startingPoint;
+    CGPoint currentPoint;
+    CGFloat y1;
+    CGFloat y2;
+    CGFloat minX;
+    CGFloat maxX;
+};
+
+static bool findIntersectionPoint(float y, CGPoint p1, CGPoint p2, CGFloat&amp; x)
+{
+    x = p1.x + (y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y);
+    return (p1.y &lt; y &amp;&amp; p2.y &gt; y) || (p1.y &gt; y &amp;&amp; p2.y &lt; y);
+}
+
+static void updateX(GlyphIterationState&amp; state, CGFloat x)
+{
+    state.minX = std::min(state.minX, x);
+    state.maxX = std::max(state.maxX, x);
+}
+
+// This function is called by CGPathApply and is therefore invoked for each
+// contour in a glyph. This function models each contours as a straight line
+// and calculates the intersections between each pseudo-contour and
+// two horizontal lines (the upper and lower bounds of an underline) found in
+// GlyphIterationState::y1 and GlyphIterationState::y2. It keeps track of the
+// leftmost and rightmost intersection in GlyphIterationState::minX and
+// GlyphIterationState::maxX.
+static void findPathIntersections(void* stateAsVoidPointer, const CGPathElement* e)
+{
+    auto&amp; state = *static_cast&lt;GlyphIterationState*&gt;(stateAsVoidPointer);
+    bool doIntersection = false;
+    CGPoint point = CGPointZero;
+    switch (e-&gt;type) {
+    case kCGPathElementMoveToPoint:
+        state.startingPoint = e-&gt;points[0];
+        state.currentPoint = e-&gt;points[0];
+        break;
+    case kCGPathElementAddLineToPoint:
+        doIntersection = true;
+        point = e-&gt;points[0];
+        break;
+    case kCGPathElementAddQuadCurveToPoint:
+        doIntersection = true;
+        point = e-&gt;points[1];
+        break;
+    case kCGPathElementAddCurveToPoint:
+        doIntersection = true;
+        point = e-&gt;points[2];
+        break;
+    case kCGPathElementCloseSubpath:
+        doIntersection = true;
+        point = state.startingPoint;
+        break;
+    }
+    if (!doIntersection)
+        return;
+    CGFloat x;
+    if (findIntersectionPoint(state.y1, state.currentPoint, point, x))
+        updateX(state, x);
+    if (findIntersectionPoint(state.y2, state.currentPoint, point, x))
+        updateX(state, x);
+    if ((state.currentPoint.y &gt;= state.y1 &amp;&amp; state.currentPoint.y &lt;= state.y2)
+        || (state.currentPoint.y &lt;= state.y1 &amp;&amp; state.currentPoint.y &gt;= state.y2))
+        updateX(state, state.currentPoint.x);
+    state.currentPoint = point;
+}
+
+class MacGlyphToPathTranslator final : public GlyphToPathTranslator {
+public:
+    MacGlyphToPathTranslator(const TextRun&amp; textRun, const GlyphBuffer&amp; glyphBuffer, const FloatPoint&amp; textOrigin)
+        : m_index(0)
+        , m_textRun(textRun)
+        , m_glyphBuffer(glyphBuffer)
+        , m_fontData(glyphBuffer.fontDataAt(m_index))
+        , m_translation(CGAffineTransformScale(CGAffineTransformMakeTranslation(textOrigin.x(), textOrigin.y()), 1, -1))
+    {
+        moveToNextValidGlyph();
+    }
+private:
+    virtual bool containsMorePaths() override
+    {
+        return m_index != m_glyphBuffer.size();
+    }
+    virtual Path path() override;
+    virtual std::pair&lt;float, float&gt; extents() override;
+    virtual GlyphUnderlineType underlineType() override;
+    virtual void advance() override;
+    void moveToNextValidGlyph();
+
+    int m_index;
+    const TextRun&amp; m_textRun;
+    const GlyphBuffer&amp; m_glyphBuffer;
+    const SimpleFontData* m_fontData;
+    CGAffineTransform m_translation;
+};
+
+Path MacGlyphToPathTranslator::path()
+{
+    RetainPtr&lt;CGPathRef&gt; result = adoptCF(CTFontCreatePathForGlyph(m_fontData-&gt;platformData().ctFont(), m_glyphBuffer.glyphAt(m_index), &amp;m_translation));
+    return adoptCF(CGPathCreateMutableCopy(result.get()));
+}
+
+std::pair&lt;float, float&gt; MacGlyphToPathTranslator::extents()
+{
+    CGPoint beginning = CGPointApplyAffineTransform(CGPointMake(0, 0), m_translation);
+    CGSize end = CGSizeApplyAffineTransform(m_glyphBuffer.advanceAt(m_index), m_translation);
+    return std::make_pair(static_cast&lt;float&gt;(beginning.x), static_cast&lt;float&gt;(beginning.x + end.width));
+}
+
+auto MacGlyphToPathTranslator::underlineType() -&gt; GlyphUnderlineType
+{
+    return computeUnderlineType(m_textRun, m_glyphBuffer, m_index);
+}
+
+void MacGlyphToPathTranslator::moveToNextValidGlyph()
+{
+    if (!m_fontData-&gt;isSVGFont())
+        return;
+    advance();
+}
+
+void MacGlyphToPathTranslator::advance()
+{
+    do {
+        GlyphBufferAdvance advance = m_glyphBuffer.advanceAt(m_index);
+        m_translation = CGAffineTransformTranslate(m_translation, advance.width(), advance.height());
+        ++m_index;
+        if (m_index &gt;= m_glyphBuffer.size())
+            break;
+        m_fontData = m_glyphBuffer.fontDataAt(m_index);
+    } while (m_fontData-&gt;isSVGFont() &amp;&amp; m_index &lt; m_glyphBuffer.size());
+}
+
+DashArray FontCascade::dashesForIntersectionsWithRect(const TextRun&amp; run, const FloatPoint&amp; textOrigin, const FloatRect&amp; lineExtents) const
+{
+    if (isLoadingCustomFonts())
+        return DashArray();
+
+    GlyphBuffer glyphBuffer;
+    glyphBuffer.saveOffsetsInString();
+    float deltaX;
+    if (codePath(run) != FontCascade::Complex)
+        deltaX = getGlyphsAndAdvancesForSimpleText(run, 0, run.length(), glyphBuffer);
+    else
+        deltaX = getGlyphsAndAdvancesForComplexText(run, 0, run.length(), glyphBuffer);
+
+    if (!glyphBuffer.size())
+        return DashArray();
+    
+    // FIXME: Handle SVG + non-SVG interleaved runs. https://bugs.webkit.org/show_bug.cgi?id=133778
+    const SimpleFontData* fontData = glyphBuffer.fontDataAt(0);
+    std::unique_ptr&lt;GlyphToPathTranslator&gt; translator;
+    bool isSVG = false;
+    FloatPoint origin = FloatPoint(textOrigin.x() + deltaX, textOrigin.y());
+    if (!fontData-&gt;isSVGFont())
+        translator = std::make_unique&lt;MacGlyphToPathTranslator&gt;(run, glyphBuffer, origin);
+    else {
+        TextRun::RenderingContext* renderingContext = run.renderingContext();
+        if (!renderingContext)
+            return DashArray();
+        translator = renderingContext-&gt;createGlyphToPathTranslator(*fontData, &amp;run, glyphBuffer, 0, glyphBuffer.size(), origin);
+        isSVG = true;
+    }
+    DashArray result;
+    for (int index = 0; translator-&gt;containsMorePaths(); ++index, translator-&gt;advance()) {
+        GlyphIterationState info = GlyphIterationState(CGPointMake(0, 0), CGPointMake(0, 0), lineExtents.y(), lineExtents.y() + lineExtents.height(), lineExtents.x() + lineExtents.width(), lineExtents.x());
+        const SimpleFontData* localFontData = glyphBuffer.fontDataAt(index);
+        if (!localFontData || (!isSVG &amp;&amp; localFontData-&gt;isSVGFont()) || (isSVG &amp;&amp; localFontData != fontData)) {
+            // The advances will get all messed up if we do anything other than bail here.
+            result.clear();
+            break;
+        }
+        switch (translator-&gt;underlineType()) {
+        case GlyphToPathTranslator::GlyphUnderlineType::SkipDescenders: {
+            Path path = translator-&gt;path();
+            CGPathApply(path.platformPath(), &amp;info, &amp;findPathIntersections);
+            if (info.minX &lt; info.maxX) {
+                result.append(info.minX - lineExtents.x());
+                result.append(info.maxX - lineExtents.x());
+            }
+            break;
+        }
+        case GlyphToPathTranslator::GlyphUnderlineType::SkipGlyph: {
+            std::pair&lt;float, float&gt; extents = translator-&gt;extents();
+            result.append(extents.first - lineExtents.x());
+            result.append(extents.second - lineExtents.x());
+            break;
+        }
+        case GlyphToPathTranslator::GlyphUnderlineType::DrawOverGlyph:
+            // Nothing to do
+            break;
+        }
+    }
+    return result;
+}
+#endif
+
+bool FontCascade::primaryFontDataIsSystemFont() const
+{
+#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED &gt; 1090
+    const auto&amp; fontData = primaryFontData();
+    return !fontData.isSVGFont() &amp;&amp; CTFontDescriptorIsSystemUIFont(adoptCF(CTFontCopyFontDescriptor(fontData.platformData().ctFont())).get());
+#else
+    // System fonts are hidden by having a name that begins with a period, so simply search
+    // for that here rather than try to keep the list up to date.
+    return firstFamily().startsWith('.');
+#endif
+}
+
+}
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacFontCoreTextcppfromrev178496trunkSourceWebCoreplatformgraphicsmacSimpleFontDataCoreTextcpp"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/mac/FontCoreText.cpp (from rev 178496, trunk/Source/WebCore/platform/graphics/mac/SimpleFontDataCoreText.cpp) (0 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/FontCoreText.cpp                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/mac/FontCoreText.cpp        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -0,0 +1,70 @@
</span><ins>+/*
+ * Copyright (C) 2005, 2006, 2012 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov
+ *
+ * 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 INC. AND ITS CONTRIBUTORS ``AS IS''
+ * 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 INC. 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.
+ */
+
+#include &quot;config.h&quot;
+#include &quot;SimpleFontData.h&quot;
+
+#if !PLATFORM(IOS)
+#include &lt;ApplicationServices/ApplicationServices.h&gt;
+#else
+#include &lt;CoreText/CoreText.h&gt;
+#endif
+
+namespace WebCore {
+
+CFDictionaryRef SimpleFontData::getCFStringAttributes(TypesettingFeatures typesettingFeatures, FontOrientation orientation) const
+{
+    unsigned key = typesettingFeatures + 1;
+    HashMap&lt;unsigned, RetainPtr&lt;CFDictionaryRef&gt;&gt;::AddResult addResult = m_CFStringAttributes.add(key, RetainPtr&lt;CFDictionaryRef&gt;());
+    RetainPtr&lt;CFDictionaryRef&gt;&amp; attributesDictionary = addResult.iterator-&gt;value;
+    if (!addResult.isNewEntry)
+        return attributesDictionary.get();
+
+    attributesDictionary = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 4, &amp;kCFCopyStringDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
+    CFMutableDictionaryRef mutableAttributes = (CFMutableDictionaryRef)attributesDictionary.get();
+
+    CFDictionarySetValue(mutableAttributes, kCTFontAttributeName, platformData().ctFont());
+
+    if (!(typesettingFeatures &amp; Kerning)) {
+        const float zero = 0;
+        static CFNumberRef zeroKerningValue = CFNumberCreate(kCFAllocatorDefault, kCFNumberFloatType, &amp;zero);
+        CFDictionarySetValue(mutableAttributes, kCTKernAttributeName, zeroKerningValue);
+    }
+
+    bool allowLigatures = (orientation == Horizontal &amp;&amp; platformData().allowsLigatures()) || (typesettingFeatures &amp; Ligatures);
+    if (!allowLigatures) {
+        const int zero = 0;
+        static CFNumberRef essentialLigaturesValue = CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &amp;zero);
+        CFDictionarySetValue(mutableAttributes, kCTLigatureAttributeName, essentialLigaturesValue);
+    }
+
+    if (orientation == Vertical)
+        CFDictionarySetValue(mutableAttributes, kCTVerticalFormsAttributeName, kCFBooleanTrue);
+
+    return attributesDictionary.get();
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacFontMacmm"></a>
<div class="delfile"><h4>Deleted: trunk/Source/WebCore/platform/graphics/mac/FontMac.mm (178517 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/FontMac.mm        2015-01-15 19:20:03 UTC (rev 178517)
+++ trunk/Source/WebCore/platform/graphics/mac/FontMac.mm        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -1,605 +0,0 @@
</span><del>-/*
- * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
- *           (C) 1999 Antti Koivisto (koivisto@kde.org)
- *           (C) 2000 Dirk Mueller (mueller@kde.org)
- * Copyright (C) 2003, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public License
- * along with this library; see the file COPYING.LIB.  If not, write to
- * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
- * Boston, MA 02110-1301, USA.
- */
-
-#import &quot;config.h&quot;
-#import &quot;FontCascade.h&quot;
-
-#import &quot;CoreGraphicsSPI.h&quot;
-#import &quot;CoreTextSPI.h&quot;
-#import &quot;DashArray.h&quot;
-#import &quot;GlyphBuffer.h&quot;
-#import &quot;GraphicsContext.h&quot;
-#import &quot;Logging.h&quot;
-#import &quot;SimpleFontData.h&quot;
-#import &quot;WebCoreSystemInterface.h&quot;
-#if USE(APPKIT)
-#import &lt;AppKit/AppKit.h&gt;
-#endif
-#import &lt;wtf/MathExtras.h&gt;
-
-#if ENABLE(LETTERPRESS)
-#import &quot;CoreUISPI.h&quot;
-#import &quot;SoftLinking.h&quot;
-
-SOFT_LINK_PRIVATE_FRAMEWORK(CoreUI)
-SOFT_LINK_CLASS(CoreUI, CUICatalog)
-SOFT_LINK_CLASS(CoreUI, CUIStyleEffectConfiguration)
-
-SOFT_LINK_FRAMEWORK(UIKit)
-SOFT_LINK(UIKit, _UIKitGetTextEffectsCatalog, CUICatalog *, (void), ())
-#endif
-
-#define SYNTHETIC_OBLIQUE_ANGLE 14
-
-#ifdef __LP64__
-#define URefCon void*
-#else
-#define URefCon UInt32
-#endif
-
-namespace WebCore {
-
-bool FontCascade::canReturnFallbackFontsForComplexText()
-{
-    return true;
-}
-
-bool FontCascade::canExpandAroundIdeographsInComplexText()
-{
-    return true;
-}
-
-static inline void fillVectorWithHorizontalGlyphPositions(Vector&lt;CGPoint, 256&gt;&amp; positions, CGContextRef context, const CGSize* advances, size_t count)
-{
-    CGAffineTransform matrix = CGAffineTransformInvert(CGContextGetTextMatrix(context));
-    positions[0] = CGPointZero;
-    for (size_t i = 1; i &lt; count; ++i) {
-        CGSize advance = CGSizeApplyAffineTransform(advances[i - 1], matrix);
-        positions[i].x = positions[i - 1].x + advance.width;
-        positions[i].y = positions[i - 1].y + advance.height;
-    }
-}
-
-static inline bool shouldUseLetterpressEffect(const GraphicsContext&amp; context)
-{
-#if ENABLE(LETTERPRESS)
-    return context.textDrawingMode() &amp; TextModeLetterpress;
-#else
-    UNUSED_PARAM(context);
-    return false;
-#endif
-}
-
-static void showLetterpressedGlyphsWithAdvances(const FloatPoint&amp; point, const SimpleFontData* font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
-{
-#if ENABLE(LETTERPRESS)
-    if (!count)
-        return;
-
-    const FontPlatformData&amp; platformData = font-&gt;platformData();
-    if (platformData.orientation() == Vertical) {
-        // FIXME: Implement support for vertical text. See &lt;rdar://problem/13737298&gt;.
-        return;
-    }
-
-    CGContextSetTextPosition(context, point.x(), point.y());
-    Vector&lt;CGPoint, 256&gt; positions(count);
-    fillVectorWithHorizontalGlyphPositions(positions, context, advances, count);
-
-    CTFontRef ctFont = platformData.ctFont();
-    CGContextSetFontSize(context, CTFontGetSize(ctFont));
-
-    static CUICatalog *catalog = _UIKitGetTextEffectsCatalog();
-    if (!catalog)
-        return;
-
-    static CUIStyleEffectConfiguration *styleConfiguration;
-    if (!styleConfiguration) {
-        styleConfiguration = [allocCUIStyleEffectConfigurationInstance() init];
-        styleConfiguration.useSimplifiedEffect = YES;
-    }
-
-    [catalog drawGlyphs:glyphs atPositions:positions.data() inContext:context withFont:ctFont count:count stylePresetName:@&quot;_UIKitNewLetterpressStyle&quot; styleConfiguration:styleConfiguration foregroundColor:CGContextGetFillColorAsColor(context)];
-#else
-    UNUSED_PARAM(point);
-    UNUSED_PARAM(font);
-    UNUSED_PARAM(context);
-    UNUSED_PARAM(glyphs);
-    UNUSED_PARAM(advances);
-    UNUSED_PARAM(count);
-#endif
-}
-
-static void showGlyphsWithAdvances(const FloatPoint&amp; point, const SimpleFontData* font, CGContextRef context, const CGGlyph* glyphs, const CGSize* advances, size_t count)
-{
-    if (!count)
-        return;
-
-    CGContextSetTextPosition(context, point.x(), point.y());
-
-    const FontPlatformData&amp; platformData = font-&gt;platformData();
-    Vector&lt;CGPoint, 256&gt; positions(count);
-    if (platformData.isColorBitmapFont())
-        fillVectorWithHorizontalGlyphPositions(positions, context, advances, count);
-    if (platformData.orientation() == Vertical) {
-        CGAffineTransform savedMatrix;
-        CGAffineTransform rotateLeftTransform = CGAffineTransformMake(0, -1, 1, 0, 0, 0);
-        savedMatrix = CGContextGetTextMatrix(context);
-        CGAffineTransform runMatrix = CGAffineTransformConcat(savedMatrix, rotateLeftTransform);
-        CGContextSetTextMatrix(context, runMatrix);
-
-        Vector&lt;CGSize, 256&gt; translations(count);
-        CTFontGetVerticalTranslationsForGlyphs(platformData.ctFont(), glyphs, translations.data(), count);
-
-        CGAffineTransform transform = CGAffineTransformInvert(CGContextGetTextMatrix(context));
-
-        CGPoint position = FloatPoint(point.x(), point.y() + font-&gt;fontMetrics().floatAscent(IdeographicBaseline) - font-&gt;fontMetrics().floatAscent());
-        for (size_t i = 0; i &lt; count; ++i) {
-            CGSize translation = CGSizeApplyAffineTransform(translations[i], rotateLeftTransform);
-            positions[i] = CGPointApplyAffineTransform(CGPointMake(position.x - translation.width, position.y + translation.height), transform);
-            position.x += advances[i].width;
-            position.y += advances[i].height;
-        }
-        if (!platformData.isColorBitmapFont())
-            CGContextShowGlyphsAtPositions(context, glyphs, positions.data(), count);
-        else
-            CTFontDrawGlyphs(platformData.ctFont(), glyphs, positions.data(), count, context);
-        CGContextSetTextMatrix(context, savedMatrix);
-    } else {
-        if (!platformData.isColorBitmapFont())
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored &quot;-Wdeprecated-declarations&quot;
-            CGContextShowGlyphsWithAdvances(context, glyphs, advances, count);
-#pragma clang diagnostic pop
-        else
-            CTFontDrawGlyphs(platformData.ctFont(), glyphs, positions.data(), count, context);
-    }
-}
-
-#if PLATFORM(MAC)
-static void setCGFontRenderingMode(CGContextRef cgContext, NSFontRenderingMode renderingMode, BOOL shouldSubpixelQuantize)
-{
-    if (renderingMode == NSFontIntegerAdvancementsRenderingMode) {
-        CGContextSetShouldAntialiasFonts(cgContext, false);
-        return;
-    }
-
-    CGContextSetShouldAntialiasFonts(cgContext, true);
-
-    CGAffineTransform contextTransform = CGContextGetCTM(cgContext);
-    BOOL isTranslationOrIntegralScale = WTF::isIntegral(contextTransform.a) &amp;&amp; WTF::isIntegral(contextTransform.d) &amp;&amp; contextTransform.b == 0.f &amp;&amp; contextTransform.c == 0.f;
-    BOOL isRotated = ((contextTransform.b || contextTransform.c) &amp;&amp; (contextTransform.a || contextTransform.d));
-    BOOL doSubpixelQuantization = isTranslationOrIntegralScale || (!isRotated &amp;&amp; shouldSubpixelQuantize);
-
-    CGContextSetShouldSubpixelPositionFonts(cgContext, renderingMode != NSFontAntialiasedIntegerAdvancementsRenderingMode || !isTranslationOrIntegralScale);
-    CGContextSetShouldSubpixelQuantizeFonts(cgContext, doSubpixelQuantization);
-}
-#endif
-
-void FontCascade::drawGlyphs(GraphicsContext* context, const SimpleFontData* font, const GlyphBuffer&amp; glyphBuffer, int from, int numGlyphs, const FloatPoint&amp; anchorPoint) const
-{
-    const FontPlatformData&amp; platformData = font-&gt;platformData();
-    if (!platformData.size())
-        return;
-
-    CGContextRef cgContext = context-&gt;platformContext();
-
-    bool shouldSmoothFonts;
-    bool changeFontSmoothing;
-    
-    switch(fontDescription().fontSmoothing()) {
-    case Antialiased: {
-        context-&gt;setShouldAntialias(true);
-        shouldSmoothFonts = false;
-        changeFontSmoothing = true;
-        break;
-    }
-    case SubpixelAntialiased: {
-        context-&gt;setShouldAntialias(true);
-        shouldSmoothFonts = true;
-        changeFontSmoothing = true;
-        break;
-    }
-    case NoSmoothing: {
-        context-&gt;setShouldAntialias(false);
-        shouldSmoothFonts = false;
-        changeFontSmoothing = true;
-        break;
-    }
-    case AutoSmoothing: {
-        shouldSmoothFonts = true;
-        changeFontSmoothing = false;
-        break;
-    }
-    }
-    
-    if (!shouldUseSmoothing()) {
-        shouldSmoothFonts = false;
-        changeFontSmoothing = true;
-    }
-
-#if !PLATFORM(IOS)
-    bool originalShouldUseFontSmoothing = false;
-    if (changeFontSmoothing) {
-        originalShouldUseFontSmoothing = CGContextGetShouldSmoothFonts(cgContext);
-        CGContextSetShouldSmoothFonts(cgContext, shouldSmoothFonts);
-    }
-#endif
-
-#if !PLATFORM(IOS)
-    NSFont* drawFont;
-    if (!isPrinterFont()) {
-        drawFont = [platformData.nsFont() screenFont];
-        if (drawFont != platformData.nsFont()) {
-            // We are getting this in too many places (3406411); use ERROR so it only prints on debug versions for now. (We should debug this also, eventually).
-            LOG_ERROR(&quot;Attempting to set non-screen font (%@) when drawing to screen.  Using screen font anyway, may result in incorrect metrics.&quot;,
-                [[[platformData.nsFont() fontDescriptor] fontAttributes] objectForKey:NSFontNameAttribute]);
-        }
-    } else {
-        drawFont = [platformData.nsFont() printerFont];
-        if (drawFont != platformData.nsFont()) {
-            NSLog(@&quot;Attempting to set non-printer font (%@) when printing.  Using printer font anyway, may result in incorrect metrics.&quot;,
-                [[[platformData.nsFont() fontDescriptor] fontAttributes] objectForKey:NSFontNameAttribute]);
-        }
-    }
-#endif
-    
-    CGContextSetFont(cgContext, platformData.cgFont());
-
-    bool useLetterpressEffect = shouldUseLetterpressEffect(*context);
-    FloatPoint point = anchorPoint;
-#if PLATFORM(IOS)
-    float fontSize = platformData.size();
-    CGAffineTransform matrix = useLetterpressEffect || platformData.isColorBitmapFont() ? CGAffineTransformIdentity : CGAffineTransformMakeScale(fontSize, fontSize);
-    if (platformData.m_isEmoji) {
-        if (!context-&gt;emojiDrawingEnabled())
-            return;
-
-        // Mimic the positioining of non-bitmap glyphs, which are not subpixel-positioned.
-        point.setY(ceilf(point.y()));
-
-        // Emoji glyphs snap to the CSS pixel grid.
-        point.setX(floorf(point.x()));
-
-        // Emoji glyphs are offset one CSS pixel to the right.
-        point.move(1, 0);
-
-        // Emoji glyphs are offset vertically based on font size.
-        float y = point.y();
-        if (fontSize &lt;= 15) {
-            // Undo Core Text's y adjustment.
-            static float yAdjustmentFactor = iosExecutableWasLinkedOnOrAfterVersion(wkIOSSystemVersion_6_0) ? .19 : .1;
-            point.setY(floorf(y - yAdjustmentFactor * (fontSize + 2) + 2));
-        } else {
-            if (fontSize &lt; 26)
-                y -= .35f * fontSize - 10;
-
-            // Undo Core Text's y adjustment.
-            static float yAdjustment = iosExecutableWasLinkedOnOrAfterVersion(wkIOSSystemVersion_6_0) ? 3.8 : 2;
-            point.setY(floorf(y - yAdjustment));
-        }
-    }
-#else
-    CGAffineTransform matrix = CGAffineTransformIdentity;
-    if (drawFont &amp;&amp; !platformData.isColorBitmapFont())
-        memcpy(&amp;matrix, [drawFont matrix], sizeof(matrix));
-#endif
-    matrix.b = -matrix.b;
-    matrix.d = -matrix.d;
-    if (platformData.m_syntheticOblique) {
-        static float obliqueSkew = tanf(SYNTHETIC_OBLIQUE_ANGLE * piFloat / 180);
-        if (platformData.orientation() == Vertical)
-            matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, obliqueSkew, 0, 1, 0, 0));
-        else
-            matrix = CGAffineTransformConcat(matrix, CGAffineTransformMake(1, 0, -obliqueSkew, 1, 0, 0));
-    }
-    CGContextSetTextMatrix(cgContext, matrix);
-
-#if PLATFORM(IOS)
-    CGContextSetFontSize(cgContext, 1);
-    CGContextSetShouldSubpixelQuantizeFonts(cgContext, context-&gt;shouldSubpixelQuantizeFonts());
-#else
-    setCGFontRenderingMode(cgContext, [drawFont renderingMode], context-&gt;shouldSubpixelQuantizeFonts());
-    if (drawFont)
-        CGContextSetFontSize(cgContext, 1);
-    else
-        CGContextSetFontSize(cgContext, platformData.m_size);
-#endif
-
-
-    FloatSize shadowOffset;
-    float shadowBlur;
-    Color shadowColor;
-    ColorSpace shadowColorSpace;
-    ColorSpace fillColorSpace = context-&gt;fillColorSpace();
-    context-&gt;getShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
-
-    AffineTransform contextCTM = context-&gt;getCTM();
-    float syntheticBoldOffset = font-&gt;syntheticBoldOffset();
-    if (syntheticBoldOffset &amp;&amp; !contextCTM.isIdentityOrTranslationOrFlipped()) {
-        FloatSize horizontalUnitSizeInDevicePixels = contextCTM.mapSize(FloatSize(1, 0));
-        float horizontalUnitLengthInDevicePixels = sqrtf(horizontalUnitSizeInDevicePixels.width() * horizontalUnitSizeInDevicePixels.width() + horizontalUnitSizeInDevicePixels.height() * horizontalUnitSizeInDevicePixels.height());
-        if (horizontalUnitLengthInDevicePixels)
-            syntheticBoldOffset /= horizontalUnitLengthInDevicePixels;
-    };
-
-    bool hasSimpleShadow = context-&gt;textDrawingMode() == TextModeFill &amp;&amp; shadowColor.isValid() &amp;&amp; !shadowBlur &amp;&amp; !platformData.isColorBitmapFont() &amp;&amp; (!context-&gt;shadowsIgnoreTransforms() || contextCTM.isIdentityOrTranslationOrFlipped()) &amp;&amp; !context-&gt;isInTransparencyLayer();
-    if (hasSimpleShadow) {
-        // Paint simple shadows ourselves instead of relying on CG shadows, to avoid losing subpixel antialiasing.
-        context-&gt;clearShadow();
-        Color fillColor = context-&gt;fillColor();
-        Color shadowFillColor(shadowColor.red(), shadowColor.green(), shadowColor.blue(), shadowColor.alpha() * fillColor.alpha() / 255);
-        context-&gt;setFillColor(shadowFillColor, shadowColorSpace);
-        float shadowTextX = point.x() + shadowOffset.width();
-        // If shadows are ignoring transforms, then we haven't applied the Y coordinate flip yet, so down is negative.
-        float shadowTextY = point.y() + shadowOffset.height() * (context-&gt;shadowsIgnoreTransforms() ? -1 : 1);
-        showGlyphsWithAdvances(FloatPoint(shadowTextX, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), static_cast&lt;const CGSize*&gt;(glyphBuffer.advances(from)), numGlyphs);
-#if !PLATFORM(IOS)
-        if (syntheticBoldOffset)
-#else
-        if (syntheticBoldOffset &amp;&amp; !platformData.m_isEmoji)
-#endif
-            showGlyphsWithAdvances(FloatPoint(shadowTextX + syntheticBoldOffset, shadowTextY), font, cgContext, glyphBuffer.glyphs(from), static_cast&lt;const CGSize*&gt;(glyphBuffer.advances(from)), numGlyphs);
-        context-&gt;setFillColor(fillColor, fillColorSpace);
-    }
-
-    if (useLetterpressEffect)
-        showLetterpressedGlyphsWithAdvances(point, font, cgContext, glyphBuffer.glyphs(from), static_cast&lt;const CGSize*&gt;(glyphBuffer.advances(from)), numGlyphs);
-    else
-        showGlyphsWithAdvances(point, font, cgContext, glyphBuffer.glyphs(from), static_cast&lt;const CGSize*&gt;(glyphBuffer.advances(from)), numGlyphs);
-#if !PLATFORM(IOS)
-    if (syntheticBoldOffset)
-#else
-    if (syntheticBoldOffset &amp;&amp; !platformData.m_isEmoji)
-#endif
-        showGlyphsWithAdvances(FloatPoint(point.x() + syntheticBoldOffset, point.y()), font, cgContext, glyphBuffer.glyphs(from), static_cast&lt;const CGSize*&gt;(glyphBuffer.advances(from)), numGlyphs);
-
-    if (hasSimpleShadow)
-        context-&gt;setShadow(shadowOffset, shadowBlur, shadowColor, shadowColorSpace);
-
-#if !PLATFORM(IOS)
-    if (changeFontSmoothing)
-        CGContextSetShouldSmoothFonts(cgContext, originalShouldUseFontSmoothing);
-#endif
-}
-
-#if ENABLE(CSS3_TEXT_DECORATION_SKIP_INK)
-struct GlyphIterationState {
-    GlyphIterationState(CGPoint startingPoint, CGPoint currentPoint, CGFloat y1, CGFloat y2, CGFloat minX, CGFloat maxX)
-        : startingPoint(startingPoint)
-        , currentPoint(currentPoint)
-        , y1(y1)
-        , y2(y2)
-        , minX(minX)
-        , maxX(maxX)
-    {
-    }
-    CGPoint startingPoint;
-    CGPoint currentPoint;
-    CGFloat y1;
-    CGFloat y2;
-    CGFloat minX;
-    CGFloat maxX;
-};
-
-static bool findIntersectionPoint(float y, CGPoint p1, CGPoint p2, CGFloat&amp; x)
-{
-    x = p1.x + (y - p1.y) * (p2.x - p1.x) / (p2.y - p1.y);
-    return (p1.y &lt; y &amp;&amp; p2.y &gt; y) || (p1.y &gt; y &amp;&amp; p2.y &lt; y);
-}
-
-static void updateX(GlyphIterationState&amp; state, CGFloat x)
-{
-    state.minX = std::min(state.minX, x);
-    state.maxX = std::max(state.maxX, x);
-}
-
-// This function is called by CGPathApply and is therefore invoked for each
-// contour in a glyph. This function models each contours as a straight line
-// and calculates the intersections between each pseudo-contour and
-// two horizontal lines (the upper and lower bounds of an underline) found in
-// GlyphIterationState::y1 and GlyphIterationState::y2. It keeps track of the
-// leftmost and rightmost intersection in GlyphIterationState::minX and
-// GlyphIterationState::maxX.
-static void findPathIntersections(void* stateAsVoidPointer, const CGPathElement* e)
-{
-    auto&amp; state = *static_cast&lt;GlyphIterationState*&gt;(stateAsVoidPointer);
-    bool doIntersection = false;
-    CGPoint point = CGPointZero;
-    switch (e-&gt;type) {
-    case kCGPathElementMoveToPoint:
-        state.startingPoint = e-&gt;points[0];
-        state.currentPoint = e-&gt;points[0];
-        break;
-    case kCGPathElementAddLineToPoint:
-        doIntersection = true;
-        point = e-&gt;points[0];
-        break;
-    case kCGPathElementAddQuadCurveToPoint:
-        doIntersection = true;
-        point = e-&gt;points[1];
-        break;
-    case kCGPathElementAddCurveToPoint:
-        doIntersection = true;
-        point = e-&gt;points[2];
-        break;
-    case kCGPathElementCloseSubpath:
-        doIntersection = true;
-        point = state.startingPoint;
-        break;
-    }
-    if (!doIntersection)
-        return;
-    CGFloat x;
-    if (findIntersectionPoint(state.y1, state.currentPoint, point, x))
-        updateX(state, x);
-    if (findIntersectionPoint(state.y2, state.currentPoint, point, x))
-        updateX(state, x);
-    if ((state.currentPoint.y &gt;= state.y1 &amp;&amp; state.currentPoint.y &lt;= state.y2)
-        || (state.currentPoint.y &lt;= state.y1 &amp;&amp; state.currentPoint.y &gt;= state.y2))
-        updateX(state, state.currentPoint.x);
-    state.currentPoint = point;
-}
-
-class MacGlyphToPathTranslator final : public GlyphToPathTranslator {
-public:
-    MacGlyphToPathTranslator(const TextRun&amp; textRun, const GlyphBuffer&amp; glyphBuffer, const FloatPoint&amp; textOrigin)
-        : m_index(0)
-        , m_textRun(textRun)
-        , m_glyphBuffer(glyphBuffer)
-        , m_fontData(glyphBuffer.fontDataAt(m_index))
-        , m_translation(CGAffineTransformScale(CGAffineTransformMakeTranslation(textOrigin.x(), textOrigin.y()), 1, -1))
-    {
-        moveToNextValidGlyph();
-    }
-private:
-    virtual bool containsMorePaths() override
-    {
-        return m_index != m_glyphBuffer.size();
-    }
-    virtual Path path() override;
-    virtual std::pair&lt;float, float&gt; extents() override;
-    virtual GlyphUnderlineType underlineType() override;
-    virtual void advance() override;
-    void moveToNextValidGlyph();
-
-    int m_index;
-    const TextRun&amp; m_textRun;
-    const GlyphBuffer&amp; m_glyphBuffer;
-    const SimpleFontData* m_fontData;
-    CGAffineTransform m_translation;
-};
-
-Path MacGlyphToPathTranslator::path()
-{
-    RetainPtr&lt;CGPathRef&gt; result = adoptCF(CTFontCreatePathForGlyph(m_fontData-&gt;platformData().ctFont(), m_glyphBuffer.glyphAt(m_index), &amp;m_translation));
-    return adoptCF(CGPathCreateMutableCopy(result.get()));
-}
-
-std::pair&lt;float, float&gt; MacGlyphToPathTranslator::extents()
-{
-    CGPoint beginning = CGPointApplyAffineTransform(CGPointMake(0, 0), m_translation);
-    CGSize end = CGSizeApplyAffineTransform(m_glyphBuffer.advanceAt(m_index), m_translation);
-    return std::make_pair(static_cast&lt;float&gt;(beginning.x), static_cast&lt;float&gt;(beginning.x + end.width));
-}
-
-auto MacGlyphToPathTranslator::underlineType() -&gt; GlyphUnderlineType
-{
-    return computeUnderlineType(m_textRun, m_glyphBuffer, m_index);
-}
-
-void MacGlyphToPathTranslator::moveToNextValidGlyph()
-{
-    if (!m_fontData-&gt;isSVGFont())
-        return;
-    advance();
-}
-
-void MacGlyphToPathTranslator::advance()
-{
-    do {
-        GlyphBufferAdvance advance = m_glyphBuffer.advanceAt(m_index);
-        m_translation = CGAffineTransformTranslate(m_translation, advance.width(), advance.height());
-        ++m_index;
-        if (m_index &gt;= m_glyphBuffer.size())
-            break;
-        m_fontData = m_glyphBuffer.fontDataAt(m_index);
-    } while (m_fontData-&gt;isSVGFont() &amp;&amp; m_index &lt; m_glyphBuffer.size());
-}
-
-DashArray FontCascade::dashesForIntersectionsWithRect(const TextRun&amp; run, const FloatPoint&amp; textOrigin, const FloatRect&amp; lineExtents) const
-{
-    if (isLoadingCustomFonts())
-        return DashArray();
-
-    GlyphBuffer glyphBuffer;
-    glyphBuffer.saveOffsetsInString();
-    float deltaX;
-    if (codePath(run) != FontCascade::Complex)
-        deltaX = getGlyphsAndAdvancesForSimpleText(run, 0, run.length(), glyphBuffer);
-    else
-        deltaX = getGlyphsAndAdvancesForComplexText(run, 0, run.length(), glyphBuffer);
-
-    if (!glyphBuffer.size())
-        return DashArray();
-    
-    // FIXME: Handle SVG + non-SVG interleaved runs. https://bugs.webkit.org/show_bug.cgi?id=133778
-    const SimpleFontData* fontData = glyphBuffer.fontDataAt(0);
-    std::unique_ptr&lt;GlyphToPathTranslator&gt; translator;
-    bool isSVG = false;
-    FloatPoint origin = FloatPoint(textOrigin.x() + deltaX, textOrigin.y());
-    if (!fontData-&gt;isSVGFont())
-        translator = std::make_unique&lt;MacGlyphToPathTranslator&gt;(run, glyphBuffer, origin);
-    else {
-        TextRun::RenderingContext* renderingContext = run.renderingContext();
-        if (!renderingContext)
-            return DashArray();
-        translator = renderingContext-&gt;createGlyphToPathTranslator(*fontData, &amp;run, glyphBuffer, 0, glyphBuffer.size(), origin);
-        isSVG = true;
-    }
-    DashArray result;
-    for (int index = 0; translator-&gt;containsMorePaths(); ++index, translator-&gt;advance()) {
-        GlyphIterationState info = GlyphIterationState(CGPointMake(0, 0), CGPointMake(0, 0), lineExtents.y(), lineExtents.y() + lineExtents.height(), lineExtents.x() + lineExtents.width(), lineExtents.x());
-        const SimpleFontData* localFontData = glyphBuffer.fontDataAt(index);
-        if (!localFontData || (!isSVG &amp;&amp; localFontData-&gt;isSVGFont()) || (isSVG &amp;&amp; localFontData != fontData)) {
-            // The advances will get all messed up if we do anything other than bail here.
-            result.clear();
-            break;
-        }
-        switch (translator-&gt;underlineType()) {
-        case GlyphToPathTranslator::GlyphUnderlineType::SkipDescenders: {
-            Path path = translator-&gt;path();
-            CGPathApply(path.platformPath(), &amp;info, &amp;findPathIntersections);
-            if (info.minX &lt; info.maxX) {
-                result.append(info.minX - lineExtents.x());
-                result.append(info.maxX - lineExtents.x());
-            }
-            break;
-        }
-        case GlyphToPathTranslator::GlyphUnderlineType::SkipGlyph: {
-            std::pair&lt;float, float&gt; extents = translator-&gt;extents();
-            result.append(extents.first - lineExtents.x());
-            result.append(extents.second - lineExtents.x());
-            break;
-        }
-        case GlyphToPathTranslator::GlyphUnderlineType::DrawOverGlyph:
-            // Nothing to do
-            break;
-        }
-    }
-    return result;
-}
-#endif
-
-bool FontCascade::primaryFontDataIsSystemFont() const
-{
-#if PLATFORM(IOS) || __MAC_OS_X_VERSION_MIN_REQUIRED &gt; 1090
-    const auto&amp; fontData = primaryFontData();
-    return !fontData.isSVGFont() &amp;&amp; CTFontDescriptorIsSystemUIFont(adoptCF(CTFontCopyFontDescriptor(fontData.platformData().ctFont())).get());
-#else
-    // System fonts are hidden by having a name that begins with a period, so simply search
-    // for that here rather than try to keep the list up to date.
-    return firstFamily().startsWith('.');
-#endif
-}
-
-}
</del></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacFontMacmmfromrev178510trunkSourceWebCoreplatformgraphicsmacSimpleFontDataMacmm"></a>
<div class="copfile"><h4>Copied: trunk/Source/WebCore/platform/graphics/mac/FontMac.mm (from rev 178510, trunk/Source/WebCore/platform/graphics/mac/SimpleFontDataMac.mm) (0 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/FontMac.mm                                (rev 0)
+++ trunk/Source/WebCore/platform/graphics/mac/FontMac.mm        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -0,0 +1,474 @@
</span><ins>+/*
+ * Copyright (C) 2005, 2006, 2010, 2011 Apple Inc. All rights reserved.
+ * Copyright (C) 2006 Alexey Proskuryakov
+ *
+ * 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 INC. AND ITS CONTRIBUTORS ``AS IS''
+ * 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 INC. 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.
+ */
+
+#import &quot;config.h&quot;
+#import &quot;SimpleFontData.h&quot;
+
+#import &quot;BlockExceptions.h&quot;
+#import &quot;Color.h&quot;
+#import &quot;CoreGraphicsSPI.h&quot;
+#import &quot;CoreTextSPI.h&quot;
+#import &quot;FloatRect.h&quot;
+#import &quot;FontCache.h&quot;
+#import &quot;FontCascade.h&quot;
+#import &quot;FontDescription.h&quot;
+#import &quot;SharedBuffer.h&quot;
+#import &quot;WebCoreSystemInterface.h&quot;
+#if USE(APPKIT)
+#import &lt;AppKit/AppKit.h&gt;
+#import &lt;ApplicationServices/ApplicationServices.h&gt;
+#else
+#import &lt;CoreText/CoreText.h&gt;
+#endif
+#import &lt;float.h&gt;
+#import &lt;unicode/uchar.h&gt;
+#import &lt;wtf/Assertions.h&gt;
+#import &lt;wtf/StdLibExtras.h&gt;
+#import &lt;wtf/RetainPtr.h&gt;
+
+#if !PLATFORM(IOS)
+@interface NSFont (WebAppKitSecretAPI)
+- (BOOL)_isFakeFixedPitch;
+@end
+#endif
+
+namespace WebCore {
+
+#if USE(APPKIT)
+static bool fontHasVerticalGlyphs(CTFontRef ctFont)
+{
+    // The check doesn't look neat but this is what AppKit does for vertical writing...
+    RetainPtr&lt;CFArrayRef&gt; tableTags = adoptCF(CTFontCopyAvailableTables(ctFont, kCTFontTableOptionNoOptions));
+    CFIndex numTables = CFArrayGetCount(tableTags.get());
+    for (CFIndex index = 0; index &lt; numTables; ++index) {
+        CTFontTableTag tag = (CTFontTableTag)(uintptr_t)CFArrayGetValueAtIndex(tableTags.get(), index);
+        if (tag == kCTFontTableVhea || tag == kCTFontTableVORG)
+            return true;
+    }
+    return false;
+}
+
+static bool initFontData(SimpleFontData* fontData)
+{
+    if (!fontData-&gt;platformData().cgFont())
+        return false;
+
+    return true;
+}
+
+static NSString *webFallbackFontFamily(void)
+{
+    static NSString *webFallbackFontFamily = [[[NSFont systemFontOfSize:16.0f] familyName] retain];
+    return webFallbackFontFamily;
+}
+
+const SimpleFontData* SimpleFontData::compositeFontReferenceFontData(NSFont *key) const
+{
+    if (!key || CFEqual(adoptCF(CTFontCopyPostScriptName(CTFontRef(key))).get(), CFSTR(&quot;LastResort&quot;)))
+        return nullptr;
+
+    if (!m_derivedFontData)
+        m_derivedFontData = std::make_unique&lt;DerivedFontData&gt;(isCustomFont());
+
+    auto addResult = m_derivedFontData-&gt;compositeFontReferences.add(key, nullptr);
+    if (addResult.isNewEntry) {
+        bool isUsingPrinterFont = platformData().isPrinterFont();
+        NSFont *substituteFont = isUsingPrinterFont ? [key printerFont] : [key screenFont];
+
+        CTFontSymbolicTraits traits = CTFontGetSymbolicTraits((CTFontRef)substituteFont);
+        bool syntheticBold = platformData().syntheticBold() &amp;&amp; !(traits &amp; kCTFontBoldTrait);
+        bool syntheticOblique = platformData().syntheticOblique() &amp;&amp; !(traits &amp; kCTFontItalicTrait);
+
+        FontPlatformData substitutePlatform(substituteFont, platformData().size(), isUsingPrinterFont, syntheticBold, syntheticOblique, platformData().orientation(), platformData().widthVariant());
+        addResult.iterator-&gt;value = SimpleFontData::create(substitutePlatform, isCustomFont());
+    }
+    return addResult.iterator-&gt;value.get();
+}
+
+void SimpleFontData::platformInit()
+{
+    m_syntheticBoldOffset = m_platformData.m_syntheticBold ? 1.0f : 0.f;
+
+    bool failedSetup = false;
+    if (!initFontData(this)) {
+        // Ack! Something very bad happened, like a corrupt font.
+        // Try looking for an alternate 'base' font for this renderer.
+
+        // Special case hack to use &quot;Times New Roman&quot; in place of &quot;Times&quot;.
+        // &quot;Times RO&quot; is a common font whose family name is &quot;Times&quot;.
+        // It overrides the normal &quot;Times&quot; family font.
+        // It also appears to have a corrupt regular variant.
+        NSString *fallbackFontFamily;
+        if ([[m_platformData.nsFont() familyName] isEqual:@&quot;Times&quot;])
+            fallbackFontFamily = @&quot;Times New Roman&quot;;
+        else
+            fallbackFontFamily = webFallbackFontFamily();
+        
+        // Try setting up the alternate font.
+        // This is a last ditch effort to use a substitute font when something has gone wrong.
+#if !ERROR_DISABLED
+        RetainPtr&lt;NSFont&gt; initialFont = m_platformData.nsFont();
+#endif
+        if (m_platformData.font())
+            m_platformData.setNSFont([[NSFontManager sharedFontManager] convertFont:m_platformData.nsFont() toFamily:fallbackFontFamily]);
+        else
+            m_platformData.setNSFont([NSFont fontWithName:fallbackFontFamily size:m_platformData.size()]);
+        if (!initFontData(this)) {
+            if ([fallbackFontFamily isEqual:@&quot;Times New Roman&quot;]) {
+                // OK, couldn't setup Times New Roman as an alternate to Times, fallback
+                // on the system font.  If this fails we have no alternative left.
+                m_platformData.setNSFont([[NSFontManager sharedFontManager] convertFont:m_platformData.nsFont() toFamily:webFallbackFontFamily()]);
+                if (!initFontData(this)) {
+                    // We tried, Times, Times New Roman, and the system font. No joy. We have to give up.
+                    LOG_ERROR(&quot;unable to initialize with font %@&quot;, initialFont.get());
+                    failedSetup = true;
+                }
+            } else {
+                // We tried the requested font and the system font. No joy. We have to give up.
+                LOG_ERROR(&quot;unable to initialize with font %@&quot;, initialFont.get());
+                failedSetup = true;
+            }
+        }
+
+        // Report the problem.
+        LOG_ERROR(&quot;Corrupt font detected, using %@ in place of %@.&quot;,
+            [m_platformData.nsFont() familyName], [initialFont.get() familyName]);
+    }
+
+    // If all else fails, try to set up using the system font.
+    // This is probably because Times and Times New Roman are both unavailable.
+    if (failedSetup) {
+        m_platformData.setNSFont([NSFont systemFontOfSize:[m_platformData.nsFont() pointSize]]);
+        LOG_ERROR(&quot;failed to set up font, using system font %s&quot;, m_platformData.font());
+        initFontData(this);
+    }
+    
+    int iAscent;
+    int iDescent;
+    int iCapHeight;
+    int iLineGap;
+    unsigned unitsPerEm;
+    iAscent = CGFontGetAscent(m_platformData.cgFont());
+    // Some fonts erroneously specify a positive descender value. We follow Core Text in assuming that
+    // such fonts meant the same distance, but in the reverse direction.
+    iDescent = -abs(CGFontGetDescent(m_platformData.cgFont()));
+    iCapHeight = CGFontGetCapHeight(m_platformData.cgFont());
+    iLineGap = CGFontGetLeading(m_platformData.cgFont());
+    unitsPerEm = CGFontGetUnitsPerEm(m_platformData.cgFont());
+
+    float pointSize = m_platformData.m_size;
+    float ascent = scaleEmToUnits(iAscent, unitsPerEm) * pointSize;
+    float descent = -scaleEmToUnits(iDescent, unitsPerEm) * pointSize;
+    float capHeight = scaleEmToUnits(iCapHeight, unitsPerEm) * pointSize;
+    
+    float lineGap = scaleEmToUnits(iLineGap, unitsPerEm) * pointSize;
+
+    // We need to adjust Times, Helvetica, and Courier to closely match the
+    // vertical metrics of their Microsoft counterparts that are the de facto
+    // web standard. The AppKit adjustment of 20% is too big and is
+    // incorrectly added to line spacing, so we use a 15% adjustment instead
+    // and add it to the ascent.
+    NSString *familyName = [m_platformData.nsFont() familyName];
+    if ([familyName isEqualToString:@&quot;Times&quot;] || [familyName isEqualToString:@&quot;Helvetica&quot;] || [familyName isEqualToString:@&quot;Courier&quot;])
+        ascent += floorf(((ascent + descent) * 0.15f) + 0.5f);
+
+    // Compute and store line spacing, before the line metrics hacks are applied.
+    m_fontMetrics.setLineSpacing(lroundf(ascent) + lroundf(descent) + lroundf(lineGap));
+
+    // Hack Hiragino line metrics to allow room for marked text underlines.
+    // &lt;rdar://problem/5386183&gt;
+    if (descent &lt; 3 &amp;&amp; lineGap &gt;= 3 &amp;&amp; [familyName hasPrefix:@&quot;Hiragino&quot;]) {
+        lineGap -= 3 - descent;
+        descent = 3;
+    }
+    
+    if (platformData().orientation() == Vertical &amp;&amp; !isTextOrientationFallback())
+        m_hasVerticalGlyphs = fontHasVerticalGlyphs(m_platformData.ctFont());
+
+    float xHeight;
+
+    if (platformData().orientation() == Horizontal) {
+        // Measure the actual character &quot;x&quot;, since it's possible for it to extend below the baseline, and we need the
+        // reported x-height to only include the portion of the glyph that is above the baseline.
+        NSGlyph xGlyph = glyphForCharacter('x');
+        if (xGlyph)
+            xHeight = -CGRectGetMinY(platformBoundsForGlyph(xGlyph));
+        else
+            xHeight = scaleEmToUnits(CGFontGetXHeight(m_platformData.cgFont()), unitsPerEm) * pointSize;
+    } else
+        xHeight = verticalRightOrientationFontData()-&gt;fontMetrics().xHeight();
+
+    m_fontMetrics.setUnitsPerEm(unitsPerEm);
+    m_fontMetrics.setAscent(ascent);
+    m_fontMetrics.setDescent(descent);
+    m_fontMetrics.setCapHeight(capHeight);
+    m_fontMetrics.setLineGap(lineGap);
+    m_fontMetrics.setXHeight(xHeight);
+}
+
+static CFDataRef copyFontTableForTag(FontPlatformData&amp; platformData, FourCharCode tableName)
+{
+    return CGFontCopyTableForTag(platformData.cgFont(), tableName);
+}
+
+void SimpleFontData::platformCharWidthInit()
+{
+    m_avgCharWidth = 0;
+    m_maxCharWidth = 0;
+    
+    RetainPtr&lt;CFDataRef&gt; os2Table = adoptCF(copyFontTableForTag(m_platformData, 'OS/2'));
+    if (os2Table &amp;&amp; CFDataGetLength(os2Table.get()) &gt;= 4) {
+        const UInt8* os2 = CFDataGetBytePtr(os2Table.get());
+        SInt16 os2AvgCharWidth = os2[2] * 256 + os2[3];
+        m_avgCharWidth = scaleEmToUnits(os2AvgCharWidth, m_fontMetrics.unitsPerEm()) * m_platformData.m_size;
+    }
+
+    RetainPtr&lt;CFDataRef&gt; headTable = adoptCF(copyFontTableForTag(m_platformData, 'head'));
+    if (headTable &amp;&amp; CFDataGetLength(headTable.get()) &gt;= 42) {
+        const UInt8* head = CFDataGetBytePtr(headTable.get());
+        ushort uxMin = head[36] * 256 + head[37];
+        ushort uxMax = head[40] * 256 + head[41];
+        SInt16 xMin = static_cast&lt;SInt16&gt;(uxMin);
+        SInt16 xMax = static_cast&lt;SInt16&gt;(uxMax);
+        float diff = static_cast&lt;float&gt;(xMax - xMin);
+        m_maxCharWidth = scaleEmToUnits(diff, m_fontMetrics.unitsPerEm()) * m_platformData.m_size;
+    }
+
+    // Fallback to a cross-platform estimate, which will populate these values if they are non-positive.
+    initCharWidths();
+}
+#endif // USE(APPKIT)
+
+void SimpleFontData::platformDestroy()
+{
+}
+
+#if !PLATFORM(IOS)
+PassRefPtr&lt;SimpleFontData&gt; SimpleFontData::platformCreateScaledFontData(const FontDescription&amp; fontDescription, float scaleFactor) const
+{
+    if (isCustomFont()) {
+        FontPlatformData scaledFontData(m_platformData);
+        scaledFontData.m_size = scaledFontData.m_size * scaleFactor;
+        return SimpleFontData::create(scaledFontData, true, false);
+    }
+
+    BEGIN_BLOCK_OBJC_EXCEPTIONS;
+    float size = m_platformData.size() * scaleFactor;
+    FontPlatformData scaledFontData([[NSFontManager sharedFontManager] convertFont:m_platformData.nsFont() toSize:size], size, m_platformData.isPrinterFont(), false, false, m_platformData.orientation());
+
+    // AppKit resets the type information (screen/printer) when you convert a font to a different size.
+    // We have to fix up the font that we're handed back.
+    scaledFontData.setNSFont(fontDescription.usePrinterFont() ? [scaledFontData.nsFont() printerFont] : [scaledFontData.nsFont() screenFont]);
+
+    if (scaledFontData.font()) {
+        NSFontManager *fontManager = [NSFontManager sharedFontManager];
+        NSFontTraitMask fontTraits = [fontManager traitsOfFont:m_platformData.nsFont()];
+
+        if (m_platformData.m_syntheticBold)
+            fontTraits |= NSBoldFontMask;
+        if (m_platformData.m_syntheticOblique)
+            fontTraits |= NSItalicFontMask;
+
+        NSFontTraitMask scaledFontTraits = [fontManager traitsOfFont:scaledFontData.nsFont()];
+        scaledFontData.m_syntheticBold = (fontTraits &amp; NSBoldFontMask) &amp;&amp; !(scaledFontTraits &amp; NSBoldFontMask);
+        scaledFontData.m_syntheticOblique = (fontTraits &amp; NSItalicFontMask) &amp;&amp; !(scaledFontTraits &amp; NSItalicFontMask);
+
+        return fontCache().fontForPlatformData(scaledFontData);
+    }
+    END_BLOCK_OBJC_EXCEPTIONS;
+
+    return 0;
+}
+
+void SimpleFontData::determinePitch()
+{
+    NSFont* f = m_platformData.nsFont();
+    // Special case Osaka-Mono.
+    // According to &lt;rdar://problem/3999467&gt;, we should treat Osaka-Mono as fixed pitch.
+    // Note that the AppKit does not report Osaka-Mono as fixed pitch.
+
+    // Special case MS-PGothic.
+    // According to &lt;rdar://problem/4032938&gt;, we should not treat MS-PGothic as fixed pitch.
+    // Note that AppKit does report MS-PGothic as fixed pitch.
+
+    // Special case MonotypeCorsiva
+    // According to &lt;rdar://problem/5454704&gt;, we should not treat MonotypeCorsiva as fixed pitch.
+    // Note that AppKit does report MonotypeCorsiva as fixed pitch.
+
+    NSString *name = [f fontName];
+    m_treatAsFixedPitch = ([f isFixedPitch] || [f _isFakeFixedPitch] ||
+           [name caseInsensitiveCompare:@&quot;Osaka-Mono&quot;] == NSOrderedSame) &amp;&amp;
+           [name caseInsensitiveCompare:@&quot;MS-PGothic&quot;] != NSOrderedSame &amp;&amp;
+           [name caseInsensitiveCompare:@&quot;MonotypeCorsiva&quot;] != NSOrderedSame;
+}
+#endif // !PLATFORM(IOS)
+
+FloatRect SimpleFontData::platformBoundsForGlyph(Glyph glyph) const
+{
+    FloatRect boundingBox;
+    boundingBox = CTFontGetBoundingRectsForGlyphs(m_platformData.ctFont(), platformData().orientation() == Vertical ? kCTFontVerticalOrientation : kCTFontHorizontalOrientation, &amp;glyph, 0, 1);
+    boundingBox.setY(-boundingBox.maxY());
+    if (m_syntheticBoldOffset)
+        boundingBox.setWidth(boundingBox.width() + m_syntheticBoldOffset);
+
+    return boundingBox;
+}
+
+#if PLATFORM(MAC)
+inline CGFontRenderingStyle SimpleFontData::renderingStyle() const
+{
+    CGFontRenderingStyle style = kCGFontRenderingStyleAntialiasing | kCGFontRenderingStyleSubpixelPositioning | kCGFontRenderingStyleSubpixelQuantization;
+    NSFont *font = platformData().nsFont();
+    if (font) {
+        switch ([font renderingMode]) {
+        case NSFontIntegerAdvancementsRenderingMode:
+            style = 0;
+            break;
+        case NSFontAntialiasedIntegerAdvancementsRenderingMode:
+            style = kCGFontRenderingStyleAntialiasing;
+            break;
+        default:
+            break;
+        }
+    }
+    return style;
+}
+
+inline bool SimpleFontData::advanceForColorBitmapFont(Glyph glyph, CGSize&amp; advance) const
+{
+    NSFont *font = platformData().nsFont();
+    if (!font || !platformData().isColorBitmapFont())
+        return false;
+    advance = NSSizeToCGSize([font advancementForGlyph:glyph]);
+    return true;
+}
+#endif
+
+static bool hasCustomTracking(CTFontRef font)
+{
+#if PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &lt; 1090
+    UNUSED_PARAM(font);
+    return false;
+#else
+    return CTFontDescriptorIsSystemUIFont(adoptCF(CTFontCopyFontDescriptor(font)).get());
+#endif
+}
+
+static inline bool isEmoji(const FontPlatformData&amp; platformData)
+{
+#if PLATFORM(IOS)
+    return platformData.m_isEmoji;
+#else
+    UNUSED_PARAM(platformData);
+    return false;
+#endif
+}
+
+inline bool SimpleFontData::canUseFastGlyphAdvanceGetter(Glyph glyph, CGSize&amp; advance, bool&amp; populatedAdvance) const
+{
+    // Fast getter doesn't take custom tracking into account
+    if (hasCustomTracking(platformData().ctFont()))
+        return false;
+    // Fast getter doesn't work for emoji
+    if (isEmoji(platformData()))
+        return false;
+    // ... or for any bitmap fonts in general
+    if (advanceForColorBitmapFont(glyph, advance)) {
+        populatedAdvance = true;
+        return false;
+    }
+    return true;
+}
+
+float SimpleFontData::platformWidthForGlyph(Glyph glyph) const
+{
+    CGSize advance = CGSizeZero;
+    bool horizontal = platformData().orientation() == Horizontal;
+    bool populatedAdvance = false;
+    if ((horizontal || m_isBrokenIdeographFallback) &amp;&amp; canUseFastGlyphAdvanceGetter(glyph, advance, populatedAdvance)) {
+        float pointSize = platformData().m_size;
+        CGAffineTransform m = CGAffineTransformMakeScale(pointSize, pointSize);
+        if (!CGFontGetGlyphAdvancesForStyle(platformData().cgFont(), &amp;m, renderingStyle(), &amp;glyph, 1, &amp;advance)) {
+            RetainPtr&lt;CFStringRef&gt; fullName = adoptCF(CGFontCopyFullName(platformData().cgFont()));
+            LOG_ERROR(&quot;Unable to cache glyph widths for %@ %f&quot;, fullName.get(), pointSize);
+            advance.width = 0;
+        }
+    } else if (!populatedAdvance)
+        CTFontGetAdvancesForGlyphs(m_platformData.ctFont(), horizontal ? kCTFontHorizontalOrientation : kCTFontVerticalOrientation, &amp;glyph, &amp;advance, 1);
+
+    return advance.width + m_syntheticBoldOffset;
+}
+
+struct ProviderInfo {
+    const UChar* characters;
+    size_t length;
+    CFDictionaryRef attributes;
+};
+
+static const UniChar* provideStringAndAttributes(CFIndex stringIndex, CFIndex* count, CFDictionaryRef* attributes, void* context)
+{
+    ProviderInfo* info = static_cast&lt;struct ProviderInfo*&gt;(context);
+    if (stringIndex &lt; 0 || static_cast&lt;size_t&gt;(stringIndex) &gt;= info-&gt;length)
+        return 0;
+
+    *count = info-&gt;length - stringIndex;
+    *attributes = info-&gt;attributes;
+    return info-&gt;characters + stringIndex;
+}
+
+bool SimpleFontData::canRenderCombiningCharacterSequence(const UChar* characters, size_t length) const
+{
+    ASSERT(isMainThread());
+
+    if (!m_combiningCharacterSequenceSupport)
+        m_combiningCharacterSequenceSupport = std::make_unique&lt;HashMap&lt;String, bool&gt;&gt;();
+
+    WTF::HashMap&lt;String, bool&gt;::AddResult addResult = m_combiningCharacterSequenceSupport-&gt;add(String(characters, length), false);
+    if (!addResult.isNewEntry)
+        return addResult.iterator-&gt;value;
+
+    RetainPtr&lt;CFTypeRef&gt; fontEqualityObject = platformData().objectForEqualityCheck();
+
+    ProviderInfo info = { characters, length, getCFStringAttributes(0, platformData().orientation()) };
+    RetainPtr&lt;CTLineRef&gt; line = adoptCF(CTLineCreateWithUniCharProvider(&amp;provideStringAndAttributes, 0, &amp;info));
+
+    CFArrayRef runArray = CTLineGetGlyphRuns(line.get());
+    CFIndex runCount = CFArrayGetCount(runArray);
+
+    for (CFIndex r = 0; r &lt; runCount; r++) {
+        CTRunRef ctRun = static_cast&lt;CTRunRef&gt;(CFArrayGetValueAtIndex(runArray, r));
+        ASSERT(CFGetTypeID(ctRun) == CTRunGetTypeID());
+        CFDictionaryRef runAttributes = CTRunGetAttributes(ctRun);
+        CTFontRef runFont = static_cast&lt;CTFontRef&gt;(CFDictionaryGetValue(runAttributes, kCTFontAttributeName));
+        if (!CFEqual(fontEqualityObject.get(), FontPlatformData::objectForEqualityCheck(runFont).get()))
+            return false;
+    }
+
+    addResult.iterator-&gt;value = true;
+    return true;
+}
+
+} // namespace WebCore
</ins></span></pre></div>
<a id="trunkSourceWebCoreplatformwinDragImageWincpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/win/DragImageWin.cpp (178517 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/win/DragImageWin.cpp        2015-01-15 19:20:03 UTC (rev 178517)
+++ trunk/Source/WebCore/platform/win/DragImageWin.cpp        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -27,7 +27,7 @@
</span><span class="cx"> #include &quot;DragImage.h&quot;
</span><span class="cx"> 
</span><span class="cx"> #include &quot;FloatRoundedRect.h&quot;
</span><del>-#include &quot;Font.h&quot;
</del><ins>+#include &quot;FontCascade.h&quot;
</ins><span class="cx"> #include &quot;FontDescription.h&quot;
</span><span class="cx"> #include &quot;FontSelector.h&quot;
</span><span class="cx"> #include &quot;GraphicsContext.h&quot;
</span><span class="lines">@@ -101,9 +101,9 @@
</span><span class="cx"> const float DragLinkLabelFontsize = 11;
</span><span class="cx"> const float DragLinkUrlFontSize = 10;
</span><span class="cx"> 
</span><del>-static Font dragLabelFont(int size, bool bold, FontRenderingMode renderingMode)
</del><ins>+static FontCascade dragLabelFont(int size, bool bold, FontRenderingMode renderingMode)
</ins><span class="cx"> {
</span><del>-    Font result;
</del><ins>+    FontCascade result;
</ins><span class="cx">     NONCLIENTMETRICS metrics;
</span><span class="cx">     metrics.cbSize = sizeof(metrics);
</span><span class="cx">     SystemParametersInfo(SPI_GETNONCLIENTMETRICS, metrics.cbSize, &amp;metrics, 0);
</span><span class="lines">@@ -114,7 +114,7 @@
</span><span class="cx">     description.setSpecifiedSize((float)size);
</span><span class="cx">     description.setComputedSize((float)size);
</span><span class="cx">     description.setRenderingMode(renderingMode);
</span><del>-    result = Font(description, 0, 0);
</del><ins>+    result = FontCascade(description, 0, 0);
</ins><span class="cx">     result.update(0);
</span><span class="cx">     return result;
</span><span class="cx"> }
</span><span class="lines">@@ -123,8 +123,8 @@
</span><span class="cx"> {
</span><span class="cx">     // This is more or less an exact match for the Mac OS X code.
</span><span class="cx"> 
</span><del>-    const Font* labelFont;
-    const Font* urlFont;
</del><ins>+    const FontCascade* labelFont;
+    const FontCascade* urlFont;
</ins><span class="cx"> 
</span><span class="cx">     if (fontRenderingMode == AlternateRenderingMode) {
</span><span class="cx">         static const Font alternateRenderingModeLabelFont = dragLabelFont(DragLinkLabelFontsize, true, AlternateRenderingMode);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformwinPopupMenuWincpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/win/PopupMenuWin.cpp (178517 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/win/PopupMenuWin.cpp        2015-01-15 19:20:03 UTC (rev 178517)
+++ trunk/Source/WebCore/platform/win/PopupMenuWin.cpp        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -335,11 +335,11 @@
</span><span class="cx">         if (text.isEmpty())
</span><span class="cx">             continue;
</span><span class="cx"> 
</span><del>-        Font itemFont = client()-&gt;menuStyle().font();
</del><ins>+        FontCascade itemFont = client()-&gt;menuStyle().font();
</ins><span class="cx">         if (client()-&gt;itemIsLabel(i)) {
</span><span class="cx">             FontDescription d = itemFont.fontDescription();
</span><span class="cx">             d.setWeight(d.bolderWeight());
</span><del>-            itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing());
</del><ins>+            itemFont = FontCascade(d, itemFont.letterSpacing(), itemFont.wordSpacing());
</ins><span class="cx">             itemFont.update(m_popupClient-&gt;fontSelector());
</span><span class="cx">         }
</span><span class="cx"> 
</span><span class="lines">@@ -641,11 +641,11 @@
</span><span class="cx">         TextRun textRun(itemText, 0, 0, TextRun::AllowTrailingExpansion, itemStyle.textDirection(), itemStyle.hasTextDirectionOverride());
</span><span class="cx">         context.setFillColor(optionTextColor, ColorSpaceDeviceRGB);
</span><span class="cx">         
</span><del>-        Font itemFont = client()-&gt;menuStyle().font();
</del><ins>+        FontCascade itemFont = client()-&gt;menuStyle().font();
</ins><span class="cx">         if (client()-&gt;itemIsLabel(index)) {
</span><span class="cx">             FontDescription d = itemFont.fontDescription();
</span><span class="cx">             d.setWeight(d.bolderWeight());
</span><del>-            itemFont = Font(d, itemFont.letterSpacing(), itemFont.wordSpacing());
</del><ins>+            itemFont = FontCascade(d, itemFont.letterSpacing(), itemFont.wordSpacing());
</ins><span class="cx">             itemFont.update(m_popupClient-&gt;fontSelector());
</span><span class="cx">         }
</span><span class="cx">         
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformwinWebCoreTextRenderercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/win/WebCoreTextRenderer.cpp (178517 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/win/WebCoreTextRenderer.cpp        2015-01-15 19:20:03 UTC (rev 178517)
+++ trunk/Source/WebCore/platform/win/WebCoreTextRenderer.cpp        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -25,7 +25,7 @@
</span><span class="cx"> #include &quot;config.h&quot;
</span><span class="cx"> #include &quot;WebCoreTextRenderer.h&quot;
</span><span class="cx"> 
</span><del>-#include &quot;Font.h&quot;
</del><ins>+#include &quot;FontCascade.h&quot;
</ins><span class="cx"> #include &quot;FontDescription.h&quot;
</span><span class="cx"> #include &quot;GraphicsContext.h&quot;
</span><span class="cx"> #include &quot;StringTruncator.h&quot;
</span><span class="lines">@@ -45,7 +45,7 @@
</span><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-static void doDrawTextAtPoint(GraphicsContext&amp; context, const String&amp; text, const IntPoint&amp; point, const Font&amp; font, const Color&amp; color, int underlinedIndex)
</del><ins>+static void doDrawTextAtPoint(GraphicsContext&amp; context, const String&amp; text, const IntPoint&amp; point, const FontCascade&amp; font, const Color&amp; color, int underlinedIndex)
</ins><span class="cx"> {
</span><span class="cx">     TextRun run(text);
</span><span class="cx"> 
</span><span class="lines">@@ -76,7 +76,7 @@
</span><span class="cx">     }
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-void WebCoreDrawDoubledTextAtPoint(GraphicsContext&amp; context, const String&amp; text, const IntPoint&amp; point, const Font&amp; font, const Color&amp; topColor, const Color&amp; bottomColor, int underlinedIndex)
</del><ins>+void WebCoreDrawDoubledTextAtPoint(GraphicsContext&amp; context, const String&amp; text, const IntPoint&amp; point, const FontCascade&amp; font, const Color&amp; topColor, const Color&amp; bottomColor, int underlinedIndex)
</ins><span class="cx"> {
</span><span class="cx">     context.save();
</span><span class="cx"> 
</span><span class="lines">@@ -89,7 +89,7 @@
</span><span class="cx">     context.restore();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-float WebCoreTextFloatWidth(const String&amp; text, const Font&amp; font)
</del><ins>+float WebCoreTextFloatWidth(const String&amp; text, const FontCascade&amp; font)
</ins><span class="cx"> {
</span><span class="cx">     return StringTruncator::width(text, font, StringTruncator::EnableRoundingHacks);
</span><span class="cx"> }
</span><span class="lines">@@ -106,12 +106,12 @@
</span><span class="cx"> 
</span><span class="cx"> void WebCoreSetAlwaysUsesComplexTextCodePath(bool complex)
</span><span class="cx"> {
</span><del>-    Font::setCodePath(complex ? Font::Complex : Font::Auto);
</del><ins>+    Font::setCodePath(complex ? FontCascade::Complex : FontCascade::Auto);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> bool WebCoreAlwaysUsesComplexTextCodePath()
</span><span class="cx"> {
</span><del>-    return Font::codePath() == Font::Complex;
</del><ins>+    return Font::codePath() == FontCascade::Complex;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> } // namespace WebCore
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeSafaricpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderThemeSafari.cpp (178517 => 178518)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderThemeSafari.cpp        2015-01-15 19:20:03 UTC (rev 178517)
+++ trunk/Source/WebCore/rendering/RenderThemeSafari.cpp        2015-01-15 19:29:05 UTC (rev 178518)
</span><span class="lines">@@ -401,7 +401,7 @@
</span><span class="cx">     style.setLineHeight(RenderStyle::initialLineHeight());
</span><span class="cx"> 
</span><span class="cx">     if (style.setFontDescription(fontDescription))
</span><del>-        style.font().update(styleResolver.fontSelector());
</del><ins>+        style.fontCascade().update(styleResolver.fontSelector());
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> NSControlSize RenderThemeSafari::controlSizeForSystemFont(RenderStyle&amp; style) const
</span></span></pre>
</div>
</div>

</body>
</html>