1 /**********************************************************************
2 painterformat.cpp  - Output a set of painter commands for 2D depiction
3 
4 Copyright (C) 2012 by Noel O'Boyle
5 
6 This file is part of the Open Babel project.
7 For more information, see <http://openbabel.org/>
8 
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation version 2 of the License.
12 
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 GNU General Public License for more details.
17 ***********************************************************************/
18 #include <openbabel/babelconfig.h>
19 #include <openbabel/obmolecformat.h>
20 #include <openbabel/mol.h>
21 #include <openbabel/op.h>
22 #include <openbabel/depict/depict.h>
23 #include <openbabel/depict/commandpainter.h>
24 
25 using namespace std;
26 
27 
28 
29 namespace OpenBabel
30 {
31 
32 class PainterFormat : public OBMoleculeFormat
33 {
34 public:
35   //Register this format type ID in the constructor
PainterFormat()36   PainterFormat()
37   {
38     OBConversion::RegisterFormat("paint",this);
39   }
40 
Description()41   virtual const char* Description() //required
42   {
43     return
44     "Painter format\n"
45     "Commands used to generate a 2D depiction of a molecule\n\n"
46 
47     "This is a utility format that is useful if you want to\n"
48     "generate a depiction of a molecule yourself, for example\n"
49     "by drawing on a Graphics2D canvas in Java. The format\n"
50     "writes out a list of drawing commands as shown\n"
51     "in the following example::\n\n"
52 
53     "  obabel -:CC(=O)Cl -opaint\n\n"
54 
55 "  NewCanvas 149.3 140.0\n"
56 "  SetPenColor 0.0 0.0 0.0 1.0 (rgba)\n"
57 "  DrawLine 109.3 100.0 to 74.6 80.0\n"
58 "  SetPenColor 0.0 0.0 0.0 1.0 (rgba)\n"
59 "  DrawLine 71.6 80.0 to 71.6 53.0\n"
60 "  DrawLine 77.6 80.0 to 77.6 53.0\n"
61 "  SetPenColor 0.0 0.0 0.0 1.0 (rgba)\n"
62 "  DrawLine 74.6 80.0 to 51.3 93.5\n"
63 "  SetPenColor 0.4 0.4 0.4 1.0 (rgba)\n"
64 "  SetPenColor 0.4 0.4 0.4 1.0 (rgba)\n"
65 "  SetPenColor 1.0 0.1 0.1 1.0 (rgba)\n"
66 "  SetFontSize 16\n"
67 "  SetFontSize 16\n"
68 "  SetFontSize 16\n"
69 "  DrawText 74.6 40.0 \"O\"\n"
70 "  SetPenColor 0.1 0.9 0.1 1.0 (rgba)\n"
71 "  SetFontSize 16\n"
72 "  SetFontSize 16\n"
73 "  SetFontSize 16\n"
74 "  SetFontSize 16\n"
75 "  DrawText 40.0 100.0 \"Cl\"\n\n"
76 
77 "Note that the origin is considered to be in the top left corner.\n\n"
78 
79 "The following image was drawn using the information\n"
80 "in this format as described at\n"
81 "http://baoilleach.blogspot.co.uk/2012/04/painting-molecules-your-way-introducing.html:\n\n"
82 
83 ".. image:: ../_static/bananamol.png\n\n"
84 
85     "Write Options e.g. -xM\n"
86     " M Do not include a margin around the depiction\n\n"
87 
88     ;
89   };
90 
91 
Flags()92   virtual unsigned int Flags()
93   {
94       return NOTREADABLE;
95   };
96 
97   virtual bool WriteMolecule(OBBase* pOb, OBConversion* pConv);
98 };
99   ////////////////////////////////////////////////////
100 
101 //Make an instance of the format class
102 PainterFormat thePainterFormat;
103 
104 /////////////////////////////////////////////////////////////////
105 
106 ////////////////////////////////////////////////////////////////
107 
WriteMolecule(OBBase * pOb,OBConversion * pConv)108 bool PainterFormat::WriteMolecule(OBBase* pOb, OBConversion* pConv)
109 {
110   OBMol* pmol = dynamic_cast<OBMol*>(pOb);
111   if (pmol == nullptr)
112       return false;
113 
114   ostream& ofs = *pConv->GetOutStream();
115 
116   OBMol workingmol(*pmol); // Copy the molecule
117 
118   //*** Coordinate generation ***
119   //Generate coordinates only if no existing 2D coordinates
120   if(!workingmol.Has2D(true))
121   {
122     OBOp* pOp = OBOp::FindType("gen2D");
123     if(!pOp)
124     {
125       obErrorLog.ThrowError("PainterFormat", "gen2D not found", obError, onceOnly);
126       return false;
127     }
128     if(!pOp->Do(&workingmol))
129     {
130       obErrorLog.ThrowError("PainterFormat", string(workingmol.GetTitle()) + "- Coordinate generation unsuccessful", obError);
131       return false;
132     }
133   }
134   if(!workingmol.Has2D() && workingmol.NumAtoms()>1)
135   {
136     string mes("Molecule ");
137     mes += workingmol.GetTitle();
138     mes += " needs 2D coordinates to display in PNG2format";
139     obErrorLog.ThrowError("PainterFormat", mes, obError);
140     return false;
141   }
142 
143   CommandPainter painter(*pConv->GetOutStream());
144   OBDepict depictor(&painter);
145   if(pConv->IsOption("M"))
146     depictor.SetOption(OBDepict::noMargin);
147   depictor.DrawMolecule(&workingmol);
148 
149   return true; //or false to stop converting
150 }
151 
152 } //namespace OpenBabel
153 
154