Bug Summary

File:bitmap/bitscale.c
Location:line 1011, column 5
Description:Value stored to 'pci' is never read

Annotated Source Code

1/*
2
3Copyright 1991, 1994, 1998 The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28
29/*
30 * Author: Keith Packard, MIT X Consortium
31 */
32
33#ifdef HAVE_CONFIG_H1
34#include <config.h>
35#endif
36#include "libxfontint.h"
37
38#include <X11/fonts/fntfilst.h>
39#include <X11/fonts/bitmap.h>
40#include <X11/fonts/fontutil.h>
41#include <math.h>
42
43#ifndef MAX
44#define MAX(a,b)(((a)>(b)) ? a : b) (((a)>(b)) ? a : b)
45#endif
46
47static void bitmapUnloadScalable (FontPtr pFont);
48static void ScaleBitmap ( FontPtr pFont, CharInfoPtr opci,
49 CharInfoPtr pci, double *inv_xform,
50 double widthMult, double heightMult );
51static FontPtr BitmapScaleBitmaps(FontPtr pf, FontPtr opf,
52 double widthMult, double heightMult,
53 FontScalablePtr vals);
54
55enum scaleType {
56 atom, truncate_atom, pixel_size, point_size, resolution_x,
57 resolution_y, average_width, scaledX, scaledY, unscaled, fontname,
58 raw_ascent, raw_descent, raw_pixelsize, raw_pointsize,
59 raw_average_width, uncomputed
60};
61
62typedef struct _fontProp {
63 const char *name;
64 Atom atom;
65 enum scaleType type;
66} fontProp;
67
68static FontEntryPtr FindBestToScale ( FontPathElementPtr fpe,
69 FontEntryPtr entry,
70 FontScalablePtr vals,
71 FontScalablePtr best,
72 double *dxp, double *dyp,
73 double *sdxp, double *sdyp,
74 FontPathElementPtr *fpep );
75
76static unsigned long bitscaleGeneration = 0; /* initialization flag */
77
78static fontProp fontNamePropTable[] = {
79 { "FOUNDRY", 0, atom },
80 { "FAMILY_NAME", 0, atom },
81 { "WEIGHT_NAME", 0, atom },
82 { "SLANT", 0, atom },
83 { "SETWIDTH_NAME", 0, atom },
84 { "ADD_STYLE_NAME", 0, atom },
85 { "PIXEL_SIZE", 0, pixel_size },
86 { "POINT_SIZE", 0, point_size },
87 { "RESOLUTION_X", 0, resolution_x },
88 { "RESOLUTION_Y", 0, resolution_y },
89 { "SPACING", 0, atom },
90 { "AVERAGE_WIDTH", 0, average_width },
91 { "CHARSET_REGISTRY", 0, atom },
92 { "CHARSET_ENCODING", 0, truncate_atom },
93 { "FONT", 0, fontname },
94 { "RAW_ASCENT", 0, raw_ascent },
95 { "RAW_DESCENT", 0, raw_descent },
96 { "RAW_PIXEL_SIZE", 0, raw_pixelsize },
97 { "RAW_POINT_SIZE", 0, raw_pointsize },
98 { "RAW_AVERAGE_WIDTH", 0, raw_average_width }
99};
100
101#define TRANSFORM_POINT(matrix, x, y, dest)((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), (dest)[1]
= (matrix)[1] * (x) + (matrix)[3] * (y))
\
102 ((dest)[0] = (matrix)[0] * (x) + (matrix)[2] * (y), \
103 (dest)[1] = (matrix)[1] * (x) + (matrix)[3] * (y))
104
105#define CHECK_EXTENT(lsb, rsb, desc, asc, data)((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , (rsb) < (data
)[0] ? (rsb) = (data)[0] : 0, (-desc) > (data)[1] ? (desc)
= -(data)[1] : 0 , (asc) < (data)[1] ? (asc) = (data)[1] :
0)
\
106 ((lsb) > (data)[0] ? (lsb) = (data)[0] : 0 , \
107 (rsb) < (data)[0] ? (rsb) = (data)[0] : 0, \
108 (-desc) > (data)[1] ? (desc) = -(data)[1] : 0 , \
109 (asc) < (data)[1] ? (asc) = (data)[1] : 0)
110
111#define NPROPS(sizeof(fontNamePropTable) / sizeof(fontProp)) (sizeof(fontNamePropTable) / sizeof(fontProp))
112
113/* Warning: order of the next two tables is critically interdependent.
114 Location of "unscaled" properties at the end of fontPropTable[]
115 is important. */
116
117static fontProp fontPropTable[] = {
118 { "MIN_SPACE", 0, scaledX },
119 { "NORM_SPACE", 0, scaledX },
120 { "MAX_SPACE", 0, scaledX },
121 { "END_SPACE", 0, scaledX },
122 { "AVG_CAPITAL_WIDTH", 0, scaledX },
123 { "AVG_LOWERCASE_WIDTH", 0, scaledX },
124 { "QUAD_WIDTH", 0, scaledX },
125 { "FIGURE_WIDTH", 0, scaledX },
126 { "SUPERSCRIPT_X", 0, scaledX },
127 { "SUPERSCRIPT_Y", 0, scaledY },
128 { "SUBSCRIPT_X", 0, scaledX },
129 { "SUBSCRIPT_Y", 0, scaledY },
130 { "SUPERSCRIPT_SIZE", 0, scaledY },
131 { "SUBSCRIPT_SIZE", 0, scaledY },
132 { "SMALL_CAP_SIZE", 0, scaledY },
133 { "UNDERLINE_POSITION", 0, scaledY },
134 { "UNDERLINE_THICKNESS", 0, scaledY },
135 { "STRIKEOUT_ASCENT", 0, scaledY },
136 { "STRIKEOUT_DESCENT", 0, scaledY },
137 { "CAP_HEIGHT", 0, scaledY },
138 { "X_HEIGHT", 0, scaledY },
139 { "ITALIC_ANGLE", 0, unscaled },
140 { "RELATIVE_SETWIDTH", 0, unscaled },
141 { "RELATIVE_WEIGHT", 0, unscaled },
142 { "WEIGHT", 0, unscaled },
143 { "DESTINATION", 0, unscaled },
144 { "PCL_FONT_NAME", 0, unscaled },
145 { "_ADOBE_POSTSCRIPT_FONTNAME", 0, unscaled }
146};
147
148static fontProp rawFontPropTable[] = {
149 { "RAW_MIN_SPACE", 0, },
150 { "RAW_NORM_SPACE", 0, },
151 { "RAW_MAX_SPACE", 0, },
152 { "RAW_END_SPACE", 0, },
153 { "RAW_AVG_CAPITAL_WIDTH", 0, },
154 { "RAW_AVG_LOWERCASE_WIDTH", 0, },
155 { "RAW_QUAD_WIDTH", 0, },
156 { "RAW_FIGURE_WIDTH", 0, },
157 { "RAW_SUPERSCRIPT_X", 0, },
158 { "RAW_SUPERSCRIPT_Y", 0, },
159 { "RAW_SUBSCRIPT_X", 0, },
160 { "RAW_SUBSCRIPT_Y", 0, },
161 { "RAW_SUPERSCRIPT_SIZE", 0, },
162 { "RAW_SUBSCRIPT_SIZE", 0, },
163 { "RAW_SMALL_CAP_SIZE", 0, },
164 { "RAW_UNDERLINE_POSITION", 0, },
165 { "RAW_UNDERLINE_THICKNESS", 0, },
166 { "RAW_STRIKEOUT_ASCENT", 0, },
167 { "RAW_STRIKEOUT_DESCENT", 0, },
168 { "RAW_CAP_HEIGHT", 0, },
169 { "RAW_X_HEIGHT", 0, }
170};
171
172static void
173initFontPropTable(void)
174{
175 int i;
176 fontProp *t;
177
178 i = sizeof(fontNamePropTable) / sizeof(fontProp);
179 for (t = fontNamePropTable; i; i--, t++)
180 t->atom = MakeAtom__libxfont__MakeAtom(t->name, (unsigned) strlen(t->name), TRUE1);
181
182 i = sizeof(fontPropTable) / sizeof(fontProp);
183 for (t = fontPropTable; i; i--, t++)
184 t->atom = MakeAtom__libxfont__MakeAtom(t->name, (unsigned) strlen(t->name), TRUE1);
185
186 i = sizeof(rawFontPropTable) / sizeof(fontProp);
187 for (t = rawFontPropTable; i; i--, t++)
188 t->atom = MakeAtom__libxfont__MakeAtom(t->name, (unsigned) strlen(t->name), TRUE1);
189}
190
191#if 0
192static FontEntryPtr
193GetScalableEntry (FontPathElementPtr fpe, FontNamePtr name)
194{
195 FontDirectoryPtr dir;
196
197 dir = (FontDirectoryPtr) fpe->private;
198 return FontFileFindNameInDir (&dir->scalable, name);
199}
200#endif
201
202static double
203get_matrix_horizontal_component(double *matrix)
204{
205 return hypot(matrix[0], matrix[1]);
206}
207
208static double
209get_matrix_vertical_component(double *matrix)
210{
211 return hypot(matrix[2], matrix[3]);
212}
213
214
215static Bool
216ComputeScaleFactors(FontScalablePtr from, FontScalablePtr to,
217 double *dx, double *dy, double *sdx, double *sdy,
218 double *rescale_x)
219{
220 double srcpixelset, destpixelset, srcpixel, destpixel;
221
222 srcpixelset = get_matrix_horizontal_component(from->pixel_matrix);
223 destpixelset = get_matrix_horizontal_component(to->pixel_matrix);
224 srcpixel = get_matrix_vertical_component(from->pixel_matrix);
225 destpixel = get_matrix_vertical_component(to->pixel_matrix);
226
227 if (srcpixelset >= EPS1.0e-20)
228 {
229 *dx = destpixelset / srcpixelset;
230 *sdx = 1000.0 / srcpixelset;
231 }
232 else
233 *sdx = *dx = 0;
234
235 *rescale_x = 1.0;
236
237 /* If client specified a width, it overrides setsize; in this
238 context, we interpret width as applying to the font before any
239 rotation, even though that's not what is ultimately returned in
240 the width field. */
241 if (from->width > 0 && to->width > 0 && fabs(*dx) > EPS1.0e-20)
242 {
243 double rescale = (double)to->width / (double)from->width;
244
245 /* If the client specified a transformation matrix, the rescaling
246 for width does *not* override the setsize. Instead, just check
247 for consistency between the setsize from the matrix and the
248 setsize that would result from rescaling according to the width.
249 This assumes (perhaps naively) that the width is correctly
250 reported in the name. As an interesting side effect, this test
251 may result in choosing a different source bitmap (one that
252 scales consistently between the setsize *and* the width) than it
253 would choose if a width were not specified. Sort of a hidden
254 multiple-master functionality. */
255 if ((to->values_supplied & PIXELSIZE_MASK0x3) == PIXELSIZE_ARRAY0x2 ||
256 (to->values_supplied & POINTSIZE_MASK0xc) == POINTSIZE_ARRAY0x8)
257 {
258 /* Reject if resulting width difference is >= 1 pixel */
259 if (fabs(rescale * from->width - *dx * from->width) >= 10)
260 return FALSE0;
261 }
262 else
263 {
264 *rescale_x = rescale/(*dx);
265 *dx = rescale;
266 }
267 }
268
269 if (srcpixel >= EPS1.0e-20)
270 {
271 *dy = destpixel / srcpixel;
272 *sdy = 1000.0 / srcpixel;
273 }
274 else
275 *sdy = *dy = 0;
276
277 return TRUE1;
278}
279
280/* favor enlargement over reduction because of aliasing resulting
281 from reduction */
282#define SCORE(m,s)if (m >= 1.0) { if (m == 1.0) score += (16 * s); else if (
m == 2.0) score += (4 * s); else score += (int)(((double)(3 *
s)) / m); } else { score += (int)(((double)(2 * s)) * m); }
\
283if (m >= 1.0) { \
284 if (m == 1.0) \
285 score += (16 * s); \
286 else if (m == 2.0) \
287 score += (4 * s); \
288 else \
289 score += (int)(((double)(3 * s)) / m); \
290} else { \
291 score += (int)(((double)(2 * s)) * m); \
292}
293
294/* don't need to favor enlargement when looking for bitmap that can
295 be used unscalable */
296#define SCORE2(m,s)if (m >= 1.0) score += (int)(((double)(8 * s)) / m); else score
+= (int)(((double)(8 * s)) * m);
\
297if (m >= 1.0) \
298 score += (int)(((double)(8 * s)) / m); \
299else \
300 score += (int)(((double)(8 * s)) * m);
301
302static FontEntryPtr
303FindBestToScale(FontPathElementPtr fpe, FontEntryPtr entry,
304 FontScalablePtr vals, FontScalablePtr best,
305 double *dxp, double *dyp,
306 double *sdxp, double *sdyp,
307 FontPathElementPtr *fpep)
308{
309 FontScalableRec temp;
310 int source, i;
311 int best_score, best_unscaled_score,
312 score;
313 double dx = 0.0, sdx = 0.0, dx_amount = 0.0,
314 dy = 0.0, sdy = 0.0, dy_amount = 0.0,
315 best_dx = 0.0, best_sdx = 0.0, best_dx_amount = 0.0,
316 best_dy = 0.0, best_sdy = 0.0, best_dy_amount = 0.0,
317 best_unscaled_sdx = 0.0, best_unscaled_sdy = 0.0,
318 rescale_x = 0.0, best_rescale_x = 0.0,
319 best_unscaled_rescale_x = 0.0;
320 FontEntryPtr zero;
321 FontNameRec zeroName;
322 char zeroChars[MAXFONTNAMELEN1024];
323 FontDirectoryPtr dir;
324 FontScaledPtr scaled;
325 FontScalableExtraPtr extra;
326 FontScaledPtr best_scaled, best_unscaled;
327 FontPathElementPtr best_fpe = NULL((void *)0), best_unscaled_fpe = NULL((void *)0);
328 FontEntryPtr bitmap = NULL((void *)0);
329 FontEntryPtr result;
330 int aliascount = 20;
331 FontPathElementPtr bitmap_fpe = NULL((void *)0);
332 FontNameRec xlfdName;
333
334 /* find the best match */
335 rescale_x = 1.0;
336 best_scaled = 0;
337 best_score = 0;
338 best_unscaled = 0;
339 best_unscaled_score = -1;
340 best_dx_amount = best_dy_amount = HUGE_VAL__builtin_huge_val();
341 memcpy (zeroChars, entry->name.name, entry->name.length)__builtin___memcpy_chk (zeroChars, entry->name.name, entry
->name.length, __builtin_object_size (zeroChars, 0))
;
342 zeroChars[entry->name.length] = '\0';
343 zeroName.name = zeroChars;
344 FontParseXLFDName (zeroChars, &temp, FONT_XLFD_REPLACE_ZERO2);
345 zeroName.length = strlen (zeroChars);
346 zeroName.ndashes = entry->name.ndashes;
347 xlfdName.name = vals->xlfdName;
348 xlfdName.length = strlen(xlfdName.name);
349 xlfdName.ndashes = FontFileCountDashes(xlfdName.name, xlfdName.length);
350 restart_bestscale_loop: ;
351 /*
352 * Look through all the registered bitmap sources for
353 * the same zero name as ours; entries along that one
354 * can be scaled as desired.
355 */
356 for (source = 0; source < FontFileBitmapSources.count; source++)
357 {
358 /* There might already be a bitmap that satisfies the request
359 but didn't have a zero name that was found by the scalable
360 font matching logic. Keep track if there is. */
361 if (bitmap == NULL((void *)0) && vals->xlfdName != NULL((void *)0))
362 {
363 bitmap_fpe = FontFileBitmapSources.fpe[source];
364 dir = (FontDirectoryPtr) bitmap_fpe->private;
365 bitmap = FontFileFindNameInDir (&dir->nonScalable, &xlfdName);
366 if (bitmap && bitmap->type != FONT_ENTRY_BITMAP2)
367 {
368 if (bitmap->type == FONT_ENTRY_ALIAS3 && aliascount > 0)
369 {
370 aliascount--;
371 xlfdName.name = bitmap->u.alias.resolved;
372 xlfdName.length = strlen(xlfdName.name);
373 xlfdName.ndashes = FontFileCountDashes(xlfdName.name,
374 xlfdName.length);
375 bitmap = NULL((void *)0);
376 goto restart_bestscale_loop;
377 }
378 else
379 bitmap = NULL((void *)0);
380 }
381 }
382
383 if (FontFileBitmapSources.fpe[source] == fpe)
384 zero = entry;
385 else
386 {
387 dir = (FontDirectoryPtr) FontFileBitmapSources.fpe[source]->private;
388 zero = FontFileFindNameInDir (&dir->scalable, &zeroName);
389 if (!zero)
390 continue;
391 }
392 extra = zero->u.scalable.extra;
393 for (i = 0; i < extra->numScaled; i++)
394 {
395 scaled = &extra->scaled[i];
396 if (!scaled->bitmap)
397 continue;
398 if (!ComputeScaleFactors(&scaled->vals, vals, &dx, &dy, &sdx, &sdy,
399 &rescale_x))
400 continue;
401 score = 0;
402 dx_amount = dx;
403 dy_amount = dy;
404 SCORE(dy_amount, 10)if (dy_amount >= 1.0) { if (dy_amount == 1.0) score += (16
* 10); else if (dy_amount == 2.0) score += (4 * 10); else score
+= (int)(((double)(3 * 10)) / dy_amount); } else { score += (
int)(((double)(2 * 10)) * dy_amount); }
;
405 SCORE(dx_amount, 1)if (dx_amount >= 1.0) { if (dx_amount == 1.0) score += (16
* 1); else if (dx_amount == 2.0) score += (4 * 1); else score
+= (int)(((double)(3 * 1)) / dx_amount); } else { score += (
int)(((double)(2 * 1)) * dx_amount); }
;
406 if ((score > best_score) ||
407 ((score == best_score) &&
408 ((dy_amount < best_dy_amount) ||
409 ((dy_amount == best_dy_amount) &&
410 (dx_amount < best_dx_amount)))))
411 {
412 best_fpe = FontFileBitmapSources.fpe[source];
413 best_scaled = scaled;
414 best_score = score;
415 best_dx = dx;
416 best_dy = dy;
417 best_sdx = sdx;
418 best_sdy = sdy;
419 best_dx_amount = dx_amount;
420 best_dy_amount = dy_amount;
421 best_rescale_x = rescale_x;
422 }
423 /* Is this font a candidate for use without ugly rescaling? */
424 if (fabs(dx) > EPS1.0e-20 && fabs(dy) > EPS1.0e-20 &&
425 fabs(vals->pixel_matrix[0] * rescale_x -
426 scaled->vals.pixel_matrix[0]) < 1 &&
427 fabs(vals->pixel_matrix[1] * rescale_x -
428 scaled->vals.pixel_matrix[1]) < EPS1.0e-20 &&
429 fabs(vals->pixel_matrix[2] -
430 scaled->vals.pixel_matrix[2]) < EPS1.0e-20 &&
431 fabs(vals->pixel_matrix[3] -
432 scaled->vals.pixel_matrix[3]) < 1)
433 {
434 /* Yes. The pixel sizes are close on the diagonal and
435 extremely close off the diagonal. */
436 score = 0;
437 SCORE2(vals->pixel_matrix[3] /if (vals->pixel_matrix[3] / scaled->vals.pixel_matrix[3
] >= 1.0) score += (int)(((double)(8 * 10)) / vals->pixel_matrix
[3] / scaled->vals.pixel_matrix[3]); else score += (int)((
(double)(8 * 10)) * vals->pixel_matrix[3] / scaled->vals
.pixel_matrix[3]);
438 scaled->vals.pixel_matrix[3], 10)if (vals->pixel_matrix[3] / scaled->vals.pixel_matrix[3
] >= 1.0) score += (int)(((double)(8 * 10)) / vals->pixel_matrix
[3] / scaled->vals.pixel_matrix[3]); else score += (int)((
(double)(8 * 10)) * vals->pixel_matrix[3] / scaled->vals
.pixel_matrix[3]);
;
439 SCORE2(vals->pixel_matrix[0] * rescale_x /if (vals->pixel_matrix[0] * rescale_x / scaled->vals.pixel_matrix
[0] >= 1.0) score += (int)(((double)(8 * 1)) / vals->pixel_matrix
[0] * rescale_x / scaled->vals.pixel_matrix[0]); else score
+= (int)(((double)(8 * 1)) * vals->pixel_matrix[0] * rescale_x
/ scaled->vals.pixel_matrix[0]);
440 scaled->vals.pixel_matrix[0], 1)if (vals->pixel_matrix[0] * rescale_x / scaled->vals.pixel_matrix
[0] >= 1.0) score += (int)(((double)(8 * 1)) / vals->pixel_matrix
[0] * rescale_x / scaled->vals.pixel_matrix[0]); else score
+= (int)(((double)(8 * 1)) * vals->pixel_matrix[0] * rescale_x
/ scaled->vals.pixel_matrix[0]);
;
441 if (score > best_unscaled_score)
442 {
443 best_unscaled_fpe = FontFileBitmapSources.fpe[source];
444 best_unscaled = scaled;
445 best_unscaled_sdx = sdx / dx;
446 best_unscaled_sdy = sdy / dy;
447 best_unscaled_score = score;
448 best_unscaled_rescale_x = rescale_x;
449 }
450 }
451 }
452 }
453 if (best_unscaled)
454 {
455 *best = best_unscaled->vals;
456 *fpep = best_unscaled_fpe;
457 *dxp = 1.0;
458 *dyp = 1.0;
459 *sdxp = best_unscaled_sdx;
460 *sdyp = best_unscaled_sdy;
461 rescale_x = best_unscaled_rescale_x;
462 result = best_unscaled->bitmap;
463 }
464 else if (best_scaled)
465 {
466 *best = best_scaled->vals;
467 *fpep = best_fpe;
468 *dxp = best_dx;
469 *dyp = best_dy;
470 *sdxp = best_sdx;
471 *sdyp = best_sdy;
472 rescale_x = best_rescale_x;
473 result = best_scaled->bitmap;
474 }
475 else
476 result = NULL((void *)0);
477
478 if (bitmap != NULL((void *)0) && (result == NULL((void *)0) || *dxp != 1.0 || *dyp != 1.0))
479 {
480 *fpep = bitmap_fpe;
481 FontParseXLFDName (bitmap->name.name, best, FONT_XLFD_REPLACE_NONE0);
482 if (ComputeScaleFactors(best, best, dxp, dyp, sdxp, sdyp, &rescale_x))
483 result = bitmap;
484 else
485 result = NULL((void *)0);
486 }
487
488 if (result && rescale_x != 1.0)
489 {
490 /* We have rescaled horizontally due to an XLFD width field. Change
491 the matrix appropriately */
492 vals->pixel_matrix[0] *= rescale_x;
493 vals->pixel_matrix[1] *= rescale_x;
494 vals->values_supplied = vals->values_supplied & ~POINTSIZE_MASK0xc;
495 /* Recompute and reround the FontScalablePtr values after
496 rescaling for the new width. */
497 FontFileCompleteXLFD(vals, vals);
498 }
499
500 return result;
501}
502
503static long
504doround(double x)
505{
506 return (x >= 0) ? (long)(x + .5) : (long)(x - .5);
507}
508
509static int
510computeProps(FontPropPtr pf, char *wasStringProp,
511 FontPropPtr npf, char *isStringProp,
512 unsigned int nprops, double xfactor, double yfactor,
513 double sXfactor, double sYfactor)
514{
515 int n;
516 int count;
517 fontProp *t;
518 double rawfactor = 0.0;
519
520 for (count = 0; nprops > 0; nprops--, pf++, wasStringProp++) {
521 n = sizeof(fontPropTable) / sizeof(fontProp);
522 for (t = fontPropTable; n && (t->atom != pf->name); n--, t++);
523 if (!n)
524 continue;
525
526 switch (t->type) {
527 case scaledX:
528 npf->value = doround(xfactor * (double)pf->value);
529 rawfactor = sXfactor;
530 break;
531 case scaledY:
532 npf->value = doround(yfactor * (double)pf->value);
533 rawfactor = sYfactor;
534 break;
535 case unscaled:
536 npf->value = pf->value;
537 npf->name = pf->name;
538 npf++;
539 count++;
540 *isStringProp++ = *wasStringProp;
541 break;
542 default:
543 break;
544 }
545 if (t->type != unscaled)
546 {
547 npf->name = pf->name;
548 npf++;
549 count++;
550 npf->value = doround(rawfactor * (double)pf->value);
551 npf->name = rawFontPropTable[t - fontPropTable].atom;
552 npf++;
553 count++;
554 *isStringProp++ = *wasStringProp;
555 *isStringProp++ = *wasStringProp;
556 }
557 }
558 return count;
559}
560
561
562static int
563ComputeScaledProperties(FontInfoPtr sourceFontInfo, /* the font to be scaled */
564 char *name, /* name of resulting font */
565 FontScalablePtr vals,
566 double dx, double dy, /* scale factors in x and y */
567 double sdx, double sdy, /* directions */
568 long sWidth, /* 1000-pixel average width */
569 FontPropPtr *pProps, /* returns properties;
570 preallocated */
571 char **pIsStringProp) /* return booleans;
572 preallocated */
573{
574 int n;
575 char *ptr1 = NULL((void *)0), *ptr2 = NULL((void *)0);
576 char *ptr3;
577 FontPropPtr fp;
578 fontProp *fpt;
579 char *isStringProp;
580 int nProps;
581
582 if (bitscaleGeneration != __GetServerGeneration()) {
583 initFontPropTable();
584 bitscaleGeneration = __GetServerGeneration();
585 }
586 nProps = NPROPS(sizeof(fontNamePropTable) / sizeof(fontProp)) + 1 + sizeof(fontPropTable) / sizeof(fontProp) +
587 sizeof(rawFontPropTable) / sizeof(fontProp);
588 fp = malloc(sizeof(FontPropRec) * nProps);
589 *pProps = fp;
590 if (!fp) {
591 fprintf(stderr__stderrp, "Error: Couldn't allocate font properties (%ld*%d)\n",
592 (unsigned long)sizeof(FontPropRec), nProps);
593 return 1;
594 }
595 isStringProp = malloc (nProps);
596 *pIsStringProp = isStringProp;
597 if (!isStringProp)
598 {
599 fprintf(stderr__stderrp, "Error: Couldn't allocate isStringProp (%d)\n", nProps);
600 free (fp);
601 return 1;
602 }
603 ptr2 = name;
604 for (fpt = fontNamePropTable, n = NPROPS(sizeof(fontNamePropTable) / sizeof(fontProp));
605 n;
606 fp++, fpt++, n--, isStringProp++)
607 {
608
609 if (*ptr2)
610 {
611 ptr1 = ptr2 + 1;
612 if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0');
613 }
614
615 *isStringProp = 0;
616 switch (fpt->type) {
617 case atom:
618 fp->value = MakeAtom__libxfont__MakeAtom(ptr1, ptr2 - ptr1, TRUE1);
619 *isStringProp = 1;
620 break;
621 case truncate_atom:
622 for (ptr3 = ptr1; *ptr3; ptr3++)
623 if (*ptr3 == '[')
624 break;
625 if (!*ptr3) ptr3 = ptr2;
626 fp->value = MakeAtom__libxfont__MakeAtom(ptr1, ptr3 - ptr1, TRUE1);
627 *isStringProp = 1;
628 break;
629 case pixel_size:
630 fp->value = doround(vals->pixel_matrix[3]);
631 break;
632 case point_size:
633 fp->value = doround(vals->point_matrix[3] * 10.0);
634 break;
635 case resolution_x:
636 fp->value = vals->x;
637 break;
638 case resolution_y:
639 fp->value = vals->y;
640 break;
641 case average_width:
642 fp->value = vals->width;
643 break;
644 case fontname:
645 fp->value = MakeAtom__libxfont__MakeAtom(name, strlen(name), TRUE1);
646 *isStringProp = 1;
647 break;
648 case raw_ascent:
649 fp->value = sourceFontInfo->fontAscent * sdy;
650 break;
651 case raw_descent:
652 fp->value = sourceFontInfo->fontDescent * sdy;
653 break;
654 case raw_pointsize:
655 fp->value = (long)(72270.0 / (double)vals->y + .5);
656 break;
657 case raw_pixelsize:
658 fp->value = 1000;
659 break;
660 case raw_average_width:
661 fp->value = sWidth;
662 break;
663 default:
664 break;
665 }
666 fp->name = fpt->atom;
667 }
668 n = NPROPS(sizeof(fontNamePropTable) / sizeof(fontProp));
669 n += computeProps(sourceFontInfo->props, sourceFontInfo->isStringProp,
670 fp, isStringProp, sourceFontInfo->nprops, dx, dy,
671 sdx, sdy);
672 return n;
673}
674
675
676static int
677compute_xform_matrix(FontScalablePtr vals, double dx, double dy,
678 double *xform, double *inv_xform,
679 double *xmult, double *ymult)
680{
681 double det;
682 double pixel = get_matrix_vertical_component(vals->pixel_matrix);
683 double pixelset = get_matrix_horizontal_component(vals->pixel_matrix);
684
685 if (pixel < EPS1.0e-20 || pixelset < EPS1.0e-20) return 0;
686
687 /* Initialize the transformation matrix to the scaling factors */
688 xform[0] = dx / pixelset;
689 xform[1] = xform[2] = 0.0;
690 xform[3] = dy / pixel;
691
692/* Inline matrix multiply -- somewhat ugly to minimize register usage */
693#define MULTIPLY_XFORM(a,b,c,d){ register double aa = (a), bb = (b), cc = (c), dd = (d); register
double temp; temp = aa * xform[0] + cc * xform[1]; aa = aa *
xform[2] + cc * xform[3]; xform[1] = bb * xform[0] + dd * xform
[1]; xform[3] = bb * xform[2] + dd * xform[3]; xform[0] = temp
; xform[2] = aa; }
\
694{ \
695 register double aa = (a), bb = (b), cc = (c), dd = (d); \
696 register double temp; \
697 temp = aa * xform[0] + cc * xform[1]; \
698 aa = aa * xform[2] + cc * xform[3]; \
699 xform[1] = bb * xform[0] + dd * xform[1]; \
700 xform[3] = bb * xform[2] + dd * xform[3]; \
701 xform[0] = temp; \
702 xform[2] = aa; \
703}
704
705 /* Rescale the transformation matrix for size of source font */
706 MULTIPLY_XFORM(vals->pixel_matrix[0],{ register double aa = (vals->pixel_matrix[0]), bb = (vals
->pixel_matrix[1]), cc = (vals->pixel_matrix[2]), dd = (
vals->pixel_matrix[3]); register double temp; temp = aa * xform
[0] + cc * xform[1]; aa = aa * xform[2] + cc * xform[3]; xform
[1] = bb * xform[0] + dd * xform[1]; xform[3] = bb * xform[2]
+ dd * xform[3]; xform[0] = temp; xform[2] = aa; }
707 vals->pixel_matrix[1],{ register double aa = (vals->pixel_matrix[0]), bb = (vals
->pixel_matrix[1]), cc = (vals->pixel_matrix[2]), dd = (
vals->pixel_matrix[3]); register double temp; temp = aa * xform
[0] + cc * xform[1]; aa = aa * xform[2] + cc * xform[3]; xform
[1] = bb * xform[0] + dd * xform[1]; xform[3] = bb * xform[2]
+ dd * xform[3]; xform[0] = temp; xform[2] = aa; }
708 vals->pixel_matrix[2],{ register double aa = (vals->pixel_matrix[0]), bb = (vals
->pixel_matrix[1]), cc = (vals->pixel_matrix[2]), dd = (
vals->pixel_matrix[3]); register double temp; temp = aa * xform
[0] + cc * xform[1]; aa = aa * xform[2] + cc * xform[3]; xform
[1] = bb * xform[0] + dd * xform[1]; xform[3] = bb * xform[2]
+ dd * xform[3]; xform[0] = temp; xform[2] = aa; }
709 vals->pixel_matrix[3]){ register double aa = (vals->pixel_matrix[0]), bb = (vals
->pixel_matrix[1]), cc = (vals->pixel_matrix[2]), dd = (
vals->pixel_matrix[3]); register double temp; temp = aa * xform
[0] + cc * xform[1]; aa = aa * xform[2] + cc * xform[3]; xform
[1] = bb * xform[0] + dd * xform[1]; xform[3] = bb * xform[2]
+ dd * xform[3]; xform[0] = temp; xform[2] = aa; }
;
710
711 *xmult = xform[0];
712 *ymult = xform[3];
713
714
715 if (inv_xform == NULL((void *)0)) return 1;
716
717 /* Compute the determinant for use in inverting the matrix. */
718 det = xform[0] * xform[3] - xform[1] * xform[2];
719
720 /* If the determinant is tiny or zero, give up */
721 if (fabs(det) < EPS1.0e-20) return 0;
722
723 /* Compute the inverse */
724 inv_xform[0] = xform[3] / det;
725 inv_xform[1] = -xform[1] / det;
726 inv_xform[2] = -xform[2] / det;
727 inv_xform[3] = xform[0] / det;
728
729 return 1;
730}
731
732/*
733 * ScaleFont
734 * returns a pointer to the new scaled font, or NULL (due to AllocError).
735 */
736#pragma GCC diagnostic ignored "-Wbad-function-cast"
737
738static FontPtr
739ScaleFont(FontPtr opf, /* originating font */
740 double widthMult, /* glyphs width scale factor */
741 double heightMult, /* glyphs height scale factor */
742 double sWidthMult, /* scalable glyphs width scale factor */
743 double sHeightMult, /* scalable glyphs height scale factor */
744 FontScalablePtr vals,
745 double *newWidthMult, /* return: X component of glyphs width
746 scale factor */
747 double *newHeightMult, /* return: Y component of glyphs height
748 scale factor */
749 long *sWidth) /* return: average 1000-pixel width */
750{
751 FontPtr pf;
752 FontInfoPtr pfi,
753 opfi;
754 BitmapFontPtr bitmapFont,
755 obitmapFont;
756 CharInfoPtr pci,
757 opci;
758 int nchars = 0; /* how many characters in the font */
759 int i;
760 int firstCol, lastCol, firstRow, lastRow;
761 double xform[4], inv_xform[4];
762 double xmult, ymult;
763 int totalwidth = 0, totalchars = 0;
764#define OLDINDEX(i)(((i)/(lastCol - firstCol + 1) + firstRow - opf->info.firstRow
) * (opf->info.lastCol - opf->info.firstCol + 1) + (i)%
(lastCol - firstCol + 1) + firstCol - opf->info.firstCol)
(((i)/(lastCol - firstCol + 1) + \
765 firstRow - opf->info.firstRow) * \
766 (opf->info.lastCol - opf->info.firstCol + 1) + \
767 (i)%(lastCol - firstCol + 1) + \
768 firstCol - opf->info.firstCol)
769
770 *sWidth = 0;
771
772 opfi = &opf->info;
773 obitmapFont = (BitmapFontPtr) opf->fontPrivate;
774
775 bitmapFont = 0;
776 if (!(pf = CreateFontRec())) {
777 fprintf(stderr__stderrp, "Error: Couldn't allocate FontRec (%ld)\n",
778 (unsigned long)sizeof(FontRec));
779 goto bail;
780 }
781 pf->refcnt = 0;
782 pf->bit = opf->bit;
783 pf->byte = opf->byte;
784 pf->glyph = opf->glyph;
785 pf->scan = opf->scan;
786
787 pf->get_glyphs = bitmapGetGlyphs;
788 pf->get_metrics = bitmapGetMetrics;
789 pf->unload_font = bitmapUnloadScalable;
790 pf->unload_glyphs = NULL((void *)0);
791
792 pfi = &pf->info;
793 *pfi = *opfi;
794 /* If charset subsetting specified in vals, determine what our range
795 needs to be for the output font */
796 if (vals->nranges)
797 {
798 pfi->allExist = 0;
799 firstCol = 255;
800 lastCol = 0;
801 firstRow = 255;
802 lastRow = 0;
803
804 for (i = 0; i < vals->nranges; i++)
805 {
806 if (vals->ranges[i].min_char_high != vals->ranges[i].max_char_high)
807 {
808 firstCol = opfi->firstCol;
809 lastCol = opfi->lastCol;
810 }
811 if (firstCol > vals->ranges[i].min_char_low)
812 firstCol = vals->ranges[i].min_char_low;
813 if (lastCol < vals->ranges[i].max_char_low)
814 lastCol = vals->ranges[i].max_char_low;
815 if (firstRow > vals->ranges[i].min_char_high)
816 firstRow = vals->ranges[i].min_char_high;
817 if (lastRow < vals->ranges[i].max_char_high)
818 lastRow = vals->ranges[i].max_char_high;
819 }
820
821 if (firstCol > lastCol || firstRow > lastRow)
822 goto bail;
823
824 if (firstCol < opfi->firstCol)
825 firstCol = opfi->firstCol;
826 if (lastCol > opfi->lastCol)
827 lastCol = opfi->lastCol;
828 if (firstRow < opfi->firstRow)
829 firstRow = opfi->firstRow;
830 if (lastRow > opfi->lastRow)
831 lastRow = opfi->lastRow;
832 }
833 else
834 {
835 firstCol = opfi->firstCol;
836 lastCol = opfi->lastCol;
837 firstRow = opfi->firstRow;
838 lastRow = opfi->lastRow;
839 }
840
841 bitmapFont = malloc(sizeof(BitmapFontRec));
842 if (!bitmapFont) {
843 fprintf(stderr__stderrp, "Error: Couldn't allocate bitmapFont (%ld)\n",
844 (unsigned long)sizeof(BitmapFontRec));
845 goto bail;
846 }
847 nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1);
848 pfi->firstRow = firstRow;
849 pfi->lastRow = lastRow;
850 pfi->firstCol = firstCol;
851 pfi->lastCol = lastCol;
852 pf->fontPrivate = (pointer) bitmapFont;
853 bitmapFont->version_num = obitmapFont->version_num;
854 bitmapFont->num_chars = nchars;
855 bitmapFont->num_tables = obitmapFont->num_tables;
856 bitmapFont->metrics = 0;
857 bitmapFont->ink_metrics = 0;
858 bitmapFont->bitmaps = 0;
859 bitmapFont->encoding = 0;
860 bitmapFont->bitmapExtra = 0;
861 bitmapFont->pDefault = 0;
862 bitmapFont->metrics = malloc(nchars * sizeof(CharInfoRec));
863 if (!bitmapFont->metrics) {
864 fprintf(stderr__stderrp, "Error: Couldn't allocate metrics (%d*%ld)\n",
865 nchars, (unsigned long)sizeof(CharInfoRec));
866 goto bail;
867 }
868 bitmapFont->encoding = calloc(NUM_SEGMENTS(nchars)(((nchars)+128 -1)/128), sizeof(CharInfoPtr*));
869 if (!bitmapFont->encoding) {
870 fprintf(stderr__stderrp, "Error: Couldn't allocate encoding (%d*%ld)\n",
871 nchars, (unsigned long)sizeof(CharInfoPtr));
872 goto bail;
873 }
874
875#undef MAXSHORT32767
876#define MAXSHORT32767 32767
877#undef MINSHORT-32768
878#define MINSHORT-32768 -32768
879
880 pfi->anamorphic = FALSE0;
881 if (heightMult != widthMult)
882 pfi->anamorphic = TRUE1;
883 pfi->cachable = TRUE1;
884
885 if (!compute_xform_matrix(vals, widthMult, heightMult, xform,
886 inv_xform, &xmult, &ymult))
887 goto bail;
888
889 pfi->fontAscent = opfi->fontAscent * ymult;
890 pfi->fontDescent = opfi->fontDescent * ymult;
891
892 pfi->minbounds.leftSideBearing = MAXSHORT32767;
893 pfi->minbounds.rightSideBearing = MAXSHORT32767;
894 pfi->minbounds.ascent = MAXSHORT32767;
895 pfi->minbounds.descent = MAXSHORT32767;
896 pfi->minbounds.characterWidth = MAXSHORT32767;
897 pfi->minbounds.attributes = MAXSHORT32767;
898
899 pfi->maxbounds.leftSideBearing = MINSHORT-32768;
900 pfi->maxbounds.rightSideBearing = MINSHORT-32768;
901 pfi->maxbounds.ascent = MINSHORT-32768;
902 pfi->maxbounds.descent = MINSHORT-32768;
903 pfi->maxbounds.characterWidth = MINSHORT-32768;
904 pfi->maxbounds.attributes = MINSHORT-32768;
905
906 /* Compute the transformation and inverse transformation matrices.
907 Can fail if the determinant is zero. */
908
909 pci = bitmapFont->metrics;
910 for (i = 0; i < nchars; i++)
911 {
912 if ((opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i))(obitmapFont->encoding[((((i)/(lastCol - firstCol + 1) + firstRow
- opf->info.firstRow) * (opf->info.lastCol - opf->info
.firstCol + 1) + (i)%(lastCol - firstCol + 1) + firstCol - opf
->info.firstCol))/128]?(obitmapFont->encoding[((((i)/(lastCol
- firstCol + 1) + firstRow - opf->info.firstRow) * (opf->
info.lastCol - opf->info.firstCol + 1) + (i)%(lastCol - firstCol
+ 1) + firstCol - opf->info.firstCol))/128][((((i)/(lastCol
- firstCol + 1) + firstRow - opf->info.firstRow) * (opf->
info.lastCol - opf->info.firstCol + 1) + (i)%(lastCol - firstCol
+ 1) + firstCol - opf->info.firstCol))%128]):0)
))
913 {
914 double newlsb, newrsb, newdesc, newasc, point[2];
915
916#define minchar(p)((p).min_char_low + ((p).min_char_high << 8)) ((p).min_char_low + ((p).min_char_high << 8))
917#define maxchar(p)((p).max_char_low + ((p).max_char_high << 8)) ((p).max_char_low + ((p).max_char_high << 8))
918
919 if (vals->nranges)
920 {
921 int row = i / (lastCol - firstCol + 1) + firstRow;
922 int col = i % (lastCol - firstCol + 1) + firstCol;
923 int ch = (row << 8) + col;
924 int j;
925 for (j = 0; j < vals->nranges; j++)
926 if (ch >= minchar(vals->ranges[j])((vals->ranges[j]).min_char_low + ((vals->ranges[j]).min_char_high
<< 8))
&&
927 ch <= maxchar(vals->ranges[j])((vals->ranges[j]).max_char_low + ((vals->ranges[j]).max_char_high
<< 8))
)
928 break;
929 if (j == vals->nranges)
930 {
931 continue;
932 }
933 }
934
935 if (opci->metrics.leftSideBearing == 0 &&
936 opci->metrics.rightSideBearing == 0 &&
937 opci->metrics.ascent == 0 &&
938 opci->metrics.descent == 0 &&
939 opci->metrics.characterWidth == 0)
940 {
941 continue;
942 }
943
944 if(!bitmapFont->encoding[SEGMENT_MAJOR(i)((i)/128)]) {
945 bitmapFont->encoding[SEGMENT_MAJOR(i)((i)/128)]=
946 calloc(BITMAP_FONT_SEGMENT_SIZE128, sizeof(CharInfoPtr));
947 if(!bitmapFont->encoding[SEGMENT_MAJOR(i)((i)/128)])
948 goto bail;
949 }
950 ACCESSENCODINGL(bitmapFont->encoding, i)(bitmapFont->encoding[(i)/128][(i)%128]) = pci;
951
952 /* Compute new extents for this glyph */
953 TRANSFORM_POINT(xform,((point)[0] = (xform)[0] * (opci->metrics.leftSideBearing)
+ (xform)[2] * (-opci->metrics.descent), (point)[1] = (xform
)[1] * (opci->metrics.leftSideBearing) + (xform)[3] * (-opci
->metrics.descent))
954 opci->metrics.leftSideBearing,((point)[0] = (xform)[0] * (opci->metrics.leftSideBearing)
+ (xform)[2] * (-opci->metrics.descent), (point)[1] = (xform
)[1] * (opci->metrics.leftSideBearing) + (xform)[3] * (-opci
->metrics.descent))
955 -opci->metrics.descent,((point)[0] = (xform)[0] * (opci->metrics.leftSideBearing)
+ (xform)[2] * (-opci->metrics.descent), (point)[1] = (xform
)[1] * (opci->metrics.leftSideBearing) + (xform)[3] * (-opci
->metrics.descent))
956 point)((point)[0] = (xform)[0] * (opci->metrics.leftSideBearing)
+ (xform)[2] * (-opci->metrics.descent), (point)[1] = (xform
)[1] * (opci->metrics.leftSideBearing) + (xform)[3] * (-opci
->metrics.descent))
;
957 newlsb = point[0];
958 newrsb = newlsb;
959 newdesc = -point[1];
960 newasc = -newdesc;
961 TRANSFORM_POINT(xform,((point)[0] = (xform)[0] * (opci->metrics.leftSideBearing)
+ (xform)[2] * (opci->metrics.ascent), (point)[1] = (xform
)[1] * (opci->metrics.leftSideBearing) + (xform)[3] * (opci
->metrics.ascent))
962 opci->metrics.leftSideBearing,((point)[0] = (xform)[0] * (opci->metrics.leftSideBearing)
+ (xform)[2] * (opci->metrics.ascent), (point)[1] = (xform
)[1] * (opci->metrics.leftSideBearing) + (xform)[3] * (opci
->metrics.ascent))
963 opci->metrics.ascent,((point)[0] = (xform)[0] * (opci->metrics.leftSideBearing)
+ (xform)[2] * (opci->metrics.ascent), (point)[1] = (xform
)[1] * (opci->metrics.leftSideBearing) + (xform)[3] * (opci
->metrics.ascent))
964 point)((point)[0] = (xform)[0] * (opci->metrics.leftSideBearing)
+ (xform)[2] * (opci->metrics.ascent), (point)[1] = (xform
)[1] * (opci->metrics.leftSideBearing) + (xform)[3] * (opci
->metrics.ascent))
;
965 CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point)((newlsb) > (point)[0] ? (newlsb) = (point)[0] : 0 , (newrsb
) < (point)[0] ? (newrsb) = (point)[0] : 0, (-newdesc) >
(point)[1] ? (newdesc) = -(point)[1] : 0 , (newasc) < (point
)[1] ? (newasc) = (point)[1] : 0)
;
966 TRANSFORM_POINT(xform,((point)[0] = (xform)[0] * (opci->metrics.rightSideBearing
) + (xform)[2] * (-opci->metrics.descent), (point)[1] = (xform
)[1] * (opci->metrics.rightSideBearing) + (xform)[3] * (-opci
->metrics.descent))
967 opci->metrics.rightSideBearing,((point)[0] = (xform)[0] * (opci->metrics.rightSideBearing
) + (xform)[2] * (-opci->metrics.descent), (point)[1] = (xform
)[1] * (opci->metrics.rightSideBearing) + (xform)[3] * (-opci
->metrics.descent))
968 -opci->metrics.descent,((point)[0] = (xform)[0] * (opci->metrics.rightSideBearing
) + (xform)[2] * (-opci->metrics.descent), (point)[1] = (xform
)[1] * (opci->metrics.rightSideBearing) + (xform)[3] * (-opci
->metrics.descent))
969 point)((point)[0] = (xform)[0] * (opci->metrics.rightSideBearing
) + (xform)[2] * (-opci->metrics.descent), (point)[1] = (xform
)[1] * (opci->metrics.rightSideBearing) + (xform)[3] * (-opci
->metrics.descent))
;
970 CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point)((newlsb) > (point)[0] ? (newlsb) = (point)[0] : 0 , (newrsb
) < (point)[0] ? (newrsb) = (point)[0] : 0, (-newdesc) >
(point)[1] ? (newdesc) = -(point)[1] : 0 , (newasc) < (point
)[1] ? (newasc) = (point)[1] : 0)
;
971 TRANSFORM_POINT(xform,((point)[0] = (xform)[0] * (opci->metrics.rightSideBearing
) + (xform)[2] * (opci->metrics.ascent), (point)[1] = (xform
)[1] * (opci->metrics.rightSideBearing) + (xform)[3] * (opci
->metrics.ascent))
972 opci->metrics.rightSideBearing,((point)[0] = (xform)[0] * (opci->metrics.rightSideBearing
) + (xform)[2] * (opci->metrics.ascent), (point)[1] = (xform
)[1] * (opci->metrics.rightSideBearing) + (xform)[3] * (opci
->metrics.ascent))
973 opci->metrics.ascent,((point)[0] = (xform)[0] * (opci->metrics.rightSideBearing
) + (xform)[2] * (opci->metrics.ascent), (point)[1] = (xform
)[1] * (opci->metrics.rightSideBearing) + (xform)[3] * (opci
->metrics.ascent))
974 point)((point)[0] = (xform)[0] * (opci->metrics.rightSideBearing
) + (xform)[2] * (opci->metrics.ascent), (point)[1] = (xform
)[1] * (opci->metrics.rightSideBearing) + (xform)[3] * (opci
->metrics.ascent))
;
975 CHECK_EXTENT(newlsb, newrsb, newdesc, newasc, point)((newlsb) > (point)[0] ? (newlsb) = (point)[0] : 0 , (newrsb
) < (point)[0] ? (newrsb) = (point)[0] : 0, (-newdesc) >
(point)[1] ? (newdesc) = -(point)[1] : 0 , (newasc) < (point
)[1] ? (newasc) = (point)[1] : 0)
;
976
977 pci->metrics.leftSideBearing = (int)floor(newlsb);
978 pci->metrics.rightSideBearing = (int)floor(newrsb + .5);
979 pci->metrics.descent = (int)ceil(newdesc);
980 pci->metrics.ascent = (int)floor(newasc + .5);
981 /* Accumulate total width of characters before transformation,
982 to ascertain predominant direction of font. */
983 totalwidth += opci->metrics.characterWidth;
984 pci->metrics.characterWidth =
985 doround((double)opci->metrics.characterWidth * xmult);
986 pci->metrics.attributes =
987 doround((double)opci->metrics.characterWidth * sWidthMult);
988 if (!pci->metrics.characterWidth)
989 {
990 /* Since transformation may shrink width, height, and
991 escapement to zero, make sure existing characters
992 are not mistaken for undefined characters. */
993
994 if (pci->metrics.rightSideBearing ==
995 pci->metrics.leftSideBearing)
996 pci->metrics.rightSideBearing++;
997 if (pci->metrics.ascent == -pci->metrics.descent)
998 pci->metrics.ascent++;
999 }
1000
1001 pci++;
1002 }
1003 }
1004
1005
1006 /*
1007 * For each character, set the per-character metrics, scale the glyph, and
1008 * check per-font minbounds and maxbounds character information.
1009 */
1010
1011 pci = bitmapFont->metrics;
Value stored to 'pci' is never read
1012 for (i = 0; i < nchars; i++)
1013 {
1014 if ((pci = ACCESSENCODING(bitmapFont->encoding,i)(bitmapFont->encoding[(i)/128]?(bitmapFont->encoding[(i
)/128][(i)%128]):0)
) &&
1015 (opci = ACCESSENCODING(obitmapFont->encoding,OLDINDEX(i))(obitmapFont->encoding[((((i)/(lastCol - firstCol + 1) + firstRow
- opf->info.firstRow) * (opf->info.lastCol - opf->info
.firstCol + 1) + (i)%(lastCol - firstCol + 1) + firstCol - opf
->info.firstCol))/128]?(obitmapFont->encoding[((((i)/(lastCol
- firstCol + 1) + firstRow - opf->info.firstRow) * (opf->
info.lastCol - opf->info.firstCol + 1) + (i)%(lastCol - firstCol
+ 1) + firstCol - opf->info.firstCol))/128][((((i)/(lastCol
- firstCol + 1) + firstRow - opf->info.firstRow) * (opf->
info.lastCol - opf->info.firstCol + 1) + (i)%(lastCol - firstCol
+ 1) + firstCol - opf->info.firstCol))%128]):0)
))
1016 {
1017 totalchars++;
1018 *sWidth += abs((int)(INT16)pci->metrics.attributes);
1019#define MINMAX(field) \
1020 if (pfi->minbounds.field > pci->metrics.field) \
1021 pfi->minbounds.field = pci->metrics.field; \
1022 if (pfi->maxbounds.field < pci->metrics.field) \
1023 pfi->maxbounds.field = pci->metrics.field
1024
1025 MINMAX(leftSideBearing);
1026 MINMAX(rightSideBearing);
1027 MINMAX(ascent);
1028 MINMAX(descent);
1029 MINMAX(characterWidth);
1030
1031 /* Hack: Cast attributes into a signed quantity. Tread lightly
1032 for now and don't go changing the global Xproto.h file */
1033 if ((INT16)pfi->minbounds.attributes >
1034 (INT16)pci->metrics.attributes)
1035 pfi->minbounds.attributes = pci->metrics.attributes;
1036 if ((INT16)pfi->maxbounds.attributes <
1037 (INT16)pci->metrics.attributes)
1038 pfi->maxbounds.attributes = pci->metrics.attributes;
1039#undef MINMAX
1040 }
1041 }
1042 pfi->ink_minbounds = pfi->minbounds;
1043 pfi->ink_maxbounds = pfi->maxbounds;
1044 if (totalchars)
1045 {
1046 *sWidth = (*sWidth * 10 + totalchars / 2) / totalchars;
1047 if (totalwidth < 0)
1048 {
1049 /* Dominant direction is R->L */
1050 *sWidth = -*sWidth;
1051 }
1052
1053 if (pfi->minbounds.characterWidth == pfi->maxbounds.characterWidth)
1054 vals->width = pfi->minbounds.characterWidth * 10;
1055 else
1056 vals->width = doround((double)*sWidth * vals->pixel_matrix[0] /
1057 1000.0);
1058 }
1059 else
1060 {
1061 vals->width = 0;
1062 *sWidth = 0;
1063 }
1064 FontComputeInfoAccelerators (pfi);
1065
1066 if (pfi->defaultCh != (unsigned short) NO_SUCH_CHAR-1) {
1067 unsigned int r,
1068 c,
1069 cols;
1070
1071 r = pfi->defaultCh >> 8;
1072 c = pfi->defaultCh & 0xFF;
1073 if (pfi->firstRow <= r && r <= pfi->lastRow &&
1074 pfi->firstCol <= c && c <= pfi->lastCol) {
1075 cols = pfi->lastCol - pfi->firstCol + 1;
1076 r = r - pfi->firstRow;
1077 c = c - pfi->firstCol;
1078 bitmapFont->pDefault =
1079 ACCESSENCODING(bitmapFont->encoding, r * cols + c)(bitmapFont->encoding[(r * cols + c)/128]?(bitmapFont->
encoding[(r * cols + c)/128][(r * cols + c)%128]):0)
;
1080 }
1081 }
1082
1083 *newWidthMult = xmult;
1084 *newHeightMult = ymult;
1085 return pf;
1086bail:
1087 if (pf)
1088 free(pf);
1089 if (bitmapFont) {
1090 free(bitmapFont->metrics);
1091 free(bitmapFont->ink_metrics);
1092 free(bitmapFont->bitmaps);
1093 if(bitmapFont->encoding)
1094 for(i=0; i<NUM_SEGMENTS(nchars)(((nchars)+128 -1)/128); i++)
1095 free(bitmapFont->encoding[i]);
1096 free(bitmapFont->encoding);
1097 }
1098 return NULL((void *)0);
1099}
1100
1101static void
1102ScaleBitmap(FontPtr pFont, CharInfoPtr opci, CharInfoPtr pci,
1103 double *inv_xform, double widthMult, double heightMult)
1104{
1105 register char *bitmap, /* The bits */
1106 *newBitmap;
1107 register int bpr, /* Padding information */
1108 newBpr;
1109 int width, /* Extents information */
1110 height,
1111 newWidth,
1112 newHeight;
1113 register int row, /* Loop variables */
1114 col;
1115 INT32 deltaX, /* Increments for resampling loop */
1116 deltaY;
1117 INT32 xValue, /* Subscripts for resampling loop */
1118 yValue;
1119 double point[2];
1120 unsigned char *char_grayscale = 0;
1121 INT32 *diffusion_workspace = NULL((void *)0), *thisrow = NULL((void *)0),
1122 *nextrow = NULL((void *)0), pixmult = 0;
1123 int box_x = 0, box_y = 0;
1124
1125 static unsigned char masklsb[] =
1126 { 0x1, 0x2, 0x4, 0x8, 0x10, 0x20, 0x40, 0x80 };
1127 static unsigned char maskmsb[] =
1128 { 0x80, 0x40, 0x20, 0x10, 0x8, 0x4, 0x2, 0x1 };
1129 unsigned char *mask = (pFont->bit == LSBFirst0 ? masklsb : maskmsb);
1130
1131
1132 bitmap = opci->bits;
1133 newBitmap = pci->bits;
1134 width = GLYPHWIDTHPIXELS(opci)((opci)->metrics.rightSideBearing - (opci)->metrics.leftSideBearing
)
;
1135 height = GLYPHHEIGHTPIXELS(opci)((opci)->metrics.ascent + (opci)->metrics.descent);
1136 newWidth = GLYPHWIDTHPIXELS(pci)((pci)->metrics.rightSideBearing - (pci)->metrics.leftSideBearing
)
;
1137 newHeight = GLYPHHEIGHTPIXELS(pci)((pci)->metrics.ascent + (pci)->metrics.descent);
1138 if (!newWidth || !newHeight || !width || !height)
1139 return;
1140
1141 bpr = BYTES_PER_ROW(width, pFont->glyph)((pFont->glyph) == 1 ? (((width)+7)>>3) :(pFont->
glyph) == 2 ? ((((width)+15)>>3)&~1) :(pFont->glyph
) == 4 ? ((((width)+31)>>3)&~3) :(pFont->glyph) ==
8 ? ((((width)+63)>>3)&~7) : 0)
;
1142 newBpr = BYTES_PER_ROW(newWidth, pFont->glyph)((pFont->glyph) == 1 ? (((newWidth)+7)>>3) :(pFont->
glyph) == 2 ? ((((newWidth)+15)>>3)&~1) :(pFont->
glyph) == 4 ? ((((newWidth)+31)>>3)&~3) :(pFont->
glyph) == 8 ? ((((newWidth)+63)>>3)&~7) : 0)
;
1143
1144 if (widthMult > 0.0 && heightMult > 0.0 &&
1145 (widthMult < 1.0 || heightMult < 1.0))
1146 {
1147 /* We are reducing in one or both dimensions. In an attempt to
1148 reduce aliasing, we'll antialias by passing the original
1149 glyph through a low-pass box filter (which results in a
1150 grayscale image), then use error diffusion to create bitonal
1151 output in the resampling loop. */
1152
1153 /* First compute the sizes of the box filter */
1154 widthMult = ceil(1.0 / widthMult);
1155 heightMult = ceil(1.0 / heightMult);
1156 box_x = width / 2;
1157 box_y = height / 2;
1158 if (widthMult < (double)box_x) box_x = (int)widthMult;
1159 if (heightMult < (double)box_y) box_y = (int)heightMult;
1160 /* The pixmult value (below) is used to darken the image before
1161 we perform error diffusion: a necessary concession to the
1162 fact that it's very difficult to generate readable halftoned
1163 glyphs. The degree of darkening is proportional to the size
1164 of the blurring filter, hence inversely proportional to the
1165 darkness of the lightest gray that results from antialiasing.
1166 The result is that characters that exercise this logic (those
1167 generated by reducing from a larger source font) tend to err
1168 on the side of being too bold instead of being too light to
1169 be readable. */
1170 pixmult = box_x * box_y * 192;
1171
1172 if (box_x > 1 || box_y > 1)
1173 {
1174 /* Looks like we need to anti-alias. Create a workspace to
1175 contain the grayscale character plus an additional row and
1176 column for scratch */
1177 char_grayscale = malloc((width + 1) * (height + 1));
1178 if (char_grayscale)
1179 {
1180 diffusion_workspace = calloc((newWidth + 2) * 2, sizeof(int));
1181 if (!diffusion_workspace)
1182 {
1183 fprintf(stderr__stderrp, "Warning: Couldn't allocate diffusion"
1184 " workspace (%ld)\n",
1185 (newWidth + 2) * 2 * (unsigned long)sizeof(int));
1186 free(char_grayscale);
1187 char_grayscale = (unsigned char *)0;
1188 }
1189 /* Initialize our error diffusion workspace for later use */
1190 thisrow = diffusion_workspace + 1;
1191 nextrow = diffusion_workspace + newWidth + 3;
1192 } else {
1193 fprintf(stderr__stderrp, "Warning: Couldn't allocate character grayscale (%d)\n", (width + 1) * (height + 1));
1194 }
1195 }
1196 }
1197
1198 if (char_grayscale)
1199 {
1200 /* We will be doing antialiasing. First copy the bitmap into
1201 our buffer, mapping input range [0,1] to output range
1202 [0,255]. */
1203 register unsigned char *srcptr, *dstptr;
1204 srcptr = (unsigned char *)bitmap;
1205 dstptr = char_grayscale;
1206 for (row = 0; row < height; row++)
1207 {
1208 for (col = 0; col < width; col++)
1209 *dstptr++ = (srcptr[col >> 3] & mask[col & 0x7]) ? 255 : 0;
1210 srcptr += bpr; /* On to next row of source */
1211 dstptr++; /* Skip scratch column in dest */
1212 }
1213 if (box_x > 1)
1214 {
1215 /* Our box filter has a width > 1... let's filter the rows */
1216
1217 int right_width = box_x / 2;
1218 int left_width = box_x - right_width - 1;
1219
1220 for (row = 0; row < height; row++)
1221 {
1222 int sum = 0;
1223 int left_size = 0, right_size = 0;
1224
1225 srcptr = char_grayscale + (width + 1) * row;
1226 dstptr = char_grayscale + (width + 1) * height; /* scratch */
1227
1228 /* We've computed the shape of our full box filter. Now
1229 compute the right-hand part of the moving sum */
1230 for (right_size = 0; right_size < right_width; right_size++)
1231 sum += srcptr[right_size];
1232
1233 /* Now start moving the sum, growing the box filter, and
1234 dropping averages into our scratch buffer */
1235 for (left_size = 0; left_size < left_width; left_size++)
1236 {
1237 sum += srcptr[right_width];
1238 *dstptr++ = sum / (left_size + right_width + 1);
1239 srcptr++;
1240 }
1241
1242 /* The box filter has reached full width... continue
1243 computation of moving average until the right side
1244 hits the wall. */
1245 for (col = left_size; col + right_size < width; col++)
1246 {
1247 sum += srcptr[right_width];
1248 *dstptr++ = sum / box_x;
1249 sum -= srcptr[-left_width];
1250 srcptr++;
1251 }
1252
1253 /* Collapse the right side of the box filter */
1254 for (; right_size > 0; right_size--)
1255 {
1256 *dstptr++ = sum / (left_width + right_size);
1257 sum -= srcptr[-left_width];
1258 srcptr++;
1259 }
1260
1261 /* Done with the row... copy dest back over source */
1262 memmove(char_grayscale + (width + 1) * row,__builtin___memmove_chk (char_grayscale + (width + 1) * row, char_grayscale
+ (width + 1) * height, width, __builtin_object_size (char_grayscale
+ (width + 1) * row, 0))
1263 char_grayscale + (width + 1) * height,__builtin___memmove_chk (char_grayscale + (width + 1) * row, char_grayscale
+ (width + 1) * height, width, __builtin_object_size (char_grayscale
+ (width + 1) * row, 0))
1264 width)__builtin___memmove_chk (char_grayscale + (width + 1) * row, char_grayscale
+ (width + 1) * height, width, __builtin_object_size (char_grayscale
+ (width + 1) * row, 0))
;
1265 }
1266 }
1267 if (box_y > 1)
1268 {
1269 /* Our box filter has a height > 1... let's filter the columns */
1270
1271 int bottom_height = box_y / 2;
1272 int top_height = box_y - bottom_height - 1;
1273
1274 for (col = 0; col < width; col++)
1275 {
1276 int sum = 0;
1277 int top_size = 0, bottom_size = 0;
1278
1279 srcptr = char_grayscale + col;
1280 dstptr = char_grayscale + width; /* scratch */
1281
1282 /* We've computed the shape of our full box filter. Now
1283 compute the bottom part of the moving sum */
1284 for (bottom_size = 0;
1285 bottom_size < bottom_height;
1286 bottom_size++)
1287 sum += srcptr[bottom_size * (width + 1)];
1288
1289 /* Now start moving the sum, growing the box filter, and
1290 dropping averages into our scratch buffer */
1291 for (top_size = 0; top_size < top_height; top_size++)
1292 {
1293 sum += srcptr[bottom_height * (width + 1)];
1294 *dstptr = sum / (top_size + bottom_height + 1);
1295 dstptr += width + 1;
1296 srcptr += width + 1;
1297 }
1298
1299 /* The box filter has reached full height... continue
1300 computation of moving average until the bottom
1301 hits the wall. */
1302 for (row = top_size; row + bottom_size < height; row++)
1303 {
1304 sum += srcptr[bottom_height * (width + 1)];
1305 *dstptr = sum / box_y;
1306 dstptr += width + 1;
1307 sum -= srcptr[-top_height * (width + 1)];
1308 srcptr += width + 1;
1309 }
1310
1311 /* Collapse the bottom of the box filter */
1312 for (; bottom_size > 0; bottom_size--)
1313 {
1314 *dstptr = sum / (top_height + bottom_size);
1315 dstptr += width + 1;
1316 sum -= srcptr[-top_height * (width + 1)];
1317 srcptr += width + 1;
1318 }
1319
1320 /* Done with the column... copy dest back over source */
1321
1322 dstptr = char_grayscale + col;
1323 srcptr = char_grayscale + width; /* scratch */
1324 for (row = 0; row < height; row++)
1325 {
1326 *dstptr = *srcptr;
1327 dstptr += width + 1;
1328 srcptr += width + 1;
1329 }
1330 }
1331 }
1332
1333 /* Increase the grayvalue to increase ink a bit */
1334 srcptr = char_grayscale;
1335 for (row = 0; row < height; row++)
1336 {
1337 for (col = 0; col < width; col++)
1338 {
1339 register int pixvalue = (int)*srcptr * pixmult / 256;
1340 if (pixvalue > 255) pixvalue = 255;
1341 *srcptr = pixvalue;
1342 srcptr++;
1343 }
1344 srcptr++;
1345 }
1346 }
1347
1348 /* Compute the increment values for the resampling loop */
1349 TRANSFORM_POINT(inv_xform, 1, 0, point)((point)[0] = (inv_xform)[0] * (1) + (inv_xform)[2] * (0), (point
)[1] = (inv_xform)[1] * (1) + (inv_xform)[3] * (0))
;
1350 deltaX = (INT32)(point[0] * 65536.0);
1351 deltaY = (INT32)(-point[1] * 65536.0);
1352
1353 /* Resampling loop: resamples original glyph for generation of new
1354 glyph in transformed coordinate system. */
1355
1356 for (row = 0; row < newHeight; row++)
1357 {
1358 /* Compute inverse transformation for start of this row */
1359 TRANSFORM_POINT(inv_xform,((point)[0] = (inv_xform)[0] * ((double)(pci->metrics.leftSideBearing
) + .5) + (inv_xform)[2] * ((double)(pci->metrics.ascent -
row) - .5), (point)[1] = (inv_xform)[1] * ((double)(pci->
metrics.leftSideBearing) + .5) + (inv_xform)[3] * ((double)(pci
->metrics.ascent - row) - .5))
1360 (double)(pci->metrics.leftSideBearing) + .5,((point)[0] = (inv_xform)[0] * ((double)(pci->metrics.leftSideBearing
) + .5) + (inv_xform)[2] * ((double)(pci->metrics.ascent -
row) - .5), (point)[1] = (inv_xform)[1] * ((double)(pci->
metrics.leftSideBearing) + .5) + (inv_xform)[3] * ((double)(pci
->metrics.ascent - row) - .5))
1361 (double)(pci->metrics.ascent - row) - .5,((point)[0] = (inv_xform)[0] * ((double)(pci->metrics.leftSideBearing
) + .5) + (inv_xform)[2] * ((double)(pci->metrics.ascent -
row) - .5), (point)[1] = (inv_xform)[1] * ((double)(pci->
metrics.leftSideBearing) + .5) + (inv_xform)[3] * ((double)(pci
->metrics.ascent - row) - .5))
1362 point)((point)[0] = (inv_xform)[0] * ((double)(pci->metrics.leftSideBearing
) + .5) + (inv_xform)[2] * ((double)(pci->metrics.ascent -
row) - .5), (point)[1] = (inv_xform)[1] * ((double)(pci->
metrics.leftSideBearing) + .5) + (inv_xform)[3] * ((double)(pci
->metrics.ascent - row) - .5))
;
1363
1364 /* Adjust for coordinate system to get resampling point */
1365 point[0] -= opci->metrics.leftSideBearing;
1366 point[1] = opci->metrics.ascent - point[1];
1367
1368 /* Convert to integer coordinates */
1369 xValue = (INT32)(point[0] * 65536.0);
1370 yValue = (INT32)(point[1] * 65536.0);
1371
1372 if (char_grayscale)
1373 {
1374 INT32 *temp;
1375 for (col = 0; col < newWidth; col++)
1376 {
1377 register int x = xValue >> 16, y = yValue >> 16;
1378 int pixvalue, error;
1379
1380 pixvalue = ((x >= 0 && x < width && y >= 0 && y < height) ?
1381 char_grayscale[x + y * (width + 1)] : 0) +
1382 thisrow[col] / 16;
1383 if (pixvalue > 255) pixvalue = 255;
1384 else if (pixvalue < 0) pixvalue = 0;
1385
1386 /* Choose the bit value and set resulting error value */
1387 if (pixvalue >= 128)
1388 {
1389 newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7];
1390 error = pixvalue - 255;
1391 }
1392 else
1393 error = -pixvalue;
1394
1395 /* Diffuse the error */
1396 thisrow[col + 1] += error * 7;
1397 nextrow[col - 1] += error * 3;
1398 nextrow[col] += error * 5;
1399 nextrow[col + 1] = error;
1400
1401 xValue += deltaX;
1402 yValue += deltaY;
1403 }
1404
1405 /* Add in error values that fell off either end */
1406 nextrow[0] += nextrow[-1];
1407 nextrow[newWidth - 2] += thisrow[newWidth];
1408 nextrow[newWidth - 1] += nextrow[newWidth];
1409 nextrow[newWidth] = 0;
1410
1411 temp = nextrow;
1412 nextrow = thisrow;
1413 thisrow = temp;
1414 nextrow[-1] = nextrow[0] = 0;
1415 }
1416 else
1417 {
1418 for (col = 0; col < newWidth; col++)
1419 {
1420 register int x = xValue >> 16, y = yValue >> 16;
1421
1422 if (x >= 0 && x < width && y >= 0 && y < height)
1423 {
1424 /* Use point-sampling for rescaling. */
1425
1426 if (bitmap[(x >> 3) + y * bpr] & mask[x & 0x7])
1427 newBitmap[(col >> 3) + row * newBpr] |= mask[col & 0x7];
1428 }
1429
1430 xValue += deltaX;
1431 yValue += deltaY;
1432 }
1433 }
1434 }
1435
1436
1437 if (char_grayscale)
1438 {
1439 free(char_grayscale);
1440 free(diffusion_workspace);
1441 }
1442}
1443
1444static FontPtr
1445BitmapScaleBitmaps(FontPtr pf, /* scaled font */
1446 FontPtr opf, /* originating font */
1447 double widthMult, /* glyphs width scale factor */
1448 double heightMult, /* glyphs height scale factor */
1449 FontScalablePtr vals)
1450{
1451 register int i;
1452 int nchars = 0;
1453 char *glyphBytes;
1454 BitmapFontPtr bitmapFont,
1455 obitmapFont;
1456 CharInfoPtr pci,
1457 opci;
1458 FontInfoPtr pfi;
1459 int glyph;
1460 unsigned bytestoalloc = 0;
1461 int firstCol, lastCol, firstRow, lastRow;
1462
1463 double xform[4], inv_xform[4];
1464 double xmult, ymult;
1465
1466 bitmapFont = (BitmapFontPtr) pf->fontPrivate;
1467 obitmapFont = (BitmapFontPtr) opf->fontPrivate;
1468
1469 if (!compute_xform_matrix(vals, widthMult, heightMult, xform,
1470 inv_xform, &xmult, &ymult))
1471 goto bail;
1472
1473 pfi = &pf->info;
1474 firstCol = pfi->firstCol;
1475 lastCol = pfi->lastCol;
1476 firstRow = pfi->firstRow;
1477 lastRow = pfi->lastRow;
1478
1479 nchars = (lastRow - firstRow + 1) * (lastCol - firstCol + 1);
1480 glyph = pf->glyph;
1481 for (i = 0; i < nchars; i++)
1482 {
1483 if ((pci = ACCESSENCODING(bitmapFont->encoding, i)(bitmapFont->encoding[(i)/128]?(bitmapFont->encoding[(i
)/128][(i)%128]):0)
))
1484 bytestoalloc += BYTES_FOR_GLYPH(pci, glyph)(((pci)->metrics.ascent + (pci)->metrics.descent) * ((glyph
) == 1 ? (((((pci)->metrics.rightSideBearing - (pci)->metrics
.leftSideBearing))+7)>>3) :(glyph) == 2 ? ((((((pci)->
metrics.rightSideBearing - (pci)->metrics.leftSideBearing)
)+15)>>3)&~1) :(glyph) == 4 ? ((((((pci)->metrics
.rightSideBearing - (pci)->metrics.leftSideBearing))+31)>>
3)&~3) :(glyph) == 8 ? ((((((pci)->metrics.rightSideBearing
- (pci)->metrics.leftSideBearing))+63)>>3)&~7) :
0))
;
1485 }
1486
1487 /* Do we add the font malloc stuff for VALUE ADDED ? */
1488 /* Will need to remember to free in the Unload routine */
1489
1490
1491 bitmapFont->bitmaps = calloc(1, bytestoalloc);
1492 if (!bitmapFont->bitmaps) {
1493 fprintf(stderr__stderrp, "Error: Couldn't allocate bitmaps (%d)\n", bytestoalloc);
1494 goto bail;
1495 }
1496
1497 glyphBytes = bitmapFont->bitmaps;
1498 for (i = 0; i < nchars; i++)
1499 {
1500 if ((pci = ACCESSENCODING(bitmapFont->encoding, i)(bitmapFont->encoding[(i)/128]?(bitmapFont->encoding[(i
)/128][(i)%128]):0)
) &&
1501 (opci = ACCESSENCODING(obitmapFont->encoding, OLDINDEX(i))(obitmapFont->encoding[((((i)/(lastCol - firstCol + 1) + firstRow
- opf->info.firstRow) * (opf->info.lastCol - opf->info
.firstCol + 1) + (i)%(lastCol - firstCol + 1) + firstCol - opf
->info.firstCol))/128]?(obitmapFont->encoding[((((i)/(lastCol
- firstCol + 1) + firstRow - opf->info.firstRow) * (opf->
info.lastCol - opf->info.firstCol + 1) + (i)%(lastCol - firstCol
+ 1) + firstCol - opf->info.firstCol))/128][((((i)/(lastCol
- firstCol + 1) + firstRow - opf->info.firstRow) * (opf->
info.lastCol - opf->info.firstCol + 1) + (i)%(lastCol - firstCol
+ 1) + firstCol - opf->info.firstCol))%128]):0)
))
1502 {
1503 pci->bits = glyphBytes;
1504 ScaleBitmap (pf, opci, pci, inv_xform,
1505 widthMult, heightMult);
1506 glyphBytes += BYTES_FOR_GLYPH(pci, glyph)(((pci)->metrics.ascent + (pci)->metrics.descent) * ((glyph
) == 1 ? (((((pci)->metrics.rightSideBearing - (pci)->metrics
.leftSideBearing))+7)>>3) :(glyph) == 2 ? ((((((pci)->
metrics.rightSideBearing - (pci)->metrics.leftSideBearing)
)+15)>>3)&~1) :(glyph) == 4 ? ((((((pci)->metrics
.rightSideBearing - (pci)->metrics.leftSideBearing))+31)>>
3)&~3) :(glyph) == 8 ? ((((((pci)->metrics.rightSideBearing
- (pci)->metrics.leftSideBearing))+63)>>3)&~7) :
0))
;
1507 }
1508 }
1509 return pf;
1510
1511bail:
1512 if (pf)
1513 free(pf);
1514 if (bitmapFont) {
1515 free(bitmapFont->metrics);
1516 free(bitmapFont->ink_metrics);
1517 free(bitmapFont->bitmaps);
1518 if(bitmapFont->encoding)
1519 for(i=0; i<NUM_SEGMENTS(nchars)(((nchars)+128 -1)/128); i++)
1520 free(bitmapFont->encoding[i]);
1521 free(bitmapFont->encoding);
1522 }
1523 return NULL((void *)0);
1524}
1525
1526/* ARGSUSED */
1527int
1528BitmapOpenScalable (FontPathElementPtr fpe,
1529 FontPtr *pFont,
1530 int flags,
1531 FontEntryPtr entry,
1532 char *fileName, /* unused */
1533 FontScalablePtr vals,
1534 fsBitmapFormat format,
1535 fsBitmapFormatMask fmask,
1536 FontPtr non_cachable_font) /* We don't do licensing */
1537{
1538 FontScalableRec best;
1539 FontPtr font = NullFont((FontPtr) 0);
1540 double dx, sdx,
1541 dy, sdy,
1542 savedX, savedY;
1543 FontPropPtr props;
1544 char *isStringProp = NULL((void *)0);
1545 int propCount;
1546 int status;
1547 long sWidth;
1548
1549 FontEntryPtr scaleFrom;
1550 FontPathElementPtr scaleFPE = NULL((void *)0);
1551 FontPtr sourceFont;
1552 char fontName[MAXFONTNAMELEN1024];
1553
1554 /* Can't deal with mix-endian fonts yet */
1555
1556
1557 /* Reject outrageously small font sizes to keep the math from
1558 blowing up. */
1559 if (get_matrix_vertical_component(vals->pixel_matrix) < 1.0 ||
1560 get_matrix_horizontal_component(vals->pixel_matrix) < 1.0)
1561 return BadFontName83;
1562
1563 scaleFrom = FindBestToScale(fpe, entry, vals, &best, &dx, &dy, &sdx, &sdy,
1564 &scaleFPE);
1565
1566 if (!scaleFrom)
1567 return BadFontName83;
1568
1569 status = FontFileOpenBitmap(scaleFPE, &sourceFont, LoadAll0x1, scaleFrom,
1570 format, fmask);
1571
1572 if (status != Successful85)
1573 return BadFontName83;
1574
1575 if (!vals->width)
1576 vals->width = best.width * dx;
1577
1578 /* Compute the scaled font */
1579
1580 savedX = dx;
1581 savedY = dy;
1582 font = ScaleFont(sourceFont, dx, dy, sdx, sdy, vals, &dx, &dy, &sWidth);
1583 if (font)
1584 font = BitmapScaleBitmaps(font, sourceFont, savedX, savedY, vals);
1585
1586 if (!font)
1587 {
1588 if (!sourceFont->refcnt)
1589 FontFileCloseFont((FontPathElementPtr) 0, sourceFont);
1590 return AllocError80;
1591 }
1592
1593 /* Prepare font properties for the new font */
1594
1595 strcpy (fontName, scaleFrom->name.name)__builtin___strcpy_chk (fontName, scaleFrom->name.name, __builtin_object_size
(fontName, 2 > 1 ? 1 : 0))
;
1596 FontParseXLFDName (fontName, vals, FONT_XLFD_REPLACE_VALUE3);
1597
1598 propCount = ComputeScaledProperties(&sourceFont->info, fontName, vals,
1599 dx, dy, sdx, sdy, sWidth, &props,
1600 &isStringProp);
1601
1602 if (!sourceFont->refcnt)
1603 FontFileCloseFont((FontPathElementPtr) 0, sourceFont);
1604
1605 font->info.props = props;
1606 font->info.nprops = propCount;
1607 font->info.isStringProp = isStringProp;
1608
1609 if (propCount && (!props || !isStringProp))
1610 {
1611 bitmapUnloadScalable(font);
1612 return AllocError80;
1613 }
1614
1615 *pFont = font;
1616 return Successful85;
1617}
1618
1619int
1620BitmapGetInfoScalable (FontPathElementPtr fpe,
1621 FontInfoPtr pFontInfo,
1622 FontEntryPtr entry,
1623 FontNamePtr fontName,
1624 char *fileName,
1625 FontScalablePtr vals)
1626{
1627 FontPtr pfont;
1628 int flags = 0;
1629 long format = 0; /* It doesn't matter what format for just info */
1630 long fmask = 0;
1631 int ret;
1632
1633 ret = BitmapOpenScalable(fpe, &pfont, flags, entry, fileName, vals,
1634 format, fmask, NULL((void *)0));
1635 if (ret != Successful85)
1636 return ret;
1637 *pFontInfo = pfont->info;
1638
1639 pfont->info.nprops = 0;
1640 pfont->info.props = NULL((void *)0);
1641 pfont->info.isStringProp = NULL((void *)0);
1642
1643 (*pfont->unload_font)(pfont);
1644 return Successful85;
1645}
1646
1647static void
1648bitmapUnloadScalable (FontPtr pFont)
1649{
1650 BitmapFontPtr bitmapFont;
1651 FontInfoPtr pfi;
1652 int i, nencoding;
1653
1654 bitmapFont = (BitmapFontPtr) pFont->fontPrivate;
1655 pfi = &pFont->info;
1656 free (pfi->props);
1657 free (pfi->isStringProp);
1658 if(bitmapFont->encoding) {
1659 nencoding = (pFont->info.lastCol - pFont->info.firstCol + 1) *
1660 (pFont->info.lastRow - pFont->info.firstRow + 1);
1661 for(i=0; i<NUM_SEGMENTS(nencoding)(((nencoding)+128 -1)/128); i++)
1662 free(bitmapFont->encoding[i]);
1663 }
1664 free (bitmapFont->encoding);
1665 free (bitmapFont->bitmaps);
1666 free (bitmapFont->ink_metrics);
1667 free (bitmapFont->metrics);
1668 free (pFont->fontPrivate);
1669 DestroyFontRec (pFont);
1670}