]> git.sesse.net Git - rdpsrv/blob - Xserver/lib/font/Speedo/spglyph.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / lib / font / Speedo / spglyph.c
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 = &current_font_values;
62 static int  bit_order,
63             byte_order,
64             scan;
65
66 unsigned long
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
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
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
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
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
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 }