KHtml

paintbuffer.h
1 /*
2  * This file is part of the KDE libraries
3  *
4  * Copyright (C) 2007 Germain Garand <[email protected]>
5  *
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.
10  *
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.
15  *
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.
20  *
21  */
22 
23 // The PaintBuffer class provides a shared buffer for efficient repetitive painting.
24 //
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.
30 
31 #ifndef html_paintbuffer_h
32 #define html_paintbuffer_h
33 
34 #include <QPixmap>
35 #include <QStack>
36 #include <QPainter>
37 #include <QPaintEngine>
38 #include <assert.h>
39 
40 namespace khtml
41 {
42 
43 class BufferedPainter;
44 class BufferSweeper;
45 
46 class PaintBuffer: public QObject
47 {
48  friend class khtml::BufferSweeper;
49 
50  Q_OBJECT
51 
52 public:
53  static const int maxPixelBuffering;
54  static const int leaseTime;
55  static const int cleanupTime;
56  static const int maxBuffers;
57 
58  static QPixmap *grab(QSize s = QSize());
59  static void release(QPixmap *p);
60 
61  static void cleanup();
62 
63  PaintBuffer();
64  void reset();
65  void timerEvent(QTimerEvent *e) override;
66 
67 private:
68  QPixmap *getBuf(QSize S);
69 
70  static QStack<PaintBuffer *> *s_avail;
71  static QStack<PaintBuffer *> *s_grabbed;
72  static QStack<QPixmap *> *s_full;
73  static BufferSweeper *s_sweeper;
74 
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;
82 };
83 
84 class BufferedPainter
85 {
86 public:
87  BufferedPainter(QPixmap *px, QPainter *&p, const QRegion &rr, bool replacePainter)
88  {
89  QRect br = rr.boundingRect();
90  m_rect = br;
91  bool doFill = 1 || !px->hasAlphaChannel(); // shared pixmaps aren't properly cleared
92  // with Qt 4 + NVidia proprietary driver.
93  // So we can't use this optimization until
94  // we can detect this defect.
95  if (doFill) {
96  px->fill(Qt::transparent);
97  }
98  m_painter.begin(px);
99 
100  m_off = br.topLeft() + QPoint(static_cast<int>(p->worldTransform().dx()),
101  static_cast<int>(p->worldTransform().dy()));
102  m_painter.setWorldTransform(p->worldTransform());
103  m_painter.translate(-m_off);
104  m_painter.setClipRegion(m_region = rr);
105  //foreach(QRect rrr, m_region.rects())
106  // qCDebug(KHTML_LOG) << rrr;
107 
108  if (!doFill) {
109  m_painter.setCompositionMode(QPainter::CompositionMode_Source);
110  m_painter.fillRect(br, Qt::transparent);
111  }
112 
113  m_painter.setCompositionMode(p->compositionMode());
114  m_buf = px;
115 
116  m_painter.setFont(p->font());
117  m_painter.setBrush(p->brush());
118  m_painter.setPen(p->pen());
119  m_painter.setBackground(p->background());
120  m_painter.setRenderHints(p->renderHints());
121  // ### what else?
122 
123  m_origPainter = p;
124  if (replacePainter) {
125  p = &m_painter;
126  }
127  m_paused = false;
128  }
129 
130  void transfer(float opacity)
131  {
132  // ### when using DestinationIn with an alpha above 0.99, the resulting buffer ends up black in Qt 4.5.1
133  bool constantOpacity = (opacity > 0.99) || (m_origPainter->paintEngine() && m_origPainter->paintEngine()->hasFeature(QPaintEngine::ConstantOpacity));
134  if (!constantOpacity) {
135  QColor color;
136  color.setAlphaF(opacity);
137  m_painter.setCompositionMode(QPainter::CompositionMode_DestinationIn);
138  m_painter.fillRect(m_rect, color);
139  }
140  m_painter.end();
141  QTransform t = m_origPainter->worldTransform();
142  QPoint trans(static_cast<int>(t.dx()), static_cast<int>(t.dy()));
143  m_origPainter->save();
144  m_origPainter->resetTransform();
145  m_origPainter->setClipRegion(trans.isNull() ? m_region : m_region.translated(trans));
146  m_origPainter->setWorldTransform(t);
147  if (constantOpacity) {
148  m_origPainter->setOpacity(opacity);
149  }
150  m_origPainter->drawPixmap(m_off - trans, *m_buf, QRect(0, 0, m_rect.width(), m_rect.height()));
151  m_origPainter->restore();
152  }
153 
154  static BufferedPainter *start(QPainter *&, const QRegion &);
155  static void end(QPainter *&, BufferedPainter *bp, float opacity = 1.0);
156 
157  const QPainter *painter() const
158  {
159  return &m_painter;
160  }
161  QPainter *originalPainter() const
162  {
163  return m_origPainter;
164  }
165  QPixmap *buffer() const
166  {
167  return m_buf;
168  }
169 private:
170  bool m_paused;
171  QRect m_rect;
172  QRegion m_region;
173  QPoint m_off;
174  QPainter m_painter;
175  QPixmap *m_buf;
176  QPainter *m_origPainter;
177 };
178 
179 }
180 #endif
const QBrush & background() const const
void fill(const QColor &color)
qreal dx() const const
qreal dy() const const
QPainter::RenderHints renderHints() const const
const QFont & font() const const
This file is part of the HTML rendering engine for KDE.
QRect boundingRect() const const
bool hasAlphaChannel() const const
Q_OBJECTQ_OBJECT
QPainter::CompositionMode compositionMode() const const
const QTransform & worldTransform() const const
CompositionMode_Source
const QBrush & brush() const const
const QList< QKeySequence > & end()
QPoint topLeft() const const
void setAlphaF(qreal alpha)
KGuiItem reset()
transparent
const QPen & pen() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2021 The KDE developers.
Generated on Mon Oct 25 2021 22:48:19 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.