1 /* $XConsortium: out_util.c,v 1.2 91/05/11 09:53:35 rws Exp $ */
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.
13 BITSTREAM CHARTER is a registered trademark of Bitstream Inc.
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.
28 /*************************** O U T _ U T I L . C *****************************
30 * This is a utility module share by all bitmap output modules *
32 *****************************************************************************/
35 #include "spdo_prv.h" /* General definitions for Speedo */
36 /* absolute value function */
37 #define ABS(X) ( (X < 0) ? -X : X)
38 #if INCL_BLACK || INCL_2D || INCL_SCREEN
40 FUNCTION void init_char_out(Psw,Pmin,Pmax)
42 point_t Psw, Pmin, Pmax;
44 sp_globals.set_width.x = (fix31)Psw.x << sp_globals.poshift;
45 sp_globals.set_width.y = (fix31)Psw.y << sp_globals.poshift;
46 set_first_band_out(Pmin, Pmax);
47 init_intercepts_out();
48 if (sp_globals.normal)
50 sp_globals.bmap_xmin = Pmin.x;
51 sp_globals.bmap_xmax = Pmax.x;
52 sp_globals.bmap_ymin = Pmin.y;
53 sp_globals.bmap_ymax = Pmax.y;
54 sp_globals.extents_running = FALSE;
58 sp_globals.bmap_xmin = 32000;
59 sp_globals.bmap_xmax = -32000;
60 sp_globals.bmap_ymin = 32000;
61 sp_globals.bmap_ymax = -32000;
62 sp_globals.extents_running = TRUE;
64 sp_globals.first_pass = TRUE;
67 FUNCTION void begin_sub_char_out(Psw, Pmin, Pmax)
72 /* Called at the start of each sub-character in a composite character
76 printf("BEGIN_SUB_CHAR_out(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f\n",
77 (real)Psw.x / (real)sp_globals.onepix, (real)Psw.y / (real)sp_globals.onepix,
78 (real)Pmin.x / (real)sp_globals.onepix, (real)Pmin.y / (real)sp_globals.onepix,
79 (real)Pmax.x / (real)sp_globals.onepix, (real)Pmax.y / (real)sp_globals.onepix);
81 restart_intercepts_out();
82 if (!sp_globals.extents_running)
84 sp_globals.bmap_xmin = 32000;
85 sp_globals.bmap_xmax = -32000;
86 sp_globals.bmap_ymin = 32000;
87 sp_globals.bmap_ymax = -32000;
88 sp_globals.extents_running = TRUE;
92 FUNCTION void curve_out(P1, P2, P3,depth)
96 /* Called for each curve in the transformed character if curves out enabled
100 printf("CURVE_OUT(%3.1f, %3.1f, %3.1f, %3.1f, %3.1f, %3.1f)\n",
101 (real)P1.x / (real)sp_globals.onepix, (real)P1.y / (real)sp_globals.onepix,
102 (real)P2.x / (real)sp_globals.onepix, (real)P2.y / (real)sp_globals.onepix,
103 (real)P3.x / (real)sp_globals.onepix, (real)P3.y / (real)sp_globals.onepix);
109 FUNCTION void end_contour_out()
111 /* Called after the last vector in each contour
115 printf("END_CONTOUR_OUT()\n");
120 FUNCTION void end_sub_char_out()
122 /* Called after the last contour in each sub-character in a compound character
126 printf("END_SUB_CHAR_OUT()\n");
131 FUNCTION void init_intercepts_out()
133 /* Called to initialize intercept storage data structure
141 printf(" Init intercepts (Y band from %d to %d)\n", sp_globals.y_band.band_min, sp_globals.y_band.band_max);
142 if (sp_globals.x_scan_active)
143 printf(" (X band from %d to %d)\n", sp_globals.x_band.band_min, sp_globals.x_band.band_max);
146 sp_globals.intercept_oflo = FALSE;
148 sp_globals.no_y_lists = sp_globals.y_band.band_max - sp_globals.y_band.band_min + 1;
150 if (sp_globals.output_mode == MODE_2D)
152 sp_globals.no_x_lists = sp_globals.x_scan_active ?
153 sp_globals.x_band.band_max - sp_globals.x_band.band_min + 1 : 0;
154 no_lists = sp_globals.no_y_lists + sp_globals.no_x_lists;
158 no_lists = sp_globals.no_y_lists;
161 sp_globals.y_band.band_floor = 0;
162 sp_globals.y_band.band_ceiling = sp_globals.no_y_lists;
165 if (no_lists >= MAX_INTERCEPTS) /* Not enough room for list table? */
167 no_lists = sp_globals.no_y_lists = MAX_INTERCEPTS;
168 sp_globals.intercept_oflo = TRUE;
169 sp_globals.y_band.band_min = sp_globals.y_band.band_max - sp_globals.no_y_lists + 1;
171 sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min;
172 sp_globals.y_band.band_ceiling = sp_globals.no_y_lists;
173 sp_globals.no_x_lists = 0;
174 sp_globals.x_scan_active = FALSE;
178 for (i = 0; i < no_lists; i++) /* For each active value... */
181 if (sp_globals.output_mode == MODE_SCREEN)
182 sp_intercepts.inttype[i]=0;
184 sp_intercepts.cdr[i] = 0; /* Mark each intercept list empty */
187 sp_globals.first_offset = sp_globals.next_offset = no_lists;
190 sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min;
191 sp_globals.x_band.band_array_offset = sp_globals.x_band.band_min - sp_globals.no_y_lists;
192 sp_globals.x_band.band_floor = sp_globals.no_y_lists;
193 sp_globals.x_band.band_ceiling = no_lists;
196 sp_intercepts.inttype[sp_globals.no_y_lists-1] = END_INT;
202 FUNCTION void restart_intercepts_out()
205 /* Called by sp_make_char when a new sub character is started
206 * Freezes current sorted lists
212 printf(" Restart intercepts:\n");
214 sp_globals.first_offset = sp_globals.next_offset;
219 FUNCTION void set_first_band_out(Pmin, Pmax)
225 sp_globals.ymin = Pmin.y;
226 sp_globals.ymax = Pmax.y;
228 sp_globals.ymin = (sp_globals.ymin - sp_globals.onepix + 1) >> sp_globals.pixshift;
229 sp_globals.ymax = (sp_globals.ymax + sp_globals.onepix - 1) >> sp_globals.pixshift;
232 switch(sp_globals.tcb0.xtype)
234 case 1: /* 180 degree rotation */
235 if (sp_globals.specs.flags & CLIP_TOP)
237 sp_globals.clip_ymin = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
238 sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
239 sp_globals.clip_ymin = -1* sp_globals.clip_ymin;
240 if (sp_globals.ymin < sp_globals.clip_ymin)
241 sp_globals.ymin = sp_globals.clip_ymin;
243 if (sp_globals.specs.flags & CLIP_BOTTOM)
245 sp_globals.clip_ymax = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
246 sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
247 if (sp_globals.ymax > sp_globals.clip_ymax)
248 sp_globals.ymax = sp_globals.clip_ymax;
251 case 2: /* 90 degree rotation */
252 sp_globals.clip_ymax = 0;
253 if ((sp_globals.specs.flags & CLIP_TOP) &&
254 (sp_globals.ymax > sp_globals.clip_ymax))
255 sp_globals.ymax = sp_globals.clip_ymax;
256 sp_globals.clip_ymin = ((sp_globals.set_width.y+32768L) >> 16);
257 if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
258 (sp_globals.ymin < sp_globals.clip_ymin))
259 sp_globals.ymin = sp_globals.clip_ymin;
261 case 3: /* 270 degree rotation */
262 sp_globals.clip_ymax = ((sp_globals.set_width.y+32768L) >> 16);
263 if ((sp_globals.specs.flags & CLIP_TOP) &&
264 (sp_globals.ymax > sp_globals.clip_ymax))
265 sp_globals.ymax = sp_globals.clip_ymax;
266 sp_globals.clip_ymin = 0;
267 if ((sp_globals.specs.flags & CLIP_BOTTOM) &&
268 (sp_globals.ymin < sp_globals.clip_ymin))
269 sp_globals.ymin = sp_globals.clip_ymin;
271 default: /* this is for zero degree rotation and arbitrary rotation */
272 if (sp_globals.specs.flags & CLIP_TOP)
274 sp_globals.clip_ymax = (fix31)((fix31)EM_TOP * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
275 sp_globals.clip_ymax = sp_globals.clip_ymax >> sp_globals.multshift;
276 if (sp_globals.ymax > sp_globals.clip_ymax)
277 sp_globals.ymax = sp_globals.clip_ymax;
279 if (sp_globals.specs.flags & CLIP_BOTTOM)
281 sp_globals.clip_ymin = (fix31)((fix31)(-1 * EM_BOT) * sp_globals.tcb0.yppo + ((1<<sp_globals.multshift)/2));
282 sp_globals.clip_ymin = sp_globals.clip_ymin >> sp_globals.multshift;
283 sp_globals.clip_ymin = - sp_globals.clip_ymin;
284 if (sp_globals.ymin < sp_globals.clip_ymin)
285 sp_globals.ymin = sp_globals.clip_ymin;
290 sp_globals.y_band.band_min = sp_globals.ymin;
291 sp_globals.y_band.band_max = sp_globals.ymax - 1;
293 sp_globals.xmin = (Pmin.x + sp_globals.pixrnd) >> sp_globals.pixshift;
294 sp_globals.xmax = (Pmax.x + sp_globals.pixrnd) >> sp_globals.pixshift;
298 sp_globals.x_band.band_min = sp_globals.xmin - 1; /* subtract one pixel of "safety margin" */
299 sp_globals.x_band.band_max = sp_globals.xmax /* - 1 + 1 */; /* Add one pixel of "safety margin" */
309 FUNCTION void reduce_band_size_out()
312 sp_globals.y_band.band_min = sp_globals.y_band.band_max - ((sp_globals.y_band.band_max - sp_globals.y_band.band_min) >> 1);
314 sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min;
319 FUNCTION boolean next_band_out()
324 if (sp_globals.y_band.band_min <= sp_globals.ymin)
326 tmpfix15 = sp_globals.y_band.band_max - sp_globals.y_band.band_min;
327 sp_globals.y_band.band_max = sp_globals.y_band.band_min - 1;
328 sp_globals.y_band.band_min = sp_globals.y_band.band_max - tmpfix15;
329 if (sp_globals.y_band.band_min < sp_globals.ymin)
330 sp_globals.y_band.band_min = sp_globals.ymin;
332 sp_globals.y_band.band_array_offset = sp_globals.y_band.band_min;