Panda3D
pnmPainter.cxx
1 // Filename: pnmPainter.cxx
2 // Created by: drose (02Feb07)
3 //
4 ////////////////////////////////////////////////////////////////////
5 //
6 // PANDA 3D SOFTWARE
7 // Copyright (c) Carnegie Mellon University. All rights reserved.
8 //
9 // All use of this software is subject to the terms of the revised BSD
10 // license. You should have received a copy of this license along
11 // with this source code in a file named "LICENSE."
12 //
13 ////////////////////////////////////////////////////////////////////
14 
15 #include "pnmPainter.h"
16 
17 ////////////////////////////////////////////////////////////////////
18 // Function: PNMPainter::Constructor
19 // Access: Published
20 // Description: The constructor stores a pointer to the PNMImage you
21 // pass it, but it does not take ownership of the
22 // object; you are responsible for ensuring that the
23 // PNMImage does not destruct during the lifetime of the
24 // PNMPainter object.
25 //
26 // The xo, yo coordinates specify an optional offset for
27 // fill coordinates. If you are painting with a pattern
28 // fill, these specify the virtual coordinates of the
29 // upper-left corner of the image, which can allow you
30 // to adjust the pattern to line up with nested images,
31 // if necessary.
32 ////////////////////////////////////////////////////////////////////
34 PNMPainter(PNMImage &image, int xo, int yo) :
35  _image(image),
36  _xo(xo), _yo(yo)
37 {
38  _pen = PNMBrush::make_pixel(LColorf(0, 0, 0, 1));
39  _fill = PNMBrush::make_pixel(LColorf(1, 1, 1, 1));
40 }
41 
42 ////////////////////////////////////////////////////////////////////
43 // Function: PNMPainter::draw_line
44 // Access: Published
45 // Description: Draws an antialiased line on the PNMImage, using the
46 // current pen.
47 ////////////////////////////////////////////////////////////////////
48 void PNMPainter::
49 draw_line(float xa, float ya, float xb, float yb) {
50  // Shift the line coordinates to position the center of the pen on
51  // the line.
52  xa -= (_pen->get_xc() - 0.5);
53  xb -= (_pen->get_xc() - 0.5);
54  ya -= (_pen->get_yc() - 0.5);
55  yb -= (_pen->get_yc() - 0.5);
56 
57  // Compute the line delta.
58  float xd = xb - xa;
59  float yd = yb - ya;
60 
61  if (xa == xb && ya == yb) {
62  // Just a single point. Treat it as a very short horizontal line.
63  xd = 1.0;
64  }
65 
66  if (cabs(xd) > cabs(yd)) {
67  // This line is more horizontal than vertical.
68  if (xa < xb) {
69  // Draw the line from left to right.
70  int x_min = (int)cfloor(xa);
71  int x_max = (int)cceil(xb);
72 
73  // The first point.
74  draw_hline_point(x_min, xa, ya, xd, yd, 1.0 - (xa - x_min));
75 
76  // The middle points.
77  for (int x = x_min + 1; x < x_max; ++x) {
78  draw_hline_point(x, xa, ya, xd, yd, 1.0);
79  }
80 
81  if (x_max != x_min) {
82  // The last point.
83  draw_hline_point(x_max, xa, ya, xd, yd, 1.0 - (x_max - xb));
84  }
85 
86  } else {
87  // Draw the line from right to left.
88  int x_min = (int)cfloor(xb);
89  int x_max = (int)cceil(xa);
90 
91  // The first point.
92  draw_hline_point(x_max, xa, ya, xd, yd, 1.0 - (x_max - xa));
93 
94  // The middle points.
95  for (int x = x_max - 1; x > x_min; --x) {
96  draw_hline_point(x, xa, ya, xd, yd, 1.0);
97  }
98 
99  if (x_max != x_min) {
100  // The last point.
101  draw_hline_point(x_min, xa, ya, xd, yd, 1.0 - (xb - x_min));
102  }
103  }
104 
105  } else {
106  // This line is more vertical than horizontal.
107  if (ya < yb) {
108  // Draw the line from top to bottom.
109  int y_min = (int)cfloor(ya);
110  int y_max = (int)cceil(yb);
111 
112  // The first point.
113  draw_vline_point(y_min, xa, ya, xd, yd, 1.0 - (ya - y_min));
114 
115  // The middle points.
116  for (int y = y_min + 1; y < y_max; ++y) {
117  draw_vline_point(y, xa, ya, xd, yd, 1.0);
118  }
119 
120  if (y_max != y_min) {
121  // The last point.
122  draw_vline_point(y_max, xa, ya, xd, yd, 1.0 - (y_max - yb));
123  }
124 
125  } else {
126  // Draw the line from bottom to top.
127  int y_min = (int)cfloor(yb);
128  int y_max = (int)cceil(ya);
129 
130  // The first point.
131  draw_vline_point(y_max, xa, ya, xd, yd, 1.0 - (y_max - ya));
132 
133  // The middle points.
134  for (int y = y_max - 1; y > y_min; --y) {
135  draw_vline_point(y, xa, ya, xd, yd, 1.0);
136  }
137 
138  if (y_max != y_min) {
139  // The last point.
140  draw_vline_point(y_min, xa, ya, xd, yd, 1.0 - (yb - y_min));
141  }
142  }
143  }
144 }
145 
146 ////////////////////////////////////////////////////////////////////
147 // Function: PNMPainter::draw_rectangle
148 // Access: Published
149 // Description: Draws a filled rectangule on the PNMImage, using the
150 // current pen for the outline, and the current fill
151 // brush for the interior.
152 //
153 // The two coordinates specify any two diagonally
154 // opposite corners.
155 ////////////////////////////////////////////////////////////////////
156 void PNMPainter::
157 draw_rectangle(float xa, float ya, float xb, float yb) {
158  // Make (xa, ya) be the upper-left corner, and (xb, yb) the
159  // lower-right.
160  if (xa > xb) {
161  float t = xa;
162  xa = xb;
163  xb = t;
164  }
165  if (ya > yb) {
166  float t = ya;
167  ya = yb;
168  yb = t;
169  }
170 
171  // First, fill the interior.
172  int x_min = (int)cceil(xa);
173  int x_max = (int)cfloor(xb);
174  int y_min = (int)cceil(ya);
175  int y_max = (int)cfloor(yb);
176  for (int y = y_min; y <= y_max; ++y) {
177  _fill->fill(_image, x_min, x_max, y, _xo, _yo);
178  }
179 
180  // Then, draw the outline.
181  draw_line(xa, ya, xa, yb);
182  draw_line(xa, yb, xb, yb);
183  draw_line(xb, yb, xb, ya);
184  draw_line(xb, ya, xa, ya);
185 }
The name of this class derives from the fact that we originally implemented it as a layer on top of t...
Definition: pnmImage.h:68
PNMPainter(PNMImage &image, int xo=0, int yo=0)
The constructor stores a pointer to the PNMImage you pass it, but it does not take ownership of the o...
Definition: pnmPainter.cxx:34
void draw_line(float xa, float ya, float xb, float yb)
Draws an antialiased line on the PNMImage, using the current pen.
Definition: pnmPainter.cxx:49
void draw_rectangle(float xa, float ya, float xb, float yb)
Draws a filled rectangule on the PNMImage, using the current pen for the outline, and the current fil...
Definition: pnmPainter.cxx:157
This is the base class for all three-component vectors and points.
Definition: lvecBase4.h:111