Move locale information into FontDescription
authormmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jul 2015 00:12:38 +0000 (00:12 +0000)
committermmaxfield@apple.com <mmaxfield@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 31 Jul 2015 00:12:38 +0000 (00:12 +0000)
https://bugs.webkit.org/show_bug.cgi?id=147457

Reviewed by Andreas Kling.

Currently, the "lang" attribute on a node sets locale information in RenderStyle.
Font selection is sensitive to this locale information, and occurs deep within
platform/ code, far away from RenderStyle. Because every RenderStyle owns a
FontDescription, and font selection can consult with FontDescriptions, it makes
sense to move the variable from RenderStyle to FontDescription, and provide
convenience methods on RenderStyle which inspect its FontDescription for locale
information.

This patch is in preparation for correctly obeying locale information when
performing font fallback.

No new tests because there is no behavior change.

* css/CSSPropertyNames.in:
* css/StyleBuilderCustom.h:
(WebCore::StyleBuilderCustom::applyValueWebkitLocale):
* platform/graphics/FontCache.h:
(WebCore::FontDescriptionKey::FontDescriptionKey):
(WebCore::FontDescriptionKey::operator==):
* platform/graphics/FontCascade.cpp:
* platform/graphics/FontDescription.cpp:
(WebCore::FontDescription::FontDescription):
(WebCore::FontDescription::setLocale):
* platform/graphics/FontDescription.h:
(WebCore::FontDescription::locale):
(WebCore::FontDescription::initialLocale):
(WebCore::FontDescription::operator==):
(WebCore::FontDescription::FontDescription): Deleted.
(WebCore::FontDescription::setScript): Deleted.
* platform/text/LocaleToScriptMappingDefault.cpp:
(WebCore::localeToScriptCodeForFontSelection):
* rendering/style/RenderStyle.cpp:
(WebCore::RenderStyle::changeRequiresLayout): Deleted.
* rendering/style/RenderStyle.h:
* rendering/style/StyleRareInheritedData.cpp:
(WebCore::StyleRareInheritedData::StyleRareInheritedData): Deleted.
(WebCore::StyleRareInheritedData::operator==): Deleted.
* rendering/style/StyleRareInheritedData.h:
* style/StyleResolveForDocument.cpp:
(WebCore::Style::resolveForDocument):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@187626 268f45cc-cd09-0410-ab3c-d52691b4dbfc

13 files changed:
Source/WebCore/ChangeLog
Source/WebCore/css/CSSPropertyNames.in
Source/WebCore/css/StyleBuilderCustom.h
Source/WebCore/platform/graphics/FontCache.h
Source/WebCore/platform/graphics/FontCascade.cpp
Source/WebCore/platform/graphics/FontDescription.cpp
Source/WebCore/platform/graphics/FontDescription.h
Source/WebCore/platform/text/LocaleToScriptMappingDefault.cpp
Source/WebCore/rendering/style/RenderStyle.cpp
Source/WebCore/rendering/style/RenderStyle.h
Source/WebCore/rendering/style/StyleRareInheritedData.cpp
Source/WebCore/rendering/style/StyleRareInheritedData.h
Source/WebCore/style/StyleResolveForDocument.cpp

