1 // This may look like C code, but it's really -*- C++ -*- 2 /* 3 * Copyright (C) 2008 Emweb bv, Herent, Belgium. 4 * 5 * See the LICENSE file for terms of use. 6 */ 7 #ifndef WCANVAS_PAINT_DEVICE_H_ 8 #define WCANVAS_PAINT_DEVICE_H_ 9 10 #include <Wt/WBrush.h> 11 #include <Wt/WFont.h> 12 #include <Wt/WObject.h> 13 #include <Wt/WPaintDevice.h> 14 #include <Wt/WPainterPath.h> 15 #include <Wt/WPen.h> 16 #include <Wt/WPointF.h> 17 #include <Wt/WShadow.h> 18 #include <Wt/WTransform.h> 19 20 #include <sstream> 21 22 namespace Wt { 23 24 class DomElement; 25 class WTransform; 26 class ServerSideFontMetrics; 27 28 /*! \class WCanvasPaintDevice Wt/WCanvasPaintDevice.h Wt/WCanvasPaintDevice.h 29 * \brief A paint device for rendering using the HTML 5 <canvas> element. 30 * 31 * The %WCanvasPaintDevice is used by WPaintedWidget to render to the 32 * browser using the HTML 5 <canvas> element. You usually will 33 * not use the device directly, but rather rely on WPaintedWidget to 34 * use this device when appropriate. 35 * 36 * \note Older browsers do not have text support in <canvas>. 37 * Text is then rendered in an overlayed DIV and a consequence text is 38 * not subject to rotation and scaling components of the current 39 * transformation (but does take into account translation). On most 40 * browser you can use the WSvgImage or WVmlImage paint devices which 41 * do support text natively. 42 * 43 * \ingroup painting 44 */ 45 class WT_API WCanvasPaintDevice : public WObject, public WPaintDevice 46 { 47 public: 48 /*! \brief Create a canvas paint device. 49 */ 50 WCanvasPaintDevice(const WLength& width, const WLength& height, 51 bool paintUpdate = false); 52 virtual ~WCanvasPaintDevice(); 53 54 virtual WFlags<PaintDeviceFeatureFlag> features() const override; 55 virtual void setChanged(WFlags<PainterChangeFlag> flags) override; 56 virtual void drawArc(const WRectF& rect, double startAngle, double spanAngle) 57 override; 58 virtual void drawImage(const WRectF& rect, const std::string& imgUri, 59 int imgWidth, int imgHeight, const WRectF& sourceRect) override; 60 virtual void drawLine(double x1, double y1, double x2, double y2) override; 61 virtual void drawPath(const WPainterPath& path) override; 62 virtual void drawStencilAlongPath(const WPainterPath &stencil, 63 const WPainterPath &path, 64 bool softClipping); 65 virtual void drawRect(const WRectF& rectangle) override; 66 virtual void drawText(const WRectF& rect, 67 WFlags<AlignmentFlag> alignmentFlags, 68 TextFlag textFlag, 69 const WString& text, 70 const WPointF *clipPoint) override; 71 virtual void drawTextOnPath(const WRectF &rect, 72 WFlags<AlignmentFlag> alignmentFlags, 73 const std::vector<WString> &text, 74 const WTransform &transform, 75 const WPainterPath &path, 76 double angle, double lineHeight, 77 bool softClipping); 78 virtual WTextItem measureText(const WString& text, double maxWidth = -1, 79 bool wordWrap = false) override; 80 virtual WFontMetrics fontMetrics() override; 81 virtual void init() override; 82 virtual void done() override; paintActive()83 virtual bool paintActive() const override { return painter_ != nullptr; } 84 85 void render(const std::string &paintedWidgetJsRef, 86 const std::string& canvasId, 87 DomElement* text, 88 const std::string& updateAreasJs); 89 void renderPaintCommands(std::stringstream& js, const std::string& element); 90 width()91 virtual WLength width() const override { return width_; } height()92 virtual WLength height() const override { return height_; } 93 94 protected: painter()95 virtual WPainter *painter() const override { return painter_; } setPainter(WPainter * painter)96 virtual void setPainter(WPainter *painter) override { painter_ = painter; } 97 98 private: 99 enum class TextMethod { MozText, Html5Text, DomText }; 100 101 WLength width_, height_; 102 WPainter *painter_; 103 WFlags<PainterChangeFlag> changeFlags_; 104 bool paintUpdate_; 105 106 TextMethod textMethod_; 107 108 bool currentNoPen_, currentNoBrush_, lastTransformWasIdentity_; 109 110 WTransform currentTransform_; 111 WBrush currentBrush_; 112 WPen currentPen_; 113 WShadow currentShadow_; 114 WFont currentFont_; 115 WPointF pathTranslation_; 116 WPainterPath currentClipPath_; 117 WTransform currentClipTransform_; 118 bool currentClippingEnabled_; 119 ServerSideFontMetrics *fontMetrics_; 120 121 std::stringstream js_; 122 std::vector<DomElement *> textElements_; 123 std::vector<std::string> images_; 124 125 void finishPath(); 126 void renderTransform(std::stringstream& s, const WTransform& t); 127 void renderStateChanges(bool resetPathTranslation); 128 void resetPathTranslation(); 129 void drawPlainPath(std::stringstream& s, const WPainterPath& path); 130 131 int createImage(const std::string& imgUri); 132 textMethod()133 TextMethod textMethod() const { return textMethod_; } 134 135 friend class WWidgetCanvasPainter; 136 }; 137 138 } 139 140 #endif // WCANVAS_PAINT_DEVICE_H_ 141