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 
119  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 
128  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 
146  void ResumeGraphic(Object *object, std::string gId) override;
147  void EndResumedGraphic(Object *object, View *view) override;
149 
154  void StartTextGraphic(Object *object, const std::string &gClass, const std::string &gId) override;
155  void EndTextGraphic(Object *object, View *view) override;
157 
162  void RotateGraphic(Point const &orig, double angle) override;
164 
169  void StartPage() override;
170  void EndPage() override;
172 
177  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 
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 SetUseLiberation(bool useLiberation) { m_useLiberation = useLiberation; }
208 
212  void SetSvgBoundingBoxes(bool svgBoundingBoxes) { m_svgBoundingBoxes = svgBoundingBoxes; }
213 
217  void SetSvgViewBox(bool svgViewBox) { m_svgViewBox = svgViewBox; }
218 
222  void SetHtml5(bool html5) { m_html5 = html5; }
223 
227  void SetIndent(int indent) { m_indent = indent; }
228 
232  void SetFormatRaw(bool rawFormat) { m_formatRaw = rawFormat; }
233 
237  void SetRemoveXlink(bool removeXlink) { m_removeXlink = removeXlink; }
238 
242  void SetCss(const std::string &css)
243  {
244  m_css = css;
245  this->PrefixCssRules(m_css);
246  }
247 
252  void SetAdditionalAttributes(const std::vector<std::string> &additionalAttributes)
253  {
254  for (std::string s : additionalAttributes) {
255  std::string className = s.substr(0, s.find("@")); // parse <element@attribute>, e.g., "note@pname"
256  std::string attributeName = s.substr(s.find("@") + 1);
257  ClassId classId = ObjectFactory::GetInstance()->GetClassId(className);
258  m_svgAdditionalAttributes.insert({ classId, attributeName });
259  }
260  }
261 
265  void SetSmuflTextFont(option_SMUFLTEXTFONT smuflTextFont) { m_smuflTextFont = smuflTextFont; }
266 
267 private:
272  bool CopyFileToStream(const std::string &filename, std::ostream &dest);
273 
277  void DrawSvgBoundingBox(Object *object, View *view);
278 
282  void DrawSvgBoundingBoxRectangle(int x, int y, int width, int height);
283 
287  void VrvTextFont() { m_vrvTextFont = true; }
288 
292  void VrvTextFontFallback() { m_vrvTextFontFallback = true; }
293 
297  void IncludeTextFont(const std::string &fontname, const Resources *resources);
298 
303  void Commit(bool xml_declaration);
304 
305  void WriteLine(std::string);
306 
307  std::string GetColor(int color) const;
308 
309  pugi::xml_node AddChild(std::string name);
310 
315  void AppendStrokeLineCap(pugi::xml_node node, const Pen &pen);
316  void AppendStrokeLineJoin(pugi::xml_node node, const Pen &pen);
317  void AppendStrokeDashArray(pugi::xml_node node, const Pen &pen);
319 
323  void PrefixCssRules(std::string &rules);
324 
325 public:
326  //
327 private:
333  bool m_vrvTextFont;
334 
338  bool m_vrvTextFontFallback;
339 
340  // we use a std::stringstream because we want to prepend the <defs> which will know only when we reach the end of
341  // the page
342  // some viewer seem to support to have the <defs> at the end, but some do not (pdf2svg, for example)
343  // for this reason, the full svg is finally written a string from the destructor or when Flush() is called
344  std::ostringstream m_outdata;
345 
346  bool m_committed; // did we flushed the file?
347  int m_originX, m_originY;
348 
349  // Here we hold references to all different glyphs used so far,
350  // including any glyph for the same code but from different fonts.
351  // They will be added at the end of the file as <defs>.
352  // With multiple font support we need to keep track of:
353  // a) the glyph (to check if is has been already added)
354  // b) the id assigned to glyphs on the (that is has been consumed by the already rendered elements)
355  // To keep things as similar as possible to previous versions we generate ids with as uuuu-ss (where uuuu is the
356  // Smulf code for the glyph and ss the per-session suffix) for most of the cases (single font usage). When the same
357  // glyph has been used from several fonts we use uuuu-n-ss where n indicates the collision count.
358  class GlyphRef {
359  public:
360  GlyphRef(const Glyph *glyph, int count, const std::string &postfix);
361  const Glyph *GetGlyph() const { return m_glyph; };
362  const std::string &GetRefId() const { return m_refId; };
363 
364  private:
365  const Glyph *m_glyph;
366  std::string m_refId;
367  };
368  const std::string InsertGlyphRef(const Glyph *glyph);
369  std::vector<std::pair<const Glyph *, GlyphRef>> m_smuflGlyphs;
370  std::map<std::string, int> m_glyphCodeFontCounter;
371 
372  // pugixml data
373  pugi::xml_document m_svgDoc;
374  pugi::xml_node m_svgNode;
375  pugi::xml_node m_pageNode;
376  pugi::xml_node m_currentNode;
377  std::list<pugi::xml_node> m_svgNodeStack;
378 
379  // output as mm (for pdf generation with a 72 dpi)
380  bool m_mmOutput;
381  bool m_facsimile;
382  // use LiberationTextFont
383  bool m_useLiberation;
384  // add bouding boxes in svg output
385  bool m_svgBoundingBoxes;
386  // use viewbox on svg root element
387  bool m_svgViewBox;
388  // output HTML5 data-* attributes
389  bool m_html5;
390  // additional CSS
391  std::string m_css;
392  // copy additional attributes of given elements to the SVG, in the form "note@pname; layer@n"
393  std::multimap<ClassId, std::string> m_svgAdditionalAttributes;
394  // format output as raw, stripping extraneous whitespace and non-content newlines
395  bool m_formatRaw;
396  // remove xlink from href attributes
397  bool m_removeXlink;
398  // indentation value (-1 for tabs)
399  int m_indent;
400  // postfix to be added to font glyphs
401  std::string m_glyphPostfixId;
402  // embedding of the smufl text font
403  option_SMUFLTEXTFONT m_smuflTextFont;
404  // the document id
405  std::string m_docId;
406 };
407 
408 } // namespace vrv
409 
410 #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:62
Simple class for representing points.
Definition: devicecontextbase.h:203
This class implements a drawing context for generating SVG files.
Definition: svgdevicecontext.h:39
void SetSvgViewBox(bool svgViewBox)
Setting m_svgViewBox flag (false by default)
Definition: svgdevicecontext.h:217
void SetCss(const std::string &css)
Setter for an additional CSS.
Definition: svgdevicecontext.h:242
void SetSmuflTextFont(option_SMUFLTEXTFONT smuflTextFont)
Setter for a the smufl text font option.
Definition: svgdevicecontext.h:265
void SetIndent(int indent)
Setter for indent of the SVG (default is 3, -1 for tabs)
Definition: svgdevicecontext.h:227
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:199
void SetUseLiberation(bool useLiberation)
Setting use Liberation flag (false by default)
Definition: svgdevicecontext.h:207
bool UseGlobalStyling() override
In SVG use global styling but not with mm output (for pdf generation)
Definition: svgdevicecontext.h:194
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:252
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:232
void SetRemoveXlink(bool removeXlink)
Removes the xlink: prefex on href attributes, necessary for some newer browsers.
Definition: svgdevicecontext.h:237
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:222
void SetSvgBoundingBoxes(bool svgBoundingBoxes)
Setting m_svgBoudingBoxes flag (false by default)
Definition: svgdevicecontext.h:212
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