]> git.sesse.net Git - rdpsrv/blob - Xserver/lib/font/Speedo/do_trns.c
Support RDP5 logon packets.
[rdpsrv] / Xserver / lib / font / Speedo / do_trns.c
1 /* $XConsortium: do_trns.c,v 1.4 94/04/17 20:17:43 gildea Exp $ */
2
3 /*
4
5 Copyright 1989-1991, Bitstream Inc., Cambridge, MA.
6 You are hereby granted permission under all Bitstream propriety rights to
7 use, copy, modify, sublicense, sell, and redistribute the Bitstream Speedo
8 software and the Bitstream Charter outline font for any purpose and without
9 restrictions; provided, that this notice is left intact on all copies of such
10 software or font and that Bitstream's trademark is acknowledged as shown below
11 on all unmodified copies of such font.
12
13 BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
14
15
16 BITSTREAM INC. DISCLAIMS ANY AND ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
17 WITHOUT LIMITATION THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
18 PARTICULAR PURPOSE.  BITSTREAM SHALL NOT BE LIABLE FOR ANY DIRECT OR INDIRECT
19 DAMAGES, INCLUDING BUT NOT LIMITED TO LOST PROFITS, LOST DATA, OR ANY OTHER
20 INCIDENTAL OR CONSEQUENTIAL DAMAGES, ARISING OUT OF OR IN ANY WAY CONNECTED
21 WITH THE SPEEDO SOFTWARE OR THE BITSTREAM CHARTER OUTLINE FONT.
22
23 */
24
25 /**************************** D O _ T R N S . C ******************************
26  *                                                                           *
27  * This module is responsible for executing all intelligent transformation   *
28  * for bounding box and outline data                                         *
29  *                                                                           *
30  ****************************************************************************/
31
32
33 #include "spdo_prv.h"               /* General definitions for Speedo    */
34
35 #define   DEBUG      0
36
37 #if DEBUG
38 #include <stdio.h>
39 #define SHOW(X) printf("X = %d\n", X)
40 #else
41 #define SHOW(X)
42 #endif
43
44 /***** GLOBAL VARIABLES *****/
45
46 /***** GLOBAL FUNCTIONS *****/
47
48 /***** EXTERNAL VARIABLES *****/
49
50 /***** EXTERNAL FUNCTIONS *****/
51
52 /***** STATIC VARIABLES *****/
53
54 /***** STATIC FUNCTIONS *****/
55
56 #if PROTOS_AVAIL
57 static void sp_split_curve(PROTO_DECL2 point_t P1,point_t P2,point_t P3,fix15 depth);
58 static ufix8 FONTFAR *sp_get_args(PROTO_DECL2 ufix8 FONTFAR *pointer,ufix8  format,point_t STACKFAR *pP);
59 #else
60 static void   sp_split_curve();            /* Split Bezier curve into vectors */
61 static ufix8 FONTFAR *sp_get_args();      /* Read X Y argument pair */
62 #endif
63
64
65 FUNCTION ufix8 FONTFAR *read_bbox(pointer, pPmin, pPmax, set_flag)
66 GDECL
67 ufix8 FONTFAR *pointer;    /* Pointer to next byte in char data */
68 point_t STACKFAR *pPmin;      /* Lower left corner of bounding box */
69 point_t STACKFAR *pPmax;      /* Upper right corner of bounding box */
70 boolean set_flag; /* flag to indicate whether global oru bbox should be saved */
71 /*
72  * Called by make_simp_char() and make_comp_char() to read the 
73  * bounding box data from the font.
74  * Sets Pmin and Pmax to the bottom left and top right corners
75  * of the bounding box after transformation into device space.
76  * The units of Pmin and Pmax are sub-pixels.
77  * Updates *ppointer to point to the byte following the
78  * bounding box data.
79  */
80 {
81 ufix8    format1;
82 ufix8    format;
83 fix15    i;
84 point_t  P;
85
86 sp_globals.x_int = 0;
87 sp_globals.y_int = sp_globals.Y_int_org;
88 sp_globals.x_orus = sp_globals.y_orus = 0;
89 format1 = NEXT_BYTE(pointer);
90 pointer = sp_get_args(pointer, format1, pPmin);
91 #if INCL_SQUEEZING || INCL_ISW
92 if (set_flag)
93     {
94     sp_globals.bbox_xmin_orus = sp_globals.x_orus;
95     sp_globals.bbox_ymin_orus = sp_globals.y_orus;
96     }
97 #endif
98 *pPmax = *pPmin;
99 for (i = 1; i < 4; i++)
100     {
101     switch(i)
102         {
103     case 1:
104         if (format1 & BIT6)            /* Xmax requires X int zone 1? */
105             sp_globals.x_int++;
106         format = (format1 >> 4) | 0x0c;
107         break;
108
109     case 2:
110         if (format1 & BIT7)            /* Ymax requires Y int zone 1? */
111             sp_globals.y_int++;
112         format = NEXT_BYTE(pointer);
113         break;
114
115     case 3:
116         sp_globals.x_int = 0; 
117         format >>= 4;
118         break;
119
120     default:
121                 break;
122         }
123
124     pointer = sp_get_args(pointer, format, &P);
125 #if INCL_SQUEEZING || INCL_ISW
126     if (set_flag && (i==2))
127         {
128         sp_globals.bbox_xmax_orus = sp_globals.x_orus;
129         sp_globals.bbox_ymax_orus = sp_globals.y_orus;
130         }
131 #endif
132     if ((i == 2) || (!sp_globals.normal)) 
133         {
134         if (P.x < pPmin->x)
135             pPmin->x = P.x;
136         if (P.y < pPmin->y)
137             pPmin->y = P.y;
138         if (P.x > pPmax->x)
139             pPmax->x = P.x;
140         if (P.y > pPmax->y)
141             pPmax->y = P.y;
142         }
143     }
144
145 #if DEBUG
146 printf("BBOX %6.1f(Xint 0), %6.1f(Yint 0), %6.1f(Xint %d), %6.1f(Yint %d)\n",
147     (real)pPmin->x / (real)sp_globals.onepix, 
148     (real)pPmin->y / (real)sp_globals.onepix, 
149     (real)pPmax->x / (real)sp_globals.onepix, 
150     (format1 >> 6) & 0x01,
151     (real)pPmax->y / (real)sp_globals.onepix,
152     (format1 >> 7) & 0x01);
153
154 #endif
155 return pointer;
156 }
157 \f
158 FUNCTION void proc_outl_data(pointer)
159 GDECL
160 ufix8 FONTFAR *pointer;      /* Pointer to next byte in char data */
161 /*
162  * Called by make_simp_char() and make_comp_char() to read the 
163  * outline data from the font.
164  * The outline data is parsed, transformed into device coordinates
165  * and passed to an output module for further processing.
166  * Note that pointer is not updated to facilitate repeated
167  * processing of the outline data when banding mode is in effect.
168  */
169 {
170 ufix8    format1, format2;
171 point_t  P0, P1, P2, P3;
172 fix15    depth;
173 fix15    curve_count;
174
175 sp_globals.x_int = 0;
176 sp_globals.y_int = sp_globals.Y_int_org;
177 #if INCL_PLAID_OUT                 /* Plaid data monitoring included? */
178 record_xint((fix15)sp_globals.x_int);         /* Record xint data */
179 record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org)); /* Record yint data */
180 #endif
181
182 sp_globals.x_orus = sp_globals.y_orus = 0;
183 curve_count = 0;
184 while(TRUE)
185     {
186     format1 = NEXT_BYTE(pointer);
187     switch(format1 >> 4)
188         {
189     case 0:                        /* LINE */
190         pointer = sp_get_args(pointer, format1, &P1);
191 #if DEBUG
192         printf("LINE %6.1f, %6.1f\n",
193             (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix);
194 #endif
195         fn_line(P1);
196         sp_globals.P0 = P1;
197         continue;
198
199     case 1:                        /* Short XINT */
200         sp_globals.x_int = format1 & 0x0f;
201 #if DEBUG
202         printf("XINT %d\n", sp_globals.x_int);
203 #endif
204 #if INCL_PLAID_OUT                 /* Plaid data monitoring included? */
205 record_xint((fix15)sp_globals.x_int);         /* Record xint data */
206 #endif
207         continue;
208
209     case 2:                        /* Short YINT */
210         sp_globals.y_int = sp_globals.Y_int_org + (format1 & 0x0f);
211 #if DEBUG
212         printf("YINT %d\n", sp_globals.y_int - sp_globals.Y_int_org);
213 #endif
214 #if INCL_PLAID_OUT                 /* Plaid data monitoring included? */
215 record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org)); /* Record yint data */
216 #endif
217         continue;
218          
219     case 3:                        /* Miscellaneous */
220         switch(format1 & 0x0f)
221             {
222         case 0:                    /* END */
223             if (curve_count)
224                 {
225                 fn_end_contour();
226                 }
227             return;
228
229         case 1:                     /* Long XINT */
230             sp_globals.x_int = NEXT_BYTE(pointer);
231 #if DEBUG
232             printf("XINT %d\n", sp_globals.x_int);
233 #endif
234 #if INCL_PLAID_OUT                 /* Plaid data monitoring included? */
235 record_xint((fix15)sp_globals.x_int);         /* Record xint data */
236 #endif
237             continue;
238
239         case 2:                     /* Long YINT */
240             sp_globals.y_int = sp_globals.Y_int_org + NEXT_BYTE(pointer);
241 #if DEBUG
242             printf("YINT %d\n", sp_globals.y_int - sp_globals.Y_int_org);
243 #endif
244 #if INCL_PLAID_OUT                 /* Plaid data monitoring included? */
245 record_yint((fix15)(sp_globals.y_int - sp_globals.Y_int_org)); /* Record yint data */
246 #endif
247             continue;
248
249         default:                    /* Not used */
250             continue;
251             }    
252
253     case 4:                         /* MOVE Inside */
254     case 5:                         /* MOVE Outside */
255         if (curve_count++)
256             {
257             fn_end_contour();
258             }                                
259                 
260         pointer = sp_get_args(pointer, format1, &P0);
261                 sp_globals.P0 = P0;
262 #if DEBUG
263         printf("MOVE %6.1f, %6.1f\n",
264             (real)sp_globals.P0.x / (real)sp_globals.onepix, (real)sp_globals.P0.y / (real)sp_globals.onepix);
265 #endif
266         fn_begin_contour(sp_globals.P0, (boolean)(format1 & BIT4));
267         continue;
268
269     case 6:                         /* Undefined */
270 #if DEBUG
271         printf("*** Undefined instruction (Hex %4x)\n", format1);
272 #endif
273         continue;
274
275     case 7:                         /* Undefined */
276 #if DEBUG
277         printf("*** Undefined instruction (Hex %4x)\n", format1);
278 #endif
279         continue;
280
281     default:                        /* CRVE */
282         format2 = NEXT_BYTE(pointer);
283         pointer = sp_get_args(pointer, format1, &P1);
284         pointer = sp_get_args(pointer, format2, &P2);
285         pointer = sp_get_args(pointer, (ufix8)(format2 >> 4), &P3);
286         depth = (format1 >> 4) & 0x07;
287 #if DEBUG
288         printf("CRVE %6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %6.1f, %d\n",
289             (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix, 
290             (real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix,
291             (real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix,
292             depth);
293 #endif
294         depth += sp_globals.depth_adj;
295         if (sp_globals.curves_out)
296             {
297             fn_curve(P1, P2, P3, depth);
298             sp_globals.P0 = P3;
299             continue;
300             }
301         if (depth <= 0)
302             {
303             fn_line(P3);
304             sp_globals.P0 = P3;
305             continue;
306             }   
307         sp_split_curve(P1, P2, P3, depth);
308         continue;
309         }
310     }
311 }
312 \f
313 FUNCTION static void sp_split_curve(P1, P2, P3, depth)
314 GDECL
315 point_t P1;    /* First control point of Bezier curve */
316 point_t P2;    /* Second  control point of Bezier curve */
317 point_t P3;    /* End point of Bezier curve */
318 fix15   depth; /* Levels of recursive subdivision required */
319 /*
320  * Called by proc_outl_data() to subdivide Bezier curves into an
321  * appropriate number of vectors, whenever curves are not enabled
322  * for output to the currently selected output module.
323  * sp_split_curve() calls itself recursively to the depth specified
324  * at which point it calls line() to deliver each vector resulting
325  * from the spliting process.
326  */
327 {
328 fix31   X0 = (fix31)sp_globals.P0.x;
329 fix31   Y0 = (fix31)sp_globals.P0.y;
330 fix31   X1 = (fix31)P1.x;
331 fix31   Y1 = (fix31)P1.y;
332 fix31   X2 = (fix31)P2.x;
333 fix31   Y2 = (fix31)P2.y;
334 fix31   X3 = (fix31)P3.x;
335 fix31   Y3 = (fix31)P3.y;
336 point_t Pmid;
337 point_t Pctrl1;
338 point_t Pctrl2;
339
340 #if DEBUG
341 printf("CRVE(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n",
342     (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix,
343     (real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix,
344     (real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix);
345 #endif
346
347
348 Pmid.x = (X0 + (X1 + X2) * 3 + X3 + 4) >> 3;
349 Pmid.y = (Y0 + (Y1 + Y2) * 3 + Y3 + 4) >> 3;
350 if ((--depth) <= 0)
351     {
352     fn_line(Pmid);
353     sp_globals.P0 = Pmid;
354     fn_line(P3);
355     sp_globals.P0 = P3;
356     }
357 else
358     {
359     Pctrl1.x = (X0 + X1 + 1) >> 1;
360     Pctrl1.y = (Y0 + Y1 + 1) >> 1;
361     Pctrl2.x = (X0 + (X1 << 1) + X2 + 2) >> 2;
362     Pctrl2.y = (Y0 + (Y1 << 1) + Y2 + 2) >> 2;
363     sp_split_curve(Pctrl1, Pctrl2, Pmid, depth);
364     Pctrl1.x = (X1 + (X2 << 1) + X3 + 2) >> 2;
365     Pctrl1.y = (Y1 + (Y2 << 1) + Y3 + 2) >> 2;
366     Pctrl2.x = (X2 + X3 + 1) >> 1;
367     Pctrl2.y = (Y2 + Y3 + 1) >> 1;
368     sp_split_curve(Pctrl1, Pctrl2, P3, depth);
369     }
370 }
371 \f
372 FUNCTION static ufix8 FONTFAR *sp_get_args(pointer, format, pP)
373 GDECL
374 ufix8 FONTFAR  *pointer;  /* Pointer to next byte in char data */
375 ufix8     format;    /* Format specifiaction of argument pair */
376 point_t STACKFAR *pP;        /* Resulting transformed point */
377 /*
378  * Called by read_bbox() and proc_outl_data() to read an X Y argument
379  * pair from the font.
380  * The format is specified as follows:
381  *     Bits 0-1: Type of X argument.
382  *     Bits 2-3: Type of Y argument.
383  * where the 4 possible argument types are:
384  *     Type 0:   Controlled coordinate represented by one byte
385  *               index into the X or Y controlled coordinate table.
386  *     Type 1:   Interpolated coordinate represented by a two-byte
387  *               signed integer.
388  *     Type 2:   Interpolated coordinate represented by a one-byte
389  *               signed increment/decrement relative to the 
390  *               proceding X or Y coordinate.
391  *     Type 3:   Repeat of preceding X or Y argument value and type.
392  * The units of P are sub-pixels.
393  * Updates *ppointer to point to the byte following the
394  * argument pair.
395  */
396 {
397 ufix8   edge;
398
399 /* Read X argument */
400 switch(format & 0x03)
401     {
402 case 0:                           /* Index to controlled oru */
403     edge = NEXT_BYTE(pointer);
404     sp_globals.x_orus = sp_plaid.orus[edge];
405 #if INCL_RULES
406     sp_globals.x_pix = sp_plaid.pix[edge];
407 #endif
408     break;
409
410 case 1:                           /* 2 byte interpolated oru value */
411     sp_globals.x_orus = NEXT_WORD(pointer);
412     goto L1;
413
414 case 2:                           /* 1 byte signed oru increment */
415     sp_globals.x_orus += (fix15)((fix7)NEXT_BYTE(pointer));
416 L1: 
417 #if INCL_RULES
418     sp_globals.x_pix = TRANS(sp_globals.x_orus, sp_plaid.mult[sp_globals.x_int], sp_plaid.offset[sp_globals.x_int], sp_globals.mpshift);
419 #endif
420     break;
421
422 default:                          /* No change in X value */
423     break;
424     }
425
426 /* Read Y argument */
427 switch((format >> 2) & 0x03)
428     {
429 case 0:                           /* Index to controlled oru */
430     edge = sp_globals.Y_edge_org + NEXT_BYTE(pointer);
431     sp_globals.y_orus = sp_plaid.orus[edge];
432 #if INCL_RULES
433     sp_globals.y_pix = sp_plaid.pix[edge];
434 #endif
435     break;
436
437 case 1:                           /* 2 byte interpolated oru value */
438     sp_globals.y_orus = NEXT_WORD(pointer);
439     goto L2;
440
441 case 2:                           /* 1 byte signed oru increment */
442     sp_globals.y_orus += (fix15)((fix7)NEXT_BYTE(pointer));
443 L2: 
444 #if INCL_RULES
445     sp_globals.y_pix = TRANS(sp_globals.y_orus, sp_plaid.mult[sp_globals.y_int], sp_plaid.offset[sp_globals.y_int], sp_globals.mpshift);
446 #endif
447     break;
448
449 default:                          /* No change in X value */
450     break;
451     }
452
453 #if INCL_RULES
454 switch(sp_globals.tcb.xmode)
455     {
456 case 0:                           /* X mode 0 */
457     pP->x = sp_globals.x_pix;
458     break;
459
460 case 1:                           /* X mode 1 */
461     pP->x = -sp_globals.x_pix;
462     break;
463
464 case 2:                           /* X mode 2 */
465     pP->x = sp_globals.y_pix;
466     break;
467
468 case 3:                           /* X mode 3 */
469     pP->x = -sp_globals.y_pix;
470     break;
471
472 default:                          /* X mode 4 */
473 #endif
474     pP->x = (MULT16(sp_globals.x_orus, sp_globals.tcb.xxmult) + 
475              MULT16(sp_globals.y_orus, sp_globals.tcb.xymult) + 
476              sp_globals.tcb.xoffset) >> sp_globals.mpshift;
477 #if INCL_RULES
478     break;
479     }
480
481 switch(sp_globals.tcb.ymode)
482     {
483 case 0:                           /* Y mode 0 */
484     pP->y = sp_globals.y_pix;
485     break;
486
487 case 1:                           /* Y mode 1 */
488     pP->y = -sp_globals.y_pix;
489     break;
490
491 case 2:                           /* Y mode 2 */
492     pP->y = sp_globals.x_pix;
493     break;
494
495 case 3:                           /* Y mode 3 */
496     pP->y = -sp_globals.x_pix;
497     break;
498
499 default:                          /* Y mode 4 */
500 #endif
501     pP->y = (MULT16(sp_globals.x_orus, sp_globals.tcb.yxmult) + 
502              MULT16(sp_globals.y_orus, sp_globals.tcb.yymult) + 
503              sp_globals.tcb.yoffset) >> sp_globals.mpshift;
504 #if INCL_RULES
505     break;
506     }
507 #endif
508
509 return pointer;
510 }
511
512
513