OpenASIP 2.2
Loading...
Searching...
No Matches
EPSGenerator.cc
Go to the documentation of this file.
1/*
2 Copyright (c) 2002-2009 Tampere University.
3
4 This file is part of TTA-Based Codesign Environment (TCE).
5
6 Permission is hereby granted, free of charge, to any person obtaining a
7 copy of this software and associated documentation files (the "Software"),
8 to deal in the Software without restriction, including without limitation
9 the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 and/or sell copies of the Software, and to permit persons to whom the
11 Software is furnished to do so, subject to the following conditions:
12
13 The above copyright notice and this permission notice shall be included in
14 all copies or substantial portions of the Software.
15
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 DEALINGS IN THE SOFTWARE.
23 */
24/**
25 * @file EPSGenerator.cc
26 *
27 * Implementation of EPSGenerator class.
28 *
29 * @author Veli-Pekka Jääskeläinen 2005 (vjaaskel-no.spam-cs.tut.fi)
30 * @note rating: red
31 */
32
33#include <boost/format.hpp>
34#include "EPSGenerator.hh"
35#include "Application.hh"
36#include "Conversion.hh"
37#include "VertexList.hh"
38
39using boost::format;
40using std::endl;
41
42const unsigned EPSGenerator::DEFAULT_MARGIN = 20;
43
44const std::string EPSGenerator::FMT_RLINETO = " %1% %2% rlineto";
45const std::string EPSGenerator::FMT_LINETO = " %1% %2% lineto";
46const std::string EPSGenerator::FMT_MOVETO = " %1% %2% moveto";
47
48/**
49 * The Constructor.
50 */
52 hasTitle_(false), title_(""), creator_("TCE EPS Generator"),
53 lineWidth_(1), minX_(0), minY_(0), maxX_(0), maxY_(0),
54 scale_(1) ,boundsSet_(false), xMargin_(DEFAULT_MARGIN),
55 yMargin_(DEFAULT_MARGIN) {
56
57 time_t currentTime;
58 time(&currentTime);
59 creationDate_ = ctime(&currentTime);
60
61 fillColour_.r = 0;
62 fillColour_.g = 0;
63 fillColour_.b = 0;
64 lineColour_.r = 0;
65 lineColour_.g = 0;
66 lineColour_.b = 0;
67}
68
69
70/**
71 * The Destructor.
72 */
76
77/**
78 * Stretches eps bounds so that the given point is inside the bounds.
79 */
80void
82
83 if (boundsSet_) {
84 minX_ = (x < minX_) ? x : minX_;
85 maxX_ = (x > maxX_) ? x : maxX_;
86 minY_ = (y < minY_) ? y : minY_;
87 maxY_ = (y > maxY_) ? y : maxY_;
88 } else {
89 boundsSet_ = true;
90 minX_ = x;
91 maxX_ = x;
92 minY_ = y;
93 maxY_ = y;
94 }
95}
96
97/**
98 * Draws a rectangle.
99 *
100 * @param x Lower left corner x-coordinate of the rectangle.
101 * @param y Lower left corner y-coordinate of the rectangle.
102 * @param width Width of the rectangle.
103 * @param height Height of the rectangle.
104 */
105void
106EPSGenerator::drawRectangle(int x, int y, unsigned width, unsigned height) {
107 drawRectanglePath(x, y, width, height);
108 buffer_.push("stroke");
109}
110
111/**
112 * Draws a rectangle fileld with the fill colour set.
113 *
114 * @param x Lower left corner x-coordinate of the rectangle.
115 * @param y Lower left corner y-coordinate of the rectangle.
116 * @param width Width of the rectangle.
117 * @param height Height of the rectangle.
118 */
119void
121 int x, int y, unsigned width, unsigned height) {
122
123 drawRectanglePath(x, y, width, height);
124 buffer_.push(" gsave");
126 buffer_.push(" fill");
127 buffer_.push(" grestore");
129 buffer_.push("stroke");
130}
131
132/**
133 * Writes path of a rectangle outline to the eps buffer.
134 *
135 * @param x Lower left corner x-coordinate of the rectangle.
136 * @param y Lower left corner y-coordinate of the rectangle.
137 * @param width Width of the rectangle.
138 * @param height Height of the rectangle.
139 */
140void
142 int x, int y, unsigned width, unsigned height) {
143
144 appendToBounds(x, y);
145 appendToBounds(x + width, y + height);
146
147 format move = format(FMT_MOVETO) % x % y;
148 format line1 = format(FMT_RLINETO) % width % 0;
149 format line2 = format(FMT_RLINETO) % 0 % height;
150 format line3 = format(FMT_RLINETO) % (-1 * (int)width) % 0;
151
152 buffer_.push("");
153 buffer_.push("newpath");
154 buffer_.push(move.str());
155 buffer_.push(line1.str());
156 buffer_.push(line2.str());
157 buffer_.push(line3.str());
158 buffer_.push(" closepath");
159}
160
161
162/**
163 * Draws a line.
164 *
165 * @param x1 X-coordinate of the first end point of the line.
166 * @param y1 Y-coordinate of the first end point of the line.
167 * @param x2 X-coordinate of the second end point of the line.
168 * @param y2 Y-coordinate of the second end point of the line.
169 */
170void
171EPSGenerator::drawLine(int x1, int y1, int x2, int y2) {
172
173 appendToBounds(x1, y1);
174 appendToBounds(x2, y2);
175
176 format move = format(FMT_MOVETO) % x1 % y1;
177 format line = format(FMT_LINETO) % x2 % y2;
178 buffer_.push("");
179 buffer_.push("newpath");
180 buffer_.push(move.str());
181 buffer_.push(line.str() );
182 buffer_.push("stroke");
183}
184
185/**
186 * Draws a polygon outline.
187 *
188 * @param vertices Vector of at least three coordinate pairs which are the
189 * polygon vertices.
190 */
191void
193 assert(vertices.size() > 2);
194 drawPolygonPath(vertices);
195 buffer_.push("stroke");
196}
197
198
199/**
200 * Draws a filled polygon.
201 *
202 * @param vertices Vector of at least three coordinate pairs which are the
203 * polygon vertices.
204 */
205void
207
208 assert(vertices.size() > 2);
209 drawPolygonPath(vertices);
210 buffer_.push(" gsave");
212 buffer_.push(" fill");
213 buffer_.push(" grestore");
215 buffer_.push("stroke");
216}
217
218/**
219 * Writes path of a polygon outline to the eps buffer.
220 *
221 * @param vertices Vector of at least three coordinate pairs which are the
222 * polygon vertices.
223 */
224void
226
227 assert(vertices.size() > 2);
228
229 format move(FMT_MOVETO);
230
231 int x = vertices.vertexX(0);
232 int y = vertices.vertexY(0);
233 appendToBounds(x, y);
234 move % x % y;
235
236 buffer_.push("");
237 buffer_.push("newpath");
238 buffer_.push(move.str());
239
240 for (unsigned i = 1; i < vertices.size(); i++) {
241
242 x = vertices.vertexX(i);
243 y = vertices.vertexY(i);
244 appendToBounds(x, y);
245 format lineto(FMT_LINETO);
246 lineto % x % y;
247 buffer_.push(lineto.str());
248 }
249
250 buffer_.push(" closepath");
251}
252
253
254/**
255 * Draws a circle.
256 *
257 * @param x X-coordinate of the circle centre.
258 * @param y Y-coordinate of the circle centre.
259 * @param radius Radius of the circle.
260 */
261void
262EPSGenerator::drawCircle(int x, int y, unsigned radius) {
263 drawCirclePath(x, y, radius);
264 buffer_.push("stroke");
265}
266
267/**
268 * Draws a circle filled with the fill colour.
269 *
270 * @param x X-coordinate of the circle centre.
271 * @param y Y-coordinate of the circle centre.
272 * @param radius Radius of the circle.
273 */
274void
275EPSGenerator::drawFilledCircle(int x, int y, unsigned radius) {
276 drawCirclePath(x, y, radius);
277 buffer_.push(" gsave");
279 buffer_.push(" fill");
280 buffer_.push(" grestore");
282 buffer_.push("stroke");
283}
284
285
286/**
287 * Writes path of a circle outline to the eps buffer.
288 *
289 * @param x X-coordinate of the circle centre.
290 * @param y Y-coordinate of the circle centre.
291 * @param radius Radius of the circle.
292 */
293void
294EPSGenerator::drawCirclePath(int x, int y, unsigned radius) {
295
296 appendToBounds(x + radius, y + radius);
297 appendToBounds(x - radius, y - radius);
298
299 buffer_.push("");
300
301 std::string fmtCircle = " %1% %2% %3% 0 360 arc";
302
303 boost::format circle = format(fmtCircle) % x % y % radius;
304 buffer_.push("newpath");
305 buffer_.push(circle.str());
306}
307
308
309/**
310 * Draws outline of an ellipse.
311 *
312 * @param x X-coordinate of the ellipse bounding box lower left corner.
313 * @param y Y-coordinate of the ellipse bounding box lower left corner.
314 * @param width Width of the ellipse.
315 * @param height Height of the ellipse.
316 */
317void
318EPSGenerator::drawEllipse(int x, int y, unsigned width, unsigned height) {
319 doDrawEllipse(x, y, width, height, false);
320}
321
322
323/**
324 * Draws a filled ellipse.
325 *
326 * @param x X-coordinate of the ellipse bounding box lower left corner.
327 * @param y Y-coordinate of the ellipse bounding box lower left corner.
328 * @param width Width of the ellipse.
329 * @param height Height of the ellipse.
330 */
331void
333 int x, int y, unsigned width, unsigned height) {
334
335 doDrawEllipse(x, y, width, height, true);
336}
337
338/**
339 * Writes path of an ellipse outline to the eps buffer.
340 *
341 * @param x X-coordinate of the ellipse bounding box lower left corner.
342 * @param y Y-coordinate of the ellipse bounding box lower left corner.
343 * @param width Width of the ellipse.
344 * @param height Height of the ellipse.
345 * @param fill True, if the ellipse shoud be filled.
346 */
347void
349 int x, int y, unsigned width, unsigned height, bool fill) {
350
351 appendToBounds(x + width, y + height);
352 appendToBounds(x, y);
353
354 buffer_.push("");
355
356 format fmtScale = format("1 %1% %2% div scale");
357 format fmtTranslate = format("%1% %2% translate");
358 fmtScale % width % height;
359 fmtTranslate % (x + width / 2) % (y + height / 2);
360
361 buffer_.push("gsave");
362 buffer_.push(fmtTranslate.str());
363 buffer_.push(fmtScale.str());
364
365
366 std::string fmtEllipse = " 0 0 %4% 2 div 0 360 arc";
367
368 boost::format ellipse = format(fmtEllipse) % x % y % width % height;
369 buffer_.push("newpath");
370 buffer_.push(ellipse.str());
371
372 if (fill) {
373 buffer_.push(" gsave");
375 buffer_.push(" fill");
376 buffer_.push(" grestore");
378 }
379
380 buffer_.push("stroke");
381 buffer_.push("grestore");
382}
383
384/**
385 * Draws text to the eps with the current font set with setFont method.
386 *
387 * @param x X-coordinate of the text bounds lower left corner.
388 * @param y Y-coordinate of the text bounds lower left corner.
389 * @param text Text to draw.
390 */
391void
392EPSGenerator::drawText(int x, int y, std::string text) {
393
394 format fmtMoveTo("%1% %2% moveto");
395 format fmtShowText(" (%1%) show");
396
397 fmtMoveTo % x % y;
398 fmtShowText % text;
399
400 buffer_.push("");
401 buffer_.push(fmtMoveTo.str());
402 buffer_.push(fmtShowText.str());
403
404}
405
406/**
407 * Sets the creator string of the image.
408 *
409 * The creator string will be set as the Creator comment of the generated
410 * eps file.
411 *
412 * @param creator String describing the creator of the eps-file.
413 */
414void
415EPSGenerator::setCreator(std::string creator) {
416 creator_ = creator;
417}
418
419/**
420 * Sets the title of the eps file.
421 *
422 * Title string will be set as the title comment of the generated eps file.
423 * If the title string is empty, the title comment will be omitted.
424 *
425 * @param title Title of the eps file.
426 */
427void
428EPSGenerator::setTitle(std::string title) {
429
430 if (title.length() > 0) {
431 hasTitle_ = true;
432 } else {
433 hasTitle_ = false;
434 }
435 title_ = title;
436}
437
438/**
439 * Sets the line width of the shapes that are drawn after this function call.
440 *
441 * @param width Width of the lines drawn to the eps.
442 */
443void
445 lineWidth_ = width;
446 buffer_.push("");
447 std::string setlinewidth = "%1% setlinewidth";
448 buffer_.push(str(format(setlinewidth) % width));
449}
450
451
452/**
453 * Sets the font face and size.
454 *
455 * @param size Font height in pixels.
456 * @param fontName Name of the font. The name must be valid post script font
457 * name.
458 */
459void
460EPSGenerator::setFont(unsigned size, std::string fontName) {
461 format setFont = format("/%2% findfont %1% scalefont setfont");
462 setFont % size % fontName;
463 buffer_.push("");
464 buffer_.push(setFont.str());
465}
466
467/**
468 * Sets the line drawing colour.
469 *
470 * @param r Red component scaled between 0 and 1.
471 * @param g Green component scaled between 0 and 1.
472 * @param b Blue component scaled between 0 and 1.
473 */
474void
475EPSGenerator::setLineColour(double r, double g, double b) {
476 if (r < 0 || g < 0 || b < 0 || r > 1 || g > 1 || b > 1) {
477 std::string error =
478 "Colour component values must be between 0 and 1.";
479 std::string proc = "EPSGenerator::setLineColour";
480 OutOfRange e(__FILE__, __LINE__, proc, error);
481 throw e;
482 }
483
484 lineColour_.r = r;
485 lineColour_.g = g;
486 lineColour_.b = b;
487
489}
490
491/**
492 * Sets the shape filling colour.
493 *
494 * @param r Red component scaled between 0 and 1.
495 * @param g Green component scaled between 0 and 1.
496 * @param b Blue component scaled between 0 and 1.
497 */
498void
499EPSGenerator::setFillColour(double r, double g, double b) {
500 if (r < 0 || g < 0 || b < 0 || r > 1 || g > 1 || b > 1) {
501 std::string error =
502 "Colour component values must be between 0 and 1.";
503 std::string proc = "EPSGenerator::setFillColour";
504 OutOfRange e(__FILE__, __LINE__, proc, error);
505 throw e;
506 }
507
508 fillColour_.r = r;
509 fillColour_.g = g;
510 fillColour_.b = b;
511}
512
513/**
514 * Clears the eps code buffer.
515 */
516void
518 while(!buffer_.empty()) {
519 buffer_.pop();
520 }
521}
522
523/**
524 * Generates an eps file which contains the graphics client drew.
525 *
526 * @param ostream Output stream to write the eps file contents to.
527 */
528void
529EPSGenerator::writeEPS(std::ostream& ostream) {
530
531 int w = (int)(scale_*(maxX_ - minX_ + 2 * xMargin_));
532 int h = (int)(scale_*(maxY_ - minY_ + 2 * yMargin_));
533
534 // Write eps headers.
535 ostream << "%!PS-Adobe-3.0 EPSF-3.0" << endl;
536 ostream << "%%BoundingBox: 0 0 " << w << " " << h << " " << endl;
537 if (hasTitle_) {
538 ostream << "%%Title: (" << title_ << ")" << endl;
539 }
540 ostream << "%%Creator: " << creator_ << endl;
541 ostream << "%%CreationDate: " << creationDate_ << endl;
542 ostream << "%%EndComments" << endl;
543
544
545 // Set scaling factor & translation. The coordinate system is translated
546 // so that the minimum x and y coordinates are zero.
547 ostream << scale_ << " " << scale_ << " scale" << endl;
548 ostream << minX_ * -1 + (int)xMargin_ << " "
549 << minY_ * -1 + (int)yMargin_ << " translate" << endl;
550
551
552 // Write the postscript drawing code from the code buffer to the
553 // output stream.
554 while (!buffer_.empty()) {
555 std::string line = buffer_.front();
556 buffer_.pop();
557 ostream << line << endl;
558 }
559 ostream << endl << "showpage" << endl << endl;
560
561 // Write end of file comment.
562 ostream << "%%EOF" << endl;
563}
564
565
566/**
567 * Sets the coordinate system scaling factors for the coordinate axels.
568 *
569 * This function sets only the final scaling factor of the image.
570 * Only the last scaling factor set before calling writeEPS has effect on
571 * the final eps file.
572 *
573 * @param scale Scaling factor.
574 */
575void
577 if (scale < 0) {
578 std::string error = "Scaling factor must be greater than zero.";
579 std::string proc = "EPSGenerator::setScale";
580 OutOfRange e(__FILE__, __LINE__, proc, error);
581 throw e;
582 }
583
584 scale_ = scale;
585}
586
587/**
588 * Sets the eps margins.
589 *
590 * @param x Left and right side margin.
591 * @param y Top and bottom margin.
592 */
593void
594EPSGenerator::setMargins(unsigned x, unsigned y) {
595 xMargin_ = x;
596 yMargin_ = y;
597}
598
599
600/**
601 * Sets the eps drawing colour to the current line drawing colour.
602 */
603void
605 format setColour("%1% %2% %3% setrgbcolor");
606 setColour % lineColour_.r % lineColour_.g % lineColour_.b;
607 buffer_.push(setColour.str());
608}
609
610/**
611 * Sets the eps drawing colour to the current filling colour.
612 */
613void
615 format setColour("%1% %2% %3% setrgbcolor");
616 setColour % fillColour_.r % fillColour_.g % fillColour_.b;
617 buffer_.push(setColour.str());
618}
#define assert(condition)
find Finds info of the inner loops in the false
void setTitle(std::string title)
unsigned yMargin_
Margin to add on the top and bottom side of the figure in pixels.
void useLineColour()
void drawLine(int llx, int lly, int urx, int ury)
unsigned lineWidth_
Current width of the lines drawn.
void drawRectangle(int x, int y, unsigned width, unsigned height)
bool hasTitle_
True, if the EPS file has a title.
static const std::string FMT_MOVETO
Format string for postscript moveto command.
double scale_
Final scaling factor for the eps file.
static const unsigned DEFAULT_MARGIN
Default margin width.
void drawPolygon(const VertexList &vertices)
int minX_
Minimum x-coordinate used before scaling & translation.
void drawFilledCircle(int x, int y, unsigned radius)
void drawFilledRectangle(int x, int y, unsigned width, unsigned height)
std::string title_
Title of the EPS file.
void drawFilledPolygon(const VertexList &vertices)
int minY_
Minimum y-coordinate used before scaling & translation.
void drawText(int x, int y, std::string text)
unsigned xMargin_
Margin to add on the left and right side of the figure in pixels.
void doDrawEllipse(int x, int y, unsigned width, unsigned height, bool fill)
void appendToBounds(int x, int y)
void setFont(unsigned size, std::string fontName="Courier-Bold")
colour lineColour_
Current drawing colour for lines.
colour fillColour_
Current colour for filling shape backgrounds.
void setMargins(unsigned x, unsigned y)
static const std::string FMT_LINETO
Format string for postscript lineto command.
std::string creationDate_
String describing the creation date of the EPS file.
void drawCirclePath(int x, int y, unsigned radius)
void drawPolygonPath(const VertexList &vertices)
void drawCircle(int x, int y, unsigned radius)
void drawEllipse(int x, int y, unsigned width, unsigned height)
int maxY_
Maximum y-coordinate used before scaling & translation.
void drawRectanglePath(int x, int y, unsigned width, unsigned height)
void drawFilledEllipse(int x, int y, unsigned width, unsigned height)
void setLineColour(double r, double g, double b)
void writeEPS(std::ostream &stream)
int maxX_
Maximum x-coordinate used before scaling & translation.
bool boundsSet_
True, if a point has been added to the bounds.
std::queue< std::string > buffer_
Buffer for the .eps code to be written.
static const std::string FMT_RLINETO
Format string for postscript rlineto command.
void setLineWidth(unsigned width)
std::string creator_
String describing the creator of the document.
void setFillColour(double r, double g, double b)
void useFillColour()
void setScale(double scale)
void setCreator(std::string creator)
int vertexY(size_t index) const
size_t size() const
Definition VertexList.cc:68
int vertexX(size_t index) const
Definition VertexList.cc:80