<!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>[190192] trunk</title>
</head>
<body>

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

<h3>Log Message</h3>
<pre>[Cocoa] [Font Features] Implement font-variant-*
https://bugs.webkit.org/show_bug.cgi?id=148413

Reviewed by Darin Adler.

Source/WebCore:

This patch is the first pass of implementing of the font-variant-* properties. Specifically,
these properties are:
font-variant-ligatures
font-variant-position
font-variant-caps
font-variant-numeric
font-variant-alternates
font-variant-east-asian

These new properties are held inside FontDescription as bit fields. At font creation time,
we consult with the FontDescription to figure out which variants are specified. We then
convert those variants to font features, and resolve these font features with the additional
features specified by font-feature-settings (as the spec requires). This patch also makes
our caches sensitive to these new properties of FontDescription so we don't look up cached,
stale fonts.

The implementation has some caveats, however. They are listed here:
1. These new properties need to interact correctly with @font-face declarations. In
particular, only certain properties of the FontDescription should be considered when
detecting if a @font-face declaration applies to a particular element. This discrimination
does not happen correctly. In addition, any feature-specific CSS properties inside the
@font-face declaration need to be consulted at a particular point during the feature
resolve. This does not currently occur.
2. One of the properties, font-variant-alternates, has a few values which require custom
CSS functions, which makes modeling the properties as bit fields tricky. These extra values
need to be implemented. This patch implements all the values which do not require extra CSS
features.
3. These new properties have a shorthand, font-variant, which is designed to be backward-
compatible with CSS 2.1's concept of font-variant. In particular, CSS 2.1 allows you to use
&quot;normal&quot; and &quot;small-caps&quot; with font-variant. Both of these values are values of the new
property font-variant-caps. However, our existing implementation of small-caps does not
use font features when they exist; instead, it simply draws text at a smaller font size and
uses (effectively) text-transform to force capital letters. This implementation needs to be
unified with the new font-variant-caps property so that we can expand font-variant to be
a shorthand for the new properties.
4. font-variant-position and font-variant-caps should provide appropriate synthesis if no
matching font-feature exists.
5. FontCascade::typesettingFeatures() is now no-longer accurate. Fixing this would be large
enough to warrant its own patch.
6. These properties are not tested with TrueType fonts.

Tests: css3/font-variant-all-webfont.html
       css3/font-variant-parsing.html