index f73ef95..ac49a6c 100644 (file)
@@ -1,3 +1,51 @@
+2015-07-30  Myles C. Maxfield  <mmaxfield@apple.com>
+
+        Move locale information into FontDescription
+        https://bugs.webkit.org/show_bug.cgi?id=147457
+
+        Reviewed by Andreas Kling.
+
+        Currently, the "lang" attribute on a node sets locale information in RenderStyle.
+        Font selection is sensitive to this locale information, and occurs deep within
+        platform/ code, far away from RenderStyle. Because every RenderStyle owns a
+        FontDescription, and font selection can consult with FontDescriptions, it makes
+        sense to move the variable from RenderStyle to FontDescription, and provide
+        convenience methods on RenderStyle which inspect its FontDescription for locale
+        information.
+
+        This patch is in preparation for correctly obeying locale information when
+        performing font fallback.
+
+        No new tests because there is no behavior change.
+
+        * css/CSSPropertyNames.in:
+        * css/StyleBuilderCustom.h:
+        (WebCore::StyleBuilderCustom::applyValueWebkitLocale):
+        * platform/graphics/FontCache.h:
+        (WebCore::FontDescriptionKey::FontDescriptionKey):
+        (WebCore::FontDescriptionKey::operator==):
+        * platform/graphics/FontCascade.cpp:
+        * platform/graphics/FontDescription.cpp:
+        (WebCore::FontDescription::FontDescription):
+        (WebCore::FontDescription::setLocale):
+        * platform/graphics/FontDescription.h:
+        (WebCore::FontDescription::locale):
+        (WebCore::FontDescription::initialLocale):
+        (WebCore::FontDescription::operator==):
+        (WebCore::FontDescription::FontDescription): Deleted.
+        (WebCore::FontDescription::setScript): Deleted.
+        * platform/text/LocaleToScriptMappingDefault.cpp:
+        (WebCore::localeToScriptCodeForFontSelection):
+        * rendering/style/RenderStyle.cpp:
+        (WebCore::RenderStyle::changeRequiresLayout): Deleted.
+        * rendering/style/RenderStyle.h:
+        * rendering/style/StyleRareInheritedData.cpp:
+        (WebCore::StyleRareInheritedData::StyleRareInheritedData): Deleted.
+        (WebCore::StyleRareInheritedData::operator==): Deleted.
+        * rendering/style/StyleRareInheritedData.h:
+        * style/StyleResolveForDocument.cpp:
+        (WebCore::Style::resolveForDocument):
+
 2015-07-30  Anders Carlsson  <andersca@apple.com>
 
         Remove stray printf.
index 5122c4f..eaeb14d 100644 (file)
@@ -109,7 +109,7 @@ text-rendering [Inherited, FontProperty, NameForMethods=TextRenderingMode]
 -webkit-font-kerning [Inherited, FontProperty, NameForMethods=Kerning]
 -webkit-font-smoothing [Inherited, FontProperty]
 -webkit-font-variant-ligatures [Inherited, Custom=All]
--webkit-locale [Inherited, Custom=Value]
+-webkit-locale [Inherited, FontProperty, Custom=Value]
 -webkit-text-orientation [Inherited, Custom=Value]
 -epub-text-orientation = -webkit-text-orientation
 #if defined(ENABLE_IOS_TEXT_AUTOSIZING) && ENABLE_IOS_TEXT_AUTOSIZING
index 17ed265..2eb1aa0 100644 (file)
@@ -40,7 +40,6 @@
 #include "ElementAncestorIterator.h"
 #include "Frame.h"
 #include "HTMLElement.h"
-#include "LocaleToScriptMapping.h"
 #include "Rect.h"
 #include "RenderTheme.h"
 #include "SVGElement.h"
