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