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