[175] | 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 | }
|
---|