root/trunk/WebCore/rendering/RenderView.h

Revision 50869, 9.5 KB (checked in by hamaji@chromium.org, 10 days ago)

2009-11-12 Yuta Kitamura < yutak@chromium.org>

Reviewed by Eric Seidel.

Prevent text inside a multi-column block from being split into columns.

If the tentative height of a multi-column block was too small, we need to
expand the block height and try to layout again, in order to prevent text
from being split into different columns.

CSS Multicolumn text is split awkwardly
 https://bugs.webkit.org/show_bug.cgi?id=22249

  • fast/multicol/single-line.html: Added.
  • fast/multicol/single-line-expected.checksum: Added.
  • fast/multicol/single-line-expected.png: Added.
  • fast/multicol/single-line-expected.txt: Added.

2009-11-12 Yuta Kitamura < yutak@chromium.org>

Reviewed by Eric Seidel.

Prevent text inside a multi-column block from being split into columns.

If the tentative height of a multi-column block was too small, we need to
expand the block height and try to layout again, in order to prevent text
from being split into different columns.

CSS Multicolumn text is split awkwardly
 https://bugs.webkit.org/show_bug.cgi?id=22249

Test: fast/multicol/single-line.html

  • rendering/RenderBlock.cpp: (WebCore::RenderBlock::layoutColumns):
  • rendering/RenderBlock.h:
  • rendering/RenderLineBoxList.cpp: (WebCore::RenderLineBoxList::paint):
  • rendering/RenderView.h: (WebCore::RenderView::setTruncatedAt): (WebCore::RenderView::setMinimumColumnHeight): (WebCore::RenderView::minimumColumnHeight):
  • Property svn:eol-style set to native
