KHtml

html_canvasimpl.h
1 /*
2  * Copyright (C) 2007, 2008 Maksim Orlovich <[email protected]>
3  * Copyright (C) 2004 Apple Computer, Inc. All rights reserved.
4  * Copyright (C) 2007, 2008 Fredrik Höglund <[email protected]>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser 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  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  *
20  * Portions of this code are (c) by Apple Computer, Inc. and were licensed
21  * under the following terms:
22  *
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the above copyright
27  * notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  * notice, this list of conditions and the following disclaimer in the
30  * documentation and/or other materials provided with the distribution.
31  *
32  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
33  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
34  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
35  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
36  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
37  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
38  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
39  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
40  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
41  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
42  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43  */
44 #ifndef HTML_CANVASIMPL_H
45 #define HTML_CANVASIMPL_H
46 
47 #include "dom/dom_string.h"
48 #include "html/html_elementimpl.h"
49 #include "misc/khtmllayout.h"
50 #include "rendering/render_object.h"
51 
52 #include <QRegion>
53 #include <QMap>
54 #include <QList>
55 #include <QStack>
56 #include <QPixmap>
57 #include <QGradient>
58 
59 namespace khtmlImLoad
60 {
61 class CanvasImage;
62 }
63 
64 namespace DOM
65 {
66 
67 class CanvasContext2DImpl;
68 
69 class HTMLCanvasElementImpl : public HTMLElementImpl
70 {
71 public:
72  HTMLCanvasElementImpl(DocumentImpl *doc);
73  ~HTMLCanvasElementImpl();
74 
75  void parseAttribute(AttributeImpl *) override;
76  Id id() const override;
77 
78  void attach() override;
79 
80  int width() const
81  {
82  return w;
83  }
84  int height() const
85  {
86  return h;
87  }
88 
89  CanvasContext2DImpl *getContext2D();
90 
91  // Note: we use QString here for efficiency reasons. We only need
92  // one version since we only do the required image/png
93  QString toDataURL(int &exceptionCode);
94 
95  // Returns the canvas image, but does not guarantee it's
96  // up-to-date
97  khtmlImLoad::CanvasImage *getCanvasImage();
98 
99  bool isUnsafe() const;
100  void markUnsafe();
101 private:
102  int w, h;
103  SharedPtr<CanvasContext2DImpl> context;
104  bool unsafe;
105 };
106 
107 // Base class for representing styles for fill and stroke.
108 // Not part of the DOM
109 class CanvasStyleBaseImpl : public khtml::Shared<CanvasStyleBaseImpl>
110 {
111 public:
112  enum Type {
113  Color,
114  Gradient,
115  Pattern
116  };
117 
118  virtual bool isUnsafe() const
119  {
120  return false;
121  }
122  virtual ~CanvasStyleBaseImpl() {}
123 
124  virtual Type type() const = 0;
125  virtual QBrush toBrush() const = 0;
126 };
127 
128 // Not part of the DOM.
129 class CanvasColorImpl : public CanvasStyleBaseImpl
130 {
131 public:
132  QColor color;
133 
134  CanvasColorImpl(const QColor &newColor) : color(newColor)
135  {}
136 
137  Type type() const override
138  {
139  return Color;
140  }
141 
142  QBrush toBrush() const override
143  {
144  return QBrush(color);
145  }
146 
147  DOM::DOMString toString() const;
148 
149  // Note: returns 0 if it can not be parsed.
150  static CanvasColorImpl *fromString(const DOM::DOMString &s);
151 };
152 
153 class CanvasPatternImpl : public CanvasStyleBaseImpl
154 {
155 public:
156  CanvasPatternImpl(const QImage &inImg, bool unsafe, bool rx, bool ry);
157 
158  Type type() const override
159  {
160  return Pattern;
161  }
162  QBrush toBrush() const override;
163 
164  // Returns the rect that a pattern fill or stroke should be clipped to, given
165  // the repeat setting and the indicated brush origin and bounding rect.
166  // The bounding rect (usually the canvas rect) limits the clip rect extent
167  // in the repeating dimension(s).
168  QRectF clipForRepeat(const QPointF &origin, const QRectF &bounds) const;
169 
170  bool isUnsafe() const override
171  {
172  return unsafe;
173  }
174 private:
175  QImage img;
176  bool repeatX, repeatY;
177  bool unsafe;
178 };
179 
180 class CanvasGradientImpl : public CanvasStyleBaseImpl
181 {
182 public:
183  CanvasGradientImpl(QGradient *newGradient, float innerRadius = 0.0, bool inverse = false);
184  ~CanvasGradientImpl();
185 
186  // Our internal interface..
187  Type type() const override
188  {
189  return Gradient;
190  }
191  QBrush toBrush() const override;
192 
193  // DOM API
194  void addColorStop(float offset, const DOM::DOMString &color, int &exceptionCode);
195 private:
196  QGradient *gradient;
197  float innerRadius; // In a radial gradient
198  bool inverse; // For radial gradients only
199 };
200 
201 class CanvasImageDataImpl : public khtml::Shared<CanvasImageDataImpl>
202 {
203 public:
204  // Creates an uninitialized image..
205  CanvasImageDataImpl(unsigned width, unsigned height);
206  CanvasImageDataImpl *clone() const;
207 
208  unsigned width() const;
209  unsigned height() const;
210  QColor pixel(unsigned pixelNum) const;
211  void setPixel(unsigned pixelNum, const QColor &val);
212  void setComponent(unsigned pixelNum, int component, int value);
213  QImage data;
214 private:
215  CanvasImageDataImpl(const QImage &_data);
216 };
217 
218 class CanvasContext2DImpl : public khtml::Shared<CanvasContext2DImpl>
219 {
220 public:
221  CanvasContext2DImpl(HTMLCanvasElementImpl *element, int width, int height);
222  ~CanvasContext2DImpl();
223 
224  // Note: the native API does not attempt to validate
225  // input for NaN and +/- infinity to raise exceptions;
226  // but it does handle them for transformations
227 
228  // For renderer..
229  void commit();
230 
231  // Public API, exported via the DOM.
232  HTMLCanvasElementImpl *canvas() const;
233 
234  // State management
235  void save();
236  void restore();
237 
238  // Transformations
239  void scale(float x, float y);
240  void rotate(float angle);
241  void translate(float x, float y);
242  void transform(float m11, float m12, float m21, float m22, float dx, float dy);
243  void setTransform(float m11, float m12, float m21, float m22, float dx, float dy);
244 
245  // Composition state setting
246  float globalAlpha() const;
247  void setGlobalAlpha(float a);
248  DOMString globalCompositeOperation() const;
249  void setGlobalCompositeOperation(const DOMString &op);
250 
251  // Colors and styles..
252  void setStrokeStyle(CanvasStyleBaseImpl *strokeStyle);
253  CanvasStyleBaseImpl *strokeStyle() const;
254  void setFillStyle(CanvasStyleBaseImpl *fillStyle);
255  CanvasStyleBaseImpl *fillStyle() const;
256  CanvasGradientImpl *createLinearGradient(float x0, float y0, float x1, float y1) const;
257  CanvasGradientImpl *createRadialGradient(float x0, float y0, float r0, float x1, float y1, float r1, int &exceptionCode) const;
258  CanvasPatternImpl *createPattern(ElementImpl *pat, const DOMString &rpt, int &exceptionCode) const;
259 
260  // Line attributes
261  float lineWidth() const;
262  void setLineWidth(float newLW);
263  DOMString lineCap() const;
264  void setLineCap(const DOMString &newCap);
265  DOMString lineJoin() const;
266  void setLineJoin(const DOMString &newJoin);
267  float miterLimit() const;
268  void setMiterLimit(float newML);
269 
270  // Shadow attributes
271  float shadowOffsetX() const;
272  void setShadowOffsetX(float newOX);
273  float shadowOffsetY() const;
274  void setShadowOffsetY(float newOY);
275  float shadowBlur() const;
276  void setShadowBlur(float newBlur);
277  DOMString shadowColor() const;
278  void setShadowColor(const DOMString &newColor);
279 
280  // Rectangle operations
281  void clearRect(float x, float y, float w, float h, int &exceptionCode);
282  void fillRect(float x, float y, float w, float h, int &exceptionCode);
283  void strokeRect(float x, float y, float w, float h, int &exceptionCode);
284 
285  // Path-based ops
286  void beginPath();
287  void closePath();
288  void moveTo(float x, float y);
289  void lineTo(float x, float y);
290  void quadraticCurveTo(float cpx, float cpy, float x, float y);
291  void bezierCurveTo(float cp1x, float cp1y, float cp2x, float cp2y, float x, float y);
292  void arcTo(float x1, float y1, float x2, float y2, float radius, int &exceptionCode);
293  void rect(float x, float y, float w, float h, int &exceptionCode);
294  void arc(float x, float y, float radius, float startAngle, float endAngle,
295  bool ccw, int &exceptionCode);
296  void fill();
297  void stroke();
298  void clip();
299  bool isPointInPath(float x, float y) const;
300 
301  // Image ops
302  void drawImage(ElementImpl *image, float dx, float dy, int &exceptionCode);
303  void drawImage(ElementImpl *image, float dx, float dy, float dw, float dh, int &exceptionCode);
304  void drawImage(ElementImpl *image, float sx, float sy, float sw, float sh,
305  float dx, float dy, float dw, float dh, int &exceptionCode);
306 
307  // Pixel ops
308  CanvasImageDataImpl *getImageData(float sx, float sy, float sw, float sh, int &exceptionCode);
309  void putImageData(CanvasImageDataImpl *data, float dx, float dy, int &exceptionCode);
310  CanvasImageDataImpl *createImageData(float sw, float sh, int &exceptionCode);
311 
312 private:
313  friend class HTMLCanvasElementImpl;
314 
315  enum PathPaintOp { DrawFill, DrawStroke };
316  enum PaintFlags { NoPaintFlags = 0, NotUsingCanvasPattern = 1 };
317 
318  // initialize canvas for new size
319  void resetContext(int width, int height);
320 
321  bool isPathEmpty() const;
322 
323  bool needsShadow() const;
324 
325  // Returns the clip path in device coordinates that the fill or stroke should be
326  // limited to, given the repeat setting of the pattern that will be used.
327  QPainterPath clipForPatternRepeat(QPainter *painter, const PathPaintOp op) const;
328 
329  // Helper function that fills or strokes a path, honoring shadow and pattern
330  // repeat settings.
331  void drawPath(QPainter *painter, const QPainterPath &path, PathPaintOp op) const;
332 
333  // Draws a shadowed path using the painter.
334  void drawPathWithShadow(QPainter *painter, const QPainterPath &path, PathPaintOp op,
335  PaintFlags flags = NoPaintFlags) const;
336 
337  void drawImage(QPainter *painter, const QRectF &dstRect, const QImage &image,
338  const QRectF &srcRect) const;
339 
340  // Cleared by canvas dtor..
341  HTMLCanvasElementImpl *canvasElement;
342 
343  // Helper for methods that take images via elements; this will extract them,
344  // and signal an exception if needed be. It will also return if the
345  // image is unsafe
346  QImage extractImage(ElementImpl *el, int &exceptionCode, bool &unsafeOut) const;
347 
348  // This method will prepare a painter for use, making sure it's active,
349  // that all the dirty state got sync'd, etc, and will mark the
350  // canvas as dirty so the renderer can flush everything, etc.
351  QPainter *acquirePainter();
352 
353  // We use khtmlImLoad to manage our canvas image, so that
354  // the Renderer can scale easily.
355  khtmlImLoad::CanvasImage *canvasImage;
356 
357  // The path is global, and never saved/restored
358  QPainterPath path;
359 
360  // We keep track of non-path state ourselves. There are two reasons:
361  // 1) The painter may have to be end()ed so we can not rely on it to remember
362  // things
363  // 2) The stroke and fill style can actually be DOM objects, so we have to
364  // be able to hand them back
365  // "The canvas state" section of the spec describes what's included here
366  struct PaintState {
367  // Viewport state (not readable from outside)
369  bool infinityTransform; // Marks that the transform has become invalid,
370  // and should be treated as identity.
371  QPainterPath clipPath; // This is in -physical- coordinates
372  bool clipping; // If clipping is enabled
373 
374  // Compositing state
375  float globalAlpha;
376  QPainter::CompositionMode globalCompositeOperation;
377 
378  // Stroke and fill styles.
379  SharedPtr<CanvasStyleBaseImpl> strokeStyle;
380  SharedPtr<CanvasStyleBaseImpl> fillStyle;
381 
382  // Line stuff
383  float lineWidth;
384  Qt::PenCapStyle lineCap;
385  Qt::PenJoinStyle lineJoin;
386  float miterLimit;
387 
388  // Shadow stuff
389  float shadowOffsetX;
390  float shadowOffsetY;
391  float shadowBlur;
392  QColor shadowColor;
393  };
394 
395  // The stack of states. The entry on the top is always the current state.
396  QStack<PaintState> stateStack;
397 
398  const PaintState &activeState() const
399  {
400  return stateStack.top();
401  }
402  PaintState &activeState()
403  {
404  return stateStack.top();
405  }
406 
407  QPointF mapToDevice(const QPointF &point) const
408  {
409  return point * stateStack.top().transform;
410  }
411 
412  QPointF mapToDevice(float x, float y) const
413  {
414  return QPointF(x, y) * stateStack.top().transform;
415  }
416 
417  QPointF mapToUser(const QPointF &point) const
418  {
419  return point * stateStack.top().transform.inverted();
420  }
421 
422  enum DirtyFlags {
423  DrtTransform = 0x01,
424  DrtClip = 0x02,
425  DrtAlpha = 0x04,
426  DrtCompOp = 0x08,
427  DrtStroke = 0x10,
428  DrtFill = 0x20,
429  DrtAll = 0xFF
430  };
431 
432  // The painter for working on the QImage. Might not be active.
433  // Should not be used directly, but rather via acquirePainter
434  QPainter workPainter;
435 
436  // How out-of-date the painter is, if it is active.
437  int dirty;
438 
439  // If we have not committed all the changes to the entire
440  // scaler hierarchy
441  bool needsCommit;
442 
443  // Tells the element and then the renderer that we changed, so need
444  // repainting.
445  void needRendererUpdate();
446 
447  // Flushes changes to the backbuffer.
448  void syncBackBuffer();
449 
450  // False if no user moveTo-element was inserted in the path
451  // see CanvasContext2DImpl::beginPath()
452  bool emptyPath;
453 };
454 
455 } //namespace
456 
457 #endif
KDOCTOOLS_EXPORT QString transform(const QString &file, const QString &stylesheet, const QVector< const char * > &params=QVector< const char * >())
PenCapStyle
Type type(const QSqlDatabase &db)
const QList< QKeySequence > & save()
A CanvasImage encapsulates a QImage that will be painted on externally, in order to permit scaling of...
Definition: canvasimage.h:39
This class implements the basic string we use in the DOM.
Definition: dom_string.h:44
PenJoinStyle
This library provides a full-featured HTML parser and widget.
char * toString(const T &value)
T & top()
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Tue Aug 11 2020 22:47:49 by doxygen 1.8.11 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.