Verovio
Source code documentation
svgdevicecontext.h
1 // Name: svgdevicecontext.h
3 // Author: Laurent Pugin
4 // Created: 2011
5 // Copyright (c) Authors and others. All rights reserved.
7 
8 #ifndef __VRV_SVG_DC_H__
9 #define __VRV_SVG_DC_H__
10 
11 #include <fstream>
12 #include <list>
13 #include <set>
14 #include <string>
15 #include <vector>
16 
17 //----------------------------------------------------------------------------
18 
19 #include "devicecontext.h"
20 #include "object.h"
21 #include "options.h"
22 
23 //----------------------------------------------------------------------------
24 
25 class Glyph;
26 class Resources;
27 
28 namespace vrv {
29 
30 //----------------------------------------------------------------------------
31 // SvgDeviceContext
32 //----------------------------------------------------------------------------
33 
40 public:
44  SvgDeviceContext(const std::string &docId);
46  virtual ~SvgDeviceContext();
48 
52  void SetBackground(int color, int style = PEN_SOLID) override;
54  void SetBackgroundImage(void *image, double opacity = 1.0) override;
55  void SetBackgroundMode(int mode) override;
56  void SetTextForeground(int color) override;
57  void SetTextBackground(int color) override;
58  void SetLogicalOrigin(int x, int y) override;
60 
64  Point GetLogicalOrigin() override;
67 
72  std::string GetStringSVG(bool xml_declaration = false);
73 
77  void DrawQuadBezierPath(Point bezier[3]) override;
79  void DrawCubicBezierPath(Point bezier[4]) override;
80  void DrawCubicBezierPathFilled(Point bezier1[4], Point bezier2[4]) override;
81  void DrawBentParallelogramFilled(Point side[4], int height) override;
82  void DrawCircle(int x, int y, int radius) override;
83  void DrawEllipse(int x, int y, int width, int height) override;
84  void DrawEllipticArc(int x, int y, int width, int height, double start, double end) override;
85  void DrawLine(int x1, int y1, int x2, int y2) override;
86  void DrawPolyline(int n, Point points[], bool close) override;
87  void DrawPolygon(int n, Point points[]) override;
88  void DrawRectangle(int x, int y, int width, int height) override;
89  void DrawRotatedText(const std::string &text, int x, int y, double angle) override;
90  void DrawRoundedRectangle(int x, int y, int width, int height, int radius) override;
91  void DrawText(const std::string &text, const std::u32string &wtext = U"", int x = VRV_UNSET, int y = VRV_UNSET,
92  int width = VRV_UNSET, int height = VRV_UNSET) override;
93  void DrawMusicText(const std::u32string &text, int x, int y, bool setSmuflGlyph = false) override;
94  void DrawSpline(int n, Point points[]) override;
95  void DrawGraphicUri(int x, int y, int width, int height, const std::string &uri) override;
96  void DrawSvgShape(int x, int y, int width, int height, double scale, pugi::xml_node svg) override;
97  void DrawBackgroundImage(int x = 0, int y = 0) override;
99 
103  void StartText(int x, int y, data_HORIZONTALALIGNMENT alignment = HORIZONTALALIGNMENT_left) override;
105  void EndText() override;
106 
110  void MoveTextTo(int x, int y, data_HORIZONTALALIGNMENT alignment) override;
112  void MoveTextVerticallyTo(int y) override;
114 
118  void StartGraphic(Object *object, const std::string &gClass, const std::string &gId, GraphicID graphicID = PRIMARY,
120  bool prepend = false) override;
121  void EndGraphic(Object *object, View *view) override;
123 
127  void StartCustomGraphic(const std::string &name, std::string gClass = "", std::string gId = "") override;
129  void EndCustomGraphic() override;
131 
135  void SetCustomGraphicColor(const std::string &color) override;
136 
140  void SetCustomGraphicAttributes(const std::string &data, const std::string &value) override;
141 
145  void ResumeGraphic(Object *object, std::string gId) override;
147  void EndResumedGraphic(Object *object, View *view) override;
149 
153  void StartTextGraphic(Object *object, const std::string &gClass, const std::string &gId) override;
155  void EndTextGraphic(Object *object, View *view) override;
157 
161  void RotateGraphic(Point const &orig, double angle) override;
164 
168  void StartPage() override;
170  void EndPage() override;
172 
176  void AddDescription(const std::string &text) override;
179 
183  void AppendIdAndClass(const std::string &gId, const std::string &baseClass, const std::string &addedClasses,
184  GraphicID graphicID = PRIMARY);
185 
189  void AppendAdditionalAttributes(Object *object);
190 
194  bool UseGlobalStyling() override { return !m_mmOutput; }
195 
199  void SetMMOutput(bool mmOutput) { m_mmOutput = mmOutput; }
200 
201  void SetFacsimile(bool facsimile) { m_facsimile = facsimile; }
202  bool GetFacsimile() { return m_facsimile; }
203 
207  void SetSvgBoundingBoxes(bool svgBoundingBoxes) { m_svgBoundingBoxes = svgBoundingBoxes; }
208 
212  void SetSvgViewBox(bool svgViewBox) { m_svgViewBox = svgViewBox; }
213 
217  void SetHtml5(bool html5) { m_html5 = html5; }
218 
222  void SetIndent(int indent) { m_indent = indent; }
223 
227  void SetFormatRaw(bool rawFormat) { m_formatRaw = rawFormat; }
228 
232  void SetRemoveXlink(bool removeXlink) { m_removeXlink = removeXlink; }
233 
237  void SetCss(const std::string &css)
238  {
239  m_css = css;
240  this->PrefixCssRules(m_css);
241  }
242 
247  void SetAdditionalAttributes(const std::vector<std::string> &additionalAttributes)
248  {
249  for (std::string s : additionalAttributes) {
250  std::string className = s.substr(0, s.find("@")); // parse <element@attribute>, e.g., "note@pname"
251  std::string attributeName = s.substr(s.find("@") + 1);
252  ClassId classId = ObjectFactory::GetInstance()->GetClassId(className);
253  m_svgAdditionalAttributes.insert({ classId, attributeName });
254  }
255  }
256 
260  void SetSmuflTextFont(option_SMUFLTEXTFONT smuflTextFont) { m_smuflTextFont = smuflTextFont; }
261 
262 private:
267  bool CopyFileToStream(const std::string &filename, std::ostream &dest);
268 
272  void DrawSvgBoundingBox(Object *object, View *view);
273 
277  void DrawSvgBoundingBoxRectangle(int x, int y, int width, int height);
278 
282  void VrvTextFont() { m_vrvTextFont = true; }
283 
287  void VrvTextFontFallback() { m_vrvTextFontFallback = true; }
288 
292  void IncludeTextFont(const std::string &fontname, const Resources *resources);
293 
298  void Commit(bool xml_declaration);
299 
300  void WriteLine(std::string);
301 
302  std::string GetColor(int color) const;
303 
304  pugi::xml_node AddChild(std::string name);
305 
309  void AppendStrokeLineCap(pugi::xml_node node, const Pen &pen);
311  void AppendStrokeLineJoin(pugi::xml_node node, const Pen &pen);
312  void AppendStrokeDashArray(pugi::xml_node node, const Pen &pen);
314 
318  void PrefixCssRules(std::string &rules);
319 
320 public:
321  //
322 private:
328  bool m_vrvTextFont;
329 
333  bool m_vrvTextFontFallback;
334 
335  // we use a std::stringstream because we want to prepend the <defs> which will know only when we reach the end of
336  // the page
337  // some viewer seem to support to have the <defs> at the end, but some do not (pdf2svg, for example)
338  // for this reason, the full svg is finally written a string from the destructor or when Flush() is called
339  std::ostringstream m_outdata;
340 
341  bool m_committed; // did we flushed the file?
342  int m_originX, m_originY;
343 
344  // Here we hold references to all different glyphs used so far,
345  // including any glyph for the same code but from different fonts.
346  // They will be added at the end of the file as <defs>.
347  // With multiple font support we need to keep track of:
348  // a) the glyph (to check if is has been already added)
349  // b) the id assigned to glyphs on the (that is has been consumed by the already rendered elements)
350  // To keep things as similar as possible to previous versions we generate ids with as uuuu-ss (where uuuu is the
351  // Smulf code for the glyph and ss the per-session suffix) for most of the cases (single font usage). When the same
352  // glyph has been used from several fonts we use uuuu-n-ss where n indicates the collision count.
353  class GlyphRef {
354  public:
355  GlyphRef(const Glyph *glyph, int count, const std::string &postfix);
356  const Glyph *GetGlyph() const { return m_glyph; };
357  const std::string &GetRefId() const { return m_refId; };
358 
359  private:
360  const Glyph *m_glyph;
361  std::string m_refId;
362  };
363  const std::string InsertGlyphRef(const Glyph *glyph);
364  std::map<const Glyph *, GlyphRef> m_smuflGlyphs;
365  std::map<std::string, int> m_glyphCodeFontCounter;
366 
367  // pugixml data
368  pugi::xml_document m_svgDoc;
369  pugi::xml_node m_svgNode;
370  pugi::xml_node m_pageNode;
371  pugi::xml_node m_currentNode;
372  std::list<pugi::xml_node> m_svgNodeStack;
373 
374  // output as mm (for pdf generation with a 72 dpi)
375  bool m_mmOutput;
376  bool m_facsimile;
377  // add bouding boxes in svg output
378  bool m_svgBoundingBoxes;
379  // use viewbox on svg root element
380  bool m_svgViewBox;
381  // output HTML5 data-* attributes
382  bool m_html5;
383  // additional CSS
384  std::string m_css;
385  // copy additional attributes of given elements to the SVG, in the form "note@pname; layer@n"
386  std::multimap<ClassId, std::string> m_svgAdditionalAttributes;
387  // format output as raw, stripping extraneous whitespace and non-content newlines
388  bool m_formatRaw;
389  // remove xlink from href attributes
390  bool m_removeXlink;
391  // indentation value (-1 for tabs)
392  int m_indent;
393  // postfix to be added to font glyphs
394  std::string m_glyphPostfixId;
395  // embedding of the smufl text font
396  option_SMUFLTEXTFONT m_smuflTextFont;
397  // the document id
398  std::string m_docId;
399 };
400 
401 } // namespace vrv
402 
403 #endif // __VRV_SVG_DC_H__
vrv::ObjectFactory::GetClassId
ClassId GetClassId(std::string name)
Get the ClassId from the MEI element string name by making a lookup in the register.
vrv::SvgDeviceContext::SetAdditionalAttributes
void SetAdditionalAttributes(const std::vector< std::string > &additionalAttributes)
Copies additional attributes of defined elements to the SVG, each string in the form "elementName@att...
Definition: svgdevicecontext.h:247
vrv::SvgDeviceContext::SetIndent
void SetIndent(int indent)
Setter for indent of the SVG (default is 3, -1 for tabs)
Definition: svgdevicecontext.h:222
vrv::SvgDeviceContext::SetHtml5
void SetHtml5(bool html5)
Setting m_html5 flag (false by default)
Definition: svgdevicecontext.h:217
vrv::Object
This class represents a basic object.
Definition: object.h:59
vrv::SvgDeviceContext::SetMMOutput
void SetMMOutput(bool mmOutput)
Setting mm output flag (false by default)
Definition: svgdevicecontext.h:199
vrv::SvgDeviceContext::AppendIdAndClass
void AppendIdAndClass(const std::string &gId, const std::string &baseClass, const std::string &addedClasses, GraphicID graphicID=PRIMARY)
Add id, data-id and class attributes.
vrv::SvgDeviceContext::SetSvgViewBox
void SetSvgViewBox(bool svgViewBox)
Setting m_svgViewBox flag (false by default)
Definition: svgdevicecontext.h:212
vrv::DeviceContext
This class is an abstract device context.
Definition: devicecontext.h:57
vrv::SvgDeviceContext::UseGlobalStyling
bool UseGlobalStyling() override
In SVG use global styling but not with mm output (for pdf generation)
Definition: svgdevicecontext.h:194
vrv::SvgDeviceContext::SetCustomGraphicAttributes
void SetCustomGraphicAttributes(const std::string &data, const std::string &value) override
Method for adding custom graphic data-* attributes.
vrv::SvgDeviceContext::SetRemoveXlink
void SetRemoveXlink(bool removeXlink)
Removes the xlink: prefex on href attributes, necessary for some newer browsers.
Definition: svgdevicecontext.h:232
vrv::SvgDeviceContext::GetStringSVG
std::string GetStringSVG(bool xml_declaration=false)
}
vrv::ObjectFactory::GetInstance
static ObjectFactory * GetInstance()
A static method returning a static object in order to guarantee initialisation.
vrv::SvgDeviceContext::AppendAdditionalAttributes
void AppendAdditionalAttributes(Object *object)
Append additional attributes, as given in m_svgAdditionalAttributes.
vrv::SvgDeviceContext::SetCss
void SetCss(const std::string &css)
Setter for an additional CSS.
Definition: svgdevicecontext.h:237
vrv::View
This class is a drawing context and corresponds to the view of a MVC design pattern.
Definition: view.h:105
vrv::SvgDeviceContext::SetFormatRaw
void SetFormatRaw(bool rawFormat)
Set the SVG to have 'raw' formatting, with no extraneous whitespace or newlines.
Definition: svgdevicecontext.h:227
vrv::SvgDeviceContext::SetSmuflTextFont
void SetSmuflTextFont(option_SMUFLTEXTFONT smuflTextFont)
Setter for a the smufl text font option.
Definition: svgdevicecontext.h:260
vrv::Point
Simple class for representing points.
Definition: devicecontextbase.h:203
vrv::SvgDeviceContext::SetSvgBoundingBoxes
void SetSvgBoundingBoxes(bool svgBoundingBoxes)
Setting m_svgBoudingBoxes flag (false by default)
Definition: svgdevicecontext.h:207
vrv::SvgDeviceContext
This class implements a drawing context for generating SVG files.
Definition: svgdevicecontext.h:39
vrv::SvgDeviceContext::SetCustomGraphicColor
void SetCustomGraphicColor(const std::string &color) override
Method for changing the color of a custom graphic.