1/*
2 * Copyright (C) 2000 Lars Knoll (knoll@kde.org)
3 *           (C) 2000 Antti Koivisto (koivisto@kde.org)
4 *           (C) 2000 Dirk Mueller (mueller@kde.org)
5 *           (C) 2004 Allan Sandfeld Jensen (kde@carewolf.com)
6 * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
7 *
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
12 *
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 * Library General Public License for more details.
17 *
18 * You should have received a copy of the GNU Library General Public License
19 * along with this library; see the file COPYING.LIB.  If not, write to
20 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301, USA.
22 *
23 */
24
25#ifndef RenderSelectionInfo_h
26#define RenderSelectionInfo_h
27
28#include "core/rendering/RenderBox.h"
29#include "platform/geometry/IntRect.h"
30
31namespace blink {
32
33class RenderSelectionInfoBase : public NoBaseWillBeGarbageCollected<RenderSelectionInfoBase> {
34    WTF_MAKE_NONCOPYABLE(RenderSelectionInfoBase); WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
35public:
36    RenderSelectionInfoBase()
37        : m_object(nullptr)
38        , m_paintInvalidationContainer(nullptr)
39        , m_state(RenderObject::SelectionNone)
40    {
41    }
42
43    RenderSelectionInfoBase(RenderObject* o)
44        : m_object(o)
45        , m_paintInvalidationContainer(o->isRooted() ? o->containerForPaintInvalidation() : nullptr)
46        , m_state(o->selectionState())
47    {
48    }
49
50    void trace(Visitor* visitor)
51    {
52        visitor->trace(m_object);
53        visitor->trace(m_paintInvalidationContainer);
54    }
55
56    RenderObject* object() const { return m_object; }
57    const RenderLayerModelObject* paintInvalidationContainer() const { return m_paintInvalidationContainer; }
58    RenderObject::SelectionState state() const { return m_state; }
59
60protected:
61    RawPtrWillBeMember<RenderObject> m_object;
62    RawPtrWillBeMember<const RenderLayerModelObject> m_paintInvalidationContainer;
63    RenderObject::SelectionState m_state;
64};
65
66// This struct is used when the selection changes to cache the old and new state of the selection for each RenderObject.
67class RenderSelectionInfo FINAL : public RenderSelectionInfoBase {
68public:
69    RenderSelectionInfo(RenderObject* o)
70        : RenderSelectionInfoBase(o)
71    {
72        if (m_paintInvalidationContainer && o->canUpdateSelectionOnRootLineBoxes()) {
73            m_rect = o->selectionRectForPaintInvalidation(m_paintInvalidationContainer);
74            // FIXME: groupedMapping() leaks the squashing abstraction. See RenderBlockSelectionInfo for more details.
75            if (m_paintInvalidationContainer->layer()->groupedMapping())
76                RenderLayer::mapRectToPaintBackingCoordinates(m_paintInvalidationContainer, m_rect);
77        } else {
78            m_rect = LayoutRect();
79        }
80    }
81
82    void invalidatePaint()
83    {
84        m_object->invalidatePaintUsingContainer(m_paintInvalidationContainer, enclosingIntRect(m_rect), InvalidationSelection);
85    }
86
87    LayoutRect rect() const { return m_rect; }
88
89private:
90    LayoutRect m_rect; // relative to paint invalidation container
91};
92
93// This struct is used when the selection changes to cache the old and new state of the selection for each RenderBlock.
94class RenderBlockSelectionInfo FINAL : public RenderSelectionInfoBase {
95public:
96    RenderBlockSelectionInfo(RenderBlock* b)
97        : RenderSelectionInfoBase(b)
98    {
99        if (m_paintInvalidationContainer && b->canUpdateSelectionOnRootLineBoxes())
100            m_rects = block()->selectionGapRectsForPaintInvalidation(m_paintInvalidationContainer);
101        else
102            m_rects = GapRects();
103    }
104
105    void invalidatePaint()
106    {
107        LayoutRect paintInvalidationRect = m_rects;
108        // FIXME: this is leaking the squashing abstraction. However, removing the groupedMapping() condiitional causes
109        // RenderBox::mapRectToPaintInvalidationBacking to get called, which makes rect adjustments even if you pass the same
110        // paintInvalidationContainer as the render object. Find out why it does that and fix.
111        if (m_paintInvalidationContainer && m_paintInvalidationContainer->layer()->groupedMapping())
112            RenderLayer::mapRectToPaintBackingCoordinates(m_paintInvalidationContainer, paintInvalidationRect);
113        m_object->invalidatePaintUsingContainer(m_paintInvalidationContainer, enclosingIntRect(paintInvalidationRect), InvalidationSelection);
114    }
115
116    RenderBlock* block() const { return toRenderBlock(m_object); }
117    GapRects rects() const { return m_rects; }
118
119private:
120    GapRects m_rects; // relative to paint invalidation container
121};
122
123} // namespace blink
124
125
126#endif // RenderSelectionInfo_h
127