]> git.lyx.org Git - lyx.git/blob - src/insets/insetgraphicsParams.C
3f699fd39309d56095416a514a56c4707ad3b72a
[lyx.git] / src / insets / insetgraphicsParams.C
1 /* This file is part of
2  * =================================================
3  *
4  *          LyX, The Document Processor
5  *          Copyright 1995 Matthias Ettrich.
6  *          Copyright 1995-2001 The LyX Team.
7  *
8  * \author Baruch Even
9  * \author Herbert Voss <voss@lyx.org>
10  *
11  * ================================================= */
12
13 #include <config.h>
14
15 #ifdef __GNUG__
16 #pragma implementation
17 #endif
18
19 #include "insetgraphicsParams.h"
20
21 #include "graphics/GraphicsParams.h"
22 #include "graphics/GraphicsCache.h"
23
24 #include "support/translator.h"
25 #include "support/filetools.h"
26 #include "support/lyxlib.h"
27 #include "support/LOstream.h"
28 #include "support/LAssert.h"
29 #include "support/lstrings.h"
30 #include "lyxrc.h"
31 #include "debug.h"
32 #include "lyxlex.h"
33
34 using std::ostream;
35
36
37 namespace {
38
39 /// This variable keeps a tab on whether the translator was set with the
40 /// translations.
41 bool translatorsSet = false;
42
43 /// This is the translator between the Display enum and corresponding lyx
44 /// file strings.
45 Translator< InsetGraphicsParams::DisplayType, string >
46 displayTranslator(InsetGraphicsParams::DEFAULT, "default");
47
48 } // namespace anon
49
50
51 InsetGraphicsParams::InsetGraphicsParams()
52 {
53         init();
54         // Set translators
55         if (! translatorsSet) {
56                 translatorsSet = true;
57                 // Fill the display translator
58                 displayTranslator.addPair(DEFAULT, "default");
59                 displayTranslator.addPair(MONOCHROME, "monochrome");
60                 displayTranslator.addPair(GRAYSCALE, "grayscale");
61                 displayTranslator.addPair(COLOR, "color");
62                 displayTranslator.addPair(NONE, "none");
63         }
64 }
65
66
67 InsetGraphicsParams::InsetGraphicsParams(InsetGraphicsParams const & igp)
68 {
69         // I decided to skip the initialization since the copy will overwrite
70         // everything anyway.
71         //    init();
72         copy(igp);
73 }
74
75 InsetGraphicsParams &
76 InsetGraphicsParams::operator=(InsetGraphicsParams const & params)
77 {
78         // Are we assigning the object into itself?
79         if (this == &params)
80                 return * this;
81         copy(params);
82         return *this;
83 }
84
85 void InsetGraphicsParams::init()
86 {
87         subcaptionText = filename = string();
88         bb = string();                  // bounding box
89         draft = false;                  // draft mode
90         clip = false;                   // clip image
91         display = DEFAULT;              // see pref
92         subcaption = false;             // subfigure
93         noUnzip = false;                // unzip files
94         width = LyXLength();            // set to 0pt
95         height = LyXLength();
96         lyxwidth = LyXLength();         // for the view in lyx
97         lyxheight = LyXLength();        // also set to 0pt
98         scale = 0;                      // unit is %
99         lyxscale = 0;                   // same for lyxview
100         size_type = DEFAULT_SIZE;       // do nothing
101         lyxsize_type = DEFAULT_SIZE;    // do nothing
102         keepLyXAspectRatio = false;     // only for LyXview
103         keepAspectRatio = false;        // only for latex
104         rotate = false;                 // Rotating
105         rotateOrigin = "center";        // Origin
106         rotateAngle = 0.0;              // in degrees
107         special = string();             // userdefined stuff
108 }
109
110 void InsetGraphicsParams::copy(InsetGraphicsParams const & igp)
111 {
112         filename = igp.filename;
113         bb = igp.bb;
114         draft = igp.draft;
115         clip = igp.clip;
116         display = igp.display;
117         subcaption = igp.subcaption;
118         subcaptionText = igp.subcaptionText;
119         noUnzip = igp.noUnzip;
120         keepAspectRatio = igp.keepAspectRatio;
121         width = igp.width;
122         height = igp.height;
123         scale = igp.scale;
124         size_type = igp.size_type;
125         lyxsize_type = igp.lyxsize_type;
126         lyxwidth = igp.lyxwidth;
127         lyxheight = igp.lyxheight;
128         keepLyXAspectRatio = igp.keepLyXAspectRatio;
129         lyxscale = igp.lyxscale;
130         rotate = igp.rotate;
131         rotateOrigin = igp.rotateOrigin;
132         rotateAngle = igp.rotateAngle;
133         special = igp.special;
134 }
135
136 bool operator==(InsetGraphicsParams const & left,
137                 InsetGraphicsParams const & right)
138 {
139         if (left.filename == right.filename &&
140             left.bb == right.bb &&
141             left.draft == right.draft &&
142             left.clip == right.clip &&
143             left.display == right.display &&
144             left.subcaption == right.subcaption &&
145             left.noUnzip == right.noUnzip &&
146             left.subcaptionText == right.subcaptionText &&
147             left.keepAspectRatio == right.keepAspectRatio &&
148             left.width == right.width &&
149             left.height == right.height &&
150             left.scale == right.scale &&
151             left.size_type == right.size_type &&
152             left.lyxsize_type == right.lyxsize_type &&
153             left.lyxwidth == right.lyxwidth &&
154             left.lyxheight == right.lyxheight &&
155             left.keepLyXAspectRatio == right.keepLyXAspectRatio &&
156             left.lyxscale == right.lyxscale &&
157             left.rotate == right.rotate &&
158             left.rotateOrigin == right.rotateOrigin &&
159             lyx::float_equal(left.rotateAngle, right.rotateAngle, 0.001 &&
160                              left.special == right.special)
161                 )
162                 return true;
163
164         return false;
165 }
166
167 bool operator!=(InsetGraphicsParams const & left,
168                 InsetGraphicsParams const & right)
169 {
170         return  !(left == right);
171 }
172
173
174 void InsetGraphicsParams::Write(ostream & os) const
175 {
176         // If there is no filename, write nothing for it.
177         if (!filename.empty()) {
178                 os << "\tfilename " << filename << '\n';
179         }
180         if (!bb.empty())                // bounding box
181                 os << "\tBoundingBox " << bb << '\n';
182         if (clip)                       // clip image
183                 os << "\tclip\n";
184         if (draft)                      // draft mode
185                 os << "\tdraft\n";
186         // Save the display type for the view inside lyx
187         os << "\tdisplay " << displayTranslator.find(display) << '\n';
188         // Save the subcaption status
189         if (subcaption)
190                 os << "\tsubcaption\n";
191         if (!subcaptionText.empty())
192                 os << "\tsubcaptionText \"" << subcaptionText << '\"' << '\n';
193         if (noUnzip)
194                 os << "\tnoUnzip\n";
195         // we always need the size type
196         // 0: no special
197         // 1: width/height combination
198         // 2: scale
199         os << "\tsize_type " <<  size_type << '\n';
200         if (!width.zero())
201                 os << "\twidth " << width.asString() << '\n';
202         if (!height.zero())
203                 os << "\theight " << height.asString() << '\n';
204         if (scale != 0)
205                 os << "\tscale " << scale << '\n';
206         if (keepAspectRatio)
207                 os << "\tkeepAspectRatio\n";
208         if (rotate)
209                 os << "\trotate\n";
210         if (rotateAngle != 0.0)
211                 os << "\trotateAngle " << rotateAngle << '\n';
212         if (!rotateOrigin.empty())
213                 os << "\trotateOrigin " << rotateOrigin << '\n';
214         if (!special.empty())
215                 os << "\tspecial " << special << '\n';
216         // the values for the view in lyx
217         os << "\tlyxsize_type " <<  lyxsize_type << '\n';
218         if (!lyxwidth.zero())           // the lyx-viewsize
219                 os << "\tlyxwidth " << lyxwidth.asString() << '\n';
220         if (!lyxheight.zero())
221                 os << "\tlyxheight " << lyxheight.asString();
222         if (keepLyXAspectRatio)
223                 os << "\tkeepLyXAspectRatio\n";
224         if (lyxscale != 0)
225                 os << "\tlyxscale " << lyxscale << '\n';
226 }
227
228
229 bool InsetGraphicsParams::Read(LyXLex & lex, string const & token)
230 {
231         if (token == "filename") {
232                 lex.eatLine();
233                 filename = lex.getString();
234         } else if (token == "BoundingBox") {
235                 for (int i=0; i<4 ;i++) {
236                         lex.next();
237                         bb += (lex.getString()+" ");
238                 }
239         } else if (token == "clip") {
240                 clip = true;
241         } else if (token == "draft") {
242                 draft = true;
243         } else if (token == "display") {
244                 lex.next();
245                 string const type = lex.getString();
246                 display = displayTranslator.find(type);
247         } else if (token == "subcaption") {
248                 subcaption = true;
249         } else if (token == "subcaptionText") {
250                 lex.next();
251                 subcaptionText = lex.getString();
252         } else if (token == "noUnzip") {
253                 noUnzip = true;
254         } else if (token == "size_type") {
255                 lex.next();
256                 switch (lex.getInteger()) {
257                 case 0:
258                         size_type = DEFAULT_SIZE;
259                         break;
260                 case 1:
261                         size_type = WH;
262                         break;
263                 case 2:
264                         size_type = SCALE;
265                         break;
266                 }
267         } else if (token == "width") {
268                 lex.next();
269                 width = LyXLength(lex.getString());
270         } else if (token == "height") {
271                 lex.next();
272                 height = LyXLength(lex.getString());
273         } else if (token == "keepAspectRatio") {
274                 keepAspectRatio = true;
275         } else if (token == "scale") {
276                 lex.next();
277                 scale = lex.getInteger();
278         } else if (token == "rotate") {
279                 rotate = true;
280         } else if (token == "rotateAngle") {
281                 lex.next();
282                 rotateAngle = lex.getFloat();
283         } else if (token == "rotateOrigin") {
284                 lex.next();
285                 rotateOrigin=lex.getString();
286         } else if (token == "lyxsize_type") {
287                 lex.next();
288                 switch (lex.getInteger()) {
289                 case 0:
290                         lyxsize_type = DEFAULT_SIZE;
291                         break;
292                 case 1:
293                         lyxsize_type = WH;
294                         break;
295                 case 2:
296                         lyxsize_type = SCALE;
297                         break;
298                 }
299         } else if (token == "lyxwidth") {
300                 lex.next();
301                 lyxwidth = LyXLength(lex.getString());
302         } else if (token == "lyxheight") {
303                 lex.next();
304                 lyxheight = LyXLength(lex.getString());
305         } else if (token == "keepLyXAspectRatio") {
306                 keepLyXAspectRatio = true;
307         } else if (token == "lyxscale") {
308                 lex.next();
309                 lyxscale = lex.getInteger();
310         } else if (token == "special") {
311                 lex.eatLine();
312                 special = lex.getString();
313         } else {        // If it's none of the above, its not ours.
314                 return false;
315         }
316         return true;
317 }
318
319
320 grfx::Params InsetGraphicsParams::as_grfxParams(string const & filepath) const
321 {
322         grfx::Params pars;
323         pars.width    = 0;
324         pars.height   = 0;
325         pars.scale    = 0;
326         pars.keepLyXAspectRatio = false;
327         pars.angle    = 0;
328         pars.filename = filename;
329
330         if (!filepath.empty()) {
331                 pars.filename = MakeAbsPath(pars.filename, filepath);
332         }
333
334         if (clip) {
335                 pars.bb = bb;
336
337                 // Get the original Bounding Box from the file
338                 string const tmp = readBB_from_PSFile(filename);
339                 lyxerr[Debug::GRAPHICS] << "BB_from_File: " << tmp << std::endl;
340                 if (!tmp.empty()) {
341                         int const bb_orig_xl = strToInt(token(tmp, ' ', 0));
342                         int const bb_orig_yb = strToInt(token(tmp, ' ', 1));
343
344                         pars.bb.xl -= bb_orig_xl;
345                         pars.bb.xr -= bb_orig_xl;
346                         pars.bb.yb -= bb_orig_yb;
347                         pars.bb.yt -= bb_orig_yb;
348                 }
349
350                 pars.bb.xl = std::max(0, pars.bb.xl);
351                 pars.bb.xr = std::max(0, pars.bb.xr);
352                 pars.bb.yb = std::max(0, pars.bb.yb);
353                 pars.bb.yt = std::max(0, pars.bb.yt);
354
355                 // Paranoia check.
356                 int const width  = pars.bb.xr - pars.bb.xl;
357                 int const height = pars.bb.yt - pars.bb.yb;
358
359                 if (width  < 0 || height < 0) {
360                         pars.bb.xl = 0;
361                         pars.bb.xr = 0;
362                         pars.bb.yb = 0;
363                         pars.bb.yt = 0;
364                 }
365         }
366         
367         if (rotate)
368                 pars.angle = int(rotateAngle);
369
370         switch (display) {
371                 case InsetGraphicsParams::NONE:
372                         pars.display = grfx::NoDisplay;
373                 break;
374
375                 case InsetGraphicsParams::MONOCHROME:
376                         pars.display = grfx::MonochromeDisplay;
377                 break;
378
379                 case InsetGraphicsParams::GRAYSCALE: 
380                         pars.display = grfx::GrayscaleDisplay;
381
382                 case InsetGraphicsParams::COLOR:
383                         pars.display = grfx::ColorDisplay;
384                 break;
385
386                 default: {
387                         if (lyxrc.display_graphics == "mono")
388                                 pars.display = grfx::MonochromeDisplay;
389                         else if (lyxrc.display_graphics == "gray")
390                                 pars.display = grfx::GrayscaleDisplay;
391                         else if (lyxrc.display_graphics == "color")
392                                 pars.display = grfx::ColorDisplay;
393                         else
394                                 pars.display = grfx::NoDisplay;
395                 }
396         }
397         
398         // Override the above if we're not using a gui
399         if (!lyxrc.use_gui) {
400                 pars.display = grfx::NoDisplay;
401         }
402         
403         if (lyxsize_type == InsetGraphicsParams::SCALE) {
404                 pars.scale = lyxscale;
405                 
406         } else if (lyxsize_type == InsetGraphicsParams::WH) {
407                 pars.width = lyxwidth.inBP();
408                 pars.height = lyxheight.inBP();
409                 pars.keepLyXAspectRatio = keepLyXAspectRatio;
410         }
411         
412         return pars;
413 }