Changeset 83396 in webkit


Ignore:
Timestamp:
Apr 9, 2011 11:29:26 PM (13 years ago)
Author:
mitz@apple.com
Message:

<rdar://problem/9215280> Detached canvas draws with incorrect font

Reviewed by Beth Dakin.

Source/WebCore:

Test: fast/canvas/font-update.html

The existing mechanism for updating the font in a canvas 2D context was lacking in at least
two ways: it neglected to update fonts in all but the topmost state in the stack, and since it
was based on HTMLCanvasElemen's attach() and recalcStyle(), it did not work when the element
was not attached.

This change takes the responsibility for font updates away from the canvas element and gives it
to the canvas context and its graphics state.

  • css/CSSFontSelector.cpp:

(WebCore::CSSFontSelector::registerForInvalidationCallbacks): Added. Adds to the set of registered
font selector clients.
(WebCore::CSSFontSelector::unregisterForInvalidationCallbacks): Added. Removes from the set of
registered font selector clients.
(WebCore::CSSFontSelector::dispatchInvalidationCallbacks): Calls fontsNeedUpdate() on all registered
clients and forces a style recalc on the document.
(WebCore::CSSFontSelector::fontLoaded): Changed to call dispatchInvalidationCallbacks().
(WebCore::CSSFontSelector::fontCacheInvalidated): Ditto.

  • css/CSSFontSelector.h:
  • html/HTMLCanvasElement.cpp: Removed overrides of attach() and recalcStyle().
  • html/HTMLCanvasElement.h:
  • html/canvas/CanvasRenderingContext2D.cpp:

(WebCore::CanvasRenderingContext2D::State::~State): Added. Unregisters with the font selector.
(WebCore::CanvasRenderingContext2D::State::fontsNeedUpdate): Added. Called by the font selector
when its fonts need to be updated. Updates the font.
(WebCore::CanvasRenderingContext2D::setFont): Registers the state with the font selector.

  • html/canvas/CanvasRenderingContext2D.h:
  • platform/graphics/FontSelector.h:

(WebCore::FontSelectorClient::~FontSelectorClient):

LayoutTests:

  • fast/canvas/font-update-expected.checksum: Added.
  • fast/canvas/font-update-expected.png: Added.
  • fast/canvas/font-update-expected.txt: Added.
  • fast/canvas/font-update.html: Added.
