1 /*
2 * This file is part of the XForms library package.
3 *
4 * XForms is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2.1, or
7 * (at your option) any later version.
8 *
9 * XForms is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with XForms. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18
19 /*
20 * This file is part of the XForms library package.
21 * Copyright (c) 1997-2002 by T.C. Zhao
22 * All rights reserved.
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include "include/forms.h"
30 #include "flinternal.h"
31 #include "private/pflps.h"
32 #include <stdlib.h>
33
34 extern char *fl_ul_magic_char;
35
36 /*
37 * Text stuff. Default fonts follows the XFORM built-in
38 */
39
40 static const char *fnts[ FL_MAXFONTS ] =
41 {
42 "Helvetica",
43 "Helvetica-Bold",
44 "Helvetica-Oblique",
45 "Helvetica-BoldOblique",
46 "Courier",
47 "Courier-Bold",
48 "Courier-Oblique",
49 "Courier-BoldOblique",
50 "Times-Roman",
51 "Times-Bold",
52 "Times-Italic",
53 "Times-BoldItalic",
54
55 /* xforms users charter */
56
57 "Times-Roman",
58 "Times-Bold",
59 "Times-Italic",
60 "Times-BoldItalic",
61
62 "Symbol"
63 };
64
65
66 /***************************************
67 ***************************************/
68
69 void
flps_invalidate_font_cache(void)70 flps_invalidate_font_cache( void )
71 {
72 flps->cur_style = flps->cur_size = -1;
73 }
74
75
76 /***************************************
77 ***************************************/
78
79 void
flps_set_font(int style,int size)80 flps_set_font( int style,
81 int size )
82 {
83
84 if ( style >= FL_SHADOW_STYLE )
85 style %= FL_SHADOW_STYLE;
86
87 if ( style == flps->cur_style && size == flps->cur_size )
88 return;
89
90 if ( flps->scale_text )
91 size = 0.5 * ( flps->final_xscale + flps->final_yscale );
92
93 flps_output( "%d point /%s SetFont\n", size, fnts[ style ] );
94 flps_output( "/H %d point def\n", size );
95
96 flps->cur_style = style;
97 flps->cur_size = size;
98 }
99
100
101 #define has_desc( s ) ( strchr( s, 'g' ) \
102 || strchr( s, 'j' ) \
103 || strchr( s, 'q' ) \
104 || strchr( s, 'y' ) \
105 || strchr( s, 'p' ) )
106
107 #define is_desc( c ) ( c == 'g' \
108 || c == 'j' \
109 || c == 'q' \
110 || c == 'y' \
111 || c == 'p' )
112
113
114 /***************************************
115 ***************************************/
116
117 static void
do_underline(const char * s,int n)118 do_underline( const char * s,
119 int n )
120 {
121
122 flps_output( "/len (%s) SW pop def\n", s );
123
124 if ( n == -1 )
125 {
126 flps_output( "/ty CP exch pop %d sub def ", 1 + has_desc( s ) * 2 );
127 flps_output( "/tx CP pop len sub def " );
128 flps_output( "tx ty M len tx add ty LT S\n" );
129 }
130 else
131 {
132 char *t = fl_strdup( s );
133
134 t[ n ] = '\0';
135 flps_output( "/ul (%c) SW pop def\n", s[ n ] );
136 flps_output( "/ty CP exch pop %d sub def ",
137 1 + is_desc( s [ n ] ) * 2 );
138 flps_output( "/tx CP pop len sub (%s) SW pop add def\n", t );
139 flps_output( "tx ty M ul tx add ty LT S\n" );
140 fl_free( t );
141 }
142 }
143
144
145 #define Quote( c ) ( c == '(' || c == ')' || c == '%')
146
147
148 /***************************************
149 ***************************************/
150
151 static char *
ps_quote(char * str)152 ps_quote( char * str )
153 {
154 static char buf[ 1024 ];
155 char *s,
156 *q = buf;
157
158 for ( s = str; *s; s++ )
159 {
160 if ( Quote( *s ) )
161 *q++ = '\\';
162 *q++ = *s;
163 }
164 *q = '\0';
165
166 return buf;
167 }
168
169
170 /***************************************
171 * This routine is always called by other routines. Once we get here,
172 * the text would always remain within the box specified by
173 * {x,y,w,h}.
174 ***************************************/
175
176 static void
flps_drw_text(int align,float x,float y,float w,float h,FL_COLOR c,int style,int size,const char * sstr)177 flps_drw_text( int align,
178 float x,
179 float y,
180 float w,
181 float h,
182 FL_COLOR c,
183 int style,
184 int size,
185 const char * sstr )
186 {
187 int ulpos = -1, lnumb;
188 int i;
189 char *lines[ 512 ];
190 char *str;
191 char newlabel[ 255 ],
192 *p;
193 float bw = 2;
194 int halign,
195 valign;
196 int is_vert;
197
198 flps_color( c );
199 flps_set_font( style, size );
200
201 str = fl_strdup( sstr );
202
203 lines[ 0 ] = str;
204
205 if ( ( is_vert = align & FL_ALIGN_VERT ) )
206 {
207 align &= ~ FL_ALIGN_VERT;
208 flps_output( "gsave %.1f %.1f translate 90 rotate\n", x, y );
209 x = y = 0;
210 }
211
212 /* this is a hack to get arbitary rotation for image_postscript */
213
214 if ( flps->rotation )
215 {
216 flps_output( "gsave %.1f %.1f translate %g rotate\n", x, y,
217 flps->rotation * 0.1 );
218 x = y = 0;
219 }
220
221 /* split (multi-line)string into lines */
222
223 for ( i = 0, lnumb = 1; str[ i ] != '\0'; i++ )
224 {
225 if ( str[ i ] == '\n')
226 {
227 str[ i ] = '\0';
228 lines[ lnumb ] = str + i + 1;
229 lnumb++;
230 }
231 }
232
233 fli_get_hv_align( align, &halign, &valign );
234
235 /* figure out where the starting point is */
236
237 switch ( halign )
238 {
239 case FL_ALIGN_CENTER :
240 flps_output( "/x %.1f def ", x + 0.5 * w );
241 break;
242
243 case FL_ALIGN_LEFT :
244 flps_output( "/x %.1f def ", bw + x );
245 break;
246
247 case FL_ALIGN_RIGHT :
248 flps_output( "/x %.1f def ", x + w - 1 - bw );
249 break;
250 }
251
252 switch ( valign )
253 {
254 case FL_ALIGN_TOP :
255 flps_output( "/y %.1f H sub def\n", y + h - bw );
256 break;
257
258 case FL_ALIGN_BOTTOM :
259 flps_output( "/y %.1f %.1f H mul add def\n",
260 y + bw, lnumb - 0.9 );
261 break;
262
263 case FL_ALIGN_CENTER :
264 flps_output( "/y %.1f %.1f H mul add def\n",
265 y + 0.5 * h, 0.5 * lnumb - 0.9 );
266 break;
267 }
268
269 for ( i = 0; i < lnumb; i++ )
270 {
271 /* check if have underline request */
272
273 if ( ( p = strchr( lines[ i ], *fl_ul_magic_char ) ) )
274 {
275 char *q;
276
277 ulpos = p - lines[ i ];
278 q = newlabel;
279 p = lines[ i ];
280 for ( ; *p; p++ )
281 if ( *p != *fl_ul_magic_char )
282 *q++ = *p;
283 *q = 0;
284 lines[ i ] = newlabel;
285 }
286
287 flps_output( "x y M " );
288
289 switch ( halign )
290 {
291 case FL_ALIGN_CENTER :
292 flps_output( "(%s) Cshow\n", ps_quote( lines[ i ] ) );
293 break;
294
295 case FL_ALIGN_LEFT :
296 flps_output( "(%s) Lshow\n", ps_quote( lines[ i ] ) );
297 break;
298
299 case FL_ALIGN_RIGHT :
300 flps_output( "(%s) Rshow\n", ps_quote( lines[ i ] ) );
301 break;
302 }
303
304 if ( ulpos >= 0 )
305 do_underline( lines[ i ], ulpos - 1 );
306
307 ulpos = -1;
308
309 if ( i != lnumb - 1 )
310 flps_output( "/y y H sub def\n" );
311 }
312
313 fl_free( str );
314
315 if ( is_vert || flps->rotation )
316 flps_output( "grestore\n" );
317 }
318
319
320 #define D( x, y, c ) flps_drw_text( align, x, y, w, h, c, style, size, str )
321
322
323 /***************************************
324 ***************************************/
325
326 void
flps_draw_text(int align,int x,int y,int w,int h,FL_COLOR col,int style,int size,const char * istr)327 flps_draw_text( int align,
328 int x,
329 int y,
330 int w,
331 int h,
332 FL_COLOR col,
333 int style,
334 int size,
335 const char * istr )
336 {
337 int special = FL_INVALID_STYLE;
338 const char *str = istr;
339
340 if ( ! str || ! *str )
341 return;
342
343 if ( *str == '@' && str[ 1 ] != '@' )
344 {
345 if ( w < 3 || h < 3 )
346 {
347 w = h = size + 4;
348 x -= w / 2;
349 y -= h / 2;
350 }
351
352 flps_draw_symbol( str, x, y, w, h, col );
353 return;
354 }
355
356 str += str[ 1 ] == '@';
357
358 if ( special_style( style ) )
359 {
360 special = ( style / FL_SHADOW_STYLE ) * FL_SHADOW_STYLE;
361 style %= FL_SHADOW_STYLE;
362 }
363
364 if ( special == FL_SHADOW_STYLE )
365 D( x + 2, y - 2, FL_BOTTOM_BCOL );
366 else if ( special == FL_ENGRAVED_STYLE )
367 {
368 D( x - 1, y, FL_RIGHT_BCOL );
369 D( x, y + 1, FL_RIGHT_BCOL );
370 D( x - 1, y + 1, FL_RIGHT_BCOL );
371 D( x + 1, y, FL_LEFT_BCOL );
372 D( x, y - 1, FL_LEFT_BCOL );
373 D( x + 1, y - 1, FL_LEFT_BCOL );
374 }
375 else if ( special == FL_EMBOSSED_STYLE )
376 {
377 D( x - 1, y, FL_TOP_BCOL );
378 D( x, y + 1, FL_TOP_BCOL );
379 D( x - 1, y + 1, FL_TOP_BCOL );
380 D( x + 1, y, FL_RIGHT_BCOL );
381 D( x, y - 1, FL_RIGHT_BCOL );
382 D( x + 1, y - 1, FL_RIGHT_BCOL );
383 }
384
385 flps_drw_text( align, x, y, w, h, col, style, size, str );
386 }
387
388
389 /***************************************
390 ***************************************/
391
392 void
flps_draw_text_beside(int align,int x,int y,int w,int h,FL_COLOR col,int style,int size,const char * str)393 flps_draw_text_beside( int align,
394 int x,
395 int y,
396 int w,
397 int h,
398 FL_COLOR col,
399 int style,
400 int size,
401 const char * str )
402 {
403 if ( ! str || ! *str )
404 return;
405
406 switch( fl_to_outside_lalign( align ) )
407 {
408 case FL_ALIGN_LEFT :
409 flps_draw_text( FL_ALIGN_RIGHT, x - h, y, h, h, col, style, size,
410 str );
411 break;
412
413 case FL_ALIGN_RIGHT :
414 flps_draw_text( FL_ALIGN_LEFT, x + w, y, h, h, col, style, size,
415 str );
416 break;
417
418 case FL_ALIGN_TOP :
419 flps_draw_text( FL_ALIGN_BOTTOM, x, y + h, w, h, col, style, size,
420 str );
421 break;
422
423 case FL_ALIGN_BOTTOM :
424 flps_draw_text( FL_ALIGN_TOP, x, y - h, w, h, col, style, size,
425 str );
426 break;
427
428 case FL_ALIGN_LEFT_BOTTOM :
429 flps_draw_text( FL_ALIGN_LEFT_TOP, x, y - h, w, h, col, style,
430 size, str );
431 break;
432
433 case FL_ALIGN_RIGHT_BOTTOM :
434 flps_draw_text( FL_ALIGN_RIGHT_TOP, x, y - h, w, h, col, style,
435 size, str );
436 break;
437
438 case FL_ALIGN_LEFT_TOP :
439 flps_draw_text( FL_ALIGN_LEFT_BOTTOM, x, y + h, w, h, col, style,
440 size, str );
441 break;
442
443 case FL_ALIGN_RIGHT_TOP :
444 flps_draw_text( FL_ALIGN_RIGHT_BOTTOM, x, y + h, w, h, col, style,
445 size, str );
446 break;
447
448 case FL_ALIGN_CENTER :
449 flps_draw_text( FL_ALIGN_CENTER, x, y, w, h, col, style, size,
450 str );
451 break;
452
453 default :
454 flps_draw_text( FL_ALIGN_TOP, x, y - h, w, h, col, style, size,
455 str );
456 break;
457 }
458 }
459
460
461 /*
462 * Local variables:
463 * tab-width: 4
464 * indent-tabs-mode: nil
465 * End:
466 */
467