- Revision
- 94508
- Author
- [email protected]
- Date
- 2011-09-04 17:01:40 -0700 (Sun, 04 Sep 2011)
Log Message
<rdar://problem/10071256> Retain retired custom fonts until the next style recalc
Reviewed by Darin Adler.
Source/WebCore:
Test: fast/css/font-face-used-after-retired.html
During style recalc, existing renderers may reference their old style, including font data.
Allow them to do so safely by keeping retired custom font data around until after style recalc.
* css/CSSFontFace.cpp:
(WebCore::CSSFontFace::retireCustomFont): Added. Calls through to CSSFontSelector, if the font
face is still part of any segmented font face. Otherwise, deletes the custom font data.
* css/CSSFontFace.h:
* css/CSSFontFaceSource.cpp:
(WebCore::CSSFontFaceSource::pruneTable): Changed to call retireCustomFont() instead of deleting
retired font data.
* css/CSSFontSelector.cpp:
(WebCore::CSSFontSelector::retireCustomFont): Added. Calls through to the Document, if this is
still the active font selector for a document. Otherwise, deletes the custom font data.
* css/CSSFontSelector.h:
* css/CSSSegmentedFontFace.cpp:
(WebCore::CSSSegmentedFontFace::pruneTable): Changed to call retireCustomFont() instead of
deleting retired font data.
* dom/Document.cpp:
(WebCore::Document::~Document): Added a call to deleteRetiredCustomFonts(), in case the Document
is destroyed before getting a chance to recalc style after custom fonts have been retired.
(WebCore::Document::recalcStyle): Added a call to deleteRetiredCustomFonts() after style recalc.
(WebCore::Document::deleteRetiredCustomFonts): Added. Deletes all previously-retired custom font
data.
* dom/Document.h:
(WebCore::Document::retireCustomFont): Added.
LayoutTests:
* fast/css/font-face-used-after-retired-expected.txt: Added.
* fast/css/font-face-used-after-retired.html: Added.
Modified Paths
Added Paths
Diff
Modified: trunk/LayoutTests/ChangeLog (94507 => 94508)
--- trunk/LayoutTests/ChangeLog 2011-09-04 21:24:22 UTC (rev 94507)
+++ trunk/LayoutTests/ChangeLog 2011-09-05 00:01:40 UTC (rev 94508)
@@ -1,3 +1,12 @@
+2011-09-04 Dan Bernstein <[email protected]>
+
+ <rdar://problem/10071256> Retain retired custom fonts until the next style recalc
+
+ Reviewed by Darin Adler.
+
+ * fast/css/font-face-used-after-retired-expected.txt: Added.
+ * fast/css/font-face-used-after-retired.html: Added.
+
2011-09-04 Sam Weinig <[email protected]>
Forgot to check in new results for fast/events/event-creation.html
Added: trunk/LayoutTests/fast/css/font-face-used-after-retired-expected.txt (0 => 94508)
--- trunk/LayoutTests/fast/css/font-face-used-after-retired-expected.txt (rev 0)
+++ trunk/LayoutTests/fast/css/font-face-used-after-retired-expected.txt 2011-09-05 00:01:40 UTC (rev 94508)
@@ -0,0 +1,2 @@
+
+PASS
Added: trunk/LayoutTests/fast/css/font-face-used-after-retired.html (0 => 94508)
--- trunk/LayoutTests/fast/css/font-face-used-after-retired.html (rev 0)
+++ trunk/LayoutTests/fast/css/font-face-used-after-retired.html 2011-09-05 00:01:40 UTC (rev 94508)
@@ -0,0 +1,20 @@
+<style>
+ @font-face {
+ font-family: custom;
+ src: url(no-such-file.ttf);
+ }
+</style>
+<!-- content: counter(page) causes the style diff to be "detach" -->
+<div style="font-family: custom; content: counter(page);">
+ <br>PASS
+</div>
+<script>
+ if (window.layoutTestController) {
+ layoutTestController.dumpAsText();
+ layoutTestController.waitUntilDone();
+ // Must wait for the font to fail to load.
+ setTimeout(function() { layoutTestController.notifyDone() }, 100);
+ }
+
+ document.execCommand("SelectAll");
+</script>
Modified: trunk/Source/WebCore/ChangeLog (94507 => 94508)
--- trunk/Source/WebCore/ChangeLog 2011-09-04 21:24:22 UTC (rev 94507)
+++ trunk/Source/WebCore/ChangeLog 2011-09-05 00:01:40 UTC (rev 94508)
@@ -1,3 +1,37 @@
+2011-09-04 Dan Bernstein <[email protected]>
+
+ <rdar://problem/10071256> Retain retired custom fonts until the next style recalc
+
+ Reviewed by Darin Adler.
+
+ Test: fast/css/font-face-used-after-retired.html
+
+ During style recalc, existing renderers may reference their old style, including font data.
+ Allow them to do so safely by keeping retired custom font data around until after style recalc.
+
+ * css/CSSFontFace.cpp:
+ (WebCore::CSSFontFace::retireCustomFont): Added. Calls through to CSSFontSelector, if the font
+ face is still part of any segmented font face. Otherwise, deletes the custom font data.
+ * css/CSSFontFace.h:
+ * css/CSSFontFaceSource.cpp:
+ (WebCore::CSSFontFaceSource::pruneTable): Changed to call retireCustomFont() instead of deleting
+ retired font data.
+ * css/CSSFontSelector.cpp:
+ (WebCore::CSSFontSelector::retireCustomFont): Added. Calls through to the Document, if this is
+ still the active font selector for a document. Otherwise, deletes the custom font data.
+ * css/CSSFontSelector.h:
+ * css/CSSSegmentedFontFace.cpp:
+ (WebCore::CSSSegmentedFontFace::pruneTable): Changed to call retireCustomFont() instead of
+ deleting retired font data.
+ * dom/Document.cpp:
+ (WebCore::Document::~Document): Added a call to deleteRetiredCustomFonts(), in case the Document
+ is destroyed before getting a chance to recalc style after custom fonts have been retired.
+ (WebCore::Document::recalcStyle): Added a call to deleteRetiredCustomFonts() after style recalc.
+ (WebCore::Document::deleteRetiredCustomFonts): Added. Deletes all previously-retired custom font
+ data.
+ * dom/Document.h:
+ (WebCore::Document::retireCustomFont): Added.
+
2011-09-04 Sam Weinig <[email protected]>
Document.createEvent should support all the interfaces of Event we got
Modified: trunk/Source/WebCore/css/CSSFontFace.cpp (94507 => 94508)
--- trunk/Source/WebCore/css/CSSFontFace.cpp 2011-09-04 21:24:22 UTC (rev 94507)
+++ trunk/Source/WebCore/css/CSSFontFace.cpp 2011-09-05 00:01:40 UTC (rev 94508)
@@ -118,6 +118,19 @@
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
{
Modified: trunk/Source/WebCore/css/CSSFontFace.h (94507 => 94508)
--- trunk/Source/WebCore/css/CSSFontFace.h 2011-09-04 21:24:22 UTC (rev 94507)
+++ trunk/Source/WebCore/css/CSSFontFace.h 2011-09-05 00:01:40 UTC (rev 94508)
@@ -63,6 +63,7 @@
void addSource(CSSFontFaceSource*);
void fontLoaded(CSSFontFaceSource*);
+ void retireCustomFont(SimpleFontData*);
SimpleFontData* getFontData(const FontDescription&, bool syntheticBold, bool syntheticItalic);
Modified: trunk/Source/WebCore/css/CSSFontFaceSource.cpp (94507 => 94508)
--- trunk/Source/WebCore/css/CSSFontFaceSource.cpp 2011-09-04 21:24:22 UTC (rev 94507)
+++ trunk/Source/WebCore/css/CSSFontFaceSource.cpp 2011-09-05 00:01:40 UTC (rev 94508)
@@ -71,10 +71,11 @@
{
if (m_fontDataTable.isEmpty())
return;
+
HashMap<unsigned, SimpleFontData*>::iterator end = m_fontDataTable.end();
for (HashMap<unsigned, SimpleFontData*>::iterator it = m_fontDataTable.begin(); it != end; ++it)
- GlyphPageTreeNode::pruneTreeCustomFontData(it->second);
- deleteAllValues(m_fontDataTable);
+ m_face->retireCustomFont(it->second);
+
m_fontDataTable.clear();
}
Modified: trunk/Source/WebCore/css/CSSFontSelector.cpp (94507 => 94508)
--- trunk/Source/WebCore/css/CSSFontSelector.cpp 2011-09-04 21:24:22 UTC (rev 94507)
+++ trunk/Source/WebCore/css/CSSFontSelector.cpp 2011-09-05 00:01:40 UTC (rev 94508)
@@ -383,6 +383,16 @@
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())
Modified: trunk/Source/WebCore/css/CSSFontSelector.h (94507 => 94508)
--- trunk/Source/WebCore/css/CSSFontSelector.h 2011-09-04 21:24:22 UTC (rev 94507)
+++ trunk/Source/WebCore/css/CSSFontSelector.h 2011-09-05 00:01:40 UTC (rev 94508)
@@ -59,6 +59,8 @@
void fontLoaded();
virtual void fontCacheInvalidated();
+ void retireCustomFont(FontData*);
+
bool isEmpty() const;
CachedResourceLoader* cachedResourceLoader() const;
Modified: trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp (94507 => 94508)
--- trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp 2011-09-04 21:24:22 UTC (rev 94507)
+++ trunk/Source/WebCore/css/CSSSegmentedFontFace.cpp 2011-09-05 00:01:40 UTC (rev 94508)
@@ -52,10 +52,11 @@
// Make sure the glyph page tree prunes out all uses of this custom font.
if (m_fontDataTable.isEmpty())
return;
+
HashMap<unsigned, SegmentedFontData*>::iterator end = m_fontDataTable.end();
for (HashMap<unsigned, SegmentedFontData*>::iterator it = m_fontDataTable.begin(); it != end; ++it)
- GlyphPageTreeNode::pruneTreeCustomFontData(it->second);
- deleteAllValues(m_fontDataTable);
+ m_fontSelector->retireCustomFont(it->second);
+
m_fontDataTable.clear();
}
Modified: trunk/Source/WebCore/dom/Document.cpp (94507 => 94508)
--- trunk/Source/WebCore/dom/Document.cpp 2011-09-04 21:24:22 UTC (rev 94507)
+++ trunk/Source/WebCore/dom/Document.cpp 2011-09-05 00:01:40 UTC (rev 94508)
@@ -574,6 +574,8 @@
(*m_userSheets)[i]->clearOwnerNode();
}
+ deleteRetiredCustomFonts();
+
m_weakReference->clear();
if (m_mediaQueryMatcher)
@@ -1562,6 +1564,9 @@
element->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();
@@ -1698,6 +1703,20 @@
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<RenderStyle> style = styleForPage(pageIndex);
Modified: trunk/Source/WebCore/dom/Document.h (94507 => 94508)
--- trunk/Source/WebCore/dom/Document.h 2011-09-04 21:24:22 UTC (rev 94507)
+++ trunk/Source/WebCore/dom/Document.h 2011-09-05 00:01:40 UTC (rev 94508)
@@ -81,6 +81,7 @@
class Event;
class EventListener;
class EventQueue;
+class FontData;
class FormAssociatedElement;
class Frame;
class FrameView;
@@ -547,6 +548,8 @@
PassRefPtr<RenderStyle> styleForElementIgnoringPendingStylesheets(Element*);
PassRefPtr<RenderStyle> styleForPage(int pageIndex);
+ void retireCustomFont(FontData*);
+
// Returns true if page box (margin boxes and page borders) is visible.
bool isPageBoxVisible(int pageIndex);
@@ -1135,6 +1138,8 @@
void createStyleSelector();
+ void deleteRetiredCustomFonts();
+
PassRefPtr<NodeList> handleZeroPadding(const HitTestRequest&, HitTestResult&) const;
void loadEventDelayTimerFired(Timer<Document>*);
@@ -1148,7 +1153,8 @@
OwnPtr<CSSStyleSelector> m_styleSelector;
bool m_didCalculateStyleSelector;
bool m_hasDirtyStyleSelector;
-
+ Vector<OwnPtr<FontData> > m_retiredCustomFonts;
+
mutable RefPtr<CSSPrimitiveValueCache> m_cssPrimitiveValueCache;
Frame* m_frame;