don't discard iframe children.
[kdelibs.git] / khtml / misc / paintbuffer.h
blob696b014839256334a16c55ab4834a9380d1d223e
1 /*
2 * This file is part of the KDE libraries
4 * Copyright (C) 2007 Germain Garand <germain@ebooksfrance.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
23 // The PaintBuffer class provides a shared buffer for efficient repetitive painting.
25 // It will grow to encompass the biggest size encountered, in order to avoid
26 // constantly resizing.
27 // When it grows over maxPixelBuffering, it periodically checks if such a size
28 // is still needed. If not, it shrinks down to the biggest size < maxPixelBuffering
29 // that was requested during the overflow lapse.
31 #ifndef html_paintbuffer_h
32 #define html_paintbuffer_h
34 #include <QPixmap>
35 #include <QStack>
36 #include <QPainter>
37 #include <QPaintEngine>
38 #include <kdebug.h>
39 #include <assert.h>
41 namespace khtml {
43 class BufferedPainter;
44 class BufferSweeper;
46 class PaintBuffer: public QObject
48 friend class khtml::BufferSweeper;
50 Q_OBJECT
52 public:
53 static const int maxPixelBuffering;
54 static const int leaseTime;
55 static const int cleanupTime;
56 static const int maxBuffers;
58 static QPixmap* grab( QSize s = QSize() );
59 static void release(QPixmap*p);
61 static void cleanup();
63 PaintBuffer();
64 void reset();
65 virtual void timerEvent(QTimerEvent* e);
67 private:
68 QPixmap* getBuf( QSize S );
70 static QStack<PaintBuffer*> *s_avail;
71 static QStack<PaintBuffer*> *s_grabbed;
72 static QStack<QPixmap*> *s_full;
73 static BufferSweeper *s_sweeper;
75 QPixmap m_buf;
76 bool m_overflow;
77 bool m_grabbed;
78 bool m_renewTimer;
79 int m_timer;
80 int m_resetWidth;
81 int m_resetHeight;
84 class BufferedPainter
86 public:
87 BufferedPainter(QPixmap* px, QPainter*& p, const QRegion &rr, bool replacePainter) {
88 QRect br = rr.boundingRect();
89 m_rect = br;
90 bool doFill = 1 || !px->hasAlphaChannel(); // shared pixmaps aren't properly cleared
91 // with Qt 4 + NVidia proprietary driver.
92 // So we can't use this optimization until
93 // we can detect this defect.
94 if (doFill)
95 px->fill(Qt::transparent);
96 m_painter.begin(px);
98 m_off = br.topLeft() + QPoint( static_cast<int>(p->worldTransform().dx()),
99 static_cast<int>(p->worldTransform().dy()));
100 m_painter.setWorldTransform(p->worldTransform());
101 m_painter.translate( -m_off );
102 m_painter.setClipRegion(m_region = rr);
103 //foreach(QRect rrr, m_region.rects())
104 // kDebug() << rrr;
106 if (!doFill) {
107 m_painter.setCompositionMode( QPainter::CompositionMode_Source );
108 m_painter.fillRect(br, Qt::transparent);
111 m_painter.setCompositionMode(p->compositionMode());
112 m_buf = px;
114 m_painter.setFont( p->font() );
115 m_painter.setBrush( p->brush() );
116 m_painter.setPen( p->pen() );
117 m_painter.setBackground( p->background() );
118 // ### what else?
120 m_origPainter = p;
121 if (replacePainter)
122 p = &m_painter;
123 m_paused = false;
126 void transfer( float opacity ) {
127 bool constantOpacity = m_origPainter->paintEngine()->hasFeature(QPaintEngine::ConstantOpacity);
128 if (!constantOpacity) {
129 QColor color;
130 color.setAlphaF(opacity);
131 m_painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
132 m_painter.fillRect(m_rect, color);
134 m_painter.end();
135 QTransform t = m_origPainter->worldTransform();
136 QPoint trans(static_cast<int>(t.dx()),static_cast<int>(t.dy()));
137 m_origPainter->save();
138 m_origPainter->resetTransform();
139 m_origPainter->setClipRegion(trans.isNull() ? m_region : m_region.translated(trans));
140 m_origPainter->setWorldTransform(t);
141 if (constantOpacity)
142 m_origPainter->setOpacity(opacity);
143 m_origPainter->drawPixmap(m_off-trans, *m_buf, QRect(0,0,m_rect.width(),m_rect.height()));
144 m_origPainter->restore();
147 static BufferedPainter* start(QPainter*&, const QRegion&);
148 static void end(QPainter*&, BufferedPainter* bp, float opacity=1.0);
150 const QPainter* painter() const { return &m_painter; }
151 QPainter* originalPainter() const { return m_origPainter; }
152 QPixmap* buffer() const { return m_buf; }
153 private:
154 bool m_paused;
155 QRect m_rect;
156 QRegion m_region;
157 QPoint m_off;
158 QPainter m_painter;
159 QPixmap* m_buf;
160 QPainter* m_origPainter;
164 #endif