From 148e59acccda9790f6db649b46652f92fa042715 Mon Sep 17 00:00:00 2001 From: Victoria Lease Date: Mon, 30 Apr 2012 16:30:16 -0700 Subject: Cherrypick WebKit r94508. http://trac.webkit.org/changeset/94508 This, in conjunction with WebKit r95959, addresses our issue involving referencing deleted fonts. Bug: 6105670 Change-Id: Ica4c89046ed47e2c75d13640a27ac92f2aad6709 --- Source/WebCore/css/CSSFontFace.cpp | 13 +++++++++++++ Source/WebCore/css/CSSFontFace.h | 1 + Source/WebCore/css/CSSFontFaceSource.cpp | 5 +++-- Source/WebCore/css/CSSFontSelector.cpp | 10 ++++++++++ Source/WebCore/css/CSSFontSelector.h | 2 ++ Source/WebCore/css/CSSSegmentedFontFace.cpp | 5 +++-- Source/WebCore/dom/Document.cpp | 19 +++++++++++++++++++ Source/WebCore/dom/Document.h | 8 +++++++- 8 files changed, 58 insertions(+), 5 deletions(-) diff --git a/Source/WebCore/css/CSSFontFace.cpp b/Source/WebCore/css/CSSFontFace.cpp index 2c50a04..3b6dea4 100644 --- a/Source/WebCore/css/CSSFontFace.cpp +++ b/Source/WebCore/css/CSSFontFace.cpp @@ -118,6 +118,19 @@ SimpleFontData* CSSFontFace::getFontData(const FontDescription& fontDescription, return 0; } +void CSSFontFace::retireCustomFont(SimpleFontData* fontData) +{ + if (m_segmentedFontFaces.isEmpty()) { + GlyphPageTreeNode::pruneTreeCustomFontData(fontData); + delete fontData; + return; + } + + // Use one of the CSSSegmentedFontFaces' font selector. They all have + // the same font selector. + (*m_segmentedFontFaces.begin())->fontSelector()->retireCustomFont(fontData); +} + #if ENABLE(SVG_FONTS) bool CSSFontFace::hasSVGFontFaceSource() const { diff --git a/Source/WebCore/css/CSSFontFace.h b/Source/WebCore/css/CSSFontFace.h index 55e048c..45f8f13 100644 --- a/Source/WebCore/css/CSSFontFace.h +++ b/Source/WebCore/css/CSSFontFace.h @@ -63,6 +63,7 @@ public: void addSource(CSSFontFaceSource*); void fontLoaded(CSSFontFaceSource*); + void retireCustomFont(SimpleFontData*); SimpleFontData* getFontData(const FontDescription&, bool syntheticBold, bool syntheticItalic); diff --git a/Source/WebCore/css/CSSFontFaceSource.cpp b/Source/WebCore/css/CSSFontFaceSource.cpp index eeb90a4..49175e6 100644 --- a/Source/WebCore/css/CSSFontFaceSource.cpp +++ b/Source/WebCore/css/CSSFontFaceSource.cpp @@ -69,10 +69,11 @@ void CSSFontFaceSource::pruneTable() { if (m_fontDataTable.isEmpty()) return; + HashMap::iterator end = m_fontDataTable.end(); for (HashMap::iterator it = m_fontDataTable.begin(); it != end; ++it) - GlyphPageTreeNode::pruneTreeCustomFontData(it->second); - deleteAllValues(m_fontDataTable); + m_face->retireCustomFont(it->second); + m_fontDataTable.clear(); } diff --git a/Source/WebCore/css/CSSFontSelector.cpp b/Source/WebCore/css/CSSFontSelector.cpp index 8024afa..0f70664 100644 --- a/Source/WebCore/css/CSSFontSelector.cpp +++ b/Source/WebCore/css/CSSFontSelector.cpp @@ -378,6 +378,16 @@ void CSSFontSelector::fontCacheInvalidated() dispatchInvalidationCallbacks(); } +void CSSFontSelector::retireCustomFont(FontData* fontData) +{ + if (m_document) + m_document->retireCustomFont(fontData); + else { + GlyphPageTreeNode::pruneTreeCustomFontData(fontData); + delete fontData; + } +} + static FontData* fontDataForGenericFamily(Document* document, const FontDescription& fontDescription, const AtomicString& familyName) { if (!document || !document->frame()) diff --git a/Source/WebCore/css/CSSFontSelector.h b/Source/WebCore/css/CSSFontSelector.h index f50ea42..2b0df28 100644 --- a/Source/WebCore/css/CSSFontSelector.h +++ b/Source/WebCore/css/CSSFontSelector.h @@ -59,6 +59,8 @@ public: void fontLoaded(); virtual void fontCacheInvalidated(); + void retireCustomFont(FontData*); + bool isEmpty() const; CachedResourceLoader* cachedResourceLoader() const; diff --git a/Source/WebCore/css/CSSSegmentedFontFace.cpp b/Source/WebCore/css/CSSSegmentedFontFace.cpp index 1f6e20d..6303ff8 100644 --- a/Source/WebCore/css/CSSSegmentedFontFace.cpp +++ b/Source/WebCore/css/CSSSegmentedFontFace.cpp @@ -52,10 +52,11 @@ void CSSSegmentedFontFace::pruneTable() // Make sure the glyph page tree prunes out all uses of this custom font. if (m_fontDataTable.isEmpty()) return; + HashMap::iterator end = m_fontDataTable.end(); for (HashMap::iterator it = m_fontDataTable.begin(); it != end; ++it) - GlyphPageTreeNode::pruneTreeCustomFontData(it->second); - deleteAllValues(m_fontDataTable); + m_fontSelector->retireCustomFont(it->second); + m_fontDataTable.clear(); } diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp index 7fc628c..e7e1124 100644 --- a/Source/WebCore/dom/Document.cpp +++ b/Source/WebCore/dom/Document.cpp @@ -561,6 +561,8 @@ Document::~Document() (*m_pageGroupUserSheets)[i]->clearOwnerNode(); } + deleteRetiredCustomFonts(); + m_weakReference->clear(); if (m_mediaQueryMatcher) @@ -1487,6 +1489,9 @@ void Document::recalcStyle(StyleChange change) if (change >= Inherit || n->childNeedsStyleRecalc() || n->needsStyleRecalc()) n->recalcStyle(change); + // Now that all RenderStyles that pointed to retired fonts have been updated, the fonts can safely be deleted. + deleteRetiredCustomFonts(); + #if USE(ACCELERATED_COMPOSITING) if (view()) { bool layoutPending = view()->layoutPending() || renderer()->needsLayout(); @@ -1623,6 +1628,20 @@ PassRefPtr Document::styleForPage(int pageIndex) return style.release(); } +void Document::retireCustomFont(FontData* fontData) +{ + m_retiredCustomFonts.append(adoptPtr(fontData)); +} + +void Document::deleteRetiredCustomFonts() +{ + size_t size = m_retiredCustomFonts.size(); + for (size_t i = 0; i < size; ++i) + GlyphPageTreeNode::pruneTreeCustomFontData(m_retiredCustomFonts[i].get()); + + m_retiredCustomFonts.clear(); +} + bool Document::isPageBoxVisible(int pageIndex) { RefPtr style = styleForPage(pageIndex); diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h index 7478e6c..a4fc266 100644 --- a/Source/WebCore/dom/Document.h +++ b/Source/WebCore/dom/Document.h @@ -76,6 +76,7 @@ class EntityReference; class Event; class EventListener; class EventQueue; +class FontData; class FormAssociatedElement; class Frame; class FrameView; @@ -526,6 +527,8 @@ public: PassRefPtr styleForElementIgnoringPendingStylesheets(Element*); PassRefPtr styleForPage(int pageIndex); + void retireCustomFont(FontData*); + // Returns true if page box (margin boxes and page borders) is visible. bool isPageBoxVisible(int pageIndex); @@ -1142,6 +1145,8 @@ private: void createStyleSelector(); + void deleteRetiredCustomFonts(); + PassRefPtr handleZeroPadding(const HitTestRequest&, HitTestResult&) const; void loadEventDelayTimerFired(Timer*); @@ -1151,7 +1156,8 @@ private: OwnPtr m_styleSelector; bool m_didCalculateStyleSelector; bool m_hasDirtyStyleSelector; - + Vector > m_retiredCustomFonts; + mutable RefPtr m_cssPrimitiveValueCache; Frame* m_frame; -- cgit v1.1