1 /* $XConsortium: spglyph.c,v 1.17 94/04/17 20:17:49 gildea Exp $ */
3 * Copyright 1990, 1991 Network Computing Devices;
4 * Portions Copyright 1987 by Digital Equipment Corporation
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.
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.
22 * Author: Dave Lemke, Network Computing Devices Inc
27 Copyright (c) 1987 X Consortium
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:
37 The above copyright notice and this permission notice shall be included
38 in all copies or substantial portions of the Software.
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.
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.
55 #include <X11/X.h> /* for bit order #defines */
58 #undef CLIP_BBOX_NOISE
60 static CurrentFontValuesRec current_font_values;
61 static CurrentFontValuesPtr cfv = ¤t_font_values;
67 sp_compute_data_size(pfont, mappad, scanlinepad, start, end)
75 unsigned long size = 0;
77 SpeedoFontPtr spf = (SpeedoFontPtr) pfont->fontPrivate;
78 FontInfoPtr pinfo = &pfont->info;
81 firstChar = spf->master->first_char_id;
83 /* allocate the space */
89 case BitmapFormatImageRectMin:
91 for (ch = start; ch <= end; ch++) {
92 ci = &spf->encoding[ch - firstChar];
96 charsize = GLYPH_SIZE(ci, scanlinepad);
97 charsize *= cim->ascent + cim->descent;
101 case BitmapFormatImageRectMaxWidth:
102 bpr = GLWIDTHBYTESPADDED(FONT_MAX_WIDTH(pinfo), scanlinepad);
104 for (ch = start; ch <= end; ch++) {
105 ci = &spf->encoding[ch - firstChar];
109 charsize = bpr * (cim->ascent + cim->descent);
113 case BitmapFormatImageRectMax:
114 bpr = GLWIDTHBYTESPADDED(FONT_MAX_WIDTH(pinfo), scanlinepad);
116 size = (end - start + 1) * bpr * FONT_MAX_HEIGHT(pinfo);
130 CharInfoPtr ci = &spf->encoding[cfv->char_id - spf->master->first_char_id];
133 bpr = GLYPH_SIZE(ci, cfv->scanpad);
135 if (bpr) { /* char may not have any metrics... */
138 assert(cfv->bp - sp_fp_cur->bitmaps <= sp_fp_cur->bitmap_size);
143 sp_set_bitmap_bits(y, xbit1, xbit2)
153 if (xbit1 > cfv->bit_width) {
155 #ifdef CLIP_BBOX_NOISE
156 SpeedoErr("Run wider than bitmap width -- truncated\n");
159 xbit1 = cfv->bit_width;
161 if (xbit2 > cfv->bit_width) {
163 #ifdef CLIP_BBOX_NOISE
164 SpeedoErr("Run wider than bitmap width -- truncated\n");
167 xbit2 = cfv->bit_width;
174 while (cfv->cur_y != y) {
175 finish_line(sp_fp_cur);
180 if (y >= cfv->bit_height) {
182 #ifdef CLIP_BBOX_NOISE
183 SpeedoErr("Y larger than bitmap height -- truncated\n");
189 if (xbit1 < 0) /* XXX this is more than a little bit rude... */
192 nmiddle = (xbit1 >> 3);
193 dst = (CARD8 *) (cfv->bp + nmiddle);
194 xbit2 -= (xbit1 & ~7);
195 nmiddle = (xbit2 >> 3);
198 if (bit_order == MSBFirst) {
199 startmask = ((CARD8) ~0) >> xbit1;
200 endmask = ~(((CARD8) ~0) >> xbit2);
202 startmask = ((CARD8) ~0) << xbit1;
203 endmask = ~(((CARD8) ~0) << xbit2);
206 *dst |= endmask & startmask;
217 sp_open_bitmap(x_set_width, y_set_width, xorg, yorg, xsize, ysize)
225 CharInfoPtr ci = &sp_fp_cur->encoding[cfv->char_id - sp_fp_cur->master->first_char_id];
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
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:
236 * 1 - the reported min & max bounds may not correspond to the extents
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)
251 off_horz = (fix15) ((xorg - 32768L) / 65536);
253 off_horz = (fix15) ((xorg + 32768L) / 65536);
255 off_vert = (fix15) ((yorg - 32768L) / 65536);
257 off_vert = (fix15) ((yorg + 32768L) / 65536);
258 if (xsize != 0 || ysize != 0 || ci->metrics.characterWidth)
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;
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. */
270 ci->metrics.leftSideBearing = ci->metrics.descent = 0;
271 ci->metrics.rightSideBearing = ci->metrics.ascent = 1;
274 cfv->bit_width = xsize;
275 cfv->bit_height = ysize;
277 cfv->bit_width = ci->metrics.rightSideBearing -
278 ci->metrics.leftSideBearing;
279 cfv->bit_height = ci->metrics.ascent + ci->metrics.descent;
282 assert(cfv->bp - sp_fp_cur->bitmaps <= sp_fp_cur->bitmap_size);
283 ci->bits = (char *) cfv->bp;
291 CharInfoPtr ci = &sp_fp_cur->encoding[cfv->char_id - sp_fp_cur->master->first_char_id];
295 bpr = GLYPH_SIZE(ci, cfv->scanpad);
297 finish_line(sp_fp_cur);
300 while (cfv->last_y < cfv->bit_height) {
301 finish_line(sp_fp_cur);
304 if (byte_order != bit_order) {
309 TwoByteSwap(cfv->bp, bpr * cfv->bit_height);
312 FourByteSwap(cfv->bp, bpr * cfv->bit_height);
319 sp_build_all_bitmaps(pfont, format, fmask)
321 fsBitmapFormat format;
322 fsBitmapFormatMask fmask;
326 image = BitmapFormatImageRectMin;
327 unsigned long glyph_size;
328 SpeedoFontPtr spf = (SpeedoFontPtr) pfont->fontPrivate;
329 SpeedoMasterFontPtr spmf = spf->master;
336 ret = CheckFSFormat(format, fmask,
337 &bit_order, &byte_order, &scan, &glyph, &image);
339 pfont->bit = bit_order;
340 pfont->byte = byte_order;
341 pfont->glyph = glyph;
343 if (ret != Successful)
344 return BadFontFormat;
346 start = spmf->first_char_id;
348 glyph_size = sp_compute_data_size(pfont, image, glyph, start, end);
350 /* XXX -- MONDO KLUDGE -- add some slop */
352 * not sure why this is wanted, but it keeps the packer from going off the
353 * end and toasting us down the line
358 spf->bitmap_size = glyph_size;
361 bitmaps = (pointer) xalloc(glyph_size);
364 bzero((char *) bitmaps, glyph_size);
366 /* set up some state */
368 spf->bitmaps = bitmaps;
369 cfv->format = format;
370 cfv->scanpad = glyph;
373 for (i = 0; i < spmf->num_chars; i++) {
375 cfv->char_index = spmf->enc[i * 2 + 1];
376 cfv->char_id = spmf->enc[i * 2];
378 fprintf(stderr, "build_all_sp_bitmaps:i = %d, Char ID = %d\n", i, cfv->char_id);
384 * See if this character is in the list of ranges specified in the
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]))
392 /* If not, don't realize it. */
393 if (spf->vals.nranges && j == spf->vals.nranges)
396 if (!sp_make_char(cfv->char_index)) {
398 #ifdef DEBUG /* can be very common with some encodings */
399 SpeedoErr("Can't make char %d\n", cfv->char_index);