1 /* grDStyle.c -
2 *
3 * Parse and read in the display style file.
4 *
5 * *********************************************************************
6 * * Copyright (C) 1985, 1990 Regents of the University of California. *
7 * * Permission to use, copy, modify, and distribute this *
8 * * software and its documentation for any purpose and without *
9 * * fee is hereby granted, provided that the above copyright *
10 * * notice appear in all copies. The University of California *
11 * * makes no representations about the suitability of this *
12 * * software for any purpose. It is provided "as is" without *
13 * * express or implied warranty. Export of this software outside *
14 * * of the United States of America may require an export license. *
15 * *********************************************************************
16 *
17 * Portions of this code are Copyright (C) 2003 Open Circuit Design, Inc.,
18 * for MultiGiG Ltd.
19 */
20
21 #ifndef lint
22 static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/graphics/grDStyle.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $";
23 #endif /* not lint */
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29
30 #include "utils/magic.h"
31 #include "utils/malloc.h"
32 #include "utils/styles.h"
33 #include "utils/utils.h"
34 #include "textio/textio.h"
35 #include "utils/geometry.h"
36 #include "graphics/glyphs.h"
37 #include "windows/windows.h"
38 #include "graphics/graphics.h"
39 #include "graphics/graphicsInt.h"
40 #include "tiles/tile.h"
41 #include "utils/hash.h"
42 #include "database/database.h"
43 #include "dbwind/dbwind.h"
44
45 /* imports from other graphics files */
46 extern void (*grSetSPatternPtr)();
47 extern void (*grDefineCursorPtr)();
48
49 /* data structures local to this file only */
50
51 /* Define a linked-list record to keep track of styles prior */
52 /* to allocating the fixed array GrStyleTable. */
53
54 typedef struct _dstylelink {
55 GR_STYLE_LINE style;
56 char shortname;
57 struct _dstylelink *next;
58 } dstylelink;
59
60 /* data structures local to the graphics module */
61
62 extern int grBitPlaneMask; /* Mask of the valid bit-plane bits. */
63
64 static GrGlyphs *grCursorGlyphs = NULL;
65 static dstylelink *dstylehead = NULL;
66
67 global int **GrStippleTable = NULL;
68 global int grNumStipples = 0;
69
70 /* MUST be the same indices as the constants in graphicsInt.h */
71 char *fillStyles[] = {
72 "solid",
73 "cross",
74 "outline",
75 "stipple",
76 "grid",
77 NULL };
78
79
80
81 /* Internal constants for each section of the style file. */
82 /* These are bitmask-mapped so the display style reader */
83 /* can check that the section are read in proper order. */
84
85 #define IGNORE -1
86 #define DISP_STYLES 1
87 #define LAYOUT_STYLES 2
88 #define PALE_STYLES 4
89 #define STIPPLES 8
90 #define DISP_VERSION 16
91
92 #define STRLEN 200
93
94 /* Global variables to export to other modules */
95
96 int GrStyleNames[128]; /* short names for styles */
97 GR_STYLE_LINE *GrStyleTable;
98
99
100
101 bool
GrDrawGlyphNum(num,xoff,yoff)102 GrDrawGlyphNum(num, xoff, yoff)
103 int num;
104 int xoff;
105 int yoff;
106 {
107 Point p;
108
109 p.p_x = xoff;
110 p.p_y = yoff;
111 if (num >= grCursorGlyphs->gr_num) return FALSE;
112 GrDrawGlyph(grCursorGlyphs->gr_glyph[num], &p);
113 return TRUE;
114 }
115
116 /*
117 * ----------------------------------------------------------------------------
118 *
119 * GrGetStyleFromName --
120 *
121 * Return an integer style number given a "long name".
122 *
123 * Results:
124 * Integer style number, or -1 if no style matches the name.
125 *
126 * Side effects:
127 * None.
128 *
129 * ----------------------------------------------------------------------------
130 */
131
132 int
GrGetStyleFromName(stylename)133 GrGetStyleFromName(stylename)
134 char *stylename;
135 {
136 int style;
137 int maxstyles = TECHBEGINSTYLES + (DBWNumStyles * 2);
138
139 for (style = 0; style < maxstyles; style++)
140 if (GrStyleTable[style].longname != NULL)
141 if (!strcmp(stylename, GrStyleTable[style].longname))
142 break;
143
144 return (style == maxstyles) ? -1 : style;
145 }
146
147 /*
148 * ----------------------------------------------------------------------------
149 *
150 * GrResetStyles --
151 *
152 * Free memory associated with the display styles in preparation for
153 * re-reading the styles file.
154 *
155 * Results:
156 * None.
157 *
158 * Side effects:
159 * Allocated memory free'd.
160 *
161 * ----------------------------------------------------------------------------
162 */
163
164 void
GrResetStyles()165 GrResetStyles()
166 {
167 int i;
168
169 if (DBWNumStyles == 0) return; /* Nothing has been allocated yet */
170
171 for (i = 0; i < TECHBEGINSTYLES + (DBWNumStyles * 2); i++)
172 if (GrStyleTable[i].longname != NULL)
173 freeMagic(GrStyleTable[i].longname);
174
175 freeMagic((char *)GrStyleTable);
176 GrStyleTable = NULL;
177 DBWNumStyles = 0;
178 }
179
180
181 /*
182 * ----------------------------------------------------------------------------
183 * styleBuildDisplayStyle:
184 *
185 * Take one line of the display_styles section and process it.
186 *
187 * Results:
188 * True if things worked, false otherwise.
189 *
190 * Side effects:
191 * none
192 * ----------------------------------------------------------------------------
193 */
194
195 bool
styleBuildDisplayStyle(line,version)196 styleBuildDisplayStyle(line, version)
197 char *line;
198 int version;
199 {
200 bool res;
201 int argsread;
202 int ord = 1, mask, color, outline, nfill, stipple;
203 char shortName, longName[52];
204 char fill[42], ordstr[12], colorName[30];
205 dstylelink *newstyle, *sstyle;
206
207 char v6scanline[] = "%10s %o %29s %o %40s %d %c %50s";
208 char v7scanline[] = "%10s %i %29s %i %40s %d %c %50s";
209
210 char *scanline = (version > 6) ? v7scanline : v6scanline;
211
212 res = TRUE;
213
214 if ((argsread = sscanf(line, scanline,
215 ordstr, &mask, colorName, &outline, fill, &stipple,
216 &shortName, &longName)) < 7)
217 {
218 res = FALSE;
219 }
220 else
221 {
222 newstyle = (dstylelink *)mallocMagic(sizeof(dstylelink));
223 newstyle->next = dstylehead;
224 dstylehead = newstyle; /* note that dstylehead has styles
225 * in reverse order.
226 */
227
228 /* Allow colors to be specified by index or by name */
229 if (sscanf(colorName, ((version > 6) ? "%i" : "%o"), &color) == 0)
230 color = GrNameToColor(colorName);
231
232 newstyle->style.mask = (mask & grBitPlaneMask);
233 newstyle->style.color = (color & grBitPlaneMask);
234 newstyle->style.outline = outline;
235 if (StrIsInt(ordstr))
236 {
237 newstyle->style.idx = atoi(ordstr);
238 if (newstyle->style.idx > ord)
239 ord = newstyle->style.idx + 1;
240 }
241 else
242 newstyle->style.idx = ord++;
243 nfill = LookupFull(fill, fillStyles);
244 if (nfill < 0)
245 res = FALSE;
246 newstyle->style.fill = nfill;
247 newstyle->style.stipple = stipple;
248
249 /* Add short style name reverse lookup table entry */
250 newstyle->shortname = shortName & 0x7f;
251
252 if (argsread == 8)
253 newstyle->style.longname = StrDup(NULL, longName);
254 else
255 newstyle->style.longname = NULL;
256 }
257 return(res);
258 }
259
260
261 /*
262 * ----------------------------------------------------------------------------
263 * styleBuildStippleStyle:
264 *
265 * Take one line of the stipples section and process it.
266 *
267 * Results:
268 * True if things worked, false otherwise.
269 *
270 * Side effects:
271 * none
272 * ----------------------------------------------------------------------------
273 */
274
275 bool
styleBuildStipplesStyle(line,version)276 styleBuildStipplesStyle(line, version)
277 char *line;
278 int version;
279 {
280 bool res;
281 int ord;
282 int row[8];
283
284 char v6scanline[] = "%d %o %o %o %o %o %o %o %o";
285 char v7scanline[] = "%d %x %x %x %x %x %x %x %x";
286
287 char *scanline = (version > 6) ? v7scanline : v6scanline;
288
289 res = TRUE;
290
291 if (sscanf(line, scanline,
292 &ord, &(row[0]), &(row[1]), &(row[2]), &(row[3]),
293 &(row[4]), &(row[5]), &(row[6]), &(row[7]) ) != 9)
294 {
295 res = FALSE;
296 }
297 else
298 {
299 if (ord < 0)
300 res = FALSE;
301 else
302 {
303 int i, j, ns, **sttable;
304
305 ns = MAX(grNumStipples, ord + 1);
306 if (ns > grNumStipples)
307 {
308 /* Grab in blocks of 8 to avoid over-use of malloc. . . */
309 if (ns < (grNumStipples + 8)) ns = grNumStipples + 8;
310
311 sttable = (int **)mallocMagic(ns * sizeof(int *));
312 for (i = 0; i < grNumStipples; i++)
313 sttable[i] = GrStippleTable[i];
314 for (; i < ns; i++)
315 {
316 sttable[i] = (int *)mallocMagic(8 * sizeof(int));
317 for (j = 0; j < 8; j++)
318 sttable[i][j] = 0;
319 }
320 if (GrStippleTable) freeMagic((char *)GrStippleTable);
321 GrStippleTable = sttable;
322 grNumStipples = ns;
323 }
324 for (i = 0; i < 8; i++)
325 GrStippleTable[ord][i] = row[i];
326 }
327 }
328 return(res);
329 }
330
331
332 /*
333 * ----------------------------------------------------------------------------
334 * GrLoadCursors --
335 *
336 * Loads the graphics cursors from a given file. There must not be
337 * any window locks set, as this routine may need to write to the
338 * display.
339 *
340 * Results:
341 * True if things worked, false otherwise.
342 *
343 * Side effects:
344 * Cursor patterns are loaded, which may involve writing to the
345 * display. The file from which the cursors are read is determined
346 * by combining grCursorType (a driver-dependent string) with a
347 * ".glyphs" extension.
348 * ----------------------------------------------------------------------------
349 */
350
351 bool
GrLoadCursors(path,libPath)352 GrLoadCursors(path, libPath)
353 char *path;
354 char *libPath;
355 {
356 if (grCursorGlyphs != (GrGlyphs *) NULL)
357 {
358 GrFreeGlyphs(grCursorGlyphs);
359 grCursorGlyphs = (GrGlyphs *) NULL;
360 }
361
362 if (!GrReadGlyphs(grCursorType, path, libPath, &grCursorGlyphs))
363 {
364 return FALSE;
365 }
366
367 if (grDefineCursorPtr == NULL)
368 TxError("Display does not have a programmable cursor.\n");
369 else
370 (*grDefineCursorPtr)(grCursorGlyphs);
371
372 return TRUE;
373 }
374
375
376 /*
377 * ----------------------------------------------------------------------------
378 * GrLoadStyles:
379 *
380 * Reads in a display style file. This has the effect of setting the
381 * box styles and stipple patterns.
382 *
383 * Results:
384 * -1 if the file contained a format error.
385 * -2 if the file was not found.
386 * 0 if everything went OK.
387 *
388 * Side effects:
389 * global variables are changed.
390 * ----------------------------------------------------------------------------
391 */
392
393 int
GrLoadStyles(techType,path,libPath)394 GrLoadStyles(techType, path, libPath)
395 char *techType; /* Type of styles wanted by the technology
396 * file (usually "std"). We tack two things
397 * onto this name: the type of styles
398 * wanted by the display, and a version
399 * suffix. This three-part name is used
400 * to look up the actual display styles
401 * file.
402 */
403 char *path;
404 char *libPath;
405 {
406 FILE *inp;
407 int res = 0;
408 int i, scount, processed = DISP_VERSION;
409 char fullName[256];
410 dstylelink *sstyle;
411 int MaxTechStyles = 0, MaxTileStyles = 0;
412
413 /* The dstyle file format version number was buried in the filename */
414 /* prior to version 6. Therefore versions which do not have a */
415 /* "version" keyword in the file should default to version 5. */
416 int version = 5;
417
418 /* Reset number of styles to zero */
419 GrResetStyles();
420
421 for (i = 0; i < 128; i++) GrStyleNames[i] = 0;
422
423 (void) sprintf(fullName, "%.100s.%.100s.dstyle", techType, grDStyleType);
424
425 inp = PaOpen(fullName, "r", (char *) NULL, path, libPath, (char **) NULL);
426 if (inp == NULL)
427 {
428 /* Try old format ".dstyle5"? */
429 (void) sprintf(fullName, "%.100s.%.100s.dstyle5", techType, grDStyleType);
430 inp = PaOpen(fullName, "r", (char *) NULL, path, libPath, (char **) NULL);
431 if (inp == NULL)
432 {
433 TxError("Couldn't open display styles file \"%s\"\n", fullName);
434 return(-2);
435 }
436 }
437 else
438 {
439 char line[STRLEN], sectionName[STRLEN];
440 char *sres;
441 bool newSection = FALSE;
442 int section;
443
444 while (TRUE)
445 {
446 sres = fgets(line, STRLEN, inp);
447 if (sres == NULL) break;
448 if (StrIsWhite(line, FALSE))
449 newSection = TRUE;
450 else if (line[0] == '#')
451 {
452 /* comment line */
453 }
454 else if (newSection)
455 {
456 if (sscanf(line, "%s", sectionName) != 1)
457 {
458 TxError("File contained format error: "
459 "unable to read section name.\n");
460 res = -1;
461 }
462 if (strcmp(sectionName, "version") == 0)
463 {
464 if (sscanf(line, "%*s %d", &version) != 1)
465 {
466 TxError("DStyle format version could not be "
467 "read: assuming version 6\n");
468 version = 6;
469 }
470 section = DISP_VERSION;
471 }
472 else if (strcmp(sectionName, "display_styles") == 0)
473 {
474 int locbitplanes;
475
476 if ((processed & (LAYOUT_STYLES | PALE_STYLES)) != 0)
477 {
478 TxError("DStyle sections out of order: display_styles must "
479 "come before layout_styles and pale_styles\n");
480 res = -1;
481 }
482 section = DISP_STYLES;
483 scount = 0;
484 }
485 else if (strcmp(sectionName, "layout_styles") == 0)
486 {
487 if ((processed & PALE_STYLES) != 0)
488 {
489 TxError("DStyle sections out of order: layout_styles must "
490 "come before pale_styles\n");
491 MainExit(1);
492 }
493 section = LAYOUT_STYLES;
494 if (scount < TECHBEGINSTYLES)
495 {
496 TxError("Error: Display style file defines only %d of "
497 "%d required internal styles.\n", scount,
498 TECHBEGINSTYLES);
499 }
500 else if (scount > TECHBEGINSTYLES)
501 {
502 TxError("Error: Display style file defines too many (%d) "
503 "internal styles; should be %d.\n", scount,
504 TECHBEGINSTYLES);
505 }
506 scount = 0;
507 }
508 else if (strcmp(sectionName, "pale_styles") == 0)
509 {
510 section = PALE_STYLES;
511 MaxTechStyles = scount + TECHBEGINSTYLES;
512 scount = 0;
513 }
514 else if (strcmp(sectionName, "stipples") == 0)
515 {
516 section = STIPPLES;
517 if (grNumStipples > 0)
518 {
519 while (grNumStipples > 0)
520 freeMagic((char *)GrStippleTable[--grNumStipples]);
521 freeMagic((char *)GrStippleTable);
522 GrStippleTable = NULL;
523 }
524 }
525 else
526 {
527 if (StrIsInt(sectionName))
528 {
529 TxError("Unexpected empty line in .dstyle file.\n");
530 newSection = FALSE;
531 goto recovery;
532 }
533 TxError("Bad section name \"%s\" in .dstyle file.\n",
534 sectionName);
535 section = IGNORE;
536 }
537 newSection = FALSE;
538 processed |= section;
539 }
540 else
541 {
542 int newres = TRUE;
543
544 recovery:
545 switch (section)
546 {
547 case LAYOUT_STYLES:
548 case PALE_STYLES:
549 case DISP_STYLES:
550 newres = styleBuildDisplayStyle(line, version);
551 scount++;
552 break;
553 case STIPPLES:
554 newres = styleBuildStipplesStyle(line, version);
555 break;
556 case DISP_VERSION:
557 case IGNORE:
558 break;
559 default:
560 TxError("Internal error in GrStyle\n");
561 break;
562 }
563 if (!newres)
564 {
565 TxError("Style line contained format error: %s", line);
566 res = -1;
567 }
568 }
569 }
570 }
571 if (fclose(inp) == EOF)
572 TxError("Could not close styles file.\n");
573
574 if ((processed | STIPPLES) != (LAYOUT_STYLES | DISP_STYLES
575 | PALE_STYLES | STIPPLES | DISP_VERSION))
576 {
577 TxError("Not all required style sections were read. Missing"
578 " sections are:");
579 if (!(processed & DISP_STYLES))
580 TxError(" display_styles");
581 if (!(processed & LAYOUT_STYLES))
582 TxError(" layout_styles");
583 if (!(processed & PALE_STYLES))
584 TxError(" pale_styles");
585 if (!(processed & DISP_VERSION))
586 TxError(" version");
587 TxError("\n");
588 res = -1;
589 }
590 else
591 {
592 if (grSetSPatternPtr)
593 (*grSetSPatternPtr)(GrStippleTable, grNumStipples);
594
595 if ((MaxTechStyles - TECHBEGINSTYLES) != scount)
596 {
597 TxError("Error: Number of pale styles (%d) is different from "
598 "the number of layout styles (%d)\n",
599 scount, MaxTechStyles - TECHBEGINSTYLES);
600 res = -1;
601 }
602 else
603 {
604 DBWNumStyles = scount;
605 MaxTileStyles = MaxTechStyles + scount;
606
607 GrStyleTable = (GR_STYLE_LINE *)mallocMagic(MaxTileStyles *
608 sizeof(GR_STYLE_LINE));
609
610 /* Fill in table backwards, since linked list is a stack */
611 sstyle = dstylehead;
612 for (i = MaxTileStyles - 1; i >= 0; i--)
613 {
614 if (sstyle == NULL)
615 {
616 GrStyleTable[i].longname = NULL;
617 break;
618 }
619 else
620 {
621 GrStyleTable[i] = sstyle->style;
622 /* Add short style name reverse lookup table entry */
623 GrStyleNames[(int)(sstyle->shortname)] = i;
624 freeMagic(sstyle);
625 sstyle = sstyle->next;
626 }
627 }
628 dstylehead = NULL;
629 }
630 }
631 if (res != 0) GrResetStyles();
632 return(res);
633 }
634