RDKit
Open-source cheminformatics and machine learning.
DrawText.h
Go to the documentation of this file.
1 //
2 // @@ All Rights Reserved @@
3 // This file is part of the RDKit.
4 // The contents are covered by the terms of the BSD license
5 // which is included in the file license.txt, found at the root
6 // of the RDKit source tree.
7 //
8 //
9 // Original author: David Cosgrove (CozChemIx) on 29/04/2020.
10 //
11 // This is an abstract base class for drawing text into a MolDraw2D
12 // object.
13 
14 #ifndef RDKIT_DRAWTEXT_H
15 #define RDKIT_DRAWTEXT_H
16 
17 #include <string>
18 #include <vector>
19 
20 #include <RDGeneral/export.h>
21 #include <Geometry/point.h>
23 
24 using RDGeom::Point2D;
25 
26 namespace RDKit {
27 
28 enum class TextDrawType : unsigned char {
29  TextDrawNormal = 0,
32 };
33 std::ostream &operator<<(std::ostream &oss, const TextAlignType &tat);
34 std::ostream &operator<<(std::ostream &oss, const TextDrawType &tdt);
35 std::ostream &operator<<(std::ostream &oss, const OrientType &o);
36 
37 // ****************************************************************************
39  public:
40  static constexpr double FONT_SIZE = 0.6; // seems to be a good number
41 
42  DrawText(double max_fnt_sz, double min_fnt_sz);
43  virtual ~DrawText() {}
44 
45  DrawColour const &colour() const;
46  void setColour(const DrawColour &col);
47 
48  // size in "pixels" i.e scale() * base_font_size_.
49  double fontSize() const;
50  void setFontSize(double new_size);
51  double baseFontSize() const;
52  void setBaseFontSize(double new_size);
53  double maxFontSize() const;
54  void setMaxFontSize(double new_max);
55  double minFontSize() const;
56  void setMinFontSize(double new_max);
57  double fontScale() const;
58  void setFontScale(double new_scale);
59 
60  // these are only relevant for the FreeType DrawText classes.
61  virtual std::string getFontFile() const { return ""; }
62  virtual void setFontFile(const std::string &font_file) {
63  RDUNUSED_PARAM(font_file);
64  }
65 
66  //! using the current scale, work out the size of the label
67  /*!
68  Bear in mind when implementing this, that, for example, NH2 will appear as
69  NH<sub>2</sub> to convey that the 2 is a subscript, and this needs to
70  be accounted for in the width and height.
71  */
72  virtual void getStringSize(const std::string &label, double &label_width,
73  double &label_height) const;
74  // returns the extremes of the label, in draw (pixel) coords. dontSplit
75  // true suppresses the call to atomLabelToPieces.
76  void getStringExtremes(const std::string &label, OrientType orient,
77  double &x_min, double &y_min, double &x_max,
78  double &y_max, bool dontSplit = false) const;
79  void getStringRects(const std::string &text, OrientType orient,
80  std::vector<std::shared_ptr<StringRect>> &rects,
81  std::vector<TextDrawType> &draw_modes,
82  std::vector<char> &draw_chars,
83  bool dontSplit = false) const;
84 
85  //! drawString centres the string on cds.
86  virtual void drawString(const std::string &str, const Point2D &cds,
87  TextAlignType align);
88  // Aligns them according to OrientType. This version assumes it's an
89  // atomic symbol and calls atomLabelToPieces. This will behave
90  // badly with general text. Surround the string with <lit></lit>
91  // if that's an issue, or use the version above.
92  void drawString(const std::string &label, const Point2D &cds,
93  OrientType orient);
94 
95  // put the label on end2, and then move end2 so that it is at
96  // the intersection of a string rectangle and the line from end1 to
97  // end2, if there is an intersection. Mostly for trimming bonds
98  // back from atom labels. end1 and end2 in draw coords.
99  void adjustLineForString(const std::string &label, OrientType orient,
100  const Point2D &end1, Point2D &end2) const;
101 
102  // draw the char, with the bottom left hand corner at cds
103  virtual void drawChar(char c, const Point2D &cds) = 0;
104 
105  // puts a colourful rectangle around each character in the string.
106  // For debugging, mostly.
107  void drawStringRects(const std::string &label, OrientType orient,
108  const Point2D &cds, MolDraw2D &mol_draw) const;
109 
110  // cds in draw coords
111  // does the label at cds intersect the given StringRect.
112  bool doesRectIntersect(const std::string &label, OrientType orient,
113  const Point2D &cds, const StringRect &rect) const;
114  // does the vector of StringRects, each translated by cds, intersect the
115  // given StringRect.
116  bool doesRectIntersect(const std::vector<std::shared_ptr<StringRect>> &rects,
117  const Point2D &cds, const StringRect &rect) const;
118  bool doesLineIntersect(const std::string &label, OrientType orient,
119  const Point2D &cds, const Point2D &end1,
120  const Point2D &end2, double padding) const;
121  bool doesLineIntersect(const std::vector<std::shared_ptr<StringRect>> &rects,
122  const Point2D &cds, const Point2D &end1,
123  const Point2D &end2, double padding) const;
125  const std::vector<std::shared_ptr<StringRect>> &rects,
126  const Point2D &cds1, const std::string &label2, OrientType orient2,
127  const Point2D &cds2) const;
128  bool doesStringIntersect(const std::string &label1, OrientType orient1,
129  const Point2D &cds1, const std::string &label2,
130  OrientType orient2, const Point2D &cds2) const;
131 
132  protected:
133  // amount to scale subscripts and superscripts by
134  constexpr static double SUBS_SCALE = 0.66;
135  constexpr static double SUPER_SCALE = 0.66;
136 
137  virtual void alignString(
138  TextAlignType align, const std::vector<TextDrawType> &draw_modes,
139  std::vector<std::shared_ptr<StringRect>> &rects) const;
140  // adjust the string rectangles up and down for super- and subscripts
142  const std::vector<TextDrawType> &draw_modes,
143  std::vector<std::shared_ptr<StringRect>> &rects) const;
144  // return a scale factor appropriate for the character and draw type
145  // (normal or super- or subscript)
146  double selectScaleFactor(char c, TextDrawType draw_type) const;
147 
148  private:
149  DrawColour colour_;
150  double font_scale_;
151  double max_font_size_;
152  double min_font_size_;
153  double base_font_size_ = FONT_SIZE;
154 
155  // return a vector of StringRects, one for each char in text, with
156  // super- and subscripts taken into account. Sizes in pixel coords,
157  // i.e. scaled by fontScale().
158  virtual void getStringRects(const std::string &text,
159  std::vector<std::shared_ptr<StringRect>> &rects,
160  std::vector<TextDrawType> &draw_modes,
161  std::vector<char> &draw_chars) const = 0;
162  void drawChars(const Point2D &a_cds,
163  const std::vector<std::shared_ptr<StringRect>> &rects,
164  const std::vector<TextDrawType> &draw_modes,
165  const std::vector<char> &draw_chars);
166 };
167 
168 //! establishes whether to put string draw mode into super- or sub-script
169 //! mode based on contents of instring from i onwards. Increments i
170 //! appropriately
171 //! \returns true or false depending on whether it did something or not
172 RDKIT_MOLDRAW2D_EXPORT bool setStringDrawMode(const std::string &instring,
173  TextDrawType &draw_mode,
174  size_t &i);
175 
176 // take the label for the given atom and return the individual pieces
177 // that need to be drawn for it. So NH<sub>2</sub> will return
178 // "N", "H<sub>2</sub>".
179 std::vector<std::string> atomLabelToPieces(const std::string &label,
180  OrientType orient);
181 
182 } // namespace RDKit
183 
184 #endif // RDKIT_DRAWTEXT_H
#define RDUNUSED_PARAM(x)
Definition: Invariant.h:196
double fontSize() const
virtual ~DrawText()
Definition: DrawText.h:43
double baseFontSize() const
virtual void setFontFile(const std::string &font_file)
Definition: DrawText.h:62
void setMaxFontSize(double new_max)
bool doesLineIntersect(const std::vector< std::shared_ptr< StringRect >> &rects, const Point2D &cds, const Point2D &end1, const Point2D &end2, double padding) const
double minFontSize() const
bool doesLineIntersect(const std::string &label, OrientType orient, const Point2D &cds, const Point2D &end1, const Point2D &end2, double padding) const
double maxFontSize() const
void adjustStringRectsForSuperSubScript(const std::vector< TextDrawType > &draw_modes, std::vector< std::shared_ptr< StringRect >> &rects) const
virtual void drawChar(char c, const Point2D &cds)=0
void getStringExtremes(const std::string &label, OrientType orient, double &x_min, double &y_min, double &x_max, double &y_max, bool dontSplit=false) const
virtual std::string getFontFile() const
Definition: DrawText.h:61
DrawText(double max_fnt_sz, double min_fnt_sz)
void drawString(const std::string &label, const Point2D &cds, OrientType orient)
void setBaseFontSize(double new_size)
void getStringRects(const std::string &text, OrientType orient, std::vector< std::shared_ptr< StringRect >> &rects, std::vector< TextDrawType > &draw_modes, std::vector< char > &draw_chars, bool dontSplit=false) const
bool doesRectIntersect(const std::string &label, OrientType orient, const Point2D &cds, const StringRect &rect) const
bool doesRectIntersect(const std::vector< std::shared_ptr< StringRect >> &rects, const Point2D &cds, const StringRect &rect) const
DrawColour const & colour() const
virtual void alignString(TextAlignType align, const std::vector< TextDrawType > &draw_modes, std::vector< std::shared_ptr< StringRect >> &rects) const
virtual void drawString(const std::string &str, const Point2D &cds, TextAlignType align)
drawString centres the string on cds.
double selectScaleFactor(char c, TextDrawType draw_type) const
void setMinFontSize(double new_max)
void setColour(const DrawColour &col)
bool doesStringIntersect(const std::vector< std::shared_ptr< StringRect >> &rects, const Point2D &cds1, const std::string &label2, OrientType orient2, const Point2D &cds2) const
void setFontScale(double new_scale)
double fontScale() const
virtual void getStringSize(const std::string &label, double &label_width, double &label_height) const
using the current scale, work out the size of the label
void setFontSize(double new_size)
void drawStringRects(const std::string &label, OrientType orient, const Point2D &cds, MolDraw2D &mol_draw) const
void adjustLineForString(const std::string &label, OrientType orient, const Point2D &end1, Point2D &end2) const
bool doesStringIntersect(const std::string &label1, OrientType orient1, const Point2D &cds1, const std::string &label2, OrientType orient2, const Point2D &cds2) const
MolDraw2D is the base class for doing 2D renderings of molecules.
Definition: MolDraw2D.h:337
#define RDKIT_MOLDRAW2D_EXPORT
Definition: export.h:265
Std stuff.
Definition: Abbreviations.h:18
TextDrawType
Definition: DrawText.h:28
RDKIT_MOLDRAW2D_EXPORT bool setStringDrawMode(const std::string &instring, TextDrawType &draw_mode, size_t &i)
TextAlignType
Definition: MolDraw2D.h:43
std::vector< std::string > atomLabelToPieces(const std::string &label, OrientType orient)
OrientType
Definition: MolDraw2D.h:42
std::ostream & operator<<(std::ostream &oss, const TextAlignType &tat)