1 |
|
---|
2 | /*
|
---|
3 | * bltPs.c --
|
---|
4 | *
|
---|
5 | * This module implements general PostScript conversion routines.
|
---|
6 | *
|
---|
7 | * Copyright 1991-1998 Lucent Technologies, Inc.
|
---|
8 | *
|
---|
9 | * Permission to use, copy, modify, and distribute this software and
|
---|
10 | * its documentation for any purpose and without fee is hereby
|
---|
11 | * granted, provided that the above copyright notice appear in all
|
---|
12 | * copies and that both that the copyright notice and warranty
|
---|
13 | * disclaimer appear in supporting documentation, and that the names
|
---|
14 | * of Lucent Technologies any of their entities not be used in
|
---|
15 | * advertising or publicity pertaining to distribution of the software
|
---|
16 | * without specific, written prior permission.
|
---|
17 | *
|
---|
18 | * Lucent Technologies disclaims all warranties with regard to this
|
---|
19 | * software, including all implied warranties of merchantability and
|
---|
20 | * fitness. In no event shall Lucent Technologies be liable for any
|
---|
21 | * special, indirect or consequential damages or any damages
|
---|
22 | * whatsoever resulting from loss of use, data or profits, whether in
|
---|
23 | * an action of contract, negligence or other tortuous action, arising
|
---|
24 | * out of or in connection with the use or performance of this
|
---|
25 | * software.
|
---|
26 | */
|
---|
27 |
|
---|
28 | #include "bltInt.h"
|
---|
29 | #include "bltPs.h"
|
---|
30 |
|
---|
31 | #include <X11/Xutil.h>
|
---|
32 | #include <X11/Xatom.h>
|
---|
33 | #if defined(__STDC__)
|
---|
34 | #include <stdarg.h>
|
---|
35 | #else
|
---|
36 | #include <varargs.h>
|
---|
37 | #endif
|
---|
38 |
|
---|
39 | #define PS_MAXPATH 1500 /* Maximum number of components in a PostScript
|
---|
40 | * (level 1) path. */
|
---|
41 |
|
---|
42 | PsToken
|
---|
43 | Blt_GetPsToken(interp, tkwin)
|
---|
44 | Tcl_Interp *interp;
|
---|
45 | Tk_Window tkwin;
|
---|
46 | {
|
---|
47 | struct PsTokenStruct *tokenPtr;
|
---|
48 |
|
---|
49 | tokenPtr = Blt_Malloc(sizeof(struct PsTokenStruct));
|
---|
50 | assert(tokenPtr);
|
---|
51 |
|
---|
52 | tokenPtr->fontVarName = tokenPtr->colorVarName = NULL;
|
---|
53 | tokenPtr->interp = interp;
|
---|
54 | tokenPtr->tkwin = tkwin;
|
---|
55 | tokenPtr->colorMode = PS_MODE_COLOR;
|
---|
56 | Tcl_DStringInit(&(tokenPtr->dString));
|
---|
57 | return tokenPtr;
|
---|
58 | }
|
---|
59 |
|
---|
60 | void
|
---|
61 | Blt_ReleasePsToken(tokenPtr)
|
---|
62 | struct PsTokenStruct *tokenPtr;
|
---|
63 | {
|
---|
64 | Tcl_DStringFree(&(tokenPtr->dString));
|
---|
65 | Blt_Free(tokenPtr);
|
---|
66 | }
|
---|
67 |
|
---|
68 | char *
|
---|
69 | Blt_PostScriptFromToken(tokenPtr)
|
---|
70 | struct PsTokenStruct *tokenPtr;
|
---|
71 | {
|
---|
72 | return Tcl_DStringValue(&(tokenPtr->dString));
|
---|
73 | }
|
---|
74 |
|
---|
75 | char *
|
---|
76 | Blt_ScratchBufferFromToken(tokenPtr)
|
---|
77 | struct PsTokenStruct *tokenPtr;
|
---|
78 | {
|
---|
79 | return tokenPtr->scratchArr;
|
---|
80 | }
|
---|
81 |
|
---|
82 | void
|
---|
83 | Blt_AppendToPostScript
|
---|
84 | TCL_VARARGS_DEF(PsToken, arg1)
|
---|
85 | {
|
---|
86 | va_list argList;
|
---|
87 | struct PsTokenStruct *tokenPtr;
|
---|
88 | char *string;
|
---|
89 |
|
---|
90 | tokenPtr = TCL_VARARGS_START(struct PsTokenStruct, arg1, argList);
|
---|
91 | for (;;) {
|
---|
92 | string = va_arg(argList, char *);
|
---|
93 | if (string == NULL) {
|
---|
94 | break;
|
---|
95 | }
|
---|
96 | Tcl_DStringAppend(&(tokenPtr->dString), string, -1);
|
---|
97 | }
|
---|
98 | }
|
---|
99 |
|
---|
100 | void
|
---|
101 | Blt_FormatToPostScript
|
---|
102 | TCL_VARARGS_DEF(PsToken, arg1)
|
---|
103 | {
|
---|
104 | va_list argList;
|
---|
105 | struct PsTokenStruct *tokenPtr;
|
---|
106 | char *fmt;
|
---|
107 |
|
---|
108 | tokenPtr = TCL_VARARGS_START(struct PsTokenStruct, arg1, argList);
|
---|
109 | fmt = va_arg(argList, char *);
|
---|
110 | vsprintf(tokenPtr->scratchArr, fmt, argList);
|
---|
111 | va_end(argList);
|
---|
112 | Tcl_DStringAppend(&(tokenPtr->dString), tokenPtr->scratchArr, -1);
|
---|
113 | }
|
---|
114 |
|
---|
115 | int
|
---|
116 | Blt_FileToPostScript(tokenPtr, fileName)
|
---|
117 | struct PsTokenStruct *tokenPtr;
|
---|
118 | char *fileName;
|
---|
119 | {
|
---|
120 | Tcl_Channel channel;
|
---|
121 | Tcl_DString dString;
|
---|
122 | Tcl_Interp *interp;
|
---|
123 | char *buf;
|
---|
124 | char *libDir;
|
---|
125 | int nBytes;
|
---|
126 |
|
---|
127 | interp = tokenPtr->interp;
|
---|
128 | buf = tokenPtr->scratchArr;
|
---|
129 |
|
---|
130 | /*
|
---|
131 | * Read in a standard prolog file from file and append it to the
|
---|
132 | * PostScript output stored in the Tcl_DString in tokenPtr.
|
---|
133 | */
|
---|
134 |
|
---|
135 | libDir = (char *)Tcl_GetVar(interp, "blt_library", TCL_GLOBAL_ONLY);
|
---|
136 | if (libDir == NULL) {
|
---|
137 | Tcl_AppendResult(interp, "couldn't find BLT script library:",
|
---|
138 | "global variable \"blt_library\" doesn't exist", (char *)NULL);
|
---|
139 | return TCL_ERROR;
|
---|
140 | }
|
---|
141 | Tcl_DStringInit(&dString);
|
---|
142 | Tcl_DStringAppend(&dString, libDir, -1);
|
---|
143 | Tcl_DStringAppend(&dString, "/", -1);
|
---|
144 | Tcl_DStringAppend(&dString, fileName, -1);
|
---|
145 | fileName = Tcl_DStringValue(&dString);
|
---|
146 | Blt_AppendToPostScript(tokenPtr, "\n% including file \"", fileName,
|
---|
147 | "\"\n\n", (char *)NULL);
|
---|
148 | channel = Tcl_OpenFileChannel(interp, fileName, "r", 0);
|
---|
149 | if (channel == NULL) {
|
---|
150 | Tcl_AppendResult(interp, "couldn't open prologue file \"", fileName,
|
---|
151 | "\": ", Tcl_PosixError(interp), (char *)NULL);
|
---|
152 | return TCL_ERROR;
|
---|
153 | }
|
---|
154 | for(;;) {
|
---|
155 | nBytes = Tcl_Read(channel, buf, PSTOKEN_BUFSIZ);
|
---|
156 | if (nBytes < 0) {
|
---|
157 | Tcl_AppendResult(interp, "error reading prologue file \"",
|
---|
158 | fileName, "\": ", Tcl_PosixError(interp),
|
---|
159 | (char *)NULL);
|
---|
160 | Tcl_Close(interp, channel);
|
---|
161 | Tcl_DStringFree(&dString);
|
---|
162 | return TCL_ERROR;
|
---|
163 | }
|
---|
164 | if (nBytes == 0) {
|
---|
165 | break;
|
---|
166 | }
|
---|
167 | buf[nBytes] = '\0';
|
---|
168 | Blt_AppendToPostScript(tokenPtr, buf, (char *)NULL);
|
---|
169 | }
|
---|
170 | Tcl_DStringFree(&dString);
|
---|
171 | Tcl_Close(interp, channel);
|
---|
172 | return TCL_OK;
|
---|
173 | }
|
---|
174 | /*
|
---|
175 | *----------------------------------------------------------------------
|
---|
176 | *
|
---|
177 | * XColorToPostScript --
|
---|
178 | *
|
---|
179 | * Convert the a XColor (from its RGB values) to a PostScript
|
---|
180 | * command. If a Tk color map variable exists, it will be
|
---|
181 | * consulted for a PostScript translation based upon the color
|
---|
182 | * name.
|
---|
183 | *
|
---|
184 | * Maps an X color intensity (0 to 2^16-1) to a floating point
|
---|
185 | * value [0..1]. Many versions of Tk don't properly handle the
|
---|
186 | * the lower 8 bits of the color intensity, so we can only
|
---|
187 | * consider the upper 8 bits.
|
---|
188 | *
|
---|
189 | * Results:
|
---|
190 | * The string representing the color mode is returned.
|
---|
191 | *
|
---|
192 | *----------------------------------------------------------------------
|
---|
193 | */
|
---|
194 | static void
|
---|
195 | XColorToPostScript(tokenPtr, colorPtr)
|
---|
196 | struct PsTokenStruct *tokenPtr;
|
---|
197 | XColor *colorPtr; /* Color value to be converted */
|
---|
198 | {
|
---|
199 | /*
|
---|
200 | * Shift off the lower byte before dividing because some versions
|
---|
201 | * of Tk don't fill the lower byte correctly.
|
---|
202 | */
|
---|
203 | Blt_FormatToPostScript(tokenPtr, "%g %g %g",
|
---|
204 | ((double)(colorPtr->red >> 8) / 255.0),
|
---|
205 | ((double)(colorPtr->green >> 8) / 255.0),
|
---|
206 | ((double)(colorPtr->blue >> 8) / 255.0));
|
---|
207 | }
|
---|
208 |
|
---|
209 | void
|
---|
210 | Blt_BackgroundToPostScript(tokenPtr, colorPtr)
|
---|
211 | struct PsTokenStruct *tokenPtr;
|
---|
212 | XColor *colorPtr;
|
---|
213 | {
|
---|
214 | /* If the color name exists in Tcl array variable, use that translation */
|
---|
215 | if (tokenPtr->colorVarName != NULL) {
|
---|
216 | CONST char *psColor;
|
---|
217 |
|
---|
218 | psColor = Tcl_GetVar2(tokenPtr->interp, tokenPtr->colorVarName,
|
---|
219 | Tk_NameOfColor(colorPtr), 0);
|
---|
220 | if (psColor != NULL) {
|
---|
221 | Blt_AppendToPostScript(tokenPtr, " ", psColor, "\n", (char *)NULL);
|
---|
222 | return;
|
---|
223 | }
|
---|
224 | }
|
---|
225 | XColorToPostScript(tokenPtr, colorPtr);
|
---|
226 | Blt_AppendToPostScript(tokenPtr, " SetBgColor\n", (char *)NULL);
|
---|
227 | }
|
---|
228 |
|
---|
229 | void
|
---|
230 | Blt_ForegroundToPostScript(tokenPtr, colorPtr)
|
---|
231 | struct PsTokenStruct *tokenPtr;
|
---|
232 | XColor *colorPtr;
|
---|
233 | {
|
---|
234 | /* If the color name exists in Tcl array variable, use that translation */
|
---|
235 | if (tokenPtr->colorVarName != NULL) {
|
---|
236 | CONST char *psColor;
|
---|
237 |
|
---|
238 | psColor = Tcl_GetVar2(tokenPtr->interp, tokenPtr->colorVarName,
|
---|
239 | Tk_NameOfColor(colorPtr), 0);
|
---|
240 | if (psColor != NULL) {
|
---|
241 | Blt_AppendToPostScript(tokenPtr, " ", psColor, "\n", (char *)NULL);
|
---|
242 | return;
|
---|
243 | }
|
---|
244 | }
|
---|
245 | XColorToPostScript(tokenPtr, colorPtr);
|
---|
246 | Blt_AppendToPostScript(tokenPtr, " SetFgColor\n", (char *)NULL);
|
---|
247 | }
|
---|
248 |
|
---|
249 | /*
|
---|
250 | *----------------------------------------------------------------------
|
---|
251 | *
|
---|
252 | * ReverseBits --
|
---|
253 | *
|
---|
254 | * Convert a byte from a X image into PostScript image order.
|
---|
255 | * This requires not only the nybbles to be reversed but also
|
---|
256 | * their bit values.
|
---|
257 | *
|
---|
258 | * Results:
|
---|
259 | * The converted byte is returned.
|
---|
260 | *
|
---|
261 | *----------------------------------------------------------------------
|
---|
262 | */
|
---|
263 | INLINE static unsigned char
|
---|
264 | ReverseBits(byte)
|
---|
265 | register unsigned char byte;
|
---|
266 | {
|
---|
267 | byte = ((byte >> 1) & 0x55) | ((byte << 1) & 0xaa);
|
---|
268 | byte = ((byte >> 2) & 0x33) | ((byte << 2) & 0xcc);
|
---|
269 | byte = ((byte >> 4) & 0x0f) | ((byte << 4) & 0xf0);
|
---|
270 | return byte;
|
---|
271 | }
|
---|
272 |
|
---|
273 | /*
|
---|
274 | *----------------------------------------------------------------------
|
---|
275 | *
|
---|
276 | * ByteToHex --
|
---|
277 | *
|
---|
278 | * Convert a byte to its ASCII hexidecimal equivalent.
|
---|
279 | *
|
---|
280 | * Results:
|
---|
281 | * The converted 2 ASCII character string is returned.
|
---|
282 | *
|
---|
283 | *----------------------------------------------------------------------
|
---|
284 | */
|
---|
285 | INLINE static void
|
---|
286 | ByteToHex(byte, string)
|
---|
287 | register unsigned char byte;
|
---|
288 | char *string;
|
---|
289 | {
|
---|
290 | static char hexDigits[] = "0123456789ABCDEF";
|
---|
291 |
|
---|
292 | string[0] = hexDigits[byte >> 4];
|
---|
293 | string[1] = hexDigits[byte & 0x0F];
|
---|
294 | }
|
---|
295 |
|
---|
296 | #ifdef WIN32
|
---|
297 | /*
|
---|
298 | * -------------------------------------------------------------------------
|
---|
299 | *
|
---|
300 | * Blt_BitmapDataToPostScript --
|
---|
301 | *
|
---|
302 | * Output a PostScript image string of the given bitmap image.
|
---|
303 | * It is assumed the image is one bit deep and a zero value
|
---|
304 | * indicates an off-pixel. To convert to PostScript, the bits
|
---|
305 | * need to be reversed from the X11 image order.
|
---|
306 | *
|
---|
307 | * Results:
|
---|
308 | * None.
|
---|
309 | *
|
---|
310 | * Side Effects:
|
---|
311 | * The PostScript image string is appended.
|
---|
312 | *
|
---|
313 | * -------------------------------------------------------------------------
|
---|
314 | */
|
---|
315 | void
|
---|
316 | Blt_BitmapDataToPostScript(
|
---|
317 | struct PsTokenStruct *tokenPtr,
|
---|
318 | Display *display,
|
---|
319 | Pixmap bitmap,
|
---|
320 | int width, int height)
|
---|
321 | {
|
---|
322 | register unsigned char byte;
|
---|
323 | register int x, y, bitPos;
|
---|
324 | unsigned long pixel;
|
---|
325 | int byteCount;
|
---|
326 | char string[10];
|
---|
327 | unsigned char *srcBits, *srcPtr;
|
---|
328 | int bytesPerRow;
|
---|
329 |
|
---|
330 | srcBits = Blt_GetBitmapData(display, bitmap, width, height, &bytesPerRow);
|
---|
331 | if (srcBits == NULL) {
|
---|
332 | OutputDebugString("Can't get bitmap data");
|
---|
333 | return;
|
---|
334 | }
|
---|
335 | Blt_AppendToPostScript(tokenPtr, "\t<", (char *)NULL);
|
---|
336 | byteCount = bitPos = 0; /* Suppress compiler warning */
|
---|
337 | for (y = height - 1; y >= 0; y--) {
|
---|
338 | srcPtr = srcBits + (bytesPerRow * y);
|
---|
339 | byte = 0;
|
---|
340 | for (x = 0; x < width; x++) {
|
---|
341 | bitPos = x % 8;
|
---|
342 | pixel = (*srcPtr & (0x80 >> bitPos));
|
---|
343 | if (pixel) {
|
---|
344 | byte |= (unsigned char)(1 << bitPos);
|
---|
345 | }
|
---|
346 | if (bitPos == 7) {
|
---|
347 | byte = ReverseBits(byte);
|
---|
348 | ByteToHex(byte, string);
|
---|
349 | string[2] = '\0';
|
---|
350 | byteCount++;
|
---|
351 | srcPtr++;
|
---|
352 | byte = 0;
|
---|
353 | if (byteCount >= 30) {
|
---|
354 | string[2] = '\n';
|
---|
355 | string[3] = '\t';
|
---|
356 | string[4] = '\0';
|
---|
357 | byteCount = 0;
|
---|
358 | }
|
---|
359 | Blt_AppendToPostScript(tokenPtr, string, (char *)NULL);
|
---|
360 | }
|
---|
361 | } /* x */
|
---|
362 | if (bitPos != 7) {
|
---|
363 | byte = ReverseBits(byte);
|
---|
364 | ByteToHex(byte, string);
|
---|
365 | string[2] = '\0';
|
---|
366 | Blt_AppendToPostScript(tokenPtr, string, (char *)NULL);
|
---|
367 | byteCount++;
|
---|
368 | }
|
---|
369 | } /* y */
|
---|
370 | Blt_Free(srcBits);
|
---|
371 | Blt_AppendToPostScript(tokenPtr, ">\n", (char *)NULL);
|
---|
372 | }
|
---|
373 |
|
---|
374 | #else
|
---|
375 |
|
---|
376 | /*
|
---|
377 | * -------------------------------------------------------------------------
|
---|
378 | *
|
---|
379 | * Blt_BitmapDataToPostScript --
|
---|
380 | *
|
---|
381 | * Output a PostScript image string of the given bitmap image.
|
---|
382 | * It is assumed the image is one bit deep and a zero value
|
---|
383 | * indicates an off-pixel. To convert to PostScript, the bits
|
---|
384 | * need to be reversed from the X11 image order.
|
---|
385 | *
|
---|
386 | * Results:
|
---|
387 | * None.
|
---|
388 | *
|
---|
389 | * Side Effects:
|
---|
390 | * The PostScript image string is appended to interp->result.
|
---|
391 | *
|
---|
392 | * -------------------------------------------------------------------------
|
---|
393 | */
|
---|
394 | void
|
---|
395 | Blt_BitmapDataToPostScript(tokenPtr, display, bitmap, width, height)
|
---|
396 | struct PsTokenStruct *tokenPtr;
|
---|
397 | Display *display;
|
---|
398 | Pixmap bitmap;
|
---|
399 | int width, height;
|
---|
400 | {
|
---|
401 | register unsigned char byte = 0;
|
---|
402 | register int x, y, bitPos;
|
---|
403 | unsigned long pixel;
|
---|
404 | XImage *imagePtr;
|
---|
405 | int byteCount;
|
---|
406 | char string[10];
|
---|
407 |
|
---|
408 | imagePtr = XGetImage(display, bitmap, 0, 0, width, height, 1, ZPixmap);
|
---|
409 | Blt_AppendToPostScript(tokenPtr, "\t<", (char *)NULL);
|
---|
410 | byteCount = bitPos = 0; /* Suppress compiler warning */
|
---|
411 | for (y = 0; y < height; y++) {
|
---|
412 | byte = 0;
|
---|
413 | for (x = 0; x < width; x++) {
|
---|
414 | pixel = XGetPixel(imagePtr, x, y);
|
---|
415 | bitPos = x % 8;
|
---|
416 | byte |= (unsigned char)(pixel << bitPos);
|
---|
417 | if (bitPos == 7) {
|
---|
418 | byte = ReverseBits(byte);
|
---|
419 | ByteToHex(byte, string);
|
---|
420 | string[2] = '\0';
|
---|
421 | byteCount++;
|
---|
422 | byte = 0;
|
---|
423 | if (byteCount >= 30) {
|
---|
424 | string[2] = '\n';
|
---|
425 | string[3] = '\t';
|
---|
426 | string[4] = '\0';
|
---|
427 | byteCount = 0;
|
---|
428 | }
|
---|
429 | Blt_AppendToPostScript(tokenPtr, string, (char *)NULL);
|
---|
430 | }
|
---|
431 | } /* x */
|
---|
432 | if (bitPos != 7) {
|
---|
433 | byte = ReverseBits(byte);
|
---|
434 | ByteToHex(byte, string);
|
---|
435 | string[2] = '\0';
|
---|
436 | Blt_AppendToPostScript(tokenPtr, string, (char *)NULL);
|
---|
437 | byteCount++;
|
---|
438 | }
|
---|
439 | } /* y */
|
---|
440 | Blt_AppendToPostScript(tokenPtr, ">\n", (char *)NULL);
|
---|
441 | XDestroyImage(imagePtr);
|
---|
442 | }
|
---|
443 |
|
---|
444 | #endif /* WIN32 */
|
---|
445 |
|
---|
446 | /*
|
---|
447 | *----------------------------------------------------------------------
|
---|
448 | *
|
---|
449 | * Blt_ColorImageToPsData --
|
---|
450 | *
|
---|
451 | * Converts a color image to PostScript RGB (3 components)
|
---|
452 | * or Greyscale (1 component) output. With 3 components, we
|
---|
453 | * assume the "colorimage" operator is available.
|
---|
454 | *
|
---|
455 | * Note that the image converted from bottom to top, to conform
|
---|
456 | * to the PostScript coordinate system.
|
---|
457 | *
|
---|
458 | * Results:
|
---|
459 | * The PostScript data comprising the color image is written
|
---|
460 | * into the dynamic string.
|
---|
461 | *
|
---|
462 | *----------------------------------------------------------------------
|
---|
463 | */
|
---|
464 | int
|
---|
465 | Blt_ColorImageToPsData(image, nComponents, resultPtr, prefix)
|
---|
466 | Blt_ColorImage image;
|
---|
467 | int nComponents;
|
---|
468 | Tcl_DString *resultPtr;
|
---|
469 | char *prefix;
|
---|
470 | {
|
---|
471 | char string[10];
|
---|
472 | register int count;
|
---|
473 | register int x, y;
|
---|
474 | register Pix32 *pixelPtr;
|
---|
475 | unsigned char byte;
|
---|
476 | int width, height;
|
---|
477 | int offset;
|
---|
478 | int nLines;
|
---|
479 | width = Blt_ColorImageWidth(image);
|
---|
480 | height = Blt_ColorImageHeight(image);
|
---|
481 |
|
---|
482 | nLines = 0;
|
---|
483 | count = 0;
|
---|
484 | offset = (height - 1) * width;
|
---|
485 | if (nComponents == 3) {
|
---|
486 | for (y = (height - 1); y >= 0; y--) {
|
---|
487 | pixelPtr = Blt_ColorImageBits(image) + offset;
|
---|
488 | for (x = 0; x < width; x++, pixelPtr++) {
|
---|
489 | if (count == 0) {
|
---|
490 | Tcl_DStringAppend(resultPtr, prefix, -1);
|
---|
491 | Tcl_DStringAppend(resultPtr, " ", -1);
|
---|
492 | }
|
---|
493 | count += 6;
|
---|
494 | ByteToHex(pixelPtr->Red, string);
|
---|
495 | ByteToHex(pixelPtr->Green, string + 2);
|
---|
496 | ByteToHex(pixelPtr->Blue, string + 4);
|
---|
497 | string[6] = '\0';
|
---|
498 | if (count >= 60) {
|
---|
499 | string[6] = '\n';
|
---|
500 | string[7] = '\0';
|
---|
501 | count = 0;
|
---|
502 | nLines++;
|
---|
503 | }
|
---|
504 | Tcl_DStringAppend(resultPtr, string, -1);
|
---|
505 | }
|
---|
506 | offset -= width;
|
---|
507 | }
|
---|
508 | } else if (nComponents == 1) {
|
---|
509 | for (y = (height - 1); y >= 0; y--) {
|
---|
510 | pixelPtr = Blt_ColorImageBits(image) + offset;
|
---|
511 | for (x = 0; x < width; x++, pixelPtr++) {
|
---|
512 | if (count == 0) {
|
---|
513 | Tcl_DStringAppend(resultPtr, prefix, -1);
|
---|
514 | Tcl_DStringAppend(resultPtr, " ", -1);
|
---|
515 | }
|
---|
516 | count += 2;
|
---|
517 | byte = ~(pixelPtr->Red);
|
---|
518 | ByteToHex(byte, string);
|
---|
519 | string[2] = '\0';
|
---|
520 | if (count >= 60) {
|
---|
521 | string[2] = '\n';
|
---|
522 | string[3] = '\0';
|
---|
523 | count = 0;
|
---|
524 | nLines++;
|
---|
525 | }
|
---|
526 | Tcl_DStringAppend(resultPtr, string, -1);
|
---|
527 | }
|
---|
528 | offset -= width;
|
---|
529 | }
|
---|
530 | }
|
---|
531 | if (count != 0) {
|
---|
532 | Tcl_DStringAppend(resultPtr, "\n", -1);
|
---|
533 | nLines++;
|
---|
534 | }
|
---|
535 | return nLines;
|
---|
536 | }
|
---|
537 |
|
---|
538 | /*
|
---|
539 | *----------------------------------------------------------------------
|
---|
540 | *
|
---|
541 | * NameOfAtom --
|
---|
542 | *
|
---|
543 | * Wrapper routine for Tk_GetAtomName. Returns NULL instead of
|
---|
544 | * "?bad atom?" if the atom can't be found.
|
---|
545 | *
|
---|
546 | * Results:
|
---|
547 | * The name of the atom is returned if found. Otherwise NULL.
|
---|
548 | *
|
---|
549 | *----------------------------------------------------------------------
|
---|
550 | */
|
---|
551 | static char *
|
---|
552 | NameOfAtom(tkwin, atom)
|
---|
553 | Tk_Window tkwin;
|
---|
554 | Atom atom;
|
---|
555 | {
|
---|
556 | char *result;
|
---|
557 |
|
---|
558 | result = Tk_GetAtomName(tkwin, atom);
|
---|
559 | if ((result[0] == '?') && (strcmp(result, "?bad atom?") == 0)) {
|
---|
560 | return NULL;
|
---|
561 | }
|
---|
562 | return result;
|
---|
563 | }
|
---|
564 |
|
---|
565 |
|
---|
566 | typedef struct {
|
---|
567 | char *alias;
|
---|
568 | char *fontName;
|
---|
569 | } FontMap;
|
---|
570 |
|
---|
571 | static FontMap psFontMap[] =
|
---|
572 | {
|
---|
573 | {"Arial", "Helvetica",},
|
---|
574 | {"AvantGarde", "AvantGarde",},
|
---|
575 | {"Courier New", "Courier",},
|
---|
576 | {"Courier", "Courier",},
|
---|
577 | {"Geneva", "Helvetica",},
|
---|
578 | {"Helvetica", "Helvetica",},
|
---|
579 | {"Monaco", "Courier",},
|
---|
580 | {"New Century Schoolbook", "NewCenturySchlbk",},
|
---|
581 | {"New York", "Times",},
|
---|
582 | {"Palatino", "Palatino",},
|
---|
583 | {"Symbol", "Symbol",},
|
---|
584 | {"Times New Roman", "Times",},
|
---|
585 | {"Times Roman", "Times",},
|
---|
586 | {"Times", "Times",},
|
---|
587 | {"Utopia", "Utopia",},
|
---|
588 | {"ZapfChancery", "ZapfChancery",},
|
---|
589 | {"ZapfDingbats", "ZapfDingbats",},
|
---|
590 | };
|
---|
591 |
|
---|
592 | static int nFontNames = (sizeof(psFontMap) / sizeof(FontMap));
|
---|
593 |
|
---|
594 | #ifndef WIN32
|
---|
595 | /*
|
---|
596 | * -----------------------------------------------------------------
|
---|
597 | *
|
---|
598 | * XFontStructToPostScript --
|
---|
599 | *
|
---|
600 | * Map X11 font to a PostScript font. Currently, only fonts whose
|
---|
601 | * FOUNDRY property are "Adobe" are converted. Simply gets the
|
---|
602 | * XA_FULL_NAME and XA_FAMILY properties and pieces together a
|
---|
603 | * PostScript fontname.
|
---|
604 | *
|
---|
605 | * Results:
|
---|
606 | * Returns the mapped PostScript font name if one is possible.
|
---|
607 | * Otherwise returns NULL.
|
---|
608 | *
|
---|
609 | * -----------------------------------------------------------------
|
---|
610 | */
|
---|
611 | static char *
|
---|
612 | XFontStructToPostScript(tkwin, fontPtr)
|
---|
613 | Tk_Window tkwin; /* Window to query for atoms */
|
---|
614 | XFontStruct *fontPtr; /* Font structure to map to name */
|
---|
615 | {
|
---|
616 | Atom atom;
|
---|
617 | char *fullName, *family, *foundry;
|
---|
618 | register char *src, *dest;
|
---|
619 | int familyLen;
|
---|
620 | char *start;
|
---|
621 | static char string[200]; /* What size? */
|
---|
622 |
|
---|
623 | if (XGetFontProperty(fontPtr, XA_FULL_NAME, &atom) == False) {
|
---|
624 | return NULL;
|
---|
625 | }
|
---|
626 | fullName = NameOfAtom(tkwin, atom);
|
---|
627 | if (fullName == NULL) {
|
---|
628 | return NULL;
|
---|
629 | }
|
---|
630 | family = foundry = NULL;
|
---|
631 | if (XGetFontProperty(fontPtr, Tk_InternAtom(tkwin, "FOUNDRY"), &atom)) {
|
---|
632 | foundry = NameOfAtom(tkwin, atom);
|
---|
633 | }
|
---|
634 | if (XGetFontProperty(fontPtr, XA_FAMILY_NAME, &atom)) {
|
---|
635 | family = NameOfAtom(tkwin, atom);
|
---|
636 | }
|
---|
637 | /*
|
---|
638 | * Try to map the font only if the foundry is Adobe
|
---|
639 | */
|
---|
640 | if ((foundry == NULL) || (family == NULL)) {
|
---|
641 | return NULL;
|
---|
642 | }
|
---|
643 | src = NULL;
|
---|
644 | familyLen = strlen(family);
|
---|
645 | if (strncasecmp(fullName, family, familyLen) == 0) {
|
---|
646 | src = fullName + familyLen;
|
---|
647 | }
|
---|
648 | if (strcmp(foundry, "Adobe") != 0) {
|
---|
649 | register int i;
|
---|
650 |
|
---|
651 | if (strncasecmp(family, "itc ", 4) == 0) {
|
---|
652 | family += 4; /* Throw out the "itc" prefix */
|
---|
653 | }
|
---|
654 | for (i = 0; i < nFontNames; i++) {
|
---|
655 | if (strcasecmp(family, psFontMap[i].alias) == 0) {
|
---|
656 | family = psFontMap[i].fontName;
|
---|
657 | }
|
---|
658 | }
|
---|
659 | if (i == nFontNames) {
|
---|
660 | family = "Helvetica"; /* Default to a known font */
|
---|
661 | }
|
---|
662 | }
|
---|
663 | /*
|
---|
664 | * PostScript font name is in the form <family>-<type face>
|
---|
665 | */
|
---|
666 | sprintf(string, "%s-", family);
|
---|
667 | dest = start = string + strlen(string);
|
---|
668 |
|
---|
669 | /*
|
---|
670 | * Append the type face (part of the full name trailing the family name)
|
---|
671 | * to the the PostScript font name, removing any spaces or dashes
|
---|
672 | *
|
---|
673 | * ex. " Bold Italic" ==> "BoldItalic"
|
---|
674 | */
|
---|
675 | if (src != NULL) {
|
---|
676 | while (*src != '\0') {
|
---|
677 | if ((*src != ' ') && (*src != '-')) {
|
---|
678 | *dest++ = *src;
|
---|
679 | }
|
---|
680 | src++;
|
---|
681 | }
|
---|
682 | }
|
---|
683 | if (dest == start) {
|
---|
684 | --dest; /* Remove '-' to leave just the family name */
|
---|
685 | }
|
---|
686 | *dest = '\0'; /* Make a valid string */
|
---|
687 | return string;
|
---|
688 | }
|
---|
689 |
|
---|
690 | #endif /* !WIN32 */
|
---|
691 | |
---|
692 |
|
---|
693 |
|
---|
694 | /*
|
---|
695 | * -------------------------------------------------------------------
|
---|
696 | * Routines to convert X drawing functions to PostScript commands.
|
---|
697 | * -------------------------------------------------------------------
|
---|
698 | */
|
---|
699 | void
|
---|
700 | Blt_ClearBackgroundToPostScript(tokenPtr)
|
---|
701 | struct PsTokenStruct *tokenPtr;
|
---|
702 | {
|
---|
703 | Blt_AppendToPostScript(tokenPtr,
|
---|
704 | " 1.0 1.0 1.0 SetBgColor\n",
|
---|
705 | (char *)NULL);
|
---|
706 | }
|
---|
707 |
|
---|
708 | void
|
---|
709 | Blt_CapStyleToPostScript(tokenPtr, capStyle)
|
---|
710 | struct PsTokenStruct *tokenPtr;
|
---|
711 | int capStyle;
|
---|
712 | {
|
---|
713 | /*
|
---|
714 | * X11:not last = 0, butt = 1, round = 2, projecting = 3
|
---|
715 | * PS: butt = 0, round = 1, projecting = 2
|
---|
716 | */
|
---|
717 | if (capStyle > 0) {
|
---|
718 | capStyle--;
|
---|
719 | }
|
---|
720 | Blt_FormatToPostScript(tokenPtr,
|
---|
721 | "%d setlinecap\n",
|
---|
722 | capStyle);
|
---|
723 | }
|
---|
724 |
|
---|
725 | void
|
---|
726 | Blt_JoinStyleToPostScript(tokenPtr, joinStyle)
|
---|
727 | struct PsTokenStruct *tokenPtr;
|
---|
728 | int joinStyle;
|
---|
729 | {
|
---|
730 | /*
|
---|
731 | * miter = 0, round = 1, bevel = 2
|
---|
732 | */
|
---|
733 | Blt_FormatToPostScript(tokenPtr,
|
---|
734 | "%d setlinejoin\n",
|
---|
735 | joinStyle);
|
---|
736 | }
|
---|
737 |
|
---|
738 | void
|
---|
739 | Blt_LineWidthToPostScript(tokenPtr, lineWidth)
|
---|
740 | struct PsTokenStruct *tokenPtr;
|
---|
741 | int lineWidth;
|
---|
742 | {
|
---|
743 | if (lineWidth < 1) {
|
---|
744 | lineWidth = 1;
|
---|
745 | }
|
---|
746 | Blt_FormatToPostScript(tokenPtr,
|
---|
747 | "%d setlinewidth\n",
|
---|
748 | lineWidth);
|
---|
749 | }
|
---|
750 |
|
---|
751 | void
|
---|
752 | Blt_LineDashesToPostScript(tokenPtr, dashesPtr)
|
---|
753 | struct PsTokenStruct *tokenPtr;
|
---|
754 | Blt_Dashes *dashesPtr;
|
---|
755 | {
|
---|
756 |
|
---|
757 | Blt_AppendToPostScript(tokenPtr, "[ ", (char *)NULL);
|
---|
758 | if (dashesPtr != NULL) {
|
---|
759 | unsigned char *p;
|
---|
760 |
|
---|
761 | for (p = dashesPtr->values; *p != 0; p++) {
|
---|
762 | Blt_FormatToPostScript(tokenPtr, " %d", *p);
|
---|
763 | }
|
---|
764 | }
|
---|
765 | Blt_AppendToPostScript(tokenPtr, "] 0 setdash\n", (char *)NULL);
|
---|
766 | }
|
---|
767 |
|
---|
768 | void
|
---|
769 | Blt_LineAttributesToPostScript(tokenPtr, colorPtr, lineWidth, dashesPtr,
|
---|
770 | capStyle, joinStyle)
|
---|
771 | struct PsTokenStruct *tokenPtr;
|
---|
772 | XColor *colorPtr;
|
---|
773 | int lineWidth;
|
---|
774 | Blt_Dashes *dashesPtr;
|
---|
775 | int capStyle, joinStyle;
|
---|
776 | {
|
---|
777 | Blt_JoinStyleToPostScript(tokenPtr, joinStyle);
|
---|
778 | Blt_CapStyleToPostScript(tokenPtr, capStyle);
|
---|
779 | Blt_ForegroundToPostScript(tokenPtr, colorPtr);
|
---|
780 | Blt_LineWidthToPostScript(tokenPtr, lineWidth);
|
---|
781 | Blt_LineDashesToPostScript(tokenPtr, dashesPtr);
|
---|
782 | Blt_AppendToPostScript(tokenPtr, "/DashesProc {} def\n", (char *)NULL);
|
---|
783 | }
|
---|
784 |
|
---|
785 | void
|
---|
786 | Blt_RectangleToPostScript(tokenPtr, x, y, width, height)
|
---|
787 | struct PsTokenStruct *tokenPtr;
|
---|
788 | double x, y;
|
---|
789 | int width, height;
|
---|
790 | {
|
---|
791 | Blt_FormatToPostScript(tokenPtr,
|
---|
792 | "%g %g %d %d Box fill\n\n",
|
---|
793 | x, y, width, height);
|
---|
794 | }
|
---|
795 |
|
---|
796 | void
|
---|
797 | Blt_RegionToPostScript(tokenPtr, x, y, width, height)
|
---|
798 | struct PsTokenStruct *tokenPtr;
|
---|
799 | double x, y;
|
---|
800 | int width, height;
|
---|
801 | {
|
---|
802 | Blt_FormatToPostScript(tokenPtr, "%g %g %d %d Box\n\n",
|
---|
803 | x, y, width, height);
|
---|
804 | }
|
---|
805 |
|
---|
806 | void
|
---|
807 | Blt_PathToPostScript(tokenPtr, screenPts, nScreenPts)
|
---|
808 | struct PsTokenStruct *tokenPtr;
|
---|
809 | register Point2D *screenPts;
|
---|
810 | int nScreenPts;
|
---|
811 | {
|
---|
812 | register Point2D *pointPtr, *endPtr;
|
---|
813 |
|
---|
814 | pointPtr = screenPts;
|
---|
815 | Blt_FormatToPostScript(tokenPtr, "newpath %g %g moveto\n",
|
---|
816 | pointPtr->x, pointPtr->y);
|
---|
817 | pointPtr++;
|
---|
818 | endPtr = screenPts + nScreenPts;
|
---|
819 | while (pointPtr < endPtr) {
|
---|
820 | Blt_FormatToPostScript(tokenPtr, "%g %g lineto\n",
|
---|
821 | pointPtr->x, pointPtr->y);
|
---|
822 | pointPtr++;
|
---|
823 | }
|
---|
824 | }
|
---|
825 |
|
---|
826 | void
|
---|
827 | Blt_PolygonToPostScript(tokenPtr, screenPts, nScreenPts)
|
---|
828 | struct PsTokenStruct *tokenPtr;
|
---|
829 | Point2D *screenPts;
|
---|
830 | int nScreenPts;
|
---|
831 | {
|
---|
832 | Blt_PathToPostScript(tokenPtr, screenPts, nScreenPts);
|
---|
833 | Blt_FormatToPostScript(tokenPtr, "%g %g ", screenPts[0].x, screenPts[0].y);
|
---|
834 | Blt_AppendToPostScript(tokenPtr, " lineto closepath Fill\n", (char *)NULL);
|
---|
835 | }
|
---|
836 |
|
---|
837 | void
|
---|
838 | Blt_SegmentsToPostScript(tokenPtr, segPtr, nSegments)
|
---|
839 | struct PsTokenStruct *tokenPtr;
|
---|
840 | register XSegment *segPtr;
|
---|
841 | int nSegments;
|
---|
842 | {
|
---|
843 | register int i;
|
---|
844 |
|
---|
845 | for (i = 0; i < nSegments; i++, segPtr++) {
|
---|
846 | Blt_FormatToPostScript(tokenPtr, "%d %d moveto\n",
|
---|
847 | segPtr->x1, segPtr->y1);
|
---|
848 | Blt_FormatToPostScript(tokenPtr, " %d %d lineto\n",
|
---|
849 | segPtr->x2, segPtr->y2);
|
---|
850 | Blt_AppendToPostScript(tokenPtr, "DashesProc stroke\n", (char *)NULL);
|
---|
851 | }
|
---|
852 | }
|
---|
853 |
|
---|
854 |
|
---|
855 | void
|
---|
856 | Blt_RectanglesToPostScript(tokenPtr, rectArr, nRects)
|
---|
857 | struct PsTokenStruct *tokenPtr;
|
---|
858 | XRectangle rectArr[];
|
---|
859 | int nRects;
|
---|
860 | {
|
---|
861 | register int i;
|
---|
862 |
|
---|
863 | for (i = 0; i < nRects; i++) {
|
---|
864 | Blt_RectangleToPostScript(tokenPtr,
|
---|
865 | (double)rectArr[i].x, (double)rectArr[i].y,
|
---|
866 | (int)rectArr[i].width, (int)rectArr[i].height);
|
---|
867 | }
|
---|
868 | }
|
---|
869 |
|
---|
870 | #ifndef TK_RELIEF_SOLID
|
---|
871 | #define TK_RELIEF_SOLID -1 /* Set the an impossible value. */
|
---|
872 | #endif /* TK_RELIEF_SOLID */
|
---|
873 |
|
---|
874 | void
|
---|
875 | Blt_Draw3DRectangleToPostScript(tokenPtr, border, x, y, width, height,
|
---|
876 | borderWidth, relief)
|
---|
877 | struct PsTokenStruct *tokenPtr;
|
---|
878 | Tk_3DBorder border; /* Token for border to draw. */
|
---|
879 | double x, y; /* Coordinates of rectangle */
|
---|
880 | int width, height; /* Region to be drawn. */
|
---|
881 | int borderWidth; /* Desired width for border, in pixels. */
|
---|
882 | int relief; /* Should be either TK_RELIEF_RAISED or
|
---|
883 | * TK_RELIEF_SUNKEN; indicates position of
|
---|
884 | * interior of window relative to exterior. */
|
---|
885 | {
|
---|
886 | TkBorder *borderPtr = (TkBorder *) border;
|
---|
887 | XColor lightColor, darkColor;
|
---|
888 | XColor *lightColorPtr, *darkColorPtr;
|
---|
889 | XColor *topColor, *bottomColor;
|
---|
890 | Point2D points[7];
|
---|
891 | int twiceWidth = (borderWidth * 2);
|
---|
892 |
|
---|
893 | if ((width < twiceWidth) || (height < twiceWidth)) {
|
---|
894 | return;
|
---|
895 | }
|
---|
896 | if ((relief == TK_RELIEF_SOLID) ||
|
---|
897 | (borderPtr->lightColor == NULL) || (borderPtr->darkColor == NULL)) {
|
---|
898 | if (relief == TK_RELIEF_SOLID) {
|
---|
899 | darkColor.red = darkColor.blue = darkColor.green = 0x00;
|
---|
900 | lightColor.red = lightColor.blue = lightColor.green = 0x00;
|
---|
901 | relief = TK_RELIEF_SUNKEN;
|
---|
902 | } else {
|
---|
903 | Screen *screenPtr;
|
---|
904 |
|
---|
905 | lightColor = *borderPtr->bgColor;
|
---|
906 | screenPtr = Tk_Screen(tokenPtr->tkwin);
|
---|
907 | if (lightColor.pixel == WhitePixelOfScreen(screenPtr)) {
|
---|
908 | darkColor.red = darkColor.blue = darkColor.green = 0x00;
|
---|
909 | } else {
|
---|
910 | darkColor.red = darkColor.blue = darkColor.green = 0xFF;
|
---|
911 | }
|
---|
912 | }
|
---|
913 | lightColorPtr = &lightColor;
|
---|
914 | darkColorPtr = &darkColor;
|
---|
915 | } else {
|
---|
916 | lightColorPtr = borderPtr->lightColor;
|
---|
917 | darkColorPtr = borderPtr->darkColor;
|
---|
918 | }
|
---|
919 |
|
---|
920 |
|
---|
921 | /*
|
---|
922 | * Handle grooves and ridges with recursive calls.
|
---|
923 | */
|
---|
924 |
|
---|
925 | if ((relief == TK_RELIEF_GROOVE) || (relief == TK_RELIEF_RIDGE)) {
|
---|
926 | int halfWidth, insideOffset;
|
---|
927 |
|
---|
928 | halfWidth = borderWidth / 2;
|
---|
929 | insideOffset = borderWidth - halfWidth;
|
---|
930 | Blt_Draw3DRectangleToPostScript(tokenPtr, border, (double)x, (double)y,
|
---|
931 | width, height, halfWidth,
|
---|
932 | (relief == TK_RELIEF_GROOVE) ? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED);
|
---|
933 | Blt_Draw3DRectangleToPostScript(tokenPtr, border,
|
---|
934 | (double)(x + insideOffset), (double)(y + insideOffset),
|
---|
935 | width - insideOffset * 2, height - insideOffset * 2, halfWidth,
|
---|
936 | (relief == TK_RELIEF_GROOVE) ? TK_RELIEF_RAISED : TK_RELIEF_SUNKEN);
|
---|
937 | return;
|
---|
938 | }
|
---|
939 | if (relief == TK_RELIEF_RAISED) {
|
---|
940 | topColor = lightColorPtr;
|
---|
941 | bottomColor = darkColorPtr;
|
---|
942 | } else if (relief == TK_RELIEF_SUNKEN) {
|
---|
943 | topColor = darkColorPtr;
|
---|
944 | bottomColor = lightColorPtr;
|
---|
945 | } else {
|
---|
946 | topColor = bottomColor = borderPtr->bgColor;
|
---|
947 | }
|
---|
948 | Blt_BackgroundToPostScript(tokenPtr, bottomColor);
|
---|
949 | Blt_RectangleToPostScript(tokenPtr, x, y + height - borderWidth, width,
|
---|
950 | borderWidth);
|
---|
951 | Blt_RectangleToPostScript(tokenPtr, x + width - borderWidth, y,
|
---|
952 | borderWidth, height);
|
---|
953 | points[0].x = points[1].x = points[6].x = x;
|
---|
954 | points[0].y = points[6].y = y + height;
|
---|
955 | points[1].y = points[2].y = y;
|
---|
956 | points[2].x = x + width;
|
---|
957 | points[3].x = x + width - borderWidth;
|
---|
958 | points[3].y = points[4].y = y + borderWidth;
|
---|
959 | points[4].x = points[5].x = x + borderWidth;
|
---|
960 | points[5].y = y + height - borderWidth;
|
---|
961 | if (relief != TK_RELIEF_FLAT) {
|
---|
962 | Blt_BackgroundToPostScript(tokenPtr, topColor);
|
---|
963 | }
|
---|
964 | Blt_PolygonToPostScript(tokenPtr, points, 7);
|
---|
965 | }
|
---|
966 |
|
---|
967 | void
|
---|
968 | Blt_Fill3DRectangleToPostScript(tokenPtr, border, x, y, width, height,
|
---|
969 | borderWidth, relief)
|
---|
970 | struct PsTokenStruct *tokenPtr;
|
---|
971 | Tk_3DBorder border; /* Token for border to draw. */
|
---|
972 | double x, y; /* Coordinates of top-left of border area */
|
---|
973 | int width, height; /* Dimension of border to be drawn. */
|
---|
974 | int borderWidth; /* Desired width for border, in pixels. */
|
---|
975 | int relief; /* Should be either TK_RELIEF_RAISED or
|
---|
976 | * TK_RELIEF_SUNKEN; indicates position of
|
---|
977 | * interior of window relative to exterior. */
|
---|
978 | {
|
---|
979 | TkBorder *borderPtr = (TkBorder *) border;
|
---|
980 |
|
---|
981 | /*
|
---|
982 | * I'm assuming that the rectangle is to be drawn as a background.
|
---|
983 | * Setting the pen color as foreground or background only affects
|
---|
984 | * the plot when the colormode option is "monochrome".
|
---|
985 | */
|
---|
986 | Blt_BackgroundToPostScript(tokenPtr, borderPtr->bgColor);
|
---|
987 | Blt_RectangleToPostScript(tokenPtr, x, y, width, height);
|
---|
988 | Blt_Draw3DRectangleToPostScript(tokenPtr, border, x, y, width, height,
|
---|
989 | borderWidth, relief);
|
---|
990 | }
|
---|
991 |
|
---|
992 | void
|
---|
993 | Blt_StippleToPostScript(tokenPtr, display, bitmap)
|
---|
994 | struct PsTokenStruct *tokenPtr;
|
---|
995 | Display *display;
|
---|
996 | Pixmap bitmap;
|
---|
997 | {
|
---|
998 | int width, height;
|
---|
999 |
|
---|
1000 | Tk_SizeOfBitmap(display, bitmap, &width, &height);
|
---|
1001 | Blt_FormatToPostScript(tokenPtr,
|
---|
1002 | "gsave\n clip\n %d %d\n",
|
---|
1003 | width, height);
|
---|
1004 | Blt_BitmapDataToPostScript(tokenPtr, display, bitmap, width, height);
|
---|
1005 | Blt_AppendToPostScript(tokenPtr,
|
---|
1006 | " StippleFill\ngrestore\n",
|
---|
1007 | (char *)NULL);
|
---|
1008 | }
|
---|
1009 |
|
---|
1010 | /*
|
---|
1011 | *----------------------------------------------------------------------
|
---|
1012 | *
|
---|
1013 | * Blt_ColorImageToPostScript --
|
---|
1014 | *
|
---|
1015 | * Translates a color image into 3 component RGB PostScript output.
|
---|
1016 | * Uses PS Language Level 2 operator "colorimage".
|
---|
1017 | *
|
---|
1018 | * Results:
|
---|
1019 | * The dynamic string will contain the PostScript output.
|
---|
1020 | *
|
---|
1021 | *----------------------------------------------------------------------
|
---|
1022 | */
|
---|
1023 | void
|
---|
1024 | Blt_ColorImageToPostScript(tokenPtr, image, x, y)
|
---|
1025 | struct PsTokenStruct *tokenPtr;
|
---|
1026 | Blt_ColorImage image;
|
---|
1027 | double x, y;
|
---|
1028 | {
|
---|
1029 | int width, height;
|
---|
1030 | int tmpSize;
|
---|
1031 |
|
---|
1032 | width = Blt_ColorImageWidth(image);
|
---|
1033 | height = Blt_ColorImageHeight(image);
|
---|
1034 |
|
---|
1035 | tmpSize = width;
|
---|
1036 | if (tokenPtr->colorMode == PS_MODE_COLOR) {
|
---|
1037 | tmpSize *= 3;
|
---|
1038 | }
|
---|
1039 | Blt_FormatToPostScript(tokenPtr, "\n/tmpStr %d string def\n", tmpSize);
|
---|
1040 | Blt_AppendToPostScript(tokenPtr, "gsave\n", (char *)NULL);
|
---|
1041 | Blt_FormatToPostScript(tokenPtr, " %g %g translate\n", x, y);
|
---|
1042 | Blt_FormatToPostScript(tokenPtr, " %d %d scale\n", width, height);
|
---|
1043 | Blt_FormatToPostScript(tokenPtr, " %d %d 8\n", width, height);
|
---|
1044 | Blt_FormatToPostScript(tokenPtr, " [%d 0 0 %d 0 %d] ", width, -height,
|
---|
1045 | height);
|
---|
1046 | Blt_AppendToPostScript(tokenPtr,
|
---|
1047 | "{\n currentfile tmpStr readhexstring pop\n } ",
|
---|
1048 | (char *)NULL);
|
---|
1049 | if (tokenPtr->colorMode != PS_MODE_COLOR) {
|
---|
1050 | Blt_AppendToPostScript(tokenPtr, "image\n", (char *)NULL);
|
---|
1051 | Blt_ColorImageToGreyscale(image);
|
---|
1052 | Blt_ColorImageToPsData(image, 1, &(tokenPtr->dString), " ");
|
---|
1053 | } else {
|
---|
1054 | Blt_AppendToPostScript(tokenPtr,
|
---|
1055 | "false 3 colorimage\n",
|
---|
1056 | (char *)NULL);
|
---|
1057 | Blt_ColorImageToPsData(image, 3, &(tokenPtr->dString), " ");
|
---|
1058 | }
|
---|
1059 | Blt_AppendToPostScript(tokenPtr,
|
---|
1060 | "\ngrestore\n\n",
|
---|
1061 | (char *)NULL);
|
---|
1062 | }
|
---|
1063 |
|
---|
1064 | /*
|
---|
1065 | *----------------------------------------------------------------------
|
---|
1066 | *
|
---|
1067 | * Blt_WindowToPostScript --
|
---|
1068 | *
|
---|
1069 | * Converts a Tk window to PostScript. If the window could not
|
---|
1070 | * be "snapped", then a grey rectangle is drawn in its place.
|
---|
1071 | *
|
---|
1072 | * Results:
|
---|
1073 | * None.
|
---|
1074 | *
|
---|
1075 | *----------------------------------------------------------------------
|
---|
1076 | */
|
---|
1077 | void
|
---|
1078 | Blt_WindowToPostScript(tokenPtr, tkwin, x, y)
|
---|
1079 | struct PsTokenStruct *tokenPtr;
|
---|
1080 | Tk_Window tkwin;
|
---|
1081 | double x, y;
|
---|
1082 | {
|
---|
1083 | Blt_ColorImage image;
|
---|
1084 | int width, height;
|
---|
1085 |
|
---|
1086 | width = Tk_Width(tkwin);
|
---|
1087 | height = Tk_Height(tkwin);
|
---|
1088 | image = Blt_DrawableToColorImage(tkwin, Tk_WindowId(tkwin), 0, 0, width,
|
---|
1089 | height, GAMMA);
|
---|
1090 | if (image == NULL) {
|
---|
1091 | /* Can't grab window image so paint the window area grey */
|
---|
1092 | Blt_AppendToPostScript(tokenPtr, "% Can't grab window \"",
|
---|
1093 | Tk_PathName(tkwin), "\"\n", (char *)NULL);
|
---|
1094 | Blt_AppendToPostScript(tokenPtr, "0.5 0.5 0.5 SetBgColor\n",
|
---|
1095 | (char *)NULL);
|
---|
1096 | Blt_RectangleToPostScript(tokenPtr, x, y, width, height);
|
---|
1097 | return;
|
---|
1098 | }
|
---|
1099 | Blt_ColorImageToPostScript(tokenPtr, image, x, y);
|
---|
1100 | Blt_FreeColorImage(image);
|
---|
1101 | }
|
---|
1102 |
|
---|
1103 | /*
|
---|
1104 | * -------------------------------------------------------------------------
|
---|
1105 | *
|
---|
1106 | * Blt_PhotoToPostScript --
|
---|
1107 | *
|
---|
1108 | * Output a PostScript image string of the given photo image.
|
---|
1109 | * The photo is first converted into a color image and then
|
---|
1110 | * translated into PostScript.
|
---|
1111 | *
|
---|
1112 | * Results:
|
---|
1113 | * None.
|
---|
1114 | *
|
---|
1115 | * Side Effects:
|
---|
1116 | * The PostScript output representing the photo is appended to
|
---|
1117 | * the tokenPtr's dynamic string.
|
---|
1118 | *
|
---|
1119 | * -------------------------------------------------------------------------
|
---|
1120 | */
|
---|
1121 | void
|
---|
1122 | Blt_PhotoToPostScript(tokenPtr, photo, x, y)
|
---|
1123 | struct PsTokenStruct *tokenPtr;
|
---|
1124 | Tk_PhotoHandle photo;
|
---|
1125 | double x, y; /* Origin of photo image */
|
---|
1126 | {
|
---|
1127 | Blt_ColorImage image;
|
---|
1128 |
|
---|
1129 | image = Blt_PhotoToColorImage(photo);
|
---|
1130 | Blt_ColorImageToPostScript(tokenPtr, image, x, y);
|
---|
1131 | Blt_FreeColorImage(image);
|
---|
1132 | }
|
---|
1133 |
|
---|
1134 | /*
|
---|
1135 | * -----------------------------------------------------------------
|
---|
1136 | *
|
---|
1137 | * Blt_FontToPostScript --
|
---|
1138 | *
|
---|
1139 | * Map the Tk font to a PostScript font and point size.
|
---|
1140 | *
|
---|
1141 | * If a Tcl array variable was specified, each element should be
|
---|
1142 | * indexed by the X11 font name and contain a list of 1-2
|
---|
1143 | * elements; the PostScript font name and the desired point size.
|
---|
1144 | * The point size may be omitted and the X font point size will
|
---|
1145 | * be used.
|
---|
1146 | *
|
---|
1147 | * Otherwise, if the foundry is "Adobe", we try to do a plausible
|
---|
1148 | * mapping looking at the full name of the font and building a
|
---|
1149 | * string in the form of "Family-TypeFace".
|
---|
1150 | *
|
---|
1151 | * Returns:
|
---|
1152 | * None.
|
---|
1153 | *
|
---|
1154 | * Side Effects:
|
---|
1155 | * PostScript commands are output to change the type and the
|
---|
1156 | * point size of the current font.
|
---|
1157 | *
|
---|
1158 | * -----------------------------------------------------------------
|
---|
1159 | */
|
---|
1160 |
|
---|
1161 | void
|
---|
1162 | Blt_FontToPostScript(tokenPtr, font)
|
---|
1163 | struct PsTokenStruct *tokenPtr;
|
---|
1164 | Tk_Font font; /* Tk font to query about */
|
---|
1165 | {
|
---|
1166 | XFontStruct *fontPtr = (XFontStruct *)font;
|
---|
1167 | Tcl_Interp *interp = tokenPtr->interp;
|
---|
1168 | char *fontName;
|
---|
1169 | double pointSize;
|
---|
1170 | #if (TK_MAJOR_VERSION > 4)
|
---|
1171 | Tk_Uid family;
|
---|
1172 | register int i;
|
---|
1173 | #endif /* TK_MAJOR_VERSION > 4 */
|
---|
1174 |
|
---|
1175 | fontName = Tk_NameOfFont(font);
|
---|
1176 | pointSize = 12.0;
|
---|
1177 | /*
|
---|
1178 | * Use the font variable information if it exists.
|
---|
1179 | */
|
---|
1180 | if (tokenPtr->fontVarName != NULL) {
|
---|
1181 | char *fontInfo;
|
---|
1182 |
|
---|
1183 | fontInfo = (char *)Tcl_GetVar2(interp, tokenPtr->fontVarName, fontName,
|
---|
1184 | 0);
|
---|
1185 | if (fontInfo != NULL) {
|
---|
1186 | int nProps;
|
---|
1187 | char **propArr = NULL;
|
---|
1188 |
|
---|
1189 | if (Tcl_SplitList(interp, fontInfo, &nProps, &propArr) == TCL_OK) {
|
---|
1190 | int newSize;
|
---|
1191 |
|
---|
1192 | fontName = propArr[0];
|
---|
1193 | if ((nProps == 2) &&
|
---|
1194 | (Tcl_GetInt(interp, propArr[1], &newSize) == TCL_OK)) {
|
---|
1195 | pointSize = (double)newSize;
|
---|
1196 | }
|
---|
1197 | }
|
---|
1198 | Blt_FormatToPostScript(tokenPtr,
|
---|
1199 | "%g /%s SetFont\n",
|
---|
1200 | pointSize, fontName);
|
---|
1201 | if (propArr != (char **)NULL) {
|
---|
1202 | Blt_Free(propArr);
|
---|
1203 | }
|
---|
1204 | return;
|
---|
1205 | }
|
---|
1206 | }
|
---|
1207 | #if (TK_MAJOR_VERSION > 4)
|
---|
1208 |
|
---|
1209 | /*
|
---|
1210 | * Otherwise do a quick test to see if it's a PostScript font.
|
---|
1211 | * Tk_PostScriptFontName will silently generate a bogus PostScript
|
---|
1212 | * font description, so we have to check to see if this is really a
|
---|
1213 | * PostScript font.
|
---|
1214 | */
|
---|
1215 | family = ((TkFont *) fontPtr)->fa.family;
|
---|
1216 | for (i = 0; i < nFontNames; i++) {
|
---|
1217 | if (strncasecmp(psFontMap[i].alias, family, strlen(psFontMap[i].alias))
|
---|
1218 | == 0) {
|
---|
1219 | Tcl_DString dString;
|
---|
1220 |
|
---|
1221 | Tcl_DStringInit(&dString);
|
---|
1222 | pointSize = (double)Tk_PostscriptFontName(font, &dString);
|
---|
1223 | fontName = Tcl_DStringValue(&dString);
|
---|
1224 | Blt_FormatToPostScript(tokenPtr, "%g /%s SetFont\n", pointSize,
|
---|
1225 | fontName);
|
---|
1226 | Tcl_DStringFree(&dString);
|
---|
1227 | return;
|
---|
1228 | }
|
---|
1229 | }
|
---|
1230 |
|
---|
1231 | #endif /* TK_MAJOR_VERSION > 4 */
|
---|
1232 |
|
---|
1233 | /*
|
---|
1234 | * Can't find it. Try to use the current point size.
|
---|
1235 | */
|
---|
1236 | fontName = NULL;
|
---|
1237 | pointSize = 12.0;
|
---|
1238 |
|
---|
1239 | #ifndef WIN32
|
---|
1240 | #if (TK_MAJOR_VERSION > 4)
|
---|
1241 | /* Can you believe what I have to go through to get an XFontStruct? */
|
---|
1242 | fontPtr = XLoadQueryFont(Tk_Display(tokenPtr->tkwin), Tk_NameOfFont(font));
|
---|
1243 | #endif
|
---|
1244 | if (fontPtr != NULL) {
|
---|
1245 | unsigned long fontProp;
|
---|
1246 |
|
---|
1247 | if (XGetFontProperty(fontPtr, XA_POINT_SIZE, &fontProp) != False) {
|
---|
1248 | pointSize = (double)fontProp / 10.0;
|
---|
1249 | }
|
---|
1250 | fontName = XFontStructToPostScript(tokenPtr->tkwin, fontPtr);
|
---|
1251 | #if (TK_MAJOR_VERSION > 4)
|
---|
1252 | XFreeFont(Tk_Display(tokenPtr->tkwin), fontPtr);
|
---|
1253 | #endif /* TK_MAJOR_VERSION > 4 */
|
---|
1254 | }
|
---|
1255 | #endif /* !WIN32 */
|
---|
1256 | if ((fontName == NULL) || (fontName[0] == '\0')) {
|
---|
1257 | fontName = "Helvetica-Bold"; /* Defaulting to a known PS font */
|
---|
1258 | }
|
---|
1259 | Blt_FormatToPostScript(tokenPtr, "%g /%s SetFont\n", pointSize, fontName);
|
---|
1260 | }
|
---|
1261 |
|
---|
1262 | static void
|
---|
1263 | TextLayoutToPostScript(tokenPtr, x, y, textPtr)
|
---|
1264 | struct PsTokenStruct *tokenPtr;
|
---|
1265 | int x, y;
|
---|
1266 | TextLayout *textPtr;
|
---|
1267 | {
|
---|
1268 | char *src, *dst, *end;
|
---|
1269 | int count; /* Counts the # of bytes written to
|
---|
1270 | * the intermediate scratch buffer. */
|
---|
1271 | TextFragment *fragPtr;
|
---|
1272 | int i;
|
---|
1273 | unsigned char c;
|
---|
1274 | #if HAVE_UTF
|
---|
1275 | Tcl_UniChar ch;
|
---|
1276 | #endif
|
---|
1277 | int limit;
|
---|
1278 |
|
---|
1279 | limit = PSTOKEN_BUFSIZ - 4; /* High water mark for the scratch
|
---|
1280 | * buffer. */
|
---|
1281 | fragPtr = textPtr->fragArr;
|
---|
1282 | for (i = 0; i < textPtr->nFrags; i++, fragPtr++) {
|
---|
1283 | if (fragPtr->count < 1) {
|
---|
1284 | continue;
|
---|
1285 | }
|
---|
1286 | Blt_AppendToPostScript(tokenPtr, "(", (char *)NULL);
|
---|
1287 | count = 0;
|
---|
1288 | dst = tokenPtr->scratchArr;
|
---|
1289 | src = fragPtr->text;
|
---|
1290 | end = fragPtr->text + fragPtr->count;
|
---|
1291 | while (src < end) {
|
---|
1292 | if (count > limit) {
|
---|
1293 | /* Don't let the scatch buffer overflow */
|
---|
1294 | dst = tokenPtr->scratchArr;
|
---|
1295 | dst[count] = '\0';
|
---|
1296 | Blt_AppendToPostScript(tokenPtr, dst, (char *)NULL);
|
---|
1297 | count = 0;
|
---|
1298 | }
|
---|
1299 | #if HAVE_UTF
|
---|
1300 | /*
|
---|
1301 | * INTL: For now we just treat the characters as binary
|
---|
1302 | * data and display the lower byte. Eventually this should
|
---|
1303 | * be revised to handle international postscript fonts.
|
---|
1304 | */
|
---|
1305 | src += Tcl_UtfToUniChar(src, &ch);
|
---|
1306 | c = (unsigned char)(ch & 0xff);
|
---|
1307 | #else
|
---|
1308 | c = *src++;
|
---|
1309 | #endif
|
---|
1310 |
|
---|
1311 | if ((c == '\\') || (c == '(') || (c == ')')) {
|
---|
1312 | /*
|
---|
1313 | * If special PostScript characters characters "\", "(",
|
---|
1314 | * and ")" are contained in the text string, prepend
|
---|
1315 | * backslashes to them.
|
---|
1316 | */
|
---|
1317 | *dst++ = '\\';
|
---|
1318 | *dst++ = c;
|
---|
1319 | count += 2;
|
---|
1320 | } else if ((c < ' ') || (c > '~')) {
|
---|
1321 | /*
|
---|
1322 | * Present non-printable characters in their octal
|
---|
1323 | * representation.
|
---|
1324 | */
|
---|
1325 | sprintf(dst, "\\%03o", c);
|
---|
1326 | dst += 4;
|
---|
1327 | count += 4;
|
---|
1328 | } else {
|
---|
1329 | *dst++ = c;
|
---|
1330 | count++;
|
---|
1331 | }
|
---|
1332 | }
|
---|
1333 | tokenPtr->scratchArr[count] = '\0';
|
---|
1334 | Blt_AppendToPostScript(tokenPtr, tokenPtr->scratchArr, (char *)NULL);
|
---|
1335 | Blt_FormatToPostScript(tokenPtr, ") %d %d %d DrawAdjText\n",
|
---|
1336 | fragPtr->width, x + fragPtr->x, y + fragPtr->y);
|
---|
1337 | }
|
---|
1338 | }
|
---|
1339 |
|
---|
1340 | /*
|
---|
1341 | * -----------------------------------------------------------------
|
---|
1342 | *
|
---|
1343 | * Blt_TextToPostScript --
|
---|
1344 | *
|
---|
1345 | * Output PostScript commands to print a text string. The string
|
---|
1346 | * may be rotated at any arbitrary angle, and placed according
|
---|
1347 | * the anchor type given. The anchor indicates how to interpret
|
---|
1348 | * the window coordinates as an anchor for the text bounding box.
|
---|
1349 | *
|
---|
1350 | * Results:
|
---|
1351 | * None.
|
---|
1352 | *
|
---|
1353 | * Side Effects:
|
---|
1354 | * Text string is drawn using the given font and GC on the graph
|
---|
1355 | * window at the given coordinates, anchor, and rotation
|
---|
1356 | *
|
---|
1357 | * -----------------------------------------------------------------
|
---|
1358 | */
|
---|
1359 | void
|
---|
1360 | Blt_TextToPostScript(tokenPtr, string, tsPtr, x, y)
|
---|
1361 | struct PsTokenStruct *tokenPtr;
|
---|
1362 | char *string; /* String to convert to PostScript */
|
---|
1363 | TextStyle *tsPtr; /* Text attribute information */
|
---|
1364 | double x, y; /* Window coordinates where to print text */
|
---|
1365 | {
|
---|
1366 | double theta;
|
---|
1367 | double rotWidth, rotHeight;
|
---|
1368 | TextLayout *textPtr;
|
---|
1369 | Point2D anchorPos;
|
---|
1370 |
|
---|
1371 | if ((string == NULL) || (*string == '\0')) { /* Empty string, do nothing */
|
---|
1372 | return;
|
---|
1373 | }
|
---|
1374 | theta = FMOD(tsPtr->theta, (double)360.0);
|
---|
1375 | textPtr = Blt_GetTextLayout(string, tsPtr);
|
---|
1376 | Blt_GetBoundingBox(textPtr->width, textPtr->height, theta, &rotWidth,
|
---|
1377 | &rotHeight, (Point2D *)NULL);
|
---|
1378 | /*
|
---|
1379 | * Find the center of the bounding box
|
---|
1380 | */
|
---|
1381 | anchorPos.x = x, anchorPos.y = y;
|
---|
1382 | anchorPos = Blt_TranslatePoint(&anchorPos, ROUND(rotWidth),
|
---|
1383 | ROUND(rotHeight), tsPtr->anchor);
|
---|
1384 | anchorPos.x += (rotWidth * 0.5);
|
---|
1385 | anchorPos.y += (rotHeight * 0.5);
|
---|
1386 |
|
---|
1387 | /* Initialize text (sets translation and rotation) */
|
---|
1388 | Blt_FormatToPostScript(tokenPtr, "%d %d %g %g %g BeginText\n",
|
---|
1389 | textPtr->width, textPtr->height, tsPtr->theta, anchorPos.x,
|
---|
1390 | anchorPos.y);
|
---|
1391 |
|
---|
1392 | Blt_FontToPostScript(tokenPtr, tsPtr->font);
|
---|
1393 |
|
---|
1394 | /* All coordinates are now relative to what was set by BeginText */
|
---|
1395 | if ((tsPtr->shadow.offset > 0) && (tsPtr->shadow.color != NULL)) {
|
---|
1396 | Blt_ForegroundToPostScript(tokenPtr, tsPtr->shadow.color);
|
---|
1397 | TextLayoutToPostScript(tokenPtr, tsPtr->shadow.offset,
|
---|
1398 | tsPtr->shadow.offset, textPtr);
|
---|
1399 | }
|
---|
1400 | Blt_ForegroundToPostScript(tokenPtr, (tsPtr->state & STATE_ACTIVE)
|
---|
1401 | ? tsPtr->activeColor : tsPtr->color);
|
---|
1402 | TextLayoutToPostScript(tokenPtr, 0, 0, textPtr);
|
---|
1403 | Blt_Free(textPtr);
|
---|
1404 | Blt_AppendToPostScript(tokenPtr, "EndText\n", (char *)NULL);
|
---|
1405 | }
|
---|
1406 |
|
---|
1407 | /*
|
---|
1408 | * -----------------------------------------------------------------
|
---|
1409 | *
|
---|
1410 | * Blt_LineToPostScript --
|
---|
1411 | *
|
---|
1412 | * Outputs PostScript commands to print a multi-segmented line.
|
---|
1413 | * It assumes a procedure DashesProc was previously defined.
|
---|
1414 | *
|
---|
1415 | * Results:
|
---|
1416 | * None.
|
---|
1417 | *
|
---|
1418 | * Side Effects:
|
---|
1419 | * Segmented line is printed.
|
---|
1420 | *
|
---|
1421 | * -----------------------------------------------------------------
|
---|
1422 | */
|
---|
1423 | void
|
---|
1424 | Blt_LineToPostScript(tokenPtr, pointPtr, nPoints)
|
---|
1425 | struct PsTokenStruct *tokenPtr;
|
---|
1426 | register XPoint *pointPtr;
|
---|
1427 | int nPoints;
|
---|
1428 | {
|
---|
1429 | register int i;
|
---|
1430 |
|
---|
1431 | if (nPoints <= 0) {
|
---|
1432 | return;
|
---|
1433 | }
|
---|
1434 | Blt_FormatToPostScript(tokenPtr, " newpath %d %d moveto\n",
|
---|
1435 | pointPtr->x, pointPtr->y);
|
---|
1436 | pointPtr++;
|
---|
1437 | for (i = 1; i < (nPoints - 1); i++, pointPtr++) {
|
---|
1438 | Blt_FormatToPostScript(tokenPtr, " %d %d lineto\n",
|
---|
1439 | pointPtr->x, pointPtr->y);
|
---|
1440 | if ((i % PS_MAXPATH) == 0) {
|
---|
1441 | Blt_FormatToPostScript(tokenPtr,
|
---|
1442 | "DashesProc stroke\n newpath %d %d moveto\n",
|
---|
1443 | pointPtr->x, pointPtr->y);
|
---|
1444 | }
|
---|
1445 | }
|
---|
1446 | Blt_FormatToPostScript(tokenPtr, " %d %d lineto\n",
|
---|
1447 | pointPtr->x, pointPtr->y);
|
---|
1448 | Blt_AppendToPostScript(tokenPtr, "DashesProc stroke\n", (char *)NULL);
|
---|
1449 | }
|
---|
1450 |
|
---|
1451 | void
|
---|
1452 | Blt_BitmapToPostScript(tokenPtr, display, bitmap, scaleX, scaleY)
|
---|
1453 | struct PsTokenStruct *tokenPtr;
|
---|
1454 | Display *display;
|
---|
1455 | Pixmap bitmap; /* Bitmap to be converted to PostScript */
|
---|
1456 | double scaleX, scaleY;
|
---|
1457 | {
|
---|
1458 | int width, height;
|
---|
1459 | double scaledWidth, scaledHeight;
|
---|
1460 |
|
---|
1461 | Tk_SizeOfBitmap(display, bitmap, &width, &height);
|
---|
1462 | scaledWidth = (double)width * scaleX;
|
---|
1463 | scaledHeight = (double)height * scaleY;
|
---|
1464 | Blt_AppendToPostScript(tokenPtr, " gsave\n", (char *)NULL);
|
---|
1465 | Blt_FormatToPostScript(tokenPtr, " %g %g translate\n",
|
---|
1466 | scaledWidth * -0.5, scaledHeight * 0.5);
|
---|
1467 | Blt_FormatToPostScript(tokenPtr, " %g %g scale\n",
|
---|
1468 | scaledWidth, -scaledHeight);
|
---|
1469 | Blt_FormatToPostScript(tokenPtr, " %d %d true [%d 0 0 %d 0 %d] {",
|
---|
1470 | width, height, width, -height, height);
|
---|
1471 | Blt_BitmapDataToPostScript(tokenPtr, display, bitmap, width, height);
|
---|
1472 | Blt_AppendToPostScript(tokenPtr, " } imagemask\n grestore\n",
|
---|
1473 | (char *)NULL);
|
---|
1474 | }
|
---|
1475 |
|
---|
1476 | void
|
---|
1477 | Blt_2DSegmentsToPostScript(psToken, segPtr, nSegments)
|
---|
1478 | PsToken psToken;
|
---|
1479 | register Segment2D *segPtr;
|
---|
1480 | int nSegments;
|
---|
1481 | {
|
---|
1482 | register Segment2D *endPtr;
|
---|
1483 |
|
---|
1484 | for (endPtr = segPtr + nSegments; segPtr < endPtr; segPtr++) {
|
---|
1485 | Blt_FormatToPostScript(psToken, "%g %g moveto\n",
|
---|
1486 | segPtr->p.x, segPtr->p.y);
|
---|
1487 | Blt_FormatToPostScript(psToken, " %g %g lineto\n",
|
---|
1488 | segPtr->q.x, segPtr->q.y);
|
---|
1489 | Blt_AppendToPostScript(psToken, "DashesProc stroke\n", (char *)NULL);
|
---|
1490 | }
|
---|
1491 | }
|
---|