Location:
trunk
Files:
4 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r83393 r83396  
     12011-04-09  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Beth Dakin.
     4
     5        <rdar://problem/9215280> Detached canvas draws with incorrect font
     6
     7        * fast/canvas/font-update-expected.checksum: Added.
     8        * fast/canvas/font-update-expected.png: Added.
     9        * fast/canvas/font-update-expected.txt: Added.
     10        * fast/canvas/font-update.html: Added.
     11
    1122011-04-09  Dirk Pranke  <dpranke@chromium.org>
    213
  • trunk/Source/WebCore/ChangeLog

    r83392 r83396  
     12011-04-09  Dan Bernstein  <mitz@apple.com>
     2
     3        Reviewed by Beth Dakin.
     4
     5        <rdar://problem/9215280> Detached canvas draws with incorrect font
     6
     7        Test: fast/canvas/font-update.html
     8
     9        The existing mechanism for updating the font in a canvas 2D context was lacking in at least
     10        two ways: it neglected to update fonts in all but the topmost state in the stack, and since it
     11        was based on HTMLCanvasElemen's attach() and recalcStyle(), it did not work when the element
     12        was not attached.
     13
     14        This change takes the responsibility for font updates away from the canvas element and gives it
     15        to the canvas context and its graphics state.
     16
     17        * css/CSSFontSelector.cpp:
     18        (WebCore::CSSFontSelector::registerForInvalidationCallbacks): Added. Adds to the set of registered
     19        font selector clients.
     20        (WebCore::CSSFontSelector::unregisterForInvalidationCallbacks): Added. Removes from the set of
     21        registered font selector clients.
     22        (WebCore::CSSFontSelector::dispatchInvalidationCallbacks): Calls fontsNeedUpdate() on all registered
     23        clients and forces a style recalc on the document.
     24        (WebCore::CSSFontSelector::fontLoaded): Changed to call dispatchInvalidationCallbacks().
     25        (WebCore::CSSFontSelector::fontCacheInvalidated): Ditto.
     26        * css/CSSFontSelector.h:
     27        * html/HTMLCanvasElement.cpp: Removed overrides of attach() and recalcStyle().
     28        * html/HTMLCanvasElement.h:
     29        * html/canvas/CanvasRenderingContext2D.cpp:
     30        (WebCore::CanvasRenderingContext2D::State::~State): Added. Unregisters with the font selector.
     31        (WebCore::CanvasRenderingContext2D::State::fontsNeedUpdate): Added. Called by the font selector
     32        when its fonts need to be updated. Updates the font.
     33        (WebCore::CanvasRenderingContext2D::setFont): Registers the state with the font selector.
     34        * html/canvas/CanvasRenderingContext2D.h:
     35        * platform/graphics/FontSelector.h:
     36        (WebCore::FontSelectorClient::~FontSelectorClient):
     37
    1382011-04-09  Geoffrey Garen  <ggaren@apple.com>
    239
  • trunk/Source/WebCore/css/CSSFontSelector.cpp

    r72056 r83396  
    346346}
    347347
    348 void CSSFontSelector::fontLoaded()
    349 {
     348void CSSFontSelector::registerForInvalidationCallbacks(FontSelectorClient* client)
     349{
     350    m_clients.add(client);
     351}
     352
     353void CSSFontSelector::unregisterForInvalidationCallbacks(FontSelectorClient* client)
     354{
     355    m_clients.remove(client);
     356}
     357
     358void CSSFontSelector::dispatchInvalidationCallbacks()
     359{
     360    Vector<FontSelectorClient*> clients;
     361    copyToVector(m_clients, clients);
     362    for (size_t i = 0; i < clients.size(); ++i)
     363        clients[i]->fontsNeedUpdate(this);
     364
     365    // FIXME: Make Document a FontSelectorClient so that it can simply register for invalidation callbacks.
    350366    if (!m_document || m_document->inPageCache() || !m_document->renderer())
    351367        return;
     
    353369}
    354370
     371void CSSFontSelector::fontLoaded()
     372{
     373    dispatchInvalidationCallbacks();
     374}
     375
    355376void CSSFontSelector::fontCacheInvalidated()
    356377{
    357     if (!m_document || m_document->inPageCache() || !m_document->renderer())
    358         return;
    359     m_document->scheduleForcedStyleRecalc();
     378    dispatchInvalidationCallbacks();
    360379}
    361380
  • trunk/Source/WebCore/css/CSSFontSelector.h

    r66963 r83396  
    3030#include <wtf/Forward.h>
    3131#include <wtf/HashMap.h>
     32#include <wtf/HashSet.h>
    3233#include <wtf/RefPtr.h>
    3334#include <wtf/text/StringHash.h>
     
    6364    CachedResourceLoader* cachedResourceLoader() const;
    6465
     66    virtual void registerForInvalidationCallbacks(FontSelectorClient*);
     67    virtual void unregisterForInvalidationCallbacks(FontSelectorClient*);
     68
    6569private:
    6670    CSSFontSelector(Document*);
     71
     72    void dispatchInvalidationCallbacks();
    6773
    6874    Document* m_document;
     
    7076    HashMap<String, Vector<RefPtr<CSSFontFace> >*, CaseFoldingHash> m_locallyInstalledFontFaces;
    7177    HashMap<String, HashMap<unsigned, RefPtr<CSSSegmentedFontFace> >*, CaseFoldingHash> m_fonts;
     78    HashSet<FontSelectorClient*> m_clients;
    7279};
    7380
  • trunk/Source/WebCore/html/HTMLCanvasElement.cpp

    r82878 r83396  
    319319}
    320320
    321 void HTMLCanvasElement::attach()
    322 {
    323     HTMLElement::attach();
    324 
    325     if (m_context && m_context->is2d()) {
    326         CanvasRenderingContext2D* ctx = static_cast<CanvasRenderingContext2D*>(m_context.get());
    327         ctx->updateFont();
    328     }
    329 }
    330 
    331 void HTMLCanvasElement::recalcStyle(StyleChange change)
    332 {
    333     HTMLElement::recalcStyle(change);
    334 
    335     // Update font if needed.
    336     if (change == Force && m_context && m_context->is2d()) {
    337         CanvasRenderingContext2D* ctx = static_cast<CanvasRenderingContext2D*>(m_context.get());
    338         ctx->updateFont();
    339     }
    340 }
    341 
    342321void HTMLCanvasElement::setSurfaceSize(const IntSize& size)
    343322{
  • trunk/Source/WebCore/html/HTMLCanvasElement.h

    r81740 r83396  
    135135    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
    136136
    137     virtual void attach();
    138 
    139     virtual void recalcStyle(StyleChange);
    140 
    141137    void reset();
    142138
  • trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp

    r83355 r83396  
    214214}
    215215
     216CanvasRenderingContext2D::State::~State()
     217{
     218    if (m_realizedFont)
     219        m_font.fontSelector()->unregisterForInvalidationCallbacks(this);
     220}
     221
     222void CanvasRenderingContext2D::State::fontsNeedUpdate(FontSelector* fontSelector)
     223{
     224    ASSERT_ARG(fontSelector, fontSelector == m_font.fontSelector());
     225    ASSERT(m_realizedFont);
     226
     227    m_font.update(fontSelector);
     228}
     229
    216230void CanvasRenderingContext2D::save()
    217231{
     
    16911705    state().m_font.update(styleSelector->fontSelector());
    16921706    state().m_realizedFont = true;
    1693 }
    1694 
    1695 void CanvasRenderingContext2D::updateFont()
    1696 {
    1697     if (!state().m_realizedFont)
    1698         return;
    1699 
    1700     const Font& font = state().m_font;
    1701     font.update(font.fontSelector());
     1707    styleSelector->fontSelector()->registerForInvalidationCallbacks(&state());
    17021708}
    17031709
  • trunk/Source/WebCore/html/canvas/CanvasRenderingContext2D.h

    r75160 r83396  
    205205    String font() const;
    206206    void setFont(const String&);
    207     void updateFont();
    208207
    209208    String textAlign() const;
     
    229228
    230229private:
    231     struct State {
     230    struct State : FontSelectorClient {
    232231        State();
     232        virtual ~State();
     233
     234        virtual void fontsNeedUpdate(FontSelector*);
    233235
    234236        String m_unparsedStrokeColor;
  • trunk/Source/WebCore/platform/graphics/FontSelector.h

    r65021 r83396  
    3434class FontData;
    3535class FontDescription;
     36class FontSelectorClient;
    3637
    3738class FontSelector : public RefCounted<FontSelector> {
     
    4142
    4243    virtual void fontCacheInvalidated() { }
     44
     45    virtual void registerForInvalidationCallbacks(FontSelectorClient*) = 0;
     46    virtual void unregisterForInvalidationCallbacks(FontSelectorClient*) = 0;
     47};
     48
     49class FontSelectorClient {
     50public:
     51    virtual ~FontSelectorClient() { }
     52
     53    virtual void fontsNeedUpdate(FontSelector*) = 0;
    4354};
    4455
Note: See TracChangeset for help on using the changeset viewer.