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:
45  SvgDeviceContext(const std::string &docId);
46  virtual ~SvgDeviceContext();
48 
53  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 
65  Point GetLogicalOrigin() override;
67 
72  std::string GetStringSVG(bool xml_declaration = false);
73 
78  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 
104  void StartText(int x, int y, data_HORIZONTALALIGNMENT alignment = HORIZONTALALIGNMENT_left) override;
105  void EndText() override;
106 
111  void MoveTextTo(int x, int y, data_HORIZONTALALIGNMENT alignment) override;
112  void MoveTextVerticallyTo(int y) override;
114 
118  bool ApplyOffset() override { return true; }
119 
124  void StartGraphic(Object *object, const std::string &gClass, const std::string &gId, GraphicID graphicID = PRIMARY,
125  bool prepend = false) override;
126  void EndGraphic(Object *object, View *view) override;
128 
133  void StartCustomGraphic(const std::string &name, std::string gClass = "", std::string gId = "") override;
134  void EndCustomGraphic() override;
136 
140  void SetCustomGraphicColor(const std::string &color) override;
141 
145  void SetCustomGraphicAttributes(const std::string &data, const std::string &value) override;
146 
151  void ResumeGraphic(Object *object, std::string gId) override;
152  void EndResumedGraphic(Object *object, View *view) override;
154 
159  void StartTextGraphic(Object *object, const std::string &gClass, const std::string &gId) override;
160  void EndTextGraphic(Object *object, View *view) override;
162 
167  void RotateGraphic(Point const &orig, double angle) override;
169 
174  void StartPage() override;
175  void EndPage() override;
177 
182  void AddDescription(const std::string &text) override;
184 
188  void AppendIdAndClass(const std::string &gId, const std::string &baseClass, const std::string &addedClasses,
189  GraphicID graphicID = PRIMARY);
190 
195 
199  bool UseGlobalStyling() override { return !m_mmOutput; }
200 
204  void SetMMOutput(bool mmOutput) { m_mmOutput = mmOutput; }
205 
206  void SetFacsimile(bool facsimile) { m_facsimile = facsimile; }
207  bool GetFacsimile() { return m_facsimile; }
208 
212  void SetUseLiberation(bool useLiberation) { m_useLiberation = useLiberation; }
213 
217  void SetSvgBoundingBoxes(bool svgBoundingBoxes) { m_svgBoundingBoxes = svgBoundingBoxes; }
218 
222  void SetSvgContentBoundingBoxes(bool svgContentBoundingBoxes)
223  {
224  m_svgContentBoundingBoxes = svgContentBoundingBoxes;
225  }
226 
230  void SetSvgViewBox(bool svgViewBox) { m_svgViewBox = svgViewBox; }
231 
235  void SetHtml5(bool html5) { m_html5 = html5; }
236 
240  void SetIndent(int indent) { m_indent = indent; }
241 
245  void SetFormatRaw(bool rawFormat) { m_formatRaw = rawFormat; }
246 
250  void SetRemoveXlink(bool removeXlink) { m_removeXlink = removeXlink; }
251 
255  void SetCss(const std::string &css)
256  {
257  m_css = css;
258  this->PrefixCssRules(m_css);
259  }
260 
265  void SetAdditionalAttributes(const std::vector<std::string> &additionalAttributes)
266  {
267  for (std::string s : additionalAttributes) {
268  std::string className = s.substr(0, s.find("@")); // parse <element@attribute>, e.g., "note@pname"
269  std::string attributeName = s.substr(s.find("@") + 1);
270  ClassId classId = ObjectFactory::GetInstance()->GetClassId(className);
271  m_svgAdditionalAttributes.insert({ classId, attributeName });
272  }
273  }
274 
278  void SetSmuflTextFont(option_SMUFLTEXTFONT smuflTextFont) { m_smuflTextFont = smuflTextFont; }
279 
280 private:
285  bool CopyFileToStream(const std::string &filename, std::ostream &dest);
286 
290  void DrawSvgBoundingBox(Object *object, View *view);
291 
295  void DrawSvgBoundingBoxRectangle(int x, int y, int width, int height);
296 
300  void VrvTextFont() { m_vrvTextFont = true; }
301 
305  void VrvTextFontFallback() { m_vrvTextFontFallback = true; }
306 
310  void IncludeTextFont(const std::string &fontname, const Resources *resources);
311 
316  void Commit(bool xml_declaration);
317 
318  void WriteLine(std::string);
319 
320  std::string GetColor(int color) const;
321 
322  pugi::xml_node AddChild(std::string name);
323 
328  void AppendStrokeLineCap(pugi::xml_node node, const Pen &pen);
329  void AppendStrokeLineJoin(pugi::xml_node node, const Pen &pen);
330  void AppendStrokeDashArray(pugi::xml_node node, const Pen &pen);
332 
336  void PrefixCssRules(std::string &rules);
337 
338 public:
339  //
340 private:
346  bool m_vrvTextFont;
347 
351  bool m_vrvTextFontFallback;
352 
353  // we use a std::stringstream because we want to prepend the <defs> which will know only when we reach the end of
354  // the page
355  // some viewer seem to support to have the <defs> at the end, but some do not (pdf2svg, for example)
356  // for this reason, the full svg is finally written a string from the destructor or when Flush() is called
357  std::ostringstream m_outdata;
358 
359  bool m_committed; // did we flushed the file?
360  int m_originX, m_originY;
361 
362  // Here we hold references to all different glyphs used so far,
363  // including any glyph for the same code but from different fonts.
364  // They will be added at the end of the file as <defs>.
365  // With multiple font support we need to keep track of:
366  // a) the glyph (to check if is has been already added)
367  // b) the id assigned to glyphs on the (that is has been consumed by the already rendered elements)
368  // To keep things as similar as possible to previous versions we generate ids with as uuuu-ss (where uuuu is the
369  // Smulf code for the glyph and ss the per-session suffix) for most of the cases (single font usage). When the same
370  // glyph has been used from several fonts we use uuuu-n-ss where n indicates the collision count.
371  class GlyphRef {
372  public:
373  GlyphRef(const Glyph *glyph, int count, const std::string &postfix);
374  const Glyph *GetGlyph() const { return m_glyph; };
375  const std::string &GetRefId() const { return m_refId; };
376 
377  private:
378  const Glyph *m_glyph;
379  std::string m_refId;
380  };
381  const std::string InsertGlyphRef(const Glyph *glyph);
382  std::vector<std::pair<const Glyph *, GlyphRef>> m_smuflGlyphs;
383  std::map<std::string, int> m_glyphCodeFontCounter;
384 
385  // pugixml data
386  pugi::xml_document m_svgDoc;
387  pugi::xml_node m_svgNode;
388  pugi::xml_node m_pageNode;
389  pugi::xml_node m_currentNode;
390  std::list<pugi::xml_node> m_svgNodeStack;
391 
392  // output as mm (for pdf generation with a 72 dpi)
393  bool m_mmOutput;
394  bool m_facsimile;
395  // use LiberationTextFont
396  bool m_useLiberation;
397  // add bouding boxes in svg output
398  bool m_svgBoundingBoxes;
399  // add content bounding boxes in svg output
400  bool m_svgContentBoundingBoxes;
401  // use viewbox on svg root element
402  bool m_svgViewBox;
403  // output HTML5 data-* attributes
404  bool m_html5;
405  // additional CSS
406  std::string m_css;
407  // copy additional attributes of given elements to the SVG, in the form "note@pname; layer@n"
408  std::multimap<ClassId, std::string> m_svgAdditionalAttributes;
409  // format output as raw, stripping extraneous whitespace and non-content newlines
410  bool m_formatRaw;
411  // remove xlink from href attributes
412  bool m_removeXlink;
413  // indentation value (-1 for tabs)
414  int m_indent;
415  // postfix to be added to font glyphs
416  std::string m_glyphPostfixId;
417  // embedding of the smufl text font
418  option_SMUFLTEXTFONT m_smuflTextFont;
419  // the document id
420  std::string m_docId;
421 };
422 
423 } // namespace vrv
424 
425 #endif // __VRV_SVG_DC_H__
This class is an abstract device context.
Definition: devicecontext.h:57
ClassId GetClassId(std::string name)
Get the ClassId from the MEI element string name by making a lookup in the register.
static ObjectFactory * GetInstance()
A static method returning a static object in order to guarantee initialisation.
This class represents a basic object.
Definition: object.h:64
Simple class for representing points.
Definition: devicecontextbase.h:203
This class implements a drawing context for generating SVG files.
Definition: svgdevicecontext.h:39
void SetSvgContentBoundingBoxes(bool svgContentBoundingBoxes)
Setting m_svgContentBoundingBoxes flag (false by default)
Definition: svgdevicecontext.h:222
void SetSvgViewBox(bool svgViewBox)
Setting m_svgViewBox flag (false by default)
Definition: svgdevicecontext.h:230
void SetCss(const std::string &css)
Setter for an additional CSS.
Definition: svgdevicecontext.h:255
void SetSmuflTextFont(option_SMUFLTEXTFONT smuflTextFont)
Setter for a the smufl text font option.
Definition: svgdevicecontext.h:278
void SetIndent(int indent)
Setter for indent of the SVG (default is 3, -1 for tabs)
Definition: svgdevicecontext.h:240
void AppendAdditionalAttributes(Object *object)
Append additional attributes, as given in m_svgAdditionalAttributes.
std::string GetStringSVG(bool xml_declaration=false)
}
void SetMMOutput(bool mmOutput)
Setting mm output flag (false by default)
Definition: svgdevicecontext.h:204
void SetUseLiberation(bool useLiberation)
Setting use Liberation flag (false by default)
Definition: svgdevicecontext.h:212
bool UseGlobalStyling() override
In SVG use global styling but not with mm output (for pdf generation)
Definition: svgdevicecontext.h:199
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:265
void AppendIdAndClass(const std::string &gId, const std::string &baseClass, const std::string &addedClasses, GraphicID graphicID=PRIMARY)
Add id, data-id and class attributes.
void SetFormatRaw(bool rawFormat)
Set the SVG to have 'raw' formatting, with no extraneous whitespace or newlines.
Definition: svgdevicecontext.h:245
void SetRemoveXlink(bool removeXlink)
Removes the xlink: prefex on href attributes, necessary for some newer browsers.
Definition: svgdevicecontext.h:250
bool ApplyOffset() override
Indicate if offset should be applied.
Definition: svgdevicecontext.h:118
void SetCustomGraphicAttributes(const std::string &data, const std::string &value) override
Method for adding custom graphic data-* attributes.
void SetHtml5(bool html5)
Setting m_html5 flag (false by default)
Definition: svgdevicecontext.h:235
void SetSvgBoundingBoxes(bool svgBoundingBoxes)
Setting m_svgBoudingBoxes flag (false by default)
Definition: svgdevicecontext.h:217
void SetCustomGraphicColor(const std::string &color) override
Method for changing the color of a custom graphic.
This class is a drawing context and corresponds to the view of a MVC design pattern.
Definition: view.h:106