RDKit
Open-source cheminformatics and machine learning.
StringRect.h
Go to the documentation of this file.
1 //
2 // Copyright (C) 2021-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 used by DrawText classes. It is not intended for general use.
14 
15 #ifndef RDKIT_STRINGRECT_H
16 #define RDKIT_STRINGRECT_H
17 
18 #include <Geometry/point.h>
19 
20 namespace RDKit {
21 namespace MolDraw2D_detail {
22 
23 // for holding dimensions of the rectangle round a string.
24 struct StringRect {
25  Point2D trans_; // Where to draw char relative to other chars in string
26  Point2D offset_; // offset for draw coords so char is centred correctly
27  Point2D g_centre_; // glyph centre relative to the origin of the char.
28  double y_shift_; // shift the whole thing in y by this. For multi-line text.
29  double width_, height_; // of the glyph itself, not the character cell
30  double rect_corr_; // because if we move a char one way, we need to move the
31  // rectangle the other.
32  int clash_score_; // rough measure of how badly it clashed with other things
33  // lower is better, 0 is no clash.
34 
36  : trans_(0.0, 0.0),
37  offset_(0.0, 0.0),
39  y_shift_(0.0),
40  width_(0.0),
41  height_(0.0),
42  rect_corr_(0.0),
43  clash_score_(0) {}
44  StringRect(const Point2D &offset, const Point2D &g_centre, double w, double h)
45  : trans_(0.0, 0.0),
46  offset_(offset),
47  g_centre_(g_centre),
48  y_shift_(0.0),
49  width_(w),
50  height_(h),
51  rect_corr_(0.0),
52  clash_score_(0) {}
53  // tl is top, left; br is bottom, right of the glyph, relative to the
54  // centre. Padding in draw coords.
55  void calcCorners(Point2D &tl, Point2D &tr, Point2D &br, Point2D &bl,
56  double padding) const {
57  double wb2 = padding + width_ / 2.0;
58  double hb2 = padding + height_ / 2.0;
59  Point2D c;
60  calcCentre(c);
61  tl = Point2D(c.x - wb2, c.y - hb2);
62  tr = Point2D(c.x + wb2, c.y - hb2);
63  br = Point2D(c.x + wb2, c.y + hb2);
64  bl = Point2D(c.x - wb2, c.y + hb2);
65  }
66  void calcCentre(Point2D &c) const {
67  c = trans_ + g_centre_ - offset_;
68  c.y -= y_shift_;
69  }
70  bool isPointInside(const Point2D &pt, double padding = 0.0) const {
71  Point2D tl, tr, br, bl;
72  calcCorners(tl, tr, br, bl, padding);
73  // is +ve y up or down?
74  if (tl.y < bl.y) {
75  std::swap(tl, bl);
76  std::swap(tr, br);
77  }
78  return pt.x >= tl.x && pt.x <= br.x && pt.y >= br.y && pt.y <= tl.y;
79  }
80  bool doesItIntersect(const StringRect &other, double padding = 0.0) const {
81  Point2D ttl, ttr, tbr, tbl;
82  calcCorners(ttl, ttr, tbr, tbl, padding);
83  // is +ve y up or down?
84  if (ttl.y < tbl.y) {
85  std::swap(ttl, tbl);
86  std::swap(ttr, tbr);
87  }
88  Point2D otl, otr, obr, obl;
89  other.calcCorners(otl, otr, obr, obl, padding);
90  if (otl.y < obl.y) {
91  std::swap(otl, obl);
92  std::swap(otr, obr);
93  }
94  // This could be done with isPointInside, but that would recalculate
95  // the corners each time.
96  if ((otl.x >= ttl.x && otl.x <= ttr.x && otl.y >= tbl.y &&
97  otl.y <= ttl.y) ||
98  (otr.x >= ttl.x && otr.x <= ttr.x && otr.y >= tbl.y &&
99  otr.y <= ttl.y) ||
100  (obr.x >= ttl.x && obr.x <= ttr.x && obr.y >= tbl.y &&
101  obr.y <= ttl.y) ||
102  (obl.x >= ttl.x && obl.x <= ttr.x && obl.y >= tbl.y &&
103  obl.y <= ttl.y)) {
104  return true;
105  }
106  if ((ttl.x >= otl.x && ttl.x <= otr.x && ttl.y >= obl.y &&
107  ttl.y <= otl.y) ||
108  (ttr.x >= otl.x && ttr.x <= otr.x && ttr.y >= obl.y &&
109  ttr.y <= otl.y) ||
110  (tbr.x >= otl.x && tbr.x <= otr.x && tbr.y >= obl.y &&
111  tbr.y <= otl.y) ||
112  (tbl.x >= otl.x && tbl.x <= otr.x && tbl.y >= obl.y &&
113  tbl.y <= otl.y)) {
114  return true;
115  }
116  return false;
117  }
118 };
119 
120 } // namespace MolDraw2D_detail
121 } // namespace RDKit
122 
123 #endif // RDKIT_STRINGRECT_H
Std stuff.
Definition: Abbreviations.h:19
StringRect(const Point2D &offset, const Point2D &g_centre, double w, double h)
Definition: StringRect.h:44
bool doesItIntersect(const StringRect &other, double padding=0.0) const
Definition: StringRect.h:80
bool isPointInside(const Point2D &pt, double padding=0.0) const
Definition: StringRect.h:70
void calcCorners(Point2D &tl, Point2D &tr, Point2D &br, Point2D &bl, double padding) const
Definition: StringRect.h:55
void calcCentre(Point2D &c) const
Definition: StringRect.h:66