Line data Source code
1 : //# PlotOptions.cc: Customization classes for plotter objects.
2 : //# Copyright (C) 2008
3 : //# Associated Universities, Inc. Washington DC, USA.
4 : //#
5 : //# This library is free software; you can redistribute it and/or modify it
6 : //# under the terms of the GNU Library General Public License as published by
7 : //# the Free Software Foundation; either version 2 of the License, or (at your
8 : //# option) any later version.
9 : //#
10 : //# This library is distributed in the hope that it will be useful, but WITHOUT
11 : //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 : //# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 : //# License for more details.
14 : //#
15 : //# You should have received a copy of the GNU Library General Public License
16 : //# along with this library; if not, write to the Free Software Foundation,
17 : //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18 : //#
19 : //# Correspondence concerning AIPS++ should be addressed as follows:
20 : //# Internet email: aips2-request@nrao.edu.
21 : //# Postal address: AIPS++ Project Office
22 : //# National Radio Astronomy Observatory
23 : //# 520 Edgemont Road
24 : //# Charlottesville, VA 22903-2475 USA
25 : //#
26 : //# $Id: $
27 : #include <graphics/GenericPlotter/PlotOptions.h>
28 :
29 : using namespace std;
30 :
31 : using namespace casacore;
32 : namespace casa {
33 :
34 :
35 :
36 :
37 :
38 : ///////////////////////////
39 : // PLOTCOLOR DEFINITIONS //
40 : ///////////////////////////
41 :
42 : const String PlotColor::REC_HEXADECIMAL = "hexadecimal";
43 : const String PlotColor::REC_ALPHA = "alpha";
44 :
45 0 : PlotColor::PlotColor() { }
46 0 : PlotColor::~PlotColor() { }
47 :
48 0 : void PlotColor::setAsHexadecimal(const String& hex) {
49 0 : setAsHexadecimalOrName(hex); }
50 0 : void PlotColor::setAsName(const String& name) { setAsHexadecimalOrName(name); }
51 :
52 0 : Record PlotColor::toRecord() const {
53 0 : Record rec;
54 0 : rec.define(REC_HEXADECIMAL, asHexadecimal());
55 0 : rec.define(REC_ALPHA, alpha());
56 0 : return rec;
57 : }
58 :
59 0 : void PlotColor::fromRecord(const Record& record) {
60 0 : if(record.isDefined(REC_HEXADECIMAL) &&
61 0 : record.dataType(REC_HEXADECIMAL) == TpString)
62 0 : setAsHexadecimal(record.asString(REC_HEXADECIMAL));
63 :
64 0 : if(record.isDefined(REC_ALPHA) && record.dataType(REC_ALPHA) == TpDouble)
65 0 : setAlpha(record.asDouble(REC_ALPHA));
66 0 : }
67 :
68 0 : PlotColor& PlotColor::operator=(const PlotColor& rh) {
69 0 : setAsHexadecimal(rh.asHexadecimal());
70 0 : setAlpha(rh.alpha());
71 0 : return *this;
72 : }
73 :
74 0 : bool PlotColor::operator==(const PlotColor& rh) const {
75 0 : return asHexadecimal() == rh.asHexadecimal() && alpha() == rh.alpha(); }
76 0 : bool PlotColor::operator!=(const PlotColor& rh) const{ return !(*this == rh); }
77 :
78 :
79 : //////////////////////////
80 : // PLOTFONT DEFINITIONS //
81 : //////////////////////////
82 :
83 : const String PlotFont::REC_POINTSIZE = "pointSize";
84 : const String PlotFont::REC_PIXELSIZE = "pixelSize";
85 : const String PlotFont::REC_FAMILY = "family";
86 : const String PlotFont::REC_COLOR = "color";
87 : const String PlotFont::REC_ITALICS = "italics";
88 : const String PlotFont::REC_BOLD = "bold";
89 : const String PlotFont::REC_UNDERLINE = "underline";
90 :
91 0 : PlotFont::PlotFont() { }
92 0 : PlotFont::~PlotFont() { }
93 :
94 0 : void PlotFont::setColor(const PlotColorPtr c) { if(!c.null()) setColor(*c); }
95 0 : void PlotFont::setColor(const String& col) {
96 0 : PlotColorPtr c = color();
97 0 : c->setAsHexadecimalOrName(col);
98 0 : setColor(*c);
99 0 : }
100 :
101 0 : Record PlotFont::toRecord() const {
102 0 : Record rec;
103 0 : rec.define(REC_POINTSIZE, pointSize());
104 0 : rec.define(REC_PIXELSIZE, pixelSize());
105 0 : rec.define(REC_FAMILY, fontFamily());
106 0 : PlotColorPtr c = color();
107 0 : if(!c.null()) rec.defineRecord(REC_COLOR, color()->toRecord());
108 0 : rec.define(REC_ITALICS, italics());
109 0 : rec.define(REC_BOLD, bold());
110 0 : rec.define(REC_UNDERLINE, underline());
111 0 : return rec;
112 : }
113 :
114 0 : void PlotFont::fromRecord(const Record& record) {
115 0 : if(record.isDefined(REC_POINTSIZE) &&
116 0 : record.dataType(REC_POINTSIZE) == TpDouble)
117 0 : setPointSize(record.asDouble(REC_POINTSIZE));
118 :
119 0 : if(record.isDefined(REC_PIXELSIZE) &&
120 0 : record.dataType(REC_PIXELSIZE) == TpInt)
121 0 : setPixelSize(record.asInt(REC_PIXELSIZE));
122 :
123 0 : if(record.isDefined(REC_FAMILY) && record.dataType(REC_FAMILY) == TpString)
124 0 : setFontFamily(record.asString(REC_FAMILY));
125 :
126 0 : if(record.isDefined(REC_COLOR) && record.dataType(REC_COLOR) == TpRecord) {
127 0 : PlotColorPtr c = color();
128 0 : if(!c.null()) {
129 0 : c->fromRecord(record.asRecord(REC_COLOR));
130 0 : setColor(c);
131 : }
132 : }
133 :
134 0 : if(record.isDefined(REC_ITALICS) && record.dataType(REC_ITALICS) == TpBool)
135 0 : setItalics(record.asBool(REC_ITALICS));
136 :
137 0 : if(record.isDefined(REC_BOLD) && record.dataType(REC_BOLD) == TpBool)
138 0 : setItalics(record.asBool(REC_BOLD));
139 :
140 0 : if(record.isDefined(REC_UNDERLINE)&&record.dataType(REC_UNDERLINE)==TpBool)
141 0 : setUnderline(record.asBool(REC_UNDERLINE));
142 0 : }
143 :
144 0 : PlotFont& PlotFont::operator=(const PlotFont& rh) {
145 0 : setPointSize(rh.pointSize());
146 0 : setPixelSize(rh.pixelSize());
147 0 : setFontFamily(rh.fontFamily());
148 0 : setColor(rh.color());
149 0 : setItalics(rh.italics());
150 0 : setBold(rh.bold());
151 0 : setUnderline(rh.underline());
152 0 : return *this;
153 : }
154 :
155 0 : bool PlotFont::operator==(const PlotFont& rh) const {
156 0 : return pointSize() == rh.pointSize() &&
157 0 : pixelSize() == rh.pixelSize() &&
158 0 : fontFamily() == rh.fontFamily() &&
159 0 : *color() == *rh.color() && italics() == rh.italics() &&
160 0 : bold() == rh.bold() && underline() == rh.underline();
161 : }
162 0 : bool PlotFont::operator!=(const PlotFont& rh) const { return !(*this == rh); }
163 :
164 :
165 : //////////////////////////////
166 : // PLOTAREAFILL DEFINITIONS //
167 : //////////////////////////////
168 :
169 : const String PlotAreaFill::REC_COLOR = "color";
170 : const String PlotAreaFill::REC_PATTERN = "pattern";
171 :
172 0 : PlotAreaFill::PlotAreaFill() { }
173 0 : PlotAreaFill::~PlotAreaFill() { }
174 :
175 0 : void PlotAreaFill::setColor(const PlotColorPtr c){ if(!c.null()) setColor(*c);}
176 0 : void PlotAreaFill::setColor(const String& co) {
177 0 : PlotColorPtr c = color();
178 0 : c->setAsHexadecimalOrName(co);
179 0 : setColor(*c);
180 0 : }
181 :
182 0 : void PlotAreaFill::setPattern( const String& descriptor ){
183 0 : if(descriptor == "fill") {
184 0 : setPattern(PlotAreaFill::FILL);
185 : }
186 0 : else if(descriptor == "mesh1") {
187 0 : setPattern(PlotAreaFill::MESH1);
188 : }
189 0 : else if(descriptor == "mesh2") {
190 0 : setPattern(PlotAreaFill::MESH2);
191 : }
192 0 : else if(descriptor == "mesh3") {
193 0 : setPattern(PlotAreaFill::MESH3);
194 : }
195 : else {
196 0 : setPattern(PlotAreaFill::NOFILL);
197 : }
198 0 : }
199 :
200 0 : Record PlotAreaFill::toRecord() const {
201 0 : Record rec;
202 0 : PlotColorPtr c = color();
203 0 : if(!c.null()) rec.defineRecord(REC_COLOR, c->toRecord());
204 0 : rec.define(REC_PATTERN, (int)pattern());
205 0 : return rec;
206 : }
207 :
208 0 : void PlotAreaFill::fromRecord(const Record& record) {
209 0 : if(record.isDefined(REC_COLOR) && record.dataType(REC_COLOR) == TpRecord) {
210 0 : PlotColorPtr c = color();
211 0 : if(!c.null()) {
212 0 : c->fromRecord(record.asRecord(REC_COLOR));
213 0 : setColor(c);
214 : }
215 : }
216 :
217 0 : if(record.isDefined(REC_PATTERN) && record.dataType(REC_PATTERN) == TpInt)
218 0 : setPattern((Pattern)record.asInt(REC_PATTERN));
219 0 : }
220 :
221 0 : PlotAreaFill& PlotAreaFill::operator=(const PlotAreaFill& rh) {
222 0 : setColor(rh.color());
223 0 : setPattern(rh.pattern());
224 0 : return *this;
225 : }
226 :
227 0 : bool PlotAreaFill::operator==(const PlotAreaFill& rh) const {
228 0 : if(pattern() == rh.pattern() && pattern() == NOFILL){
229 0 : return true;
230 : }
231 0 : return *color() == *rh.color() && pattern() == rh.pattern();
232 : }
233 0 : bool PlotAreaFill::operator!=(const PlotAreaFill& rh) const {
234 0 : return !(*this == rh); }
235 :
236 :
237 : //////////////////////////
238 : // PLOTLINE DEFINITIONS //
239 : //////////////////////////
240 :
241 : const String PlotLine::REC_WIDTH = "width";
242 : const String PlotLine::REC_STYLE = "style";
243 : const String PlotLine::REC_COLOR = "color";
244 :
245 0 : PlotLine::PlotLine() { }
246 0 : PlotLine::~PlotLine() { }
247 :
248 0 : void PlotLine::setColor(const PlotColorPtr c) { if(!c.null()) setColor(*c); }
249 0 : void PlotLine::setColor(const String& col) {
250 0 : PlotColorPtr c = color();
251 0 : c->setAsHexadecimalOrName(col);
252 0 : setColor(*c);
253 0 : }
254 :
255 0 : Record PlotLine::toRecord() const {
256 0 : Record rec;
257 0 : rec.define(REC_WIDTH, width());
258 0 : rec.define(REC_STYLE, (int)style());
259 0 : PlotColorPtr c = color();
260 0 : if(!c.null()) rec.defineRecord(REC_COLOR, c->toRecord());
261 0 : return rec;
262 : }
263 :
264 0 : void PlotLine::fromRecord(const Record& record) {
265 0 : if(record.isDefined(REC_WIDTH) && record.dataType(REC_WIDTH) == TpDouble)
266 0 : setWidth(record.asDouble(REC_WIDTH));
267 :
268 0 : if(record.isDefined(REC_STYLE) && record.dataType(REC_STYLE) == TpInt)
269 0 : setStyle((Style)record.asInt(REC_STYLE));
270 :
271 0 : if(record.isDefined(REC_COLOR) && record.dataType(REC_COLOR) == TpRecord) {
272 0 : PlotColorPtr c = color();
273 0 : if(!c.null()) {
274 0 : c->fromRecord(record.asRecord(REC_COLOR));
275 0 : setColor(c);
276 : }
277 : }
278 0 : }
279 :
280 0 : PlotLine& PlotLine::operator=(const PlotLine& rh) {
281 0 : setWidth(rh.width());
282 0 : setStyle(rh.style());
283 0 : setColor(rh.color());
284 0 : return *this;
285 : }
286 :
287 0 : bool PlotLine::operator==(const PlotLine& rh) const {
288 0 : if(style() == rh.style() && style() == NOLINE) return true;
289 0 : if(width() == rh.width() && width() == 0) return true;
290 0 : return width() == rh.width() && style() == rh.style() &&
291 0 : *color() == *rh.color();
292 : }
293 :
294 0 : bool PlotLine::operator!=(const PlotLine& rh) const { return !(*this == rh); }
295 :
296 :
297 : ////////////////////////////
298 : // PLOTSYMBOL DEFINITIONS //
299 : ////////////////////////////
300 :
301 : const String PlotSymbol::REC_WIDTH = "width";
302 : const String PlotSymbol::REC_HEIGHT = "height";
303 : const String PlotSymbol::REC_HEIGHTISPIXEL = "heightIsPixel";
304 : const String PlotSymbol::REC_SYMBOL = "symbol";
305 : const String PlotSymbol::REC_UCHAR = "symbolUChar";
306 : const String PlotSymbol::REC_LINE = "line";
307 : const String PlotSymbol::REC_AREAFILL = "areaFill";
308 : const String PlotSymbol::REC_COLOR = "symbolColor";
309 :
310 0 : PlotSymbol::PlotSymbol():DEFAULT_COLOR("black") {
311 0 : currentColor = DEFAULT_COLOR;
312 0 : }
313 0 : PlotSymbol::~PlotSymbol() { }
314 :
315 0 : void PlotSymbol::setSize(psize_t size) {
316 0 : setSize(size.first, size.second); }
317 :
318 0 : bool PlotSymbol::isCharacter() const { return symbol() == CHARACTER; }
319 :
320 0 : void PlotSymbol::setLine(const PlotLinePtr l) {
321 0 : if(!l.null()) setLine(*l);
322 0 : else setLine(DEFAULT_COLOR, PlotLine::NOLINE);
323 0 : }
324 :
325 0 : void PlotSymbol::setLine(const String& color, PlotLine::Style style,
326 : double width) {
327 0 : PlotLinePtr l = line();
328 0 : l->setColor(color);
329 0 : l->setStyle(style);
330 0 : l->setWidth(width);
331 0 : setLine(*l);
332 0 : }
333 :
334 0 : void PlotSymbol::setAreaFill(const PlotAreaFillPtr a) {
335 0 : if(!a.null()) setAreaFill(*a);
336 0 : else setAreaFill(DEFAULT_COLOR, PlotAreaFill::NOFILL);
337 0 : }
338 :
339 :
340 :
341 0 : void PlotSymbol::setAreaFill(const String& color,
342 : PlotAreaFill::Pattern pattern) {
343 0 : PlotAreaFillPtr a = areaFill();
344 0 : a->setColor(color);
345 0 : a->setPattern(pattern);
346 0 : setAreaFill(*a);
347 0 : }
348 :
349 0 : void PlotSymbol::setColor(const PlotColor& color) {
350 0 : PlotLinePtr l = line();
351 0 : l->setColor(color);
352 0 : setLine(*l);
353 :
354 0 : PlotAreaFillPtr a = areaFill();
355 0 : a->setColor(color);
356 0 : setAreaFill(*a);
357 0 : currentColor = color.asHexadecimal();
358 0 : }
359 :
360 0 : void PlotSymbol::setColor(const PlotColorPtr color) {
361 0 : if(!color.null()) setColor(*color);
362 0 : }
363 :
364 0 : String PlotSymbol::getColor() const {
365 0 : return currentColor;
366 : }
367 :
368 0 : void PlotSymbol::setColor(const String& color) {
369 0 : PlotLinePtr l = line();
370 0 : l->setColor(color);
371 0 : setLine(*l);
372 :
373 0 : PlotAreaFillPtr a = areaFill();
374 0 : a->setColor(color);
375 0 : setAreaFill(*a);
376 0 : currentColor = color;
377 :
378 0 : }
379 :
380 0 : Record PlotSymbol::toRecord() const {
381 0 : Record rec;
382 :
383 0 : psize_t s = size();
384 0 : rec.define(REC_WIDTH, s.first);
385 0 : rec.define(REC_HEIGHT, s.second);
386 :
387 0 : rec.define(REC_HEIGHTISPIXEL, heightIsPixel());
388 0 : rec.define(REC_SYMBOL, (int)symbol());
389 0 : rec.define(REC_UCHAR, (int)symbolUChar());
390 0 : rec.define(REC_COLOR, currentColor);
391 :
392 0 : PlotLinePtr l = line();
393 0 : if(!l.null()) rec.defineRecord(REC_LINE, l->toRecord());
394 :
395 0 : PlotAreaFillPtr a = areaFill();
396 0 : if(!a.null()) rec.defineRecord(REC_AREAFILL, a->toRecord());
397 :
398 0 : return rec;
399 : }
400 :
401 0 : void PlotSymbol::setSymbol( const String& descriptor ){
402 0 : if(descriptor == "pixel") {
403 0 : setSymbol(PlotSymbol::PIXEL);
404 : }
405 0 : else if(descriptor == "autoscaling") {
406 0 : setSymbol(PlotSymbol::AUTOSCALING);
407 : }
408 0 : else if(descriptor== "circle") {
409 0 : setSymbol(PlotSymbol::CIRCLE);
410 : }
411 0 : else if(descriptor == "square") {
412 0 : setSymbol(PlotSymbol::SQUARE);
413 : }
414 0 : else if(descriptor == "diamond") {
415 0 : setSymbol(PlotSymbol::DIAMOND);
416 : }
417 0 : else if(descriptor == "nosymbol"){
418 0 : setSymbol(PlotSymbol::NOSYMBOL );
419 : }
420 : else {
421 0 : cout << "Unrecognized PlotSymbol: "<<descriptor.c_str()<<endl;
422 : }
423 0 : }
424 :
425 0 : void PlotSymbol::fromRecord(const Record& record) {
426 0 : psize_t s = size();
427 0 : if(record.isDefined(REC_WIDTH) && record.dataType(REC_WIDTH) == TpDouble)
428 0 : s.first = record.asDouble(REC_WIDTH);
429 0 : if(record.isDefined(REC_HEIGHT) && record.dataType(REC_HEIGHT) == TpDouble)
430 0 : s.second = record.asDouble(REC_HEIGHT);
431 0 : setSize(s);
432 :
433 0 : if(record.isDefined(REC_HEIGHTISPIXEL) &&
434 0 : record.dataType(REC_HEIGHTISPIXEL) == TpBool)
435 0 : setHeightIsPixel(record.asBool(REC_HEIGHTISPIXEL));
436 :
437 0 : if(record.isDefined(REC_UCHAR) && record.dataType(REC_UCHAR) == TpInt)
438 0 : setUSymbol((unsigned short)record.asInt(REC_UCHAR));
439 :
440 0 : if(record.isDefined(REC_SYMBOL) && record.dataType(REC_SYMBOL) == TpInt)
441 0 : setSymbol((Symbol)record.asInt(REC_SYMBOL));
442 :
443 0 : if(record.isDefined(REC_LINE) && record.dataType(REC_LINE) == TpRecord) {
444 0 : PlotLinePtr l = line();
445 0 : if(!l.null()) {
446 0 : l->fromRecord(record.asRecord(REC_LINE));
447 0 : setLine(l);
448 : }
449 : }
450 :
451 0 : if(record.isDefined(REC_AREAFILL) &&
452 0 : record.dataType(REC_AREAFILL) == TpRecord) {
453 0 : PlotAreaFillPtr a = areaFill();
454 0 : if(!a.null()) {
455 0 : a->fromRecord(record.asRecord(REC_AREAFILL));
456 0 : setAreaFill(a);
457 : }
458 : }
459 0 : if (record.isDefined(REC_COLOR) && record.dataType(REC_COLOR) == TpString){
460 0 : this->setColor( record.asString( REC_COLOR));
461 : }
462 :
463 0 : }
464 :
465 0 : PlotSymbol& PlotSymbol::operator=(const PlotSymbol& rh) {
466 0 : setSize(rh.size());
467 0 : setHeightIsPixel(rh.heightIsPixel());
468 0 : setUSymbol(rh.symbolUChar());
469 0 : setSymbol(rh.symbol());
470 0 : setLine(rh.line());
471 0 : setAreaFill(rh.areaFill());
472 0 : setColor( rh.getColor());
473 0 : return *this;
474 : }
475 :
476 0 : bool PlotSymbol::operator==(const PlotSymbol& rh) const {
477 0 : if(symbol() == rh.symbol() && symbol() == NOSYMBOL) return true;
478 0 : if(size() == rh.size() && size() == psize_t(0, 0)) return true;
479 0 : bool symbolsEqual = size() == rh.size() && symbol() == rh.symbol() &&
480 0 : (isCharacter() ? symbolChar() == rh.symbolChar() : true) &&
481 0 : (isCharacter() ? heightIsPixel() == rh.heightIsPixel() : true) &&
482 0 : *line() == *rh.line() && *areaFill() == *rh.areaFill();// &&
483 : //getColor() == rh.getColor();
484 :
485 0 : return symbolsEqual;
486 : }
487 :
488 0 : bool PlotSymbol::operator!=(const PlotSymbol& rh) const {
489 0 : return !(*this == rh); }
490 :
491 :
492 : ////////////////////////////////
493 : // PLOTCOORDINATE DEFINITIONS //
494 : ////////////////////////////////
495 :
496 0 : PlotCoordinate::PlotCoordinate() : m_system(WORLD), m_x(0), m_y(0) { }
497 :
498 0 : PlotCoordinate::PlotCoordinate(double dx, double dy, System s): m_system(s),
499 0 : m_x(dx), m_y(dy) { }
500 :
501 0 : PlotCoordinate::PlotCoordinate(const PlotCoordinate& c) { operator=(c); }
502 :
503 0 : PlotCoordinate::~PlotCoordinate() { }
504 :
505 0 : PlotCoordinate::System PlotCoordinate::system() const { return m_system; }
506 0 : double PlotCoordinate::x() const { return m_x; }
507 0 : double PlotCoordinate::y() const { return m_y; }
508 :
509 0 : PlotCoordinate& PlotCoordinate::operator=(const PlotCoordinate& rh) {
510 0 : m_system = rh.system();
511 0 : m_x = rh.x();
512 0 : m_y = rh.y();
513 0 : return *this;
514 : }
515 :
516 0 : bool PlotCoordinate::operator==(const PlotCoordinate& rh) const {
517 0 : return m_system == rh.system() && m_x == rh.x() && m_y == rh.y(); }
518 :
519 0 : bool PlotCoordinate::operator!=(const PlotCoordinate& rh) const {
520 0 : return !(*this == rh); }
521 :
522 :
523 : ////////////////////////////
524 : // PLOTREGION DEFINITIONS //
525 : ////////////////////////////
526 :
527 0 : PlotRegion::PlotRegion() { }
528 :
529 0 : PlotRegion::PlotRegion(const PlotCoordinate& upperLeft,
530 0 : const PlotCoordinate& lowerRight) : m_upperLeft(upperLeft),
531 0 : m_lowerRight(lowerRight) { }
532 :
533 0 : PlotRegion::PlotRegion(const PlotRegion& copy) : m_upperLeft(copy.upperLeft()),
534 0 : m_lowerRight(copy.lowerRight()) { }
535 :
536 0 : PlotRegion::~PlotRegion() { }
537 :
538 0 : const PlotCoordinate& PlotRegion::upperLeft() const { return m_upperLeft; }
539 :
540 0 : const PlotCoordinate& PlotRegion::lowerRight() const { return m_lowerRight; }
541 :
542 0 : double PlotRegion::top() const { return m_upperLeft.y(); }
543 :
544 0 : double PlotRegion::bottom() const { return m_lowerRight.y(); }
545 :
546 0 : double PlotRegion::left() const { return m_upperLeft.x(); }
547 :
548 0 : double PlotRegion::right() const { return m_lowerRight.x(); }
549 :
550 0 : bool PlotRegion::isValid() const {
551 0 : return m_upperLeft.system() == m_lowerRight.system() &&
552 0 : m_upperLeft.x() < m_lowerRight.x() &&
553 0 : m_upperLeft.y() > m_lowerRight.y();
554 : }
555 :
556 :
557 : ///////////////////////////////
558 : // PLOTAXESSTACK DEFINITIONS //
559 : ///////////////////////////////
560 :
561 0 : PlotAxesStack::PlotAxesStack(int lengthLimit) : m_lengthLimit(lengthLimit),
562 0 : m_stackIndex(0) {
563 0 : if(m_lengthLimit <= 1) m_lengthLimit = -1;
564 0 : }
565 :
566 0 : PlotAxesStack::~PlotAxesStack() { }
567 :
568 :
569 0 : int PlotAxesStack::lengthLimit() const { return m_lengthLimit; }
570 0 : void PlotAxesStack::setLengthLimit(int lengthLimit) {
571 0 : if(lengthLimit <= 1) lengthLimit = -1;
572 0 : if(m_lengthLimit != lengthLimit) {
573 0 : m_lengthLimit = lengthLimit;
574 0 : if(lengthLimit > 0 && m_stack.size() > (unsigned int)lengthLimit)
575 0 : shrinkStacks((unsigned int)lengthLimit);
576 : }
577 0 : }
578 :
579 0 : bool PlotAxesStack::isValid() const { return m_stack.size() > 0; }
580 0 : unsigned int PlotAxesStack::stackIndex() const { return m_stackIndex; }
581 0 : unsigned int PlotAxesStack::size() const { return m_stack.size(); }
582 :
583 0 : vector<PlotRegion> PlotAxesStack::stack() const { return m_stack; }
584 0 : vector<pair<PlotAxis, PlotAxis> > PlotAxesStack::stackAxes() const {
585 0 : return m_axes; }
586 :
587 0 : void PlotAxesStack::setBase(const PlotRegion& base, PlotAxis xAxis,
588 : PlotAxis yAxis) {
589 :
590 0 : m_stack.resize(0); // so next line sets element zero!
591 0 : m_stack.resize(1, base);
592 0 : m_axes.resize(0); // so next line sets element zero!
593 0 : m_axes.resize(1, pair<PlotAxis, PlotAxis>(xAxis, yAxis));
594 0 : m_stackIndex = 0;
595 :
596 0 : }
597 :
598 0 : void PlotAxesStack::addRegion(const PlotRegion& region, PlotAxis xAxis,
599 : PlotAxis yAxis) {
600 0 : if(m_stack.size() == 0) setBase(region, xAxis, yAxis);
601 : else {
602 0 : unsigned int newSize = m_stackIndex + 2;
603 :
604 0 : if(m_lengthLimit > 0 && newSize > (unsigned int)m_lengthLimit) {
605 : // resize by discarding old values
606 0 : shrinkStacks((unsigned int)m_lengthLimit);
607 :
608 : // Check for special indexing case. Otherwise we override the
609 : // current stack index member.
610 0 : if(m_stackIndex < (unsigned int)(m_lengthLimit - 1))
611 0 : m_stackIndex++;
612 :
613 0 : } else if(m_stack.size() != newSize) {
614 0 : m_stack.resize(newSize);
615 0 : m_axes.resize(newSize);
616 0 : m_stackIndex++;
617 :
618 0 : } else m_stackIndex++;
619 :
620 0 : m_stack[m_stackIndex] = region;
621 0 : m_axes[m_stackIndex] = pair<PlotAxis, PlotAxis>(xAxis, yAxis);
622 : }
623 0 : }
624 :
625 0 : void PlotAxesStack::clearStack(bool keepBase) {
626 0 : if(m_stack.size() == 0) return;
627 0 : m_stack.resize(keepBase ? 1 : 0);
628 0 : m_axes.resize(keepBase ? 1 : 0);
629 0 : m_stackIndex = 0;
630 : }
631 :
632 0 : PlotRegion PlotAxesStack::currentRegion() const {
633 0 : if(isValid()) return m_stack[m_stackIndex];
634 0 : else return PlotRegion();
635 : }
636 :
637 0 : PlotAxis PlotAxesStack::currentXAxis() const {
638 0 : if(isValid()) return m_axes[m_stackIndex].first;
639 0 : else return X_BOTTOM;
640 : }
641 :
642 0 : PlotAxis PlotAxesStack::currentYAxis() const {
643 0 : if(isValid()) return m_axes[m_stackIndex].second;
644 0 : else return Y_LEFT;
645 : }
646 :
647 0 : void PlotAxesStack::move(int delta) {
648 0 : if(!isValid()) return;
649 0 : if(delta == 0) delta = -m_stackIndex;
650 0 : int temp = m_stackIndex + delta;
651 0 : if(temp < 0) temp = 0;
652 0 : else if(temp >= (int)m_stack.size()) temp = m_stack.size() - 1;
653 0 : m_stackIndex = (unsigned int)temp;
654 : }
655 :
656 0 : PlotRegion PlotAxesStack::moveAndReturn(int delta) {
657 0 : move(delta);
658 0 : return currentRegion();
659 : }
660 :
661 : /*
662 : void PlotAxesStack::summary() {
663 :
664 : cout << "Stack listing ";
665 :
666 : if (size()>0) {
667 : cout << "(" << size() << "):" << endl;
668 :
669 : for (uint i=0;i<size();++i)
670 : cout << i << " "
671 : << stack()[i].left() << " "
672 : << stack()[i].right() << " "
673 : << stack()[i].bottom() << " "
674 : << stack()[i].top() << " "
675 : << endl;
676 : }
677 : else
678 : cout << "(none)" << endl;
679 :
680 : }
681 :
682 : */
683 :
684 :
685 0 : void PlotAxesStack::shrinkStacks(unsigned int n) {
686 0 : if(n == 0 || m_stack.size() >= n) return;
687 :
688 : // Shorten the stacks.
689 0 : unsigned int diff = m_stack.size() - n;
690 0 : vector<PlotRegion> stack(n);
691 0 : vector<pair<PlotAxis, PlotAxis> > axes(n);
692 :
693 : // Copy over bases.
694 0 : stack[0] = m_stack[0];
695 0 : axes[0] = m_axes[0];
696 :
697 0 : if(m_stackIndex > 0 && m_stackIndex <= diff) {
698 : // Current index is in the part that is to be discarded, so
699 : // keep that member and copy over the rest, discarding the
700 : // oldest.
701 0 : stack[1] = m_stack[m_stackIndex];
702 0 : axes[1] = m_axes[m_stackIndex];
703 :
704 0 : for(unsigned int i = 2; i < n; i++) {
705 0 : stack[i] = m_stack[i + diff];
706 0 : axes[i] = m_axes[i + diff];
707 : }
708 :
709 : // Update stack index.
710 0 : m_stackIndex = 1;
711 :
712 : } else {
713 : // Copy over the rest, discarding the oldest.
714 0 : for(unsigned int i = 1; i < n; i++) {
715 0 : stack[i] = m_stack[i + diff];
716 0 : axes[i] = m_axes[i + diff];
717 : }
718 :
719 : // Update the stack index if not at base.
720 0 : if(m_stackIndex > 0) m_stackIndex -= diff;
721 : }
722 :
723 0 : m_stack = stack;
724 0 : m_axes = axes;
725 : }
726 :
727 :
728 : //////////////////////////////////
729 : // PLOTEXPORTFORMAT DEFINITIONS //
730 : //////////////////////////////////
731 :
732 0 : PlotExportFormat::PlotExportFormat(Type t, const String& file) : type(t),
733 : verbose(true), location(file), resolution(SCREEN), dpi(-1),
734 0 : width(-1), height(-1) { }
735 :
736 0 : PlotExportFormat::~PlotExportFormat() { }
737 :
738 0 : String PlotExportFormat::exportFormat(Type t) {
739 0 : switch(t) {
740 0 : case PNG: return "PNG";
741 0 : case JPG: return "JPG";
742 0 : case PS: return "PS";
743 0 : case PDF: return "PDF";
744 0 : case TEXT: return "TEXT";
745 0 : default: return "";
746 : }
747 : }
748 :
749 0 : PlotExportFormat::Type PlotExportFormat::exportFormat(String t, bool* ok) {
750 0 : t.downcase();
751 :
752 0 : if(ok != NULL) *ok = true;
753 0 : if(t == "png") return PNG;
754 0 : else if(t == "jpg" || t == "jpeg") return JPG;
755 0 : else if(t == "ps") return PS;
756 0 : else if(t == "pdf") return PDF;
757 0 : else if(t == "txt" || t == "text" || t == "csv")
758 0 : return TEXT;
759 :
760 : // error
761 0 : if(ok != NULL) *ok = false;
762 0 : return PNG;
763 : }
764 :
765 0 : String PlotExportFormat::extensionFor(Type t) {
766 0 : switch(t) {
767 0 : case PNG: return "png";
768 0 : case JPG: return "jpg";
769 0 : case PS: return "ps";
770 0 : case PDF: return "pdf";
771 0 : case TEXT: return "txt";
772 0 : default: return "";
773 : }
774 : }
775 :
776 0 : PlotExportFormat::Type PlotExportFormat::typeForExtension(String f, bool* ok) {
777 0 : f.downcase();
778 0 : unsigned int n = f.size();
779 0 : if(ok != NULL) *ok = true;
780 0 : if(f.matches("png", n - 3)) return PNG;
781 0 : else if(f.matches("jpg", n - 3) || f.matches("jpeg", n - 4))
782 0 : return JPG;
783 0 : else if(f.matches("ps", n - 2)) return PS;
784 0 : else if(f.matches("pdf", n - 3)) return PDF;
785 0 : else if(f.matches("txt", n - 3) || f.matches("text", n - 4) ||
786 0 : f.matches("csv", n - 3))
787 0 : return TEXT;
788 :
789 : // error
790 0 : if(ok != NULL) *ok = false;
791 0 : return PNG;
792 : }
793 :
794 0 : vector<PlotExportFormat::Type> PlotExportFormat::supportedFormats() {
795 0 : vector<Type> v(NUM_FMTS);
796 0 : v[0] = PNG;
797 0 : v[1] = JPG;
798 0 : v[2] = PS;
799 0 : v[3] = PDF;
800 0 : v[4] = TEXT;
801 0 : return v;
802 : }
803 0 : vector<String> PlotExportFormat::supportedFormatStrings() {
804 0 : vector<Type> v = supportedFormats();
805 0 : vector<String> s(v.size());
806 0 : for(unsigned int i = 0; i < s.size(); i++) s[i] = exportFormat(v[i]);
807 0 : return s;
808 : }
809 :
810 0 : vector<PlotExportFormat::Type> PlotExportFormat::supportedImageFormats() {
811 0 : vector<Type> v(2);
812 0 : v[0] = PNG;
813 0 : v[1] = JPG;
814 0 : return v;
815 : }
816 :
817 0 : vector<String> PlotExportFormat::supportedImageFormatStrings() {
818 0 : vector<Type> v = supportedImageFormats();
819 0 : vector<String> s(v.size());
820 0 : for(unsigned int i = 0; i < s.size(); i++) s[i] = exportFormat(v[i]);
821 0 : return s;
822 : }
823 :
824 : }
|