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 WSVG_IMAGE_H_
8 #define WSVG_IMAGE_H_
9 
10 #include <Wt/WBrush.h>
11 #include <Wt/WFont.h>
12 #include <Wt/WPen.h>
13 #include <Wt/WPointF.h>
14 #include <Wt/WRectF.h>
15 #include <Wt/WResource.h>
16 #include <Wt/WShadow.h>
17 #include <Wt/WStringStream.h>
18 #include <Wt/WTransform.h>
19 #include <Wt/WVectorImage.h>
20 
21 namespace Wt {
22 
23 class ServerSideFontMetrics;
24 
25 /*! \class WSvgImage Wt/WSvgImage.h Wt/WSvgImage.h
26  *  \brief A paint device for rendering using Scalable Vector Graphics (SVG).
27  *
28  * The %WSvgImage is primarily used by WPaintedWidget to render to the
29  * browser in Support Vector Graphics (SVG) format.
30  *
31  * \if cpp
32  * You may also use the %WSvgImage as an independent resource, for example
33  * in conjunction with a WAnchor or WImage, or to make a hard copy of an
34  * image in SVG format, using write():
35  * \code
36  * Wt::Chart::WCartesianChart *chart = ...
37  *
38  * Wt::WSvgImage svgImage(800, 400);
39  * Wt::WPainter p(&svgImage);
40  * chart->paint(p);
41  * p.end();
42  * std::ofstream f("chart.svg");
43  * svgImage.write(f);
44  * \endcode
45  * \endif
46  *
47  * \ingroup painting
48  */
49 class WT_API WSvgImage : public WResource, public WVectorImage
50 {
51 public:
52   /*! \brief Create an SVG paint device.
53    *
54    * If \p paintUpdate is \c true, then only an SVG fragment will be
55    * rendered that can be used to update the DOM of an existing SVG
56    * image, instead of a full SVG image.
57    */
58   WSvgImage(const WLength& width, const WLength& height,
59 	    bool paintUpdate = false);
60 
61   /*! \brief Destructor.
62    */
63   ~WSvgImage();
64 
65   virtual WFlags<PaintDeviceFeatureFlag> features() const override;
66   virtual void setChanged(WFlags<PainterChangeFlag> flags) override;
67   virtual void drawArc(const WRectF& rect, double startAngle, double spanAngle)
68     override;
69   virtual void drawImage(const WRectF& rect, const std::string& imgUri,
70 			 int imgWidth, int imgHeight, const WRectF& sourceRect)
71     override;
72   virtual void drawLine(double x1, double y1, double x2, double y2) override;
73   virtual void drawRect(const WRectF& rectangle) override;
74   virtual void drawPath(const WPainterPath& path) override;
75   virtual void drawText(const WRectF& rect,
76 			WFlags<AlignmentFlag> alignmentFlags,
77 			TextFlag textFlag,
78 			const WString& text,
79 			const WPointF *clipPoint) override;
80   virtual WTextItem measureText(const WString& text, double maxWidth = -1,
81 				bool wordWrap = false) override;
82   virtual WFontMetrics fontMetrics() override;
83   virtual void init() override;
84   virtual void done() override;
paintActive()85   virtual bool paintActive() const override { return painter_ != nullptr; }
86 
87   virtual std::string rendered() override;
88 
width()89   virtual WLength width() const override { return width_; }
height()90   virtual WLength height() const override { return height_; }
91 
92   virtual void handleRequest(const Http::Request& request,
93 			     Http::Response& response) override;
94 
95 protected:
painter()96   virtual WPainter *painter() const override { return painter_; }
setPainter(WPainter * painter)97   virtual void setPainter(WPainter *painter) override { painter_ = painter; }
98 
99 private:
100   WLength   width_, height_;
101   WPainter *painter_;
102   bool      paintUpdate_;
103   WFlags<PainterChangeFlag> changeFlags_;
104 
105   bool        newGroup_;
106   bool        newClipPath_;
107   bool        busyWithPath_;
108   int         currentClipId_;
109   static int  nextClipId_;
110   int         currentFillGradientId_;
111   int         currentStrokeGradientId_;
112   static int  nextGradientId_;
113 
114   WTransform  currentTransform_;
115   WBrush      currentBrush_;
116   WFont       currentFont_;
117   WPen        currentPen_;
118   WShadow     currentShadow_;
119   int         currentShadowId_, nextShadowId_;
120 
121   WPointF     pathTranslation_;
122   WRectF      pathBoundingBox_;
123 
124   WStringStream shapes_;
125   ServerSideFontMetrics *fontMetrics_;
126 
127   void finishPath();
128   void makeNewGroup();
129   std::string fillStyle() const;
130   std::string strokeStyle() const;
131   std::string fontStyle() const;
132   std::string clipPath() const;
133   int createShadowFilter(WStringStream& out);
134   void defineGradient(const WGradient& gradient, int id);
135 
136   std::string fillStyle_, strokeStyle_, fontStyle_;
137 
138   static std::string quote(double s);
139   static std::string quote(const std::string& s);
140 
141   void drawPlainPath(WStringStream& s, const WPainterPath& path);
142 
143   void streamResourceData(std::ostream& stream);
144 };
145 
146 }
147 
148 #endif // WSVG_IMAGE_H_
149