* css/CSSComputedStyleDeclaration.cpp: Reconstruct StyleProperties from a RenderStyle.
(WebCore::appendLigaturesValue):
(WebCore::fontVariantLigaturesPropertyValue):
(WebCore::fontVariantPositionPropertyValue):
(WebCore::fontVariantCapsPropertyValue):
(WebCore::fontVariantNumericPropertyValue):
(WebCore::fontVariantAlternatesPropertyValue):
(WebCore::fontVariantEastAsianPropertyValue):
(WebCore::ComputedStyleExtractor::propertyValue):
* css/CSSFontFeatureValue.cpp: Update to FontFeatureTag instead of WTF::String.
(WebCore::CSSFontFeatureValue::CSSFontFeatureValue):
(WebCore::CSSFontFeatureValue::customCSSText):
* css/CSSFontFeatureValue.h: Ditto.
(WebCore::CSSFontFeatureValue::create):
(WebCore::CSSFontFeatureValue::tag):
* css/CSSParser.cpp: Parse the new properties according to the CSS3 fonts spec.
(WebCore::isValidKeywordPropertyAndValue):
(WebCore::isKeywordPropertyID):
(WebCore::CSSParser::parseValue):
(WebCore::CSSParser::parseFontFeatureTag):
(WebCore::CSSParser::parseFontVariantLigatures):
(WebCore::CSSParser::parseFontVariantNumeric):
(WebCore::CSSParser::parseFontVariantEastAsian):
* css/CSSParser.h:
* css/CSSPrimitiveValueMappings.h: For the three properties which are simple keyword value
properties, implement casting operators to automatically convert between RenderStyle
objects and CSS property objects.
(WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
(WebCore::CSSPrimitiveValue::operator FontVariantPosition):
(WebCore::CSSPrimitiveValue::operator FontVariantCaps):
(WebCore::CSSPrimitiveValue::operator FontVariantAlternates):
* css/CSSPropertyNames.in: New properties.
* css/CSSValueKeywords.in: New values.
* css/StyleBuilderConverter.h:
(WebCore::StyleBuilderConverter::convertFontFeatureSettings): Update to not use
RefPtrs.
* css/StyleBuilderCustom.h: Properties which are not simple keyword value properties are
decomposed into multiple members of FontDescription. These properties exist to convert
between these aggregate members and the CSS properties.
(WebCore::StyleBuilderCustom::applyInheritFontVariantLigatures):
(WebCore::StyleBuilderCustom::applyInitialFontVariantLigatures):
(WebCore::StyleBuilderCustom::applyValueFontVariantLigatures):
(WebCore::StyleBuilderCustom::applyInheritFontVariantNumeric):
(WebCore::StyleBuilderCustom::applyInitialFontVariantNumeric):
(WebCore::StyleBuilderCustom::applyValueFontVariantNumeric):
(WebCore::StyleBuilderCustom::applyInheritFontVariantEastAsian):
(WebCore::StyleBuilderCustom::applyInitialFontVariantEastAsian):
(WebCore::StyleBuilderCustom::applyValueFontVariantEastAsian):
(WebCore::StyleBuilderCustom::applyInitialWebkitFontVariantLigatures): Deleted.
(WebCore::StyleBuilderCustom::applyInheritWebkitFontVariantLigatures): Deleted.
(WebCore::StyleBuilderCustom::applyValueWebkitFontVariantLigatures): Deleted.
* editing/cocoa/HTMLConverter.mm:
(HTMLConverter::computedAttributesForElement): Unprefix font-variant-ligatures.
* platform/graphics/FontCache.h: Update cache to be sensitive to new state in
FontDescription.
(WebCore::FontDescriptionKey::FontDescriptionKey):
(WebCore::FontDescriptionKey::operator==):
(WebCore::FontDescriptionKey::computeHash):
(WebCore::FontDescriptionKey::makeFlagsKey):
(WebCore::FontDescriptionKey::makeFlagKey): Deleted.
* platform/graphics/FontCascade.cpp:
(WebCore::FontCascade::codePath): These new variants should trigger the complex text
codepath.
* platform/graphics/FontCascade.h:
(WebCore::FontCascade::computeTypesettingFeatures): Update to use new state enum.
* platform/graphics/FontDescription.cpp: Add state to hold new property values.
(WebCore::FontDescription::FontDescription):
(WebCore::FontCascadeDescription::FontCascadeDescription): Deleted.
* platform/graphics/FontDescription.h: Add state to hold new property values.
(WebCore::FontDescription::featureSettings):
(WebCore::FontDescription::variantCommonLigatures):
(WebCore::FontDescription::variantDiscretionaryLigatures):
(WebCore::FontDescription::variantHistoricalLigatures):
(WebCore::FontDescription::variantContextualAlternates):
(WebCore::FontDescription::variantPosition):
(WebCore::FontDescription::variantCaps):
(WebCore::FontDescription::variantNumericFigure):
(WebCore::FontDescription::variantNumericSpacing):
(WebCore::FontDescription::variantNumericFraction):
(WebCore::FontDescription::variantNumericOrdinal):
(WebCore::FontDescription::variantNumericSlashedZero):
(WebCore::FontDescription::variantAlternates):
(WebCore::FontDescription::variantEastAsianVariant):
(WebCore::FontDescription::variantEastAsianWidth):
(WebCore::FontDescription::variantEastAsianRuby):
(WebCore::FontDescription::variantSettings):
(WebCore::FontDescription::setFeatureSettings):
(WebCore::FontDescription::setVariantCommonLigatures):
(WebCore::FontDescription::setVariantDiscretionaryLigatures):
(WebCore::FontDescription::setVariantHistoricalLigatures):
(WebCore::FontDescription::setVariantContextualAlternates):
(WebCore::FontDescription::setVariantPosition):
(WebCore::FontDescription::setVariantCaps):
(WebCore::FontDescription::setVariantNumericFigure):
(WebCore::FontDescription::setVariantNumericSpacing):
(WebCore::FontDescription::setVariantNumericFraction):
(WebCore::FontDescription::setVariantNumericOrdinal):
(WebCore::FontDescription::setVariantNumericSlashedZero):
(WebCore::FontDescription::setVariantAlternates):
(WebCore::FontDescription::setVariantEastAsianVariant):
(WebCore::FontDescription::setVariantEastAsianWidth):
(WebCore::FontDescription::setVariantEastAsianRuby):
(WebCore::FontDescription::operator==):
(WebCore::FontCascadeDescription::initialVariantPosition):
(WebCore::FontCascadeDescription::initialVariantCaps):
(WebCore::FontCascadeDescription::initialVariantAlternates):
(WebCore::FontCascadeDescription::commonLigaturesState): Deleted.
(WebCore::FontCascadeDescription::discretionaryLigaturesState): Deleted.
(WebCore::FontCascadeDescription::historicalLigaturesState): Deleted.
(WebCore::FontCascadeDescription::setCommonLigaturesState): Deleted.
(WebCore::FontCascadeDescription::setDiscretionaryLigaturesState): Deleted.
(WebCore::FontCascadeDescription::setHistoricalLigaturesState): Deleted.
(WebCore::FontCascadeDescription::operator==): Deleted.
* platform/graphics/FontFeatureSettings.cpp: Update to use FontFeatureTag instead of
WTF::String.
(WebCore::FontFeature::FontFeature):
(WebCore::FontFeature::operator==):
(WebCore::FontFeature::operator&lt;):
(WebCore::FontFeatureSettings::hash):
(WebCore::FontFeatureSettings::create): Deleted.
* platform/graphics/FontFeatureSettings.h: Update to use FontFeatureTag instead of
WTF::String.
(WebCore::fontFeatureTag):
(WebCore::FontFeatureTagHash::hash):
(WebCore::FontFeatureTagHash::equal):
(WebCore::FontFeatureTagHashTraits::constructDeletedValue):
(WebCore::FontFeatureTagHashTraits::isDeletedValue):
(WebCore::FontFeature::tag):
(WebCore::FontFeatureSettings::operator==):
(WebCore::FontFeatureSettings::begin):
(WebCore::FontFeatureSettings::end):
(WebCore::FontFeatureSettings::FontFeatureSettings): Deleted.
* platform/graphics/cocoa/FontCacheCoreText.cpp: Ditto. Also, when computing font
features, consult with the state inside FontDescription.
(WebCore::tagEquals):
(WebCore::appendTrueTypeFeature):
(WebCore::appendOpenTypeFeature):
(WebCore::computeFeatureSettingsFromVariants):
(WebCore::preparePlatformFont):
(WebCore::platformFontLookupWithFamily):
(WebCore::fontWithFamily):
(WebCore::FontCache::createFontPlatformData):
(WebCore::FontCache::systemFallbackForCharacters):
* platform/graphics/harfbuzz/HarfBuzzShaper.cpp: Update to use references instead of
pointers.
(WebCore::HarfBuzzShaper::setFontFeatures):
* platform/graphics/mac/FontCacheMac.mm:
(WebCore::platformFontWithFamily): Ditto.
* platform/graphics/mac/FontCustomPlatformData.cpp:
(WebCore::FontCustomPlatformData::fontPlatformData): Be sensitive to new state inside FontDescription.
* platform/text/TextFlags.h:
(WebCore::FontVariantSettings::isAllNormal): New state enums.
* rendering/RenderThemeIOS.mm:
(WebCore::RenderThemeIOS::updateCachedSystemFontDescription): Be sensitive to new state inside
FontDescription.
* rendering/line/BreakingContext.h:

Tools:

Update test font to use &quot;lnum&quot; feature.

* FontWithFeatures/FontWithFeatures/FontCreator.cpp:
(Generator::appendGSUBTable):

LayoutTests:

Updating tests because font-variant-ligatures is being unprefixed.

Also, update css3/resources/FontWithFeatures.otf to support &quot;lnum&quot; feature.

* css3/font-feature-settings-rendering-2-expected.html:
* css3/font-feature-settings-rendering-2.html:
* css3/font-variant-all-webfont-expected.html: Added.
* css3/font-variant-all-webfont.html: Added.
* css3/font-variant-parsing-expected.txt: Added.
* css3/font-variant-parsing.html: Added.
* css3/resources/FontWithFeatures.otf:
* fast/css/getComputedStyle/computed-style-expected.txt:
* fast/css/getComputedStyle/computed-style-font-family-expected.txt:
* fast/css/getComputedStyle/computed-style-without-renderer-expected.txt:
* fast/css/getComputedStyle/resources/property-names.js:
* fast/css/parsing-font-variant-ligatures.html:
* fast/text/font-variant-ligatures.html:
* platform/mac/TestExpectations:
* svg/css/getComputedStyle-basic-expected.txt:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestscss3fontfeaturesettingsrendering2expectedhtml">trunk/LayoutTests/css3/font-feature-settings-rendering-2-expected.html</a></li>
<li><a href="#trunkLayoutTestscss3fontfeaturesettingsrendering2html">trunk/LayoutTests/css3/font-feature-settings-rendering-2.html</a></li>
<li><a href="#trunkLayoutTestscss3resourcesFontWithFeaturesotf">trunk/LayoutTests/css3/resources/FontWithFeatures.otf</a></li>
<li><a href="#trunkLayoutTestsfastcssgetComputedStylecomputedstyleexpectedtxt">trunk/LayoutTests/fast/css/getComputedStyle/computed-style-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcssgetComputedStylecomputedstylefontfamilyexpectedtxt">trunk/LayoutTests/fast/css/getComputedStyle/computed-style-font-family-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcssgetComputedStylecomputedstylewithoutrendererexpectedtxt">trunk/LayoutTests/fast/css/getComputedStyle/computed-style-without-renderer-expected.txt</a></li>
<li><a href="#trunkLayoutTestsfastcssgetComputedStyleresourcespropertynamesjs">trunk/LayoutTests/fast/css/getComputedStyle/resources/property-names.js</a></li>
<li><a href="#trunkLayoutTestsfastcssparsingfontvariantligatureshtml">trunk/LayoutTests/fast/css/parsing-font-variant-ligatures.html</a></li>
<li><a href="#trunkLayoutTestsfasttextfontvariantligatureshtml">trunk/LayoutTests/fast/text/font-variant-ligatures.html</a></li>
<li><a href="#trunkLayoutTestsplatformmacTestExpectations">trunk/LayoutTests/platform/mac/TestExpectations</a></li>
<li><a href="#trunkLayoutTestssvgcssgetComputedStylebasicexpectedtxt">trunk/LayoutTests/svg/css/getComputedStyle-basic-expected.txt</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCorecssCSSComputedStyleDeclarationcpp">trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontFeatureValuecpp">trunk/Source/WebCore/css/CSSFontFeatureValue.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSFontFeatureValueh">trunk/Source/WebCore/css/CSSFontFeatureValue.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSParsercpp">trunk/Source/WebCore/css/CSSParser.cpp</a></li>
<li><a href="#trunkSourceWebCorecssCSSParserh">trunk/Source/WebCore/css/CSSParser.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSPrimitiveValueMappingsh">trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h</a></li>
<li><a href="#trunkSourceWebCorecssCSSPropertyNamesin">trunk/Source/WebCore/css/CSSPropertyNames.in</a></li>
<li><a href="#trunkSourceWebCorecssCSSValueKeywordsin">trunk/Source/WebCore/css/CSSValueKeywords.in</a></li>
<li><a href="#trunkSourceWebCorecssStyleBuilderConverterh">trunk/Source/WebCore/css/StyleBuilderConverter.h</a></li>
<li><a href="#trunkSourceWebCorecssStyleBuilderCustomh">trunk/Source/WebCore/css/StyleBuilderCustom.h</a></li>
<li><a href="#trunkSourceWebCoreeditingcocoaHTMLConvertermm">trunk/Source/WebCore/editing/cocoa/HTMLConverter.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontCacheh">trunk/Source/WebCore/platform/graphics/FontCache.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontCascadecpp">trunk/Source/WebCore/platform/graphics/FontCascade.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontCascadeh">trunk/Source/WebCore/platform/graphics/FontCascade.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontDescriptioncpp">trunk/Source/WebCore/platform/graphics/FontDescription.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontDescriptionh">trunk/Source/WebCore/platform/graphics/FontDescription.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontFeatureSettingscpp">trunk/Source/WebCore/platform/graphics/FontFeatureSettings.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsFontFeatureSettingsh">trunk/Source/WebCore/platform/graphics/FontFeatureSettings.h</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicscocoaFontCacheCoreTextcpp">trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsharfbuzzHarfBuzzShapercpp">trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacFontCacheMacmm">trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm</a></li>
<li><a href="#trunkSourceWebCoreplatformgraphicsmacFontCustomPlatformDatacpp">trunk/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp</a></li>
<li><a href="#trunkSourceWebCoreplatformtextTextFlagsh">trunk/Source/WebCore/platform/text/TextFlags.h</a></li>
<li><a href="#trunkSourceWebCorerenderingRenderThemeIOSmm">trunk/Source/WebCore/rendering/RenderThemeIOS.mm</a></li>
<li><a href="#trunkSourceWebCorerenderinglineBreakingContexth">trunk/Source/WebCore/rendering/line/BreakingContext.h</a></li>
<li><a href="#trunkToolsChangeLog">trunk/Tools/ChangeLog</a></li>
<li><a href="#trunkToolsFontWithFeaturesFontWithFeaturesFontCreatorcpp">trunk/Tools/FontWithFeatures/FontWithFeatures/FontCreator.cpp</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestscss3fontvariantallwebfontexpectedhtml">trunk/LayoutTests/css3/font-variant-all-webfont-expected.html</a></li>
<li><a href="#trunkLayoutTestscss3fontvariantallwebfonthtml">trunk/LayoutTests/css3/font-variant-all-webfont.html</a></li>
<li><a href="#trunkLayoutTestscss3fontvariantparsingexpectedtxt">trunk/LayoutTests/css3/font-variant-parsing-expected.txt</a></li>
<li><a href="#trunkLayoutTestscss3fontvariantparsinghtml">trunk/LayoutTests/css3/font-variant-parsing.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/ChangeLog        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -1,3 +1,30 @@
</span><ins>+2015-09-23  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        [Cocoa] [Font Features] Implement font-variant-*
+        https://bugs.webkit.org/show_bug.cgi?id=148413
+
+        Reviewed by Darin Adler.
+
+        Updating tests because font-variant-ligatures is being unprefixed.
+
+        Also, update css3/resources/FontWithFeatures.otf to support &quot;lnum&quot; feature.
+
+        * css3/font-feature-settings-rendering-2-expected.html:
+        * css3/font-feature-settings-rendering-2.html:
+        * css3/font-variant-all-webfont-expected.html: Added.
+        * css3/font-variant-all-webfont.html: Added.
+        * css3/font-variant-parsing-expected.txt: Added.
+        * css3/font-variant-parsing.html: Added.
+        * css3/resources/FontWithFeatures.otf:
+        * fast/css/getComputedStyle/computed-style-expected.txt:
+        * fast/css/getComputedStyle/computed-style-font-family-expected.txt:
+        * fast/css/getComputedStyle/computed-style-without-renderer-expected.txt:
+        * fast/css/getComputedStyle/resources/property-names.js:
+        * fast/css/parsing-font-variant-ligatures.html:
+        * fast/text/font-variant-ligatures.html:
+        * platform/mac/TestExpectations:
+        * svg/css/getComputedStyle-basic-expected.txt:
+
</ins><span class="cx"> 2015-09-23  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, roll out r190085 as it seems to cause crashes in JSC
</span></span></pre></div>
<a id="trunkLayoutTestscss3fontfeaturesettingsrendering2expectedhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/css3/font-feature-settings-rendering-2-expected.html (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/font-feature-settings-rendering-2-expected.html        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/css3/font-feature-settings-rendering-2-expected.html        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -41,6 +41,7 @@
</span><span class="cx"> &lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
</span><span class="cx"> &lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
</span><span class="cx"> &lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
</span><ins>+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;BA&lt;/span&gt;
</ins><span class="cx"> &lt;/div&gt;
</span><span class="cx"> &lt;/body&gt;
</span><span class="cx"> &lt;/html&gt;
</span></span></pre></div>
<a id="trunkLayoutTestscss3fontfeaturesettingsrendering2html"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/css3/font-feature-settings-rendering-2.html (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/font-feature-settings-rendering-2.html        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/css3/font-feature-settings-rendering-2.html        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -38,23 +38,24 @@
</span><span class="cx"> addElement(&quot;c2pc&quot;, &quot;M&quot;);
</span><span class="cx"> addElement(&quot;unic&quot;, &quot;N&quot;);
</span><span class="cx"> addElement(&quot;titl&quot;, &quot;O&quot;);
</span><del>-addElement(&quot;onum&quot;, &quot;P&quot;);
-addElement(&quot;pnum&quot;, &quot;Q&quot;);
-addElement(&quot;tnum&quot;, &quot;R&quot;);
-addElement(&quot;frac&quot;, &quot;S&quot;);
-//addElement(&quot;afrc&quot;, &quot;T&quot;);
-addElement(&quot;ordn&quot;, &quot;U&quot;);
-addElement(&quot;zero&quot;, &quot;V&quot;);
-addElement(&quot;hist&quot;, &quot;W&quot;);
-addElement(&quot;jp78&quot;, &quot;X&quot;);
-addElement(&quot;jp83&quot;, &quot;Y&quot;);
-addElement(&quot;jp90&quot;, &quot;Z&quot;);
-addElement(&quot;jp04&quot;, &quot;a&quot;);
-addElement(&quot;smpl&quot;, &quot;b&quot;);
-addElement(&quot;trad&quot;, &quot;c&quot;);
-addElement(&quot;fwid&quot;, &quot;d&quot;);
-addElement(&quot;pwid&quot;, &quot;e&quot;);
-addElement(&quot;ruby&quot;, &quot;f&quot;);
</del><ins>+addElement(&quot;lnum&quot;, &quot;P&quot;);
+addElement(&quot;onum&quot;, &quot;Q&quot;);
+addElement(&quot;pnum&quot;, &quot;R&quot;);
+addElement(&quot;tnum&quot;, &quot;S&quot;);
+addElement(&quot;frac&quot;, &quot;T&quot;);
+//addElement(&quot;afrc&quot;, &quot;U&quot;);
+addElement(&quot;ordn&quot;, &quot;V&quot;);
+addElement(&quot;zero&quot;, &quot;W&quot;);
+addElement(&quot;hist&quot;, &quot;X&quot;);
+addElement(&quot;jp78&quot;, &quot;Y&quot;);
+addElement(&quot;jp83&quot;, &quot;Z&quot;);
+addElement(&quot;jp90&quot;, &quot;a&quot;);
+addElement(&quot;jp04&quot;, &quot;b&quot;);
+addElement(&quot;smpl&quot;, &quot;c&quot;);
+addElement(&quot;trad&quot;, &quot;d&quot;);
+addElement(&quot;fwid&quot;, &quot;e&quot;);
+addElement(&quot;pwid&quot;, &quot;f&quot;);
+addElement(&quot;ruby&quot;, &quot;g&quot;);
</ins><span class="cx"> &lt;/script&gt;
</span><span class="cx"> &lt;/body&gt;
</span><span class="cx"> &lt;/html&gt;
</span></span></pre></div>
<a id="trunkLayoutTestscss3fontvariantallwebfontexpectedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/font-variant-all-webfont-expected.html (0 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/font-variant-all-webfont-expected.html                                (rev 0)
+++ trunk/LayoutTests/css3/font-variant-all-webfont-expected.html        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -0,0 +1,59 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+@font-face {
+    font-family: &quot;FontFeaturesTest&quot;;
+    src: url(&quot;resources/FontWithFeatures.otf&quot;) format(&quot;opentype&quot;);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p&gt;This test is a dump-render-tree test which makes sure that the following properties are appropriately applied:&lt;/p&gt;
+&lt;ul&gt;
+&lt;li&gt;-webkit-font-variant-ligatures&lt;/li&gt;
+&lt;li&gt;-webkit-font-variant-position&lt;/li&gt;
+&lt;li&gt;-webkit-font-variant-caps&lt;/li&gt;
+&lt;li&gt;-webkit-font-variant-numeric&lt;/li&gt;
+&lt;li&gt;-webkit-font-variant-alternates&lt;/li&gt;
+&lt;li&gt;-webkit-font-variant-east-asian&lt;/li&gt;
+&lt;/ul&gt;
+The test passes if there is a particular sequence of checks and x characters below. Note that some x characters are expected.
+&lt;div id=&quot;insertionpoint&quot;&gt;&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;B&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;B&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;B&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;B&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;B&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;span style=&quot;font-family: FontFeaturesTest;&quot;&gt;A&lt;/span&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscss3fontvariantallwebfonthtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/font-variant-all-webfont.html (0 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/font-variant-all-webfont.html                                (rev 0)
+++ trunk/LayoutTests/css3/font-variant-all-webfont.html        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -0,0 +1,70 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;style&gt;
+@font-face {
+    font-family: &quot;FontFeaturesTest&quot;;
+    src: url(&quot;resources/FontWithFeatures.otf&quot;) format(&quot;opentype&quot;);
+}
+&lt;/style&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;p&gt;This test is a dump-render-tree test which makes sure that the following properties are appropriately applied:&lt;/p&gt;
+&lt;ul&gt;
+&lt;li&gt;-webkit-font-variant-ligatures&lt;/li&gt;
+&lt;li&gt;-webkit-font-variant-position&lt;/li&gt;
+&lt;li&gt;-webkit-font-variant-caps&lt;/li&gt;
+&lt;li&gt;-webkit-font-variant-numeric&lt;/li&gt;
+&lt;li&gt;-webkit-font-variant-alternates&lt;/li&gt;
+&lt;li&gt;-webkit-font-variant-east-asian&lt;/li&gt;
+&lt;/ul&gt;
+The test passes if there is a particular sequence of checks and x characters below. Note that some x characters are expected.
+&lt;div id=&quot;insertionpoint&quot;&gt;&lt;/div&gt;
+&lt;script&gt;
+var insertionpoint = document.getElementById(&quot;insertionpoint&quot;);
+function addElement(property, value, text) {
+    var element = document.createElement(&quot;span&quot;);
+    element.textContent = text;
+    element.setAttribute(&quot;style&quot;, &quot;font-family: FontFeaturesTest; &quot; + property + &quot;: &quot; + value + &quot;;&quot;);
+    insertionpoint.appendChild(element);
+    insertionpoint.appendChild(document.createTextNode(&quot; &quot;));
+}
+addElement(&quot;font-variant-ligatures&quot;, &quot;common-ligatures&quot;, &quot;C&quot;);
+addElement(&quot;font-variant-ligatures&quot;, &quot;common-ligatures&quot;, &quot;D&quot;);
+addElement(&quot;font-variant-ligatures&quot;, &quot;no-common-ligatures&quot;, &quot;C&quot;);
+addElement(&quot;font-variant-ligatures&quot;, &quot;no-common-ligatures&quot;, &quot;D&quot;);
+addElement(&quot;font-variant-ligatures&quot;, &quot;discretionary-ligatures&quot;, &quot;E&quot;);
+addElement(&quot;font-variant-ligatures&quot;, &quot;no-discretionary-ligatures&quot;, &quot;E&quot;);
+addElement(&quot;font-variant-ligatures&quot;, &quot;historical-ligatures&quot;, &quot;F&quot;);
+addElement(&quot;font-variant-ligatures&quot;, &quot;no-historical-ligatures&quot;, &quot;F&quot;);
+addElement(&quot;font-variant-ligatures&quot;, &quot;contextual&quot;, &quot;G&quot;);
+addElement(&quot;font-variant-ligatures&quot;, &quot;no-contextual&quot;, &quot;G&quot;);
+addElement(&quot;font-variant-position&quot;, &quot;sub&quot;, &quot;H&quot;);
+addElement(&quot;font-variant-position&quot;, &quot;super&quot;, &quot;I&quot;);
+addElement(&quot;font-variant-caps&quot;, &quot;small-caps&quot;, &quot;J&quot;);
+addElement(&quot;font-variant-caps&quot;, &quot;all-small-caps&quot;, &quot;K&quot;);
+addElement(&quot;font-variant-caps&quot;, &quot;petite-caps&quot;, &quot;L&quot;);
+addElement(&quot;font-variant-caps&quot;, &quot;all-petite-caps&quot;, &quot;M&quot;);
+addElement(&quot;font-variant-caps&quot;, &quot;unicase&quot;, &quot;N&quot;);
+addElement(&quot;font-variant-caps&quot;, &quot;titling-caps&quot;, &quot;O&quot;);
+addElement(&quot;font-variant-numeric&quot;, &quot;lining-nums&quot;, &quot;P&quot;);
+addElement(&quot;font-variant-numeric&quot;, &quot;oldstyle-nums&quot;, &quot;Q&quot;);
+addElement(&quot;font-variant-numeric&quot;, &quot;proportional-nums&quot;, &quot;R&quot;);
+addElement(&quot;font-variant-numeric&quot;, &quot;tabular-nums&quot;, &quot;S&quot;);
+addElement(&quot;font-variant-numeric&quot;, &quot;diagonal-fractions&quot;, &quot;T&quot;);
+//addElement(&quot;font-variant-numeric&quot;, &quot;stacked-fractions&quot;, &quot;U&quot;);
+addElement(&quot;font-variant-numeric&quot;, &quot;ordinal&quot;, &quot;V&quot;);
+addElement(&quot;font-variant-numeric&quot;, &quot;slashed-zero&quot;, &quot;W&quot;);
+addElement(&quot;font-variant-alternates&quot;, &quot;historical-forms&quot;, &quot;X&quot;);
+addElement(&quot;font-variant-east-asian&quot;, &quot;jis78&quot;, &quot;Y&quot;);
+addElement(&quot;font-variant-east-asian&quot;, &quot;jis83&quot;, &quot;Z&quot;);
+addElement(&quot;font-variant-east-asian&quot;, &quot;jis90&quot;, &quot;a&quot;);
+addElement(&quot;font-variant-east-asian&quot;, &quot;jis04&quot;, &quot;b&quot;);
+addElement(&quot;font-variant-east-asian&quot;, &quot;simplified&quot;, &quot;c&quot;);
+addElement(&quot;font-variant-east-asian&quot;, &quot;traditional&quot;, &quot;d&quot;);
+addElement(&quot;font-variant-east-asian&quot;, &quot;full-width&quot;, &quot;e&quot;);
+addElement(&quot;font-variant-east-asian&quot;, &quot;proportional-width&quot;, &quot;f&quot;);
+addElement(&quot;font-variant-east-asian&quot;, &quot;ruby&quot;, &quot;g&quot;);
+&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscss3fontvariantparsingexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/font-variant-parsing-expected.txt (0 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/font-variant-parsing-expected.txt                                (rev 0)
+++ trunk/LayoutTests/css3/font-variant-parsing-expected.txt        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -0,0 +1,87 @@
</span><ins>+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;common-ligatures&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;no-common-ligatures&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;discretionary-ligatures&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;no-discretionary-ligatures&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;historical-ligatures&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;no-historical-ligatures&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;contextual&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;no-contextual&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;common-ligatures no-contextual&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;common-ligatures no-contextual&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;none&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-ligatures').cssText is &quot;none&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-position').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-position').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-position').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-position').cssText is &quot;sub&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-position').cssText is &quot;super&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-position').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;small-caps&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;all-small-caps&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;petite-caps&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;all-petite-caps&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;unicase&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;titling-caps&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-caps').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;lining-nums&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;oldstyle-nums&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;proportional-nums&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;tabular-nums&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;diagonal-fractions&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;stacked-fractions&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;ordinal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;slashed-zero&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;lining-nums slashed-zero&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;lining-nums proportional-nums&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;lining-nums diagonal-fractions&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-numeric').cssText is &quot;ordinal slashed-zero&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-alternates').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-alternates').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-alternates').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-alternates').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-alternates').cssText is &quot;historical-forms&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-alternates').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;jis78&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;jis83&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;jis90&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;jis04&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;simplified&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;traditional&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;full-width&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;proportional-width&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;ruby&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;normal&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;traditional full-width&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;jis04 proportional-width&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;jis04 proportional-width ruby&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;jis83 ruby&quot;
+PASS window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('font-variant-east-asian').cssText is &quot;normal&quot;
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
</ins></span></pre></div>
<a id="trunkLayoutTestscss3fontvariantparsinghtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/css3/font-variant-parsing.html (0 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/font-variant-parsing.html                                (rev 0)
+++ trunk/LayoutTests/css3/font-variant-parsing.html        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -0,0 +1,109 @@
</span><ins>+&lt;!DOCTYPE html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
+&lt;/head&gt;
+&lt;body&gt;
+&lt;script&gt;
+function runTest(property, propertyText, expectedText) {
+    var element = document.createElement(&quot;span&quot;);
+    element.setAttribute(&quot;id&quot;, &quot;testElement&quot;);
+    if (property != &quot;&quot;)
+        element.setAttribute(&quot;style&quot;, property + &quot;: &quot; + propertyText + &quot;;&quot;);
+    document.body.appendChild(element);
+    shouldBeEqualToString(&quot;window.getComputedStyle(document.getElementById('testElement')).getPropertyCSSValue('&quot; + property + &quot;').cssText&quot;, expectedText);
+    document.body.removeChild(element);
+}
+
+runTest(&quot;font-variant-ligatures&quot;, &quot;&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;normal&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;normal common-ligatures&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;notavalidvalue&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;common-ligatures&quot;, &quot;common-ligatures&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;common-ligatures common-ligatures&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;no-common-ligatures&quot;, &quot;no-common-ligatures&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;discretionary-ligatures&quot;, &quot;discretionary-ligatures&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;no-discretionary-ligatures&quot;, &quot;no-discretionary-ligatures&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;historical-ligatures&quot;, &quot;historical-ligatures&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;no-historical-ligatures&quot;, &quot;no-historical-ligatures&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;contextual&quot;, &quot;contextual&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;no-contextual&quot;, &quot;no-contextual&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;common-ligatures no-contextual&quot;, &quot;common-ligatures no-contextual&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;no-contextual common-ligatures&quot;, &quot;common-ligatures no-contextual&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;no-contextual common-ligatures notavalidvalue&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;none&quot;, &quot;none&quot;);
+runTest(&quot;font-variant-ligatures&quot;, &quot;no-common-ligatures no-discretionary-ligatures no-historical-ligatures no-contextual&quot;, &quot;none&quot;);
+
+runTest(&quot;font-variant-position&quot;, &quot;&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-position&quot;, &quot;normal&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-position&quot;, &quot;notavalidvalue&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-position&quot;, &quot;sub&quot;, &quot;sub&quot;);
+runTest(&quot;font-variant-position&quot;, &quot;super&quot;, &quot;super&quot;);
+runTest(&quot;font-variant-position&quot;, &quot;sub super&quot;, &quot;normal&quot;);
+
+runTest(&quot;font-variant-caps&quot;, &quot;&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;normal&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;notavalidvalue&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;normal notavalidvalue&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;normal small-caps&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;small-caps&quot;, &quot;small-caps&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;all-small-caps&quot;, &quot;all-small-caps&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;petite-caps&quot;, &quot;petite-caps&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;all-petite-caps&quot;, &quot;all-petite-caps&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;unicase&quot;, &quot;unicase&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;titling-caps&quot;, &quot;titling-caps&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;unicase titling-caps&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-caps&quot;, &quot;small-caps all-small-caps&quot;, &quot;normal&quot;);
+
+runTest(&quot;font-variant-numeric&quot;, &quot;&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;normal&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;notavalidvalue&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;normal notavalidvalue&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;normal lining-nums&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;lining-nums&quot;, &quot;lining-nums&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;oldstyle-nums&quot;, &quot;oldstyle-nums&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;proportional-nums&quot;, &quot;proportional-nums&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;tabular-nums&quot;, &quot;tabular-nums&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;diagonal-fractions&quot;, &quot;diagonal-fractions&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;stacked-fractions&quot;, &quot;stacked-fractions&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;ordinal&quot;, &quot;ordinal&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;slashed-zero&quot;, &quot;slashed-zero&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;lining-nums slashed-zero&quot;, &quot;lining-nums slashed-zero&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;lining-nums oldstyle-nums&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;proportional-nums tabular-nums&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;diagonal-fractions stacked-fractions&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;lining-nums proportional-nums&quot;, &quot;lining-nums proportional-nums&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;lining-nums diagonal-fractions&quot;, &quot;lining-nums diagonal-fractions&quot;);
+runTest(&quot;font-variant-numeric&quot;, &quot;ordinal slashed-zero&quot;, &quot;ordinal slashed-zero&quot;);
+
+runTest(&quot;font-variant-alternates&quot;, &quot;&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-alternates&quot;, &quot;normal&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-alternates&quot;, &quot;notavalidvalue&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-alternates&quot;, &quot;normal notavalidvalue&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-alternates&quot;, &quot;historical-forms&quot;, &quot;historical-forms&quot;);
+runTest(&quot;font-variant-alternates&quot;, &quot;normal historical-forms&quot;, &quot;normal&quot;);
+
+runTest(&quot;font-variant-east-asian&quot;, &quot;&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;normal&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;notavalidvalue&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;normal notavalidvalue&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;jis78&quot;, &quot;jis78&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;jis83&quot;, &quot;jis83&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;jis90&quot;, &quot;jis90&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;jis04&quot;, &quot;jis04&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;simplified&quot;, &quot;simplified&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;traditional&quot;, &quot;traditional&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;full-width&quot;, &quot;full-width&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;proportional-width&quot;, &quot;proportional-width&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;ruby&quot;, &quot;ruby&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;jis78 jis83&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;jis90 traditional&quot;, &quot;normal&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;full-width traditional&quot;, &quot;traditional full-width&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;jis04 proportional-width&quot;, &quot;jis04 proportional-width&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;jis04 proportional-width ruby&quot;, &quot;jis04 proportional-width ruby&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;jis83 ruby&quot;, &quot;jis83 ruby&quot;);
+runTest(&quot;font-variant-east-asian&quot;, &quot;full-width proportional-width&quot;, &quot;normal&quot;);
+&lt;/script&gt;
+&lt;script src=&quot;../resources/js-test-post.js&quot;&gt;&lt;/script&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestscss3resourcesFontWithFeaturesotf"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/css3/resources/FontWithFeatures.otf (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/css3/resources/FontWithFeatures.otf        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/css3/resources/FontWithFeatures.otf        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> OTTO
</span><del>-\x80 CFF \x94[\xA9D\xAC&quot;;GSUB\xC5b\xBB\xFE&quot;\xE8\x94OS/2H\xE0Yb'|dcmap\xD5\xAF'\xE0jheadeD\xF8(L6hheag7(\x84$hmtx(\xA8\xD4maxpk)| name\xA8)\x9C$post)\xC0 
</del><ins>+\x80 CFF \x94[\xA9D\xAC&quot;;GSUBä»….&quot;\xE8\xBAOS/2H\xE0Yb'\xA4dcmap\xD5\xAF(jheadeD\xF8(t6hheag7(\xAC$hmtx(\xD0\xD4maxpk)\xA4 name\xA8)\xC4$post)\xE8 
</ins><span class="cx"> MylesFont9\x87\x87q\xDA
</span><span class="cx"> MylesFont        
</span><span class="cx">  @@ -8,12 +8,13 @@
</span><span class="cx"> \xA7 G \xE7 \x87 ' \xC7g\xA7G\xE7\x87'\xC7g\xA7G\xE7\x87'\xC7g\xA7G\xE7\x87'\xC7g\xA7G\xE7 \x87\xFF\xFF\xFF\xFF\xC8\xFF\xC8\xFF\xFFX\xFFX\xFF\xFF\xFF\xFD\xA8\xFF\xFD\xA8\xFF\xFF\xFF\xFF\xFF\xC8\xFF\xF4\xFF2\xFF2\xFF\xFA\xFF\xFF\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFE&gt;\xFF\xFE&gt;\xFF\xFE\xD4\xFF,\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF
 \x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\
 xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF
 \xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\
 xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE
 \xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFE
 p\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x9
 0\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xF
 Ep\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xF
 Ep\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\x
 FF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xF
 F2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF
 \x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF
 \x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF
 \xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF
 \x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xF
 F2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2
 \xFF\x90\xFF\xFEp\xFF\xFF\xFF\xFF\xF4\xFF&amp;\xFF\x90\xFF\x90\xFF2\xFF\xFF\xCE\xFF\xFEp\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFF\xCE\xFF\xFF\xCE\xFF\xFEp\xFF\x90\xFF\xFEp\xFF\xFEp\xFF\xFF\xCE\xFF2\xFF\x90\xFF\x90\xFF\xFEp\xFF\x90\xFF2\xFF2\xFF\x90\xFF\xFEp
</span><del>-X\xC2DFLT\xFF\xFF        
</del><ins>+Z\xD0DFLT\xFF\xFF        
</ins><span class="cx">  -liga\xB6clig\xBCdlig\xC2hlig\xC8calt\xCEsubs\xD4sups\xDAsmcp\xE0c2sc\xE6pcap\xECc2pc\xF2unic\xF8titl\xFEonumpnum
</span><del>-tnumfracafrcordn&quot;zero(hist.jp784jp83:jp90@jp04FsmplLtradRfwidXpwid^rubyd        
</del><ins>+liga\xBCclig\xC2dlig\xC8hlig\xCEcalt\xD4subs\xDAsups\xE0smcp\xE6c2sc\xECpcap\xF2c2pc\xF8unic\xFEtitllnum
+onumpnumtnumfrac&quot;afrc(ordn.zero4hist:jp78@jp83Fjp90Ljp04RsmplXtrad^fwiddpwidjrubyp        
</ins><span class="cx">   -&gt;FNV^fnv~\x86\x8E\x96\x9E\xA6\xAE\xB6\xBE\xC6\xCE\xD6\xDE\xE6\xEE\xF6\xFE&amp;\xF0\xF6\xFC &amp;,28&gt;DJPV\bhntz\x80\x86\x8C\x92\x98\x9E        
</span><ins>+@HPX`hpx\x80\x88\x90\x98\xA0\xA8\xB0\xB8\xC0\xC8\xD0\xD8\xE0\xE8\xF0\xF8 (0\xF8\xFE
+&quot;(.4:@FLRX^djpv|\x82\x88\x8E\x94\x9A\xA0\xA6\xAC        
</ins><span class="cx">   - \xF4TKBW\xFF\xFFf\xFF\xFC\xFF\xFF \xFF\xFFD
</span><del>- (AZaz&amp;Zz\xFF\xFFAa\xFF\xFF\xFF\xDA\xFF\xA0y\xF6\x9C_&lt;\xF5f55\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF5        MylesFont
</del><span class="cx">\ No newline at end of file
</span><ins>+ !\xF4TKBW\xFF\xFFf\xFF\xFC\xFF\xFF \xFF\xFFD
+ (AZaz&amp;Zz\xFF\xFFAa\xFF\xFF\xFF\xDA\xFF\xA0:\xCEb\xD6_&lt;\xF5f55\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF5        MylesFont
</ins><span class="cx">\ No newline at end of file
</span></span></pre></div>
<a id="trunkLayoutTestsfastcssgetComputedStylecomputedstyleexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/css/getComputedStyle/computed-style-expected.txt (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/getComputedStyle/computed-style-expected.txt        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/fast/css/getComputedStyle/computed-style-expected.txt        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -159,7 +159,12 @@
</span><span class="cx"> justify-items: start;
</span><span class="cx"> -webkit-font-kerning: auto;
</span><span class="cx"> -webkit-font-smoothing: auto;
</span><del>--webkit-font-variant-ligatures: normal;
</del><ins>+font-variant-ligatures: normal;
+font-variant-position: normal;
+font-variant-caps: normal;
+font-variant-numeric: normal;
+font-variant-alternates: normal;
+font-variant-east-asian: normal;
</ins><span class="cx"> -webkit-grid-auto-columns: auto;
</span><span class="cx"> -webkit-grid-auto-flow: row;
</span><span class="cx"> -webkit-grid-auto-rows: auto;
</span></span></pre></div>
<a id="trunkLayoutTestsfastcssgetComputedStylecomputedstylefontfamilyexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/css/getComputedStyle/computed-style-font-family-expected.txt (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/getComputedStyle/computed-style-font-family-expected.txt        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/fast/css/getComputedStyle/computed-style-font-family-expected.txt        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -6,4 +6,10 @@
</span><span class="cx"> font-synthesis: style weight;
</span><span class="cx"> font-variant: normal;
</span><span class="cx"> font-weight: normal;
</span><ins>+font-variant-ligatures: normal;
+font-variant-position: normal;
+font-variant-caps: normal;
+font-variant-numeric: normal;
+font-variant-alternates: normal;
+font-variant-east-asian: normal;
</ins><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsfastcssgetComputedStylecomputedstylewithoutrendererexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/css/getComputedStyle/computed-style-without-renderer-expected.txt (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/getComputedStyle/computed-style-without-renderer-expected.txt        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/fast/css/getComputedStyle/computed-style-without-renderer-expected.txt        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -158,7 +158,12 @@
</span><span class="cx"> justify-items: auto
</span><span class="cx"> -webkit-font-kerning: auto
</span><span class="cx"> -webkit-font-smoothing: auto
</span><del>--webkit-font-variant-ligatures: normal
</del><ins>+font-variant-ligatures: normal
+font-variant-position: normal
+font-variant-caps: normal
+font-variant-numeric: normal
+font-variant-alternates: normal
+font-variant-east-asian: normal
</ins><span class="cx"> -webkit-grid-auto-columns: auto
</span><span class="cx"> -webkit-grid-auto-flow: row
</span><span class="cx"> -webkit-grid-auto-rows: auto
</span></span></pre></div>
<a id="trunkLayoutTestsfastcssgetComputedStyleresourcespropertynamesjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/css/getComputedStyle/resources/property-names.js (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/getComputedStyle/resources/property-names.js        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/fast/css/getComputedStyle/resources/property-names.js        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -48,7 +48,6 @@
</span><span class="cx">     &quot;flex-wrap&quot;: true,
</span><span class="cx">     &quot;-webkit-font-kerning&quot;: true,
</span><span class="cx">     &quot;-webkit-font-smoothing&quot;: true,
</span><del>-    &quot;-webkit-font-variant-ligatures&quot;: true,
</del><span class="cx">     &quot;-webkit-grid-auto-columns&quot;: true,
</span><span class="cx">     &quot;-webkit-grid-auto-flow&quot;: true,
</span><span class="cx">     &quot;-webkit-grid-auto-rows&quot;: true,
</span><span class="lines">@@ -184,6 +183,12 @@
</span><span class="cx">     &quot;font-style&quot;: true,
</span><span class="cx">     &quot;font-synthesis&quot;: true,
</span><span class="cx">     &quot;font-variant&quot;: true,
</span><ins>+    &quot;font-variant-ligatures&quot;: true,
+    &quot;font-variant-position&quot;: true,
+    &quot;font-variant-caps&quot;: true,
+    &quot;font-variant-numeric&quot;: true,
+    &quot;font-variant-alternates&quot;: true,
+    &quot;font-variant-east-asian&quot;: true,
</ins><span class="cx">     &quot;font-weight&quot;: true,
</span><span class="cx">     &quot;glyph-orientation-horizontal&quot;: true,
</span><span class="cx">     &quot;glyph-orientation-vertical&quot;: true,
</span></span></pre></div>
<a id="trunkLayoutTestsfastcssparsingfontvariantligatureshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/css/parsing-font-variant-ligatures.html (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/css/parsing-font-variant-ligatures.html        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/fast/css/parsing-font-variant-ligatures.html        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -11,10 +11,10 @@
</span><span class="cx">     function test(value, expectedCSSText, expectedComputedCSSText)
</span><span class="cx">     {
</span><span class="cx">         var element = document.createElement(&quot;div&quot;);
</span><del>-        element.style.setProperty(&quot;-webkit-font-variant-ligatures&quot;, value);
-        var cssText = element.style.webkitFontVariantLigatures;
</del><ins>+        element.style.setProperty(&quot;font-variant-ligatures&quot;, value);
+        var cssText = element.style.fontVariantLigatures;
</ins><span class="cx">         document.body.appendChild(element);
</span><del>-        var computedCSSText = getComputedStyle(element).webkitFontVariantLigatures;
</del><ins>+        var computedCSSText = getComputedStyle(element).fontVariantLigatures;
</ins><span class="cx">         document.body.removeChild(element);
</span><span class="cx">         if (cssText === expectedCSSText &amp;&amp; computedCSSText == expectedComputedCSSText)
</span><span class="cx">             log(&quot;PASS: '&quot; + value + &quot;' parsed as '&quot; + expectedCSSText + &quot;' and computed to '&quot; + computedCSSText + &quot;'&quot;);
</span></span></pre></div>
<a id="trunkLayoutTestsfasttextfontvariantligatureshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/fast/text/font-variant-ligatures.html (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/fast/text/font-variant-ligatures.html        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/fast/text/font-variant-ligatures.html        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -1,7 +1,7 @@
</span><span class="cx"> &lt;style&gt;
</span><del>-    .common-ligatures-disabled { -webkit-font-variant-ligatures: no-common-ligatures; }
-    .common-ligatures-enabled { -webkit-font-variant-ligatures: common-ligatures; }
-    .common-ligatures-normal { -webkit-font-variant-ligatures: normal; }
</del><ins>+    .common-ligatures-disabled { font-variant-ligatures: no-common-ligatures; }
+    .common-ligatures-enabled { font-variant-ligatures: common-ligatures; }
+    .common-ligatures-normal { font-variant-ligatures: normal; }
</ins><span class="cx"> &lt;/style&gt;
</span><span class="cx"> &lt;body style=&quot;font-size: 36px;&quot;&gt;
</span><span class="cx">     &lt;div&gt;
</span></span></pre></div>
<a id="trunkLayoutTestsplatformmacTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/platform/mac/TestExpectations (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/platform/mac/TestExpectations        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/platform/mac/TestExpectations        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -262,6 +262,8 @@
</span><span class="cx"> css3/font-feature-settings-rendering.html
</span><span class="cx"> 
</span><span class="cx"> webkit.org/b/149246 [ Mavericks ] css3/font-feature-settings-rendering-2.html
</span><ins>+webkit.org/b/149246 [ Mavericks ] css3/font-variant-all-webfont.html
+webkit.org/b/149246 [ Mavericks ] css3/font-variant-parsing.html
</ins><span class="cx"> 
</span><span class="cx"> # This feature is disabled on Mavericks.
</span><span class="cx"> [ Mavericks ] http/tests/navigation/page-cache-pending-image-load.html [ Skip ]
</span></span></pre></div>
<a id="trunkLayoutTestssvgcssgetComputedStylebasicexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/svg/css/getComputedStyle-basic-expected.txt (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/svg/css/getComputedStyle-basic-expected.txt        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/LayoutTests/svg/css/getComputedStyle-basic-expected.txt        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -316,8 +316,18 @@
</span><span class="cx"> rect: style.getPropertyCSSValue(-webkit-font-kerning) : [object CSSPrimitiveValue]
</span><span class="cx"> rect: style.getPropertyValue(-webkit-font-smoothing) : auto
</span><span class="cx"> rect: style.getPropertyCSSValue(-webkit-font-smoothing) : [object CSSPrimitiveValue]
</span><del>-rect: style.getPropertyValue(-webkit-font-variant-ligatures) : normal
-rect: style.getPropertyCSSValue(-webkit-font-variant-ligatures) : [object CSSPrimitiveValue]
</del><ins>+rect: style.getPropertyValue(font-variant-ligatures) : normal
+rect: style.getPropertyCSSValue(font-variant-ligatures) : [object CSSPrimitiveValue]
+rect: style.getPropertyValue(font-variant-position) : normal
+rect: style.getPropertyCSSValue(font-variant-position) : [object CSSPrimitiveValue]
+rect: style.getPropertyValue(font-variant-caps) : normal
+rect: style.getPropertyCSSValue(font-variant-caps) : [object CSSPrimitiveValue]
+rect: style.getPropertyValue(font-variant-numeric) : normal
+rect: style.getPropertyCSSValue(font-variant-numeric) : [object CSSPrimitiveValue]
+rect: style.getPropertyValue(font-variant-alternates) : normal
+rect: style.getPropertyCSSValue(font-variant-alternates) : [object CSSPrimitiveValue]
+rect: style.getPropertyValue(font-variant-east-asian) : normal
+rect: style.getPropertyCSSValue(font-variant-east-asian) : [object CSSPrimitiveValue]
</ins><span class="cx"> rect: style.getPropertyValue(-webkit-grid-auto-columns) : auto
</span><span class="cx"> rect: style.getPropertyCSSValue(-webkit-grid-auto-columns) : [object CSSPrimitiveValue]
</span><span class="cx"> rect: style.getPropertyValue(-webkit-grid-auto-flow) : row
</span><span class="lines">@@ -840,8 +850,18 @@
</span><span class="cx"> g: style.getPropertyCSSValue(-webkit-font-kerning) : [object CSSPrimitiveValue]
</span><span class="cx"> g: style.getPropertyValue(-webkit-font-smoothing) : auto
</span><span class="cx"> g: style.getPropertyCSSValue(-webkit-font-smoothing) : [object CSSPrimitiveValue]
</span><del>-g: style.getPropertyValue(-webkit-font-variant-ligatures) : normal
-g: style.getPropertyCSSValue(-webkit-font-variant-ligatures) : [object CSSPrimitiveValue]
</del><ins>+g: style.getPropertyValue(font-variant-ligatures) : normal
+g: style.getPropertyCSSValue(font-variant-ligatures) : [object CSSPrimitiveValue]
+g: style.getPropertyValue(font-variant-position) : normal
+g: style.getPropertyCSSValue(font-variant-position) : [object CSSPrimitiveValue]
+g: style.getPropertyValue(font-variant-caps) : normal
+g: style.getPropertyCSSValue(font-variant-caps) : [object CSSPrimitiveValue]
+g: style.getPropertyValue(font-variant-numeric) : normal
+g: style.getPropertyCSSValue(font-variant-numeric) : [object CSSPrimitiveValue]
+g: style.getPropertyValue(font-variant-alternates) : normal
+g: style.getPropertyCSSValue(font-variant-alternates) : [object CSSPrimitiveValue]
+g: style.getPropertyValue(font-variant-east-asian) : normal
+g: style.getPropertyCSSValue(font-variant-east-asian) : [object CSSPrimitiveValue]
</ins><span class="cx"> g: style.getPropertyValue(-webkit-grid-auto-columns) : auto
</span><span class="cx"> g: style.getPropertyCSSValue(-webkit-grid-auto-columns) : [object CSSPrimitiveValue]
</span><span class="cx"> g: style.getPropertyValue(-webkit-grid-auto-flow) : row
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/ChangeLog        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -1,3 +1,211 @@
</span><ins>+2015-09-23  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        [Cocoa] [Font Features] Implement font-variant-*
+        https://bugs.webkit.org/show_bug.cgi?id=148413
+
+        Reviewed by Darin Adler.
+
+        This patch is the first pass of implementing of the font-variant-* properties. Specifically,
+        these properties are:
+        font-variant-ligatures
+        font-variant-position
+        font-variant-caps
+        font-variant-numeric
+        font-variant-alternates
+        font-variant-east-asian
+
+        These new properties are held inside FontDescription as bit fields. At font creation time,
+        we consult with the FontDescription to figure out which variants are specified. We then
+        convert those variants to font features, and resolve these font features with the additional
+        features specified by font-feature-settings (as the spec requires). This patch also makes
+        our caches sensitive to these new properties of FontDescription so we don't look up cached,
+        stale fonts.
+
+        The implementation has some caveats, however. They are listed here:
+        1. These new properties need to interact correctly with @font-face declarations. In
+        particular, only certain properties of the FontDescription should be considered when
+        detecting if a @font-face declaration applies to a particular element. This discrimination
+        does not happen correctly. In addition, any feature-specific CSS properties inside the
+        @font-face declaration need to be consulted at a particular point during the feature
+        resolve. This does not currently occur.
+        2. One of the properties, font-variant-alternates, has a few values which require custom
+        CSS functions, which makes modeling the properties as bit fields tricky. These extra values
+        need to be implemented. This patch implements all the values which do not require extra CSS
+        features.
+        3. These new properties have a shorthand, font-variant, which is designed to be backward-
+        compatible with CSS 2.1's concept of font-variant. In particular, CSS 2.1 allows you to use
+        &quot;normal&quot; and &quot;small-caps&quot; with font-variant. Both of these values are values of the new
+        property font-variant-caps. However, our existing implementation of small-caps does not
+        use font features when they exist; instead, it simply draws text at a smaller font size and
+        uses (effectively) text-transform to force capital letters. This implementation needs to be
+        unified with the new font-variant-caps property so that we can expand font-variant to be
+        a shorthand for the new properties.
+        4. font-variant-position and font-variant-caps should provide appropriate synthesis if no
+        matching font-feature exists.
+        5. FontCascade::typesettingFeatures() is now no-longer accurate. Fixing this would be large
+        enough to warrant its own patch.
+        6. These properties are not tested with TrueType fonts.
+
+        Tests: css3/font-variant-all-webfont.html
+               css3/font-variant-parsing.html
+
+        * css/CSSComputedStyleDeclaration.cpp: Reconstruct StyleProperties from a RenderStyle.
+        (WebCore::appendLigaturesValue):
+        (WebCore::fontVariantLigaturesPropertyValue):
+        (WebCore::fontVariantPositionPropertyValue):
+        (WebCore::fontVariantCapsPropertyValue):
+        (WebCore::fontVariantNumericPropertyValue):
+        (WebCore::fontVariantAlternatesPropertyValue):
+        (WebCore::fontVariantEastAsianPropertyValue):
+        (WebCore::ComputedStyleExtractor::propertyValue):
+        * css/CSSFontFeatureValue.cpp: Update to FontFeatureTag instead of WTF::String.
+        (WebCore::CSSFontFeatureValue::CSSFontFeatureValue):
+        (WebCore::CSSFontFeatureValue::customCSSText):
+        * css/CSSFontFeatureValue.h: Ditto.
+        (WebCore::CSSFontFeatureValue::create):
+        (WebCore::CSSFontFeatureValue::tag):
+        * css/CSSParser.cpp: Parse the new properties according to the CSS3 fonts spec.
+        (WebCore::isValidKeywordPropertyAndValue):
+        (WebCore::isKeywordPropertyID):
+        (WebCore::CSSParser::parseValue):
+        (WebCore::CSSParser::parseFontFeatureTag):
+        (WebCore::CSSParser::parseFontVariantLigatures):
+        (WebCore::CSSParser::parseFontVariantNumeric):
+        (WebCore::CSSParser::parseFontVariantEastAsian):
+        * css/CSSParser.h:
+        * css/CSSPrimitiveValueMappings.h: For the three properties which are simple keyword value
+        properties, implement casting operators to automatically convert between RenderStyle
+        objects and CSS property objects.
+        (WebCore::CSSPrimitiveValue::CSSPrimitiveValue):
+        (WebCore::CSSPrimitiveValue::operator FontVariantPosition):
+        (WebCore::CSSPrimitiveValue::operator FontVariantCaps):
+        (WebCore::CSSPrimitiveValue::operator FontVariantAlternates):
+        * css/CSSPropertyNames.in: New properties.
+        * css/CSSValueKeywords.in: New values.
+        * css/StyleBuilderConverter.h:
+        (WebCore::StyleBuilderConverter::convertFontFeatureSettings): Update to not use
+        RefPtrs.
+        * css/StyleBuilderCustom.h: Properties which are not simple keyword value properties are
+        decomposed into multiple members of FontDescription. These properties exist to convert
+        between these aggregate members and the CSS properties.
+        (WebCore::StyleBuilderCustom::applyInheritFontVariantLigatures):
+        (WebCore::StyleBuilderCustom::applyInitialFontVariantLigatures):
+        (WebCore::StyleBuilderCustom::applyValueFontVariantLigatures):
+        (WebCore::StyleBuilderCustom::applyInheritFontVariantNumeric):
+        (WebCore::StyleBuilderCustom::applyInitialFontVariantNumeric):
+        (WebCore::StyleBuilderCustom::applyValueFontVariantNumeric):
+        (WebCore::StyleBuilderCustom::applyInheritFontVariantEastAsian):
+        (WebCore::StyleBuilderCustom::applyInitialFontVariantEastAsian):
+        (WebCore::StyleBuilderCustom::applyValueFontVariantEastAsian):
+        (WebCore::StyleBuilderCustom::applyInitialWebkitFontVariantLigatures): Deleted.
+        (WebCore::StyleBuilderCustom::applyInheritWebkitFontVariantLigatures): Deleted.
+        (WebCore::StyleBuilderCustom::applyValueWebkitFontVariantLigatures): Deleted.
+        * editing/cocoa/HTMLConverter.mm:
+        (HTMLConverter::computedAttributesForElement): Unprefix font-variant-ligatures.
+        * platform/graphics/FontCache.h: Update cache to be sensitive to new state in
+        FontDescription.
+        (WebCore::FontDescriptionKey::FontDescriptionKey):
+        (WebCore::FontDescriptionKey::operator==):
+        (WebCore::FontDescriptionKey::computeHash):
+        (WebCore::FontDescriptionKey::makeFlagsKey):
+        (WebCore::FontDescriptionKey::makeFlagKey): Deleted.
+        * platform/graphics/FontCascade.cpp:
+        (WebCore::FontCascade::codePath): These new variants should trigger the complex text
+        codepath.
+        * platform/graphics/FontCascade.h:
+        (WebCore::FontCascade::computeTypesettingFeatures): Update to use new state enum.
+        * platform/graphics/FontDescription.cpp: Add state to hold new property values.
+        (WebCore::FontDescription::FontDescription):
+        (WebCore::FontCascadeDescription::FontCascadeDescription): Deleted.
+        * platform/graphics/FontDescription.h: Add state to hold new property values.
+        (WebCore::FontDescription::featureSettings):
+        (WebCore::FontDescription::variantCommonLigatures):
+        (WebCore::FontDescription::variantDiscretionaryLigatures):
+        (WebCore::FontDescription::variantHistoricalLigatures):
+        (WebCore::FontDescription::variantContextualAlternates):
+        (WebCore::FontDescription::variantPosition):
+        (WebCore::FontDescription::variantCaps):
+        (WebCore::FontDescription::variantNumericFigure):
+        (WebCore::FontDescription::variantNumericSpacing):
+        (WebCore::FontDescription::variantNumericFraction):
+        (WebCore::FontDescription::variantNumericOrdinal):
+        (WebCore::FontDescription::variantNumericSlashedZero):
+        (WebCore::FontDescription::variantAlternates):
+        (WebCore::FontDescription::variantEastAsianVariant):
+        (WebCore::FontDescription::variantEastAsianWidth):
+        (WebCore::FontDescription::variantEastAsianRuby):
+        (WebCore::FontDescription::variantSettings):
+        (WebCore::FontDescription::setFeatureSettings):
+        (WebCore::FontDescription::setVariantCommonLigatures):
+        (WebCore::FontDescription::setVariantDiscretionaryLigatures):
+        (WebCore::FontDescription::setVariantHistoricalLigatures):
+        (WebCore::FontDescription::setVariantContextualAlternates):
+        (WebCore::FontDescription::setVariantPosition):
+        (WebCore::FontDescription::setVariantCaps):
+        (WebCore::FontDescription::setVariantNumericFigure):
+        (WebCore::FontDescription::setVariantNumericSpacing):
+        (WebCore::FontDescription::setVariantNumericFraction):
+        (WebCore::FontDescription::setVariantNumericOrdinal):
+        (WebCore::FontDescription::setVariantNumericSlashedZero):
+        (WebCore::FontDescription::setVariantAlternates):
+        (WebCore::FontDescription::setVariantEastAsianVariant):
+        (WebCore::FontDescription::setVariantEastAsianWidth):
+        (WebCore::FontDescription::setVariantEastAsianRuby):
+        (WebCore::FontDescription::operator==):
+        (WebCore::FontCascadeDescription::initialVariantPosition):
+        (WebCore::FontCascadeDescription::initialVariantCaps):
+        (WebCore::FontCascadeDescription::initialVariantAlternates):
+        (WebCore::FontCascadeDescription::commonLigaturesState): Deleted.
+        (WebCore::FontCascadeDescription::discretionaryLigaturesState): Deleted.
+        (WebCore::FontCascadeDescription::historicalLigaturesState): Deleted.
+        (WebCore::FontCascadeDescription::setCommonLigaturesState): Deleted.
+        (WebCore::FontCascadeDescription::setDiscretionaryLigaturesState): Deleted.
+        (WebCore::FontCascadeDescription::setHistoricalLigaturesState): Deleted.
+        (WebCore::FontCascadeDescription::operator==): Deleted.
+        * platform/graphics/FontFeatureSettings.cpp: Update to use FontFeatureTag instead of
+        WTF::String.
+        (WebCore::FontFeature::FontFeature):
+        (WebCore::FontFeature::operator==):
+        (WebCore::FontFeature::operator&lt;):
+        (WebCore::FontFeatureSettings::hash):
+        (WebCore::FontFeatureSettings::create): Deleted.
+        * platform/graphics/FontFeatureSettings.h: Update to use FontFeatureTag instead of
+        WTF::String.
+        (WebCore::fontFeatureTag):
+        (WebCore::FontFeatureTagHash::hash):
+        (WebCore::FontFeatureTagHash::equal):
+        (WebCore::FontFeatureTagHashTraits::constructDeletedValue):
+        (WebCore::FontFeatureTagHashTraits::isDeletedValue):
+        (WebCore::FontFeature::tag):
+        (WebCore::FontFeatureSettings::operator==):
+        (WebCore::FontFeatureSettings::begin):
+        (WebCore::FontFeatureSettings::end):
+        (WebCore::FontFeatureSettings::FontFeatureSettings): Deleted.
+        * platform/graphics/cocoa/FontCacheCoreText.cpp: Ditto. Also, when computing font
+        features, consult with the state inside FontDescription.
+        (WebCore::tagEquals):
+        (WebCore::appendTrueTypeFeature):
+        (WebCore::appendOpenTypeFeature):
+        (WebCore::computeFeatureSettingsFromVariants):
+        (WebCore::preparePlatformFont):
+        (WebCore::platformFontLookupWithFamily):
+        (WebCore::fontWithFamily):
+        (WebCore::FontCache::createFontPlatformData):
+        (WebCore::FontCache::systemFallbackForCharacters):
+        * platform/graphics/harfbuzz/HarfBuzzShaper.cpp: Update to use references instead of
+        pointers.
+        (WebCore::HarfBuzzShaper::setFontFeatures):
+        * platform/graphics/mac/FontCacheMac.mm:
+        (WebCore::platformFontWithFamily): Ditto.
+        * platform/graphics/mac/FontCustomPlatformData.cpp:
+        (WebCore::FontCustomPlatformData::fontPlatformData): Be sensitive to new state inside FontDescription.
+        * platform/text/TextFlags.h:
+        (WebCore::FontVariantSettings::isAllNormal): New state enums.
+        * rendering/RenderThemeIOS.mm:
+        (WebCore::RenderThemeIOS::updateCachedSystemFontDescription): Be sensitive to new state inside
+        FontDescription.
+        * rendering/line/BreakingContext.h:
+
</ins><span class="cx"> 2015-09-23  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, roll out r190085 as it seems to cause crashes in JSC
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSComputedStyleDeclarationcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/css/CSSComputedStyleDeclaration.cpp        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -319,7 +319,12 @@
</span><span class="cx"> #endif
</span><span class="cx">     CSSPropertyWebkitFontKerning,
</span><span class="cx">     CSSPropertyWebkitFontSmoothing,
</span><del>-    CSSPropertyWebkitFontVariantLigatures,
</del><ins>+    CSSPropertyFontVariantLigatures,
+    CSSPropertyFontVariantPosition,
+    CSSPropertyFontVariantCaps,
+    CSSPropertyFontVariantNumeric,
+    CSSPropertyFontVariantAlternates,
+    CSSPropertyFontVariantEastAsian,
</ins><span class="cx"> #if ENABLE(CSS_GRID_LAYOUT)
</span><span class="cx">     CSSPropertyWebkitGridAutoColumns,
</span><span class="cx">     CSSPropertyWebkitGridAutoFlow,
</span><span class="lines">@@ -1197,6 +1202,192 @@
</span><span class="cx">     return WTF::move(list);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline void appendLigaturesValue(CSSValueList&amp; list, FontVariantLigatures value, CSSValueID yesValue, CSSValueID noValue)
+{
+    switch (value) {
+    case FontVariantLigatures::Normal:
+        return;
+    case FontVariantLigatures::No:
+        list.append(CSSValuePool::singleton().createIdentifierValue(noValue));
+        return;
+    case FontVariantLigatures::Yes:
+        list.append(CSSValuePool::singleton().createIdentifierValue(yesValue));
+        return;
+    }
+    ASSERT_NOT_REACHED();
+}
+
+static Ref&lt;CSSValue&gt; fontVariantLigaturesPropertyValue(FontVariantLigatures common, FontVariantLigatures discretionary, FontVariantLigatures historical, FontVariantLigatures contextualAlternates)
+{
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    if (common == FontVariantLigatures::No &amp;&amp; discretionary == FontVariantLigatures::No &amp;&amp; historical == FontVariantLigatures::No &amp;&amp; contextualAlternates == FontVariantLigatures::No)
+        return cssValuePool.createIdentifierValue(CSSValueNone);
+    if (common == FontVariantLigatures::Normal &amp;&amp; discretionary == FontVariantLigatures::Normal &amp;&amp; historical == FontVariantLigatures::Normal &amp;&amp; contextualAlternates == FontVariantLigatures::Normal)
+        return cssValuePool.createIdentifierValue(CSSValueNormal);
+
+    auto valueList = CSSValueList::createSpaceSeparated();
+    appendLigaturesValue(valueList, common, CSSValueCommonLigatures, CSSValueNoCommonLigatures);
+    appendLigaturesValue(valueList, discretionary, CSSValueDiscretionaryLigatures, CSSValueNoDiscretionaryLigatures);
+    appendLigaturesValue(valueList, historical, CSSValueHistoricalLigatures, CSSValueNoHistoricalLigatures);
+    appendLigaturesValue(valueList, contextualAlternates, CSSValueContextual, CSSValueNoContextual);
+    return WTF::move(valueList);
+}
+
+static Ref&lt;CSSValue&gt; fontVariantPositionPropertyValue(FontVariantPosition position)
+{
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    CSSValueID valueID = CSSValueNormal;
+    switch (position) {
+    case FontVariantPosition::Normal:
+        break;
+    case FontVariantPosition::Subscript:
+        valueID = CSSValueSub;
+        break;
+    case FontVariantPosition::Superscript:
+        valueID = CSSValueSuper;
+        break;
+    }
+    return cssValuePool.createIdentifierValue(valueID);
+}
+
+static Ref&lt;CSSValue&gt; fontVariantCapsPropertyValue(FontVariantCaps caps)
+{
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    CSSValueID valueID = CSSValueNormal;
+    switch (caps) {
+    case FontVariantCaps::Normal:
+        break;
+    case FontVariantCaps::Small:
+        valueID = CSSValueSmallCaps;
+        break;
+    case FontVariantCaps::AllSmall:
+        valueID = CSSValueAllSmallCaps;
+        break;
+    case FontVariantCaps::Petite:
+        valueID = CSSValuePetiteCaps;
+        break;
+    case FontVariantCaps::AllPetite:
+        valueID = CSSValueAllPetiteCaps;
+        break;
+    case FontVariantCaps::Unicase:
+        valueID = CSSValueUnicase;
+        break;
+    case FontVariantCaps::Titling:
+        valueID = CSSValueTitlingCaps;
+        break;
+    }
+    return cssValuePool.createIdentifierValue(valueID);
+}
+
+static Ref&lt;CSSValue&gt; fontVariantNumericPropertyValue(FontVariantNumericFigure figure, FontVariantNumericSpacing spacing, FontVariantNumericFraction fraction, FontVariantNumericOrdinal ordinal, FontVariantNumericSlashedZero slashedZero)
+{
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    if (figure == FontVariantNumericFigure::Normal &amp;&amp; spacing == FontVariantNumericSpacing::Normal &amp;&amp; fraction == FontVariantNumericFraction::Normal &amp;&amp; ordinal == FontVariantNumericOrdinal::Normal &amp;&amp; slashedZero == FontVariantNumericSlashedZero::Normal)
+        return cssValuePool.createIdentifierValue(CSSValueNormal);
+
+    auto valueList = CSSValueList::createSpaceSeparated();
+    switch (figure) {
+    case FontVariantNumericFigure::Normal:
+        break;
+    case FontVariantNumericFigure::LiningNumbers:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueLiningNums));
+        break;
+    case FontVariantNumericFigure::OldStyleNumbers:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueOldstyleNums));
+        break;
+    }
+
+    switch (spacing) {
+    case FontVariantNumericSpacing::Normal:
+        break;
+    case FontVariantNumericSpacing::ProportionalNumbers:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueProportionalNums));
+        break;
+    case FontVariantNumericSpacing::TabularNumbers:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueTabularNums));
+        break;
+    }
+
+    switch (fraction) {
+    case FontVariantNumericFraction::Normal:
+        break;
+    case FontVariantNumericFraction::DiagonalFractions:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueDiagonalFractions));
+        break;
+    case FontVariantNumericFraction::StackedFractions:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueStackedFractions));
+        break;
+    }
+
+    if (ordinal == FontVariantNumericOrdinal::Yes)
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueOrdinal));
+    if (slashedZero == FontVariantNumericSlashedZero::Yes)
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueSlashedZero));
+
+    return WTF::move(valueList);
+}
+
+static Ref&lt;CSSValue&gt; fontVariantAlternatesPropertyValue(FontVariantAlternates alternates)
+{
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    CSSValueID valueID = CSSValueNormal;
+    switch (alternates) {
+    case FontVariantAlternates::Normal:
+        break;
+    case FontVariantAlternates::HistoricalForms:
+        valueID = CSSValueHistoricalForms;
+        break;
+    }
+    return cssValuePool.createIdentifierValue(valueID);
+}
+
+static Ref&lt;CSSValue&gt; fontVariantEastAsianPropertyValue(FontVariantEastAsianVariant variant, FontVariantEastAsianWidth width, FontVariantEastAsianRuby ruby)
+{
+    auto&amp; cssValuePool = CSSValuePool::singleton();
+    if (variant == FontVariantEastAsianVariant::Normal &amp;&amp; width == FontVariantEastAsianWidth::Normal &amp;&amp; ruby == FontVariantEastAsianRuby::Normal)
+        return cssValuePool.createIdentifierValue(CSSValueNormal);
+
+    auto valueList = CSSValueList::createSpaceSeparated();
+    switch (variant) {
+    case FontVariantEastAsianVariant::Normal:
+        break;
+    case FontVariantEastAsianVariant::Jis78:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueJis78));
+        break;
+    case FontVariantEastAsianVariant::Jis83:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueJis83));
+        break;
+    case FontVariantEastAsianVariant::Jis90:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueJis90));
+        break;
+    case FontVariantEastAsianVariant::Jis04:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueJis04));
+        break;
+    case FontVariantEastAsianVariant::Simplified:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueSimplified));
+        break;
+    case FontVariantEastAsianVariant::Traditional:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueTraditional));
+        break;
+    }
+
+    switch (width) {
+    case FontVariantEastAsianWidth::Normal:
+        break;
+    case FontVariantEastAsianWidth::FullWidth:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueFullWidth));
+        break;
+    case FontVariantEastAsianWidth::ProportionalWidth:
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueProportionalWidth));
+        break;
+    }
+
+    if (ruby == FontVariantEastAsianRuby::Yes)
+        valueList-&gt;append(cssValuePool.createIdentifierValue(CSSValueRuby));
+
+    return WTF::move(valueList);
+}
+
</ins><span class="cx"> static Ref&lt;CSSValueList&gt; getDelayValue(const AnimationList* animList)
</span><span class="cx"> {
</span><span class="cx">     auto&amp; cssValuePool = CSSValuePool::singleton();
</span><span class="lines">@@ -2320,14 +2511,12 @@
</span><span class="cx">         case CSSPropertyFontSynthesis:
</span><span class="cx">             return fontSynthesisFromStyle(*style);
</span><span class="cx">         case CSSPropertyWebkitFontFeatureSettings: {
</span><del>-            const FontFeatureSettings* featureSettings = style-&gt;fontDescription().featureSettings();
-            if (!featureSettings || !featureSettings-&gt;size())
</del><ins>+            const FontFeatureSettings&amp; featureSettings = style-&gt;fontDescription().featureSettings();
+            if (!featureSettings.size())
</ins><span class="cx">                 return cssValuePool.createIdentifierValue(CSSValueNormal);
</span><span class="cx">             RefPtr&lt;CSSValueList&gt; list = CSSValueList::createCommaSeparated();
</span><del>-            for (unsigned i = 0; i &lt; featureSettings-&gt;size(); ++i) {
-                const FontFeature&amp; feature = featureSettings-&gt;at(i);
-                list-&gt;append(CSSFontFeatureValue::create(feature.tag(), feature.value()));
-            }
</del><ins>+            for (auto&amp; feature : featureSettings)
+                list-&gt;append(CSSFontFeatureValue::create(FontFeatureTag(feature.tag()), feature.value()));
</ins><span class="cx">             return list;
</span><span class="cx">         }
</span><span class="cx"> #if ENABLE(CSS_GRID_LAYOUT)
</span><span class="lines">@@ -2723,23 +2912,18 @@
</span><span class="cx">             return cssValuePool.createValue(style-&gt;fontDescription().kerning());
</span><span class="cx">         case CSSPropertyWebkitFontSmoothing:
</span><span class="cx">             return cssValuePool.createValue(style-&gt;fontDescription().fontSmoothing());
</span><del>-        case CSSPropertyWebkitFontVariantLigatures: {
-            auto commonLigaturesState = style-&gt;fontDescription().commonLigaturesState();
-            auto discretionaryLigaturesState = style-&gt;fontDescription().discretionaryLigaturesState();
-            auto historicalLigaturesState = style-&gt;fontDescription().historicalLigaturesState();
-            if (commonLigaturesState == FontCascadeDescription::NormalLigaturesState &amp;&amp; discretionaryLigaturesState == FontCascadeDescription::NormalLigaturesState
-                &amp;&amp; historicalLigaturesState == FontCascadeDescription::NormalLigaturesState)
-                return cssValuePool.createIdentifierValue(CSSValueNormal);
-
-            RefPtr&lt;CSSValueList&gt; valueList = CSSValueList::createSpaceSeparated();
-            if (commonLigaturesState != FontCascadeDescription::NormalLigaturesState)
-                valueList-&gt;append(cssValuePool.createIdentifierValue(commonLigaturesState == FontCascadeDescription::DisabledLigaturesState ? CSSValueNoCommonLigatures : CSSValueCommonLigatures));
-            if (discretionaryLigaturesState != FontCascadeDescription::NormalLigaturesState)
-                valueList-&gt;append(cssValuePool.createIdentifierValue(discretionaryLigaturesState == FontCascadeDescription::DisabledLigaturesState ? CSSValueNoDiscretionaryLigatures : CSSValueDiscretionaryLigatures));
-            if (historicalLigaturesState != FontCascadeDescription::NormalLigaturesState)
-                valueList-&gt;append(cssValuePool.createIdentifierValue(historicalLigaturesState == FontCascadeDescription::DisabledLigaturesState ? CSSValueNoHistoricalLigatures : CSSValueHistoricalLigatures));
-            return valueList;
-        }
</del><ins>+        case CSSPropertyFontVariantLigatures:
+            return fontVariantLigaturesPropertyValue(style-&gt;fontDescription().variantCommonLigatures(), style-&gt;fontDescription().variantDiscretionaryLigatures(), style-&gt;fontDescription().variantHistoricalLigatures(), style-&gt;fontDescription().variantContextualAlternates());
+        case CSSPropertyFontVariantPosition:
+            return fontVariantPositionPropertyValue(style-&gt;fontDescription().variantPosition());
+        case CSSPropertyFontVariantCaps:
+            return fontVariantCapsPropertyValue(style-&gt;fontDescription().variantCaps());
+        case CSSPropertyFontVariantNumeric:
+            return fontVariantNumericPropertyValue(style-&gt;fontDescription().variantNumericFigure(), style-&gt;fontDescription().variantNumericSpacing(), style-&gt;fontDescription().variantNumericFraction(), style-&gt;fontDescription().variantNumericOrdinal(), style-&gt;fontDescription().variantNumericSlashedZero());
+        case CSSPropertyFontVariantAlternates:
+            return fontVariantAlternatesPropertyValue(style-&gt;fontDescription().variantAlternates());
+        case CSSPropertyFontVariantEastAsian:
+            return fontVariantEastAsianPropertyValue(style-&gt;fontDescription().variantEastAsianVariant(), style-&gt;fontDescription().variantEastAsianWidth(), style-&gt;fontDescription().variantEastAsianRuby());
</ins><span class="cx">         case CSSPropertyZIndex:
</span><span class="cx">             if (style-&gt;hasAutoZIndex())
</span><span class="cx">                 return cssValuePool.createIdentifierValue(CSSValueAuto);
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSFontFeatureValuecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSFontFeatureValue.cpp (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontFeatureValue.cpp        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/css/CSSFontFeatureValue.cpp        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -32,9 +32,9 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-CSSFontFeatureValue::CSSFontFeatureValue(const String&amp; tag, int value)
</del><ins>+CSSFontFeatureValue::CSSFontFeatureValue(FontFeatureTag&amp;&amp; tag, int value)
</ins><span class="cx">     : CSSValue(FontFeatureClass)
</span><del>-    , m_tag(tag)
</del><ins>+    , m_tag(WTF::move(tag))
</ins><span class="cx">     , m_value(value)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="lines">@@ -43,7 +43,8 @@
</span><span class="cx"> {
</span><span class="cx">     StringBuilder builder;
</span><span class="cx">     builder.append('\'');
</span><del>-    builder.append(m_tag);
</del><ins>+    for (char c : m_tag)
+        builder.append(c);
</ins><span class="cx">     builder.appendLiteral(&quot;' &quot;);
</span><span class="cx">     builder.appendNumber(m_value);
</span><span class="cx">     return builder.toString();
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSFontFeatureValueh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSFontFeatureValue.h (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSFontFeatureValue.h        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/css/CSSFontFeatureValue.h        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -27,27 +27,27 @@
</span><span class="cx"> #define CSSFontFeatureValue_h
</span><span class="cx"> 
</span><span class="cx"> #include &quot;CSSValue.h&quot;
</span><del>-#include &lt;wtf/text/WTFString.h&gt;
</del><ins>+#include &quot;FontFeatureSettings.h&quot;
</ins><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> class CSSFontFeatureValue : public CSSValue {
</span><span class="cx"> public:
</span><del>-    static Ref&lt;CSSFontFeatureValue&gt; create(const String&amp; tag, int value)
</del><ins>+    static Ref&lt;CSSFontFeatureValue&gt; create(FontFeatureTag&amp;&amp; tag, int value)
</ins><span class="cx">     {
</span><del>-        return adoptRef(*new CSSFontFeatureValue(tag, value));
</del><ins>+        return adoptRef(*new CSSFontFeatureValue(WTF::move(tag), value));
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    const String&amp; tag() const { return m_tag; }
</del><ins>+    const FontFeatureTag&amp; tag() const { return m_tag; }
</ins><span class="cx">     int value() const { return m_value; }
</span><span class="cx">     String customCSSText() const;
</span><span class="cx"> 
</span><span class="cx">     bool equals(const CSSFontFeatureValue&amp;) const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    CSSFontFeatureValue(const String&amp;, int);
</del><ins>+    CSSFontFeatureValue(FontFeatureTag&amp;&amp;, int);
</ins><span class="cx"> 
</span><del>-    String m_tag;
</del><ins>+    FontFeatureTag m_tag;
</ins><span class="cx">     const int m_value;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSParsercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSParser.cpp (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParser.cpp        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/css/CSSParser.cpp        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -1036,6 +1036,18 @@
</span><span class="cx">             return true;
</span><span class="cx">         break;
</span><span class="cx"> #endif
</span><ins>+    case CSSPropertyFontVariantPosition: // normal | sub | super
+        if (valueID == CSSValueNormal || valueID == CSSValueSub || valueID == CSSValueSuper)
+            return true;
+        break;
+    case CSSPropertyFontVariantCaps: // normal | small-caps | all-small-caps | petite-caps | all-petite-caps | unicase | titling-caps
+        if (valueID == CSSValueNormal || valueID == CSSValueSmallCaps || valueID == CSSValueAllSmallCaps || valueID == CSSValuePetiteCaps || valueID == CSSValueAllPetiteCaps || valueID == CSSValueUnicase || valueID == CSSValueTitlingCaps)
+            return true;
+        break;
+    case CSSPropertyFontVariantAlternates: // We only support the normal and historical-forms values.
+        if (valueID == CSSValueNormal || valueID == CSSValueHistoricalForms)
+            return true;
+        break;
</ins><span class="cx">     default:
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">         return false;
</span><span class="lines">@@ -1162,6 +1174,9 @@
</span><span class="cx"> #if ENABLE(CSS_TRAILING_WORD)
</span><span class="cx">     case CSSPropertyAppleTrailingWord:
</span><span class="cx"> #endif
</span><ins>+    case CSSPropertyFontVariantPosition:
+    case CSSPropertyFontVariantCaps:
+    case CSSPropertyFontVariantAlternates:
</ins><span class="cx">         return true;
</span><span class="cx">     default:
</span><span class="cx">         return false;
</span><span class="lines">@@ -3015,13 +3030,25 @@
</span><span class="cx">         else
</span><span class="cx">             return parseFontFeatureSettings(important);
</span><span class="cx">         break;
</span><del>-
-    case CSSPropertyWebkitFontVariantLigatures:
-        if (id == CSSValueNormal)
</del><ins>+    case CSSPropertyFontVariantLigatures:
+        if (id == CSSValueNormal || id == CSSValueNone)
</ins><span class="cx">             validPrimitive = true;
</span><span class="cx">         else
</span><span class="cx">             return parseFontVariantLigatures(important);
</span><span class="cx">         break;
</span><ins>+    case CSSPropertyFontVariantNumeric:
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            return parseFontVariantNumeric(important);
+        break;
+    case CSSPropertyFontVariantEastAsian:
+        if (id == CSSValueNormal)
+            validPrimitive = true;
+        else
+            return parseFontVariantEastAsian(important);
+        break;
+
</ins><span class="cx">     case CSSPropertyWebkitClipPath:
</span><span class="cx">         parsedValue = parseClipPath();
</span><span class="cx">         break;
</span><span class="lines">@@ -10382,23 +10409,21 @@
</span><span class="cx"> 
</span><span class="cx"> bool CSSParser::parseFontFeatureTag(CSSValueList&amp; settings)
</span><span class="cx"> {
</span><del>-    // Feature tag name consists of 4-letter characters.
-    static const unsigned tagNameLength = 4;
-
</del><span class="cx">     CSSParserValue* value = m_valueList-&gt;current();
</span><span class="cx">     // Feature tag name comes first
</span><span class="cx">     if (value-&gt;unit != CSSPrimitiveValue::CSS_STRING)
</span><span class="cx">         return false;
</span><del>-    if (value-&gt;string.length() != tagNameLength)
</del><ins>+    FontFeatureTag tag;
+    if (value-&gt;string.length() != tag.size())
</ins><span class="cx">         return false;
</span><del>-    for (unsigned i = 0; i &lt; tagNameLength; ++i) {
</del><ins>+    for (unsigned i = 0; i &lt; tag.size(); ++i) {
</ins><span class="cx">         // Limits the range of characters to 0x20-0x7E, following the tag name rules defiend in the OpenType specification.
</span><span class="cx">         UChar character = value-&gt;string[i];
</span><span class="cx">         if (character &lt; 0x20 || character &gt; 0x7E)
</span><span class="cx">             return false;
</span><ins>+        tag[i] = toASCIILower(character);
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    String tag = String(value-&gt;string).convertToASCIILowercase();
</del><span class="cx">     int tagValue = 1;
</span><span class="cx">     // Feature tag values could follow: &lt;integer&gt; | on | off
</span><span class="cx">     value = m_valueList-&gt;next();
</span><span class="lines">@@ -10413,7 +10438,7 @@
</span><span class="cx">             m_valueList-&gt;next();
</span><span class="cx">         }
</span><span class="cx">     }
</span><del>-    settings.append(CSSFontFeatureValue::create(tag, tagValue));
</del><ins>+    settings.append(CSSFontFeatureValue::create(WTF::move(tag), tagValue));
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -10445,10 +10470,11 @@
</span><span class="cx"> 
</span><span class="cx"> bool CSSParser::parseFontVariantLigatures(bool important)
</span><span class="cx"> {
</span><del>-    RefPtr&lt;CSSValueList&gt; ligatureValues = CSSValueList::createSpaceSeparated();
-    bool sawCommonLigaturesValue = false;
-    bool sawDiscretionaryLigaturesValue = false;
-    bool sawHistoricalLigaturesValue = false;
</del><ins>+    auto values = CSSValueList::createSpaceSeparated();
+    bool sawCommonValue = false;
+    bool sawDiscretionaryValue = false;
+    bool sawHistoricalValue = false;
+    bool sawContextualValue = false;
</ins><span class="cx"> 
</span><span class="cx">     for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
</span><span class="cx">         if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
</span><span class="lines">@@ -10457,37 +10483,151 @@
</span><span class="cx">         switch (value-&gt;id) {
</span><span class="cx">         case CSSValueNoCommonLigatures:
</span><span class="cx">         case CSSValueCommonLigatures:
</span><del>-            if (sawCommonLigaturesValue)
</del><ins>+            if (sawCommonValue)
</ins><span class="cx">                 return false;
</span><del>-            sawCommonLigaturesValue = true;
-            ligatureValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
</del><ins>+            sawCommonValue = true;
+            values-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
</ins><span class="cx">             break;
</span><span class="cx">         case CSSValueNoDiscretionaryLigatures:
</span><span class="cx">         case CSSValueDiscretionaryLigatures:
</span><del>-            if (sawDiscretionaryLigaturesValue)
</del><ins>+            if (sawDiscretionaryValue)
</ins><span class="cx">                 return false;
</span><del>-            sawDiscretionaryLigaturesValue = true;
-            ligatureValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
</del><ins>+            sawDiscretionaryValue = true;
+            values-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
</ins><span class="cx">             break;
</span><span class="cx">         case CSSValueNoHistoricalLigatures:
</span><span class="cx">         case CSSValueHistoricalLigatures:
</span><del>-            if (sawHistoricalLigaturesValue)
</del><ins>+            if (sawHistoricalValue)
</ins><span class="cx">                 return false;
</span><del>-            sawHistoricalLigaturesValue = true;
-            ligatureValues-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
</del><ins>+            sawHistoricalValue = true;
+            values-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
</ins><span class="cx">             break;
</span><ins>+        case CSSValueContextual:
+        case CSSValueNoContextual:
+            if (sawContextualValue)
+                return false;
+            sawContextualValue = true;
+            values-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            break;
</ins><span class="cx">         default:
</span><span class="cx">             return false;
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    if (!ligatureValues-&gt;length())
</del><ins>+    if (!values-&gt;length())
</ins><span class="cx">         return false;
</span><span class="cx"> 
</span><del>-    addProperty(CSSPropertyWebkitFontVariantLigatures, ligatureValues.release(), important);
</del><ins>+    addProperty(CSSPropertyFontVariantLigatures, WTF::move(values), important);
</ins><span class="cx">     return true;
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+bool CSSParser::parseFontVariantNumeric(bool important)
+{
+    auto values = CSSValueList::createSpaceSeparated();
+    bool sawFigureValue = false;
+    bool sawSpacingValue = false;
+    bool sawFractionValue = false;
+    bool sawOrdinal = false;
+    bool sawSlashedZero = false;
+
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+            return false;
+
+        switch (value-&gt;id) {
+        case CSSValueLiningNums:
+        case CSSValueOldstyleNums:
+            if (sawFigureValue)
+                return false;
+            sawFigureValue = true;
+            values-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            break;
+        case CSSValueProportionalNums:
+        case CSSValueTabularNums:
+            if (sawSpacingValue)
+                return false;
+            sawSpacingValue = true;
+            values-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            break;
+        case CSSValueDiagonalFractions:
+        case CSSValueStackedFractions:
+            if (sawFractionValue)
+                return false;
+            sawFractionValue = true;
+            values-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            break;
+        case CSSValueOrdinal:
+            if (sawOrdinal)
+                return false;
+            sawOrdinal = true;
+            values-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            break;
+        case CSSValueSlashedZero:
+            if (sawSlashedZero)
+                return false;
+            sawSlashedZero = true;
+            values-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            break;
+        default:
+            return false;
+        }
+    }
+
+    if (!values-&gt;length())
+        return false;
+
+    addProperty(CSSPropertyFontVariantNumeric, WTF::move(values), important);
+    return true;
+}
+
+bool CSSParser::parseFontVariantEastAsian(bool important)
+{
+    auto values = CSSValueList::createSpaceSeparated();
+    bool sawVariantValue = false;
+    bool sawWidthValue = false;
+    bool sawRuby = false;
+
+    for (CSSParserValue* value = m_valueList-&gt;current(); value; value = m_valueList-&gt;next()) {
+        if (value-&gt;unit != CSSPrimitiveValue::CSS_IDENT)
+            return false;
+
+        switch (value-&gt;id) {
+        case CSSValueJis78:
+        case CSSValueJis83:
+        case CSSValueJis90:
+        case CSSValueJis04:
+        case CSSValueSimplified:
+        case CSSValueTraditional:
+            if (sawVariantValue)
+                return false;
+            sawVariantValue = true;
+            values-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            break;
+        case CSSValueFullWidth:
+        case CSSValueProportionalWidth:
+            if (sawWidthValue)
+                return false;
+            sawWidthValue = true;
+            values-&gt;append(CSSValuePool::singleton().createIdentifierValue(value-&gt;id));
+            break;
+        case CSSValueRuby:
+            sawRuby = true;
+            break;
+        default:
+            return false;
+        }
+    }
+
+    if (sawRuby)
+        values-&gt;append(CSSValuePool::singleton().createIdentifierValue(CSSValueRuby));
+
+    if (!values-&gt;length())
+        return false;
+
+    addProperty(CSSPropertyFontVariantEastAsian, WTF::move(values), important);
+    return true;
+}
+
</ins><span class="cx"> static inline bool isValidWillChangeAnimatableFeature(const CSSParserValue&amp; value)
</span><span class="cx"> {
</span><span class="cx">     if (value.id == CSSValueNone || value.id == CSSValueAuto || value.id == CSSValueAll)
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSParserh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSParser.h (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSParser.h        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/css/CSSParser.h        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -344,6 +344,8 @@
</span><span class="cx">     bool parseRegionThread(CSSPropertyID, bool important);
</span><span class="cx"> 
</span><span class="cx">     bool parseFontVariantLigatures(bool important);
</span><ins>+    bool parseFontVariantNumeric(bool important);
+    bool parseFontVariantEastAsian(bool important);
</ins><span class="cx"> 
</span><span class="cx">     bool parseWillChange(bool important);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSPrimitiveValueMappingsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/css/CSSPrimitiveValueMappings.h        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -5322,6 +5322,131 @@
</span><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><ins>+template&lt;&gt; inline CSSPrimitiveValue::CSSPrimitiveValue(FontVariantPosition position)
+    : CSSValue(PrimitiveClass)
+{
+    m_primitiveUnitType = CSS_VALUE_ID;
+    switch (position) {
+    case FontVariantPosition::Normal:
+        m_value.valueID = CSSValueNormal;
+        break;
+    case FontVariantPosition::Subscript:
+        m_value.valueID = CSSValueSub;
+        break;
+    case FontVariantPosition::Superscript:
+        m_value.valueID = CSSValueSuper;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
</ins><span class="cx"> }
</span><span class="cx"> 
</span><ins>+template&lt;&gt; inline CSSPrimitiveValue::operator FontVariantPosition() const
+{
+    ASSERT(isValueID());
+    switch (m_value.valueID) {
+    case CSSValueNormal:
+        return FontVariantPosition::Normal;
+    case CSSValueSub:
+        return FontVariantPosition::Subscript;
+    case CSSValueSuper:
+        return FontVariantPosition::Superscript;
+    default:
+        break;
+    }
+    ASSERT_NOT_REACHED();
+    return FontVariantPosition::Normal;
+}
+
+template&lt;&gt; inline CSSPrimitiveValue::CSSPrimitiveValue(FontVariantCaps caps)
+    : CSSValue(PrimitiveClass)
+{
+    m_primitiveUnitType = CSS_VALUE_ID;
+    switch (caps) {
+    case FontVariantCaps::Normal:
+        m_value.valueID = CSSValueNormal;
+        break;
+    case FontVariantCaps::Small:
+        m_value.valueID = CSSValueSmallCaps;
+        break;
+    case FontVariantCaps::AllSmall:
+        m_value.valueID = CSSValueAllSmallCaps;
+        break;
+    case FontVariantCaps::Petite:
+        m_value.valueID = CSSValuePetiteCaps;
+        break;
+    case FontVariantCaps::AllPetite:
+        m_value.valueID = CSSValueAllPetiteCaps;
+        break;
+    case FontVariantCaps::Unicase:
+        m_value.valueID = CSSValueUnicase;
+        break;
+    case FontVariantCaps::Titling:
+        m_value.valueID = CSSValueTitlingCaps;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+}
+
+template&lt;&gt; inline CSSPrimitiveValue::operator FontVariantCaps() const
+{
+    ASSERT(isValueID());
+    switch (m_value.valueID) {
+    case CSSValueNormal:
+        return FontVariantCaps::Normal;
+    case CSSValueSmallCaps:
+        return FontVariantCaps::Small;
+    case CSSValueAllSmallCaps:
+        return FontVariantCaps::AllSmall;
+    case CSSValuePetiteCaps:
+        return FontVariantCaps::Petite;
+    case CSSValueAllPetiteCaps:
+        return FontVariantCaps::AllPetite;
+    case CSSValueUnicase:
+        return FontVariantCaps::Unicase;
+    case CSSValueTitlingCaps:
+        return FontVariantCaps::Titling;
+    default:
+        break;
+    }
+    ASSERT_NOT_REACHED();
+    return FontVariantCaps::Normal;
+}
+
+template&lt;&gt; inline CSSPrimitiveValue::CSSPrimitiveValue(FontVariantAlternates alternates)
+    : CSSValue(PrimitiveClass)
+{
+    m_primitiveUnitType = CSS_VALUE_ID;
+    switch (alternates) {
+    case FontVariantAlternates::Normal:
+        m_value.valueID = CSSValueNormal;
+        break;
+    case FontVariantAlternates::HistoricalForms:
+        m_value.valueID = CSSValueHistoricalForms;
+        break;
+    default:
+        ASSERT_NOT_REACHED();
+        break;
+    }
+}
+
+template&lt;&gt; inline CSSPrimitiveValue::operator FontVariantAlternates() const
+{
+    ASSERT(isValueID());
+    switch (m_value.valueID) {
+    case CSSValueNormal:
+        return FontVariantAlternates::Normal;
+    case CSSValueHistoricalForms:
+        return FontVariantAlternates::HistoricalForms;
+    default:
+        break;
+    }
+    ASSERT_NOT_REACHED();
+    return FontVariantAlternates::Normal;
+}
+}
+
</ins><span class="cx"> #endif
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSPropertyNamesin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSPropertyNames.in (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSPropertyNames.in        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/css/CSSPropertyNames.in        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -108,7 +108,12 @@
</span><span class="cx"> -webkit-font-feature-settings [Inherited, FontProperty, Custom=Initial|Inherit, Converter=FontFeatureSettings, NameForMethods=FeatureSettings]
</span><span class="cx"> -webkit-font-kerning [Inherited, FontProperty, NameForMethods=Kerning]
</span><span class="cx"> -webkit-font-smoothing [Inherited, FontProperty]
</span><del>--webkit-font-variant-ligatures [Inherited, Custom=All]
</del><ins>+font-variant-ligatures [Inherited, FontProperty, NameForMethods=VariantLigatures, Custom=All]
+font-variant-position [Inherited, FontProperty, NameForMethods=VariantPosition]
+font-variant-caps [Inherited, FontProperty, NameForMethods=VariantCaps]
+font-variant-numeric [Inherited, FontProperty, NameForMethods=VariantNumeric, Custom=All]
+font-variant-alternates [Inherited, FontProperty, NameForMethods=VariantAlternates]
+font-variant-east-asian [Inherited, FontProperty, NameForMethods=VariantEastAsian, Custom=All]
</ins><span class="cx"> -webkit-locale [Inherited, FontProperty, Custom=Value]
</span><span class="cx"> -webkit-text-orientation [Inherited, Custom=Value]
</span><span class="cx"> -epub-text-orientation = -webkit-text-orientation
</span></span></pre></div>
<a id="trunkSourceWebCorecssCSSValueKeywordsin"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/CSSValueKeywords.in (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/CSSValueKeywords.in        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/css/CSSValueKeywords.in        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -67,17 +67,55 @@
</span><span class="cx"> //normal
</span><span class="cx"> small-caps
</span><span class="cx"> 
</span><del>-// -webkit-font-variant-ligatures:
</del><ins>+// font-variant-ligatures:
</ins><span class="cx"> //
</span><del>-// normal
</del><span class="cx"> common-ligatures
</span><span class="cx"> no-common-ligatures
</span><span class="cx"> discretionary-ligatures
</span><span class="cx"> no-discretionary-ligatures
</span><span class="cx"> historical-ligatures
</span><span class="cx"> no-historical-ligatures
</span><ins>+contextual
+no-contextual
</ins><span class="cx"> 
</span><ins>+// font-variant-caps
</ins><span class="cx"> //
</span><ins>+// FIXME: Unify this with plain font-variant
+// small-caps
+all-small-caps
+petite-caps
+all-petite-caps
+unicase
+titling-caps
+
+// font-variant-numeric
+//
+lining-nums
+oldstyle-nums
+proportional-nums
+tabular-nums
+diagonal-fractions
+stacked-fractions
+ordinal
+slashed-zero
+
+// font-variant-alternates
+//
+historical-forms
+
+// font-variant-east-asian
+//
+jis78
+jis83
+jis90
+jis04
+simplified
+traditional
+full-width
+proportional-width
+ruby
+
+//
</ins><span class="cx"> // CSS_PROP_FONT_WEIGHT:
</span><span class="cx"> //
</span><span class="cx"> normal
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleBuilderConverterh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleBuilderConverter.h (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleBuilderConverter.h        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/css/StyleBuilderConverter.h        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -112,7 +112,7 @@
</span><span class="cx"> #if ENABLE(ACCELERATED_OVERFLOW_SCROLLING)
</span><span class="cx">     static bool convertOverflowScrolling(StyleResolver&amp;, CSSValue&amp;);
</span><span class="cx"> #endif
</span><del>-    static RefPtr&lt;FontFeatureSettings&gt; convertFontFeatureSettings(StyleResolver&amp;, CSSValue&amp;);
</del><ins>+    static FontFeatureSettings convertFontFeatureSettings(StyleResolver&amp;, CSSValue&amp;);
</ins><span class="cx">     static SVGLength convertSVGLength(StyleResolver&amp;, CSSValue&amp;);
</span><span class="cx">     static Vector&lt;SVGLength&gt; convertSVGLengthVector(StyleResolver&amp;, CSSValue&amp;);
</span><span class="cx">     static Vector&lt;SVGLength&gt; convertStrokeDashArray(StyleResolver&amp;, CSSValue&amp;);
</span><span class="lines">@@ -1004,19 +1004,19 @@
</span><span class="cx">     return Nullopt;
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline RefPtr&lt;FontFeatureSettings&gt; StyleBuilderConverter::convertFontFeatureSettings(StyleResolver&amp;, CSSValue&amp; value)
</del><ins>+inline FontFeatureSettings StyleBuilderConverter::convertFontFeatureSettings(StyleResolver&amp;, CSSValue&amp; value)
</ins><span class="cx"> {
</span><span class="cx">     if (is&lt;CSSPrimitiveValue&gt;(value)) {
</span><span class="cx">         ASSERT(downcast&lt;CSSPrimitiveValue&gt;(value).getValueID() == CSSValueNormal);
</span><del>-        return nullptr;
</del><ins>+        return { };
</ins><span class="cx">     }
</span><span class="cx"> 
</span><del>-    RefPtr&lt;FontFeatureSettings&gt; settings = FontFeatureSettings::create();
</del><ins>+    FontFeatureSettings settings;
</ins><span class="cx">     for (auto&amp; item : downcast&lt;CSSValueList&gt;(value)) {
</span><span class="cx">         auto&amp; feature = downcast&lt;CSSFontFeatureValue&gt;(item.get());
</span><del>-        settings-&gt;insert(FontFeature(feature.tag(), feature.value()));
</del><ins>+        settings.insert(FontFeature(feature.tag(), feature.value()));
</ins><span class="cx">     }
</span><del>-    return WTF::move(settings);
</del><ins>+    return settings;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if PLATFORM(IOS)
</span></span></pre></div>
<a id="trunkSourceWebCorecssStyleBuilderCustomh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/css/StyleBuilderCustom.h (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/css/StyleBuilderCustom.h        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/css/StyleBuilderCustom.h        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -89,7 +89,9 @@
</span><span class="cx">     DECLARE_PROPERTY_CUSTOM_HANDLERS(TextShadow);
</span><span class="cx">     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitAspectRatio);
</span><span class="cx">     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitBoxShadow);
</span><del>-    DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitFontVariantLigatures);
</del><ins>+    DECLARE_PROPERTY_CUSTOM_HANDLERS(FontVariantLigatures);
+    DECLARE_PROPERTY_CUSTOM_HANDLERS(FontVariantNumeric);
+    DECLARE_PROPERTY_CUSTOM_HANDLERS(FontVariantEastAsian);
</ins><span class="cx"> #if ENABLE(CSS_GRID_LAYOUT)
</span><span class="cx">     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitGridTemplateAreas);
</span><span class="cx">     DECLARE_PROPERTY_CUSTOM_HANDLERS(WebkitGridTemplateColumns);
</span><span class="lines">@@ -1388,71 +1390,232 @@
</span><span class="cx">         styleResolver.style()-&gt;clearContent();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void StyleBuilderCustom::applyInitialWebkitFontVariantLigatures(StyleResolver&amp; styleResolver)
</del><ins>+inline void StyleBuilderCustom::applyInheritFontVariantLigatures(StyleResolver&amp; styleResolver)
</ins><span class="cx"> {
</span><span class="cx">     auto fontDescription = styleResolver.fontDescription();
</span><del>-
-    fontDescription.setCommonLigaturesState(FontCascadeDescription::NormalLigaturesState);
-    fontDescription.setDiscretionaryLigaturesState(FontCascadeDescription::NormalLigaturesState);
-    fontDescription.setHistoricalLigaturesState(FontCascadeDescription::NormalLigaturesState);
-
</del><ins>+    fontDescription.setVariantCommonLigatures(styleResolver.parentFontDescription().variantCommonLigatures());
+    fontDescription.setVariantDiscretionaryLigatures(styleResolver.parentFontDescription().variantDiscretionaryLigatures());
+    fontDescription.setVariantHistoricalLigatures(styleResolver.parentFontDescription().variantHistoricalLigatures());
+    fontDescription.setVariantContextualAlternates(styleResolver.parentFontDescription().variantContextualAlternates());
</ins><span class="cx">     styleResolver.setFontDescription(fontDescription);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void StyleBuilderCustom::applyInheritWebkitFontVariantLigatures(StyleResolver&amp; styleResolver)
</del><ins>+inline void StyleBuilderCustom::applyInitialFontVariantLigatures(StyleResolver&amp; styleResolver)
</ins><span class="cx"> {
</span><del>-    const auto&amp; parentFontDescription = styleResolver.parentFontDescription();
</del><span class="cx">     auto fontDescription = styleResolver.fontDescription();
</span><del>-
-    fontDescription.setCommonLigaturesState(parentFontDescription.commonLigaturesState());
-    fontDescription.setDiscretionaryLigaturesState(parentFontDescription.discretionaryLigaturesState());
-    fontDescription.setHistoricalLigaturesState(parentFontDescription.historicalLigaturesState());
-
</del><ins>+    fontDescription.setVariantCommonLigatures(FontVariantLigatures::Normal);
+    fontDescription.setVariantDiscretionaryLigatures(FontVariantLigatures::Normal);
+    fontDescription.setVariantHistoricalLigatures(FontVariantLigatures::Normal);
+    fontDescription.setVariantContextualAlternates(FontVariantLigatures::Normal);
</ins><span class="cx">     styleResolver.setFontDescription(fontDescription);
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-inline void StyleBuilderCustom::applyValueWebkitFontVariantLigatures(StyleResolver&amp; styleResolver, CSSValue&amp; value)
</del><ins>+inline void StyleBuilderCustom::applyValueFontVariantLigatures(StyleResolver&amp; styleResolver, CSSValue&amp; value)
</ins><span class="cx"> {
</span><del>-    auto commonLigaturesState = FontCascadeDescription::NormalLigaturesState;
-    auto discretionaryLigaturesState = FontCascadeDescription::NormalLigaturesState;
-    auto historicalLigaturesState = FontCascadeDescription::NormalLigaturesState;
</del><ins>+    FontVariantLigatures common = FontVariantLigatures::Normal;
+    FontVariantLigatures discretionary = FontVariantLigatures::Normal;
+    FontVariantLigatures historical = FontVariantLigatures::Normal;
+    FontVariantLigatures contextualAlternates = FontVariantLigatures::Normal;
</ins><span class="cx"> 
</span><span class="cx">     if (is&lt;CSSValueList&gt;(value)) {
</span><span class="cx">         for (auto&amp; item : downcast&lt;CSSValueList&gt;(value)) {
</span><span class="cx">             switch (downcast&lt;CSSPrimitiveValue&gt;(item.get()).getValueID()) {
</span><span class="cx">             case CSSValueNoCommonLigatures:
</span><del>-                commonLigaturesState = FontCascadeDescription::DisabledLigaturesState;
</del><ins>+                common = FontVariantLigatures::No;
</ins><span class="cx">                 break;
</span><span class="cx">             case CSSValueCommonLigatures:
</span><del>-                commonLigaturesState = FontCascadeDescription::EnabledLigaturesState;
</del><ins>+                common = FontVariantLigatures::Yes;
</ins><span class="cx">                 break;
</span><span class="cx">             case CSSValueNoDiscretionaryLigatures:
</span><del>-                discretionaryLigaturesState = FontCascadeDescription::DisabledLigaturesState;
</del><ins>+                discretionary = FontVariantLigatures::No;
</ins><span class="cx">                 break;
</span><span class="cx">             case CSSValueDiscretionaryLigatures:
</span><del>-                discretionaryLigaturesState = FontCascadeDescription::EnabledLigaturesState;
</del><ins>+                discretionary = FontVariantLigatures::Yes;
</ins><span class="cx">                 break;
</span><span class="cx">             case CSSValueNoHistoricalLigatures:
</span><del>-                historicalLigaturesState = FontCascadeDescription::DisabledLigaturesState;
</del><ins>+                historical = FontVariantLigatures::No;
</ins><span class="cx">                 break;
</span><span class="cx">             case CSSValueHistoricalLigatures:
</span><del>-                historicalLigaturesState = FontCascadeDescription::EnabledLigaturesState;
</del><ins>+                historical = FontVariantLigatures::Yes;
</ins><span class="cx">                 break;
</span><ins>+            case CSSValueContextual:
+                contextualAlternates = FontVariantLigatures::Yes;
+                break;
+            case CSSValueNoContextual:
+                contextualAlternates = FontVariantLigatures::No;
+                break;
</ins><span class="cx">             default:
</span><span class="cx">                 ASSERT_NOT_REACHED();
</span><span class="cx">                 break;
</span><span class="cx">             }
</span><span class="cx">         }
</span><ins>+    } else {
+        switch (downcast&lt;CSSPrimitiveValue&gt;(value).getValueID()) {
+        case CSSValueNormal:
+            break;
+        case CSSValueNone:
+            common = FontVariantLigatures::No;
+            discretionary = FontVariantLigatures::No;
+            historical = FontVariantLigatures::No;
+            contextualAlternates = FontVariantLigatures::No;
+            break;
+        default:
+            ASSERT_NOT_REACHED();
+            break;
+        }
+    }
+
+    auto fontDescription = styleResolver.fontDescription();
+    fontDescription.setVariantCommonLigatures(common);
+    fontDescription.setVariantDiscretionaryLigatures(discretionary);
+    fontDescription.setVariantHistoricalLigatures(historical);
+    fontDescription.setVariantContextualAlternates(contextualAlternates);
+    styleResolver.setFontDescription(fontDescription);
+}
+
+inline void StyleBuilderCustom::applyInheritFontVariantNumeric(StyleResolver&amp; styleResolver)
+{
+    auto fontDescription = styleResolver.fontDescription();
+    fontDescription.setVariantNumericFigure(styleResolver.parentFontDescription().variantNumericFigure());
+    fontDescription.setVariantNumericSpacing(styleResolver.parentFontDescription().variantNumericSpacing());
+    fontDescription.setVariantNumericFraction(styleResolver.parentFontDescription().variantNumericFraction());
+    fontDescription.setVariantNumericOrdinal(styleResolver.parentFontDescription().variantNumericOrdinal());
+    fontDescription.setVariantNumericSlashedZero(styleResolver.parentFontDescription().variantNumericSlashedZero());
+    styleResolver.setFontDescription(fontDescription);
+}
+
+inline void StyleBuilderCustom::applyInitialFontVariantNumeric(StyleResolver&amp; styleResolver)
+{
+    auto fontDescription = styleResolver.fontDescription();
+    fontDescription.setVariantNumericFigure(FontVariantNumericFigure::Normal);
+    fontDescription.setVariantNumericSpacing(FontVariantNumericSpacing::Normal);
+    fontDescription.setVariantNumericFraction(FontVariantNumericFraction::Normal);
+    fontDescription.setVariantNumericOrdinal(FontVariantNumericOrdinal::Normal);
+    fontDescription.setVariantNumericSlashedZero(FontVariantNumericSlashedZero::Normal);
+    styleResolver.setFontDescription(fontDescription);
+}
+
+inline void StyleBuilderCustom::applyValueFontVariantNumeric(StyleResolver&amp; styleResolver, CSSValue&amp; value)
+{
+    FontVariantNumericFigure figure = FontVariantNumericFigure::Normal;
+    FontVariantNumericSpacing spacing = FontVariantNumericSpacing::Normal;
+    FontVariantNumericFraction fraction = FontVariantNumericFraction::Normal;
+    FontVariantNumericOrdinal ordinal = FontVariantNumericOrdinal::Normal;
+    FontVariantNumericSlashedZero slashedZero = FontVariantNumericSlashedZero::Normal;
+
+    if (is&lt;CSSValueList&gt;(value)) {
+        for (auto&amp; item : downcast&lt;CSSValueList&gt;(value)) {
+            switch (downcast&lt;CSSPrimitiveValue&gt;(item.get()).getValueID()) {
+            case CSSValueLiningNums:
+                figure = FontVariantNumericFigure::LiningNumbers;
+                break;
+            case CSSValueOldstyleNums:
+                figure = FontVariantNumericFigure::OldStyleNumbers;
+                break;
+            case CSSValueProportionalNums:
+                spacing = FontVariantNumericSpacing::ProportionalNumbers;
+                break;
+            case CSSValueTabularNums:
+                spacing = FontVariantNumericSpacing::TabularNumbers;
+                break;
+            case CSSValueDiagonalFractions:
+                fraction = FontVariantNumericFraction::DiagonalFractions;
+                break;
+            case CSSValueStackedFractions:
+                fraction = FontVariantNumericFraction::StackedFractions;
+                break;
+            case CSSValueOrdinal:
+                ordinal = FontVariantNumericOrdinal::Yes;
+                break;
+            case CSSValueSlashedZero:
+                slashedZero = FontVariantNumericSlashedZero::Yes;
+                break;
+            default:
+                ASSERT_NOT_REACHED();
+                break;
+            }
+        }
</ins><span class="cx">     } else
</span><span class="cx">         ASSERT(downcast&lt;CSSPrimitiveValue&gt;(value).getValueID() == CSSValueNormal);
</span><span class="cx"> 
</span><span class="cx">     auto fontDescription = styleResolver.fontDescription();
</span><del>-    fontDescription.setCommonLigaturesState(commonLigaturesState);
-    fontDescription.setDiscretionaryLigaturesState(discretionaryLigaturesState);
-    fontDescription.setHistoricalLigaturesState(historicalLigaturesState);
</del><ins>+    fontDescription.setVariantNumericFigure(figure);
+    fontDescription.setVariantNumericSpacing(spacing);
+    fontDescription.setVariantNumericFraction(fraction);
+    fontDescription.setVariantNumericOrdinal(ordinal);
+    fontDescription.setVariantNumericSlashedZero(slashedZero);
</ins><span class="cx">     styleResolver.setFontDescription(fontDescription);
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+inline void StyleBuilderCustom::applyInheritFontVariantEastAsian(StyleResolver&amp; styleResolver)
+{
+    auto fontDescription = styleResolver.fontDescription();
+    fontDescription.setVariantEastAsianVariant(styleResolver.parentFontDescription().variantEastAsianVariant());
+    fontDescription.setVariantEastAsianWidth(styleResolver.parentFontDescription().variantEastAsianWidth());
+    fontDescription.setVariantEastAsianRuby(styleResolver.parentFontDescription().variantEastAsianRuby());
+    styleResolver.setFontDescription(fontDescription);
+}
+
+inline void StyleBuilderCustom::applyInitialFontVariantEastAsian(StyleResolver&amp; styleResolver)
+{
+    auto fontDescription = styleResolver.fontDescription();
+    fontDescription.setVariantEastAsianVariant(FontVariantEastAsianVariant::Normal);
+    fontDescription.setVariantEastAsianWidth(FontVariantEastAsianWidth::Normal);
+    fontDescription.setVariantEastAsianRuby(FontVariantEastAsianRuby::Normal);
+    styleResolver.setFontDescription(fontDescription);
+}
+
+inline void StyleBuilderCustom::applyValueFontVariantEastAsian(StyleResolver&amp; styleResolver, CSSValue&amp; value)
+{
+    FontVariantEastAsianVariant variant = FontVariantEastAsianVariant::Normal;
+    FontVariantEastAsianWidth width = FontVariantEastAsianWidth::Normal;
+    FontVariantEastAsianRuby ruby = FontVariantEastAsianRuby::Normal;
+
+    if (is&lt;CSSValueList&gt;(value)) {
+        for (auto&amp; item : downcast&lt;CSSValueList&gt;(value)) {
+            switch (downcast&lt;CSSPrimitiveValue&gt;(item.get()).getValueID()) {
+            case CSSValueJis78:
+                variant = FontVariantEastAsianVariant::Jis78;
+                break;
+            case CSSValueJis83:
+                variant = FontVariantEastAsianVariant::Jis83;
+                break;
+            case CSSValueJis90:
+                variant = FontVariantEastAsianVariant::Jis90;
+                break;
+            case CSSValueJis04:
+                variant = FontVariantEastAsianVariant::Jis04;
+                break;
+            case CSSValueSimplified:
+                variant = FontVariantEastAsianVariant::Simplified;
+                break;
+            case CSSValueTraditional:
+                variant = FontVariantEastAsianVariant::Traditional;
+                break;
+            case CSSValueFullWidth:
+                width = FontVariantEastAsianWidth::FullWidth;
+                break;
+            case CSSValueProportionalWidth:
+                width = FontVariantEastAsianWidth::ProportionalWidth;
+                break;
+            case CSSValueRuby:
+                ruby = FontVariantEastAsianRuby::Yes;
+                break;
+            default:
+                ASSERT_NOT_REACHED();
+                break;
+            }
+        }
+    } else
+        ASSERT(downcast&lt;CSSPrimitiveValue&gt;(value).getValueID() == CSSValueNormal);
+
+    auto fontDescription = styleResolver.fontDescription();
+    fontDescription.setVariantEastAsianVariant(variant);
+    fontDescription.setVariantEastAsianWidth(width);
+    fontDescription.setVariantEastAsianRuby(ruby);
+    styleResolver.setFontDescription(fontDescription);
+}
+
</ins><span class="cx"> inline void StyleBuilderCustom::applyInitialFontSize(StyleResolver&amp; styleResolver)
</span><span class="cx"> {
</span><span class="cx">     auto fontDescription = styleResolver.style()-&gt;fontDescription();
</span></span></pre></div>
<a id="trunkSourceWebCoreeditingcocoaHTMLConvertermm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/editing/cocoa/HTMLConverter.mm (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/editing/cocoa/HTMLConverter.mm        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/editing/cocoa/HTMLConverter.mm        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -1156,7 +1156,7 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    String fontLigatures = _caches-&gt;propertyValueForNode(element, CSSPropertyWebkitFontVariantLigatures);
</del><ins>+    String fontLigatures = _caches-&gt;propertyValueForNode(element, CSSPropertyFontVariantLigatures);
</ins><span class="cx">     if (fontLigatures.length()) {
</span><span class="cx">         if (fontLigatures.contains(&quot;normal&quot;))
</span><span class="cx">             ;   // default: whatever the system decides to do
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontCacheh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/FontCache.h (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/FontCache.h        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/graphics/FontCache.h        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -32,6 +32,7 @@
</span><span class="cx"> 
</span><span class="cx"> #include &quot;FontDescription.h&quot;
</span><span class="cx"> #include &quot;Timer.h&quot;
</span><ins>+#include &lt;array&gt;
</ins><span class="cx"> #include &lt;limits.h&gt;
</span><span class="cx"> #include &lt;wtf/Forward.h&gt;
</span><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><span class="lines">@@ -73,7 +74,7 @@
</span><span class="cx">     FontDescriptionKey(const FontDescription&amp; description)
</span><span class="cx">         : m_size(description.computedPixelSize())
</span><span class="cx">         , m_weight(description.weight())
</span><del>-        , m_flags(makeFlagKey(description))
</del><ins>+        , m_flags(makeFlagsKey(description))
</ins><span class="cx">         , m_locale(description.locale())
</span><span class="cx">         , m_featureSettings(description.featureSettings())
</span><span class="cx">     { }
</span><span class="lines">@@ -85,7 +86,7 @@
</span><span class="cx">     bool operator==(const FontDescriptionKey&amp; other) const
</span><span class="cx">     {
</span><span class="cx">         return m_size == other.m_size &amp;&amp; m_weight == other.m_weight &amp;&amp; m_flags == other.m_flags &amp;&amp; m_locale == other.m_locale
</span><del>-            &amp;&amp; ((m_featureSettings == other.m_featureSettings) || (m_featureSettings &amp;&amp; other.m_featureSettings &amp;&amp; m_featureSettings.get() == other.m_featureSettings.get()));
</del><ins>+            &amp;&amp; m_featureSettings == other.m_featureSettings;
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     bool operator!=(const FontDescriptionKey&amp; other) const
</span><span class="lines">@@ -97,15 +98,21 @@
</span><span class="cx"> 
</span><span class="cx">     inline unsigned computeHash() const
</span><span class="cx">     {
</span><del>-        unsigned toHash[] = {m_size, m_weight, m_flags, m_locale.isNull() ? 0 : m_locale.impl()-&gt;existingHash(), m_featureSettings ? m_featureSettings-&gt;hash() : 0};
-        return StringHasher::hashMemory(toHash, sizeof(toHash));
</del><ins>+        IntegerHasher hasher;
+        hasher.add(m_size);
+        hasher.add(m_weight);
+        for (unsigned flagItem : m_flags)
+            hasher.add(flagItem);
+        hasher.add(m_locale.isNull() ? 0 : m_locale.impl()-&gt;existingHash());
+        hasher.add(m_featureSettings.hash());
+        return hasher.hash();
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    static unsigned makeFlagKey(const FontDescription&amp; description)
</del><ins>+    static std::array&lt;unsigned, 2&gt; makeFlagsKey(const FontDescription&amp; description)
</ins><span class="cx">     {
</span><span class="cx">         static_assert(USCRIPT_CODE_LIMIT &lt; 0x1000, &quot;Script code must fit in an unsigned along with the other flags&quot;);
</span><del>-        return static_cast&lt;unsigned&gt;(description.script()) &lt;&lt; 11
</del><ins>+        unsigned first = static_cast&lt;unsigned&gt;(description.script()) &lt;&lt; 11
</ins><span class="cx">             | static_cast&lt;unsigned&gt;(description.textRenderingMode()) &lt;&lt; 9
</span><span class="cx">             | static_cast&lt;unsigned&gt;(description.smallCaps()) &lt;&lt; 8
</span><span class="cx">             | static_cast&lt;unsigned&gt;(description.fontSynthesis()) &lt;&lt; 6
</span><span class="lines">@@ -114,15 +121,31 @@
</span><span class="cx">             | static_cast&lt;unsigned&gt;(description.orientation()) &lt;&lt; 2
</span><span class="cx">             | static_cast&lt;unsigned&gt;(description.italic()) &lt;&lt; 1
</span><span class="cx">             | static_cast&lt;unsigned&gt;(description.renderingMode());
</span><ins>+        unsigned second = static_cast&lt;unsigned&gt;(description.variantEastAsianRuby()) &lt;&lt; 27
+            | static_cast&lt;unsigned&gt;(description.variantEastAsianWidth()) &lt;&lt; 25
+            | static_cast&lt;unsigned&gt;(description.variantEastAsianVariant()) &lt;&lt; 22
+            | static_cast&lt;unsigned&gt;(description.variantAlternates()) &lt;&lt; 21
+            | static_cast&lt;unsigned&gt;(description.variantNumericSlashedZero()) &lt;&lt; 20
+            | static_cast&lt;unsigned&gt;(description.variantNumericOrdinal()) &lt;&lt; 19
+            | static_cast&lt;unsigned&gt;(description.variantNumericFraction()) &lt;&lt; 17
+            | static_cast&lt;unsigned&gt;(description.variantNumericSpacing()) &lt;&lt; 15
+            | static_cast&lt;unsigned&gt;(description.variantNumericFigure()) &lt;&lt; 13
+            | static_cast&lt;unsigned&gt;(description.variantCaps()) &lt;&lt; 10
+            | static_cast&lt;unsigned&gt;(description.variantPosition()) &lt;&lt; 8
+            | static_cast&lt;unsigned&gt;(description.variantContextualAlternates()) &lt;&lt; 6
+            | static_cast&lt;unsigned&gt;(description.variantHistoricalLigatures()) &lt;&lt; 4
+            | static_cast&lt;unsigned&gt;(description.variantDiscretionaryLigatures()) &lt;&lt; 2
+            | static_cast&lt;unsigned&gt;(description.variantCommonLigatures());
+        return {{ first, second }};
</ins><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     static const unsigned cHashTableDeletedSize = 0xFFFFFFFFU;
</span><span class="cx"> 
</span><span class="cx">     unsigned m_size { 0 };
</span><span class="cx">     unsigned m_weight { 0 };
</span><del>-    unsigned m_flags { 0 };
</del><ins>+    std::array&lt;unsigned, 2&gt; m_flags {{ 0, 0 }};
</ins><span class="cx">     AtomicString m_locale;
</span><del>-    RefPtr&lt;FontFeatureSettings&gt; m_featureSettings;
</del><ins>+    FontFeatureSettings m_featureSettings;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> struct FontDescriptionKeyHash {
</span><span class="lines">@@ -234,14 +257,14 @@
</span><span class="cx">     bool needsSyntheticOblique;
</span><span class="cx"> };
</span><span class="cx"> 
</span><del>-RetainPtr&lt;CTFontRef&gt; preparePlatformFont(CTFontRef, TextRenderingMode, const FontFeatureSettings*);
</del><ins>+RetainPtr&lt;CTFontRef&gt; preparePlatformFont(CTFontRef, TextRenderingMode, const FontFeatureSettings&amp;, const FontVariantSettings&amp;);
</ins><span class="cx"> FontWeight fontWeightFromCoreText(CGFloat weight);
</span><span class="cx"> uint16_t toCoreTextFontWeight(FontWeight);
</span><span class="cx"> bool isFontWeightBold(FontWeight);
</span><span class="cx"> void platformInvalidateFontCache();
</span><span class="cx"> SynthesisPair computeNecessarySynthesis(CTFontRef, const FontDescription&amp;, bool isPlatformFont = false);
</span><span class="cx"> RetainPtr&lt;CTFontRef&gt; platformFontWithFamilySpecialCase(const AtomicString&amp; family, FontWeight, CTFontSymbolicTraits, float size);
</span><del>-RetainPtr&lt;CTFontRef&gt; platformFontWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits, FontWeight, const FontFeatureSettings*, TextRenderingMode, float size);
</del><ins>+RetainPtr&lt;CTFontRef&gt; platformFontWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits, FontWeight, TextRenderingMode, float size);
</ins><span class="cx"> RetainPtr&lt;CTFontRef&gt; platformLookupFallbackFont(CTFontRef, FontWeight, const AtomicString&amp; locale, const UChar* characters, unsigned length);
</span><span class="cx"> bool requiresCustomFallbackFont(UChar32 character);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontCascadecpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/FontCascade.cpp (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/FontCascade.cpp        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.cpp        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -600,7 +600,8 @@
</span><span class="cx">         return Simple;
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-    if (m_fontDescription.featureSettings() &amp;&amp; m_fontDescription.featureSettings()-&gt;size() &gt; 0)
</del><ins>+    // FIXME: This shouldn't be necessary because Font::applyTransforms() should perform all necessary shaping.
+    if (m_fontDescription.featureSettings().size() &gt; 0 || !m_fontDescription.variantSettings().isAllNormal())
</ins><span class="cx">         return Complex;
</span><span class="cx">     
</span><span class="cx">     if (run.length() &gt; 1 &amp;&amp; !WidthIterator::supportsTypesettingFeatures(*this))
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontCascadeh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/FontCascade.h (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/FontCascade.h        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/graphics/FontCascade.h        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -328,14 +328,14 @@
</span><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span><del>-        switch (m_fontDescription.commonLigaturesState()) {
-        case FontCascadeDescription::DisabledLigaturesState:
</del><ins>+        switch (m_fontDescription.variantCommonLigatures()) {
+        case FontVariantLigatures::No:
</ins><span class="cx">             features &amp;= ~Ligatures;
</span><span class="cx">             break;
</span><del>-        case FontCascadeDescription::EnabledLigaturesState:
</del><ins>+        case FontVariantLigatures::Yes:
</ins><span class="cx">             features |= Ligatures;
</span><span class="cx">             break;
</span><del>-        case FontCascadeDescription::NormalLigaturesState:
</del><ins>+        default:
</ins><span class="cx">             break;
</span><span class="cx">         }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontDescriptioncpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/FontDescription.cpp (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/FontDescription.cpp        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/graphics/FontDescription.cpp        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -35,11 +35,14 @@
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><span class="cx"> struct SameSizeAsFontCascadeDescription {
</span><del>-    void* pointers[3];
-    float sizes[2];
-    // FIXME: Make them fit into one word.
-    uint32_t bitfields;
-    uint32_t bitfields2 : 8;
</del><ins>+    Vector&lt;void*&gt; vector;
+    void* string;
+    float size;
+    unsigned bitfields1;
+    unsigned bitfields2 : 22;
+    void* array;
+    float size2;
+    unsigned bitfields3 : 10;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> COMPILE_ASSERT(sizeof(FontCascadeDescription) == sizeof(SameSizeAsFontCascadeDescription), FontCascadeDescription_should_stay_small);
</span><span class="lines">@@ -55,6 +58,21 @@
</span><span class="cx">     , m_textRendering(AutoTextRendering)
</span><span class="cx">     , m_script(localeToScriptCodeForFontSelection(m_locale))
</span><span class="cx">     , m_fontSynthesis(FontSynthesisWeight | FontSynthesisStyle)
</span><ins>+    , m_variantCommonLigatures(static_cast&lt;unsigned&gt;(FontVariantLigatures::Normal))
+    , m_variantDiscretionaryLigatures(static_cast&lt;unsigned&gt;(FontVariantLigatures::Normal))
+    , m_variantHistoricalLigatures(static_cast&lt;unsigned&gt;(FontVariantLigatures::Normal))
+    , m_variantContextualAlternates(static_cast&lt;unsigned&gt;(FontVariantLigatures::Normal))
+    , m_variantPosition(static_cast&lt;unsigned&gt;(FontVariantPosition::Normal))
+    , m_variantCaps(static_cast&lt;unsigned&gt;(FontVariantCaps::Normal))
+    , m_variantNumericFigure(static_cast&lt;unsigned&gt;(FontVariantNumericFigure::Normal))
+    , m_variantNumericSpacing(static_cast&lt;unsigned&gt;(FontVariantNumericSpacing::Normal))
+    , m_variantNumericFraction(static_cast&lt;unsigned&gt;(FontVariantNumericFraction::Normal))
+    , m_variantNumericOrdinal(static_cast&lt;unsigned&gt;(FontVariantNumericOrdinal::Normal))
+    , m_variantNumericSlashedZero(static_cast&lt;unsigned&gt;(FontVariantNumericSlashedZero::Normal))
+    , m_variantAlternates(static_cast&lt;unsigned&gt;(FontVariantAlternates::Normal))
+    , m_variantEastAsianVariant(static_cast&lt;unsigned&gt;(FontVariantEastAsianVariant::Normal))
+    , m_variantEastAsianWidth(static_cast&lt;unsigned&gt;(FontVariantEastAsianWidth::Normal))
+    , m_variantEastAsianRuby(static_cast&lt;unsigned&gt;(FontVariantEastAsianRuby::Normal))
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -75,9 +93,6 @@
</span><span class="cx"> FontCascadeDescription::FontCascadeDescription()
</span><span class="cx">     : m_isAbsoluteSize(false)
</span><span class="cx">     , m_kerning(AutoKerning)
</span><del>-    , m_commonLigaturesState(NormalLigaturesState)
-    , m_discretionaryLigaturesState(NormalLigaturesState)
-    , m_historicalLigaturesState(NormalLigaturesState)
</del><span class="cx">     , m_keywordSize(0)
</span><span class="cx">     , m_fontSmoothing(AutoSmoothing)
</span><span class="cx">     , m_isSpecifiedFont(false)
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontDescriptionh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/FontDescription.h (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/FontDescription.h        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/graphics/FontDescription.h        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -60,8 +60,41 @@
</span><span class="cx">     FontOrientation orientation() const { return static_cast&lt;FontOrientation&gt;(m_orientation); }
</span><span class="cx">     NonCJKGlyphOrientation nonCJKGlyphOrientation() const { return static_cast&lt;NonCJKGlyphOrientation&gt;(m_nonCJKGlyphOrientation); }
</span><span class="cx">     FontWidthVariant widthVariant() const { return static_cast&lt;FontWidthVariant&gt;(m_widthVariant); }
</span><del>-    FontFeatureSettings* featureSettings() const { return m_featureSettings.get(); }
</del><ins>+    const FontFeatureSettings&amp; featureSettings() const { return m_featureSettings; }
</ins><span class="cx">     FontSynthesis fontSynthesis() const { return static_cast&lt;FontSynthesis&gt;(m_fontSynthesis); }
</span><ins>+    FontVariantLigatures variantCommonLigatures() const { return static_cast&lt;FontVariantLigatures&gt;(m_variantCommonLigatures); }
+    FontVariantLigatures variantDiscretionaryLigatures() const { return static_cast&lt;FontVariantLigatures&gt;(m_variantDiscretionaryLigatures); }
+    FontVariantLigatures variantHistoricalLigatures() const { return static_cast&lt;FontVariantLigatures&gt;(m_variantHistoricalLigatures); }
+    FontVariantLigatures variantContextualAlternates() const { return static_cast&lt;FontVariantLigatures&gt;(m_variantContextualAlternates); }
+    FontVariantPosition variantPosition() const { return static_cast&lt;FontVariantPosition&gt;(m_variantPosition); }
+    FontVariantCaps variantCaps() const { return static_cast&lt;FontVariantCaps&gt;(m_variantCaps); }
+    FontVariantNumericFigure variantNumericFigure() const { return static_cast&lt;FontVariantNumericFigure&gt;(m_variantNumericFigure); }
+    FontVariantNumericSpacing variantNumericSpacing() const { return static_cast&lt;FontVariantNumericSpacing&gt;(m_variantNumericSpacing); }
+    FontVariantNumericFraction variantNumericFraction() const { return static_cast&lt;FontVariantNumericFraction&gt;(m_variantNumericFraction); }
+    FontVariantNumericOrdinal variantNumericOrdinal() const { return static_cast&lt;FontVariantNumericOrdinal&gt;(m_variantNumericOrdinal); }
+    FontVariantNumericSlashedZero variantNumericSlashedZero() const { return static_cast&lt;FontVariantNumericSlashedZero&gt;(m_variantNumericSlashedZero); }
+    FontVariantAlternates variantAlternates() const { return static_cast&lt;FontVariantAlternates&gt;(m_variantAlternates); }
+    FontVariantEastAsianVariant variantEastAsianVariant() const { return static_cast&lt;FontVariantEastAsianVariant&gt;(m_variantEastAsianVariant); }
+    FontVariantEastAsianWidth variantEastAsianWidth() const { return static_cast&lt;FontVariantEastAsianWidth&gt;(m_variantEastAsianWidth); }
+    FontVariantEastAsianRuby variantEastAsianRuby() const { return static_cast&lt;FontVariantEastAsianRuby&gt;(m_variantEastAsianRuby); }
+    FontVariantSettings variantSettings() const
+    {
+        return { variantCommonLigatures(),
+            variantDiscretionaryLigatures(),
+            variantHistoricalLigatures(),
+            variantContextualAlternates(),
+            variantPosition(),
+            variantCaps(),
+            variantNumericFigure(),
+            variantNumericSpacing(),
+            variantNumericFraction(),
+            variantNumericOrdinal(),
+            variantNumericSlashedZero(),
+            variantAlternates(),
+            variantEastAsianVariant(),
+            variantEastAsianWidth(),
+            variantEastAsianRuby() };
+    }
</ins><span class="cx"> 
</span><span class="cx">     void setComputedSize(float s) { m_computedSize = clampToFloat(s); }
</span><span class="cx">     void setItalic(FontItalic i) { m_italic = i; }
</span><span class="lines">@@ -75,13 +108,28 @@
</span><span class="cx">     void setNonCJKGlyphOrientation(NonCJKGlyphOrientation orientation) { m_nonCJKGlyphOrientation = orientation; }
</span><span class="cx">     void setWidthVariant(FontWidthVariant widthVariant) { m_widthVariant = widthVariant; } // Make sure new callers of this sync with FontPlatformData::isForTextCombine()!
</span><span class="cx">     void setLocale(const AtomicString&amp;);
</span><del>-    void setFeatureSettings(PassRefPtr&lt;FontFeatureSettings&gt; settings) { m_featureSettings = settings; }
</del><ins>+    void setFeatureSettings(FontFeatureSettings&amp;&amp; settings) { m_featureSettings = WTF::move(settings); }
</ins><span class="cx">     void setFontSynthesis(FontSynthesis fontSynthesis) { m_fontSynthesis = fontSynthesis; }
</span><ins>+    void setVariantCommonLigatures(FontVariantLigatures variant) { m_variantCommonLigatures = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantDiscretionaryLigatures(FontVariantLigatures variant) { m_variantDiscretionaryLigatures = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantHistoricalLigatures(FontVariantLigatures variant) { m_variantHistoricalLigatures = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantContextualAlternates(FontVariantLigatures variant) { m_variantContextualAlternates = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantPosition(FontVariantPosition variant) { m_variantPosition = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantCaps(FontVariantCaps variant) { m_variantCaps = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantNumericFigure(FontVariantNumericFigure variant) { m_variantNumericFigure = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantNumericSpacing(FontVariantNumericSpacing variant) { m_variantNumericSpacing = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantNumericFraction(FontVariantNumericFraction variant) { m_variantNumericFraction = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantNumericOrdinal(FontVariantNumericOrdinal variant) { m_variantNumericOrdinal = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantNumericSlashedZero(FontVariantNumericSlashedZero variant) { m_variantNumericSlashedZero = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantAlternates(FontVariantAlternates variant) { m_variantAlternates = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantEastAsianVariant(FontVariantEastAsianVariant variant) { m_variantEastAsianVariant = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantEastAsianWidth(FontVariantEastAsianWidth variant) { m_variantEastAsianWidth = static_cast&lt;unsigned&gt;(variant); }
+    void setVariantEastAsianRuby(FontVariantEastAsianRuby variant) { m_variantEastAsianRuby = static_cast&lt;unsigned&gt;(variant); }
</ins><span class="cx"> 
</span><span class="cx">     FontTraitsMask traitsMask() const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    RefPtr&lt;FontFeatureSettings&gt; m_featureSettings;
</del><ins>+    FontFeatureSettings m_featureSettings;
</ins><span class="cx">     AtomicString m_locale;
</span><span class="cx"> 
</span><span class="cx">     float m_computedSize { 0 }; // Computed size adjusted for the minimum font size and the zoom factor.
</span><span class="lines">@@ -95,6 +143,21 @@
</span><span class="cx">     unsigned m_textRendering : 2; // TextRenderingMode
</span><span class="cx">     unsigned m_script : 7; // Used to help choose an appropriate font for generic font families.
</span><span class="cx">     unsigned m_fontSynthesis : 2; // FontSynthesis type
</span><ins>+    unsigned m_variantCommonLigatures : 2; // FontVariantLigatures
+    unsigned m_variantDiscretionaryLigatures : 2; // FontVariantLigatures
+    unsigned m_variantHistoricalLigatures : 2; // FontVariantLigatures
+    unsigned m_variantContextualAlternates : 2; // FontVariantLigatures
+    unsigned m_variantPosition : 2; // FontVariantPosition
+    unsigned m_variantCaps : 3; // FontVariantCaps
+    unsigned m_variantNumericFigure : 2; // FontVariantNumericFigure
+    unsigned m_variantNumericSpacing : 2; // FontVariantNumericSpacing
+    unsigned m_variantNumericFraction : 2; // FontVariantNumericFraction
+    unsigned m_variantNumericOrdinal : 1; // FontVariantNumericOrdinal
+    unsigned m_variantNumericSlashedZero : 1; // FontVariantNumericSlashedZero
+    unsigned m_variantAlternates : 1; // FontVariantAlternates
+    unsigned m_variantEastAsianVariant : 3; // FontVariantEastAsianVariant
+    unsigned m_variantEastAsianWidth : 2; // FontVariantEastAsianWidth
+    unsigned m_variantEastAsianRuby : 1; // FontVariantEastAsianRuby
</ins><span class="cx"> };
</span><span class="cx"> 
</span><span class="cx"> inline bool FontDescription::operator==(const FontDescription&amp; other) const
</span><span class="lines">@@ -110,7 +173,22 @@
</span><span class="cx">         &amp;&amp; m_widthVariant == other.m_widthVariant
</span><span class="cx">         &amp;&amp; m_locale == other.m_locale
</span><span class="cx">         &amp;&amp; m_featureSettings == other.m_featureSettings
</span><del>-        &amp;&amp; m_fontSynthesis == other.m_fontSynthesis;
</del><ins>+        &amp;&amp; m_fontSynthesis == other.m_fontSynthesis
+        &amp;&amp; m_variantCommonLigatures == other.m_variantCommonLigatures
+        &amp;&amp; m_variantDiscretionaryLigatures == other.m_variantDiscretionaryLigatures
+        &amp;&amp; m_variantHistoricalLigatures == other.m_variantHistoricalLigatures
+        &amp;&amp; m_variantContextualAlternates == other.m_variantContextualAlternates
+        &amp;&amp; m_variantPosition == other.m_variantPosition
+        &amp;&amp; m_variantCaps == other.m_variantCaps
+        &amp;&amp; m_variantNumericFigure == other.m_variantNumericFigure
+        &amp;&amp; m_variantNumericSpacing == other.m_variantNumericSpacing
+        &amp;&amp; m_variantNumericFraction == other.m_variantNumericFraction
+        &amp;&amp; m_variantNumericOrdinal == other.m_variantNumericOrdinal
+        &amp;&amp; m_variantNumericSlashedZero == other.m_variantNumericSlashedZero
+        &amp;&amp; m_variantAlternates == other.m_variantAlternates
+        &amp;&amp; m_variantEastAsianVariant == other.m_variantEastAsianVariant
+        &amp;&amp; m_variantEastAsianWidth == other.m_variantEastAsianWidth
+        &amp;&amp; m_variantEastAsianRuby == other.m_variantEastAsianRuby;
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // FIXME: Move to a file of its own.
</span><span class="lines">@@ -118,8 +196,6 @@
</span><span class="cx"> public:
</span><span class="cx">     enum Kerning { AutoKerning, NormalKerning, NoneKerning };
</span><span class="cx"> 
</span><del>-    enum LigaturesState { NormalLigaturesState, DisabledLigaturesState, EnabledLigaturesState };
-
</del><span class="cx">     FontCascadeDescription();
</span><span class="cx"> 
</span><span class="cx">     bool operator==(const FontCascadeDescription&amp;) const;
</span><span class="lines">@@ -139,9 +215,6 @@
</span><span class="cx">     bool useFixedDefaultSize() const { return familyCount() == 1 &amp;&amp; firstFamily() == monospaceFamily; }
</span><span class="cx"> 
</span><span class="cx">     Kerning kerning() const { return static_cast&lt;Kerning&gt;(m_kerning); }
</span><del>-    LigaturesState commonLigaturesState() const { return static_cast&lt;LigaturesState&gt;(m_commonLigaturesState); }
-    LigaturesState discretionaryLigaturesState() const { return static_cast&lt;LigaturesState&gt;(m_discretionaryLigaturesState); }
-    LigaturesState historicalLigaturesState() const { return static_cast&lt;LigaturesState&gt;(m_historicalLigaturesState); }
</del><span class="cx">     unsigned keywordSize() const { return m_keywordSize; }
</span><span class="cx">     CSSValueID keywordSizeAsIdentifier() const
</span><span class="cx">     {
</span><span class="lines">@@ -158,9 +231,6 @@
</span><span class="cx">     void setSpecifiedSize(float s) { m_specifiedSize = clampToFloat(s); }
</span><span class="cx">     void setIsAbsoluteSize(bool s) { m_isAbsoluteSize = s; }
</span><span class="cx">     void setKerning(Kerning kerning) { m_kerning = kerning; }
</span><del>-    void setCommonLigaturesState(LigaturesState commonLigaturesState) { m_commonLigaturesState = commonLigaturesState; }
-    void setDiscretionaryLigaturesState(LigaturesState discretionaryLigaturesState) { m_discretionaryLigaturesState = discretionaryLigaturesState; }
-    void setHistoricalLigaturesState(LigaturesState historicalLigaturesState) { m_historicalLigaturesState = historicalLigaturesState; }
</del><span class="cx">     void setKeywordSize(unsigned size)
</span><span class="cx">     {
</span><span class="cx">         ASSERT(size &lt;= 8);
</span><span class="lines">@@ -196,6 +266,9 @@
</span><span class="cx">     static TextRenderingMode initialTextRenderingMode() { return AutoTextRendering; }
</span><span class="cx">     static FontSynthesis initialFontSynthesis() { return FontSynthesisWeight | FontSynthesisStyle; }
</span><span class="cx">     static const AtomicString&amp; initialLocale() { return nullAtom; }
</span><ins>+    static FontVariantPosition initialVariantPosition() { return FontVariantPosition::Normal; }
+    static FontVariantCaps initialVariantCaps() { return FontVariantCaps::Normal; }
+    static FontVariantAlternates initialVariantAlternates() { return FontVariantAlternates::Normal; }
</ins><span class="cx"> 
</span><span class="cx"> private:
</span><span class="cx">     RefCountedArray&lt;AtomicString&gt; m_families { 1 };
</span><span class="lines">@@ -205,9 +278,6 @@
</span><span class="cx">     unsigned m_isAbsoluteSize : 1; // Whether or not CSS specified an explicit size
</span><span class="cx">                                   // (logical sizes like &quot;medium&quot; don't count).
</span><span class="cx">     unsigned m_kerning : 2; // Kerning
</span><del>-    unsigned m_commonLigaturesState : 2;
-    unsigned m_discretionaryLigaturesState : 2;
-    unsigned m_historicalLigaturesState : 2;
</del><span class="cx"> 
</span><span class="cx">     unsigned m_keywordSize : 4; // We cache whether or not a font is currently represented by a CSS keyword (e.g., medium).  If so,
</span><span class="cx">                            // then we can accurately translate across different generic families to adjust for different preference settings
</span><span class="lines">@@ -224,9 +294,6 @@
</span><span class="cx">         &amp;&amp; m_specifiedSize == other.m_specifiedSize
</span><span class="cx">         &amp;&amp; m_isAbsoluteSize == other.m_isAbsoluteSize
</span><span class="cx">         &amp;&amp; m_kerning == other.m_kerning
</span><del>-        &amp;&amp; m_commonLigaturesState == other.m_commonLigaturesState
-        &amp;&amp; m_discretionaryLigaturesState == other.m_discretionaryLigaturesState
-        &amp;&amp; m_historicalLigaturesState == other.m_historicalLigaturesState
</del><span class="cx">         &amp;&amp; m_keywordSize == other.m_keywordSize
</span><span class="cx">         &amp;&amp; m_fontSmoothing == other.m_fontSmoothing
</span><span class="cx">         &amp;&amp; m_isSpecifiedFont == other.m_isSpecifiedFont;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontFeatureSettingscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/FontFeatureSettings.cpp (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/FontFeatureSettings.cpp        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/graphics/FontFeatureSettings.cpp        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -30,12 +30,18 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><del>-FontFeature::FontFeature(const AtomicString&amp; tag, int value)
</del><ins>+FontFeature::FontFeature(const FontFeatureTag&amp; tag, int value)
</ins><span class="cx">     : m_tag(tag)
</span><span class="cx">     , m_value(value)
</span><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+FontFeature::FontFeature(FontFeatureTag&amp;&amp; tag, int value)
+    : m_tag(WTF::move(tag))
+    , m_value(value)
+{
+}
+
</ins><span class="cx"> bool FontFeature::operator==(const FontFeature&amp; other) const
</span><span class="cx"> {
</span><span class="cx">     return m_tag == other.m_tag &amp;&amp; m_value == other.m_value;
</span><span class="lines">@@ -43,14 +49,9 @@
</span><span class="cx"> 
</span><span class="cx"> bool FontFeature::operator&lt;(const FontFeature&amp; other) const
</span><span class="cx"> {
</span><del>-    return (m_tag.impl() &lt; other.m_tag.impl()) || (m_tag.impl() == other.m_tag.impl() &amp;&amp; m_value &lt; other.m_value);
</del><ins>+    return (m_tag &lt; other.m_tag) || (m_tag == other.m_tag &amp;&amp; m_value &lt; other.m_value);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-Ref&lt;FontFeatureSettings&gt; FontFeatureSettings::create()
-{
-    return adoptRef(*new FontFeatureSettings);
-}
-
</del><span class="cx"> void FontFeatureSettings::insert(FontFeature&amp;&amp; feature)
</span><span class="cx"> {
</span><span class="cx">     // This vector will almost always have 0 or 1 items in it. Don't bother with the overhead of a binary search or a hash set.
</span><span class="lines">@@ -66,7 +67,7 @@
</span><span class="cx"> {
</span><span class="cx">     IntegerHasher hasher;
</span><span class="cx">     for (auto&amp; feature : m_list) {
</span><del>-        hasher.add(feature.tag().impl()-&gt;existingHash());
</del><ins>+        hasher.add(FontFeatureTagHash::hash(feature.tag()));
</ins><span class="cx">         hasher.add(feature.value());
</span><span class="cx">     }
</span><span class="cx">     return hasher.hash();
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsFontFeatureSettingsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/FontFeatureSettings.h (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/FontFeatureSettings.h        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/graphics/FontFeatureSettings.h        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -26,6 +26,7 @@
</span><span class="cx"> #ifndef FontFeatureSettings_h
</span><span class="cx"> #define FontFeatureSettings_h
</span><span class="cx"> 
</span><ins>+#include &lt;array&gt;
</ins><span class="cx"> #include &lt;wtf/PassRefPtr.h&gt;
</span><span class="cx"> #include &lt;wtf/RefCounted.h&gt;
</span><span class="cx"> #include &lt;wtf/RefPtr.h&gt;
</span><span class="lines">@@ -34,36 +35,55 @@
</span><span class="cx"> 
</span><span class="cx"> namespace WebCore {
</span><span class="cx"> 
</span><ins>+typedef std::array&lt;char, 4&gt; FontFeatureTag;
+
+inline FontFeatureTag fontFeatureTag(const char arr[4]) { return {{ arr[0], arr[1], arr[2], arr[3] }}; }
+
+struct FontFeatureTagHash {
+    static unsigned hash(const FontFeatureTag&amp; characters) { return (characters[0] &lt;&lt; 24) | (characters[1] &lt;&lt; 16) | (characters[2] &lt;&lt; 8) | characters[3]; }
+    static bool equal(const FontFeatureTag&amp; a, const FontFeatureTag&amp; b) { return a == b; }
+    static const bool safeToCompareToEmptyOrDeleted = true;
+};
+
+struct FontFeatureTagHashTraits : WTF::GenericHashTraits&lt;FontFeatureTag&gt; {
+    static const bool emptyValueIsZero = true;
+    static void constructDeletedValue(FontFeatureTag&amp; slot) { new (NotNull, std::addressof(slot)) FontFeatureTag({{ -1, -1, -1, -1 }}); }
+    static bool isDeletedValue(const FontFeatureTag&amp; value) { return value == FontFeatureTag({{ -1, -1, -1, -1 }}); }
+};
+
</ins><span class="cx"> class FontFeature {
</span><span class="cx"> public:
</span><del>-    FontFeature(const AtomicString&amp; tag, int value);
</del><ins>+    FontFeature() = delete;
+    FontFeature(const FontFeatureTag&amp;, int value);
+    FontFeature(FontFeatureTag&amp;&amp;, int value);
</ins><span class="cx"> 
</span><span class="cx">     bool operator==(const FontFeature&amp; other) const;
</span><span class="cx">     bool operator&lt;(const FontFeature&amp; other) const;
</span><span class="cx"> 
</span><del>-    const AtomicString&amp; tag() const { return m_tag; }
</del><ins>+    const FontFeatureTag&amp; tag() const { return m_tag; }
</ins><span class="cx">     int value() const { return m_value; }
</span><span class="cx">     bool enabled() const { return value(); }
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    AtomicString m_tag;
-    const int m_value { 0 };
</del><ins>+    FontFeatureTag m_tag;
+    int m_value;
</ins><span class="cx"> };
</span><span class="cx"> 
</span><del>-class FontFeatureSettings : public RefCounted&lt;FontFeatureSettings&gt; {
</del><ins>+class FontFeatureSettings {
</ins><span class="cx"> public:
</span><del>-    static Ref&lt;FontFeatureSettings&gt; create();
-
</del><span class="cx">     void insert(FontFeature&amp;&amp;);
</span><ins>+    bool operator==(const FontFeatureSettings&amp; other) const { return m_list == other.m_list; }
</ins><span class="cx"> 
</span><span class="cx">     size_t size() const { return m_list.size(); }
</span><span class="cx">     const FontFeature&amp; operator[](int index) const { return m_list[index]; }
</span><span class="cx">     const FontFeature&amp; at(size_t index) const { return m_list.at(index); }
</span><span class="cx"> 
</span><ins>+    Vector&lt;FontFeature&gt;::const_iterator begin() const { return m_list.begin(); }
+    Vector&lt;FontFeature&gt;::const_iterator end() const { return m_list.end(); }
+
</ins><span class="cx">     unsigned hash() const;
</span><span class="cx"> 
</span><span class="cx"> private:
</span><del>-    FontFeatureSettings() { }
</del><span class="cx">     Vector&lt;FontFeature&gt; m_list;
</span><span class="cx"> };
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicscocoaFontCacheCoreTextcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/graphics/cocoa/FontCacheCoreText.cpp        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -47,9 +47,14 @@
</span><span class="cx">     CFArrayAppendValue(features, feature.get());
</span><span class="cx"> }
</span><span class="cx"> 
</span><ins>+static inline bool tagEquals(FontFeatureTag tag, const char comparison[4])
+{
+    return equalIgnoringASCIICase(tag.data(), comparison, 4);
+}
+
</ins><span class="cx"> static inline void appendTrueTypeFeature(CFMutableArrayRef features, const FontFeature&amp; feature)
</span><span class="cx"> {
</span><del>-    if (equalIgnoringASCIICase(feature.tag(), &quot;liga&quot;) || equalIgnoringASCIICase(feature.tag(), &quot;clig&quot;)) {
</del><ins>+    if (tagEquals(feature.tag(), &quot;liga&quot;) || tagEquals(feature.tag(), &quot;clig&quot;)) {
</ins><span class="cx">         if (feature.enabled()) {
</span><span class="cx">             appendRawTrueTypeFeature(features, kLigaturesType, kCommonLigaturesOnSelector);
</span><span class="cx">             appendRawTrueTypeFeature(features, kLigaturesType, kContextualLigaturesOnSelector);
</span><span class="lines">@@ -57,79 +62,79 @@
</span><span class="cx">             appendRawTrueTypeFeature(features, kLigaturesType, kCommonLigaturesOffSelector);
</span><span class="cx">             appendRawTrueTypeFeature(features, kLigaturesType, kContextualLigaturesOffSelector);
</span><span class="cx">         }
</span><del>-    } else if (equalIgnoringASCIICase(feature.tag(), &quot;dlig&quot;)) {
</del><ins>+    } else if (tagEquals(feature.tag(), &quot;dlig&quot;)) {
</ins><span class="cx">         if (feature.enabled())
</span><span class="cx">             appendRawTrueTypeFeature(features, kLigaturesType, kRareLigaturesOnSelector);
</span><span class="cx">         else
</span><span class="cx">             appendRawTrueTypeFeature(features, kLigaturesType, kRareLigaturesOffSelector);
</span><del>-    } else if (equalIgnoringASCIICase(feature.tag(), &quot;hlig&quot;)) {
</del><ins>+    } else if (tagEquals(feature.tag(), &quot;hlig&quot;)) {
</ins><span class="cx">         if (feature.enabled())
</span><span class="cx">             appendRawTrueTypeFeature(features, kLigaturesType, kHistoricalLigaturesOnSelector);
</span><span class="cx">         else
</span><span class="cx">             appendRawTrueTypeFeature(features, kLigaturesType, kHistoricalLigaturesOffSelector);
</span><del>-    } else if (equalIgnoringASCIICase(feature.tag(), &quot;calt&quot;)) {
</del><ins>+    } else if (tagEquals(feature.tag(), &quot;calt&quot;)) {
</ins><span class="cx">         if (feature.enabled())
</span><span class="cx">             appendRawTrueTypeFeature(features, kContextualAlternatesType, kContextualAlternatesOnSelector);
</span><span class="cx">         else
</span><span class="cx">             appendRawTrueTypeFeature(features, kContextualAlternatesType, kContextualAlternatesOffSelector);
</span><del>-    } else if (equalIgnoringASCIICase(feature.tag(), &quot;subs&quot;) &amp;&amp; feature.enabled())
</del><ins>+    } else if (tagEquals(feature.tag(), &quot;subs&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kVerticalPositionType, kInferiorsSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;sups&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;sups&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kVerticalPositionType, kSuperiorsSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;smcp&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;smcp&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kLowerCaseType, kLowerCaseSmallCapsSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;c2sc&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;c2sc&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kUpperCaseType, kUpperCaseSmallCapsSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;pcap&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;pcap&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kLowerCaseType, kLowerCasePetiteCapsSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;c2pc&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;c2pc&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kUpperCaseType, kUpperCasePetiteCapsSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;unic&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;unic&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kLetterCaseType, 14);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;titl&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;titl&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kStyleOptionsType, kTitlingCapsSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;lnum&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;lnum&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kNumberCaseType, kUpperCaseNumbersSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;onum&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;onum&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kNumberCaseType, kLowerCaseNumbersSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;pnum&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;pnum&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kNumberSpacingType, kProportionalNumbersSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;tnum&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;tnum&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kNumberSpacingType, kMonospacedNumbersSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;frac&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;frac&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kFractionsType, kDiagonalFractionsSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;afrc&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;afrc&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kFractionsType, kVerticalFractionsSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;ordn&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;ordn&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kVerticalPositionType, kOrdinalsSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;zero&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;zero&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kTypographicExtrasType, kSlashedZeroOnSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;hist&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;hist&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kLigaturesType, kHistoricalLigaturesOnSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;jp78&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;jp78&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kCharacterShapeType, kJIS1978CharactersSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;jp83&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;jp83&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kCharacterShapeType, kJIS1983CharactersSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;jp90&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;jp90&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kCharacterShapeType, kJIS1990CharactersSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;jp04&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;jp04&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kCharacterShapeType, kJIS2004CharactersSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;smpl&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;smpl&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kCharacterShapeType, kSimplifiedCharactersSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;trad&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;trad&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kCharacterShapeType, kTraditionalCharactersSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;fwid&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;fwid&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kTextSpacingType, kMonospacedTextSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;pwid&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;pwid&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kTextSpacingType, kProportionalTextSelector);
</span><del>-    else if (equalIgnoringASCIICase(feature.tag(), &quot;ruby&quot;) &amp;&amp; feature.enabled())
</del><ins>+    else if (tagEquals(feature.tag(), &quot;ruby&quot;) &amp;&amp; feature.enabled())
</ins><span class="cx">         appendRawTrueTypeFeature(features, kRubyKanaType, kRubyKanaOnSelector);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> static inline void appendOpenTypeFeature(CFMutableArrayRef features, const FontFeature&amp; feature)
</span><span class="cx"> {
</span><span class="cx"> #if (PLATFORM(MAC) &amp;&amp; __MAC_OS_X_VERSION_MIN_REQUIRED &gt;= 101000) || (PLATFORM(IOS) &amp;&amp; __IPHONE_OS_VERSION_MIN_REQUIRED &gt;= 80000)
</span><del>-    RetainPtr&lt;CFStringRef&gt; featureKey = feature.tag().string().createCFString();
</del><ins>+    RetainPtr&lt;CFStringRef&gt; featureKey = adoptCF(CFStringCreateWithBytes(kCFAllocatorDefault, reinterpret_cast&lt;const UInt8*&gt;(feature.tag().data()), feature.tag().size() * sizeof(FontFeatureTag::value_type), kCFStringEncodingASCII, false));
</ins><span class="cx">     int rawFeatureValue = feature.value();
</span><span class="cx">     RetainPtr&lt;CFNumberRef&gt; featureValue = adoptCF(CFNumberCreate(kCFAllocatorDefault, kCFNumberIntType, &amp;rawFeatureValue));
</span><span class="cx">     CFTypeRef featureDictionaryKeys[] = { kCTFontOpenTypeFeatureTag, kCTFontOpenTypeFeatureValue };
</span><span class="lines">@@ -142,17 +147,197 @@
</span><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-RetainPtr&lt;CTFontRef&gt; preparePlatformFont(CTFontRef originalFont, TextRenderingMode textRenderingMode, const FontFeatureSettings* features)
</del><ins>+typedef HashMap&lt;FontFeatureTag, int, FontFeatureTagHash, FontFeatureTagHashTraits&gt; FeaturesMap;
+
+static FeaturesMap computeFeatureSettingsFromVariants(const FontVariantSettings&amp; variantSettings)
</ins><span class="cx"> {
</span><del>-    if (!originalFont || ((!features || !features-&gt;size()) &amp;&amp; (textRenderingMode != OptimizeLegibility)))
</del><ins>+    FeaturesMap result;
+
+    switch (variantSettings.commonLigatures) {
+    case FontVariantLigatures::Yes:
+        result.add(fontFeatureTag(&quot;liga&quot;), 1);
+        result.add(fontFeatureTag(&quot;clig&quot;), 1);
+        break;
+    case FontVariantLigatures::No:
+        result.add(fontFeatureTag(&quot;liga&quot;), 0);
+        result.add(fontFeatureTag(&quot;clig&quot;), 0);
+        break;
+    default:
+        break;
+    }
+
+    switch (variantSettings.discretionaryLigatures) {
+    case FontVariantLigatures::Yes:
+        result.add(fontFeatureTag(&quot;dlig&quot;), 1);
+        break;
+    case FontVariantLigatures::No:
+        result.add(fontFeatureTag(&quot;dlig&quot;), 0);
+        break;
+    default:
+        break;
+    }
+
+    switch (variantSettings.historicalLigatures) {
+    case FontVariantLigatures::Yes:
+        result.add(fontFeatureTag(&quot;hlig&quot;), 1);
+        break;
+    case FontVariantLigatures::No:
+        result.add(fontFeatureTag(&quot;hlig&quot;), 0);
+        break;
+    default:
+        break;
+    }
+
+    switch (variantSettings.contextualAlternates) {
+    case FontVariantLigatures::Yes:
+        result.add(fontFeatureTag(&quot;calt&quot;), 1);
+        break;
+    case FontVariantLigatures::No:
+        result.add(fontFeatureTag(&quot;calt&quot;), 0);
+        break;
+    default:
+        break;
+    }
+
+    switch (variantSettings.position) {
+    case FontVariantPosition::Subscript:
+        result.add(fontFeatureTag(&quot;subs&quot;), 1);
+        break;
+    case FontVariantPosition::Superscript:
+        result.add(fontFeatureTag(&quot;sups&quot;), 1);
+        break;
+    default:
+        break;
+    }
+
+    switch (variantSettings.caps) {
+    case FontVariantCaps::AllSmall:
+        result.add(fontFeatureTag(&quot;c2sc&quot;), 1);
+        FALLTHROUGH;
+    case FontVariantCaps::Small:
+        result.add(fontFeatureTag(&quot;smcp&quot;), 1);
+        break;
+    case FontVariantCaps::AllPetite:
+        result.add(fontFeatureTag(&quot;c2pc&quot;), 1);
+        FALLTHROUGH;
+    case FontVariantCaps::Petite:
+        result.add(fontFeatureTag(&quot;pcap&quot;), 1);
+        break;
+    case FontVariantCaps::Unicase:
+        result.add(fontFeatureTag(&quot;unic&quot;), 1);
+        break;
+    case FontVariantCaps::Titling:
+        result.add(fontFeatureTag(&quot;titl&quot;), 1);
+        break;
+    default:
+        break;
+    }
+
+    switch (variantSettings.numericFigure) {
+    case FontVariantNumericFigure::LiningNumbers:
+        result.add(fontFeatureTag(&quot;lnum&quot;), 1);
+        break;
+    case FontVariantNumericFigure::OldStyleNumbers:
+        result.add(fontFeatureTag(&quot;onum&quot;), 1);
+        break;
+    default:
+        break;
+    }
+
+    switch (variantSettings.numericSpacing) {
+    case FontVariantNumericSpacing::ProportionalNumbers:
+        result.add(fontFeatureTag(&quot;pnum&quot;), 1);
+        break;
+    case FontVariantNumericSpacing::TabularNumbers:
+        result.add(fontFeatureTag(&quot;tnum&quot;), 1);
+        break;
+    default:
+        break;
+    }
+
+    switch (variantSettings.numericFraction) {
+    case FontVariantNumericFraction::DiagonalFractions:
+        result.add(fontFeatureTag(&quot;frac&quot;), 1);
+        break;
+    case FontVariantNumericFraction::StackedFractions:
+        result.add(fontFeatureTag(&quot;afrc&quot;), 1);
+        break;
+    default:
+        break;
+    }
+
+    if (variantSettings.numericOrdinal == FontVariantNumericOrdinal::Yes)
+        result.add(fontFeatureTag(&quot;ordn&quot;), 1);
+    if (variantSettings.numericSlashedZero == FontVariantNumericSlashedZero::Yes)
+        result.add(fontFeatureTag(&quot;zero&quot;), 1);
+
+    switch (variantSettings.alternates) {
+    case FontVariantAlternates::HistoricalForms:
+        result.add(fontFeatureTag(&quot;hist&quot;), 1);
+        break;
+    default:
+        break;
+    }
+
+    switch (variantSettings.eastAsianVariant) {
+    case FontVariantEastAsianVariant::Jis78:
+        result.add(fontFeatureTag(&quot;jp78&quot;), 1);
+        break;
+    case FontVariantEastAsianVariant::Jis83:
+        result.add(fontFeatureTag(&quot;jp83&quot;), 1);
+        break;
+    case FontVariantEastAsianVariant::Jis90:
+        result.add(fontFeatureTag(&quot;jp90&quot;), 1);
+        break;
+    case FontVariantEastAsianVariant::Jis04:
+        result.add(fontFeatureTag(&quot;jp04&quot;), 1);
+        break;
+    case FontVariantEastAsianVariant::Simplified:
+        result.add(fontFeatureTag(&quot;smpl&quot;), 1);
+        break;
+    case FontVariantEastAsianVariant::Traditional:
+        result.add(fontFeatureTag(&quot;trad&quot;), 1);
+        break;
+    default:
+        break;
+    }
+
+    switch (variantSettings.eastAsianWidth) {
+    case FontVariantEastAsianWidth::FullWidth:
+        result.add(fontFeatureTag(&quot;fwid&quot;), 1);
+        break;
+    case FontVariantEastAsianWidth::ProportionalWidth:
+        result.add(fontFeatureTag(&quot;pwid&quot;), 1);
+        break;
+    default:
+        break;
+    }
+
+    if (variantSettings.eastAsianRuby == FontVariantEastAsianRuby::Yes)
+        result.add(fontFeatureTag(&quot;ruby&quot;), 1);
+
+    return result;
+}
+
+RetainPtr&lt;CTFontRef&gt; preparePlatformFont(CTFontRef originalFont, TextRenderingMode textRenderingMode, const FontFeatureSettings&amp; features, const FontVariantSettings&amp; variantSettings)
+{
+    if (!originalFont || (!features.size() &amp;&amp; (textRenderingMode != OptimizeLegibility) &amp;&amp; variantSettings.isAllNormal()))
</ins><span class="cx">         return originalFont;
</span><span class="cx"> 
</span><ins>+    // FIXME: We don't consult with the @font-face first, like the spec says we should.
+
+    // Spec says that font-feature-settings should override font-variant-*.
+    auto fontFeatureSettingsFromVariants = computeFeatureSettingsFromVariants(variantSettings);
+    for (auto&amp; newFeature : features)
+        fontFeatureSettingsFromVariants.set(newFeature.tag(), newFeature.value());
+
</ins><span class="cx">     RetainPtr&lt;CFMutableDictionaryRef&gt; attributes = adoptCF(CFDictionaryCreateMutable(kCFAllocatorDefault, 2, &amp;kCFTypeDictionaryKeyCallBacks, &amp;kCFTypeDictionaryValueCallBacks));
</span><del>-    if (features &amp;&amp; features-&gt;size()) {
-        RetainPtr&lt;CFMutableArrayRef&gt; featureArray = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, features-&gt;size(), &amp;kCFTypeArrayCallBacks));
-        for (size_t i = 0; i &lt; features-&gt;size(); ++i) {
-            appendTrueTypeFeature(featureArray.get(), features-&gt;at(i));
-            appendOpenTypeFeature(featureArray.get(), features-&gt;at(i));
</del><ins>+    if (fontFeatureSettingsFromVariants.size()) {
+        RetainPtr&lt;CFMutableArrayRef&gt; featureArray = adoptCF(CFArrayCreateMutable(kCFAllocatorDefault, features.size(), &amp;kCFTypeArrayCallBacks));
+        for (auto&amp; p : fontFeatureSettingsFromVariants) {
+            auto feature = FontFeature(p.key, p.value);
+            appendTrueTypeFeature(featureArray.get(), feature);
+            appendOpenTypeFeature(featureArray.get(), feature);
</ins><span class="cx">         }
</span><span class="cx">         CFDictionaryAddValue(attributes.get(), kCTFontFeatureSettingsAttribute, featureArray.get());
</span><span class="cx">     }
</span><span class="lines">@@ -410,27 +595,29 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if ENABLE(PLATFORM_FONT_LOOKUP)
</span><del>-static RetainPtr&lt;CTFontRef&gt; platformFontLookupWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits requestedTraits, FontWeight weight, const FontFeatureSettings* featureSettings, TextRenderingMode textRenderingMode, float size)
</del><ins>+static RetainPtr&lt;CTFontRef&gt; platformFontLookupWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits requestedTraits, FontWeight weight, const FontFeatureSettings&amp; featureSettings, const FontVariantSettings&amp; variantSettings, TextRenderingMode textRenderingMode, float size)
</ins><span class="cx"> {
</span><span class="cx">     const auto&amp; whitelist = fontWhitelist();
</span><span class="cx">     if (whitelist.size() &amp;&amp; !whitelist.contains(family))
</span><span class="cx">         return nullptr;
</span><span class="cx"> 
</span><span class="cx">     auto foundFont = adoptCF(CTFontCreateForCSS(family.string().createCFString().get(), toCoreTextFontWeight(weight), requestedTraits, size));
</span><del>-    return preparePlatformFont(foundFont.get(), textRenderingMode, featureSettings);
</del><ins>+    return preparePlatformFont(foundFont.get(), textRenderingMode, featureSettings, variantSettings);
</ins><span class="cx"> }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><del>-static RetainPtr&lt;CTFontRef&gt; fontWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits desiredTraits, FontWeight weight, const FontFeatureSettings* featureSettings, TextRenderingMode textRenderingMode, float size)
</del><ins>+static RetainPtr&lt;CTFontRef&gt; fontWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits desiredTraits, FontWeight weight, const FontFeatureSettings&amp; featureSettings, const FontVariantSettings&amp; variantSettings, const TextRenderingMode&amp; textRenderingMode, float size)
</ins><span class="cx"> {
</span><span class="cx">     if (family.isEmpty())
</span><span class="cx">         return nullptr;
</span><span class="cx">     if (auto specialCase = platformFontWithFamilySpecialCase(family, weight, desiredTraits, size))
</span><span class="cx">         return specialCase;
</span><span class="cx"> #if ENABLE(PLATFORM_FONT_LOOKUP)
</span><del>-    return platformFontLookupWithFamily(family, desiredTraits, weight, featureSettings, textRenderingMode, size);
</del><ins>+    return platformFontLookupWithFamily(family, desiredTraits, weight, featureSettings, variantSettings, textRenderingMode, size);
</ins><span class="cx"> #else
</span><del>-    return platformFontWithFamily(family, desiredTraits, weight, featureSettings, textRenderingMode, size);
</del><ins>+    UNUSED_PARAM(featureSettings);
+    UNUSED_PARAM(variantSettings);
+    return platformFontWithFamily(family, desiredTraits, weight, textRenderingMode, size);
</ins><span class="cx"> #endif
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="lines">@@ -471,7 +658,7 @@
</span><span class="cx">     CTFontSymbolicTraits traits = computeTraits(fontDescription);
</span><span class="cx">     float size = fontDescription.computedPixelSize();
</span><span class="cx"> 
</span><del>-    RetainPtr&lt;CTFontRef&gt; font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.textRenderingMode(), size);
</del><ins>+    RetainPtr&lt;CTFontRef&gt; font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontDescription.textRenderingMode(), size);
</ins><span class="cx"> 
</span><span class="cx"> #if PLATFORM(MAC)
</span><span class="cx">     if (!font) {
</span><span class="lines">@@ -482,7 +669,7 @@
</span><span class="cx">         // Ignore the result because we want to use our own algorithm to actually find the font.
</span><span class="cx">         autoActivateFont(family.string(), size);
</span><span class="cx"> 
</span><del>-        font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.textRenderingMode(), size);
</del><ins>+        font = fontWithFamily(family, traits, fontDescription.weight(), fontDescription.featureSettings(), fontDescription.variantSettings(), fontDescription.textRenderingMode(), size);
</ins><span class="cx">     }
</span><span class="cx"> #endif
</span><span class="cx"> 
</span><span class="lines">@@ -526,7 +713,7 @@
</span><span class="cx"> 
</span><span class="cx">     const FontPlatformData&amp; platformData = originalFontData-&gt;platformData();
</span><span class="cx">     RetainPtr&lt;CTFontRef&gt; result = platformLookupFallbackFont(platformData.font(), description.weight(), description.locale(), characters, length);
</span><del>-    result = preparePlatformFont(result.get(), description.textRenderingMode(), description.featureSettings());
</del><ins>+    result = preparePlatformFont(result.get(), description.textRenderingMode(), description.featureSettings(), description.variantSettings());
</ins><span class="cx">     if (!result)
</span><span class="cx">         return lastResortFallbackFont(description);
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsharfbuzzHarfBuzzShapercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/graphics/harfbuzz/HarfBuzzShaper.cpp        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -352,16 +352,14 @@
</span><span class="cx">         ASSERT_NOT_REACHED();
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    FontFeatureSettings* settings = description.featureSettings();
-    if (!settings)
-        return;
</del><ins>+    const FontFeatureSettings&amp; settings = description.featureSettings();
</ins><span class="cx"> 
</span><del>-    unsigned numFeatures = settings-&gt;size();
</del><ins>+    unsigned numFeatures = settings.size();
</ins><span class="cx">     for (unsigned i = 0; i &lt; numFeatures; ++i) {
</span><span class="cx">         hb_feature_t feature;
</span><del>-        auto&amp; tag = settings-&gt;at(i).tag();
</del><ins>+        auto&amp; tag = settings[i].tag();
</ins><span class="cx">         feature.tag = HB_TAG(tag[0], tag[1], tag[2], tag[3]);
</span><del>-        feature.value = settings-&gt;at(i).value();
</del><ins>+        feature.value = settings[i].value();
</ins><span class="cx">         feature.start = 0;
</span><span class="cx">         feature.end = static_cast&lt;unsigned&gt;(-1);
</span><span class="cx">         m_features.append(feature);
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacFontCacheMacmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/graphics/mac/FontCacheMac.mm        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -254,7 +254,7 @@
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> #if !ENABLE(PLATFORM_FONT_LOOKUP)
</span><del>-RetainPtr&lt;CTFontRef&gt; platformFontWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits requestedTraits, FontWeight weight, const FontFeatureSettings*, TextRenderingMode, float size)
</del><ins>+RetainPtr&lt;CTFontRef&gt; platformFontWithFamily(const AtomicString&amp; family, CTFontSymbolicTraits requestedTraits, FontWeight weight, TextRenderingMode, float size)
</ins><span class="cx"> {
</span><span class="cx">     NSFontManager *fontManager = [NSFontManager sharedFontManager];
</span><span class="cx">     NSString *availableFamily;
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformgraphicsmacFontCustomPlatformDatacpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/graphics/mac/FontCustomPlatformData.cpp        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -41,7 +41,7 @@
</span><span class="cx">     FontWidthVariant widthVariant = fontDescription.widthVariant();
</span><span class="cx"> #if CORETEXT_WEB_FONTS
</span><span class="cx">     RetainPtr&lt;CTFontRef&gt; font = adoptCF(CTFontCreateWithFontDescriptor(m_fontDescriptor.get(), size, nullptr));
</span><del>-    font = preparePlatformFont(font.get(), fontDescription.textRenderingMode(), fontDescription.featureSettings());
</del><ins>+    font = preparePlatformFont(font.get(), fontDescription.textRenderingMode(), fontDescription.featureSettings(), fontDescription.variantSettings());
</ins><span class="cx">     return FontPlatformData(font.get(), size, bold, italic, orientation, widthVariant, fontDescription.textRenderingMode());
</span><span class="cx"> #else
</span><span class="cx">     return FontPlatformData(m_cgFont.get(), size, bold, italic, orientation, widthVariant, fontDescription.textRenderingMode());
</span></span></pre></div>
<a id="trunkSourceWebCoreplatformtextTextFlagsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/platform/text/TextFlags.h (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/platform/text/TextFlags.h        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/platform/text/TextFlags.h        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -72,6 +72,119 @@
</span><span class="cx"> typedef unsigned FontSynthesis;
</span><span class="cx"> const unsigned FontSynthesisWidth = 2;
</span><span class="cx"> 
</span><ins>+enum class FontVariantLigatures {
+    Normal,
+    Yes,
+    No
+};
+
+enum class FontVariantPosition {
+    Normal,
+    Subscript,
+    Superscript
+};
+
+enum class FontVariantCaps {
+    Normal,
+    Small,
+    AllSmall,
+    Petite,
+    AllPetite,
+    Unicase,
+    Titling
+};
+
+enum class FontVariantNumericFigure {
+    Normal,
+    LiningNumbers,
+    OldStyleNumbers
+};
+
+enum class FontVariantNumericSpacing {
+    Normal,
+    ProportionalNumbers,
+    TabularNumbers
+};
+
+enum class FontVariantNumericFraction {
+    Normal,
+    DiagonalFractions,
+    StackedFractions
+};
+
+enum class FontVariantNumericOrdinal {
+    Normal,
+    Yes
+};
+
+enum class FontVariantNumericSlashedZero {
+    Normal,
+    Yes
+};
+
+enum class FontVariantAlternates {
+    Normal,
+    HistoricalForms
+};
+
+enum class FontVariantEastAsianVariant {
+    Normal,
+    Jis78,
+    Jis83,
+    Jis90,
+    Jis04,
+    Simplified,
+    Traditional
+};
+
+enum class FontVariantEastAsianWidth {
+    Normal,
+    FullWidth,
+    ProportionalWidth
+};
+
+enum class FontVariantEastAsianRuby {
+    Normal,
+    Yes
+};
+
+struct FontVariantSettings {
+    bool isAllNormal() const
+    {
+        return commonLigatures == FontVariantLigatures::Normal
+            &amp;&amp; discretionaryLigatures == FontVariantLigatures::Normal
+            &amp;&amp; historicalLigatures == FontVariantLigatures::Normal
+            &amp;&amp; contextualAlternates == FontVariantLigatures::Normal
+            &amp;&amp; position == FontVariantPosition::Normal
+            &amp;&amp; caps == FontVariantCaps::Normal
+            &amp;&amp; numericFigure == FontVariantNumericFigure::Normal
+            &amp;&amp; numericSpacing == FontVariantNumericSpacing::Normal
+            &amp;&amp; numericFraction == FontVariantNumericFraction::Normal
+            &amp;&amp; numericOrdinal == FontVariantNumericOrdinal::Normal
+            &amp;&amp; numericSlashedZero == FontVariantNumericSlashedZero::Normal
+            &amp;&amp; alternates == FontVariantAlternates::Normal
+            &amp;&amp; eastAsianVariant == FontVariantEastAsianVariant::Normal
+            &amp;&amp; eastAsianWidth == FontVariantEastAsianWidth::Normal
+            &amp;&amp; eastAsianRuby == FontVariantEastAsianRuby::Normal;
+    }
+
+    FontVariantLigatures commonLigatures;
+    FontVariantLigatures discretionaryLigatures;
+    FontVariantLigatures historicalLigatures;
+    FontVariantLigatures contextualAlternates;
+    FontVariantPosition position;
+    FontVariantCaps caps;
+    FontVariantNumericFigure numericFigure;
+    FontVariantNumericSpacing numericSpacing;
+    FontVariantNumericFraction numericFraction;
+    FontVariantNumericOrdinal numericOrdinal;
+    FontVariantNumericSlashedZero numericSlashedZero;
+    FontVariantAlternates alternates;
+    FontVariantEastAsianVariant eastAsianVariant;
+    FontVariantEastAsianWidth eastAsianWidth;
+    FontVariantEastAsianRuby eastAsianRuby;
+};
+
</ins><span class="cx"> enum FontWidthVariant {
</span><span class="cx">     RegularWidth,
</span><span class="cx">     HalfWidth,
</span></span></pre></div>
<a id="trunkSourceWebCorerenderingRenderThemeIOSmm"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/RenderThemeIOS.mm (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/RenderThemeIOS.mm        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/rendering/RenderThemeIOS.mm        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -1237,7 +1237,7 @@
</span><span class="cx"> 
</span><span class="cx">     ASSERT(fontDescriptor);
</span><span class="cx">     RetainPtr&lt;CTFontRef&gt; font = adoptCF(CTFontCreateWithFontDescriptor(fontDescriptor.get(), 0, nullptr));
</span><del>-    font = preparePlatformFont(font.get(), fontDescription.textRenderingMode(), fontDescription.featureSettings());
</del><ins>+    font = preparePlatformFont(font.get(), fontDescription.textRenderingMode(), fontDescription.featureSettings(), fontDescription.variantSettings());
</ins><span class="cx">     fontDescription.setIsAbsoluteSize(true);
</span><span class="cx">     fontDescription.setOneFamily(textStyle);
</span><span class="cx">     fontDescription.setSpecifiedSize(CTFontGetSize(font.get()));
</span></span></pre></div>
<a id="trunkSourceWebCorerenderinglineBreakingContexth"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/rendering/line/BreakingContext.h (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/rendering/line/BreakingContext.h        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Source/WebCore/rendering/line/BreakingContext.h        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -83,6 +83,7 @@
</span><span class="cx">         m_state = WordTrailingSpaceState::Computed;
</span><span class="cx">         return m_width;
</span><span class="cx">     }
</span><ins>+
</ins><span class="cx"> private:
</span><span class="cx">     enum class WordTrailingSpaceState { Uninitialized, Computed };
</span><span class="cx">     WordTrailingSpaceState m_state { WordTrailingSpaceState::Uninitialized };
</span></span></pre></div>
<a id="trunkToolsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Tools/ChangeLog (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/ChangeLog        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Tools/ChangeLog        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2015-09-23  Myles C. Maxfield  &lt;mmaxfield@apple.com&gt;
+
+        [Cocoa] [Font Features] Implement font-variant-*
+        https://bugs.webkit.org/show_bug.cgi?id=148413
+
+        Reviewed by Darin Adler.
+
+        Update test font to use &quot;lnum&quot; feature.
+
+        * FontWithFeatures/FontWithFeatures/FontCreator.cpp:
+        (Generator::appendGSUBTable):
+
</ins><span class="cx"> 2015-09-22  Andy Estes  &lt;aestes@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         ContentFiltering.AllowDownloadAfterAddData is very flaky
</span></span></pre></div>
<a id="trunkToolsFontWithFeaturesFontWithFeaturesFontCreatorcpp"></a>
<div class="modfile"><h4>Modified: trunk/Tools/FontWithFeatures/FontWithFeatures/FontCreator.cpp (190191 => 190192)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Tools/FontWithFeatures/FontWithFeatures/FontCreator.cpp        2015-09-24 00:19:03 UTC (rev 190191)
+++ trunk/Tools/FontWithFeatures/FontWithFeatures/FontCreator.cpp        2015-09-24 00:40:53 UTC (rev 190192)
</span><span class="lines">@@ -470,7 +470,7 @@
</span><span class="cx"> 
</span><span class="cx">     void appendGSUBTable()
</span><span class="cx">     {
</span><del>-        std::vector&lt;std::array&lt;char, 5&gt;&gt; features {{&quot;liga&quot;}, {&quot;clig&quot;}, {&quot;dlig&quot;}, {&quot;hlig&quot;}, {&quot;calt&quot;}, {&quot;subs&quot;}, {&quot;sups&quot;}, {&quot;smcp&quot;}, {&quot;c2sc&quot;}, {&quot;pcap&quot;}, {&quot;c2pc&quot;}, {&quot;unic&quot;}, {&quot;titl&quot;}, {&quot;onum&quot;}, {&quot;pnum&quot;}, {&quot;tnum&quot;}, {&quot;frac&quot;}, {&quot;afrc&quot;}, {&quot;ordn&quot;}, {&quot;zero&quot;}, {&quot;hist&quot;}, {&quot;jp78&quot;}, {&quot;jp83&quot;}, {&quot;jp90&quot;}, {&quot;jp04&quot;}, {&quot;smpl&quot;}, {&quot;trad&quot;}, {&quot;fwid&quot;}, {&quot;pwid&quot;}, {&quot;ruby&quot;}};
</del><ins>+        std::vector&lt;std::array&lt;char, 5&gt;&gt; features {{&quot;liga&quot;}, {&quot;clig&quot;}, {&quot;dlig&quot;}, {&quot;hlig&quot;}, {&quot;calt&quot;}, {&quot;subs&quot;}, {&quot;sups&quot;}, {&quot;smcp&quot;}, {&quot;c2sc&quot;}, {&quot;pcap&quot;}, {&quot;c2pc&quot;}, {&quot;unic&quot;}, {&quot;titl&quot;}, {&quot;lnum&quot;}, {&quot;onum&quot;}, {&quot;pnum&quot;}, {&quot;tnum&quot;}, {&quot;frac&quot;}, {&quot;afrc&quot;}, {&quot;ordn&quot;}, {&quot;zero&quot;}, {&quot;hist&quot;}, {&quot;jp78&quot;}, {&quot;jp83&quot;}, {&quot;jp90&quot;}, {&quot;jp04&quot;}, {&quot;smpl&quot;}, {&quot;trad&quot;}, {&quot;fwid&quot;}, {&quot;pwid&quot;}, {&quot;ruby&quot;}};
</ins><span class="cx">         auto tableLocation = result.size();
</span><span class="cx">         auto headerSize = 10;
</span><span class="cx"> 
</span></span></pre>
</div>
</div>

</body>
</html>