Line 
1/*
2 * Copyright (C) 1999 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2006 Apple Computer, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Library General Public License for more details.
14 *
15 * You should have received a copy of the GNU Library General Public License
16 * along with this library; see the file COPYING.LIB.  If not, write to
17 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 */
21
22#ifndef RenderView_h
23#define RenderView_h
24
25#include "FrameView.h"
26#include "LayoutState.h"
27#include "RenderBlock.h"
28#include <wtf/OwnPtr.h>
29
30namespace WebCore {
31
32class RenderWidget;
33
34#if USE(ACCELERATED_COMPOSITING)
35class RenderLayerCompositor;
36#endif
37
38class RenderView : public RenderBlock {
39public:
40    RenderView(Node*, FrameView*);
41    virtual ~RenderView();
42
43    virtual const char* renderName() const { return "RenderView"; }
44
45    virtual bool isRenderView() const { return true; }
46
47    virtual void layout();
48    virtual void calcWidth();
49    virtual void calcHeight();
50    virtual void calcPrefWidths();
51
52    // The same as the FrameView's layoutHeight/layoutWidth but with null check guards.
53    int viewHeight() const;
54    int viewWidth() const;
55
56    float zoomFactor() const;
57
58    FrameView* frameView() const { return m_frameView; }
59
60    virtual void computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect&, bool fixed = false);
61    virtual void repaintViewRectangle(const IntRect&, bool immediate = false);
62    // Repaint the view, and all composited layers that intersect the given absolute rectangle.
63    // FIXME: ideally we'd never have to do this, if all repaints are container-relative.
64    virtual void repaintRectangleInViewAndCompositedLayers(const IntRect&, bool immediate = false);
65
66    virtual void paint(PaintInfo&, int tx, int ty);
67    virtual void paintBoxDecorations(PaintInfo&, int tx, int ty);
68
69    enum SelectionRepaintMode { RepaintNewXOROld, RepaintNewMinusOld };
70    void setSelection(RenderObject* start, int startPos, RenderObject* end, int endPos, SelectionRepaintMode = RepaintNewXOROld);
71    void clearSelection();
72    virtual RenderObject* selectionStart() const { return m_selectionStart; }
73    virtual RenderObject* selectionEnd() const { return m_selectionEnd; }
74
75    bool printing() const;
76    void setPrintImages(bool enable) { m_printImages = enable; }
77    bool printImages() const { return m_printImages; }
78    void setTruncatedAt(int y) { m_truncatedAt = y; m_bestTruncatedAt = m_truncatorWidth = 0; m_minimumColumnHeight = 0; m_forcedPageBreak = false; }
79    void setBestTruncatedAt(int y, RenderBoxModelObject* forRenderer, bool forcedBreak = false);
80    void setMinimumColumnHeight(int height) { m_minimumColumnHeight = height; }
81    int bestTruncatedAt() const { return m_bestTruncatedAt; }
82    int minimumColumnHeight() const { return m_minimumColumnHeight; }
83
84    int truncatedAt() const { return m_truncatedAt; }
85
86    virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
87    virtual void absoluteQuads(Vector<FloatQuad>&);
88
89    IntRect selectionBounds(bool clipToVisibleContent = true) const;
90
91#if USE(ACCELERATED_COMPOSITING)
92    void setMaximalOutlineSize(int o);
93#else
94    void setMaximalOutlineSize(int o) { m_maximalOutlineSize = o; }
95#endif
96    int maximalOutlineSize() const { return m_maximalOutlineSize; }
97
98    virtual IntRect viewRect() const;
99
100    void selectionStartEnd(int& startPos, int& endPos) const;
101
102    IntRect printRect() const { return m_printRect; }
103    void setPrintRect(const IntRect& r) { m_printRect = r; }
104
105    void updateWidgetPositions();
106    void addWidget(RenderWidget*);
107    void removeWidget(RenderWidget*);
108
109    // layoutDelta is used transiently during layout to store how far an object has moved from its
110    // last layout location, in order to repaint correctly.
111    // If we're doing a full repaint m_layoutState will be 0, but in that case layoutDelta doesn't matter.
112    IntSize layoutDelta() const
113    {
114        return m_layoutState ? m_layoutState->m_layoutDelta : IntSize();
115    }
116    void addLayoutDelta(const IntSize& delta) 
117    {
118        if (m_layoutState)
119            m_layoutState->m_layoutDelta += delta;
120    }
121
122    bool doingFullRepaint() const { return m_frameView->needsFullRepaint(); }
123
124    void pushLayoutState(RenderBox* renderer, const IntSize& offset)
125    {
126        if (doingFullRepaint())
127            return;
128        // We push LayoutState even if layoutState is disabled because it stores layoutDelta too.
129        m_layoutState = new (renderArena()) LayoutState(m_layoutState, renderer, offset);
130    }
131
132    void pushLayoutState(RenderObject*);
133
134    void popLayoutState()
135    {
136        if (doingFullRepaint())
137            return;
138        LayoutState* state = m_layoutState;
139        m_layoutState = state->m_next;
140        state->destroy(renderArena());
141    }
142
143    // Returns true if layoutState should be used for its cached offset and clip.
144    bool layoutStateEnabled() const { return m_layoutStateDisableCount == 0 && m_layoutState; }
145    LayoutState* layoutState() const { return m_layoutState; }
146
147    // Suspends the LayoutState optimization. Used under transforms that cannot be represented by
148    // LayoutState (common in SVG) and when manipulating the render tree during layout in ways
149    // that can trigger repaint of a non-child (e.g. when a list item moves its list marker around).
150    // Note that even when disabled, LayoutState is still used to store layoutDelta.
151    void disableLayoutState() { m_layoutStateDisableCount++; }
152    void enableLayoutState() { ASSERT(m_layoutStateDisableCount > 0); m_layoutStateDisableCount--; }
153
154    virtual void updateHitTestResult(HitTestResult&, const IntPoint&);
155
156    // Notifications that this view became visible in a window, or will be
157    // removed from the window.
158    void didMoveOnscreen();
159    void willMoveOffscreen();
160
161#if USE(ACCELERATED_COMPOSITING)
162    RenderLayerCompositor* compositor();
163    bool usesCompositing() const;
164#endif
165
166protected:
167    virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
168    virtual void mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState&) const;
169
170private:
171    bool shouldRepaint(const IntRect& r) const;
172       
173    int docHeight() const;
174    int docWidth() const;
175
176protected:
177    FrameView* m_frameView;
178
179    RenderObject* m_selectionStart;
180    RenderObject* m_selectionEnd;
181    int m_selectionStartPos;
182    int m_selectionEndPos;
183
184    // used to ignore viewport width when printing to the printer
185    bool m_printImages;
186    int m_truncatedAt;
187
188    int m_maximalOutlineSize; // Used to apply a fudge factor to dirty-rect checks on blocks/tables.
189    IntRect m_printRect; // Used when printing.
190
191    typedef HashSet<RenderWidget*> RenderWidgetSet;
192
193    RenderWidgetSet m_widgets;
194
195private:
196    IntRect m_cachedSelectionBounds;
197
198    int m_bestTruncatedAt;
199    int m_truncatorWidth;
200    int m_minimumColumnHeight;
201    bool m_forcedPageBreak;
202    LayoutState* m_layoutState;
203    unsigned m_layoutStateDisableCount;
204#if USE(ACCELERATED_COMPOSITING)
205    OwnPtr<RenderLayerCompositor> m_compositor;
206#endif
207};
208
209inline RenderView* toRenderView(RenderObject* object)
210{
211    ASSERT(!object || object->isRenderView());
212    return static_cast<RenderView*>(object);
213}
214
215inline const RenderView* toRenderView(const RenderObject* object)
216{
217    ASSERT(!object || object->isRenderView());
218    return static_cast<const RenderView*>(object);
219}
220
221// This will catch anyone doing an unnecessary cast.
222void toRenderView(const RenderView*);
223
224
225// Stack-based class to assist with LayoutState push/pop
226class LayoutStateMaintainer : public Noncopyable {
227public:
228    // ctor to push now
229    LayoutStateMaintainer(RenderView* view, RenderBox* root, IntSize offset, bool disableState = false)
230        : m_view(view)
231        , m_disabled(disableState)
232        , m_didStart(false)
233        , m_didEnd(false)
234    {
235        push(root, offset);
236    }
237   
238    // ctor to maybe push later
239    LayoutStateMaintainer(RenderView* view)
240        : m_view(view)
241        , m_disabled(false)
242        , m_didStart(false)
243        , m_didEnd(false)
244    {
245    }
246   
247    ~LayoutStateMaintainer()
248    {
249        ASSERT(m_didStart == m_didEnd);   // if this fires, it means that someone did a push(), but forgot to pop().
250    }
251
252    void push(RenderBox* root, IntSize offset)
253    {
254        ASSERT(!m_didStart);
255        // We push state even if disabled, because we still need to store layoutDelta
256        m_view->pushLayoutState(root, offset);
257        if (m_disabled)
258            m_view->disableLayoutState();
259        m_didStart = true;
260    }
261
262    void pop()
263    {
264        if (m_didStart) {
265            ASSERT(!m_didEnd);
266            m_view->popLayoutState();
267            if (m_disabled)
268                m_view->enableLayoutState();
269            m_didEnd = true;
270        }
271    }
272
273    bool didPush() const { return m_didStart; }
274
275private:
276    RenderView* m_view;
277    bool m_disabled : 1;        // true if the offset and clip part of layoutState is disabled
278    bool m_didStart : 1;        // true if we did a push or disable
279    bool m_didEnd : 1;          // true if we popped or re-enabled
280};
281
282} // namespace WebCore
283
284#endif // RenderView_h
Note: See TracBrowser for help on using the browser.