]> git.lyx.org Git - lyx.git/blob - src/insets/insetgraphicsParams.C
8e0496ef344a89c0c388ea71432497765867e8be
[lyx.git] / src / insets / insetgraphicsParams.C
1 /**
2  * \file insetgraphicsParams.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Baruch Even
7  * \author Herbert Voß
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "insetgraphicsParams.h"
15
16 #include "debug.h"
17 #include "lyxlex.h"
18 #include "lyxrc.h"
19
20 #include "frontends/lyx_gui.h"
21
22 #include "graphics/GraphicsParams.h"
23
24 #include "support/filetools.h"
25 #include "support/lyxlib.h"
26 #include "support/lstrings.h"
27 #include "support/translator.h"
28
29 using lyx::support::float_equal;
30 using lyx::support::readBB_from_PSFile;
31 using lyx::support::strToDbl;
32 using lyx::support::strToInt;
33 using lyx::support::token;
34
35 using std::string;
36 using std::ostream;
37
38
39 InsetGraphicsParams::InsetGraphicsParams()
40 {
41         init();
42 }
43
44
45 InsetGraphicsParams::InsetGraphicsParams(InsetGraphicsParams const & igp)
46 {
47         // I decided to skip the initialization since the copy will overwrite
48         // everything anyway.
49         //    init();
50         copy(igp);
51 }
52
53
54 InsetGraphicsParams &
55 InsetGraphicsParams::operator=(InsetGraphicsParams const & params)
56 {
57         // Are we assigning the object into itself?
58         if (this == &params)
59                 return *this;
60         copy(params);
61         return *this;
62 }
63
64
65 void InsetGraphicsParams::init()
66 {
67         filename.erase();
68         lyxscale = 100;                 // lyx scaling in percentage
69         display = lyx::graphics::DefaultDisplay; // display mode; see preferences
70         scale = string();                       // output scaling in percentage
71         width = LyXLength();
72         height = LyXLength();
73         keepAspectRatio = false;        // for LaTeX output
74         draft = false;                  // draft mode
75         noUnzip = false;                // unzip files
76
77         bb = string();                  // bounding box
78         clip = false;                   // clip image
79
80         rotateAngle = "0";              // angle of rotation in degrees
81         rotateOrigin.erase();           // Origin of rotation
82         subcaption = false;             // subfigure
83         subcaptionText.erase();         // subfigure caption
84         special.erase();                // additional userdefined stuff
85 }
86
87
88 void InsetGraphicsParams::copy(InsetGraphicsParams const & igp)
89 {
90         filename = igp.filename;
91         lyxscale = igp.lyxscale;
92         display = igp.display;
93         scale = igp.scale;
94         width = igp.width;
95         height = igp.height;
96         keepAspectRatio = igp.keepAspectRatio;
97         draft = igp.draft;
98         noUnzip = igp.noUnzip;
99
100         bb = igp.bb;
101         clip = igp.clip;
102
103         rotateAngle = igp.rotateAngle;
104         rotateOrigin = igp.rotateOrigin;
105         subcaption = igp.subcaption;
106         subcaptionText = igp.subcaptionText;
107         special = igp.special;
108 }
109
110
111 bool operator==(InsetGraphicsParams const & left,
112                 InsetGraphicsParams const & right)
113 {
114         if (left.filename == right.filename &&
115             left.lyxscale == right.lyxscale &&
116             left.display == right.display &&
117             left.scale == right.scale &&
118             left.width == right.width &&
119             left.height == right.height &&
120             left.keepAspectRatio == right.keepAspectRatio &&
121             left.draft == right.draft &&
122             left.noUnzip == right.noUnzip &&
123
124
125             left.bb == right.bb &&
126             left.clip == right.clip &&
127
128             left.rotateAngle == right.rotateAngle &&
129             left.rotateOrigin == right.rotateOrigin &&
130             left.subcaption == right.subcaption &&
131             left.subcaptionText == right.subcaptionText &&
132             left.special == right.special
133            )
134                 return true;
135
136         return false;
137 }
138
139
140 bool operator!=(InsetGraphicsParams const & left,
141                 InsetGraphicsParams const & right)
142 {
143         return  !(left == right);
144 }
145
146
147 void InsetGraphicsParams::Write(ostream & os, string const & bufpath) const
148 {
149         // Do not write the default values
150
151         if (!filename.empty()) {
152                 os << "\tfilename " << filename.outputFilename(bufpath) << '\n';
153         }
154         if (lyxscale != 100)
155                 os << "\tlyxscale " << lyxscale << '\n';
156         if (display != lyx::graphics::DefaultDisplay)
157                 os << "\tdisplay " << lyx::graphics::displayTranslator().find(display) << '\n';
158         if (!scale.empty() && !float_equal(strToDbl(scale), 0.0, 0.05)) {
159                 if (!float_equal(strToDbl(scale), 100.0, 0.05))
160                         os << "\tscale " << scale << '\n';
161         } else {
162                 if (!width.zero())
163                         os << "\twidth " << width.asString() << '\n';
164                 if (!height.zero())
165                         os << "\theight " << height.asString() << '\n';
166         }
167
168         if (keepAspectRatio)
169                 os << "\tkeepAspectRatio\n";
170         if (draft)                      // draft mode
171                 os << "\tdraft\n";
172         if (noUnzip)
173                 os << "\tnoUnzip\n";
174
175         if (!bb.empty())                // bounding box
176                 os << "\tBoundingBox " << bb << '\n';
177         if (clip)                       // clip image
178                 os << "\tclip\n";
179
180         if (!rotateAngle.empty()
181                 && !float_equal(strToDbl(rotateAngle), 0.0, 0.001))
182                 os << "\trotateAngle " << rotateAngle << '\n';
183         if (!rotateOrigin.empty())
184                 os << "\trotateOrigin " << rotateOrigin << '\n';
185         if (subcaption)
186                 os << "\tsubcaption\n";
187         if (!subcaptionText.empty())
188                 os << "\tsubcaptionText \"" << subcaptionText << '\"' << '\n';
189         if (!special.empty())
190                 os << "\tspecial " << special << '\n';
191 }
192
193
194 bool InsetGraphicsParams::Read(LyXLex & lex, string const & token, string const & bufpath)
195 {
196         if (token == "filename") {
197                 lex.eatLine();
198                 filename.set(lex.getString(), bufpath);
199         } else if (token == "lyxscale") {
200                 lex.next();
201                 lyxscale = lex.getInteger();
202         } else if (token == "display") {
203                 lex.next();
204                 string const type = lex.getString();
205                 display = lyx::graphics::displayTranslator().find(type);
206         } else if (token == "scale") {
207                 lex.next();
208                 scale = lex.getString();
209         } else if (token == "width") {
210                 lex.next();
211                 width = LyXLength(lex.getString());
212                 scale = string();
213         } else if (token == "height") {
214                 lex.next();
215                 height = LyXLength(lex.getString());
216                 scale = string();
217         } else if (token == "keepAspectRatio") {
218                 keepAspectRatio = true;
219         } else if (token == "draft") {
220                 draft = true;
221         } else if (token == "noUnzip") {
222                 noUnzip = true;
223         } else if (token == "BoundingBox") {
224                 bb.erase();
225                 for (int i = 0; i < 4; ++i) {
226                         if (i != 0)
227                                 bb += ' ';
228                         lex.next();
229                         bb += lex.getString();
230                 }
231         } else if (token == "clip") {
232                 clip = true;
233         } else if (token == "rotateAngle") {
234                 lex.next();
235                 rotateAngle = lex.getString();
236         } else if (token == "rotateOrigin") {
237                 lex.next();
238                 rotateOrigin=lex.getString();
239         } else if (token == "subcaption") {
240                 subcaption = true;
241         } else if (token == "subcaptionText") {
242                 lex.eatLine();
243                 string sub = lex.getString();
244                 // strip surrounding " "
245                 subcaptionText = sub.substr(1, sub.length() - 2);
246         } else if (token == "special") {
247                 lex.eatLine();
248                 special = lex.getString();
249
250         // catch and ignore following two old-format tokens and their arguments.
251         // e.g. "size_kind scale" clashes with the setting of the
252         // "scale <value>" keyword.
253         } else if (token == "size_kind" || token == "lyxsize_kind") {
254                 lex.next();
255                 lex.getString();
256
257         } else {
258                 // If it's none of the above, it's not ours.
259                 return false;
260         }
261         return true;
262 }
263
264
265 lyx::graphics::Params InsetGraphicsParams::as_grfxParams() const
266 {
267         lyx::graphics::Params pars;
268         pars.filename = filename.absFilename();
269         pars.scale = lyxscale;
270         pars.angle = lyx::support::strToDbl(rotateAngle);
271
272         if (clip) {
273                 pars.bb = bb;
274
275                 // Get the original Bounding Box from the file
276                 string const tmp = readBB_from_PSFile(filename.absFilename());
277                 lyxerr[Debug::GRAPHICS] << "BB_from_File: " << tmp << std::endl;
278                 if (!tmp.empty()) {
279                         unsigned int const bb_orig_xl = strToInt(token(tmp, ' ', 0));
280                         unsigned int const bb_orig_yb = strToInt(token(tmp, ' ', 1));
281
282                         // new pars.bb values must be >= zero
283                         if  (pars.bb.xl > bb_orig_xl)
284                                 pars.bb.xl -= bb_orig_xl;
285                         else
286                                 pars.bb.xl = 0;
287
288                         if (pars.bb.xr > bb_orig_xl)
289                                 pars.bb.xr -= bb_orig_xl;
290                         else
291                                 pars.bb.xr = 0;
292
293                         if (pars.bb.yb > bb_orig_yb)
294                                 pars.bb.yb -= bb_orig_yb;
295                         else
296                                 pars.bb.yb = 0;
297
298                         if (pars.bb.yt > bb_orig_yb)
299                                 pars.bb.yt -= bb_orig_yb;
300                         else
301                                 pars.bb.yt = 0;
302                 }
303
304                 // Paranoia check.
305                 int const width  = pars.bb.xr - pars.bb.xl;
306                 int const height = pars.bb.yt - pars.bb.yb;
307
308                 if (width  < 0 || height < 0) {
309                         pars.bb.xl = 0;
310                         pars.bb.xr = 0;
311                         pars.bb.yb = 0;
312                         pars.bb.yt = 0;
313                 }
314         }
315
316         if (display == lyx::graphics::DefaultDisplay) {
317                 pars.display = lyxrc.display_graphics;
318         } else {
319                 pars.display = display;
320         }
321
322         // Override the above if we're not using a gui
323         if (!lyx_gui::use_gui) {
324                 pars.display = lyx::graphics::NoDisplay;
325         }
326
327         return pars;
328 }