19 #ifndef _RD_DRAWING_TO_CAIRO_H_ 20 #define _RD_DRAWING_TO_CAIRO_H_ 28 void setColorCairo(
int atNum, cairo_t *cr) {
32 cairo_set_source_rgb(cr, 0.0, 0.0, 1.0);
35 cairo_set_source_rgb(cr, 1.0, 0.0, 0.0);
38 cairo_set_source_rgb(cr, 0.2, 0.8, 0.8);
41 cairo_set_source_rgb(cr, 1.0, 0.5, 0.0);
44 cairo_set_source_rgb(cr, 0.8, 0.8, 0.0);
47 cairo_set_source_rgb(cr, 0.0, 0.8, 0.0);
50 cairo_set_source_rgb(cr, 0.5, 0.3, 0.1);
53 cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
56 cairo_set_source_rgb(cr, 0.0, 0.0, 0.0);
59 void drawLineCairo(std::vector<int>::const_iterator &pos, cairo_t *cr) {
62 cairo_set_line_width(cr, width * 10);
67 cairo_set_dash(cr, 0, 0, 0);
72 cairo_set_dash(cr, dashes,
sizeof(dashes) /
sizeof(dashes[0]), 0);
77 cairo_set_dash(cr, dashes,
sizeof(dashes) /
sizeof(dashes[0]), 0);
86 setColorCairo(an1, cr);
87 cairo_move_to(cr, xp1, yp1);
88 cairo_line_to(cr, xp2, yp2);
91 int mx = xp1 + (xp2 - xp1) / 2;
92 int my = yp1 + (yp2 - yp1) / 2;
94 setColorCairo(an1, cr);
95 cairo_move_to(cr, xp1, yp1);
96 cairo_line_to(cr, mx, my);
98 setColorCairo(an2, cr);
99 cairo_move_to(cr, mx, my);
100 cairo_line_to(cr, xp2, yp2);
104 void drawAtomCairo(std::vector<int>::const_iterator &pos, cairo_t *cr) {
108 double xp =
static_cast<double>(*pos++);
109 double yp =
static_cast<double>(*pos++);
111 std::string label =
"";
112 for (
unsigned int i = 0; i < slen; ++i) {
113 label += (char)*pos++;
117 if (label.length()) {
118 cairo_text_extents_t extents;
119 cairo_text_extents(cr, label.c_str(), &extents);
120 double twidth = extents.width, theight = extents.height;
142 cairo_set_source_rgb(cr, 1.0, 1., 1.);
143 cairo_rectangle(cr, xp - 10, yp - theight - 10, twidth + 20, theight + 20);
146 cairo_move_to(cr, xp, yp);
147 setColorCairo(atNum, cr);
148 cairo_show_text(cr, label.c_str());
155 int height,
int fontSize = 12,
156 int maxDotsPerAngstrom = 60) {
158 PRECONDITION(width > 0 && height > 0,
"bad dimensions");
160 cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
161 cairo_rectangle(cr, 0, 0, width, height);
164 cairo_select_font_face(cr,
"sans", CAIRO_FONT_SLANT_NORMAL,
165 CAIRO_FONT_WEIGHT_NORMAL);
167 std::vector<int>::const_iterator pos = drawing.begin();
170 std::cerr <<
"no RESOLUTION token found" << std::endl;
173 resolution = *(pos + 1);
177 std::cerr <<
"no bounds token found" << std::endl;
184 PRECONDITION(dwidth > 0 && dheight > 0,
"bad dimensions");
188 xSize =
static_cast<double>(dwidth) / resolution;
189 ySize =
static_cast<double>(dheight) / resolution;
192 if (dwidth > width || dheight > height) {
193 if (static_cast<double>(dwidth) / width >
194 static_cast<double>(dheight) / height) {
195 scale =
static_cast<double>(width) / dwidth;
197 scale =
static_cast<double>(height) / dheight;
200 if (width / xSize > height / ySize) {
201 if (width / xSize > maxDotsPerAngstrom) {
202 scale = maxDotsPerAngstrom * xSize / width;
205 if (height / ySize > maxDotsPerAngstrom) {
206 scale = maxDotsPerAngstrom * ySize / height;
212 cairo_translate(cr, .5 * (width - dwidth * scale),
213 .5 * (height - dheight * scale));
214 cairo_scale(cr, scale, scale);
217 double dFontSize = 1.5 * maxDotsPerAngstrom * fontSize / 14;
218 cairo_set_font_size(cr, dFontSize);
220 while (pos != drawing.end()) {
224 drawLineCairo(pos, cr);
227 drawAtomCairo(pos, cr);
230 std::cerr <<
"unrecognized token: " << token << std::endl;
void DrawingToCairo(const std::vector< int > &drawing, cairo_t *cr, int width, int height, int fontSize=12, int maxDotsPerAngstrom=60)
Includes a bunch of functionality for handling Atom and Bond queries.
#define PRECONDITION(expr, mess)