24 PNMTextGlyph(
double advance) :
29 _int_advance = (int)floor(_advance + 0.5);
52 LColorf fgf = LCAST(
float, fg);
54 int left = xp + _left;
60 int cleft = max(left, 0);
61 int ctop = max(top, 0);
62 int cright = min(right, dest_image.
get_x_size());
63 int cbottom = min(bottom, dest_image.
get_y_size());
65 for (
int y = ctop; y < cbottom; y++) {
66 for (
int x = cleft; x < cright; x++) {
67 double gval =
get_value(x - left, y - top);
71 }
else if (gval > 0.0) {
73 dest_image.
set_xel_a(x, y, fgf * gval + bg * (1.0 - gval));
85 const LColor &interior) {
91 LColorf fgf = LCAST(
float, fg);
92 LColorf interiorf = LCAST(
float, interior);
94 int left = xp + _left;
100 int cleft = max(left, 0);
101 int ctop = max(top, 0);
102 int cright = min(right, dest_image.
get_x_size());
103 int cbottom = min(bottom, dest_image.
get_y_size());
105 for (
int y = ctop; y < cbottom; y++) {
106 for (
int x = cleft; x < cright; x++) {
107 double gval =
get_value(x - left, y - top);
111 }
else if (gval > 0.0) {
120 dest_image.
set_xel_a(x, y, fgf * gval + bg * (1.0 - gval));
138 determine_interior() {
144 for (
int yi = 0; yi < y_size; yi++) {
145 for (
int xi = 0; xi < x_size; xi++) {
154 _scan_interior_points.clear();
155 for (
int yi = 0; yi < y_size; yi++) {
156 scan_interior(0, yi, 0,
false, 0);
157 scan_interior(x_size - 1, yi, 0,
false, 0);
159 for (
int xi = 0; xi < x_size; xi++) {
160 scan_interior(xi, 0, 0,
false, 0);
161 scan_interior(xi, y_size - 1, 0,
false, 0);
166 while (!_scan_interior_points.empty()) {
167 int index = _scan_interior_points.back();
168 _scan_interior_points.pop_back();
174 scan_interior(x - 1, y, new_code, this_dark, 0);
175 scan_interior(x, y - 1, new_code, this_dark, 0);
176 scan_interior(x + 1, y, new_code, this_dark, 0);
177 scan_interior(x, y + 1, new_code, this_dark, 0);
179 _scan_interior_points.clear();
184 for (
int yi = 0; yi < y_size; yi++) {
185 for (
int xi = 0; xi < x_size; xi++) {
187 if (((code + 2) & 0x3) == 0) {
202 scan_interior(
int x,
int y, xelval new_code,
bool neighbor_dark,
208 if (this_dark != neighbor_dark) {
213 nassertv(new_code > 0);
219 if (recurse_level > 1024) {
224 _scan_interior_points.push_back(index);
227 scan_interior(x - 1, y, new_code, this_dark, recurse_level);
228 scan_interior(x, y - 1, new_code, this_dark, recurse_level);
229 scan_interior(x + 1, y, new_code, this_dark, recurse_level);
230 scan_interior(x, y + 1, new_code, this_dark, recurse_level);
240 rescale(
double scale_factor) {
241 if (scale_factor == 1.0) {
244 nassertv(scale_factor != 0.0);
245 _advance /= scale_factor;
246 _int_advance = (int)floor(_advance + 0.5);
251 int orig_left = _left;
256 int extra_pad = (int)ceil(scale_factor);
257 orig_x_size += 2*extra_pad;
258 orig_y_size += 2*extra_pad;
259 orig_left -= extra_pad;
260 orig_top += extra_pad;
263 int new_x_size = (int)ceil(orig_x_size / scale_factor);
264 int new_y_size = (int)ceil(orig_y_size / scale_factor);
265 int new_left = (int)floor(orig_left / scale_factor);
266 int new_top = (int)ceil(orig_top / scale_factor);
271 int old_x_size = (int)(new_x_size * scale_factor + 0.5);
272 int old_y_size = (int)(new_y_size * scale_factor + 0.5);
273 int old_left = (int)(new_left * scale_factor + 0.5);
274 int old_top = (int)(new_top * scale_factor + 0.5);
276 int pad_left = orig_left - old_left;
277 int pad_top = old_top - orig_top;
280 nassertv(extra_pad + pad_left >= 0 && extra_pad + pad_top >= 0);
283 enlarged.copy_sub_image(_image, pad_left + extra_pad, pad_top + extra_pad);