Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / css / CSSSegmentedFontFace.cpp
index 1ebbc56..434fbdc 100644 (file)
@@ -28,6 +28,7 @@
 
 #include "RuntimeEnabledFeatures.h"
 #include "core/css/CSSFontFace.h"
+#include "core/css/CSSFontSelector.h"
 #include "platform/fonts/FontCache.h"
 #include "platform/fonts/FontDescription.h"
 #include "platform/fonts/SegmentedFontData.h"
@@ -35,9 +36,9 @@
 
 namespace WebCore {
 
-CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector* fontSelector, FontTraitsMask traitsMask)
+CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector* fontSelector, FontTraits traits)
     : m_fontSelector(fontSelector)
-    , m_traitsMask(traitsMask)
+    , m_traits(traits)
     , m_firstNonCssConnectedFace(m_fontFaces.end())
 {
 }
@@ -45,8 +46,10 @@ CSSSegmentedFontFace::CSSSegmentedFontFace(CSSFontSelector* fontSelector, FontTr
 CSSSegmentedFontFace::~CSSSegmentedFontFace()
 {
     pruneTable();
+#if !ENABLE(OILPAN)
     for (FontFaceList::iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it)
-        (*it)->clearSegmentedFontFace();
+        (*it)->cssFontFace()->clearSegmentedFontFace();
+#endif
 }
 
 void CSSSegmentedFontFace::pruneTable()
@@ -62,7 +65,7 @@ bool CSSSegmentedFontFace::isValid() const
 {
     // Valid if at least one font face is valid.
     for (FontFaceList::const_iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it) {
-        if ((*it)->isValid())
+        if ((*it)->cssFontFace()->isValid())
             return true;
     }
     return false;
@@ -71,36 +74,32 @@ bool CSSSegmentedFontFace::isValid() const
 void CSSSegmentedFontFace::fontLoaded(CSSFontFace*)
 {
     pruneTable();
+}
 
-    if (RuntimeEnabledFeatures::fontLoadEventsEnabled() && !isLoading()) {
-        Vector<RefPtr<LoadFontCallback> > callbacks;
-        m_callbacks.swap(callbacks);
-        for (size_t index = 0; index < callbacks.size(); ++index) {
-            if (isLoaded())
-                callbacks[index]->notifyLoaded(this);
-            else
-                callbacks[index]->notifyError(this);
-        }
-    }
+void CSSSegmentedFontFace::fontLoadWaitLimitExceeded(CSSFontFace*)
+{
+    m_fontSelector->fontLoaded();
+    pruneTable();
 }
 
-void CSSSegmentedFontFace::addFontFace(PassRefPtr<CSSFontFace> prpFontFace, bool cssConnected)
+void CSSSegmentedFontFace::addFontFace(PassRefPtrWillBeRawPtr<FontFace> prpFontFace, bool cssConnected)
 {
-    RefPtr<CSSFontFace> fontFace = prpFontFace;
+    RefPtrWillBeRawPtr<FontFace> fontFace = prpFontFace;
     pruneTable();
-    fontFace->setSegmentedFontFace(this);
+    fontFace->cssFontFace()->setSegmentedFontFace(this);
     if (cssConnected) {
         m_fontFaces.insertBefore(m_firstNonCssConnectedFace, fontFace);
     } else {
-        FontFaceList::AddResult result = m_fontFaces.add(fontFace);
+        // This is the only place in Blink that is using addReturnIterator.
+        FontFaceList::iterator iterator = m_fontFaces.addReturnIterator(fontFace);
         if (m_firstNonCssConnectedFace == m_fontFaces.end())
-            m_firstNonCssConnectedFace = result.iterator;
+            m_firstNonCssConnectedFace = iterator;
     }
 }
 
-void CSSSegmentedFontFace::removeFontFace(PassRefPtr<CSSFontFace> prpFontFace)
+void CSSSegmentedFontFace::removeFontFace(PassRefPtrWillBeRawPtr<FontFace> prpFontFace)
 {
-    RefPtr<CSSFontFace> fontFace = prpFontFace;
+    RefPtrWillBeRawPtr<FontFace> fontFace = prpFontFace;
     FontFaceList::iterator it = m_fontFaces.find(fontFace);
     if (it == m_fontFaces.end())
         return;
@@ -110,7 +109,7 @@ void CSSSegmentedFontFace::removeFontFace(PassRefPtr<CSSFontFace> prpFontFace)
     m_fontFaces.remove(it);
 
     pruneTable();
-    fontFace->clearSegmentedFontFace();
+    fontFace->cssFontFace()->clearSegmentedFontFace();
 }
 
 static void appendFontData(SegmentedFontData* newFontData, PassRefPtr<SimpleFontData> prpFaceFontData, const CSSFontFace::UnicodeRangeSet& ranges)
@@ -129,13 +128,13 @@ static void appendFontData(SegmentedFontData* newFontData, PassRefPtr<SimpleFont
 PassRefPtr<FontData> CSSSegmentedFontFace::getFontData(const FontDescription& fontDescription)
 {
     if (!isValid())
-        return 0;
+        return nullptr;
 
-    FontTraitsMask desiredTraitsMask = fontDescription.traitsMask();
+    FontTraits desiredTraits = fontDescription.traits();
     AtomicString emptyFontFamily = "";
-    FontCacheKey key = fontDescription.cacheKey(emptyFontFamily, desiredTraitsMask);
+    FontCacheKey key = fontDescription.cacheKey(emptyFontFamily, desiredTraits);
 
-    RefPtr<SegmentedFontData>& fontData = m_fontDataTable.add(key.hash(), 0).iterator->value;
+    RefPtr<SegmentedFontData>& fontData = m_fontDataTable.add(key.hash(), nullptr).storedValue->value;
     if (fontData && fontData->numRanges())
         return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has.
 
@@ -143,28 +142,28 @@ PassRefPtr<FontData> CSSSegmentedFontFace::getFontData(const FontDescription& fo
         fontData = SegmentedFontData::create();
 
     FontDescription requestedFontDescription(fontDescription);
-    requestedFontDescription.setTraitsMask(m_traitsMask);
-    requestedFontDescription.setSyntheticBold(!(m_traitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask)) && (desiredTraitsMask & (FontWeight600Mask | FontWeight700Mask | FontWeight800Mask | FontWeight900Mask)));
-    requestedFontDescription.setSyntheticItalic(!(m_traitsMask & FontStyleItalicMask) && (desiredTraitsMask & FontStyleItalicMask));
+    requestedFontDescription.setTraits(m_traits);
+    requestedFontDescription.setSyntheticBold(m_traits.weight() < FontWeight600 && desiredTraits.weight() >= FontWeight600);
+    requestedFontDescription.setSyntheticItalic(m_traits.style() == FontStyleNormal && desiredTraits.style() == FontStyleItalic);
 
     for (FontFaceList::reverse_iterator it = m_fontFaces.rbegin(); it != m_fontFaces.rend(); ++it) {
-        if (!(*it)->isValid())
+        if (!(*it)->cssFontFace()->isValid())
             continue;
-        if (RefPtr<SimpleFontData> faceFontData = (*it)->getFontData(requestedFontDescription)) {
+        if (RefPtr<SimpleFontData> faceFontData = (*it)->cssFontFace()->getFontData(requestedFontDescription)) {
             ASSERT(!faceFontData->isSegmented());
 #if ENABLE(SVG_FONTS)
             // For SVG Fonts that specify that they only support the "normal" variant, we will assume they are incapable
             // of small-caps synthesis and just ignore the font face.
-            if (faceFontData->isSVGFont() && (desiredTraitsMask & FontVariantSmallCapsMask) && !(m_traitsMask & FontVariantSmallCapsMask))
+            if (faceFontData->isSVGFont() && desiredTraits.variant() == FontVariantSmallCaps && m_traits.variant() == FontVariantNormal)
                 continue;
 #endif
-            appendFontData(fontData.get(), faceFontData.release(), (*it)->ranges());
+            appendFontData(fontData.get(), faceFontData.release(), (*it)->cssFontFace()->ranges());
         }
     }
     if (fontData->numRanges())
         return fontData; // No release, we have a reference to an object in the cache which should retain the ref count it has.
 
-    return 0;
+    return nullptr;
 }
 
 bool CSSSegmentedFontFace::isLoading() const
@@ -185,46 +184,37 @@ bool CSSSegmentedFontFace::isLoaded() const
     return true;
 }
 
-void CSSSegmentedFontFace::willUseFontData(const FontDescription& fontDescription)
+void CSSSegmentedFontFace::willUseFontData(const FontDescription& fontDescription, UChar32 character)
 {
-    for (FontFaceList::iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it)
-        (*it)->willUseFontData(fontDescription);
+    for (FontFaceList::reverse_iterator it = m_fontFaces.rbegin(); it != m_fontFaces.rend(); ++it) {
+        if ((*it)->loadStatus() != FontFace::Unloaded)
+            break;
+        if ((*it)->cssFontFace()->maybeScheduleFontLoad(fontDescription, character))
+            break;
+    }
 }
 
 bool CSSSegmentedFontFace::checkFont(const String& text) const
 {
     for (FontFaceList::const_iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it) {
-        if ((*it)->loadStatus() != FontFace::Loaded && (*it)->ranges().intersectsWith(text))
+        if ((*it)->loadStatus() != FontFace::Loaded && (*it)->cssFontFace()->ranges().intersectsWith(text))
             return false;
     }
     return true;
 }
 
-void CSSSegmentedFontFace::loadFont(const FontDescription& fontDescription, const String& text, PassRefPtr<LoadFontCallback> callback)
+void CSSSegmentedFontFace::match(const String& text, WillBeHeapVector<RefPtrWillBeMember<FontFace> >& faces) const
 {
-    for (FontFaceList::iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it) {
-        if ((*it)->loadStatus() == FontFace::Unloaded && (*it)->ranges().intersectsWith(text))
-            (*it)->load(fontDescription);
-    }
-
-    if (callback) {
-        if (isLoading())
-            m_callbacks.append(callback);
-        else if (isLoaded())
-            callback->notifyLoaded(this);
-        else
-            callback->notifyError(this);
+    for (FontFaceList::const_iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it) {
+        if ((*it)->cssFontFace()->ranges().intersectsWith(text))
+            faces.append(*it);
     }
 }
 
-Vector<RefPtr<FontFace> > CSSSegmentedFontFace::fontFaces(const String& text) const
+void CSSSegmentedFontFace::trace(Visitor* visitor)
 {
-    Vector<RefPtr<FontFace> > fontFaces;
-    for (FontFaceList::const_iterator it = m_fontFaces.begin(); it != m_fontFaces.end(); ++it) {
-        if ((*it)->ranges().intersectsWith(text))
-            fontFaces.append((*it)->fontFace());
-    }
-    return fontFaces;
+    visitor->trace(m_fontSelector);
+    visitor->trace(m_fontFaces);
 }
 
 }