RDKit: DrawingToSVG.h Source File

| RDKit Open-source cheminformatics and machine learning.

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

DrawingToSVG.h
Go to the documentation of this file.
1 // $Id$
2 /*
3 *
4 * Copyright (c) 2011, Novartis Institutes for BioMedical Research Inc.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above
14 * copyright notice, this list of conditions and the following
15 * disclaimer in the documentation and/or other materials provided
16 * with the distribution.
17 * * Neither the name of Novartis Institutes for BioMedical Research Inc.
18 * nor the names of its contributors may be used to endorse or promote
19 * products derived from this software without specific prior written
20 *permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #ifndef _RD_DRAWING_TO_SVG_H_
36 #define _RD_DRAWING_TO_SVG_H_
37
38 #include <GraphMol/MolDrawing/MolDrawing.h>
39
40 namespace RDKit {
41 namespace Drawing {
42 namespace {
43 std::string getColor(int atNum) {
44 std::string res = "#000000";
45 switch (atNum) {
46 case 7:
47 res = "#0000FF";
48 break;
49 case 8:
50 res = "#FF0000";
51 break;
52 case 9:
53 res = "#33CCCC";
54 break;
55 case 15:
56 res = "#FF7F00";
57 break;
58 case 16:
59 res = "#CCCC00";
60 break;
61 case 17:
62 res = "#00CC00";
63 break;
64 case 35:
65 res = "#7F4C19";
66 break;
67 case 0:
68 res = "#7F7F7F";
69 break;
70 default:
71 res = "#000000";
72 }
73 return res;
74 }
75 void drawLine(std::vector<int>::const_iterator &pos, std::ostringstream &sstr,
76 unsigned int lineWidthMult) {
77 int width = *pos++;
78 width *= lineWidthMult;
79
80 int dashed = *pos++;
81 std::string dashString = "";
82 switch (dashed) {
83 case 0:
84 break;
85 case 2:
86 dashString = ";stroke-dasharray:2, 6";
87 break;
88 default:
89 dashString = ";stroke-dasharray:6, 6";
90 }
91 int an1 = *pos++;
92 int an2 = *pos++;
93 std::string c1 = getColor(an1);
94 std::string c2 = getColor(an2);
95 if (c1 == c2) {
96 sstr << "<svg:path ";
97 sstr << "d='M " << *pos << "," << *(pos + 1) << " " << *(pos + 2) << ","
98 << *(pos + 3) << "' ";
99 pos += 4;
100 sstr << "style='fill:none;fill-rule:evenodd;stroke:" << c1
101 << ";stroke-width:" << width
102 << "px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
103 << dashString << "'";
104 sstr << " />\n";
105 } else {
106 int xp1 = *pos++;
107 int yp1 = *pos++;
108 int xp2 = *pos++;
109 int yp2 = *pos++;
110 int mx = xp1 + (xp2 - xp1) / 2;
111 int my = yp1 + (yp2 - yp1) / 2;
112 sstr << "<svg:path ";
113 sstr << "d='M " << xp1 << "," << yp1 << " " << mx << "," << my << "' ";
114 sstr << "style='fill:none;fill-rule:evenodd;stroke:" << c1
115 << ";stroke-width:" << width
116 << "px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
117 << dashString << "'";
118 sstr << " />\n";
119 sstr << "<svg:path ";
120 sstr << "d='M " << mx << "," << my << " " << xp2 << "," << yp2 << "' ";
121 sstr << "style='fill:none;fill-rule:evenodd;stroke:" << c2
122 << ";stroke-width:" << width
123 << "px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
124 << dashString << "'";
125 sstr << " />\n";
126 }
127 }
128
129 void drawAtom(std::vector<int>::const_iterator &pos, std::ostringstream &sstr,
130 unsigned int fontSz, bool includeAtomCircles = false) {
131 int atNum = *pos++;
132 int xp = *pos++;
133 int yp = *pos++;
134 int slen = *pos++;
135 std::string label = "";
136 for (unsigned int i = 0; i < slen; ++i) {
137 label += (char)*pos++;
138 }
139 int orient = *pos++;
140 if (label.length()) {
141 int width = fontSz * label.length();
142 int height = fontSz;
143 sstr << "<svg:g transform='translate(" << xp << "," << yp
144 << ")'><svg:rect ";
145 sstr << "style='opacity:1.0;fill:#FFFFFF;stroke:none'";
146 sstr << " width='" << width << "' height='" << height << "'";
147 sstr << " x='-" << width / 2 << "' y='-" << height / 2 << "'";
148 sstr << "> </svg:rect>\n";
149 sstr << "<svg:text";
150 sstr << " style='font-size:" << fontSz
151 << "px;font-style:normal;font-weight:normal;line-height:125%;letter-"
152 "spacing:0px;word-spacing:0px;fill-opacity:1;stroke:none;font-"
153 "family:sans-serif;text-anchor:middle"
154 << ";fill:" << getColor(atNum) << "'";
155 sstr << " y='" << .75 * fontSz / 2 << "'>";
156 sstr << "<svg:tspan>";
157 sstr << label << "</svg:tspan>";
158 sstr << "</svg:text>";
159 sstr << "</svg:g>\n";
160 }
161 if (includeAtomCircles) {
162 #if 0
163 sstr<<"<svg:circle cx='"<<xp<<"' cy='"<<yp<<"' r='5' />\n";
164 #else
165 sstr << "<svg:circle cx='" << xp << "' cy='" << yp
166 << "' r='0' style='fill:none;stroke:none' />\n";
167 #endif
168 }
169 }
170 } // end of anonymous namespace
171
172 std::string DrawingToSVG(const std::vector<int> &drawing,
173 unsigned int lineWidthMult = 2,
174 unsigned int fontSize = 50,
175 bool includeAtomCircles = false) {
176 std::vector<int>::const_iterator pos = drawing.begin() + 2;
177 if (*pos != RDKit::Drawing::BOUNDS) {
178 std::cerr << "no bounds token found" << std::endl;
179 return "";
180 }
181 pos += 3;
182 unsigned int width, height;
183 width = *pos++;
184 height = *pos++;
185 std::ostringstream sstr;
186 sstr << "<?xml version='1.0' encoding='iso-8859-1'?>\n";
187 sstr << "<svg:svg version='1.1' baseProfile='full'\n \
188 xmlns:svg='http://www.w3.org/2000/svg'\n \
189 xmlns:xlink='http://www.w3.org/1999/xlink'\n \
190 xml:space='preserve'\n";
191 sstr << "width='" << width << "px' height='" << height << "px' >\n";
192 sstr << "<svg:rect ";
193 sstr << "style='opacity:1.0;fill:#FFFFFF;stroke:none'";
194 sstr << " width='" << width << "' height='" << height << "'";
195 sstr << " x='0' y='0'";
196 sstr << "> </svg:rect>\n";
197 sstr << "<svg:g transform='translate(" << width * .05 << "," << height * .05
198 << ") scale(.85,.85)'>";
199 while (pos != drawing.end()) {
200 int token = *pos++;
201 switch (token) {
202 case RDKit::Drawing::LINE:
203 drawLine(pos, sstr, lineWidthMult);
204 break;
205 case RDKit::Drawing::ATOM:
206 drawAtom(pos, sstr, fontSize, includeAtomCircles);
207 break;
208 default:
209 std::cerr << "unrecognized token: " << token << std::endl;
210 }
211 }
212 sstr << "</svg:g></svg:svg>";
213 return sstr.str();
214 }
215 } // end of namespace Drawing
216 } // end of namespace RDKit
217 #endif
RDKit::Drawing::DrawingToSVG
std::string DrawingToSVG(const std::vector< int > &drawing, unsigned int lineWidthMult=2, unsigned int fontSize=50, bool includeAtomCircles=false)
Definition: DrawingToSVG.h:172
MolDrawing.h
RDKit::Drawing::LINE
Definition: MolDrawing.h:43
RDKit::Drawing::BOUNDS
Definition: MolDrawing.h:43
RDKit
Std stuff.
Definition: Atom.h:29
RDKit::Drawing::ATOM
Definition: MolDrawing.h:43
RDKit::Drawing::detail::drawLine
void drawLine(std::vector< ElementType > &res, int atnum1, int atnum2, int lineWidth, int dashed, double x1, double y1, double x2, double y2)
Definition: MolDrawing.h:48