8 #include <X11/IntrinsicP.h>
9 #include <X11/StringDefs.h>
14 static int StopSeen
= 0;
15 static ParseDrawFunction(), ParseDeviceControl();
16 static push_env(), pop_env();
18 #define HorizontalMove(dw, delta) ((dw)->dvi.state->x += (delta))
20 #define charWidth(fi,c) (\
22 (fi)->per_char[(c) - (fi)->min_char_or_byte2].width\
24 (fi)->max_bounds.width\
28 int charExists (fi
, c
)
34 if (c
< fi
->min_char_or_byte2
|| c
> fi
->max_char_or_byte2
)
36 p
= fi
->per_char
+ (c
- fi
->min_char_or_byte2
);
37 return (p
->lbearing
!= 0 || p
->rbearing
!= 0 || p
->width
!= 0
38 || p
->ascent
!= 0 || p
->descent
!= 0 || p
->attributes
!= 0);
43 register DviWidget dw
;
55 * make sure some state exists
61 switch (DviGetC(dw
, &c
)) {
64 case ' ': /* when input is text */
65 case 0: /* occasional noise creeps in */
67 case '{': /* push down current environment */
74 * two motion digits plus a character
76 case '0': case '1': case '2': case '3': case '4':
77 case '5': case '6': case '7': case '8': case '9':
78 HorizontalMove(dw
, (c
-'0')*10 +
79 DviGetC(dw
,&otherc
)-'0');
81 case 'c': /* single ascii character */
90 GetWord(dw
, Buffer
, BUFSIZ
);
98 map
= QueryFontMap (dw
, dw
->dvi
.state
->font_number
);
100 c
= DviCharIndex (map
, Buffer
);
102 for (i
= 1; map
= QueryFontMap (dw
, i
); i
++)
104 if ((c
= DviCharIndex (map
, Buffer
)) != -1) {
105 prevFont
= dw
->dvi
.state
->font_number
;
106 dw
->dvi
.state
->font_number
= i
;
116 * quick and dirty extents calculation:
118 if (dw
->dvi
.state
->y
+ 24 >= dw
->dvi
.extents
.y1
&&
119 dw
->dvi
.state
->y
- 24 <= dw
->dvi
.extents
.y2
&&
120 dw
->dvi
.state
->x
+ 24 >= dw
->dvi
.extents
.x1
&&
121 dw
->dvi
.state
->x
- 24 <= dw
->dvi
.extents
.x2
)
123 register XFontStruct
*font
;
124 register XTextItem
*text
;
126 if (!dw
->dvi
.display_enable
)
129 if (dw
->dvi
.state
->y
!= dw
->dvi
.cache
.y
||
130 dw
->dvi
.cache
.char_index
>= DVI_CHAR_CACHE_SIZE
)
133 * load a new font, if the current block is not empty,
136 if (dw
->dvi
.cache
.font_size
!= dw
->dvi
.state
->font_size
||
137 dw
->dvi
.cache
.font_number
!= dw
->dvi
.state
->font_number
)
139 dw
->dvi
.cache
.font_size
= dw
->dvi
.state
->font_size
;
140 dw
->dvi
.cache
.font_number
= dw
->dvi
.state
->font_number
;
141 dw
->dvi
.cache
.font
= QueryFont (dw
,
142 dw
->dvi
.cache
.font_number
,
143 dw
->dvi
.cache
.font_size
);
144 if (dw
->dvi
.cache
.cache
[dw
->dvi
.cache
.index
].nchars
!= 0) {
145 ++dw
->dvi
.cache
.index
;
146 if (dw
->dvi
.cache
.index
>= dw
->dvi
.cache
.max
)
148 dw
->dvi
.cache
.cache
[dw
->dvi
.cache
.index
].nchars
= 0;
151 if (dw
->dvi
.cache
.x
!= dw
->dvi
.state
->x
) {
152 if (dw
->dvi
.cache
.cache
[dw
->dvi
.cache
.index
].nchars
!= 0) {
153 ++dw
->dvi
.cache
.index
;
154 if (dw
->dvi
.cache
.index
>= dw
->dvi
.cache
.max
)
156 dw
->dvi
.cache
.cache
[dw
->dvi
.cache
.index
].nchars
= 0;
159 font
= dw
->dvi
.cache
.font
;
160 text
= &dw
->dvi
.cache
.cache
[dw
->dvi
.cache
.index
];
161 if (text
->nchars
== 0) {
162 text
->chars
= &dw
->dvi
.cache
.char_cache
[dw
->dvi
.cache
.char_index
];
163 text
->delta
= dw
->dvi
.state
->x
- dw
->dvi
.cache
.x
;
164 if (font
!= dw
->dvi
.font
) {
165 text
->font
= font
->fid
;
169 dw
->dvi
.cache
.x
+= text
->delta
;
171 if (charExists(font
, c
)) {
172 dw
->dvi
.cache
.char_cache
[dw
->dvi
.cache
.char_index
++] = (char) c
;
174 dw
->dvi
.cache
.x
+= charWidth(font
,c
);
178 dw
->dvi
.state
->font_number
= prevFont
;
180 case 'D': /* draw function */
181 GetLine(dw
, Buffer
, BUFSIZ
);
182 if (dw
->dvi
.display_enable
)
183 ParseDrawFunction(dw
, Buffer
);
185 case 's': /* ignore fractional sizes */
187 dw
->dvi
.state
->font_size
= n
;
191 dw
->dvi
.state
->font_number
= n
;
193 case 'H': /* absolute horizontal motion */
195 HorizontalGoto(dw
, k
);
197 case 'h': /* relative horizontal motion */
199 HorizontalMove(dw
, k
);
201 case 'w': /* word space */
211 case 'P': /* new spread */
213 case 'p': /* new page */
214 (void) GetNumber(dw
);
215 NextPage
= dw
->dvi
.current_page
+ 1;
216 RememberPagePosition(dw
, NextPage
);
221 goto NumberedCharacter
;
222 case 'n': /* end of line */
225 HorizontalGoto(dw
, 0);
227 case '+': /* continuation of X device control */
228 case '#': /* comment */
229 GetLine(dw
, NULL
, 0);
231 case 'x': /* device control */
232 ParseDeviceControl(dw
);
235 dw
->dvi
.last_page
= dw
->dvi
.current_page
;
237 return dw
->dvi
.current_page
;
250 new = (DviState
*) malloc (sizeof (*new));
252 *new = *(dw
->dvi
.state
);
255 new->font_number
= 1;
259 new->next
= dw
->dvi
.state
;
270 dw
->dvi
.state
= old
->next
;
278 while (dw
->dvi
.state
)
284 #define DRAW_ARGS_MAX 128
287 ParseDrawFunction(dw
, buf
)
291 int v
[DRAW_ARGS_MAX
];
295 v
[0] = v
[1] = v
[2] = v
[3] = 0;
301 for (i
= 0; i
< DRAW_ARGS_MAX
; i
++) {
302 if (sscanf(ptr
, "%d", v
+ i
) != 1)
306 while (*ptr
!= '\0' && *ptr
!= ' ')
311 case 'l': /* draw a line */
312 DrawLine(dw
, v
[0], v
[1]);
314 case 'c': /* circle */
315 DrawCircle(dw
, v
[0]);
318 DrawFilledCircle(dw
, v
[0]);
320 case 'e': /* ellipse */
321 DrawEllipse(dw
, v
[0], v
[1]);
324 DrawFilledEllipse(dw
, v
[0], v
[1]);
327 DrawArc(dw
, v
[0], v
[1], v
[2], v
[3]);
330 DrawPolygon(dw
, v
, i
);
333 DrawFilledPolygon(dw
, v
, i
);
335 case '~': /* wiggly line */
336 DrawSpline(dw
, v
, i
);
339 dw
->dvi
.line_thickness
= v
[0];
342 if (i
> 0 && v
[0] >= 0 && v
[0] <= DVI_FILL_MAX
)
347 warning("unknown drawing function %s", buf
);
354 dw
->dvi
.state
->x
+= v
[0];
359 dw
->dvi
.state
->y
+= v
[i
];
361 dw
->dvi
.state
->x
+= v
[i
];
367 ParseDeviceControl(dw
) /* Parse the x commands */
370 char str
[20], str1
[50], buf
[50];
372 extern int LastPage
, CurrentPage
;
374 GetWord (dw
, str
, 20);
375 switch (str
[0]) { /* crude for now */
376 case 'T': /* output device */
377 GetWord(dw
, str
, 20);
379 case 'i': /* initialize */
382 case 't': /* trailer */
384 case 'p': /* pause -- can restart */
389 case 'r': /* resolution when prepared */
390 SetDeviceResolution (dw
, GetNumber (dw
));
392 case 'f': /* font used */
394 GetWord(dw
, str
, 20);
395 GetLine(dw
, str1
, 50);
396 SetFontPosition(dw
, n
, str
, str1
);
398 case 'H': /* char height */
400 case 'S': /* slant */
403 while (DviGetC(dw
,&c
) != '\n') /* skip rest of input line */
413 c-continued-statement-offset: 8
417 c-tab-always-indent: nil