1 /*
2 * Copyright (C) 1997-2005, R3vis Corporation.
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
17 * USA, or visit http://www.gnu.org/copyleft/lgpl.html.
18 *
19 * Original Contributor:
20 * Wes Bethel, R3vis Corporation, Marin County, California
21 * Additional Contributor(s):
22 *
23 * The OpenRM project is located at http://openrm.sourceforge.net/.
24 */
25 /*
26 * $Id: rmtext.c,v 1.5 2005/02/19 16:40:20 wes Exp $
27 * Version: $Name: OpenRM-1-6-0-2-RC2 $
28 * $Revision: 1.5 $
29 * $Log: rmtext.c,v $
30 * Revision 1.5 2005/02/19 16:40:20 wes
31 * Distro sync and consolidation.
32 * Repairs to fix memory leak associated with repeated calls to rmPipeNew,
33 * rmPipeMakeCurrent, rmPipeClose.
34 *
35 * Revision 1.4 2005/01/23 17:00:22 wes
36 * Copyright updated to 2005.
37 *
38 * Revision 1.3 2004/01/16 16:48:35 wes
39 * Updated copyright line for 2004.
40 *
41 * Revision 1.2 2003/02/02 02:07:16 wes
42 * Updated copyright to 2003.
43 *
44 * Revision 1.1.1.1 2003/01/28 02:15:23 wes
45 * Manual rebuild of rm150 repository.
46 *
47 * Revision 1.11 2003/01/16 22:21:17 wes
48 * Updated all source files to reflect new organization of header files:
49 * all header files formerly located in include/rmaux, include/rmi, include/rmv
50 * are now located in include/rm.
51 *
52 * Revision 1.10 2002/04/30 19:33:49 wes
53 * Updated copyright dates.
54 *
55 * Revision 1.9 2001/10/15 00:12:59 wes
56 * Added a routine to copy all salient fields from one RMtextProps
57 * object to another.
58 *
59 * Revision 1.8 2001/07/15 16:20:14 wes
60 * Fixed bug associated with font emboldening and italicization.
61 *
62 * Revision 1.7 2001/03/31 17:12:39 wes
63 * v1.4.0-alpha-2 checkin.
64 *
65 * Revision 1.6 2000/12/03 22:35:38 wes
66 * Mods for thread safety.
67 *
68 * Revision 1.5 2000/10/03 11:40:28 wes
69 * Contributions from jdb - prototype cleanups.
70 *
71 * Revision 1.4 2000/08/23 23:30:29 wes
72 * Changed embolden and italicization parms from ints to RMenums
73 * on rmTextPropsGetAttribs.
74 *
75 * Revision 1.3 2000/05/17 14:25:13 wes
76 * Fixed compile warnings on rmTextPropsSet/GetAttribs().
77 *
78 * Revision 1.2 2000/04/20 16:29:47 wes
79 * Documentation additions/enhancements, some code rearragement.
80 *
81 * Revision 1.1.1.1 2000/02/28 21:29:40 wes
82 * OpenRM 1.2 Checkin
83 *
84 * Revision 1.1.1.1 2000/02/28 17:18:48 wes
85 * Initial entry - pre-RM120 release, source base for OpenRM 1.2.
86 *
87 */
88
89 #include <rm/rm.h>
90 #include "rmprivat.h"
91
92 /*
93 * ----------------------------------------------------
94 * @Name rmTextPropsSetAttribs
95 @pstart
96 RMenum rmTextPropsSetAttribs (RMtextProps *toModify,
97 int fontEnum,
98 int sizeEnum,
99 RMenum boldEnum,
100 RMenum italicEnum,
101 RMenum hJustifyEnum,
102 RMenum vJustifyEnum)
103
104 @pend
105
106 @astart
107 RMtextProps *toModify - a handle to an RMtextProps object (modified).
108
109 int fontEnum - an integer value that specifies a font. Must be one of
110 RM_FONT_SERIF, RM_FONT_SANS, RM_FONT_MONO, RM_FONT_SYMBOL or
111 RM_FONT_DINGBATS (input).
112
113 int sizeEnum - an integer value that specifies a typeface size. Must
114 be one of RM_FONT_XXS, RM_FONT_XS, RM_FONT_S, RM_FONT_M,
115 RM_FONT_L, RM_FONT_XL or RM_FONT_XXL (input).
116
117 RMenum boldEnum - an integer value that indicates if an emboldened
118 typeface should be used. Must be either RM_TRUE or RM_FALSE
119 (input).
120
121 RMenum italicEnum - an integer value that specifies if an italicized
122 typeface should be used. Must be either RM_TRUE or RM_FALSE
123 (input).
124
125 RMenum hJustifyEnum - an RMenum value that dicates a horizontal
126 justification policy for text. Must be one of RM_LEFT, RM_CENTER
127 or RM_RIGHT (input).
128
129 RMenum vJustifyEnum - an RMenum value that dictates a vertical
130 justification policy for text. Must be one of RM_BOTTOM, RM_CENTER
131 or RM_TOP (input).
132 @aend
133
134 @dstart
135
136 Typeface properties in RM are specified by assiging an RMtextProps
137 object to a scene graph node as a scene parameter. All descendent
138 nodes that contain text will be rendered according to the
139 specifications contained in the RMtextProps object. The intent of
140 this object is to provide control over text rendering across all
141 supported platforms with a single set of parameters.
142
143 This routine modifies an RMtextProps object to reflect the
144 caller-supplied parameters. RM_CHILL is returned upon success, or
145 RM_WHACKED upon failure.
146
147 Use rmTextPropsNew to create a new RMtextProps object, or
148 rmTextPropsDelete to delete an old one that is no longer needed.
149
150 fontEnum specifies a typeface family. On the X11 platform,
151 RM_FONT_SERIF corresponds to "adobe-times," RM_FONT_SANS to
152 "adobe-helvetica," RM_FONT_MONO to "adobe-courier," RM_FONT_SYMBOL to
153 "adobe-symbol" and RM_FONT_DINGBATS to "-*-*-zapfdingbats". On the
154 Win32 platform, the values of "times", "helvetica", "courier",
155 "symbol" and "zapfdingbats" are used.
156
157 sizeEnum specifies a particular point size for the face. RM_FONT_XXS,
158 RM_FONT_XS, RM_FONT_S, RM_FONT_M, RM_FONT_L, RM_FONT_XL and
159 RM_FONT_XXL correspond to 8, 10, 12, 14, 18, 24 and 34 points,
160 respectively, on both Win32 and X11 platforms.
161
162 boldEnum and italicEnum control emboldening and italicization of a
163 given typeface. These are specified with either RM_TRUE or RM_FALSE.
164 Specifying RM_TRUE turns on either emboldening or italicization,
165 while RM_FALSE turns them off.
166
167 Justification control is provided in both the horizontal and vertical
168 directions. Text is positioned with the use of either a 2D or 3D
169 coordinate at the RMprimitive level. Justification controls where the
170 text string appears in relationship to the on-screen projection of
171 the vertex coordinate. Left-justified text will cause the text string
172 to appear to the right of the projected vertex. Right-justified text
173 will appear to the left of the project vertex. Similarly, RM_TOP will
174 cause the text string to appear below the projected vertex, and
175 RM_BOTTOM will cause the text string to appear above the projected
176 vertex.
177
178 @dend
179 * ----------------------------------------------------
180 */
181 RMenum
rmTextPropsSetAttribs(RMtextProps * p,int font_enum,int size_enum,RMenum bold_enum,RMenum italic_enum,RMenum hJustify,RMenum vJustify)182 rmTextPropsSetAttribs (RMtextProps *p,
183 int font_enum,
184 int size_enum,
185 RMenum bold_enum,
186 RMenum italic_enum,
187 RMenum hJustify,
188 RMenum vJustify)
189 {
190 int parmsOK = 1;
191 RMenum rstat = RM_CHILL;
192
193 if (RM_ASSERT(p, "rmTextPropsSetAttribs() error: the input RMtextProps object pointer is NULL") == RM_WHACKED)
194 return(RM_WHACKED);
195
196 if (!((font_enum == RM_FONT_SERIF) || (font_enum == RM_FONT_SANS) || (font_enum == RM_FONT_MONO) ||
197 (font_enum == RM_FONT_SYMBOL) || (font_enum == RM_FONT_DINGBATS)))
198 {
199 parmsOK = 0;
200 rmWarning("rmTextPropsSetAttribs error: the input font enumerator is not valid.");
201 }
202
203 if (!((size_enum == RM_FONT_XXS) || (size_enum == RM_FONT_XS) || (size_enum == RM_FONT_S) || (size_enum == RM_FONT_M) ||
204 (size_enum == RM_FONT_L) || (size_enum == RM_FONT_L) || (size_enum == RM_FONT_XL) || (size_enum == RM_FONT_XXL)))
205 {
206 parmsOK = 0;
207 rmWarning("rmTextPropsSetAttribs error: the input size enumerator is not valid.");
208 }
209
210 if (!((bold_enum == RM_TRUE) || (bold_enum == RM_FALSE)))
211 {
212 parmsOK = 0;
213 rmWarning("rmTextPropsSetAttribs error: the input embolden enumerator is neither RM_TRUE nor RM_FALSE.");
214 }
215
216 if (!((italic_enum == RM_TRUE) || (italic_enum == RM_FALSE)))
217 {
218 parmsOK = 0;
219 rmWarning("rmTextPropsSetAttribs error: the input italicization enumerator is neither RM_TRUE nor RM_FALSE.");
220 }
221
222 if (!((hJustify == RM_LEFT) || (hJustify == RM_CENTER) || (hJustify == RM_RIGHT)))
223 {
224 parmsOK = 0;
225 rmWarning("rmTextPropsSetAttribs error: the input horizontal justification enumerator is not one of RM_LEFT, RM_CENTER nor RM_FALSE.");
226 }
227
228 if (!((vJustify == RM_TOP) || (vJustify == RM_CENTER) || (vJustify == RM_BOTTOM)))
229 {
230 parmsOK = 0;
231 rmWarning("rmTextPropsSetAttribs error: the input vertical justification enumerator is not one of RM_TOP, RM_CENTER nor RM_BOTTOM.");
232 }
233
234 if (parmsOK == 1)
235 {
236 p->fontEnum = font_enum;
237 p->italicEnum = italic_enum;
238 p->boldEnum = bold_enum;
239 p->sizeEnum = size_enum;
240 p->hJustify = hJustify;
241 p->vJustify = vJustify;
242 rstat = RM_CHILL;
243 }
244 else
245 rstat = RM_WHACKED;
246
247 return(rstat);
248 }
249
250
251 /*
252 * ----------------------------------------------------
253 * @Name rmTextPropsGetAttribs
254 @pstart
255 RMenum rmTextPropsGetAttribs (const RMtextProps *toQuery,
256 int *fontEnumReturn,
257 int *sizeEnumReturn,
258 RMenum *boldEnumReturn,
259 RMenum *italicEnumReturn,
260 RMenum *hJustifyReturn,
261 RMenum *vJustifyReturn)
262 @pend
263
264 @astart
265 const RMtextProps *toQuery - a handle to an RMtextProps object
266 (input).
267
268 int *fontEnumReturn, *sizeEnumReturn, *boldEnumReturn,
269 *italicEnumReturn - handles to return caller-supplied integers
270 (modified).
271
272 RMenum hJustifyReturn, *vJustifyReturn - handles to return
273 caller-supplied RMenums (modified). @aend
274
275 @dstart
276
277 Use this routine to obtain the current text properties from an
278 RMtextProps object. For each non-null RMenum parameter, the
279 corresponding attribute is copied from the RMtextProps object into
280 caller-supplied memory.
281
282 Returns RM_CHILL upon success, or RM_WHACKED upon failure.
283
284 See rmTextPropsSetAttributes for a description of the meaning of each
285 of the text property parameters.
286
287 @dend
288 * ----------------------------------------------------
289 */
290 RMenum
rmTextPropsGetAttribs(const RMtextProps * p,int * font_enum,int * size_enum,RMenum * bold_enum,RMenum * italic_enum,RMenum * hJustify,RMenum * vJustify)291 rmTextPropsGetAttribs (const RMtextProps *p,
292 int *font_enum,
293 int *size_enum,
294 RMenum *bold_enum,
295 RMenum *italic_enum,
296 RMenum *hJustify,
297 RMenum *vJustify)
298 {
299 if (RM_ASSERT(p, "rmTextPropsGetAttribs() error: the input RMtextProps object pointer is NULL") == RM_WHACKED)
300 return(RM_WHACKED);
301
302 if (font_enum != NULL)
303 *font_enum = p->fontEnum;
304
305 if (size_enum != NULL)
306 *size_enum = p->sizeEnum;
307
308 if (bold_enum != NULL)
309 *bold_enum = p->boldEnum;
310
311 if (italic_enum != NULL)
312 *italic_enum = p->italicEnum;
313
314 if (hJustify != NULL)
315 *hJustify = p->hJustify;
316
317 if (vJustify != NULL)
318 *vJustify = p->vJustify;
319
320 return(RM_CHILL);
321 }
322
323
324 /*
325 *
326 * RM internal font registry info:
327 *
328 * there is a finite number of different fonts that are supported through
329 * the RM interface. The number is computed as the product of the
330 * number of font families with the number of font sizes and the number
331 * of font styles.
332 *
333 * The font registry is an array of length (font_styles * font_sizes *
334 * font_styles). Each font registry object contains info about the
335 * font, once initialized. The info consists of an OpenGL display list
336 * base index and a boolean indicating whether or not the font has been
337 * "initialized" (OpenGL bitmap display lists built).
338 *
339 * The RM font registry represents the rectification between X11 and
340 * Win32 font handling. In Win32, the only way to render bitmap fonts
341 * in OpeNGL is via Wgl, and wgl won't let you have access to the
342 * raw bitmap data. Wgl encapsulates all rendered font bitmaps inside
343 * OpenGL display lists.
344 *
345 * the font registry mechanism is used by both X11 and Win32 versions
346 * of text rendering (and property querying) inside RM.
347 */
348
349 /* PRIVATE */
350 RMfontRegistry *
private_rmFontRegistryNew(void)351 private_rmFontRegistryNew(void)
352 {
353 /* potential number of fonts available at once in RM */
354 int num = RM_NUM_FONT_FACES * RM_NUM_FONT_SIZES * RM_NUM_FONT_STYLES;
355 RMfontRegistry *f;
356
357 f = (RMfontRegistry *)malloc(sizeof(RMfontRegistry)*num);
358
359 if (f == NULL)
360 return(NULL);
361
362 memset((void *)f, 0, sizeof(RMfontRegistry)*num);
363
364 return(f);
365 }
366
367 /* PRIVATE */
368 void
private_rmFontRegistryDelete(RMpipe * p,RMfontRegistry * fontRegistry)369 private_rmFontRegistryDelete(RMpipe *p,
370 RMfontRegistry *fontRegistry)
371 {
372 RMfontRegistry *fr;
373 #ifdef RM_WIN
374 HFONT font;
375 #elif RM_X
376 Font font;
377 XFontStruct *xfs;
378 #endif
379 int fontEnum;
380 int sizeEnum;
381 int italicEnum;
382 int boldEnum;
383
384 /* walk through all the font combinations, look for active fonts */
385 for (fontEnum=0; fontEnum<RM_NUM_FONT_FACES; fontEnum++)
386 {
387 for (sizeEnum=0; sizeEnum<RM_NUM_FONT_SIZES; sizeEnum++)
388 {
389 for (italicEnum=0; italicEnum<=1; italicEnum++)
390 {
391 for (boldEnum=0; boldEnum<=1; boldEnum++)
392 {
393 fr = private_rmFontRegistryEntry(fontEnum, sizeEnum,
394 italicEnum, boldEnum,
395 fontRegistry);
396 if (fr->initialized)
397 {
398 glDeleteLists(fr->listbase, fr->listCount);
399 #ifdef RM_WIN
400 font = (HFONT)(fr->fontinfo);
401 DeleteObject(font);
402 #elif RM_X
403 xfs = (XFontStruct *)(fr->fontinfo);
404 font = xfs->fid;
405 XFreeFont(rmxPipeGetDisplay(p), xfs);
406 #endif
407 }
408 }
409 }
410 }
411 }
412
413 free(fontRegistry);
414 }
415
416 /* PRIVATE */
417 int
private_rmFontRegistryIndex(int font_face,int font_size,int font_italic,int font_embolden)418 private_rmFontRegistryIndex (int font_face,
419 int font_size,
420 int font_italic,
421 int font_embolden)
422 {
423 /*
424 * compute an index into the font registry table from the input
425 * parms. this is a way of doing multidimensional array indexing.
426 */
427
428 int i, indx, xsize, xysize;
429
430 xsize = RM_NUM_FONT_STYLES;
431 xysize = xsize * RM_NUM_FONT_SIZES;
432
433 i = 0;
434 if (font_italic == RM_TRUE)
435 i |= 1;
436 if (font_embolden == RM_TRUE)
437 i |= 2;
438
439 indx = (font_face * xysize) + (font_size * xsize) + i;
440 return(indx);
441 }
442
443
444 /* PRIVATE */
445 RMfontRegistry *
private_rmFontRegistryEntry(int font_face,int font_size,int font_italic,int font_embolden,RMfontRegistry * f)446 private_rmFontRegistryEntry (int font_face,
447 int font_size,
448 int font_italic,
449 int font_embolden,
450 RMfontRegistry *f)
451 {
452 int indx = private_rmFontRegistryIndex(font_face, font_size, font_italic, font_embolden);
453
454 if (f == NULL)
455 return(NULL);
456
457 return(f + indx);
458 }
459
460 /* PRIVATE */
461 void
private_rmTextPropsCopy(const RMtextProps * s,RMtextProps * d)462 private_rmTextPropsCopy(const RMtextProps *s,
463 RMtextProps *d)
464 {
465 d->fontEnum = s->fontEnum;
466 d->italicEnum = s->italicEnum;
467 d->boldEnum = s->boldEnum;
468 d->sizeEnum = s->sizeEnum;
469 d->hJustify = s->hJustify;
470 d->vJustify = s->vJustify;
471 }
472 /* EOF */
473