1 /* $XConsortium: spglyph.c,v 1.17 94/04/17 20:17:49 gildea Exp $ */
2 /*
3 * Copyright 1990, 1991 Network Computing Devices;
4 * Portions Copyright 1987 by Digital Equipment Corporation
5 *
6 * Permission to use, copy, modify, distribute, and sell this software and
7 * its documentation for any purpose is hereby granted without fee, provided
8 * that the above copyright notice appear in all copies and that both that
9 * copyright notice and this permission notice appear in supporting
10 * documentation, and that the names of Network Computing Devices or Digital
11 * not be used in advertising or publicity pertaining to distribution of
12 * the software without specific, written prior permission.
13 *
14 * NETWORK COMPUTING DEVICES AND DIGITAL DISCLAIM ALL WARRANTIES WITH
15 * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
16 * AND FITNESS, IN NO EVENT SHALL NETWORK COMPUTING DEVICES OR DIGITAL BE
17 * LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
18 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
19 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
20 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
21 *
22 * Author: Dave Lemke, Network Computing Devices Inc
23 */
24
25 /*
26
27 Copyright (c) 1987 X Consortium
28
29 Permission is hereby granted, free of charge, to any person obtaining
30 a copy of this software and associated documentation files (the
31 "Software"), to deal in the Software without restriction, including
32 without limitation the rights to use, copy, modify, merge, publish,
33 distribute, sublicense, and/or sell copies of the Software, and to
34 permit persons to whom the Software is furnished to do so, subject to
35 the following conditions:
36
37 The above copyright notice and this permission notice shall be included
38 in all copies or substantial portions of the Software.
39
40 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
41 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
42 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
43 IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR
44 OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
45 ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
46 OTHER DEALINGS IN THE SOFTWARE.
47
48 Except as contained in this notice, the name of the X Consortium shall
49 not be used in advertising or otherwise to promote the sale, use or
50 other dealings in this Software without prior written authorization
51 from the X Consortium.
52
53 */
54
55 #include <X11/X.h> /* for bit order #defines */
56 #include "spint.h"
57
58 #undef CLIP_BBOX_NOISE
59
60 static CurrentFontValuesRec current_font_values;
61 static CurrentFontValuesPtr cfv = ¤t_font_values;
62 static int bit_order,
63 byte_order,
64 scan;
65
66 unsigned long
sp_compute_data_size(pfont,mappad,scanlinepad,start,end)67 sp_compute_data_size(pfont, mappad, scanlinepad, start, end)
68 FontPtr pfont;
69 int mappad,
70 scanlinepad;
71 unsigned long start,
72 end;
73 {
74 unsigned long ch;
75 unsigned long size = 0;
76 int bpr;
77 SpeedoFontPtr spf = (SpeedoFontPtr) pfont->fontPrivate;
78 FontInfoPtr pinfo = &pfont->info;
79 int firstChar;
80
81 firstChar = spf->master->first_char_id;
82
83 /* allocate the space */
84 switch (mappad) {
85 int charsize;
86 CharInfoPtr ci;
87 xCharInfo *cim;
88
89 case BitmapFormatImageRectMin:
90 cfv->bpr = 0;
91 for (ch = start; ch <= end; ch++) {
92 ci = &spf->encoding[ch - firstChar];
93 if (!ci)
94 ci = spf->pDefault;
95 cim = &ci->metrics;
96 charsize = GLYPH_SIZE(ci, scanlinepad);
97 charsize *= cim->ascent + cim->descent;
98 size += charsize;
99 }
100 break;
101 case BitmapFormatImageRectMaxWidth:
102 bpr = GLWIDTHBYTESPADDED(FONT_MAX_WIDTH(pinfo), scanlinepad);
103 cfv->bpr = bpr;
104 for (ch = start; ch <= end; ch++) {
105 ci = &spf->encoding[ch - firstChar];
106 if (!ci)
107 ci = spf->pDefault;
108 cim = &ci->metrics;
109 charsize = bpr * (cim->ascent + cim->descent);
110 size += charsize;
111 }
112 break;
113 case BitmapFormatImageRectMax:
114 bpr = GLWIDTHBYTESPADDED(FONT_MAX_WIDTH(pinfo), scanlinepad);
115 cfv->bpr = bpr;
116 size = (end - start + 1) * bpr * FONT_MAX_HEIGHT(pinfo);
117 break;
118 default:
119 assert(0);
120 }
121
122 return size;
123 }
124
125 static void
finish_line(spf)126 finish_line(spf)
127 SpeedoFontPtr spf;
128 {
129 int bpr = cfv->bpr;
130 CharInfoPtr ci = &spf->encoding[cfv->char_id - spf->master->first_char_id];
131
132 if (bpr == 0) {
133 bpr = GLYPH_SIZE(ci, cfv->scanpad);
134 }
135 if (bpr) { /* char may not have any metrics... */
136 cfv->bp += bpr;
137 }
138 assert(cfv->bp - sp_fp_cur->bitmaps <= sp_fp_cur->bitmap_size);
139 }
140
141
142 void
sp_set_bitmap_bits(y,xbit1,xbit2)143 sp_set_bitmap_bits(y, xbit1, xbit2)
144 fix15 y;
145 fix15 xbit1,
146 xbit2;
147 {
148 int nmiddle;
149 CARD8 startmask,
150 endmask;
151 CARD8 *dst;
152
153 if (xbit1 > cfv->bit_width) {
154
155 #ifdef CLIP_BBOX_NOISE
156 SpeedoErr("Run wider than bitmap width -- truncated\n");
157 #endif
158
159 xbit1 = cfv->bit_width;
160 }
161 if (xbit2 > cfv->bit_width) {
162
163 #ifdef CLIP_BBOX_NOISE
164 SpeedoErr("Run wider than bitmap width -- truncated\n");
165 #endif
166
167 xbit2 = cfv->bit_width;
168 }
169
170 if (xbit2 < xbit1) {
171 xbit2 = xbit1;
172 }
173
174 while (cfv->cur_y != y) {
175 finish_line(sp_fp_cur);
176 cfv->cur_y++;
177 }
178
179 cfv->last_y = y;
180 if (y >= cfv->bit_height) {
181
182 #ifdef CLIP_BBOX_NOISE
183 SpeedoErr("Y larger than bitmap height -- truncated\n");
184 #endif
185
186 cfv->trunc = 1;
187 return;
188 }
189 if (xbit1 < 0) /* XXX this is more than a little bit rude... */
190 xbit1 = 0;
191
192 nmiddle = (xbit1 >> 3);
193 dst = (CARD8 *) (cfv->bp + nmiddle);
194 xbit2 -= (xbit1 & ~7);
195 nmiddle = (xbit2 >> 3);
196 xbit1 &= 7;
197 xbit2 &= 7;
198 if (bit_order == MSBFirst) {
199 startmask = ((CARD8) ~0) >> xbit1;
200 endmask = ~(((CARD8) ~0) >> xbit2);
201 } else {
202 startmask = ((CARD8) ~0) << xbit1;
203 endmask = ~(((CARD8) ~0) << xbit2);
204 }
205 if (nmiddle == 0)
206 *dst |= endmask & startmask;
207 else {
208 *dst++ |= startmask;
209 while (--nmiddle)
210 *dst++ = (CARD8)~0;
211 *dst |= endmask;
212 }
213 }
214
215 /* ARGSUSED */
216 void
sp_open_bitmap(x_set_width,y_set_width,xorg,yorg,xsize,ysize)217 sp_open_bitmap(x_set_width, y_set_width, xorg, yorg, xsize, ysize)
218 fix31 x_set_width;
219 fix31 y_set_width;
220 fix31 xorg;
221 fix31 yorg;
222 fix15 xsize;
223 fix15 ysize;
224 {
225 CharInfoPtr ci = &sp_fp_cur->encoding[cfv->char_id - sp_fp_cur->master->first_char_id];
226
227 /*-
228 * this is set to provide better quality bitmaps. since the Speedo
229 * sp_get_bbox() function returns an approximate (but guarenteed to contain)
230 * set of metrics, some of the bitmaps can be place poorly inside and
231 * look bad.
232 *
233 * with this set, the actual bitmap values are used instead of the bboxes.
234 * it makes things look better, but causes two possible problems:
235 *
236 * 1 - the reported min & max bounds may not correspond to the extents
237 * reported
238 * 2 - if the extents are reported before the character is generated,
239 * a client could see them change. this currently never happens,
240 * but will when a desired enhancement (don't reneder till needed)
241 * is made.
242 */
243
244 #define BBOX_FIXUP 1
245
246 #ifdef BBOX_FIXUP
247 int off_horz;
248 int off_vert;
249
250 if (xorg < 0)
251 off_horz = (fix15) ((xorg - 32768L) / 65536);
252 else
253 off_horz = (fix15) ((xorg + 32768L) / 65536);
254 if (yorg < 0)
255 off_vert = (fix15) ((yorg - 32768L) / 65536);
256 else
257 off_vert = (fix15) ((yorg + 32768L) / 65536);
258 if (xsize != 0 || ysize != 0 || ci->metrics.characterWidth)
259 {
260 ci->metrics.leftSideBearing = off_horz;
261 ci->metrics.descent = -off_vert;
262 ci->metrics.rightSideBearing = xsize + off_horz;
263 ci->metrics.ascent = ysize + off_vert;
264 }
265 else
266 {
267 /* If setting the proper size would cause the character to appear to
268 be non-existent, fudge things by giving it a pixel to occupy. */
269 xsize = ysize = 1;
270 ci->metrics.leftSideBearing = ci->metrics.descent = 0;
271 ci->metrics.rightSideBearing = ci->metrics.ascent = 1;
272 }
273
274 cfv->bit_width = xsize;
275 cfv->bit_height = ysize;
276 #else
277 cfv->bit_width = ci->metrics.rightSideBearing -
278 ci->metrics.leftSideBearing;
279 cfv->bit_height = ci->metrics.ascent + ci->metrics.descent;
280 #endif
281
282 assert(cfv->bp - sp_fp_cur->bitmaps <= sp_fp_cur->bitmap_size);
283 ci->bits = (char *) cfv->bp;
284
285 cfv->cur_y = 0;
286 }
287
288 void
sp_close_bitmap()289 sp_close_bitmap()
290 {
291 CharInfoPtr ci = &sp_fp_cur->encoding[cfv->char_id - sp_fp_cur->master->first_char_id];
292 int bpr = cfv->bpr;
293
294 if (bpr == 0)
295 bpr = GLYPH_SIZE(ci, cfv->scanpad);
296 if (!cfv->trunc)
297 finish_line(sp_fp_cur);
298 cfv->trunc = 0;
299 cfv->last_y++;
300 while (cfv->last_y < cfv->bit_height) {
301 finish_line(sp_fp_cur);
302 cfv->last_y++;
303 }
304 if (byte_order != bit_order) {
305 switch (scan) {
306 case 1:
307 break;
308 case 2:
309 TwoByteSwap(cfv->bp, bpr * cfv->bit_height);
310 break;
311 case 4:
312 FourByteSwap(cfv->bp, bpr * cfv->bit_height);
313 break;
314 }
315 }
316 }
317
318 int
sp_build_all_bitmaps(pfont,format,fmask)319 sp_build_all_bitmaps(pfont, format, fmask)
320 FontPtr pfont;
321 fsBitmapFormat format;
322 fsBitmapFormatMask fmask;
323 {
324 int ret,
325 glyph = 1,
326 image = BitmapFormatImageRectMin;
327 unsigned long glyph_size;
328 SpeedoFontPtr spf = (SpeedoFontPtr) pfont->fontPrivate;
329 SpeedoMasterFontPtr spmf = spf->master;
330 pointer bitmaps;
331 int start,
332 end,
333 i;
334
335 scan = 1;
336 ret = CheckFSFormat(format, fmask,
337 &bit_order, &byte_order, &scan, &glyph, &image);
338
339 pfont->bit = bit_order;
340 pfont->byte = byte_order;
341 pfont->glyph = glyph;
342 pfont->scan = scan;
343 if (ret != Successful)
344 return BadFontFormat;
345
346 start = spmf->first_char_id;
347 end = spmf->max_id;
348 glyph_size = sp_compute_data_size(pfont, image, glyph, start, end);
349
350 /* XXX -- MONDO KLUDGE -- add some slop */
351 /*
352 * not sure why this is wanted, but it keeps the packer from going off the
353 * end and toasting us down the line
354 */
355 glyph_size += 20;
356
357 #ifdef DEBUG
358 spf->bitmap_size = glyph_size;
359 #endif
360
361 bitmaps = (pointer) xalloc(glyph_size);
362 if (!bitmaps)
363 return AllocError;
364 bzero((char *) bitmaps, glyph_size);
365
366 /* set up some state */
367 sp_fp_cur = spf;
368 spf->bitmaps = bitmaps;
369 cfv->format = format;
370 cfv->scanpad = glyph;
371 cfv->bp = bitmaps;
372
373 for (i = 0; i < spmf->num_chars; i++) {
374 int j;
375 cfv->char_index = spmf->enc[i * 2 + 1];
376 cfv->char_id = spmf->enc[i * 2];
377 #if DEBUG
378 fprintf(stderr, "build_all_sp_bitmaps:i = %d, Char ID = %d\n", i, cfv->char_id);
379 #endif
380 if (!cfv->char_id)
381 continue;
382
383 /*
384 * See if this character is in the list of ranges specified in the
385 * XLFD name
386 */
387 for (j = 0; j < spf->vals.nranges; j++)
388 if (cfv->char_id >= mincharno(spf->vals.ranges[j]) &&
389 cfv->char_id <= maxcharno(spf->vals.ranges[j]))
390 break;
391
392 /* If not, don't realize it. */
393 if (spf->vals.nranges && j == spf->vals.nranges)
394 continue;
395
396 if (!sp_make_char(cfv->char_index)) {
397
398 #ifdef DEBUG /* can be very common with some encodings */
399 SpeedoErr("Can't make char %d\n", cfv->char_index);
400 #endif
401 }
402 }
403
404 return Successful;
405 }
406