@@ -691,14 +690,12 @@ inline void StyleBuilderCustom::applyValueClip(StyleResolver& styleResolver, CSS
 inline void StyleBuilderCustom::applyValueWebkitLocale(StyleResolver& styleResolver, CSSValue& value)
 {
     auto& primitiveValue = downcast<CSSPrimitiveValue>(value);
-
-    if (primitiveValue.getValueID() == CSSValueAuto)
-        styleResolver.style()->setLocale(nullAtom);
-    else
-        styleResolver.style()->setLocale(primitiveValue.getStringValue());
     
     FontDescription fontDescription = styleResolver.style()->fontDescription();
-    fontDescription.setScript(localeToScriptCodeForFontSelection(styleResolver.style()->locale()));
+    if (primitiveValue.getValueID() == CSSValueAuto)
+        fontDescription.setLocale(nullAtom);
+    else
+        fontDescription.setLocale(primitiveValue.getStringValue());
     styleResolver.setFontDescription(fontDescription);
 }
 
index c625688..3a3d862 100644 (file)
@@ -71,11 +71,13 @@ struct FontDescriptionKey {
         : size(size)
         , weight(0)
         , flags(0)
+        , localeHash(0)
     { }
     FontDescriptionKey(const FontDescription& description)
         : size(description.computedPixelSize())
         , weight(description.weight())
         , flags(makeFlagKey(description))
+        , localeHash(description.locale().isNull() ? 0 : description.locale().impl()->existingHash())
     { }
     static unsigned makeFlagKey(const FontDescription& description)
     {
@@ -91,7 +93,7 @@ struct FontDescriptionKey {
     }
     bool operator==(const FontDescriptionKey& other) const
     {
-        return size == other.size && weight == other.weight && flags == other.flags;
+        return size == other.size && weight == other.weight && flags == other.flags && localeHash == other.localeHash;
     }
     bool operator!=(const FontDescriptionKey& other) const
     {
@@ -104,6 +106,7 @@ struct FontDescriptionKey {
     unsigned size;
     unsigned weight;
     unsigned flags;
+    unsigned localeHash; // FIXME: Here, and every client of us, makes hashes of hashes.
 };
 
 class FontCache {
index 150840c..25b901c 100644 (file)
@@ -178,8 +178,7 @@ bool FontCascade::operator==(const FontCascade& other) const
 }
 
 struct FontCascadeCacheKey {
-    // This part of the key is shared with the lower level FontCache (caching FontData objects).
-    FontDescriptionKey fontDescriptionKey;
+    FontDescriptionKey fontDescriptionKey; // Shared with the lower level FontCache (caching Font objects)
     Vector<AtomicString, 3> families;
     unsigned fontSelectorId;
     unsigned fontSelectorVersion;
@@ -241,6 +240,7 @@ static FontCascadeCacheKey makeFontCascadeCacheKey(const FontDescription& descri
     return key;
 }
 
+// FIXME: Why can't we just teach HashMap about FontCascadeCacheKey instead of hashing a hash?
 static unsigned computeFontCascadeCacheHash(const FontCascadeCacheKey& key)
 {
     Vector<unsigned, 7> hashCodes;
index bd53ae0..d0c30bb 100644 (file)
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (C) 2007 Nicholas Shanks <contact@nickshanks.com>
  * Copyright (C) 2008, 2013 Apple Inc. All rights reserved.
 
 #include "config.h"
 #include "FontDescription.h"
+#include "LocaleToScriptMapping.h"
 
 namespace WebCore {
 
 struct SameSizeAsFontDescription {
-    void* pointers[2];
+    void* pointers[3];
     float sizes[2];
-    // FXIME: Make them fit into one word.
+    // FIXME: Make them fit into one word.
     uint32_t bitfields;
     uint32_t bitfields2 : 8;
 };
 
 COMPILE_ASSERT(sizeof(FontDescription) == sizeof(SameSizeAsFontDescription), FontDescription_should_stay_small);
 
+FontDescription::FontDescription()
+    : m_orientation(Horizontal)
+    , m_nonCJKGlyphOrientation(NonCJKGlyphOrientationVerticalRight)
+    , m_widthVariant(RegularWidth)
+    , m_italic(FontItalicOff)
+    , m_smallCaps(FontSmallCapsOff)
+    , m_isAbsoluteSize(false)
+    , m_weight(FontWeightNormal)
+    , m_renderingMode(NormalRenderingMode)
+    , m_kerning(AutoKerning)
+    , m_commonLigaturesState(NormalLigaturesState)
+    , m_discretionaryLigaturesState(NormalLigaturesState)
+    , m_historicalLigaturesState(NormalLigaturesState)
+    , m_keywordSize(0)
+    , m_fontSmoothing(AutoSmoothing)
+    , m_textRendering(AutoTextRendering)
+    , m_isSpecifiedFont(false)
+    , m_script(localeToScriptCodeForFontSelection(m_locale))
+    , m_fontSynthesis(initialFontSynthesis())
+{
+}
+
 FontWeight FontDescription::lighterWeight(void) const
 {
     switch (m_weight) {
@@ -94,6 +118,12 @@ FontTraitsMask FontDescription::traitsMask() const
     
 }
 
+void FontDescription::setLocale(const AtomicString& locale)
+{
+    m_locale = locale;
+    m_script = localeToScriptCodeForFontSelection(m_locale);
+}
+
 #if ENABLE(IOS_TEXT_AUTOSIZING)
 bool FontDescription::familiesEqualForTextAutoSizing(const FontDescription& other) const
 {
index d80a2d5..5763279 100644 (file)
@@ -44,30 +44,7 @@ public:
 
     enum LigaturesState { NormalLigaturesState, DisabledLigaturesState, EnabledLigaturesState };
 
-    FontDescription()
-        : m_families(1)
-        , m_specifiedSize(0)
-        , m_computedSize(0)
-        , m_orientation(Horizontal)
-        , m_nonCJKGlyphOrientation(NonCJKGlyphOrientationVerticalRight)
-        , m_widthVariant(RegularWidth)
-        , m_italic(FontItalicOff)
-        , m_smallCaps(FontSmallCapsOff)
-        , m_isAbsoluteSize(false)
-        , m_weight(FontWeightNormal)
-        , m_renderingMode(NormalRenderingMode)
-        , m_kerning(AutoKerning)
-        , m_commonLigaturesState(NormalLigaturesState)
-        , m_discretionaryLigaturesState(NormalLigaturesState)
-        , m_historicalLigaturesState(NormalLigaturesState)
-        , m_keywordSize(0)
-        , m_fontSmoothing(AutoSmoothing)
-        , m_textRendering(AutoTextRendering)
-        , m_isSpecifiedFont(false)
-        , m_script(USCRIPT_COMMON)
-        , m_fontSynthesis(initialFontSynthesis())
-    {
-    }
+    WEBCORE_EXPORT FontDescription();
 
     bool operator==(const FontDescription&) const;
     bool operator!=(const FontDescription& other) const { return !(*this == other); }
@@ -103,6 +80,7 @@ public:
     FontSmoothingMode fontSmoothing() const { return static_cast<FontSmoothingMode>(m_fontSmoothing); }
     TextRenderingMode textRenderingMode() const { return static_cast<TextRenderingMode>(m_textRendering); }
     UScriptCode script() const { return static_cast<UScriptCode>(m_script); }
+    const AtomicString& locale() const { return m_locale; }
 
     FontTraitsMask traitsMask() const;
     bool isSpecifiedFont() const { return m_isSpecifiedFont; }
@@ -147,7 +125,7 @@ public:
     void setOrientation(FontOrientation orientation) { m_orientation = orientation; }
     void setNonCJKGlyphOrientation(NonCJKGlyphOrientation orientation) { m_nonCJKGlyphOrientation = orientation; }
     void setWidthVariant(FontWidthVariant widthVariant) { m_widthVariant = widthVariant; }
-    void setScript(UScriptCode s) { m_script = s; }
+    void setLocale(const AtomicString&);
     void setFeatureSettings(PassRefPtr<FontFeatureSettings> settings) { m_featureSettings = settings; }
     void setFontSynthesis(FontSynthesis fontSynthesis) { m_fontSynthesis = fontSynthesis; }
 
@@ -170,14 +148,16 @@ public:
     static FontSmoothingMode initialFontSmoothing() { return AutoSmoothing; }
     static TextRenderingMode initialTextRenderingMode() { return AutoTextRendering; }
     static FontSynthesis initialFontSynthesis() { return FontSynthesisWeight | FontSynthesisStyle; }
+    static const AtomicString& initialLocale() { return nullAtom; }
 
 private:
-    RefCountedArray<AtomicString> m_families;
+    RefCountedArray<AtomicString> m_families { 1 };
     RefPtr<FontFeatureSettings> m_featureSettings;
+    AtomicString m_locale { initialLocale() };
 
-    float m_specifiedSize;   // Specified CSS value. Independent of rendering issues such as integer
+    float m_specifiedSize { 0 };   // Specified CSS value. Independent of rendering issues such as integer
                              // rounding, minimum font sizes, and zooming.
-    float m_computedSize;    // Computed size adjusted for the minimum font size and the zoom factor.  
+    float m_computedSize { 0 };    // Computed size adjusted for the minimum font size and the zoom factor.
 
     unsigned m_orientation : 1; // FontOrientation - Whether the font is rendering on a horizontal line or a vertical line.
     unsigned m_nonCJKGlyphOrientation : 1; // NonCJKGlyphOrientation - Only used by vertical text. Determines the default orientation for non-ideograph glyphs.
@@ -229,7 +209,7 @@ inline bool FontDescription::operator==(const FontDescription& other) const
         && m_orientation == other.m_orientation
         && m_nonCJKGlyphOrientation == other.m_nonCJKGlyphOrientation
         && m_widthVariant == other.m_widthVariant
-        && m_script == other.m_script
+        && m_locale == other.m_locale
         && m_featureSettings == other.m_featureSettings
         && m_fontSynthesis == other.m_fontSynthesis;
 }
index d649544..3167f40 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <wtf/HashMap.h>
 #include <wtf/HashSet.h>
+#include <wtf/NeverDestroyed.h>
 #include <wtf/text/StringHash.h>
 
 namespace WebCore {
@@ -389,16 +390,16 @@ typedef HashMap<String, UScriptCode, DefaultHash<String>::Hash, LocaleScriptMapH
 
 UScriptCode localeToScriptCodeForFontSelection(const String& locale)
 {
-    DEPRECATED_DEFINE_STATIC_LOCAL(LocaleScriptMap, localeScriptMap, ());
-    if (localeScriptMap.isEmpty()) {
+    static NeverDestroyed<LocaleScriptMap> localeScriptMap;
+    if (localeScriptMap.get().isEmpty()) {
         for (size_t i = 0; i < sizeof(localeScriptList) / sizeof(LocaleScript); ++i)
-            localeScriptMap.set(ASCIILiteral(localeScriptList[i].locale), localeScriptList[i].script);
+            localeScriptMap.get().set(ASCIILiteral(localeScriptList[i].locale), localeScriptList[i].script);
     }
 
     String canonicalLocale = locale.lower().replace('-', '_');
     while (!canonicalLocale.isEmpty()) {
-        LocaleScriptMap::iterator it = localeScriptMap.find(canonicalLocale);
-        if (it != localeScriptMap.end())
+        LocaleScriptMap::iterator it = localeScriptMap.get().find(canonicalLocale);
+        if (it != localeScriptMap.get().end())
             return it->value;
         size_t pos = canonicalLocale.reverseFind('_');
         if (pos == notFound)
index 3d23484..ddf0198 100644 (file)
@@ -576,7 +576,6 @@ bool RenderStyle::changeRequiresLayout(const RenderStyle& other, unsigned& chang
             || rareInheritedData->hyphenationLimitBefore != other.rareInheritedData->hyphenationLimitBefore
             || rareInheritedData->hyphenationLimitAfter != other.rareInheritedData->hyphenationLimitAfter
             || rareInheritedData->hyphenationString != other.rareInheritedData->hyphenationString
-            || rareInheritedData->locale != other.rareInheritedData->locale
             || rareInheritedData->m_rubyPosition != other.rareInheritedData->m_rubyPosition
             || rareInheritedData->textEmphasisMark != other.rareInheritedData->textEmphasisMark
             || rareInheritedData->textEmphasisPosition != other.rareInheritedData->textEmphasisPosition
index 140f492..0436f2b 100644 (file)
@@ -998,7 +998,7 @@ public:
     short hyphenationLimitAfter() const { return rareInheritedData->hyphenationLimitAfter; }
     short hyphenationLimitLines() const { return rareInheritedData->hyphenationLimitLines; }
     const AtomicString& hyphenationString() const { return rareInheritedData->hyphenationString; }
-    const AtomicString& locale() const { return rareInheritedData->locale; }
+    const AtomicString& locale() const { return fontDescription().locale(); }
     EBorderFit borderFit() const { return static_cast<EBorderFit>(rareNonInheritedData->m_borderFit); }
     EResize resize() const { return static_cast<EResize>(rareInheritedData->resize); }
     ColumnAxis columnAxis() const { return static_cast<ColumnAxis>(rareNonInheritedData->m_multiCol->m_axis); }
@@ -1572,7 +1572,6 @@ public:
     void setHyphenationLimitAfter(short limit) { SET_VAR(rareInheritedData, hyphenationLimitAfter, limit); }
     void setHyphenationLimitLines(short limit) { SET_VAR(rareInheritedData, hyphenationLimitLines, limit); }
     void setHyphenationString(const AtomicString& h) { SET_VAR(rareInheritedData, hyphenationString, h); }
-    void setLocale(const AtomicString& locale) { SET_VAR(rareInheritedData, locale, locale); }
     void setBorderFit(EBorderFit b) { SET_VAR(rareNonInheritedData, m_borderFit, b); }
     void setResize(EResize r) { SET_VAR(rareInheritedData, resize, r); }
     void setColumnAxis(ColumnAxis axis) { SET_VAR(rareNonInheritedData.access()->m_multiCol, m_axis, axis); }
@@ -1966,7 +1965,6 @@ public:
     static short initialHyphenationLimitAfter() { return -1; }
     static short initialHyphenationLimitLines() { return -1; }
     static const AtomicString& initialHyphenationString() { return nullAtom; }
-    static const AtomicString& initialLocale() { return nullAtom; }
     static EBorderFit initialBorderFit() { return BorderFitBorder; }
     static EResize initialResize() { return RESIZE_NONE; }
     static ControlPart initialAppearance() { return NoControlPart; }
index dffa90e..c60240b 100644 (file)
@@ -206,7 +206,6 @@ inline StyleRareInheritedData::StyleRareInheritedData(const StyleRareInheritedDa
     , hyphenationLimitBefore(o.hyphenationLimitBefore)
     , hyphenationLimitAfter(o.hyphenationLimitAfter)
     , hyphenationLimitLines(o.hyphenationLimitLines)
-    , locale(o.locale)
     , textEmphasisCustomMark(o.textEmphasisCustomMark)
     , m_lineGrid(o.m_lineGrid)
     , m_tabSize(o.m_tabSize)
@@ -302,7 +301,6 @@ bool StyleRareInheritedData::operator==(const StyleRareInheritedData& o) const
         && touchCalloutEnabled == o.touchCalloutEnabled
 #endif
         && hyphenationString == o.hyphenationString
-        && locale == o.locale
         && textEmphasisCustomMark == o.textEmphasisCustomMark
         && quotesDataEquivalent(quotes.get(), o.quotes.get())
         && m_tabSize == o.m_tabSize
index 2cd9954..e85031b 100644 (file)
@@ -139,8 +139,6 @@ public:
     short hyphenationLimitAfter;
     short hyphenationLimitLines;
 
-    AtomicString locale;
-
     AtomicString textEmphasisCustomMark;
     RefPtr<QuotesData> quotes;
 
index 0d257d0..b0e3424 100644 (file)
@@ -59,7 +59,9 @@ Ref<RenderStyle> resolveForDocument(const Document& document)
     documentStyle.get().setRTLOrdering(document.visuallyOrdered() ? VisualOrder : LogicalOrder);
     documentStyle.get().setZoom(!document.printing() ? renderView.frame().pageZoomFactor() : 1);
     documentStyle.get().setPageScaleTransform(renderView.frame().frameScaleFactor());
-    documentStyle.get().setLocale(document.contentLanguage());
+    FontDescription documentFontDescription = documentStyle.get().fontDescription();
+    documentFontDescription.setLocale(document.contentLanguage());
+    documentStyle.get().setFontDescription(WTF::move(documentFontDescription));
 
     // This overrides any -webkit-user-modify inherited from the parent iframe.
     documentStyle.get().setUserModify(document.inDesignMode() ? READ_WRITE : READ_ONLY);
@@ -97,7 +99,7 @@ Ref<RenderStyle> resolveForDocument(const Document& document)
     const Settings& settings = renderView.frame().settings();
 
     FontDescription fontDescription;
-    fontDescription.setScript(localeToScriptCodeForFontSelection(documentStyle.get().locale()));
+    fontDescription.setLocale(document.contentLanguage());
     fontDescription.setRenderingMode(settings.fontRenderingMode());
     fontDescription.setOneFamily(standardFamily);