]> git.sesse.net Git - rdpsrv/blob - Xserver/lib/font/Speedo/spinfo.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / lib / font / Speedo / spinfo.c
1 /* $TOG: spinfo.c /main/17 1997/06/09 14:19:24 barstow $ */
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 "fntfilst.h"
56 #include "spint.h"
57 #include <math.h>
58
59 /* percentage of pointsize used to specify ascent & descent */
60 #define STRETCH_FACTOR  120
61
62 enum scaleType {
63     atom, truncate_atom, pixel_size, point_size, resolution_x,
64     resolution_y, average_width
65 };
66
67 typedef struct _fontProp {
68     char       *name;
69     long        atom;
70     enum scaleType type;
71 }           fontProp;
72
73 static fontProp fontNamePropTable[] = {
74     "FOUNDRY", 0, atom,
75     "FAMILY_NAME", 0, atom,
76     "WEIGHT_NAME", 0, atom,
77     "SLANT", 0, atom,
78     "SETWIDTH_NAME", 0, atom,
79     "ADD_STYLE_NAME", 0, atom,
80     "PIXEL_SIZE", 0, pixel_size,
81     "POINT_SIZE", 0, point_size,
82     "RESOLUTION_X", 0, resolution_x,
83     "RESOLUTION_Y", 0, resolution_y,
84     "SPACING", 0, atom,
85     "AVERAGE_WIDTH", 0, average_width,
86     "CHARSET_REGISTRY", 0, atom,
87     "CHARSET_ENCODING", 0, truncate_atom,
88 };
89
90 /* Warning: following array is closely related to the sequence of
91    defines after it. */
92
93 static fontProp extraProps[] = {
94     "FONT", 0, 0,
95     "COPYRIGHT", 0, 0,
96     "RAW_PIXEL_SIZE", 0, 0,
97     "RAW_POINT_SIZE", 0, 0,
98     "RAW_ASCENT", 0, 0,
99     "RAW_DESCENT", 0, 0,
100     "RAW_AVERAGE_WIDTH", 0, 0,
101 };
102
103 /* this is a bit kludgy */
104 #define FONTPROP        0
105 #define COPYRIGHTPROP   1
106 #define RAWPIXELPROP    2
107 #define RAWPOINTPROP    3
108 #define RAWASCENTPROP   4
109 #define RAWDESCENTPROP  5
110 #define RAWWIDTHPROP    6
111
112
113 #define NNAMEPROPS (sizeof(fontNamePropTable) / sizeof(fontProp))
114 #define NEXTRAPROPS (sizeof(extraProps) / sizeof(fontProp))
115
116 #define NPROPS  (NNAMEPROPS + NEXTRAPROPS)
117
118 void
119 sp_make_standard_props()
120 {
121     int         i;
122     fontProp   *t;
123
124     i = sizeof(fontNamePropTable) / sizeof(fontProp);
125     for (t = fontNamePropTable; i; i--, t++)
126         t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
127     i = sizeof(extraProps) / sizeof(fontProp);
128     for (t = extraProps; i; i--, t++)
129         t->atom = MakeAtom(t->name, (unsigned) strlen(t->name), TRUE);
130 }
131
132 void
133 sp_make_header(spf, pinfo)
134     SpeedoFontPtr spf;
135     FontInfoPtr pinfo;
136 {
137     int         pixel_size;
138     SpeedoMasterFontPtr spmf = spf->master;
139
140     pinfo->firstCol = spmf->first_char_id & 0xff;
141     pinfo->firstRow = spmf->first_char_id >> 8;
142     pinfo->lastCol = spmf->max_id & 0xff;
143     pinfo->lastRow = spmf->max_id >> 8;
144
145     /* XXX -- hackery here */
146     pinfo->defaultCh = 0;
147 /* computed by FontComputeInfoAccelerators:
148  *  noOverlap
149  *  constantMetrics
150  *  terminalFont
151  *  constantWidth
152  *  inkInside
153  */
154     pinfo->inkMetrics = 0;
155     pinfo->allExist = 0;
156     pinfo->drawDirection = LeftToRight;
157     pinfo->cachable = 1;
158     if (spf->specs.xxmult != spf->specs.yymult)
159         pinfo->anamorphic = TRUE;
160     else
161         pinfo->anamorphic = FALSE;
162 /* computed by sp_compute_bounds:
163  *  maxOverlap
164  *  maxbounds
165  *  minbounds
166  *  ink_maxbounds
167  *  ink_minbounds
168  */
169     pixel_size = spf->vals.pixel_matrix[3] * STRETCH_FACTOR / 100;
170     pinfo->fontAscent = pixel_size * 764 / 1000;        /* 764 == EM_TOP */
171     pinfo->fontDescent = pixel_size - pinfo->fontAscent;
172 }
173
174 static void
175 adjust_min_max(minc, maxc, tmp)
176     xCharInfo  *minc,
177                *maxc,
178                *tmp;
179 {
180 #define MINMAX(field,ci) \
181         if (minc->field > (ci)->field) \
182              minc->field = (ci)->field; \
183         if (maxc->field < (ci)->field) \
184             maxc->field = (ci)->field;
185
186     MINMAX(ascent, tmp);
187     MINMAX(descent, tmp);
188     MINMAX(leftSideBearing, tmp);
189     MINMAX(rightSideBearing, tmp);
190     MINMAX(characterWidth, tmp);
191
192     if ((INT16)minc->attributes > (INT16)tmp->attributes)
193         minc->attributes = tmp->attributes;
194     if ((INT16)maxc->attributes < (INT16)tmp->attributes)
195         maxc->attributes = tmp->attributes;
196
197 #undef  MINMAX
198 }
199
200
201 void
202 sp_compute_bounds(spf, pinfo, flags, sWidth)
203     SpeedoFontPtr spf;
204     FontInfoPtr pinfo;
205     unsigned long flags;
206     long *sWidth;
207 {
208     int         i,
209                 id,
210                 index,
211                 maxOverlap,
212                 overlap,
213                 total_width = 0;
214     xCharInfo   minchar,
215                 maxchar,
216                 tmpchar;
217     bbox_t      bbox;
218     fix31       width;
219     double      pix_width;
220     SpeedoMasterFontPtr spmf = spf->master;
221     int firstChar;
222     int num_chars = 0;
223
224     firstChar = spmf->first_char_id;
225     minchar.ascent = minchar.descent =
226         minchar.leftSideBearing = minchar.rightSideBearing =
227         minchar.characterWidth = minchar.attributes = 32767;
228     maxchar.ascent = maxchar.descent =
229         maxchar.leftSideBearing = maxchar.rightSideBearing =
230         maxchar.characterWidth = maxchar.attributes = -32767;
231     maxOverlap = -32767;
232     *sWidth = 0;
233     for (i = 0; i < spmf->num_chars; i++) {
234         int j;
235         int char_id;
236
237         index = spmf->enc[i * 2 + 1];
238         char_id = spmf->enc[i * 2];
239       /*
240        * See if this character is in the list of ranges specified in the
241        * XLFD name
242        */
243         for (j = 0; j < spf->vals.nranges; j++)
244             if (char_id >= mincharno(spf->vals.ranges[j]) &&
245                     char_id <= maxcharno(spf->vals.ranges[j]))
246                 break;
247         if (spf->vals.nranges && j == spf->vals.nranges)
248             continue;
249         num_chars++;
250
251         if (!(flags & ComputeBoundsOnly)) {
252
253             width = sp_get_char_width(index);
254
255             /* convert to pixel coords */
256             pix_width = (int)width * (spf->specs.xxmult / 65536L) +
257                 ((int) width * (spf->specs.xxmult % 65536L))
258                 / 65536L;
259             pix_width /= 65536L;
260
261             (void) sp_get_char_bbox(index, &bbox);
262             bbox.ymax = (bbox.ymax + 32768L) >> 16;
263             bbox.ymin = (bbox.ymin + 32768L) >> 16;
264             bbox.xmin = (bbox.xmin + 32768L) >> 16;
265             bbox.xmax = (bbox.xmax + 32768L) >> 16;
266             tmpchar.ascent = bbox.ymax;
267             tmpchar.descent = -bbox.ymin;
268             tmpchar.characterWidth = (int)(pix_width +          /* round */
269                                            (pix_width > 0 ? 0.5 : -0.5));
270             tmpchar.rightSideBearing = bbox.xmax;
271             tmpchar.leftSideBearing = bbox.xmin;
272
273             if (!tmpchar.characterWidth &&
274                 tmpchar.ascent == -tmpchar.descent &&
275                 tmpchar.rightSideBearing == tmpchar.leftSideBearing)
276             {
277                 /* Character appears non-existent, probably as a result
278                    of the transformation.  Let's give it one pixel in
279                    the universe so it's not mistaken for non-existent. */
280                 tmpchar.leftSideBearing = tmpchar.descent = 0;
281                 tmpchar.rightSideBearing = tmpchar.ascent = 1;
282             }
283
284             tmpchar.attributes = (int)((double)(int)width / 65.536 + .5);
285         }
286         else
287             tmpchar = spf->encoding[char_id - firstChar].metrics;
288
289         adjust_min_max(&minchar, &maxchar, &tmpchar);
290         overlap = tmpchar.rightSideBearing - tmpchar.characterWidth;
291         if (maxOverlap < overlap)
292             maxOverlap = overlap;
293
294         total_width += ((int)(INT16)tmpchar.attributes);
295         *sWidth += abs((int)(INT16)tmpchar.attributes);
296
297         if (flags & SaveMetrics) {
298             id = spmf->enc[i * 2] - firstChar;
299             assert(id <= spmf->max_id - firstChar);
300             spf->encoding[id].metrics = tmpchar;
301         }
302     }
303
304
305     if (num_chars > 0)
306     {
307         *sWidth = (int)(((double)*sWidth * 10.0 + (double)num_chars / 2.0) /
308                           num_chars);
309         if (total_width < 0)
310         {
311             /* Predominant direction is R->L */
312             *sWidth = -*sWidth;
313         }
314         spf->vals.width = (int)((double)*sWidth * spf->vals.pixel_matrix[0] /
315                                 1000.0 +
316                                 (spf->vals.pixel_matrix[0] > 0 ? .5 : -.5));
317     }
318     else
319     {
320         spf->vals.width = 0;
321     }
322     pinfo->maxbounds = maxchar;
323     pinfo->minbounds = minchar;
324     pinfo->ink_maxbounds = maxchar;
325     pinfo->ink_minbounds = minchar;
326     pinfo->maxOverlap = maxOverlap;
327 }
328
329 void
330 sp_compute_props(spf, fontname, pinfo, sWidth)
331     SpeedoFontPtr spf;
332     char       *fontname;
333     FontInfoPtr pinfo;
334     long        sWidth;
335 {
336     FontPropPtr pp;
337     int         i,
338                 nprops;
339     fontProp   *fpt;
340     char       *is_str;
341     char       *ptr1,
342                *ptr2;
343     char       *ptr3;
344     char        tmpname[1024];
345     FontScalableRec tmpvals;
346
347     nprops = pinfo->nprops = NPROPS;
348     pinfo->isStringProp = (char *) xalloc(sizeof(char) * nprops);
349     pinfo->props = (FontPropPtr) xalloc(sizeof(FontPropRec) * nprops);
350     if (!pinfo->isStringProp || !pinfo->props) {
351         xfree(pinfo->isStringProp);
352         pinfo->isStringProp = (char *) 0;
353         xfree(pinfo->props);
354         pinfo->props = (FontPropPtr) 0;
355         return;
356     }
357     bzero(pinfo->isStringProp, (sizeof(char) * nprops));
358
359     ptr2 = fontname;
360     for (i = NNAMEPROPS, pp = pinfo->props, fpt = fontNamePropTable,
361             is_str = pinfo->isStringProp;
362             i;
363             i--, pp++, fpt++, is_str++) {
364
365         if (*ptr2)
366         {
367             ptr1 = ptr2 + 1;
368             if (!(ptr2 = strchr(ptr1, '-'))) ptr2 = strchr(ptr1, '\0');
369         }
370
371         pp->name = fpt->atom;
372         switch (fpt->type) {
373         case atom:
374             *is_str = TRUE;
375             pp->value = MakeAtom(ptr1, ptr2 - ptr1, TRUE);
376             break;
377         case truncate_atom:
378             *is_str = TRUE;
379             for (ptr3 = ptr1; *ptr3; ptr3++)
380                 if (*ptr3 == '[')
381                     break;
382             pp->value = MakeAtom(ptr1, ptr3 - ptr1, TRUE);
383             break;
384         case pixel_size:
385             pp->value = (int)(spf->vals.pixel_matrix[3] +
386                               (spf->vals.pixel_matrix[3] > 0 ? .5 : -.5));
387             break;
388         case point_size:
389             pp->value = (int)(spf->vals.point_matrix[3] * 10.0 +
390                               (spf->vals.point_matrix[3] > 0 ? .5 : -.5));
391             break;
392         case resolution_x:
393             pp->value = spf->vals.x;
394             break;
395         case resolution_y:
396             pp->value = spf->vals.y;
397             break;
398         case average_width:
399             pp->value = spf->vals.width;
400             break;
401         }
402     }
403
404     for (i = 0, fpt = extraProps; i < NEXTRAPROPS; i++, is_str++, pp++, fpt++) {
405         pp->name = fpt->atom;
406         switch (i) {
407         case FONTPROP:
408             *is_str = TRUE;
409             strcpy(tmpname, fontname);
410             FontParseXLFDName(tmpname, &tmpvals, FONT_XLFD_REPLACE_ZERO);
411             FontParseXLFDName(tmpname, &spf->vals, FONT_XLFD_REPLACE_VALUE);
412             pp->value = MakeAtom(tmpname, strlen(tmpname), TRUE);
413             break;
414         case COPYRIGHTPROP:
415             *is_str = TRUE;
416             pp->value = MakeAtom(spf->master->copyright,
417                                  strlen(spf->master->copyright), TRUE);
418             break;
419          case RAWPIXELPROP:
420             *is_str = FALSE;
421             pp->value = 1000;
422             break;
423          case RAWPOINTPROP:
424             *is_str = FALSE;
425             pp->value = (long)(72270.0 / (double)spf->vals.y + .5);
426             break;
427          case RAWASCENTPROP:
428             *is_str = FALSE;
429             pp->value = STRETCH_FACTOR * 764 / 100;
430             break;
431          case RAWDESCENTPROP:
432             *is_str = FALSE;
433             pp->value = STRETCH_FACTOR * 236 / 100;
434             break;
435          case RAWWIDTHPROP:
436             *is_str = FALSE;
437             pp->value = sWidth;
438             break;
439         }
440     }
441 }