1 /*
2 * Author: William Chia-Wei Cheng (bill.cheng@acm.org)
3 *
4 * Copyright (C) 2001-2009, William Chia-Wei Cheng.
5 *
6 * This file may be distributed under the terms of the Q Public License
7 * as defined by Trolltech AS of Norway and appearing in the file
8 * LICENSE.QPL included in the packaging of this file.
9 *
10 * THIS FILE IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, INCLUDING
11 * THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
12 * PURPOSE. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL,
13 * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
14 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
15 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
16 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 *
18 * @(#)$Header: /mm2/home/cvs/bc-src/tgif/xbitmap.c,v 1.43 2011/05/16 16:22:00 william Exp $
19 */
20
21 #define _INCLUDE_FROM_XBITMAP_C_
22
23 #include "tgifdefs.h"
24 #include "expfdefs.h"
25 #include "cmdids.h"
26
27 #include "attr.e"
28 #include "auxtext.e"
29 #include "choice.e"
30 #include "cmd.e"
31 #include "color.e"
32 #include "cursor.e"
33 #include "cutpaste.e"
34 #include "dialog.e"
35 #include "drawing.e"
36 #include "dup.e"
37 #include "edit.e"
38 #include "eps.e"
39 #include "file.e"
40 #include "font.e"
41 #include "grid.e"
42 #include "imgproc.e"
43 #include "mainloop.e"
44 #include "mark.e"
45 #include "menu.e"
46 #include "miniline.e"
47 #include "move.e"
48 #include "msg.e"
49 #include "names.e"
50 #include "obj.e"
51 #include "page.e"
52 #include "pattern.e"
53 #include "ps.e"
54 #include "raster.e"
55 #include "rect.e"
56 #include "remote.e"
57 #include "select.e"
58 #include "setup.e"
59 #include "stretch.e"
60 #include "strtbl.e"
61 #include "util.e"
62 #include "version.e"
63 #include "xbitmap.e"
64 #include "xpixmap.e"
65 #include "xprtfltr.e"
66 #include "z_intrf.e"
67
68 GC xbmGC=NULL;
69
70 int askForXBmSpec=FALSE;
71 int stripEPSComments=FALSE;
72 int saveEPSLines=FALSE;
73
74 int leftExportPixelTrim=0;
75 int topExportPixelTrim=0;
76 int rightExportPixelTrim=0;
77 int bottomExportPixelTrim=0;
78
79 #ifdef _XPM3TOPPM
80 int xpmOutputVersion=3;
81 #else /* ~_XPM3TOPPM */
82 int xpmOutputVersion=1;
83 #endif /* _XPM3TOPPM */
84
85 Pixmap dummyBitmap=None;
86
87 char gszHhtmlExportTemplate[MAXPATHLENGTH];
88
89 /* do not translate -- program constants */
90 static char hexValue[]="0123456789abcdef";
91
92 static int importXBmRV=FALSE;
93 static int numColorsToDump=0;
94 static int charsPerPixel=1;
95 static int *pixelValue=NULL;
96 static int *colorIndexToDumpIndex=NULL;
97 static int *dumpIndexToColorIndex=NULL;
98 static char *colorChar=NULL;
99 static char **colorStr=NULL;
100
101 static int xpmInXGrabSCFormat=FALSE;
102
103 static int halfToneBitmap=FALSE; /* has precedence over thresholdBitmap */
104 static int thresholdBitmap=FALSE;
105 static float bitmapThreshold=0.5;
106 static char bitmapThresholdStr[MAXSTRING+1];
107
108 static int unsignedInXBmExport=FALSE;
109 static int commentInBitmapExport=FALSE;
110 static int useImagePixelsForTrueColorExport=FALSE;
111
112 #define IMF_FORMAT_NCSA 0
113 #define IMF_FORMAT_CERN 1
114 #define IMF_FORMAT_SPYG 2
115
116 static int generateImageMap=INVALID;
117 static char xpmToGifCmd[MAXSTRING+1];
118 static char xpmToPngCmd[MAXSTRING+1];
119 static char xpmToJpegCmd[MAXSTRING+1];
120 static char ppmToGifCmd[MAXSTRING+1];
121 static char ppmToPngCmd[MAXSTRING+1];
122 static char ppmToPngWithTransCmd[MAXSTRING+1];
123 static char ppmToJpegCmd[MAXSTRING+1];
124 static char ppm6ToXpm3Cmd[MAXSTRING+1];
125 static char xpmDeckToGifAnimCmd[MAXSTRING+1];
126 static char imageMapFileExtension[MAXSTRING+1];
127 static char htmlFileExtension[MAXSTRING+1];
128 static char gifFileExtension[MAXSTRING+1];
129 static char pngFileExtension[MAXSTRING+1];
130 static char jpegFileExtension[MAXSTRING+1];
131 static int imageMapFileFormat=IMF_FORMAT_NCSA;
132
133 #ifdef _XPM3TOPPM
134 static int useXPmVersion1ForImageMap=FALSE;
135 #else /* ~_XPM3TOPPM */
136 static int useXPmVersion1ForImageMap=TRUE;
137 #endif /* _XPM3TOPPM */
138
139 static int useXPmVersion1ForXPmDeck=TRUE;
140 static int generateHtmlHref=TRUE;
141
142 static int epsiThresholdPreviewBitmap=FALSE;
143 static double epsiPreviewBitmapThreshold=(double)0.5;
144
SetHtmlExportTemplate()145 void SetHtmlExportTemplate()
146 {
147 char spec[MAXSTRING<<1];
148
149 if (*gszHhtmlExportTemplate == '\0') {
150 sprintf(gszMsgBox, TgLoadString(STID_ENTER_HTML_TEMPLATE));
151 } else {
152 sprintf(gszMsgBox, TgLoadString(STID_ENTER_HTML_TEMPLATE_CUR_IS),
153 gszHhtmlExportTemplate);
154 }
155 *spec = '\0';
156 strcpy(spec, gszHhtmlExportTemplate);
157 if (Dialog(gszMsgBox, TgLoadCachedString(CSTID_DLG_ACCEPT_CANCEL), spec) ==
158 INVALID) {
159 return;
160 }
161 UtilTrimBlanks(spec);
162 if (strcmp(gszHhtmlExportTemplate, spec) == 0) {
163 Msg(TgLoadString(STID_HTML_TEMPLATE_UNCHANGED));
164 return;
165 }
166 if (*spec != '\0' && !UtilPathExists(spec)) {
167 sprintf(gszMsgBox, TgLoadString(STID_Q_FILE_NOT_EXIST_USE_ANYWAY), spec);
168 if (MsgBox(gszMsgBox, TOOL_NAME, YNC_MB) != MB_ID_YES) {
169 Msg(TgLoadString(STID_HTML_TEMPLATE_UNCHANGED));
170 return;
171 }
172 }
173 UtilStrCpyN(gszHhtmlExportTemplate, sizeof(gszHhtmlExportTemplate), spec);
174 if (*gszHhtmlExportTemplate == '\0') {
175 sprintf(gszMsgBox, TgLoadString(STID_NO_HTML_TEMPLATE_FILE));
176 } else {
177 sprintf(gszMsgBox, TgLoadString(STID_HTML_TEMPLATE_SET_TO_GIVEN),
178 gszHhtmlExportTemplate);
179 }
180 Msg(gszMsgBox);
181 SetFileModified(TRUE);
182 }
183
ReadHtmlExportTemplate(buf)184 int ReadHtmlExportTemplate(buf)
185 char *buf;
186 {
187 if (!importingFile) {
188 char *s=FindChar((int)'(', buf), *c_ptr=NULL;
189
190 c_ptr = FindChar((int)'"', s);
191 s = ReadString(c_ptr);
192 *(--s) = '\0';
193 *gszHhtmlExportTemplate = '\0';
194 UtilStrCpyN(gszHhtmlExportTemplate, sizeof(gszHhtmlExportTemplate),
195 c_ptr);
196 }
197 return TRUE;
198 }
199
200 static
ExpandTmpStorage()201 void ExpandTmpStorage()
202 {
203 /* the size before are all maxColors+2 */
204 pixelValue = (int*)realloc(pixelValue, (maxColors+3)*sizeof(int));
205 colorIndexToDumpIndex = (int*)realloc(colorIndexToDumpIndex,
206 (maxColors+3)*sizeof(int));
207 dumpIndexToColorIndex = (int*)realloc(dumpIndexToColorIndex,
208 (maxColors+3)*sizeof(int));
209 if (maxColors > 20) {
210 charsPerPixel = 2;
211 colorChar = (char*)realloc(colorChar, ((maxColors<<1)+4)*sizeof(char));
212 } else {
213 charsPerPixel = 1;
214 colorChar = (char*)realloc(colorChar, (maxColors+3)*sizeof(char));
215 }
216 colorStr = (char**)realloc(colorStr, (maxColors+3)*sizeof(char*));
217 if (colorStr == NULL) FailAllocMessage();
218 colorStr[maxColors+2] = NULL;
219 colorIndexToDumpIndex[maxColors+2] = INVALID;
220 dumpIndexToColorIndex[maxColors+2] = INVALID;
221 }
222
223 static
ParseExportPixelTrim(pszSpec,nInit)224 void ParseExportPixelTrim(pszSpec, nInit)
225 char *pszSpec;
226 int nInit;
227 {
228 char *pszLeft, *pszTop=NULL, *pszRight=NULL, *pszBottom=NULL;
229 int left, top, right, bottom;
230
231 pszLeft = strtok(pszSpec, " ,\t");
232 if (pszLeft == NULL) return;
233
234 pszTop = strtok(NULL, " ,\t");
235 if (pszTop != NULL) {
236 pszRight = strtok(NULL, " ,\t");
237 if (pszRight != NULL) {
238 pszBottom = strtok(NULL, " ,\t");
239 }
240 }
241 left = (pszLeft==NULL ? 0 : atoi(pszLeft));
242 top = (pszTop==NULL ? 0 : atoi(pszTop));
243 right = (pszRight==NULL ? 0 : atoi(pszRight));
244 bottom = (pszBottom==NULL ? 0 : atoi(pszBottom));
245 if (left < 0 || top < 0 || right < 0 || bottom < 0) {
246 sprintf(gszMsgBox, TgLoadString(STID_NEG_VAL_IN_EXP_PXL_TRM_ALT),
247 leftExportPixelTrim, topExportPixelTrim, rightExportPixelTrim,
248 bottomExportPixelTrim);
249 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
250 } else {
251 leftExportPixelTrim = left;
252 topExportPixelTrim = top;
253 rightExportPixelTrim = right;
254 bottomExportPixelTrim = bottom;
255 sprintf(gszMsgBox, TgLoadString(STID_EXP_PXL_TRM_VAL_SET_TO),
256 leftExportPixelTrim, topExportPixelTrim, rightExportPixelTrim,
257 bottomExportPixelTrim);
258 if (!nInit) Msg(gszMsgBox);
259 }
260 }
261
SetExportPixelTrim(cur_val_is_too_large)262 void SetExportPixelTrim(cur_val_is_too_large)
263 int cur_val_is_too_large;
264 {
265 char szSpec[MAXSTRING+1];
266
267 *szSpec = '\0';
268 sprintf(gszMsgBox, TgLoadString(STID_SPECIFY_TO_TRIM_EXP_PXL_TRM),
269 leftExportPixelTrim, topExportPixelTrim, rightExportPixelTrim,
270 bottomExportPixelTrim);
271 Dialog(gszMsgBox, TgLoadString(cur_val_is_too_large ?
272 STID_ENTER_4_NUM_CUR_TOO_LARGE : STID_ENTER_4_NUM_OR_CR_ESC), szSpec);
273 ParseExportPixelTrim(szSpec, FALSE);
274 }
275
GetXpmOutputVersion()276 int GetXpmOutputVersion()
277 {
278 return xpmOutputVersion;
279 }
280
SetXpmOutputVersion(xpm_output_version)281 void SetXpmOutputVersion(xpm_output_version)
282 int xpm_output_version;
283 {
284 xpmOutputVersion = xpm_output_version;
285 }
286
InitXBm()287 void InitXBm()
288 {
289 XGCValues values;
290 char *c_ptr;
291
292 dummyBitmap = XCreatePixmap(mainDisplay, mainWindow, 1, 1, 1);
293
294 values.foreground = 0;
295 values.background = 0;
296 values.function = GXcopy;
297 values.fill_style = FillSolid;
298 xbmGC = XCreateGC(mainDisplay, dummyBitmap,
299 GCForeground | GCBackground | GCFunction | GCFillStyle, &values);
300
301 *gszHhtmlExportTemplate = '\0';
302
303 importXBmRV = FALSE;
304 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"XBmReverseVideo")) != NULL &&
305 UtilStrICmp(c_ptr, "true") == 0) {
306 importXBmRV = TRUE;
307 }
308 askForXBmSpec = FALSE;
309 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"AskForXBmSpec")) != NULL &&
310 UtilStrICmp(c_ptr, "true") == 0) {
311 askForXBmSpec = TRUE;
312 }
313 stripEPSComments = FALSE;
314 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"StripEPSComments")) != NULL &&
315 UtilStrICmp(c_ptr, "false") != 0) {
316 fprintf(stderr, TgLoadString(STID_OBSOLETE_XDEF_USE_IGNORED),
317 TOOL_NAME, "StripEPSComments");
318 fprintf(stderr, "\n");
319 }
320 #ifdef _XPM3TOPPM
321 xpmOutputVersion = 3;
322 #else /* ~_XPM3TOPPM */
323 xpmOutputVersion = 1;
324 #endif /* _XPM3TOPPM */
325 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"XPmOutputVersion")) != NULL) {
326 xpmOutputVersion = atoi(c_ptr);
327 if (xpmOutputVersion != 1 && xpmOutputVersion != 3) {
328 #ifdef _XPM3TOPPM
329 int def_version=3;
330 #else /* ~_XPM3TOPPM */
331 int def_version=1;
332 #endif /* _XPM3TOPPM */
333
334 fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_VALUE),
335 TOOL_NAME, "XPmOutputVersion", c_ptr, def_version);
336 fprintf(stderr, "\n");
337 xpmOutputVersion = def_version;
338 }
339 }
340 xpmInXGrabSCFormat = FALSE;
341 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"XPmInXGrabSCFormat"))!=NULL &&
342 UtilStrICmp(c_ptr, "true") == 0) {
343 xpmInXGrabSCFormat = TRUE;
344 }
345 halfToneBitmap = FALSE;
346 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"HalfToneBitmap"))!=NULL &&
347 UtilStrICmp(c_ptr, "true") == 0) {
348 halfToneBitmap = TRUE;
349 }
350 thresholdBitmap = FALSE;
351 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"ThresholdBitmap")) != NULL &&
352 !halfToneBitmap && UtilStrICmp(c_ptr, "true") == 0) {
353 thresholdBitmap = TRUE;
354 }
355 bitmapThreshold = (halfToneBitmap) ? 0.5 : 1.0;
356 strcpy(bitmapThresholdStr, ((halfToneBitmap) ? "0.5" : "1.0"));
357 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"BitmapThreshold"))!=NULL) {
358 strcpy(bitmapThresholdStr, c_ptr);
359 bitmapThreshold = (float) atof(c_ptr);
360 if (bitmapThreshold < 0 || bitmapThreshold > 1) {
361 fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
362 TOOL_NAME, "BitmapThreshold", c_ptr,
363 ((halfToneBitmap) ? "0.5" : "1.0"));
364 fprintf(stderr, "\n");
365 bitmapThreshold = (halfToneBitmap) ? 0.5 : 1.0;
366 strcpy(bitmapThresholdStr, ((halfToneBitmap) ? "0.5" : "1.0"));
367 }
368 }
369 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"InitExportPixelTrim")) !=
370 NULL) {
371 ParseExportPixelTrim(c_ptr, TRUE);
372 }
373 unsignedInXBmExport = FALSE;
374 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"UnsignedInXBmExport")) !=
375 NULL && UtilStrICmp(c_ptr, "true") == 0) {
376 unsignedInXBmExport = TRUE;
377 }
378 commentInBitmapExport = FALSE;
379 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"CommentInBitmapExport")) !=
380 NULL && UtilStrICmp(c_ptr, "true") == 0) {
381 commentInBitmapExport = TRUE;
382 }
383 useImagePixelsForTrueColorExport = FALSE;
384 if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME,
385 "UseImagePixelsForTrueColorExport")) != NULL &&
386 UtilStrICmp(c_ptr, "true") == 0) {
387 useImagePixelsForTrueColorExport = TRUE;
388 }
389 epsiThresholdPreviewBitmap = FALSE;
390 if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME,
391 "EPSIThresholdPreviewBitmap")) != NULL &&
392 UtilStrICmp(c_ptr, "true") == 0) {
393 epsiThresholdPreviewBitmap = TRUE;
394 }
395 epsiPreviewBitmapThreshold = (float)0.5;
396 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,
397 "EPSIPreviewBitmapThreshold")) != NULL) {
398 epsiPreviewBitmapThreshold = (float) atof(c_ptr);
399 if (epsiPreviewBitmapThreshold < ((float)0) ||
400 epsiPreviewBitmapThreshold > (((float)1)+INT_TOL)) {
401 fprintf(stderr, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
402 TOOL_NAME, "EPSIPreviewBitmapThreshold", c_ptr, "0.5");
403 fprintf(stderr, "\n");
404 epsiPreviewBitmapThreshold = (float)0.5;
405 }
406 }
407 InitEPS();
408 }
409
ExportHalfToneBitmap()410 void ExportHalfToneBitmap()
411 {
412 halfToneBitmap = !halfToneBitmap;
413 Msg(TgLoadString(halfToneBitmap ?
414 STID_WILL_USE_FS_HALFTONE_BMP : STID_WILL_NOT_USE_FS_HALFTONE_BMP));
415 }
416
ExportThresholdBitmap()417 void ExportThresholdBitmap()
418 {
419 thresholdBitmap = !thresholdBitmap;
420 if (thresholdBitmap) {
421 sprintf(gszMsgBox, TgLoadString(STID_WILL_USE_GIVE_SMPLE_THRESHOLD),
422 bitmapThresholdStr);
423 } else {
424 sprintf(gszMsgBox, TgLoadString(STID_WILL_NOT_USE_SIMPLE_THRESHOLD));
425 }
426 Msg(gszMsgBox);
427 }
428
SetExportBitmapThreshold(buf)429 void SetExportBitmapThreshold(buf)
430 char *buf;
431 {
432 float threshold=(float)0;
433 char spec[MAXSTRING<<1];
434
435 *spec = '\0';
436 if (buf != NULL && strcmp(buf, "-1") != 0) {
437 int len=0;
438 UtilStrCpyN(spec, sizeof(spec), buf);
439 UtilTrimBlanks(spec);
440 len = strlen(spec);
441 if (len > 0 && spec[len-1] == ')') spec[len-1] = '\0';
442 } else {
443 sprintf(gszMsgBox, TgLoadString(STID_ENTER_BMP_THRESHOLD_CUR_VAL),
444 bitmapThresholdStr);
445 *spec = '\0';
446 if (Dialog(gszMsgBox, NULL, spec) == INVALID) {
447 return;
448 }
449 }
450 UtilTrimBlanks(spec);
451 if (sscanf(spec, "%f", &threshold) != 1) {
452 sprintf(gszMsgBox, TgLoadString(STID_INVALID_THRESHOLD_REMAINS),
453 spec, bitmapThresholdStr);
454 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
455 } else if (threshold < (float)0 || threshold > (float)1) {
456 sprintf(gszMsgBox, TgLoadString(STID_INVALID_THRESHOLD_REMAINS),
457 spec, bitmapThresholdStr);
458 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
459 } else {
460 strcpy(bitmapThresholdStr, spec);
461 bitmapThreshold = threshold;
462 sprintf(gszMsgBox, TgLoadString(STID_USE_GIVEN_AS_BMP_THRESHOLD),
463 bitmapThresholdStr);
464 Msg(gszMsgBox);
465 }
466 }
467
RefreshBitPixmapMenu(menu)468 int RefreshBitPixmapMenu(menu)
469 TgMenu *menu;
470 {
471 int ok=TRUE;
472
473 /* ExportHalfToneBitmap */
474 ok &= TgSetMenuItemCheckById(menu, CMDID_EXPORTHALFTONEBITMAP,
475 halfToneBitmap);
476 /* ExportThresholdBitmap */
477 ok &= TgSetMenuItemCheckById(menu, CMDID_EXPORTTHRESHOLDBITMAP,
478 thresholdBitmap);
479
480 ok &= TgEnableMenuItemById(menu, CMDID_EXPORTHALFTONEBITMAP,
481 (whereToPrint == XBM_FILE && !colorDump));
482 ok &= TgEnableMenuItemById(menu, CMDID_EXPORTTHRESHOLDBITMAP,
483 (whereToPrint == XBM_FILE && !colorDump));
484 ok &= TgEnableMenuItemById(menu, CMDID_SETEXPORTBITMAPTHRESHOLD,
485 (whereToPrint == XBM_FILE && !colorDump) && thresholdBitmap);
486
487 return ok;
488 }
489
CreateBitPixmapMenu(parent_menu,x,y,menu_info,status_str_xlated)490 TgMenu *CreateBitPixmapMenu(parent_menu, x, y, menu_info, status_str_xlated)
491 TgMenu *parent_menu;
492 int x, y;
493 TgMenuInfo *menu_info;
494 int status_str_xlated; /* ignored, always 0 */
495 {
496 TgMenu *menu=TgCreateMenuFromMenuInfo(parent_menu, x, y, menu_info, FALSE);
497
498 if (menu != NULL) {
499 menu->track_menubar = TRUE;
500 if (!RefreshBitPixmapMenu(menu)) {
501 return TgDestroyMenu(menu, TRUE);
502 }
503 }
504 return menu;
505 }
506
507 static int transparentIndex=INVALID;
508
509 static
FreeCachedStrings()510 void FreeCachedStrings()
511 {
512 register int i;
513
514 if (colorChar != NULL) {
515 for (i = 0; i < numColorsToDump+3; i++) {
516 if (colorStr[i] != NULL) {
517 free(colorStr[i]);
518 } else {
519 break;
520 }
521 }
522 free(colorStr);
523 free(colorChar);
524 free(pixelValue);
525 free(colorIndexToDumpIndex);
526 free(dumpIndexToColorIndex);
527 }
528 colorStr = NULL;
529 colorChar = NULL;
530 pixelValue = colorIndexToDumpIndex = dumpIndexToColorIndex = NULL;
531 transparentIndex = INVALID;
532 }
533
CleanUpXBm()534 void CleanUpXBm()
535 {
536 FreeCachedStrings();
537 CleanUpEPS();
538
539 if (xbmGC != NULL) XFreeGC(mainDisplay, xbmGC);
540 XFreePixmap(mainDisplay, dummyBitmap);
541
542 importXBmRV = FALSE;
543 askForXBmSpec = FALSE;
544 }
545
546 static
MultiplyTwoByTwo(m1,m2)547 void MultiplyTwoByTwo(m1, m2)
548 float m1[2][2], m2[2][2];
549 {
550 float m3[2][2];
551
552 m3[0][0] = m1[0][0]*m2[0][0] + m1[0][1]*m2[1][0];
553 m3[0][1] = m1[0][0]*m2[0][1] + m1[0][1]*m2[1][1];
554 m3[1][0] = m1[1][0]*m2[0][0] + m1[1][1]*m2[1][0];
555 m3[1][1] = m1[1][0]*m2[0][1] + m1[1][1]*m2[1][1];
556
557 m1[0][0]=m3[0][0]; m1[0][1]=m3[0][1]; m1[1][0]=m3[1][0]; m1[1][1]=m3[1][1];
558 }
559
CalcTransform(mtrx)560 void CalcTransform(mtrx)
561 register struct MtrxRec *mtrx;
562 {
563 float m1[2][2], m2[2][2], tmp_val;
564
565 switch (mtrx->rotate) {
566 case ROTATE0:
567 case ROTATE180:
568 mtrx->h_scale = mtrx->w / mtrx->image_w;
569 mtrx->v_scale = mtrx->h / mtrx->image_h;
570 break;
571 case ROTATE90:
572 case ROTATE270:
573 mtrx->h_scale = mtrx->h / mtrx->image_w;
574 mtrx->v_scale = mtrx->w / mtrx->image_h;
575 break;
576 }
577 m1[0][0]=1.0; m1[0][1]=0.0; m1[1][0]=0.0; m1[1][1]=1.0;
578 if (mtrx->flip & HORI_EVEN) {
579 m2[0][0]=(-1.0); m2[0][1]=0.0; m2[1][0]=0.0; m2[1][1]=1.0;
580 MultiplyTwoByTwo(m1, m2);
581 }
582 if (mtrx->flip & VERT_EVEN) {
583 m2[0][0]=1.0; m2[0][1]=0.0; m2[1][0]=0.0; m2[1][1]=(-1.0);
584 MultiplyTwoByTwo(m1, m2);
585 }
586 switch (mtrx->rotate) {
587 case ROTATE0:
588 if (mtrx->flip & (HORI_ODD | VERT_ODD)) {
589 m2[0][0]=rotatedCosine[ROTATE90]; m2[0][1]=rotatedSine[ROTATE90];
590 m2[1][0]=(-rotatedSine[ROTATE90]); m2[1][1]=rotatedCosine[ROTATE90];
591 MultiplyTwoByTwo(m1, m2);
592 if (mtrx->flip & HORI_ODD) {
593 m2[0][0]=(-1.0); m2[0][1]=0.0; m2[1][0]=0.0; m2[1][1]=1.0;
594 MultiplyTwoByTwo(m1, m2);
595 }
596 if (mtrx->flip & VERT_ODD) {
597 m2[0][0]=1.0; m2[0][1]=0.0; m2[1][0]=0.0; m2[1][1]=(-1.0);
598 MultiplyTwoByTwo(m1, m2);
599 }
600 m2[0][0]=rotatedCosine[ROTATE270];
601 m2[0][1]=rotatedSine[ROTATE270];
602 m2[1][0]=(-rotatedSine[ROTATE270]);
603 m2[1][1]=rotatedCosine[ROTATE270];
604 MultiplyTwoByTwo(m1, m2);
605 }
606 break;
607 case ROTATE90:
608 m2[0][0]=rotatedCosine[ROTATE90]; m2[0][1]=rotatedSine[ROTATE90];
609 m2[1][0]=(-rotatedSine[ROTATE90]); m2[1][1]=rotatedCosine[ROTATE90];
610 MultiplyTwoByTwo(m1, m2);
611 if (mtrx->flip & HORI_ODD) {
612 m2[0][0]=(-1.0); m2[0][1]=0.0; m2[1][0]=0.0; m2[1][1]=1.0;
613 MultiplyTwoByTwo(m1, m2);
614 }
615 if (mtrx->flip & VERT_ODD) {
616 m2[0][0]=1.0; m2[0][1]=0.0; m2[1][0]=0.0; m2[1][1]=(-1.0);
617 MultiplyTwoByTwo(m1, m2);
618 }
619 break;
620 case ROTATE180:
621 m2[0][0]=rotatedCosine[ROTATE90]; m2[0][1]=rotatedSine[ROTATE90];
622 m2[1][0]=(-rotatedSine[ROTATE90]); m2[1][1]=rotatedCosine[ROTATE90];
623 MultiplyTwoByTwo(m1, m2);
624 if (mtrx->flip & HORI_ODD) {
625 m2[0][0]=(-1.0); m2[0][1]=0.0; m2[1][0]=0.0; m2[1][1]=1.0;
626 MultiplyTwoByTwo(m1, m2);
627 }
628 if (mtrx->flip & VERT_ODD) {
629 m2[0][0]=1.0; m2[0][1]=0.0; m2[1][0]=0.0; m2[1][1]=(-1.0);
630 MultiplyTwoByTwo(m1, m2);
631 }
632 m2[0][0]=rotatedCosine[ROTATE90]; m2[0][1]=rotatedSine[ROTATE90];
633 m2[1][0]=(-rotatedSine[ROTATE90]); m2[1][1]=rotatedCosine[ROTATE90];
634 MultiplyTwoByTwo(m1, m2);
635 break;
636 case ROTATE270:
637 m2[0][0]=rotatedCosine[ROTATE270]; m2[0][1]=rotatedSine[ROTATE270];
638 m2[1][0]=(-rotatedSine[ROTATE270]); m2[1][1]=rotatedCosine[ROTATE270];
639 MultiplyTwoByTwo(m1, m2);
640 if (mtrx->flip & HORI_ODD) {
641 m2[0][0]=(-1.0); m2[0][1]=0.0; m2[1][0]=0.0; m2[1][1]=1.0;
642 MultiplyTwoByTwo(m1, m2);
643 }
644 if (mtrx->flip & VERT_ODD) {
645 m2[0][0]=1.0; m2[0][1]=0.0; m2[1][0]=0.0; m2[1][1]=(-1.0);
646 MultiplyTwoByTwo(m1, m2);
647 }
648 break;
649 }
650 m2[0][0]=mtrx->h_scale; m2[0][1]=0.0; m2[1][0]=0.0; m2[1][1]=mtrx->v_scale;
651 MultiplyTwoByTwo(m2, m1);
652
653 mtrx->m[0][0]=m2[0][0]; mtrx->m[0][1]=m2[0][1];
654 mtrx->m[1][0]=m2[1][0]; mtrx->m[1][1]=m2[1][1];
655 tmp_val = m2[0][0]*m2[1][1] - m2[0][1]*m2[1][0];
656 if (fabs((double) tmp_val) < 1.0e-6) {
657 tmp_val = ((float)1000000);
658 } else {
659 tmp_val = ((float)1.0)/tmp_val;
660 }
661 mtrx->rev_m[0][0] = tmp_val*m2[1][1];
662 mtrx->rev_m[0][1] = (-tmp_val)*m2[0][1];
663 mtrx->rev_m[1][0] = (-tmp_val)*m2[1][0];
664 mtrx->rev_m[1][1] = tmp_val*m2[0][0];
665
666 mtrx->transformed_w = mtrx->image_w*m2[0][0] + mtrx->image_h*m2[1][0];
667 mtrx->transformed_h = mtrx->image_w*m2[0][1] + mtrx->image_h*m2[1][1];
668
669 switch (mtrx->rotate) {
670 case ROTATE0:
671 mtrx->dump_h_scale=mtrx->m[0][0]; mtrx->dump_v_scale=mtrx->m[1][1];
672 mtrx->degree=0;
673 break;
674 case ROTATE90:
675 mtrx->dump_h_scale=mtrx->m[1][0]; mtrx->dump_v_scale=(-mtrx->m[0][1]);
676 mtrx->degree=(-90);
677 break;
678 case ROTATE180:
679 mtrx->dump_h_scale=(-mtrx->m[0][0]);
680 mtrx->dump_v_scale=(-mtrx->m[1][1]);
681 mtrx->degree=(-180);
682 break;
683 case ROTATE270:
684 mtrx->dump_h_scale=(-mtrx->m[1][0]); mtrx->dump_v_scale=mtrx->m[0][1];
685 mtrx->degree=(-270);
686 break;
687 }
688 }
689
MakeCachedBitmap(ObjPtr)690 void MakeCachedBitmap(ObjPtr)
691 struct ObjRec *ObjPtr;
692 {
693 register int r, c;
694 int w, h, flip, target_percent;
695 int num_cols, num_rows, image_w, image_h, watch_cursor;
696 int start_col, start_row, do_msg;
697 struct XBmRec *xbm_ptr=ObjPtr->detail.xbm;
698 struct MtrxRec mtrx;
699 Pixmap dest_bitmap;
700 XImage *src_image, *dest_image;
701
702 if (xbm_ptr->real_type==XBM_EPS && xbm_ptr->bitmap==None) return;
703
704 w = ObjPtr->obbox.rbx - ObjPtr->obbox.ltx;
705 h = ObjPtr->obbox.rby - ObjPtr->obbox.lty;
706 num_cols = (zoomedIn) ? (w<<zoomScale) : (w>>zoomScale);
707 num_rows = (zoomedIn) ? (h<<zoomScale) : (h>>zoomScale);
708
709 if (ObjPtr->ctm==NULL && xbm_ptr->cached_bitmap!=None &&
710 xbm_ptr->cached_zoomed==zoomedIn && xbm_ptr->cached_zoom==zoomScale &&
711 xbm_ptr->cached_w==num_cols && xbm_ptr->cached_h==num_rows &&
712 xbm_ptr->cached_flip==xbm_ptr->flip) {
713 return;
714 }
715 if ((w>>zoomScale)==0 || (h>>zoomScale)==0) {
716 if (xbm_ptr->cached_bitmap != None) {
717 XFreePixmap(mainDisplay, xbm_ptr->cached_bitmap);
718 }
719 xbm_ptr->cached_bitmap = None;
720 return;
721 }
722 watch_cursor = watchCursorOnMainWindow;
723 if (!watch_cursor && !RedrawDuringScrolling()) {
724 SetWatchCursor(drawWindow);
725 SetWatchCursor(mainWindow);
726 } else {
727 CheckInterrupt(TRUE);
728 }
729 src_image = xbm_ptr->image;
730 flip = xbm_ptr->flip;
731 image_w = xbm_ptr->image_w;
732 image_h = xbm_ptr->image_h;
733 if (xbm_ptr->cached_bitmap != None) {
734 XFreePixmap(mainDisplay, xbm_ptr->cached_bitmap);
735 }
736 xbm_ptr->cached_bitmap = None;
737
738 if (src_image == NULL) {
739 src_image = xbm_ptr->image = XGetImage(mainDisplay, xbm_ptr->bitmap,
740 0, 0, image_w, image_h, 1, ZPixmap);
741 }
742 do_msg = (((num_rows*num_cols)>=0x4000) && !RedrawDuringScrolling());
743 if (do_msg) {
744 SaveStatusStrings();
745 SetStringStatus(TgLoadCachedString(CSTID_CACHING_BITMAP));
746 XSync(mainDisplay, False);
747 }
748 dest_bitmap = XCreatePixmap(mainDisplay,dummyBitmap,num_cols,num_rows,1);
749 XFillRectangle(mainDisplay,dest_bitmap,xbmGC,0,0,num_cols,num_rows);
750 dest_image = XGetImage(mainDisplay, dest_bitmap, 0, 0, num_cols,
751 num_rows, 1, ZPixmap);
752
753 if (ObjPtr->ctm == NULL) {
754 mtrx.image_w = (float)image_w; mtrx.image_h = (float)image_h;
755 mtrx.w = (float)num_cols; mtrx.h = (float)num_rows;
756 mtrx.rotate = ROTATE0; mtrx.flip = flip;
757
758 CalcTransform(&mtrx);
759
760 start_col = (mtrx.transformed_w >= 0.0) ? 0 : (-num_cols)+1;
761 start_row = (mtrx.transformed_h >= 0.0) ? 0 : (-num_rows)+1;
762
763 target_percent = 5;
764 for (r = 0; r < num_rows; r++) {
765 double part_x, part_y;
766
767 if (do_msg && ((r & 0xf) == 0)) {
768 int percent=(r*10000/num_rows)/100;
769
770 if (percent >= target_percent) {
771 sprintf(gszMsgBox, TgLoadCachedString(CSTID_PROGRESS_PERCENT),
772 percent);
773 SetStringStatus(gszMsgBox);
774 XSync(mainDisplay, False);
775 while (target_percent <= percent) target_percent += 5;
776 }
777 }
778 part_x = ((double)(r+start_row)+0.5)*(mtrx.rev_m[1][0]);
779 part_y = ((double)(r+start_row)+0.5)*(mtrx.rev_m[1][1]);
780 for (c = 0; c < num_cols; c++) {
781 double x, y;
782
783 x = part_x+((double)(c+start_col)+0.5)*(mtrx.rev_m[0][0]);
784 y = part_y+((double)(c+start_col)+0.5)*(mtrx.rev_m[0][1]);
785 if (x >= ((double)0) && x < ((double)image_w) &&
786 y >= ((double)0) && y < ((double)image_h)) {
787 if (XGetPixel(src_image, (int)x, (int)y) == 1) {
788 XPutPixel(dest_image, c, r, 1);
789 }
790 }
791 }
792 }
793 } else {
794 int abs_offset_x=ObjPtr->obbox.ltx-ObjPtr->x;
795 int abs_offset_y=ObjPtr->obbox.lty-ObjPtr->y;
796 double sx=(double)0.0, sy=(double)0.0;
797
798 if (xbm_ptr->real_type != XBM_XBM) {
799 sx = (((double)xbm_ptr->eps_w)/((double)image_w));
800 sy = (((double)xbm_ptr->eps_h)/((double)image_h));
801 }
802 target_percent = 5;
803 for (r=0; r < num_rows; r++) {
804 int y=abs_offset_y+ABS_SIZE(r);
805 double dy=((double)y)+0.5;
806
807 if (do_msg && ((r & 0xf) == 0)) {
808 int percent=(r*10000/num_rows)/100;
809
810 if (percent >= target_percent) {
811 sprintf(gszMsgBox, TgLoadCachedString(CSTID_PROGRESS_PERCENT),
812 percent);
813 SetStringStatus(gszMsgBox);
814 XSync(mainDisplay, False);
815 while (target_percent <= percent) target_percent += 5;
816 }
817 }
818 for (c=0; c < num_cols; c++) {
819 int x=abs_offset_x+ABS_SIZE(c);
820 double dx=((double)x)+0.5;
821 double new_dx=(double)0, new_dy=(double)0;
822
823 ReverseTransformDoublePointThroughCTM(dx, dy, ObjPtr->ctm,
824 &new_dx, &new_dy);
825 if (xbm_ptr->real_type != XBM_XBM) {
826 double tmp_dx=((double)new_dx)/sx;
827 double tmp_dy=((double)new_dy)/sy;
828
829 new_dx = tmp_dx + ((double)(ObjPtr->x - ObjPtr->orig_obbox.ltx));
830 new_dy = tmp_dy + ((double)(ObjPtr->y - ObjPtr->orig_obbox.lty));
831 } else {
832 new_dx += (double)(ObjPtr->x-ObjPtr->orig_obbox.ltx);
833 new_dy += (double)(ObjPtr->y-ObjPtr->orig_obbox.lty);
834 }
835 if (new_dx >= ((double)0) && new_dx < ((double)image_w) &&
836 new_dy >= ((double)0) && new_dy < ((double)image_h)) {
837 int new_x=(int)new_dx, new_y=(int)new_dy;
838
839 if (new_x < 0) new_x = 0;
840 if (new_x >= image_w) new_x = image_w-1;
841 if (new_y < 0) new_y = 0;
842 if (new_y >= image_h) new_y = image_h-1;
843 if (XGetPixel(src_image, new_x, new_y) == 1) {
844 XPutPixel(dest_image, c, r, 1);
845 }
846 }
847 }
848 }
849 memcpy(&xbm_ptr->cached_ctm, ObjPtr->ctm, sizeof(struct XfrmMtrxRec));
850 }
851 if (do_msg) {
852 SetStringStatus(TgLoadCachedString(CSTID_FINISHED_CACHEING_BITMAP));
853 XSync(mainDisplay, False);
854 }
855 XPutImage(mainDisplay, dest_bitmap, xbmGC, dest_image, 0, 0, 0, 0,
856 num_cols, num_rows);
857 if (do_msg) RestoreStatusStrings();
858
859 xbm_ptr->cached_bitmap = dest_bitmap;
860 xbm_ptr->cached_zoomed = zoomedIn;
861 xbm_ptr->cached_zoom = zoomScale;
862 xbm_ptr->cached_flip = xbm_ptr->flip;
863 xbm_ptr->cached_w = num_cols;
864 xbm_ptr->cached_h = num_rows;
865
866 XDestroyImage(dest_image);
867
868 if (!watch_cursor && !RedrawDuringScrolling()) {
869 SetDefaultCursor(mainWindow);
870 ShowCursor();
871 } else {
872 CheckInterrupt(TRUE);
873 }
874 }
875
ExtractBitmap(OrigBitmap,OrigImage,X,Y,W,H,Bitmap,Image)876 int ExtractBitmap(OrigBitmap, OrigImage, X, Y, W, H, Bitmap, Image)
877 Pixmap OrigBitmap, *Bitmap;
878 XImage *OrigImage, **Image;
879 int X, Y, W, H;
880 {
881 register int j, i;
882 XImage *src_image;
883
884 SetWatchCursor(drawWindow);
885 SetWatchCursor(mainWindow);
886
887 if ((*Bitmap=XCreatePixmap(mainDisplay,mainWindow,W,H,1)) == None) {
888 FailAllocBitmapMessage(W, H);
889 SetDefaultCursor(mainWindow);
890 SetDefaultCursor(drawWindow);
891 return FALSE;
892 }
893
894 if ((*Image=XGetImage(mainDisplay, *Bitmap, 0, 0, W, H, 1,
895 ZPixmap)) == NULL) {
896 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME,
897 INFO_MB);
898 XFreePixmap(mainDisplay, *Bitmap); *Bitmap = None;
899 SetDefaultCursor(mainWindow);
900 SetDefaultCursor(drawWindow);
901 return FALSE;
902 }
903 if (OrigImage != NULL && X == 0 && Y == 0) {
904 src_image = OrigImage;
905 } else {
906 if ((src_image=XGetImage(mainDisplay, OrigBitmap, X, Y, W, H, 1,
907 ZPixmap)) == NULL) {
908 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME,
909 INFO_MB);
910 XFreePixmap(mainDisplay, *Bitmap);
911 *Bitmap = None;
912 XDestroyImage(*Image); *Image = NULL;
913 SetDefaultCursor(mainWindow);
914 SetDefaultCursor(drawWindow);
915 return FALSE;
916 }
917 }
918 for (i=0; i < H; i++) {
919 for (j=0; j < W; j++) {
920 XPutPixel(*Image, j, i, XGetPixel(src_image, j, i));
921 }
922 }
923 XPutImage(mainDisplay, *Bitmap, xbmGC, *Image, 0, 0, 0, 0, W, H);
924 SetDefaultCursor(mainWindow);
925 SetDefaultCursor(drawWindow);
926
927 if (!(OrigImage != NULL && X == 0 && Y == 0)) XDestroyImage(src_image);
928 return TRUE;
929 }
930
AutoTrimBitmap(OrigBitmap,pnImageW,pnImageH,pBitmap,pImage,pnEmptyImage,pnDontFreeOrigBitmap)931 int AutoTrimBitmap(OrigBitmap, pnImageW, pnImageH, pBitmap, pImage,
932 pnEmptyImage, pnDontFreeOrigBitmap)
933 Pixmap OrigBitmap, *pBitmap;
934 int *pnImageW, *pnImageH, *pnEmptyImage, *pnDontFreeOrigBitmap;
935 XImage **pImage;
936 {
937 int i=0, orig_w=(*pnImageW), orig_h=(*pnImageH);
938 int top=orig_h, left=orig_w, bottom=(-1), right=(-1);
939 XImage *image=NULL;
940
941 *pnEmptyImage = *pnDontFreeOrigBitmap = FALSE;
942
943 SetWatchCursor(drawWindow);
944 SetWatchCursor(mainWindow);
945 image = XGetImage(mainDisplay, OrigBitmap, 0, 0, orig_w, orig_h, 1, ZPixmap);
946
947 if (image == NULL) {
948 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME,
949 INFO_MB);
950 SetDefaultCursor(mainWindow);
951 SetDefaultCursor(drawWindow);
952 return FALSE;
953 }
954 for (i=0; i < orig_h; i++) {
955 int j=0;
956
957 for (j=0; j < orig_w; j++) {
958 if (XGetPixel(image, j, i) != 0) {
959 if (i < top) top = i;
960 if (i > bottom) bottom = i;
961 if (j < left) left = j;
962 if (j > right) right = j;
963 }
964 }
965 }
966 SetDefaultCursor(mainWindow);
967 SetDefaultCursor(drawWindow);
968
969 if (top == orig_h && left == orig_w && bottom == (-1) && right == (-1)) {
970 /* no image */
971 *pnEmptyImage = TRUE;
972 XDestroyImage(image);
973 return FALSE;
974 } else if (top == 0 && left == 0 && bottom == orig_w-1 &&
975 right == orig_h-1) {
976 *pnImageW = orig_w;
977 *pnImageH = orig_h;
978 *pBitmap = OrigBitmap;
979 *pImage = image;
980 *pnDontFreeOrigBitmap = TRUE;
981 } else {
982 /* trim */
983 int rc=0;
984
985 *pnImageW = right-left+1;
986 *pnImageH = bottom-top+1;
987 rc = ExtractBitmap(OrigBitmap, image, left, top, *pnImageW, *pnImageH,
988 pBitmap, pImage);
989 XDestroyImage(image);
990
991 return rc;
992 }
993 return TRUE;
994 }
995
996 static
InvertXBmObject(ObjPtr)997 void InvertXBmObject(ObjPtr)
998 struct ObjRec *ObjPtr;
999 {
1000 int i, j, image_w, image_h, pixel, watch_cursor=watchCursorOnMainWindow;
1001 Pixmap bitmap=None;
1002 XImage *image=NULL;
1003
1004 if (!watch_cursor) {
1005 SetWatchCursor(drawWindow);
1006 SetWatchCursor(mainWindow);
1007 }
1008 bitmap = ObjPtr->detail.xbm->bitmap;
1009
1010 image_w = ObjPtr->detail.xbm->image_w;
1011 image_h = ObjPtr->detail.xbm->image_h;
1012 if (ObjPtr->detail.xbm->image == NULL) {
1013 if ((image=ObjPtr->detail.xbm->image = XGetImage(mainDisplay, bitmap,
1014 0, 0, image_w, image_h, 1, ZPixmap)) == NULL) {
1015 fprintf(stderr, "%s\n",
1016 TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM));
1017 fflush(stderr);
1018 SetDefaultCursor(mainWindow);
1019 SetDefaultCursor(drawWindow);
1020 if (!watch_cursor) {
1021 SetDefaultCursor(mainWindow);
1022 ShowCursor();
1023 }
1024 return;
1025 }
1026 } else {
1027 image = ObjPtr->detail.xbm->image;
1028 }
1029 for (i=0; i < image_h; i++) {
1030 for (j=0; j < image_w; j++) {
1031 pixel = XGetPixel(image, j, i);
1032 XPutPixel(image, j, i, ((pixel==1) ? 0 : 1));
1033 }
1034 }
1035 XPutImage(mainDisplay, bitmap, xbmGC, image, 0, 0, 0, 0, image_w, image_h);
1036
1037 if (ObjPtr->detail.xbm->cached_bitmap != None) {
1038 XFreePixmap(mainDisplay, ObjPtr->detail.xbm->cached_bitmap);
1039 }
1040 ObjPtr->detail.xbm->cached_bitmap = None;
1041 if (zoomScale != 0) {
1042 ObjPtr->detail.xbm->cached_zoom = 0;
1043 }
1044 if (!watch_cursor) {
1045 SetDefaultCursor(mainWindow);
1046 ShowCursor();
1047 }
1048 }
1049
1050 static
ObjListInvertable(LastObjPtr)1051 int ObjListInvertable(LastObjPtr)
1052 struct ObjRec *LastObjPtr;
1053 {
1054 struct ObjRec *obj_ptr;
1055
1056 for (obj_ptr=LastObjPtr; obj_ptr != NULL; obj_ptr=obj_ptr->prev) {
1057 switch (obj_ptr->type) {
1058 case OBJ_XBM: return TRUE;
1059
1060 case OBJ_GROUP:
1061 case OBJ_ICON:
1062 case OBJ_SYM:
1063 if (ObjListInvertable(obj_ptr->detail.r->last)) return TRUE;
1064 break;
1065 case OBJ_PIN:
1066 if (ObjListInvertable(GetPinObj(obj_ptr)->detail.r->last)) return TRUE;
1067 break;
1068 }
1069 }
1070 return FALSE;
1071 }
1072
1073 static
InvertObjListXBitmap(LastObjPtr)1074 void InvertObjListXBitmap(LastObjPtr)
1075 struct ObjRec *LastObjPtr;
1076 {
1077 struct ObjRec *obj_ptr;
1078
1079 for (obj_ptr=LastObjPtr; obj_ptr != NULL; obj_ptr=obj_ptr->prev) {
1080 switch (obj_ptr->type) {
1081 case OBJ_XBM: InvertXBmObject(obj_ptr); break;
1082
1083 case OBJ_GROUP:
1084 case OBJ_ICON:
1085 case OBJ_SYM:
1086 InvertObjListXBitmap(obj_ptr->detail.r->last);
1087 break;
1088 case OBJ_PIN:
1089 InvertObjListXBitmap(GetPinObj(obj_ptr)->detail.r->last);
1090 break;
1091 }
1092 }
1093 }
1094
InvertXBitmaps()1095 void InvertXBitmaps()
1096 {
1097 struct SelRec *sel_ptr;
1098 int changed=FALSE;
1099
1100 if (topSel == NULL) {
1101 MsgBox(TgLoadCachedString(CSTID_NO_OBJ_SELECTED), TOOL_NAME, INFO_MB);
1102 return;
1103 }
1104 StartCompositeCmd();
1105 for (sel_ptr=botSel; sel_ptr != NULL; sel_ptr=sel_ptr->prev) {
1106 switch (sel_ptr->obj->type) {
1107 case OBJ_XBM:
1108 changed = TRUE;
1109 PrepareToReplaceAnObj(sel_ptr->obj);
1110 InvertXBmObject(sel_ptr->obj);
1111 RecordReplaceAnObj(sel_ptr->obj);
1112 break;
1113
1114 case OBJ_GROUP:
1115 case OBJ_ICON:
1116 case OBJ_SYM:
1117 case OBJ_PIN:
1118 if (ObjListInvertable(sel_ptr->obj->detail.r->last)) {
1119 changed = TRUE;
1120 PrepareToReplaceAnObj(sel_ptr->obj);
1121 InvertObjListXBitmap(sel_ptr->obj->detail.r->last);
1122 RecordReplaceAnObj(sel_ptr->obj);
1123 }
1124 break;
1125 }
1126 }
1127 EndCompositeCmd();
1128
1129 if (changed) {
1130 SetFileModified(TRUE);
1131 HighLightReverse();
1132 RedrawAnArea(botObj, selLtX-GRID_ABS_SIZE(1), selLtY-GRID_ABS_SIZE(1),
1133 selRbX+GRID_ABS_SIZE(1), selRbY+GRID_ABS_SIZE(1));
1134 HighLightForward();
1135 } else {
1136 MsgBox(TgLoadString(STID_NO_X11_BITMAP_OBJ_SELECTED), TOOL_NAME, INFO_MB);
1137 }
1138 }
1139
1140 static
ParseGeomSpec(geom_spec,image_w,image_h,src_x,src_y,src_w,src_h)1141 void ParseGeomSpec(geom_spec, image_w, image_h, src_x, src_y, src_w, src_h)
1142 char *geom_spec;
1143 int image_w, image_h, *src_x, *src_y, *src_w, *src_h;
1144 {
1145 int bitmask;
1146 XSizeHints sizehints;
1147
1148 *src_x = *src_y = 0;
1149 *src_w = image_w;
1150 *src_h = image_h;
1151
1152 bitmask = XParseGeometry(geom_spec, &(sizehints.x), &(sizehints.y),
1153 (unsigned int *)&(sizehints.width),
1154 (unsigned int *)&(sizehints.height));
1155 if (bitmask & WidthValue) *src_w = sizehints.width;
1156 if (bitmask & HeightValue) *src_h = sizehints.height;
1157 if (bitmask & XValue) {
1158 *src_x = (bitmask & XNegative) ? image_w+sizehints.x : sizehints.x;
1159 if (bitmask & XNegative) {
1160 if (*src_w > image_w) *src_w = image_w;
1161 if (*src_x >= image_w || *src_x < 0) *src_x = image_w;
1162 if (*src_x-*src_w < 0) {
1163 *src_w = *src_x;
1164 *src_x = 0;
1165 } else {
1166 *src_x -= *src_w;
1167 }
1168 } else {
1169 if (*src_w > image_w) *src_w = image_w;
1170 if (*src_x >= image_w || *src_x < 0) *src_x = 0;
1171 if (*src_x+*src_w > image_w) *src_w = image_w-*src_x;
1172 }
1173 }
1174 if (bitmask & YValue) {
1175 *src_y = (bitmask & YNegative) ? image_h+sizehints.y : sizehints.y;
1176 if (bitmask & YNegative) {
1177 if (*src_h > image_h) *src_h = image_h;
1178 if (*src_y >= image_h || *src_y < 0) *src_y = image_h;
1179 if (*src_y-*src_h < 0) {
1180 *src_h = *src_y;
1181 *src_y = 0;
1182 } else {
1183 *src_y -= *src_h;
1184 }
1185 } else {
1186 if (*src_h > image_h) *src_h = image_h;
1187 if (*src_y >= image_h || *src_y < 0) *src_y = 0;
1188 if (*src_y+*src_h > image_h) *src_h = image_h-*src_y;
1189 }
1190 }
1191 if ((bitmask&WidthValue) && *src_x+*src_w>image_w) *src_w = image_w-*src_x;
1192 if ((bitmask&HeightValue) && *src_y+*src_h>image_h) *src_h = image_h-*src_y;
1193 }
1194
1195 static
FindEqual(s)1196 char *FindEqual(s)
1197 register char *s;
1198 {
1199 while (*s != '=' && *s != '\0') s++;
1200 return ((*s == '=') ? (s) : (char*)NULL);
1201 }
1202
ParseCutSpec(spec,image_w,image_h,mag,src_x,src_y,src_w,src_h)1203 void ParseCutSpec(spec, image_w, image_h, mag, src_x, src_y, src_w, src_h)
1204 char *spec;
1205 int image_w, image_h, * src_x, * src_y, * src_w, * src_h;
1206 float *mag;
1207 {
1208 char *geom_spec;
1209
1210 *mag = 1.0;
1211
1212 if ((geom_spec=FindEqual(spec)) == NULL) {
1213 ParseGeomSpec(spec,image_w,image_h,src_x,src_y,src_w,src_h);
1214 } else {
1215 *geom_spec = '\0';
1216 geom_spec++;
1217 ParseGeomSpec(geom_spec,image_w,image_h,src_x,src_y,src_w,src_h);
1218
1219 sscanf(spec, "%f", mag);
1220 if (*mag <= 0.0) *mag = 1.0;
1221 }
1222 }
1223
CutXBitmap()1224 void CutXBitmap()
1225 {
1226 int w, h, ltx, lty, rbx, rby, new_w, new_h;
1227 int src_x, src_y, src_w, src_h, image_w, image_h;
1228 char mag_spec[MAXSTRING];
1229 float h_scale=1.0, v_scale=1.0, mag;
1230 Pixmap dest_bitmap=None;
1231 XImage *dest_image=NULL;
1232 struct ObjRec *obj_ptr=topSel->obj, *new_obj_ptr;
1233 struct XBmRec *new_xbm_ptr;
1234
1235 if (obj_ptr->detail.xbm->real_type==XBM_EPS) {
1236 MsgBox(TgLoadString(STID_CANT_CUT_AN_EPS_OBJECT), TOOL_NAME, INFO_MB);
1237 return;
1238 }
1239
1240 src_x = 0;
1241 src_y = 0;
1242 src_w = image_w = obj_ptr->detail.xbm->image_w;
1243 src_h = image_h = obj_ptr->detail.xbm->image_h;
1244 mag = 1.0;
1245
1246 h_scale = ((float)((float)(obj_ptr->obbox.rbx-obj_ptr->obbox.ltx)) /
1247 ((float)image_w));
1248 v_scale = ((float)((float)(obj_ptr->obbox.rby-obj_ptr->obbox.lty)) /
1249 ((float)image_h));
1250
1251 *mag_spec = '\0';
1252 sprintf(gszMsgBox, TgLoadString(STID_ENTER_GEOM_SPEC_ORIG_SIZE),
1253 image_w, image_h);
1254 Dialog(gszMsgBox, TgLoadCachedString(CSTID_DLG_ACCEPT_CANCEL), mag_spec);
1255 UtilTrimBlanks(mag_spec);
1256 if (*mag_spec == '\0') return;
1257
1258 ParseCutSpec(mag_spec,image_w,image_h,&mag,&src_x,&src_y,&src_w,&src_h);
1259 if (src_x==0 && src_y==0 && src_w==image_w && src_h==image_h && mag==1.0) {
1260 return;
1261 }
1262 if (src_w==0 || src_h==0) {
1263 MsgBox(TgLoadString(STID_XBM_CANT_HAVE_0_W_OR_H), TOOL_NAME, INFO_MB);
1264 return;
1265 }
1266
1267 PrepareToRecord(CMD_REPLACE, topSel, botSel, numObjSelected);
1268 if (!ExtractBitmap(obj_ptr->detail.xbm->bitmap,
1269 obj_ptr->detail.xbm->image, src_x, src_y, src_w, src_h,
1270 &dest_bitmap, &dest_image)) {
1271 AbortPrepareCmd(CMD_REPLACE);
1272 return;
1273 }
1274
1275 sprintf(gszMsgBox, TgLoadCachedString(CSTID_NEW_BMP_SIZE_IS_W_X_H),
1276 src_w, src_h);
1277 Msg(gszMsgBox);
1278
1279 UnlinkObj(obj_ptr);
1280
1281 ltx = selLtX; lty = selLtY; rbx = selRbX; rby = selRbY;
1282 HighLightReverse();
1283
1284 w = new_w = (int)(((float)src_w) * mag);
1285 h = new_h = (int)(((float)src_h) * mag);
1286
1287 new_obj_ptr = (struct ObjRec *)malloc(sizeof(struct ObjRec));
1288 if (new_obj_ptr == NULL) FailAllocMessage();
1289 memset(new_obj_ptr, 0, sizeof(struct ObjRec));
1290 DupObjBasics(obj_ptr, new_obj_ptr);
1291
1292 new_xbm_ptr = (struct XBmRec *)malloc(sizeof(struct XBmRec));
1293 if (new_xbm_ptr == NULL) FailAllocMessage();
1294 memset(new_xbm_ptr, 0, sizeof(struct XBmRec));
1295 new_obj_ptr->detail.xbm = new_xbm_ptr;
1296
1297 new_xbm_ptr->image = dest_image;
1298 new_xbm_ptr->image_w = src_w;
1299 new_xbm_ptr->image_h = src_h;
1300 new_xbm_ptr->bitmap = dest_bitmap;
1301 new_xbm_ptr->data = NULL;
1302 new_xbm_ptr->fill = obj_ptr->detail.xbm->fill;
1303 new_xbm_ptr->flip = obj_ptr->detail.xbm->flip;
1304 new_xbm_ptr->cached_zoom = 0;
1305 new_xbm_ptr->cached_bitmap = None;
1306 new_xbm_ptr->cached_flip = 0;
1307 new_xbm_ptr->cached_w = 0;
1308 new_xbm_ptr->cached_h = 0;
1309
1310 new_w = round(h_scale * ((float)w));
1311 new_h = round(v_scale * ((float)h));
1312
1313 new_obj_ptr->obbox.ltx = obj_ptr->obbox.ltx;
1314 new_obj_ptr->obbox.lty = obj_ptr->obbox.lty;
1315 new_obj_ptr->obbox.rbx = new_obj_ptr->bbox.rbx = obj_ptr->obbox.ltx+new_w;
1316 new_obj_ptr->obbox.rby = new_obj_ptr->bbox.rby = obj_ptr->obbox.lty+new_h;
1317
1318 AdjObjBBox(new_obj_ptr);
1319
1320 topSel->obj = botSel->obj = new_obj_ptr;
1321 AddObj(NULL, topObj, new_obj_ptr);
1322 RecordCmd(CMD_REPLACE, NULL, topSel, botSel, numObjSelected);
1323 FreeObj(obj_ptr);
1324
1325 UpdSelBBox();
1326 RedrawAreas(botObj, ltx-GRID_ABS_SIZE(1), lty-GRID_ABS_SIZE(1),
1327 rbx+GRID_ABS_SIZE(1), rby+GRID_ABS_SIZE(1),
1328 selLtX-GRID_ABS_SIZE(1), selLtY-GRID_ABS_SIZE(1),
1329 selRbX+GRID_ABS_SIZE(1), selRbY+GRID_ABS_SIZE(1));
1330 HighLightForward();
1331 SetFileModified(TRUE);
1332 justDupped = FALSE;
1333 }
1334
1335 static
UpdateColorsLookupTable(color_index)1336 void UpdateColorsLookupTable(color_index)
1337 int color_index;
1338 {
1339 if (colorIndexToDumpIndex[color_index] == INVALID) {
1340 if (colorStr[numColorsToDump] != NULL) {
1341 free(colorStr[numColorsToDump]);
1342 }
1343 pixelValue[numColorsToDump] = colorPixels[color_index];
1344 colorIndexToDumpIndex[color_index] = numColorsToDump;
1345 dumpIndexToColorIndex[numColorsToDump] = color_index;
1346 colorStr[numColorsToDump] = (char *) malloc(
1347 (strlen(colorMenuItems[color_index])+1)*sizeof(char));
1348 if (colorStr[numColorsToDump] == NULL) FailAllocMessage();
1349 strcpy(colorStr[numColorsToDump], colorMenuItems[color_index]);
1350 numColorsToDump++;
1351 }
1352 }
1353
1354 static
BuildStrSegColors(pStrSeg,pUserData)1355 void BuildStrSegColors(pStrSeg, pUserData)
1356 StrSegInfo *pStrSeg;
1357 void *pUserData;
1358 {
1359 UpdateColorsLookupTable(pStrSeg->color);
1360 }
1361
1362 static
BuildObjXPmColors(ObjPtr)1363 void BuildObjXPmColors(ObjPtr)
1364 struct ObjRec *ObjPtr;
1365 {
1366 register int i, color_index;
1367 register struct ObjRec *obj_ptr;
1368 register struct AttrRec *attr_ptr;
1369 struct XPmRec *xpm_ptr;
1370 int start_index, new_alloc;
1371
1372 switch (ObjPtr->type) {
1373 case OBJ_POLY:
1374 case OBJ_BOX:
1375 case OBJ_OVAL:
1376 case OBJ_POLYGON:
1377 case OBJ_ARC:
1378 case OBJ_RCBOX:
1379 case OBJ_XBM:
1380 UpdateColorsLookupTable(ObjPtr->color);
1381 if (ObjPtr->type == OBJ_XBM) {
1382 if (ObjPtr->detail.xbm->real_type==XBM_EPS &&
1383 ObjPtr->detail.xbm->bitmap==None) {
1384 char color_str[COLORSTRLEN];
1385
1386 new_alloc = FALSE;
1387 GetDrawingFgColorStr(INVALID, INVALID, color_str,
1388 sizeof(color_str));
1389 color_index = QuickFindColorIndex(NULL, color_str, &new_alloc,
1390 FALSE);
1391 if (color_index != INVALID) {
1392 if (new_alloc) ExpandTmpStorage();
1393 UpdateColorsLookupTable(color_index);
1394 }
1395 }
1396 }
1397 break;
1398
1399 case OBJ_TEXT:
1400 UpdateColorsLookupTable(ObjPtr->color);
1401 DoFuncOnStrSegForMiniLines(&ObjPtr->detail.t->minilines,
1402 BuildStrSegColors, NULL);
1403 break;
1404
1405 case OBJ_XPM:
1406 xpm_ptr = ObjPtr->detail.xpm;
1407 start_index = (xpm_ptr->first_pixel_is_bg) ? 1 : 0;
1408 for (i=start_index; i < xpm_ptr->ncolors; i++) {
1409 /* do not translate -- program constants */
1410 if (UtilStrICmp(xpm_ptr->color_str[i], "None") == 0) {
1411 if (whereToPrint == XBM_FILE && colorDump &&
1412 transparentIndex == (-1)) {
1413 /*
1414 * Transparent stuff pretty much only works for straight
1415 * XPM output and nothing else. None of the
1416 * convertors (e.g., xpmtoppm) can handle the
1417 * None color in an XPM file.
1418 */
1419 if (colorStr[numColorsToDump] != NULL) {
1420 free(colorStr[numColorsToDump]);
1421 }
1422 pixelValue[numColorsToDump] = (-1);
1423 colorStr[numColorsToDump] = UtilStrDup("None");
1424 transparentIndex = numColorsToDump++;
1425 }
1426 } else if ((color_index=QuickFindColorIndex(NULL,
1427 xpm_ptr->color_str[i], &new_alloc, TRUE)) != INVALID) {
1428 if (new_alloc) ExpandTmpStorage();
1429 UpdateColorsLookupTable(color_index);
1430 }
1431 }
1432 if (!PRTGIF && colorLayers && needToRedrawColorWindow) {
1433 RedrawColorWindow();
1434 }
1435 break;
1436
1437 case OBJ_GROUP:
1438 case OBJ_ICON:
1439 case OBJ_SYM:
1440 for (obj_ptr=ObjPtr->detail.r->first; obj_ptr != NULL;
1441 obj_ptr=obj_ptr->next) {
1442 BuildObjXPmColors(obj_ptr);
1443 }
1444 break;
1445 case OBJ_PIN:
1446 obj_ptr = GetPinObj(ObjPtr);
1447 BuildObjXPmColors(obj_ptr);
1448 break;
1449 }
1450 for (attr_ptr=ObjPtr->fattr; attr_ptr!=NULL; attr_ptr=attr_ptr->next) {
1451 BuildObjXPmColors(attr_ptr->obj);
1452 }
1453 }
1454
1455 typedef struct tagTmpBucketInfo {
1456 int pixel;
1457 struct tagTmpBucketInfo *next;
1458 } TmpBucketInfo;
1459
1460 static int numTmpBuckets=0;
1461 static TmpBucketInfo **ppTmpBuckets=NULL;
1462 static int tmpRedShift=0, tmpGreenShift=0, tmpBlueShift=0;
1463
1464 static
CleanUpTmpBuckets()1465 void CleanUpTmpBuckets()
1466 {
1467 int i=0;
1468
1469 if (ppTmpBuckets != NULL) {
1470 for (i=0; i < numTmpBuckets; i++) {
1471 TmpBucketInfo *ptbi=NULL, *ptbi_next=NULL;
1472
1473 for (ptbi=ppTmpBuckets[i]; ptbi != NULL; ptbi=ptbi_next) {
1474 ptbi_next = ptbi->next;
1475 free(ptbi);
1476 }
1477 }
1478 free(ppTmpBuckets);
1479 }
1480 tmpRedShift = tmpGreenShift = tmpBlueShift = 0;
1481 numTmpBuckets = 0;
1482 ppTmpBuckets = NULL;
1483 }
1484
1485 static
SetTmpShift(mask,pn_shifts)1486 int SetTmpShift(mask, pn_shifts)
1487 unsigned long mask;
1488 int *pn_shifts;
1489 {
1490 int i=0;
1491
1492 if (mask == 0L) return FALSE;
1493
1494 while ((mask & 0x1) == 0) {
1495 i++;
1496 mask >>= 1;
1497 }
1498 *pn_shifts = i;
1499
1500 return TRUE;
1501 }
1502
1503 static
BadMask(cWhich,mask)1504 int BadMask(cWhich, mask)
1505 char cWhich;
1506 unsigned long mask;
1507 {
1508 switch (cWhich) {
1509 case 'r':
1510 sprintf(gszMsgBox, TgLoadString(STID_BAD_RED_MASK_TRUE_COLOR_DPY),
1511 (long)mask, TOOL_NAME, "UseImagePixelsForTrueColorExport");
1512 break;
1513 case 'g':
1514 sprintf(gszMsgBox, TgLoadString(STID_BAD_GREEN_MASK_TRUE_COLOR_DPY),
1515 (long)mask, TOOL_NAME, "UseImagePixelsForTrueColorExport");
1516 break;
1517 case 'b':
1518 sprintf(gszMsgBox, TgLoadString(STID_BAD_BLUE_MASK_TRUE_COLOR_DPY),
1519 (long)mask, TOOL_NAME, "UseImagePixelsForTrueColorExport");
1520 break;
1521 }
1522 if (PRTGIF) {
1523 fprintf(stderr, "%s\n", gszMsgBox);
1524 } else {
1525 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
1526 }
1527 CleanUpTmpBuckets();
1528
1529 return FALSE;
1530 }
1531
1532 static
InitTmpBuckets()1533 int InitTmpBuckets()
1534 {
1535 numTmpBuckets = 257;
1536 ppTmpBuckets = (TmpBucketInfo**)malloc(numTmpBuckets*sizeof(TmpBucketInfo*));
1537 if (ppTmpBuckets == NULL) FailAllocMessage();
1538 memset(ppTmpBuckets, 0, numTmpBuckets*sizeof(TmpBucketInfo*));
1539
1540 if (mainVisual->class != TrueColor) {
1541 return TRUE;
1542 }
1543 if (!SetTmpShift(mainVisual->red_mask, &tmpRedShift)) {
1544 return BadMask('r', mainVisual->red_mask);
1545 }
1546 if (!SetTmpShift(mainVisual->green_mask, &tmpGreenShift)) {
1547 return BadMask('g', mainVisual->green_mask);
1548 }
1549 if (!SetTmpShift(mainVisual->blue_mask, &tmpBlueShift)) {
1550 return BadMask('b', mainVisual->blue_mask);
1551 }
1552 return TRUE;
1553 }
1554
1555 static
TmpPixelHash(pixel)1556 int TmpPixelHash(pixel)
1557 int pixel;
1558 {
1559 return (((pixel)==(-1)) ? (numTmpBuckets-1) : (pixel % numTmpBuckets));
1560 }
1561
1562 static
GetTmpValue(pixel,mask,shift,pn_value)1563 void GetTmpValue(pixel, mask, shift, pn_value)
1564 int pixel, shift, *pn_value;
1565 unsigned long mask;
1566 {
1567 double d_val=(double)0;
1568 int value=0;
1569
1570 pixel = (int)(pixel & mask);
1571 pixel >>= shift;
1572 mask >>= shift;
1573 d_val = ((double)pixel) / ((double)mask) * ((double)0x0ff);
1574 value = round(d_val);
1575 if (value > 0x0ff) value = 0x0ff;
1576 if (value < 0) value = 0;
1577 *pn_value = value;
1578 }
1579
1580 static
GetTmpColorStr(pixel,color_str)1581 void GetTmpColorStr(pixel, color_str)
1582 int pixel;
1583 char *color_str;
1584 {
1585 int red_value=0, green_value=0, blue_value=0;
1586
1587 if (mainVisual->class == TrueColor) {
1588 GetTmpValue(pixel, mainVisual->red_mask, tmpRedShift, &red_value);
1589 GetTmpValue(pixel, mainVisual->green_mask, tmpGreenShift, &green_value);
1590 GetTmpValue(pixel, mainVisual->blue_mask, tmpBlueShift, &blue_value);
1591 sprintf(color_str, "#%c%c%c%c%c%c",
1592 hexValue[(red_value>>4)&0x0f], hexValue[red_value&0x0f],
1593 hexValue[(green_value>>4)&0x0f], hexValue[green_value&0x0f],
1594 hexValue[(blue_value>>4)&0x0f], hexValue[blue_value&0x0f]);
1595 } else {
1596 XColor xcolor;
1597
1598 memset(&xcolor, 0, sizeof(XColor));
1599 xcolor.pixel = pixel;
1600 XQueryColor(mainDisplay, mainColormap, &xcolor);
1601 red_value = xcolor.red;
1602 green_value = xcolor.green;
1603 blue_value = xcolor.blue;
1604 sprintf(color_str, "#%c%c%c%c%c%c",
1605 hexValue[(red_value>>12)&0x0f], hexValue[(red_value>>8)&0x0f],
1606 hexValue[(green_value>>12)&0x0f], hexValue[(green_value>>8)&0x0f],
1607 hexValue[(blue_value>>12)&0x0f], hexValue[(blue_value>>8)&0x0f]);
1608 }
1609 }
1610
1611 static
UpdateColorsLookupTableForPixel(pixel,can_alloc)1612 void UpdateColorsLookupTableForPixel(pixel, can_alloc)
1613 int pixel, can_alloc;
1614 {
1615 char color_str[COLORSTRLEN];
1616 int bucket=TmpPixelHash(pixel);
1617 TmpBucketInfo *ptbi=NULL;
1618
1619 for (ptbi=ppTmpBuckets[bucket]; ptbi != NULL; ptbi=ptbi->next) {
1620 if (ptbi->pixel == pixel) {
1621 return;
1622 }
1623 }
1624 ptbi = (TmpBucketInfo*)malloc(sizeof(TmpBucketInfo));
1625 if (ptbi == NULL) FailAllocMessage();
1626 memset(ptbi, 0, sizeof(TmpBucketInfo));
1627 ptbi->next = ppTmpBuckets[bucket];
1628 ppTmpBuckets[bucket] = ptbi;
1629 ptbi->pixel = pixel;
1630
1631 if (can_alloc && numColorsToDump >= maxColors) {
1632 maxColors++;
1633 ExpandTmpStorage();
1634 }
1635 UtilFree(colorStr[numColorsToDump]);
1636 pixelValue[numColorsToDump] = pixel;
1637 *color_str = '\0';
1638 GetTmpColorStr(pixel, color_str);
1639 colorStr[numColorsToDump] = UtilStrDup(color_str);
1640 numColorsToDump++;
1641 }
1642
1643 static
BuildXPmColors(image,w,h,left,top,right,bottom,use_pixels)1644 void BuildXPmColors(image, w, h, left, top, right, bottom, use_pixels)
1645 XImage *image;
1646 int w, h, left, top, right, bottom, use_pixels;
1647 {
1648 int i;
1649
1650 FreeCachedStrings();
1651 if (colorChar == NULL) {
1652 pixelValue = (int*)malloc((maxColors+3)*sizeof(int));
1653 if (pixelValue == NULL) FailAllocMessage();
1654 colorIndexToDumpIndex = (int*)malloc((maxColors+3)*sizeof(int));
1655 dumpIndexToColorIndex = (int*)malloc((maxColors+3)*sizeof(int));
1656 if (colorIndexToDumpIndex == NULL || dumpIndexToColorIndex == NULL) {
1657 FailAllocMessage();
1658 }
1659 if (maxColors > 20) {
1660 charsPerPixel = 2;
1661 colorChar = (char*)malloc(((maxColors<<1)+6)*sizeof(char));
1662 } else {
1663 charsPerPixel = 1;
1664 colorChar = (char*)malloc((maxColors+3)*sizeof(char));
1665 }
1666 if (colorChar == NULL) FailAllocMessage();
1667 colorStr = (char**)malloc((maxColors+3)*sizeof(char*));
1668 if (colorStr == NULL) FailAllocMessage();
1669 memset(colorStr, 0, (maxColors+3)*sizeof(char*));
1670 }
1671 for (i = 0; i < maxColors+3; i++) {
1672 colorIndexToDumpIndex[i] = dumpIndexToColorIndex[i] = INVALID;
1673 }
1674 pixelValue[0] = GetDrawingBgPixel(INVALID, INVALID);
1675 if (myFileBgColorStr == NULL) {
1676 colorStr[0] = (char*)malloc((strlen(myBgColorStr)+1)*sizeof(char));
1677 if (colorStr[0] == NULL) FailAllocMessage();
1678 strcpy(colorStr[0], myBgColorStr);
1679 } else {
1680 colorStr[0] = (char*)malloc((strlen(myFileBgColorStr)+1)*sizeof(char));
1681 if (colorStr[0] == NULL) FailAllocMessage();
1682 strcpy(colorStr[0], myFileBgColorStr);
1683 }
1684 numColorsToDump = 1;
1685
1686 if ((use_pixels || (mainVisual->class == TrueColor &&
1687 useImagePixelsForTrueColorExport)) && !InitTmpBuckets()) {
1688 if (!use_pixels) {
1689 useImagePixelsForTrueColorExport = FALSE;
1690 } else {
1691 use_pixels = FALSE;
1692 }
1693 }
1694 if ((use_pixels || (mainVisual->class == TrueColor &&
1695 useImagePixelsForTrueColorExport))) {
1696 SetStringStatus(TgLoadCachedString(CSTID_BLD_COLOR_TBL_FROM_PIXEL_DOTS));
1697 for (i=top; i < h-bottom; i++) {
1698 int j=0;
1699
1700 for (j=left; j < w-right; j++) {
1701 int pixel=XGetPixel(image,j-left,i-top);
1702
1703 UpdateColorsLookupTableForPixel(pixel, FALSE);
1704 }
1705 }
1706 CleanUpTmpBuckets();
1707 } else {
1708 struct ObjRec *obj_ptr=NULL;
1709
1710 for (obj_ptr=botObj; obj_ptr != NULL; obj_ptr=obj_ptr->prev) {
1711 BuildObjXPmColors(obj_ptr);
1712 }
1713 }
1714 colorChar[0] = '`';
1715 if (charsPerPixel > 1) colorChar[1] = '`';
1716 if (numColorsToDump >= 256) {
1717 for (i=1; i < numColorsToDump; i++) {
1718 if (charsPerPixel == 1) {
1719 colorChar[i] = (char)(((int)('a'))+i-1);
1720 } else {
1721 int left=(int)(i/80), right=(i%80);
1722
1723 if (left >= 31) {
1724 colorChar[i*2] = (char)(((int)('/'))+left-31);
1725 } else {
1726 colorChar[i*2] = (char)(((int)('`'))+left);
1727 }
1728 if (right >= 31) {
1729 colorChar[i*2+1] = (char)(((int)('/'))+right-31);
1730 } else {
1731 colorChar[i*2+1] = (char)(((int)('`'))+right);
1732 }
1733 }
1734 }
1735 } else {
1736 for (i=1; i < numColorsToDump; i++) {
1737 if (charsPerPixel == 1) {
1738 colorChar[i] = (char)(((int)('a'))+i-1);
1739 } else {
1740 colorChar[i*2] = (char)(((int)('a'))+(int)(i/10));
1741 colorChar[i*2+1] = (char)(((int)('0'))+(i%10));
1742 }
1743 }
1744 }
1745 }
1746
1747 static
ColorStrToXPmStr(index,color_str)1748 void ColorStrToXPmStr(index, color_str)
1749 int index;
1750 char *color_str;
1751 {
1752 char s[3];
1753 int i, value;
1754
1755 if (*(colorStr[index]) == '#') {
1756 strcpy(color_str, colorStr[index]);
1757 } else {
1758 for (i = 0; i < maxColors; i++) {
1759 if (colorPixels[i] == pixelValue[index]) {
1760 break;
1761 }
1762 }
1763 if (i == maxColors) {
1764 strcpy(color_str, colorStr[index]);
1765 } else {
1766 strcpy(color_str, "#");
1767 value = (int)(((float)tgifColors[i].red/maxRGB) * 0x100);
1768 if (value > 255) {
1769 value = 255;
1770 } else if (value < 255) {
1771 value = 0;
1772 }
1773 sprintf(s, "%c%c", hexValue[(value>>4)&0x0f], hexValue[value&0x0f]);
1774 strcat(color_str, s);
1775 strcat(color_str, s);
1776
1777 value = (int)(((float)tgifColors[i].green/maxRGB) * 0x100);
1778 if (value > 255) {
1779 value = 255;
1780 } else if (value < 255) {
1781 value = 0;
1782 }
1783 sprintf(s, "%c%c", hexValue[(value>>4)&0x0f], hexValue[value&0x0f]);
1784 strcat(color_str, s);
1785 strcat(color_str, s);
1786
1787 value = (int)(((float)tgifColors[i].blue/maxRGB) * 0x100);
1788 if (value > 255) {
1789 value = 255;
1790 } else if (value < 255) {
1791 value = 0;
1792 }
1793 sprintf(s, "%c%c", hexValue[(value>>4)&0x0f], hexValue[value&0x0f]);
1794 strcat(color_str, s);
1795 strcat(color_str, s);
1796 }
1797 }
1798 }
1799
1800 static
DumpXPmColors(FP)1801 void DumpXPmColors(FP)
1802 FILE *FP;
1803 {
1804 int i, j;
1805 char s[MAXSTRING];
1806
1807 if (xpmOutputVersion == 1) {
1808 if (xpmInXGrabSCFormat) {
1809 for (i=0; i < numColorsToDump-1; i++) {
1810 if (fprintf(FP, "\"") == EOF) writeFileFailed = TRUE;
1811 for (j = 0; j < charsPerPixel; j++) {
1812 if (fprintf(FP, "%c", colorChar[i*charsPerPixel+j]) == EOF) {
1813 writeFileFailed = TRUE;
1814 }
1815 }
1816 ColorStrToXPmStr(i, s);
1817 if (fprintf(FP, "\", \"%s\"\n", s) == EOF) writeFileFailed = TRUE;
1818 }
1819 if (fprintf(FP, "\"") == EOF) writeFileFailed = TRUE;
1820 for (j = 0; j < charsPerPixel; j++) {
1821 if (fprintf(FP, "%c", colorChar[i*charsPerPixel+j]) == EOF) {
1822 writeFileFailed = TRUE;
1823 }
1824 }
1825 ColorStrToXPmStr(i, s);
1826 if (fprintf(FP, "\", \"%s\"\n} ;\n", s) == EOF) {
1827 writeFileFailed = TRUE;
1828 }
1829 } else {
1830 for (i=0; i < numColorsToDump-1; i++) {
1831 if (fprintf(FP, " \"") == EOF) writeFileFailed = TRUE;
1832 for (j = 0; j < charsPerPixel; j++) {
1833 if (fprintf(FP, "%c", colorChar[i*charsPerPixel+j]) == EOF) {
1834 writeFileFailed = TRUE;
1835 }
1836 }
1837 if (fprintf(FP, "\", \"%s\",\n", colorStr[i]) == EOF) {
1838 writeFileFailed = TRUE;
1839 }
1840 }
1841 if (fprintf(FP, " \"") == EOF) writeFileFailed = TRUE;
1842 for (j = 0; j < charsPerPixel; j++) {
1843 if (fprintf(FP, "%c", colorChar[i*charsPerPixel+j]) == EOF) {
1844 writeFileFailed = TRUE;
1845 }
1846 }
1847 if (fprintf(FP, "\", \"%s\"\n};\n", colorStr[i]) == EOF) {
1848 writeFileFailed = TRUE;
1849 }
1850 }
1851 } else {
1852 /* xpmOutputVersion is 3 */
1853 for (i=0; i < numColorsToDump; i++) {
1854 if (fprintf(FP, "\"") == EOF) writeFileFailed = TRUE;
1855 for (j = 0; j < charsPerPixel; j++) {
1856 if (fprintf(FP, "%c", colorChar[i*charsPerPixel+j]) == EOF) {
1857 writeFileFailed = TRUE;
1858 }
1859 }
1860 if (fprintf(FP, " c %s\",\n", colorStr[i]) == EOF) {
1861 writeFileFailed = TRUE;
1862 }
1863 }
1864 }
1865 }
1866
1867 static
SetupTrueColorInfoFromImage(image,ptci)1868 int SetupTrueColorInfoFromImage(image, ptci)
1869 XImage *image;
1870 TrueColorInfo *ptci;
1871 {
1872 unsigned int r_mask=0, g_mask=0, b_mask=0;
1873 unsigned int r_maxval=0, g_maxval=0, b_maxval=0;
1874 unsigned int r_bits=0, g_bits=0, b_bits=0;
1875 int r_shift=(-1), g_shift=(-1), b_shift=(-1);
1876 unsigned int shifts=0;
1877
1878 ptci->r_mask = r_mask = image->red_mask;
1879 ptci->g_mask = g_mask = image->green_mask;
1880 ptci->b_mask = b_mask = image->blue_mask;
1881 if (r_mask == 0 && g_mask == 0 && b_mask == 0) {
1882 if (PRTGIF && !cmdLineOpenDisplay) {
1883 FatalUnexpectedError(
1884 /* debug, do not translate */
1885 "Unimplemented in SetupTrueColorInfoFromImage().", NULL);
1886 return FALSE;
1887 }
1888 return SetupTrueColorInfo(ptci);
1889 }
1890 for (shifts=0; r_mask|g_mask|b_mask; shifts++) {
1891 if (r_mask & 0x1) {
1892 if (r_shift == (-1)) {
1893 r_shift = shifts;
1894 r_maxval = r_mask;
1895 }
1896 r_bits++;
1897 }
1898 if (g_mask & 0x1) {
1899 if (g_shift == (-1)) {
1900 g_shift = shifts;
1901 g_maxval = g_mask;
1902 }
1903 g_bits++;
1904 }
1905 if (b_mask & 0x1) {
1906 if (b_shift == (-1)) {
1907 b_shift = shifts;
1908 b_maxval = b_mask;
1909 }
1910 b_bits++;
1911 }
1912 r_mask >>= 1;
1913 g_mask >>= 1;
1914 b_mask >>= 1;
1915 }
1916 ptci->r_shift = (unsigned int)r_shift;
1917 ptci->g_shift = (unsigned int)g_shift;
1918 ptci->b_shift = (unsigned int)b_shift;
1919 ptci->dr_maxval = (double)r_maxval;
1920 ptci->dg_maxval = (double)g_maxval;
1921 ptci->db_maxval = (double)b_maxval;
1922 ptci->dr_maxval_div255 = ptci->dr_maxval / ((double)255);
1923 ptci->dg_maxval_div255 = ptci->dg_maxval / ((double)255);
1924 ptci->db_maxval_div255 = ptci->db_maxval / ((double)255);
1925 ptci->num_r_bits = r_bits;
1926 ptci->num_g_bits = g_bits;
1927 ptci->num_b_bits = b_bits;
1928
1929 if (r_shift==(-1) || g_shift==(-1) || b_shift==(-1)) {
1930 return FALSE;
1931 }
1932 return TRUE;
1933 }
1934
InitTrueColorInfo(image,ptci,image_w)1935 int InitTrueColorInfo(image, ptci, image_w)
1936 XImage *image;
1937 TrueColorInfo *ptci;
1938 int image_w;
1939 {
1940 unsigned int bytes_per_pixel=image->bits_per_pixel/8;
1941
1942 memset(ptci, 0, sizeof(TrueColorInfo));
1943 if (bytes_per_pixel > 4) {
1944 #ifdef _TGIF_DBG /* debug, do not translate */
1945 fprintf(stderr, "bytes_per_pixel (%1d) > 4 in InitTrueColorInfo().\n",
1946 bytes_per_pixel);
1947 #endif /* _TGIF_DBG */
1948 return FALSE;
1949 }
1950 if ((unsigned int)(image->bytes_per_line/image_w) != bytes_per_pixel) {
1951 #ifdef _TGIF_DBG /* debug, do not translate */
1952 fprintf(stderr, "bytes_per_pixel (%1d) != %1d %s.\n",
1953 bytes_per_pixel, (unsigned int)(image->bytes_per_line/image_w),
1954 "in InitTrueColorInfo()");
1955 #endif /* _TGIF_DBG */
1956 return FALSE;
1957 }
1958 return SetupTrueColorInfoFromImage(image, ptci);
1959 }
1960
1961 /*
1962 * static
1963 * void MapPixToEPSI(SrcX, SrcY, SrcW, SrcH, DestW, DestH, DestX, DestY)
1964 * int SrcX, SrcY, SrcW, SrcH, DestW, DestH, * DestX, * DestY;
1965 * {
1966 * if (pageStyle == LANDSCAPE)
1967 * {
1968 * *DestY = (int)round(((float)DestH) -
1969 * ((((float)DestH)*((float)SrcX))/((float)SrcW)));
1970 * *DestX = (int)round((((float)DestW)*((float)SrcY))/((float)SrcH));
1971 * }
1972 * else
1973 * {
1974 * *DestX = (int)round((((float)DestW)*((float)SrcX))/((float)SrcW));
1975 * *DestY = (int)round((((float)DestH)*((float)SrcY))/((float)SrcH));
1976 * }
1977 * if (*DestX >= DestW) *DestX = DestW-1; if (*DestX < 0) *DestX = 0;
1978 * if (*DestY >= DestH) *DestY = DestH-1; if (*DestY < 0) *DestY = 0;
1979 * }
1980 */
1981
1982 static
MapEPSIToPix(DestX,DestY,DestW,DestH,SrcW,SrcH,SrcX,SrcY)1983 void MapEPSIToPix(DestX, DestY, DestW, DestH, SrcW, SrcH, SrcX, SrcY)
1984 int DestX, DestY, DestW, DestH, SrcW, SrcH, * SrcX, * SrcY;
1985 {
1986 if (pageStyle == LANDSCAPE) {
1987 *SrcX = (int)round(((float)(DestH-DestY))*((float)SrcW)/((float)DestH));
1988 *SrcY = (int)round((((float)SrcH)*((float)DestX))/((float)DestW));
1989 } else {
1990 *SrcX = (int)round((((float)SrcW)*((float)DestX))/((float)DestW));
1991 *SrcY = (int)round((((float)SrcH)*((float)DestY))/((float)DestH));
1992 }
1993 if (*SrcX >= SrcW) *SrcX = SrcW-1; if (*SrcX < 0) *SrcX = 0;
1994 if (*SrcY >= SrcH) *SrcY = SrcH-1; if (*SrcY < 0) *SrcY = 0;
1995 }
1996
GenPreviewBitmap(FP,llxPage,llyPage,urxPage,uryPage)1997 void GenPreviewBitmap(FP, llxPage, llyPage, urxPage, uryPage)
1998 FILE *FP;
1999 int llxPage, llyPage, urxPage, uryPage;
2000 {
2001 int col=0, row=0, ltx=0, lty=0, w=0, h=0, x=0, y=0;
2002 int **data=NULL, num_image_bytes_per_row=0;
2003 int image_w=urxPage-llxPage, image_h=uryPage-llyPage, num_lines=0;
2004 Pixmap pixmap=None;
2005 XImage *image=NULL;
2006 TrueColorInfo tci;
2007
2008 if (image_w == 0 || image_h == 0) return;
2009 if ((pixmap=DrawAllOnPixmap(<x, <y, &w, &h, TRUE)) == None) return;
2010
2011 image = XGetImage(mainDisplay, pixmap, 0, 0, w, h, AllPlanes, ZPixmap);
2012 if (image == NULL) {
2013 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME, INFO_MB);
2014 XFreePixmap(mainDisplay, pixmap);
2015 return;
2016 }
2017 if (fullTrueColorMode) {
2018 if (!InitTrueColorInfo(image, &tci, w)) {
2019 XDestroyImage(image);
2020 XFreePixmap(mainDisplay, pixmap);
2021 return;
2022 }
2023 }
2024 if (image_w < 0) image_w = (-image_w);
2025 if (image_h < 0) image_h = (-image_h);
2026 num_image_bytes_per_row = ((image_w & 0x7) ? (image_w>>3)+1 : (image_w>>3));
2027 num_lines = ((image_w & 0x7) ? (((image_w>>3)+1)<<1) : ((image_w>>3)<<1));
2028 num_lines = ((num_lines & 0x3f) ? (num_lines>>6)+1 : (num_lines>>6));
2029
2030 if ((data=(int**)malloc(image_h*sizeof(int*))) == NULL) {
2031 FailAllocMessage();
2032 return;
2033 }
2034 for (row=0; row < image_h; row++) {
2035 if ((data[row]=(int*)malloc(num_image_bytes_per_row*sizeof(int))) ==
2036 NULL) {
2037 FailAllocMessage();
2038 return;
2039 } else {
2040 for (col=0; col<num_image_bytes_per_row; col++) data[row][col] = 0;
2041 }
2042 }
2043 fprintf(FP, "%%%%BeginPreview: %1d %1d 1 %1d\n", image_w, image_h,
2044 num_lines*image_h);
2045 for (row=0; row < image_h; row++) {
2046 int bg_pixel=GetDrawingBgPixel(INVALID, INVALID);
2047
2048 for (col=0; col < image_w; col++) {
2049 int pixel=XGetPixel(image, x, y);
2050
2051 MapEPSIToPix(col, row, image_w, image_h, w, h, &x, &y);
2052 if (epsiThresholdPreviewBitmap) {
2053 double gray=(double)0;
2054
2055 if (fullTrueColorMode) {
2056 uint32_t pix=(uint32_t)(unsigned int)pixel;
2057 unsigned int r=0, g=0, b=0;
2058 double dr=(double)0, dg=(double)0, db=(double)0;
2059
2060 r = (pix & tci.r_mask) >> tci.r_shift;
2061 g = (pix & tci.g_mask) >> tci.g_shift;
2062 b = (pix & tci.b_mask) >> tci.b_shift;
2063 dr = ((double)r) / tci.dr_maxval;
2064 dg = ((double)g) / tci.dg_maxval;
2065 db = ((double)b) / tci.db_maxval;
2066 gray = (double)(0.299*dr + 0.587*dg + 0.114*db);
2067 } else {
2068 int k=0, found_index=INVALID;
2069
2070 for (k=0; k < maxColors; k++) {
2071 if (colorPixels[k] == pixel) {
2072 found_index = k;
2073 break;
2074 }
2075 }
2076 if (found_index == INVALID) {
2077 if (pixel == bg_pixel) {
2078 gray = (double)1.0;
2079 } else {
2080 sprintf(gszMsgBox,
2081 TgLoadString(STID_UNRECOG_GIVEN_PIXEL_VAL_1_USE),
2082 pixel, (long)pixel);
2083 Msg(gszMsgBox);
2084 gray = (double)0.0;
2085 }
2086 } else {
2087 gray = 0.299*((double)tgifColors[found_index].red/maxRGB) +
2088 0.587*((double)tgifColors[found_index].green/maxRGB) +
2089 0.114*((double)tgifColors[found_index].blue/maxRGB);
2090 }
2091 }
2092 if (gray < epsiPreviewBitmapThreshold) {
2093 data[row][col>>3] |= (1<<(7 - (col & 0x7)));
2094 }
2095 } else {
2096 if (pixel != bg_pixel) {
2097 data[row][col>>3] |= (1<<(7 - (col & 0x7)));
2098 }
2099 }
2100 }
2101 }
2102 for (row=0; row < image_h; row++) {
2103 int byte_count=0;
2104
2105 fprintf(FP, "%% ");
2106 for (col=0; col < num_image_bytes_per_row; col++) {
2107 if (byte_count++ == 32) {
2108 byte_count = 1;
2109 fprintf(FP, "\n%% ");
2110 }
2111 fprintf(FP, "%c", hexValue[(data[row][col]>>4) & 0xf]);
2112 fprintf(FP, "%c", hexValue[data[row][col] & 0xf]);
2113 }
2114 fprintf(FP, "\n");
2115 }
2116 fprintf(FP, "%%%%EndImage\n");
2117 fprintf(FP, "%%%%EndPreview\n");
2118
2119 for (row=0; row < image_h; row++) free(data[row]);
2120 free(data);
2121 XDestroyImage(image);
2122 XFreePixmap(mainDisplay, pixmap);
2123 }
2124
2125 static char defXpmToGif[]="xpmtoppm %s | ppmtogif";
2126 static char defXpmToPng[]="xpmtoppm %s | pnmtopng";
2127 static char defXpmToJpeg[]="xpmtoppm %s | cjpeg";
2128 static char defPpmToGif[]="ppmquant 222 %s | ppmtogif";
2129 static char defPpmToPng[]="pnmtopng %s";
2130 static char defPpmToPngWithTrans[]="pnmtopng -transparent %s %s";
2131 static char defPpmToJpeg[]="cjpeg %s";
2132 static char defPpm6ToXpm3[]="ppmtoxpm %s";
2133 static char defXpmDeckToGifAnim[]="gifsicle -lforever --delay 10";
2134
2135 static
InitImageMap()2136 void InitImageMap()
2137 {
2138 char *c_ptr;
2139
2140 if (generateImageMap != INVALID) return;
2141
2142 generateImageMap = FALSE;
2143 if (!PRTGIF || cmdLineOpenDisplay) {
2144 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"GenerateImageMap")) !=
2145 NULL && UtilStrICmp(c_ptr, "true") == 0) {
2146 generateImageMap = TRUE;
2147 }
2148 }
2149 strcpy(xpmToGifCmd, defXpmToGif);
2150 if (!PRTGIF || cmdLineOpenDisplay) {
2151 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"XpmToGif")) != NULL) {
2152 int count=0;
2153
2154 strcpy(xpmToGifCmd, c_ptr);
2155 UtilTrimBlanks(xpmToGifCmd);
2156 for (c_ptr=strstr(xpmToGifCmd,"%s"); c_ptr!=NULL;
2157 c_ptr=strstr(++c_ptr,"%s")) {
2158 count++;
2159 }
2160 if (count != 1) {
2161 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
2162 TOOL_NAME, "XpmToGif", xpmToGifCmd, defXpmToGif);
2163 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2164 strcpy(xpmToGifCmd, defXpmToGif);
2165 }
2166 }
2167 }
2168 strcpy(ppmToGifCmd, defPpmToGif);
2169 if (!PRTGIF || cmdLineOpenDisplay) {
2170 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"PpmToGif")) != NULL) {
2171 int count=0;
2172
2173 strcpy(ppmToGifCmd, c_ptr);
2174 UtilTrimBlanks(ppmToGifCmd);
2175 for (c_ptr=strstr(ppmToGifCmd,"%s"); c_ptr!=NULL;
2176 c_ptr=strstr(++c_ptr,"%s")) {
2177 count++;
2178 }
2179 if (count != 1) {
2180 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
2181 TOOL_NAME, "PpmToGif", ppmToGifCmd, defPpmToGif);
2182 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2183 strcpy(ppmToGifCmd, defPpmToGif);
2184 }
2185 }
2186 }
2187 strcpy(gifFileExtension, "gif");
2188 if (!PRTGIF || cmdLineOpenDisplay) {
2189 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"GifFileExtension")) !=
2190 NULL) {
2191 strcpy(gifFileExtension, c_ptr);
2192 }
2193 }
2194 strcpy(xpmToPngCmd, defXpmToPng);
2195 if (!PRTGIF || cmdLineOpenDisplay) {
2196 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"XpmToPng")) != NULL) {
2197 int count=0;
2198
2199 strcpy(xpmToPngCmd, c_ptr);
2200 UtilTrimBlanks(xpmToPngCmd);
2201 for (c_ptr=strstr(xpmToPngCmd,"%s"); c_ptr!=NULL;
2202 c_ptr=strstr(++c_ptr,"%s")) {
2203 count++;
2204 }
2205 if (count != 1) {
2206 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
2207 TOOL_NAME, "XpmToPng", xpmToPngCmd, defXpmToPng);
2208 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2209 strcpy(xpmToPngCmd, defXpmToPng);
2210 }
2211 }
2212 }
2213 strcpy(ppmToPngCmd, defPpmToPng);
2214 if (!PRTGIF || cmdLineOpenDisplay) {
2215 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"PpmToPng")) != NULL) {
2216 int count=0;
2217
2218 strcpy(ppmToPngCmd, c_ptr);
2219 UtilTrimBlanks(ppmToPngCmd);
2220 for (c_ptr=strstr(ppmToPngCmd,"%s"); c_ptr!=NULL;
2221 c_ptr=strstr(++c_ptr,"%s")) {
2222 count++;
2223 }
2224 if (count != 1) {
2225 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
2226 TOOL_NAME, "PpmToPng", ppmToPngCmd, defPpmToPng);
2227 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2228 strcpy(ppmToPngCmd, defPpmToPng);
2229 }
2230 }
2231 }
2232 strcpy(ppmToPngWithTransCmd, defPpmToPngWithTrans);
2233 if (!PRTGIF || cmdLineOpenDisplay) {
2234 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,
2235 "PpmToPngWithTransparentColor")) != NULL) {
2236 int count=0;
2237
2238 strcpy(ppmToPngWithTransCmd, c_ptr);
2239 UtilTrimBlanks(ppmToPngWithTransCmd);
2240 for (c_ptr=strstr(ppmToPngWithTransCmd,"%s"); c_ptr!=NULL;
2241 c_ptr=strstr(++c_ptr,"%s")) {
2242 count++;
2243 }
2244 if (count != 2) {
2245 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
2246 TOOL_NAME, "PpmToPngWithTransparentColor",
2247 ppmToPngWithTransCmd, defPpmToPngWithTrans);
2248 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2249 strcpy(ppmToPngWithTransCmd, defPpmToPngWithTrans);
2250 }
2251 }
2252 }
2253 strcpy(pngFileExtension, "png");
2254 if (!PRTGIF || cmdLineOpenDisplay) {
2255 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"PngFileExtension")) !=
2256 NULL) {
2257 strcpy(pngFileExtension, c_ptr);
2258 }
2259 }
2260 strcpy(xpmToJpegCmd, defXpmToJpeg);
2261 if (!PRTGIF || cmdLineOpenDisplay) {
2262 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"XpmToJpeg")) != NULL) {
2263 int count=0;
2264
2265 strcpy(xpmToJpegCmd, c_ptr);
2266 UtilTrimBlanks(xpmToJpegCmd);
2267 for (c_ptr=strstr(xpmToJpegCmd,"%s"); c_ptr!=NULL;
2268 c_ptr=strstr(++c_ptr,"%s")) {
2269 count++;
2270 }
2271 if (count != 1) {
2272 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
2273 TOOL_NAME, "XpmToJpeg", xpmToJpegCmd, defXpmToJpeg);
2274 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2275 strcpy(xpmToJpegCmd, defXpmToJpeg);
2276 }
2277 }
2278 }
2279 strcpy(ppmToJpegCmd, defPpmToJpeg);
2280 if (!PRTGIF || cmdLineOpenDisplay) {
2281 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"PpmToJpeg")) != NULL) {
2282 int count=0;
2283
2284 strcpy(ppmToJpegCmd, c_ptr);
2285 UtilTrimBlanks(ppmToJpegCmd);
2286 for (c_ptr=strstr(ppmToJpegCmd,"%s"); c_ptr!=NULL;
2287 c_ptr=strstr(++c_ptr,"%s")) {
2288 count++;
2289 }
2290 if (count != 1) {
2291 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
2292 TOOL_NAME, "PpmToJpeg", ppmToJpegCmd, defPpmToJpeg);
2293 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2294 strcpy(ppmToJpegCmd, defPpmToJpeg);
2295 }
2296 }
2297 }
2298 strcpy(ppm6ToXpm3Cmd, defPpm6ToXpm3);
2299 if (!PRTGIF || cmdLineOpenDisplay) {
2300 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"Ppm6ToXpm3")) != NULL) {
2301 int count=0;
2302
2303 strcpy(ppm6ToXpm3Cmd, c_ptr);
2304 UtilTrimBlanks(ppm6ToXpm3Cmd);
2305 for (c_ptr=strstr(ppm6ToXpm3Cmd,"%s"); c_ptr!=NULL;
2306 c_ptr=strstr(++c_ptr,"%s")) {
2307 count++;
2308 }
2309 if (count != 1) {
2310 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
2311 TOOL_NAME, "PpmToJpeg", ppm6ToXpm3Cmd, defPpm6ToXpm3);
2312 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2313 strcpy(ppm6ToXpm3Cmd, defPpm6ToXpm3);
2314 }
2315 }
2316 }
2317 strcpy(jpegFileExtension, "jpeg");
2318 if (!PRTGIF || cmdLineOpenDisplay) {
2319 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"JpegFileExtension")) !=
2320 NULL) {
2321 strcpy(jpegFileExtension, c_ptr);
2322 }
2323 }
2324 #ifdef _XPM3TOPPM
2325 useXPmVersion1ForImageMap = FALSE;
2326 #else /* ~_XPM3TOPPM */
2327 useXPmVersion1ForImageMap = TRUE;
2328 #endif /* _XPM3TOPPM */
2329 if (!PRTGIF || cmdLineOpenDisplay) {
2330 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,
2331 "UseXPmVersion1ForImageMap")) != NULL) {
2332 if (UtilStrICmp("false",c_ptr) == 0) {
2333 useXPmVersion1ForImageMap = FALSE;
2334 } else if (UtilStrICmp("true",c_ptr) == 0) {
2335 useXPmVersion1ForImageMap = TRUE;
2336 }
2337 }
2338 }
2339 useXPmVersion1ForXPmDeck = TRUE;
2340 if (!PRTGIF || cmdLineOpenDisplay) {
2341 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,
2342 "UseXPmVersion1ForXPmDeck")) != NULL &&
2343 UtilStrICmp("false",c_ptr) == 0) {
2344 useXPmVersion1ForXPmDeck = FALSE;
2345 }
2346 }
2347 strcpy(imageMapFileExtension, "map");
2348 if (!PRTGIF || cmdLineOpenDisplay) {
2349 if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME,
2350 "ImageMapFileExtension")) != NULL) {
2351 strcpy(imageMapFileExtension, c_ptr);
2352 }
2353 }
2354 imageMapFileFormat = IMF_FORMAT_NCSA;
2355 if (!PRTGIF || cmdLineOpenDisplay) {
2356 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"ImageMapFileFormat")) !=
2357 NULL) {
2358 if (strcmp(c_ptr, "NCSA") == 0) {
2359 imageMapFileFormat = IMF_FORMAT_NCSA;
2360 } else if (strcmp(c_ptr, "CERN") == 0) {
2361 imageMapFileFormat = IMF_FORMAT_CERN;
2362 } else {
2363 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
2364 TOOL_NAME, "ImageMapFileFormat", c_ptr, "NCSA");
2365 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2366 }
2367 }
2368 }
2369 strcpy(htmlFileExtension, "html");
2370 if (!PRTGIF || cmdLineOpenDisplay) {
2371 if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME,
2372 "HtmlFileExtension")) != NULL && (*c_ptr != '\0')) {
2373 strcpy(htmlFileExtension, c_ptr);
2374 }
2375 }
2376 generateHtmlHref = TRUE;
2377 if (!PRTGIF || cmdLineOpenDisplay) {
2378 if ((c_ptr=XGetDefault(mainDisplay, TOOL_NAME, "GenerateHtmlHref")) !=
2379 NULL) {
2380 if (UtilStrICmp(c_ptr, "false") == 0) {
2381 generateHtmlHref = FALSE;
2382 }
2383 }
2384 }
2385 strcpy(xpmDeckToGifAnimCmd, defXpmDeckToGifAnim);
2386 if (!PRTGIF || cmdLineOpenDisplay) {
2387 if ((c_ptr=XGetDefault(mainDisplay,TOOL_NAME,"XpmDeckToGifAnim")) !=
2388 NULL) {
2389 strcpy(xpmDeckToGifAnimCmd, c_ptr);
2390 UtilTrimBlanks(xpmDeckToGifAnimCmd);
2391 if (strstr(xpmDeckToGifAnimCmd, "%s") != NULL) {
2392 sprintf(gszMsgBox, TgLoadString(STID_INVALID_XDEF_USE_ALT_STR),
2393 TOOL_NAME, "XpmDeckToGifAnim", xpmDeckToGifAnimCmd,
2394 defXpmDeckToGifAnim);
2395 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2396 strcpy(xpmDeckToGifAnimCmd, defXpmDeckToGifAnim);
2397 }
2398 }
2399 }
2400 }
2401
2402 static
ModifyToGenerateHtmlHref(value_str)2403 char *ModifyToGenerateHtmlHref(value_str)
2404 char *value_str;
2405 /* data in value_str is not supposed to be touched on return */
2406 {
2407 char *href=NULL, *name=NULL, *pound=NULL, *dot=NULL;
2408 int len=0;
2409
2410 if (generateHtmlHref && imageMapFileFormat==IMF_FORMAT_SPYG) {
2411 if (value_str[0] == '#' && strchr(value_str, DIR_SEP) == NULL &&
2412 (((!(PRTGIF && !cmdLineOpenDisplay)) && dumpOneFilePerPage) ||
2413 (PRTGIF && !cmdLineOpenDisplay && cmdLineOneFilePerPage))) {
2414 char page_spec[MAXSTRING];
2415 int page_num=0;
2416
2417 if (GetPageNumFromPageSpec(&value_str[1], &page_num)) {
2418 sprintf(page_spec, "%1d", page_num);
2419
2420 if ((name=UtilStrRChr(curFileName, DIR_SEP)) == NULL) {
2421 name = curFileName;
2422 } else {
2423 name++;
2424 }
2425 pound = strchr(name, '#');
2426 if (pound != NULL) *pound = '\0';
2427 dot = UtilStrRChr(name, '.');
2428 if (dot != NULL) {
2429 *dot = '\0';
2430 len = strlen(name)+strlen(page_spec)+strlen(htmlFileExtension)+3;
2431 href = (char*)malloc((len+1)*sizeof(char));
2432 if (href == NULL) FailAllocMessage();
2433 sprintf(href, "%s-%1d.%s", name, page_num, htmlFileExtension);
2434 *dot = '.';
2435 }
2436 if (pound != NULL) *pound = '#';
2437 } else {
2438 /* Cannot get page number information, may be it's okay! */
2439 }
2440 } else {
2441 if ((name=UtilStrRChr(value_str, DIR_SEP)) == NULL) {
2442 name = value_str;
2443 } else {
2444 name++;
2445 }
2446 pound = strchr(name, '#');
2447 if (pound != NULL) *pound = '\0';
2448 dot = UtilStrRChr(name, '.');
2449 if (dot != NULL && ((UtilStrICmp(&dot[1], "obj")==0 ||
2450 UtilStrICmp(&dot[1], OBJ_FILE_EXT)==0) ||
2451 UtilStrICmp(&dot[1], "sym")==0 ||
2452 UtilStrICmp(&dot[1], SYM_FILE_EXT)==0)) {
2453 *dot = '\0';
2454 len = strlen(value_str)+strlen(htmlFileExtension)+2;
2455 if (pound != NULL) len += strlen(£[1])+1;
2456 href = (char*)malloc((len+1)*sizeof(char));
2457 if (href == NULL) FailAllocMessage();
2458 if (pound != NULL) {
2459 sprintf(href, "%s.%s#%s", value_str, htmlFileExtension,
2460 £[1]);
2461 } else {
2462 sprintf(href, "%s.%s", value_str, htmlFileExtension);
2463 }
2464 *dot = '.';
2465 }
2466 if (pound != NULL) *pound = '#';
2467 }
2468 }
2469 return href;
2470 }
2471
2472 static
GenerateObjImageMap(FP,ObjPtr,LtX,LtY)2473 int GenerateObjImageMap(FP, ObjPtr, LtX, LtY)
2474 FILE *FP;
2475 struct ObjRec *ObjPtr;
2476 int LtX, LtY;
2477 {
2478 register int i;
2479 int n, something_generated=FALSE;
2480 struct AttrRec *attr_ptr;
2481 struct ObjRec *obj_ptr;
2482 IntPoint *v=NULL;
2483
2484 if ((attr_ptr=FindAttrWithName(ObjPtr, "href=", NULL)) != NULL) {
2485 char *href=ModifyToGenerateHtmlHref(attr_ptr->attr_value.s);
2486
2487 switch (ObjPtr->type) {
2488 case OBJ_POLY:
2489 case OBJ_POLYGON:
2490 if (ObjPtr->type == OBJ_POLY) {
2491 n = ObjPtr->detail.p->n;
2492 v = ObjPtr->detail.p->vlist;
2493 } else {
2494 n = ObjPtr->detail.g->n;
2495 v = ObjPtr->detail.g->vlist;
2496 }
2497 switch (imageMapFileFormat) {
2498 case IMF_FORMAT_NCSA:
2499 fprintf(FP, "\npoly %s", attr_ptr->attr_value.s);
2500 for (i=0; i < n; i++) {
2501 fprintf(FP, " %1d,%1d", v[i].x-LtX, v[i].y-LtY);
2502 }
2503 fprintf(FP, "\n");
2504 break;
2505 case IMF_FORMAT_CERN:
2506 fprintf(FP, "\npoly");
2507 for (i=0; i < n; i++) {
2508 fprintf(FP, " (%1d,%1d)", v[i].x-LtX, v[i].y-LtY);
2509 }
2510 fprintf(FP, " %s\n", attr_ptr->attr_value.s);
2511 break;
2512 case IMF_FORMAT_SPYG:
2513 fprintf(FP, "<AREA SHAPE=\"POLY\" COORDS=\"");
2514 for (i=0; i < n; i++) {
2515 fprintf(FP, "%s%1d,%1d", (i==0 ? "" : ","),
2516 v[i].x-LtX, v[i].y-LtY);
2517 }
2518 fprintf(FP, "\" HREF=\"%s\">\n",
2519 (href != NULL ? href : attr_ptr->attr_value.s));
2520 break;
2521 default: break;
2522 }
2523 break;
2524 case OBJ_OVAL:
2525 if (ObjPtr->obbox.rbx-ObjPtr->obbox.ltx ==
2526 ObjPtr->obbox.rby-ObjPtr->obbox.lty) {
2527 switch (imageMapFileFormat) {
2528 case IMF_FORMAT_NCSA:
2529 fprintf(FP, "\ncircle %s %1d,%1d %1d,%1d\n",
2530 attr_ptr->attr_value.s,
2531 ((ObjPtr->obbox.ltx+ObjPtr->obbox.rbx)>>1)-LtX,
2532 ((ObjPtr->obbox.lty+ObjPtr->obbox.rby)>>1)-LtY,
2533 ObjPtr->obbox.rbx-LtX,
2534 ((ObjPtr->obbox.lty+ObjPtr->obbox.rby)>>1)-LtY);
2535 break;
2536 case IMF_FORMAT_CERN:
2537 fprintf(FP, "\ncircle (%1d,%1d) %1d %s\n",
2538 ((ObjPtr->obbox.ltx+ObjPtr->obbox.rbx)>>1)-LtX,
2539 ((ObjPtr->obbox.lty+ObjPtr->obbox.rby)>>1)-LtY,
2540 (ObjPtr->obbox.rbx-ObjPtr->obbox.ltx)>>1,
2541 attr_ptr->attr_value.s);
2542 break;
2543 case IMF_FORMAT_SPYG:
2544 fprintf(FP, "<AREA SHAPE=\"CIRCLE\" COORDS=\"");
2545 fprintf(FP, "%1d,%1d,%1d",
2546 ((ObjPtr->obbox.ltx+ObjPtr->obbox.rbx)>>1)-LtX,
2547 ((ObjPtr->obbox.lty+ObjPtr->obbox.rby)>>1)-LtY,
2548 (ObjPtr->obbox.rbx-ObjPtr->obbox.ltx)>>1);
2549 fprintf(FP, "\" HREF=\"%s\">\n",
2550 (href != NULL ? href : attr_ptr->attr_value.s));
2551 break;
2552 default: break;
2553 }
2554 } else {
2555 switch (imageMapFileFormat) {
2556 case IMF_FORMAT_NCSA:
2557 fprintf(FP, "\nrect %s %1d,%1d %1d,%1d\n",
2558 attr_ptr->attr_value.s,
2559 ObjPtr->obbox.ltx-LtX, ObjPtr->obbox.lty-LtY,
2560 ObjPtr->obbox.rbx-LtX, ObjPtr->obbox.rby-LtY);
2561 break;
2562 case IMF_FORMAT_CERN:
2563 fprintf(FP, "\nrect (%1d,%1d) (%1d,%1d) %s\n",
2564 ObjPtr->obbox.ltx-LtX, ObjPtr->obbox.lty-LtY,
2565 ObjPtr->obbox.rbx-LtX, ObjPtr->obbox.rby-LtY,
2566 attr_ptr->attr_value.s);
2567 break;
2568 case IMF_FORMAT_SPYG:
2569 fprintf(FP, "<AREA SHAPE=\"RECT\" COORDS=\"");
2570 fprintf(FP, "%1d,%1d,%1d,%1d",
2571 ObjPtr->obbox.ltx-LtX, ObjPtr->obbox.lty-LtY,
2572 ObjPtr->obbox.rbx-LtX, ObjPtr->obbox.rby-LtY);
2573 fprintf(FP, "\" HREF=\"%s\">\n",
2574 (href != NULL ? href : attr_ptr->attr_value.s));
2575 break;
2576 default: break;
2577 }
2578 }
2579 break;
2580 default:
2581 switch (imageMapFileFormat) {
2582 case IMF_FORMAT_NCSA:
2583 fprintf(FP, "\nrect %s %1d,%1d %1d,%1d\n",
2584 attr_ptr->attr_value.s,
2585 ObjPtr->obbox.ltx-LtX, ObjPtr->obbox.lty-LtY,
2586 ObjPtr->obbox.rbx-LtX, ObjPtr->obbox.rby-LtY);
2587 break;
2588 case IMF_FORMAT_CERN:
2589 fprintf(FP, "\nrect (%1d,%1d) (%1d,%1d) %s\n",
2590 ObjPtr->obbox.ltx-LtX, ObjPtr->obbox.lty-LtY,
2591 ObjPtr->obbox.rbx-LtX, ObjPtr->obbox.rby-LtY,
2592 attr_ptr->attr_value.s);
2593 break;
2594 case IMF_FORMAT_SPYG:
2595 fprintf(FP, "<AREA SHAPE=\"RECT\" COORDS=\"");
2596 fprintf(FP, "%1d,%1d,%1d,%1d",
2597 ObjPtr->obbox.ltx-LtX, ObjPtr->obbox.lty-LtY,
2598 ObjPtr->obbox.rbx-LtX, ObjPtr->obbox.rby-LtY);
2599 fprintf(FP, "\" HREF=\"%s\">\n",
2600 (href != NULL ? href : attr_ptr->attr_value.s));
2601 break;
2602 default: break;
2603 }
2604 break;
2605 }
2606 if (href != NULL) free(href);
2607 return TRUE;
2608 }
2609 switch (ObjPtr->type) {
2610 case OBJ_GROUP:
2611 case OBJ_ICON:
2612 case OBJ_SYM:
2613 for (obj_ptr=ObjPtr->detail.r->first; obj_ptr != NULL;
2614 obj_ptr=obj_ptr->next) {
2615 if (GenerateObjImageMap (FP, obj_ptr, LtX, LtY)) {
2616 something_generated = TRUE;;
2617 }
2618 }
2619 break;
2620 case OBJ_PIN:
2621 obj_ptr = GetPinObj(ObjPtr);
2622 if (GenerateObjImageMap(FP, obj_ptr, LtX, LtY)) {
2623 something_generated = TRUE;;
2624 }
2625 break;
2626 }
2627 return something_generated;
2628 }
2629
2630 static
GenerateHtmlHeader(map_fp)2631 void GenerateHtmlHeader(map_fp)
2632 FILE *map_fp;
2633 {
2634 struct AttrRec *attr_ptr;
2635
2636 fprintf(map_fp, "<HTML>\n<HEAD>\n");
2637 if (curPage->name != NULL && *curPage->name != '\0') {
2638 fprintf(map_fp, "<TITLE>\n%s\n</TITLE>\n", curPage->name);
2639 } else if ((attr_ptr=FindFileAttrWithName("title=")) != NULL) {
2640 fprintf(map_fp, "<TITLE>\n%s\n</TITLE>\n",
2641 attr_ptr->attr_value.s);
2642 }
2643 if ((attr_ptr=FindFileAttrWithName("base=")) != NULL) {
2644 fprintf(map_fp, "<BASE HREF=\"%s\">\n", attr_ptr->attr_value.s);
2645 }
2646 if ((attr_ptr=FindFileAttrWithName("made=")) != NULL) {
2647 fprintf(map_fp, "<LINK REV=\"made\" HREF=\"%s\">\n",
2648 attr_ptr->attr_value.s);
2649 }
2650 if ((attr_ptr=FindFileAttrWithName("keywords=")) != NULL) {
2651 fprintf(map_fp, "<META HTTP-EQUIV=\"Keywords\" CONTENT=\"%s\">\n",
2652 attr_ptr->attr_value.s);
2653 }
2654 fprintf(map_fp, "</HEAD>\n<BODY>\n");
2655 }
2656
2657 static
GenerateUseMapHeader(map_fp,gif_fname,map_fname)2658 void GenerateUseMapHeader(map_fp, gif_fname, map_fname)
2659 FILE *map_fp;
2660 char *gif_fname, *map_fname;
2661 {
2662 char *gif_fname_ptr=UtilStrRChr(gif_fname, DIR_SEP);
2663 char *map_fname_ptr=UtilStrRChr(map_fname, DIR_SEP);
2664 int page_num=0;
2665 struct AttrRec *attr_ptr;
2666
2667 if (gif_fname_ptr != NULL) gif_fname_ptr++;
2668 if (map_fname_ptr != NULL) map_fname_ptr++;
2669 fprintf(map_fp, "<H1>\n");
2670 attr_ptr = FindFileAttrWithName("alt=");
2671 if (attr_ptr != NULL) {
2672 fprintf(map_fp, "<IMG ALT=\"%s\" SRC=\"%s\" USEMAP=\"%s#p%1d\">\n",
2673 attr_ptr->attr_value.s,
2674 (gif_fname_ptr==NULL ? "unknown" : gif_fname_ptr),
2675 (map_fname_ptr==NULL ? "unknown" : map_fname_ptr), page_num);
2676 } else {
2677 fprintf(map_fp, "<IMG SRC=\"%s\" USEMAP=\"%s#p%1d\">\n",
2678 (gif_fname_ptr==NULL ? "unknown" : gif_fname_ptr),
2679 (map_fname_ptr==NULL ? "unknown" : map_fname_ptr), page_num);
2680 }
2681 fprintf(map_fp, "</H1>\n");
2682 fprintf(map_fp, "<MAP NAME=\"p%1d\">\n", page_num);
2683 }
2684
2685 static
GenerateUseMapTrailer(map_fp,W,H)2686 void GenerateUseMapTrailer(map_fp, W, H)
2687 FILE *map_fp;
2688 int W, H;
2689 {
2690 struct AttrRec *attr_ptr=FindFileAttrWithName("href=");
2691
2692 if (attr_ptr != NULL) {
2693 char *href=ModifyToGenerateHtmlHref(attr_ptr->attr_value.s);
2694
2695 fprintf(map_fp, "<AREA SHAPE=\"RECT\" COORDS=\"");
2696 fprintf(map_fp, "0,0,%1d,%1d", W, H);
2697 fprintf(map_fp, "\" HREF=\"%s\">\n",
2698 (href != NULL ? href : attr_ptr->attr_value.s));
2699 if (href != NULL) free(href);
2700 }
2701 fprintf(map_fp, "</MAP>\n");
2702 }
2703
2704 static
GenerateHtmlTrailer(map_fp)2705 void GenerateHtmlTrailer(map_fp)
2706 FILE *map_fp;
2707 {
2708 fprintf(map_fp, "</BODY>\n</HTML>\n");
2709 }
2710
2711 static
OpenMapFile(pszMapFile)2712 FILE *OpenMapFile(pszMapFile)
2713 char *pszMapFile;
2714 {
2715 FILE *pFile=fopen(pszMapFile, "w");
2716
2717 if (pFile == NULL) {
2718 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
2719 pszMapFile);
2720 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2721 return NULL;
2722 }
2723 return pFile;
2724 }
2725
2726 static
DumpCommentInBitmapExport(fp)2727 void DumpCommentInBitmapExport(fp)
2728 FILE *fp;
2729 {
2730 if (commentInBitmapExport) {
2731 fprintf(fp, "/*\n");
2732 fprintf(fp, " * @%s%s\n", "(#)$H", "eader$");
2733 fprintf(fp, " */\n");
2734 }
2735 }
2736
2737 static
ColorNameToXPmStr(color_name,s)2738 void ColorNameToXPmStr(color_name, s)
2739 char *color_name, *s;
2740 {
2741 if (*color_name == '#') {
2742 strcpy(s, color_name);
2743 } else {
2744 XColor exact_def;
2745
2746 if (TgifParseColor(color_name, &exact_def)) {
2747 unsigned int r=0, g=0, b=0;
2748 double dr=(double)0, dg=(double)0, db=(double)0;
2749
2750 dr = ((double)exact_def.red) / ((double)maxRGB) * ((double)255);
2751 dg = ((double)exact_def.green) / ((double)maxRGB) * ((double)255);
2752 db = ((double)exact_def.blue) / ((double)maxRGB) * ((double)255);
2753 r = (unsigned int)round(dr);
2754 g = (unsigned int)round(dg);
2755 b = (unsigned int)round(db);
2756 if (r > 255) r = 255;
2757 if (g > 255) g = 255;
2758 if (b > 255) b = 255;
2759 sprintf(s, "#%02x%02x%02x", r, g, b);
2760 } else {
2761 strcpy(s, color_name);
2762 }
2763 }
2764 }
2765
2766 static
Xpm3ToXpm1(gif_fname)2767 int Xpm3ToXpm1(gif_fname)
2768 char *gif_fname;
2769 {
2770 int i=0, j=0, rc=0, ncolors=0, chars_per_pixel=0, line_len=0;
2771 int first_pixel_is_bg=FALSE, image_w=0, image_h=0, w=0, h=0;
2772 char *color_char=NULL, **color_str=NULL, *xpm_data=NULL, *xpm_data_ptr=NULL;
2773 char *psz=NULL, name[MAXPATHLENGTH], s[MAXSTRING];
2774 int watch_cursor=watchCursorOnMainWindow, saved_color_display=colorDisplay;
2775 FILE *fp=NULL;
2776
2777 psz = UtilStrRChr(gif_fname, DIR_SEP);
2778 if (psz == NULL) {
2779 UtilStrCpyN(name, sizeof(name), gif_fname);
2780 } else {
2781 UtilStrCpyN(name, sizeof(name), &psz[1]);
2782 }
2783 psz = UtilStrRChr(name, '.');
2784 if (psz != NULL) {
2785 *psz = '\0';
2786 }
2787 UtilTrimBlanks(name);
2788 if (*name == '\0') {
2789 #ifdef _TGIF_DBG /* debug, do not translate */
2790 fprintf(stderr, "Unexpected empty string in Xpm3ToXpm1().\n");
2791 #endif /* _TGIF_DBG */
2792 return FALSE;
2793 }
2794 if (!watch_cursor) {
2795 SetWatchCursor(drawWindow);
2796 SetWatchCursor(mainWindow);
2797 }
2798 colorDisplay = FALSE;
2799 rc = MyReadPixmapFile(gif_fname,
2800 &image_w, &image_h, &w, &h, NULL, NULL, NULL, NULL,
2801 &ncolors, &chars_per_pixel, &first_pixel_is_bg, &color_char,
2802 &color_str, NULL, &xpm_data);
2803 colorDisplay = saved_color_display;
2804 if (rc != BitmapSuccess) {
2805 if (!watch_cursor) {
2806 SetDefaultCursor(mainWindow);
2807 ShowCursor();
2808 }
2809 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_IMPORT_XPM_FILE), gif_fname);
2810 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2811 return FALSE;
2812 }
2813 if ((fp=fopen(gif_fname, "w")) == NULL) {
2814 if (!watch_cursor) {
2815 SetDefaultCursor(mainWindow);
2816 ShowCursor();
2817 }
2818 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
2819 gif_fname);
2820 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2821 return FALSE;
2822 }
2823 writeFileFailed = FALSE;
2824
2825 /* DumpXpmHeader(fp, w, h, name, 0, 0, 0, 0); */
2826
2827 DumpCommentInBitmapExport(fp);
2828 /* do not translate -- program constants */
2829 fprintf(fp, "#define %s_format 1\n", name);
2830 fprintf(fp, "#define %s_width %1d\n", name, image_w);
2831 fprintf(fp, "#define %s_height %1d\n", name, image_h);
2832 fprintf(fp, "#define %s_ncolors %1d\n", name, ncolors);
2833 fprintf(fp, "#define %s_chars_per_pixel %1d\n", name, chars_per_pixel);
2834 if (xpmInXGrabSCFormat) {
2835 fprintf(fp, "static char * %s_colors[] = {\n", name);
2836 } else {
2837 fprintf(fp, "static char *%s_colors[] = {\n", name);
2838 }
2839 /* DumpXPmColors(fp); */
2840 if (xpmInXGrabSCFormat) {
2841 for (i=0; i < ncolors-1; i++) {
2842 if (fprintf(fp, "\"") == EOF) writeFileFailed = TRUE;
2843 for (j = 0; j < chars_per_pixel; j++) {
2844 if (fprintf(fp, "%c", color_char[i*chars_per_pixel+j]) == EOF) {
2845 writeFileFailed = TRUE;
2846 }
2847 }
2848 ColorNameToXPmStr(color_str[i], s);
2849 if (fprintf(fp, "\", \"%s\"\n", s) == EOF) writeFileFailed = TRUE;
2850 }
2851 if (fprintf(fp, "\"") == EOF) writeFileFailed = TRUE;
2852 for (j = 0; j < chars_per_pixel; j++) {
2853 if (fprintf(fp, "%c", color_char[i*chars_per_pixel+j]) == EOF) {
2854 writeFileFailed = TRUE;
2855 }
2856 }
2857 ColorNameToXPmStr(color_str[i], s);
2858 if (fprintf(fp, "\", \"%s\"\n} ;\n", s) == EOF) {
2859 writeFileFailed = TRUE;
2860 }
2861 } else {
2862 for (i=0; i < ncolors-1; i++) {
2863 if (fprintf(fp, " \"") == EOF) writeFileFailed = TRUE;
2864 for (j = 0; j < chars_per_pixel; j++) {
2865 if (fprintf(fp, "%c", color_char[i*chars_per_pixel+j]) == EOF) {
2866 writeFileFailed = TRUE;
2867 }
2868 }
2869 if (fprintf(fp, "\", \"%s\",\n", color_str[i]) == EOF) {
2870 writeFileFailed = TRUE;
2871 }
2872 }
2873 if (fprintf(fp, " \"") == EOF) writeFileFailed = TRUE;
2874 for (j = 0; j < chars_per_pixel; j++) {
2875 if (fprintf(fp, "%c", color_char[i*chars_per_pixel+j]) == EOF) {
2876 writeFileFailed = TRUE;
2877 }
2878 }
2879 if (fprintf(fp, "\", \"%s\"\n};\n", color_str[i]) == EOF) {
2880 writeFileFailed = TRUE;
2881 }
2882 }
2883
2884 if (xpmInXGrabSCFormat) {
2885 fprintf(fp, "static char * %s_pixels[] = {\n", name);
2886 } else {
2887 fprintf(fp, "static char *%s_pixels[] = {\n", name);
2888 }
2889 line_len = chars_per_pixel * image_w;
2890 xpm_data_ptr = xpm_data;
2891 for (i=0; i < image_h; i++) {
2892 char saved_ch=xpm_data_ptr[line_len];
2893
2894 xpm_data_ptr[line_len] = '\0';
2895 fprintf(fp, "\"%s\"", xpm_data_ptr);
2896 xpm_data_ptr[line_len] = saved_ch;
2897 xpm_data_ptr += line_len;
2898
2899 if (i == image_h-1) {
2900 if (xpmInXGrabSCFormat) {
2901 if (fprintf(fp, ",\n} ;\n") == EOF) writeFileFailed = TRUE;
2902 } else {
2903 if (fprintf(fp, "\n};\n") == EOF) writeFileFailed = TRUE;
2904 }
2905 } else if (fprintf(fp, ",\n") == EOF) {
2906 writeFileFailed = TRUE;
2907 }
2908 }
2909 fclose(fp);
2910
2911 if (!watch_cursor) {
2912 SetDefaultCursor(mainWindow);
2913 ShowCursor();
2914 }
2915 return TRUE;
2916 }
2917
2918 static
ConvertXpmToGif(xpm_fname,gif_fname,src_is_ppm,where_to_print)2919 int ConvertXpmToGif(xpm_fname, gif_fname, src_is_ppm, where_to_print)
2920 char *xpm_fname, *gif_fname;
2921 int src_is_ppm, where_to_print;
2922 {
2923 char cmd[MAXSTRING<<1], netpbm_msg[MAXSTRING<<1], buf[1024];
2924 FILE *gif_fp=fopen(gif_fname,"w"), *pfp=NULL;
2925 int bytes_read=0, watch_cursor=watchCursorOnMainWindow;
2926
2927 if (gif_fp == NULL) {
2928 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
2929 gif_fname);
2930 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
2931 return FALSE;
2932 }
2933 switch (where_to_print) {
2934 case GIF_FILE:
2935 case HTML_FILE:
2936 *netpbm_msg = '\0';
2937 if (src_is_ppm) {
2938 sprintf(cmd, ppmToGifCmd, xpm_fname);
2939 if (strncmp(cmd, "ppm", 3) == 0) {
2940 sprintf(netpbm_msg, TgLoadString(STID_NETPBM_PROGS_VISIT_HOME_PAGE),
2941 TOOL_NAME, homePageURL);
2942 }
2943 } else {
2944 sprintf(cmd, xpmToGifCmd, xpm_fname);
2945 if (strncmp(cmd, "xpmtop", 6) == 0) {
2946 sprintf(netpbm_msg, TgLoadString(STID_NETPBM_PROGS_VISIT_HOME_PAGE),
2947 TOOL_NAME, homePageURL);
2948 }
2949 }
2950 if (!FindProgramInPath(cmd, netpbm_msg, FALSE)) {
2951 fclose(gif_fp);
2952 unlink(gif_fname);
2953 return FALSE;
2954 }
2955 break;
2956 case PNG_FILE:
2957 *netpbm_msg = '\0';
2958 if (src_is_ppm) {
2959 if (pngExportHasTransparentColor) {
2960 sprintf(cmd, ppmToPngWithTransCmd, pngExportTransparentColor,
2961 xpm_fname);
2962 if (strncmp(cmd, "pnmtop", 6) == 0) {
2963 sprintf(netpbm_msg,
2964 TgLoadString(STID_NETPBM_PNMTOPNG_VST_HOME_PAGE),
2965 TOOL_NAME, homePageURL);
2966 }
2967 } else {
2968 sprintf(cmd, ppmToPngCmd, xpm_fname);
2969 if (strncmp(cmd, "pnmtop", 6) == 0) {
2970 sprintf(netpbm_msg,
2971 TgLoadString(STID_NETPBM_PNMTOPNG_VST_HOME_PAGE),
2972 TOOL_NAME, homePageURL);
2973 }
2974 }
2975 } else {
2976 sprintf(cmd, xpmToPngCmd, xpm_fname);
2977 if (strncmp(cmd, "xpmtop", 6) == 0) {
2978 sprintf(netpbm_msg,
2979 TgLoadString(STID_NETPBM_PNMTOPNG_VST_HOME_PAGE), TOOL_NAME,
2980 homePageURL);
2981 }
2982 }
2983 if (!FindProgramInPath(cmd, netpbm_msg, FALSE)) {
2984 fclose(gif_fp);
2985 unlink(gif_fname);
2986 return FALSE;
2987 }
2988 break;
2989 case JPEG_FILE:
2990 *netpbm_msg = '\0';
2991 if (src_is_ppm) {
2992 sprintf(cmd, ppmToJpegCmd, xpm_fname);
2993 if (strncmp(cmd, "cjpeg", 5) == 0) {
2994 sprintf(netpbm_msg, TgLoadString(STID_NETPBM_JPEG_VST_HOME_PAGE),
2995 TOOL_NAME, homePageURL);
2996 }
2997 } else {
2998 sprintf(cmd, xpmToJpegCmd, xpm_fname);
2999 if (strncmp(cmd, "xpmtop", 6) == 0) {
3000 sprintf(netpbm_msg, TgLoadString(STID_NETPBM_JPEG_VST_HOME_PAGE),
3001 TOOL_NAME, homePageURL);
3002 }
3003 }
3004 if (!FindProgramInPath(cmd, netpbm_msg, FALSE)) {
3005 fclose(gif_fp);
3006 unlink(gif_fname);
3007 return FALSE;
3008 }
3009 break;
3010 case XBM_FILE:
3011 sprintf(cmd, ppm6ToXpm3Cmd, xpm_fname);
3012 *netpbm_msg = '\0';
3013 if (strncmp(cmd, "ppmtox", 6) == 0) {
3014 sprintf(netpbm_msg, TgLoadString(STID_NETPBM_JPEG_VST_HOME_PAGE),
3015 TOOL_NAME, homePageURL);
3016 }
3017 if (!FindProgramInPath(cmd, netpbm_msg, FALSE)) {
3018 fclose(gif_fp);
3019 unlink(gif_fname);
3020 return FALSE;
3021 }
3022 break;
3023 }
3024 sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM), cmd);
3025 Msg(gszMsgBox);
3026 SetStringStatus(gszMsgBox);
3027 XSync(mainDisplay, False);
3028 if ((pfp=(FILE*)popen(cmd, "r")) == NULL) {
3029 fclose(gif_fp);
3030 unlink(gif_fname);
3031 sprintf(gszMsgBox, TgLoadString(STID_FAIL_TO_EXECUTE_CMD), cmd);
3032 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3033 return FALSE;
3034 }
3035 if (!watch_cursor) {
3036 SetWatchCursor(drawWindow);
3037 SetWatchCursor(mainWindow);
3038 }
3039 while ((bytes_read=fread(buf, sizeof(char), sizeof(buf), pfp)) > 0) {
3040 if ((int)fwrite(buf, sizeof(char), bytes_read, gif_fp) <= 0) {
3041 writeFileFailed = TRUE;
3042 break;
3043 }
3044 }
3045 pclose(pfp);
3046 if (!watch_cursor) {
3047 SetDefaultCursor(mainWindow);
3048 ShowCursor();
3049 }
3050 SetStringStatus(TgLoadCachedString(CSTID_DOTS_DONE));
3051 fclose(gif_fp);
3052 if (writeFileFailed) {
3053 return FailToWriteFileMessage(gif_fname);
3054 }
3055 if (whereToPrint == XBM_FILE && xpmOutputVersion == 1) {
3056 return Xpm3ToXpm1(gif_fname);
3057 }
3058 return TRUE;
3059 }
3060
3061 #define TGV_FILE_NAME 0
3062 #define TGV_CUR_NUM 1
3063 #define TGV_FIRST_NUM 2
3064 #define TGV_LAST_NUM 3
3065 #define TGV_PREV_NUM 4
3066 #define TGV_PREV_NUM_NO_WRAP 5
3067 #define TGV_NEXT_NUM 6
3068 #define TGV_NEXT_NUM_NO_WRAP 7
3069 #define TGV_TITLE 8
3070 #define TGV_MAP_WIDTH 9
3071 #define TGV_MAP_HEIGHT 10
3072 #define TGV_MAP_OBJS 11
3073
3074 struct tagTgVars {
3075 char *var_name;
3076 int var_type;
3077 } gszTgVars[] = {
3078 { "&tgvfilename", TGV_FILE_NAME },
3079 { "&tgvcurnum", TGV_CUR_NUM },
3080 { "&tgvfirstnum", TGV_FIRST_NUM },
3081 { "&tgvlastnum", TGV_LAST_NUM },
3082 { "&tgvprevnum", TGV_PREV_NUM },
3083 { "&tgvprevnumnowrap", TGV_PREV_NUM_NO_WRAP },
3084 { "&tgvnextnum", TGV_NEXT_NUM },
3085 { "&tgvnextnumnowrap", TGV_NEXT_NUM_NO_WRAP },
3086 { "&tgvtitle", TGV_TITLE },
3087 { "&tgvmapwidth", TGV_MAP_WIDTH },
3088 { "&tgvmapheight", TGV_MAP_HEIGHT },
3089 { "&tgvmapobjs", TGV_MAP_OBJS },
3090 { NULL, INVALID }
3091 };
3092
3093 static
FindTgVarType(buf)3094 int FindTgVarType(buf)
3095 char *buf;
3096 {
3097 struct tagTgVars *ptv=NULL;
3098
3099 for (ptv=gszTgVars; ptv->var_name != NULL; ptv++) {
3100 if (UtilStrICmp(buf, ptv->var_name) == 0) {
3101 return ptv->var_type;
3102 }
3103 }
3104 return INVALID;
3105 }
3106
3107 static
GenerateTemplateHtmlVar(map_fp,var_type,gif_fname,map_fname,fname,LtX,LtY,RbX,RbY)3108 void GenerateTemplateHtmlVar(map_fp, var_type, gif_fname, map_fname, fname,
3109 LtX, LtY, RbX, RbY)
3110 FILE *map_fp;
3111 char *gif_fname, *map_fname, *fname;
3112 int var_type, LtX, LtY, RbX, RbY;
3113 {
3114 struct ObjRec *obj_ptr=NULL;
3115 struct AttrRec *attr_ptr=NULL;
3116
3117 switch (var_type) {
3118 case TGV_FILE_NAME: fprintf(map_fp, "%s", fname); break;
3119 case TGV_CUR_NUM: fprintf(map_fp, "%1d", curPageNum); break;
3120 case TGV_FIRST_NUM: fprintf(map_fp, "1"); break;
3121 case TGV_LAST_NUM: fprintf(map_fp, "%1d", lastPageNum); break;
3122 case TGV_PREV_NUM:
3123 if (curPageNum == 1) {
3124 fprintf(map_fp, "%1d", lastPageNum);
3125 } else {
3126 fprintf(map_fp, "%1d", curPageNum-1);
3127 }
3128 break;
3129 case TGV_PREV_NUM_NO_WRAP:
3130 if (curPageNum == 1) {
3131 fprintf(map_fp, "1");
3132 } else {
3133 fprintf(map_fp, "%1d", curPageNum-1);
3134 }
3135 break;
3136 case TGV_NEXT_NUM:
3137 if (curPageNum == lastPageNum) {
3138 fprintf(map_fp, "1");
3139 } else {
3140 fprintf(map_fp, "%1d", curPageNum+1);
3141 }
3142 break;
3143 case TGV_NEXT_NUM_NO_WRAP:
3144 if (curPageNum == lastPageNum) {
3145 fprintf(map_fp, "%1d", lastPageNum);
3146 } else {
3147 fprintf(map_fp, "%1d", curPageNum+1);
3148 }
3149 break;
3150 case TGV_TITLE:
3151 if (curPage->name != NULL && *curPage->name != '\0') {
3152 fprintf(map_fp, "%s", curPage->name);
3153 } else if ((attr_ptr=FindFileAttrWithName("title=")) != NULL) {
3154 fprintf(map_fp, "%s", attr_ptr->attr_value.s);
3155 } else {
3156 fprintf(map_fp, TgLoadCachedString(CSTID_PARANED_UNKNOWN));
3157 }
3158 break;
3159 case TGV_MAP_WIDTH: fprintf(map_fp, "%1d", RbX-LtX); break;
3160 case TGV_MAP_HEIGHT: fprintf(map_fp, "%1d", RbY-LtY); break;
3161 case TGV_MAP_OBJS:
3162 for (obj_ptr=topObj; obj_ptr != NULL; obj_ptr=obj_ptr->next) {
3163 if (GenerateObjImageMap(map_fp, obj_ptr, LtX, LtY)) {
3164 }
3165 }
3166 break;
3167 }
3168 }
3169
3170 static
GenerateTemplateHtmlFile(map_fp,tmpl_fp,gif_fname,map_fname,LtX,LtY,RbX,RbY)3171 void GenerateTemplateHtmlFile(map_fp, tmpl_fp, gif_fname, map_fname,
3172 LtX, LtY, RbX, RbY)
3173 FILE *map_fp, *tmpl_fp;
3174 char *gif_fname, *map_fname;
3175 int LtX, LtY, RbX, RbY;
3176 {
3177 char *buf=NULL, *fname=NULL, *c_ptr=NULL;
3178 int line_num=0;
3179
3180 if ((c_ptr=UtilStrRChr(curFileName, DIR_SEP)) == NULL) {
3181 fname = UtilStrDup(curFileName);
3182 } else {
3183 fname = UtilStrDup(++c_ptr);
3184 }
3185 if (fname == NULL) FailAllocMessage();
3186 if ((c_ptr=strchr(fname, '#')) != NULL) *c_ptr = '\0';
3187 GetRealBaseName(fname);
3188 if ((c_ptr=UtilStrRChr(fname, '.')) != NULL) *c_ptr = '\0';
3189
3190 while ((buf=UtilGetALine(tmpl_fp)) != NULL) {
3191 char *psz_start=buf, *psz=NULL, *psz1=NULL;
3192
3193 line_num++;
3194 if (*psz_start == '\0') {
3195 fprintf(map_fp, "%s\n", psz_start);
3196 UtilFree(buf);
3197 continue;
3198 }
3199 while ((psz=strstr(psz_start,"&tgv")) != NULL &&
3200 (psz1=strchr(psz,';')) != NULL) {
3201 int var_type=INVALID;
3202
3203 *psz1 = '\0';
3204 if ((var_type=FindTgVarType(psz)) != INVALID) {
3205 *psz = '\0';
3206 fprintf(map_fp, "%s", psz_start);
3207 *psz = '&';
3208 psz_start = &psz1[1];
3209 GenerateTemplateHtmlVar(map_fp, var_type, gif_fname, map_fname,
3210 fname, LtX, LtY, RbX, RbY);
3211 } else {
3212 fprintf(map_fp, "%s", psz_start);
3213 psz_start = psz1;
3214 }
3215 *psz1 = ';';
3216 }
3217 if (psz_start != NULL) {
3218 fprintf(map_fp, "%s\n", psz_start);
3219 } else {
3220 fprintf(map_fp, "\n");
3221 }
3222 UtilFree(buf);
3223 }
3224 UtilFree(fname);
3225 }
3226
3227 static
GenerateImageMap(XpmFileName,src_is_ppm,LtX,LtY,RbX,RbY,nPageNumInFileName)3228 void GenerateImageMap(XpmFileName, src_is_ppm, LtX, LtY, RbX, RbY,
3229 nPageNumInFileName)
3230 char *XpmFileName;
3231 int src_is_ppm, LtX, LtY, RbX, RbY, nPageNumInFileName;
3232 {
3233 char map_fname[MAXPATHLENGTH+1], gif_fname[MAXPATHLENGTH+1];
3234 char tmpl_fname[MAXPATHLENGTH+1];
3235 struct ObjRec *obj_ptr=NULL;
3236 FILE *map_fp=NULL, *tmpl_fp=NULL;
3237 int xpm_ext_len, len, something_generated=FALSE, short_name=FALSE;
3238 struct AttrRec *attr_ptr=NULL;
3239 char *psz=UtilStrRChr(XpmFileName,DIR_SEP), *rest=NULL;
3240
3241 *map_fname = *gif_fname = *tmpl_fname = '\0';
3242 len = strlen(XpmFileName);
3243 if (psz == NULL) {
3244 psz = UtilStrRChr(XpmFileName, '.');
3245 if (psz == NULL) {
3246 sprintf(gszMsgBox, TgLoadString(STID_FNAME_FORMAT_ERROR_IN_FUNC),
3247 "GenerateImageMap()");
3248 FatalUnexpectedError(gszMsgBox, NULL);
3249 return;
3250 }
3251 xpm_ext_len = strlen(psz);
3252 } else {
3253 char *psz1=NULL;
3254
3255 *psz = '\0';
3256 psz1 = UtilStrRChr(&psz[1], '.');
3257 if (psz1 == NULL) {
3258 *psz = DIR_SEP;
3259 sprintf(gszMsgBox, TgLoadString(STID_FNAME_FORMAT_ERROR_IN_FUNC),
3260 "GenerateImageMap()");
3261 FatalUnexpectedError(gszMsgBox, NULL);
3262 return;
3263 }
3264 xpm_ext_len = strlen(psz1);
3265 *psz = DIR_SEP;
3266 }
3267 if (XpmFileName[len-xpm_ext_len] != '.') {
3268 sprintf(gszMsgBox, TgLoadString(STID_FNAME_FORMAT_ERROR_IN_FUNC),
3269 "GenerateImageMap()");
3270 FatalUnexpectedError(gszMsgBox, NULL);
3271 return;
3272 }
3273 XpmFileName[len-xpm_ext_len] = '\0';
3274 switch (whereToPrint) {
3275 case GIF_FILE:
3276 sprintf(map_fname, "%s%s%s", XpmFileName,
3277 *imageMapFileExtension == '\0' ? "" : ".", imageMapFileExtension);
3278 sprintf(gif_fname, "%s%s%s", XpmFileName,
3279 *gifFileExtension == '\0' ? "" : ".", gifFileExtension);
3280 break;
3281 case HTML_FILE:
3282 if (*gszHhtmlExportTemplate != '\0') {
3283 if (*gszHhtmlExportTemplate == DIR_SEP) {
3284 strcpy(tmpl_fname, gszHhtmlExportTemplate);
3285 } else {
3286 char *psz=UtilStrRChr(XpmFileName, DIR_SEP);
3287
3288 if (psz == NULL) {
3289 strcpy(tmpl_fname, gszHhtmlExportTemplate);
3290 } else {
3291 *psz = '\0';
3292 sprintf(tmpl_fname, "%s%c%s", XpmFileName, DIR_SEP,
3293 gszHhtmlExportTemplate);
3294 *psz = DIR_SEP;
3295 }
3296 }
3297 }
3298 sprintf(map_fname, "%s%s%s", XpmFileName,
3299 *htmlFileExtension == '\0' ? "" : ".", htmlFileExtension);
3300 sprintf(gif_fname, "%s%s%s", XpmFileName,
3301 *gifFileExtension == '\0' ? "" : ".", gifFileExtension);
3302 break;
3303 case PNG_FILE:
3304 *map_fname = '\0';
3305 sprintf(gif_fname, "%s%s%s", XpmFileName,
3306 *pngFileExtension == '\0' ? "" : ".", pngFileExtension);
3307 break;
3308 case JPEG_FILE:
3309 *map_fname = '\0';
3310 sprintf(gif_fname, "%s%s%s", XpmFileName,
3311 *jpegFileExtension == '\0' ? "" : ".", jpegFileExtension);
3312 break;
3313 case XBM_FILE:
3314 *map_fname = '\0';
3315 sprintf(gif_fname, "%s.xpm", XpmFileName);
3316 break;
3317 }
3318 XpmFileName[len-xpm_ext_len] = '.';
3319
3320 if ((short_name=IsPrefix(bootDir, gif_fname, &rest))) ++rest;
3321 sprintf(gszMsgBox, TgLoadString(STID_CONVERTING_INTO_NAMED_FILE), rest);
3322 if (PRTGIF && !cmdLineStdOut) {
3323 if (!cmdLineQuiet) {
3324 fprintf(stderr, "%s\n", gszMsgBox);
3325 }
3326 } else {
3327 Msg(gszMsgBox);
3328 }
3329 if (*tmpl_fname != '\0' && whereToPrint == HTML_FILE &&
3330 ((tmpl_fp=fopen(tmpl_fname,"r")) == NULL)) {
3331 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_HTML_TMPL_READ),
3332 tmpl_fname);
3333 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3334 return;
3335 }
3336 if (!ConvertXpmToGif(XpmFileName, gif_fname, src_is_ppm, whereToPrint)) {
3337 if (tmpl_fp != NULL) fclose(tmpl_fp);
3338 return;
3339 }
3340 switch (whereToPrint) {
3341 case GIF_FILE:
3342 if ((attr_ptr=FindFileAttrWithName("href=")) != NULL) {
3343 map_fp = OpenMapFile(map_fname);
3344 if (map_fp != NULL) {
3345 Msg(TgLoadCachedString(CSTID_GENERATING_IMAGEMAP_FILE_DOTS));
3346 fprintf(map_fp, "default %s\n", attr_ptr->attr_value.s);
3347 for (obj_ptr=topObj; obj_ptr != NULL; obj_ptr=obj_ptr->next) {
3348 if (GenerateObjImageMap(map_fp, obj_ptr, LtX, LtY)) {
3349 something_generated = TRUE;
3350 }
3351 }
3352 fclose(map_fp);
3353 Msg("");
3354 sprintf(gszMsgBox, TgLoadString(STID_NAMED_IMAGEMAP_FILE_GEN),
3355 map_fname);
3356 Msg(gszMsgBox);
3357 }
3358 } else if (generateImageMap) {
3359 if (nPageNumInFileName) {
3360 /* surpress the error message if we are print one file per page */
3361 } else if (something_generated) {
3362 sprintf(gszMsgBox, TgLoadString(STID_CANT_FND_FATTR_IMGMAP_NOT_GEN),
3363 "href=");
3364 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3365 } else {
3366 sprintf(gszMsgBox, TgLoadString(STID_CANT_FND_FATTR_NO_IMGMAP_GIF),
3367 "href=");
3368 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3369 }
3370 }
3371 break;
3372 case HTML_FILE:
3373 map_fp = OpenMapFile(map_fname);
3374 if (map_fp != NULL) {
3375 int saved_image_map_file_format=imageMapFileFormat;
3376
3377 if (tmpl_fp == NULL) {
3378 Msg(TgLoadCachedString(CSTID_GENERATING_HTML_FILE_DOTS));
3379 GenerateHtmlHeader(map_fp);
3380 GenerateUseMapHeader(map_fp, gif_fname, map_fname);
3381 imageMapFileFormat = IMF_FORMAT_SPYG;
3382 for (obj_ptr=topObj; obj_ptr != NULL; obj_ptr=obj_ptr->next) {
3383 if (GenerateObjImageMap(map_fp, obj_ptr, LtX, LtY)) {
3384 something_generated = TRUE;
3385 }
3386 }
3387 GenerateUseMapTrailer(map_fp, RbX-LtX, RbY-LtY);
3388 GenerateHtmlTrailer(map_fp);
3389 } else {
3390 sprintf(gszMsgBox,
3391 TgLoadCachedString(CSTID_GEN_TEMPLATE_HTML_FILE_DOTS),
3392 tmpl_fname);
3393 Msg(gszMsgBox);
3394 imageMapFileFormat = IMF_FORMAT_SPYG;
3395 GenerateTemplateHtmlFile(map_fp, tmpl_fp, gif_fname, map_fname,
3396 LtX, LtY, RbX, RbY);
3397 fclose(tmpl_fp);
3398 }
3399 Msg("");
3400 fclose(map_fp);
3401 imageMapFileFormat = saved_image_map_file_format;
3402 sprintf(gszMsgBox, TgLoadString(STID_NAMED_HTML_FILE_GEN),
3403 map_fname);
3404 Msg(gszMsgBox);
3405 }
3406 break;
3407
3408 case PNG_FILE: break;
3409 case JPEG_FILE: break;
3410 case PPM_FILE: break;
3411 case XBM_FILE: break;
3412 }
3413 }
3414
3415 #ifdef NOT_DEFINED
3416 #ifdef _TGIF_DBG /* debug, do not translate */
3417 static
DebugXPmColors()3418 void DebugXPmColors()
3419 {
3420 int i=0;
3421
3422 fprintf(stderr, "\nnumColorsToDump = %1d\n", numColorsToDump);
3423 fprintf(stderr, "maxColors = %1d\n", maxColors);
3424 fprintf(stderr, "\nThe following indices ranges from 0 to maxColors-1:\n");
3425 for (i=0; i < maxColors; i++) {
3426 if (mainVisual->class == TrueColor) {
3427 fprintf(stderr, "%s[%3d]=%3d, %s[%3d]=0x%06lx\n",
3428 "colorIndexToDumpIndex", i, colorIndexToDumpIndex[i],
3429 "colorPixels", i, (long)colorPixels[i]);
3430 } else {
3431 fprintf(stderr, "%s[%3d]=%3d, %s[%3d]=%3d\n",
3432 "colorIndexToDumpIndex", i, colorIndexToDumpIndex[i],
3433 "colorPixels", i, colorPixels[i]);
3434 }
3435 }
3436 fprintf(stderr, "\n%s 0 to numColorsToDump-1:\n",
3437 "The following indices ranges from");
3438 for (i=0; i < numColorsToDump; i++) {
3439 int j=0;
3440
3441 if (mainVisual->class == TrueColor) {
3442 fprintf(stderr, "%s[%3d]=0x%06lx, %s[%3d]=",
3443 "pixelValue", i, (long)pixelValue[i], "colorChar", i);
3444 } else {
3445 fprintf(stderr, "%s[%3d]=%3d, %s[%3d]=",
3446 "pixelValue", i, pixelValue[i], "colorChar", i);
3447 }
3448 for (j = 0; j < charsPerPixel; j++) {
3449 fprintf(stderr, "%c", colorChar[i*charsPerPixel+j]);
3450 }
3451 fprintf(stderr, ", %s[%3d]=%s\n", "colorStr", i, colorStr[i]);
3452 }
3453 }
3454 #endif /* _TGIF_DBG */
3455
3456 #ifdef _TGIF_DBG /* debug, do not translate */
3457 static
DebugXPmColorsAndExportImage(image,w,h,left,top,right,bottom)3458 void DebugXPmColorsAndExportImage(image, w, h, left, top, right, bottom)
3459 XImage *image;
3460 int w, h, left, top, right, bottom;
3461 {
3462 int i=0;
3463
3464 DebugXPmColors();
3465
3466 fprintf(stderr, "\nHere is the image:\n");
3467 fprintf(stderr, " (%s\n %s\n %s)\n",
3468 "recall that if colorIndexToDumpIndex[color_index] = index",
3469 "then pixelValue[index] == pixel, where pixel is a value seen below",
3470 "and color_index indexes colorPixels and colorMenuItems");
3471 for (i=top; i < h-bottom; i++) {
3472 int j=0;
3473
3474 for (j=left; j < w-right; j++) {
3475 int data=XGetPixel(image,j-left,i-top);
3476
3477 if (j+1 == w-right) {
3478 if (mainVisual->class == TrueColor) {
3479 fprintf(stderr, "%06lx\n", (long)data);
3480 } else {
3481 fprintf(stderr, "%3d\n", data);
3482 }
3483 } else {
3484 if (mainVisual->class == TrueColor) {
3485 fprintf(stderr, "%06lx ", (long)data);
3486 } else {
3487 fprintf(stderr, "%3d ", data);
3488 }
3489 }
3490 }
3491 }
3492 }
3493 #endif /* _TGIF_DBG */
3494 #endif /* NOT_DEFINED */
3495
3496 static
AdjustForRealBaseName(fname,gzipped,no_name)3497 void AdjustForRealBaseName(fname, gzipped, no_name)
3498 char *fname;
3499 int gzipped, no_name;
3500 {
3501 char *psz=NULL, *psz1=NULL;
3502
3503 if (no_name) return;
3504 if ((psz1=UtilStrRChr(fname, '.')) == NULL) return;
3505 *psz1 = '\0';
3506 if (!gzipped) return;
3507 if ((psz=UtilStrRChr(fname, '.')) == NULL) {
3508 *psz1 = '.';
3509 return;
3510 }
3511 *psz = '\0';
3512 }
3513
GetRealBaseName(fname)3514 void GetRealBaseName(fname)
3515 char *fname;
3516 {
3517 int gzipped=FALSE, no_name=FALSE;
3518
3519 if (FileNameHasExtension(fname, OBJ_FILE_TYPE, &gzipped, &no_name)) {
3520 AdjustForRealBaseName(fname, gzipped, no_name);
3521 return;
3522 }
3523 gzipped = no_name = FALSE;
3524 if (FileNameHasExtension(fname, SYM_FILE_TYPE, &gzipped, &no_name)) {
3525 AdjustForRealBaseName(fname, gzipped, no_name);
3526 return;
3527 }
3528 gzipped = no_name = FALSE;
3529 if (FileNameHasExtension(fname, PIN_FILE_TYPE, &gzipped, &no_name)) {
3530 AdjustForRealBaseName(fname, gzipped, no_name);
3531 return;
3532 }
3533 }
3534
3535 static
RotateImageForLandscape(src_image,p_w,p_h,p_left,p_top,p_right,p_bottom)3536 XImage *RotateImageForLandscape(src_image, p_w, p_h, p_left, p_top, p_right,
3537 p_bottom)
3538 XImage *src_image;
3539 int *p_w, *p_h, *p_left, *p_top, *p_right, *p_bottom;
3540 {
3541 int x=0, y=0;
3542 int new_w=(*p_h), new_h=(*p_w), new_left=(*p_top), new_top=(*p_right);
3543 int new_right=(*p_bottom), new_bottom=(*p_left);
3544 Pixmap dest_pixmap=None;
3545 XImage *dest_image=NULL;
3546
3547 dest_pixmap = XCreatePixmap(mainDisplay, mainWindow, new_w, new_h,
3548 mainDepth);
3549 dest_image = (dest_pixmap==None ? NULL : XGetImage(mainDisplay, dest_pixmap,
3550 0, 0, new_w, new_h, AllPlanes, ZPixmap));
3551 if (dest_pixmap == None || dest_image == NULL) {
3552 FailAllocPixmapMessage(new_w, new_h);
3553 if (dest_pixmap != None) XFreePixmap(mainDisplay, dest_pixmap);
3554 if (dest_image != NULL) XDestroyImage(dest_image);
3555 return NULL;
3556 }
3557 for (y=0; y < new_w; y++) {
3558 for (x=0; x < new_h; x++) {
3559 XPutPixel(dest_image, y, (new_h-1)-x, XGetPixel(src_image, x, y));
3560 }
3561 }
3562 *p_w = new_w;
3563 *p_h = new_h;
3564 *p_left = new_left;
3565 *p_top = new_top;
3566 *p_right = new_right;
3567 *p_bottom = new_bottom;
3568
3569 XFreePixmap(mainDisplay, dest_pixmap);
3570
3571 return dest_image;
3572 }
3573
3574 static int dumpPpmPreferred=FALSE;
3575
3576 static
DumpXpmHeader(fp,w,h,name,left,top,right,bottom)3577 void DumpXpmHeader(fp, w, h, name, left, top, right, bottom)
3578 FILE *fp;
3579 int w, h, left, top, right, bottom;
3580 char *name;
3581 {
3582 if (whereToPrint == PPM_FILE ||
3583 (whereToPrint != XBM_FILE && dumpPpmPreferred)) {
3584 fprintf(fp, "P6\n%1d %1d\n255\n", w-left-right, h-top-bottom);
3585 } else if (xpmOutputVersion == 1) {
3586 DumpCommentInBitmapExport(fp);
3587 /* do not translate -- program constants */
3588 fprintf(fp, "#define %s_format 1\n", name);
3589 fprintf(fp, "#define %s_width %1d\n", name, w-left-right);
3590 fprintf(fp, "#define %s_height %1d\n", name, h-top-bottom);
3591 fprintf(fp, "#define %s_ncolors %1d\n", name, numColorsToDump);
3592 fprintf(fp, "#define %s_chars_per_pixel %1d\n", name, charsPerPixel);
3593 if (xpmInXGrabSCFormat) {
3594 fprintf(fp, "static char * %s_colors[] = {\n", name);
3595 } else {
3596 fprintf(fp, "static char *%s_colors[] = {\n", name);
3597 }
3598 DumpXPmColors(fp);
3599 if (xpmInXGrabSCFormat) {
3600 fprintf(fp, "static char * %s_pixels[] = {\n", name);
3601 } else {
3602 fprintf(fp, "static char *%s_pixels[] = {\n", name);
3603 }
3604 } else {
3605 /* xpmOutputVersion is 3 */
3606 fprintf(fp, "/* XPM */\n");
3607 DumpCommentInBitmapExport(fp);
3608 fprintf(fp, "static char * %s[] = {\n", name);
3609 fprintf(fp, "\"%1d %1d %1d %1d\",\n",
3610 w-left-right, h-top-bottom, numColorsToDump, charsPerPixel);
3611 DumpXPmColors(fp);
3612 }
3613 }
3614
3615 static
DumpXbmHeader(fp,w,h,name,left,top,right,bottom)3616 void DumpXbmHeader(fp, w, h, name, left, top, right, bottom)
3617 FILE *fp;
3618 int w, h, left, top, right, bottom;
3619 char *name;
3620 {
3621 if (whereToPrint == PPM_FILE) {
3622 fprintf(fp, "P4\n%1d %1d\n", w-left-right, h-top-bottom);
3623 } else {
3624 DumpCommentInBitmapExport(fp);
3625 /* do not translate -- program constants */
3626 fprintf(fp, "#define %s_width %1d\n", name, w-left-right);
3627 fprintf(fp, "#define %s_height %1d\n", name, h-top-bottom);
3628 fprintf(fp, "#define %s_x_hot 0\n", name);
3629 fprintf(fp, "#define %s_y_hot 0\n", name);
3630 fprintf(fp, "static %schar %s_bits[] = {\n ",
3631 (unsignedInXBmExport ? "unsigned " : ""), name);
3632 }
3633 }
3634
SetAColorByteInfo(pcb,pXColor)3635 void SetAColorByteInfo(pcb, pXColor)
3636 ColorBytes *pcb;
3637 XColor *pXColor;
3638 {
3639 double red=0, green=0, blue=0;
3640 int r=0, g=0, b=0;
3641
3642 red = ((double)255)*((double)(pXColor->red))/((double)maxRGB);
3643 green = ((double)255)*((double)(pXColor->green))/((double)maxRGB);
3644 blue = ((double)255)*((double)(pXColor->blue))/((double)maxRGB);
3645
3646 r = round(red);
3647 g = round(green);
3648 b = round(blue);
3649
3650 if (r > 255) r = 255;
3651 if (g > 255) g = 255;
3652 if (b > 255) b = 255;
3653
3654 if (r < 0) r = 0;
3655 if (g < 0) g = 0;
3656 if (b < 0) b = 0;
3657
3658 pcb->r = (unsigned char)(r & 0x0ff);
3659 pcb->g = (unsigned char)(g & 0x0ff);
3660 pcb->b = (unsigned char)(b & 0x0ff);
3661
3662 pcb->valid = TRUE;
3663 }
3664
3665 static
SetColorBytes(pcb,index,table_size)3666 void SetColorBytes(pcb, index, table_size)
3667 ColorBytes *pcb;
3668 int index, table_size;
3669 {
3670 #ifdef _TGIF_DBG /* debug, do not translate */
3671 TgAssert(index >= 0 && index < table_size,
3672 "index out of range in SetColorBytes()", NULL);
3673 #endif /* _TGIF_DBG */
3674 if (pcb[index].valid) return;
3675
3676 SetAColorByteInfo(&pcb[index], &tgifColors[index]);
3677 }
3678
3679 static
DumpPpmBody(fp,image,bitmap_image,w,h,left,top,right,bottom,nInImageProc,bg_pixel)3680 int DumpPpmBody(fp, image, bitmap_image, w, h, left, top, right,
3681 bottom, nInImageProc, bg_pixel)
3682 FILE *fp;
3683 XImage *image, *bitmap_image;
3684 int w, h, left, top, right, bottom, nInImageProc, bg_pixel;
3685 {
3686 XColor *saved_tgif_colors=tgifColors;
3687 ColorBytes *pcb=(ColorBytes*)malloc((maxColors+3)*sizeof(ColorBytes));
3688 ColorBytes my_bg_cb;
3689 int i=0, target_percent=5;
3690
3691 if (pcb == NULL) FailAllocMessage();
3692 memset(pcb, 0, (maxColors+3)*sizeof(ColorBytes));
3693 memset(&my_bg_cb, 0, sizeof(ColorBytes));
3694 if (printUsingRequestedColor) tgifColors = tgifRequestedColors;
3695
3696 SetAColorByteInfo(&my_bg_cb, &myBgColor);
3697
3698 for (i=top; i < h-bottom; i++) {
3699 int j=0, percent=((i-top)*10000/(h-top-bottom))/100;
3700
3701 if (percent >= target_percent) {
3702 sprintf(gszMsgBox, TgLoadCachedString(CSTID_PROGRESS_PERCENT),
3703 percent);
3704 SetStringStatus(gszMsgBox);
3705 XSync(mainDisplay, False);
3706 while (target_percent <= percent) target_percent += 5;
3707 }
3708 for (j=left; j < w-right; j++) {
3709 int transparent=FALSE, data=0;
3710
3711 if (nInImageProc && bitmap_image != NULL) {
3712 if (XGetPixel(bitmap_image,j-left,i-top) != 0) {
3713 data = XGetPixel(image,j-left,i-top);
3714 } else {
3715 transparent = TRUE;
3716 }
3717 } else {
3718 data = XGetPixel(image,j-left,i-top);
3719 }
3720 if (!nInImageProc && data == bg_pixel) {
3721 if (fprintf(fp, "%c%c%c",
3722 my_bg_cb.r, my_bg_cb.g, my_bg_cb.b) == EOF) {
3723 writeFileFailed = TRUE;
3724 }
3725 } else {
3726 int index=INVALID, color_index=BAD;
3727
3728 if (transparent) {
3729 index = transparentIndex;
3730 } else {
3731 index = XPmLookUp(data, INVALID, NULL, &color_index);
3732 }
3733 if (index == INVALID || color_index == BAD ||
3734 color_index == INVALID) {
3735 sprintf(gszMsgBox,
3736 TgLoadString(transparent ?
3737 STID_UNRECOG_GIVEN_TRPIX_VAL_PRINT :
3738 STID_UNRECOG_GIVEN_PIXEL_VAL_PRINT),
3739 j-left, i-top, data, (long)data);
3740 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3741
3742 if (printUsingRequestedColor) tgifColors = saved_tgif_colors;
3743 free(pcb);
3744 return FALSE;
3745 }
3746 SetColorBytes(pcb, color_index, (maxColors+3));
3747 if (fprintf(fp, "%c%c%c", pcb[color_index].r, pcb[color_index].g,
3748 pcb[color_index].b) == EOF) {
3749 writeFileFailed = TRUE;
3750 }
3751 }
3752 }
3753 }
3754 if (printUsingRequestedColor) tgifColors = saved_tgif_colors;
3755 free(pcb);
3756
3757 return TRUE;
3758 }
3759
3760 static
DumpXpmBody(fp,image,bitmap_image,w,h,left,top,right,bottom,nInImageProc,bg_pixel)3761 int DumpXpmBody(fp, image, bitmap_image, w, h, left, top, right,
3762 bottom, nInImageProc, bg_pixel)
3763 FILE *fp;
3764 XImage *image, *bitmap_image;
3765 int w, h, left, top, right, bottom, nInImageProc, bg_pixel;
3766 {
3767 int i=0, target_percent=5;
3768
3769 if (whereToPrint == PPM_FILE ||
3770 (whereToPrint != XBM_FILE && dumpPpmPreferred)) {
3771 return DumpPpmBody(fp, image, bitmap_image, w, h, left, top, right,
3772 bottom, nInImageProc, bg_pixel);
3773 }
3774 for (i=top; i < h-bottom; i++) {
3775 int j=0, percent=((i-top)*10000/(h-top-bottom))/100;
3776
3777 if (percent >= target_percent) {
3778 sprintf(gszMsgBox, TgLoadCachedString(CSTID_PROGRESS_PERCENT),
3779 percent);
3780 SetStringStatus(gszMsgBox);
3781 XSync(mainDisplay, False);
3782 while (target_percent <= percent) target_percent += 5;
3783 }
3784 if (fprintf(fp, "\"") == EOF) writeFileFailed = TRUE;
3785 for (j=left; j < w-right; j++) {
3786 int transparent=FALSE, data=0;
3787
3788 if (nInImageProc && bitmap_image != NULL) {
3789 if (XGetPixel(bitmap_image,j-left,i-top) != 0) {
3790 data = XGetPixel(image,j-left,i-top);
3791 } else {
3792 transparent = TRUE;
3793 }
3794 } else {
3795 data = XGetPixel(image,j-left,i-top);
3796 }
3797 if (!nInImageProc && data == bg_pixel) {
3798 switch (charsPerPixel) {
3799 case 1:
3800 if (fprintf(fp, "`") == EOF) writeFileFailed = TRUE;
3801 break;
3802 case 2:
3803 if (fprintf(fp, "``") == EOF) writeFileFailed = TRUE;
3804 break;
3805 }
3806 } else {
3807 int k=0, index=0;
3808
3809 if (transparent) {
3810 index = transparentIndex;
3811 } else {
3812 index = XPmLookUp(data, INVALID, NULL, NULL);
3813 }
3814 if (index == INVALID) {
3815 sprintf(gszMsgBox,
3816 TgLoadString(transparent ?
3817 STID_UNRECOG_GIVEN_TRPIX_VAL_PRINT :
3818 STID_UNRECOG_GIVEN_PIXEL_VAL_PRINT),
3819 j-left, i-top, data, (long)data);
3820 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
3821
3822 return FALSE;
3823 }
3824 for (k=0; k < charsPerPixel; k++) {
3825 if (fprintf(fp, "%c", colorChar[index*charsPerPixel+k]) == EOF) {
3826 writeFileFailed = TRUE;
3827 }
3828 }
3829 }
3830 }
3831 if (i == h-bottom-1) {
3832 if (xpmInXGrabSCFormat) {
3833 if (fprintf(fp, "\",\n} ;\n") == EOF) {
3834 writeFileFailed = TRUE;
3835 }
3836 } else {
3837 if (fprintf(fp, "\"\n};\n") == EOF) {
3838 writeFileFailed = TRUE;
3839 }
3840 }
3841 } else if (fprintf(fp, "\",\n") == EOF) {
3842 writeFileFailed = TRUE;
3843 }
3844 }
3845 return TRUE;
3846 }
3847
3848 #define FS_SCALE 0x400
3849 #define HALF_FS_SCALE 0x200
3850
3851 static
DumpXbmHalfToneBody(fp,image,w,h,left,top,right,bottom,bg_pixel)3852 void DumpXbmHalfToneBody(fp, image, w, h, left, top, right, bottom, bg_pixel)
3853 FILE *fp;
3854 XImage *image;
3855 int w, h, left, top, right, bottom, bg_pixel;
3856 {
3857 int i=0, j=0, k=0, bit_count=0, data=0, pixel=0, byte_count=0;
3858 TrueColorInfo tci;
3859 ProgressInfo pi;
3860
3861 /*--------------------------------------------------*/
3862 /* the halftoning code is adapted from 'pgmopbm.c', */
3863 /* which is part of the pbmplus package. */
3864 /* */
3865 /* Copyright (C) 1989 by Jef Poskanzer */
3866 /*--------------------------------------------------*/
3867 long *thiserr, *nexterr, *tmperr, threshval, sum;
3868 int fs_forward=TRUE, col, limitcol, found_index, *bits;
3869 float gray;
3870
3871 sprintf(gszMsgBox,
3872 TgLoadCachedString(CSTID_FS_HALFTONE_BMP_THRESH_DOTS),
3873 bitmapThresholdStr);
3874 Msg(gszMsgBox);
3875
3876 srand(0);
3877 thiserr = (long*)malloc((w-left-right+2)*sizeof(long));
3878 nexterr = (long*)malloc((w-left-right+2)*sizeof(long));
3879 bits = (int*)malloc((w-left-right+2)*sizeof(int));
3880 if (thiserr==NULL || nexterr==NULL || bits==NULL) FailAllocMessage();
3881 for (j = 0; j < w-left-right+2; j++) {
3882 thiserr[j] = (rand() % FS_SCALE - HALF_FS_SCALE) >> 2;
3883 }
3884 threshval = (long)(bitmapThreshold * (float)FS_SCALE);
3885 if (fullTrueColorMode) {
3886 if (!InitTrueColorInfo(image, &tci, w)) {
3887 return;
3888 }
3889 }
3890 byte_count = 0;
3891 BeginProgress(&pi, h-top-bottom);
3892 for (i=top; i < h-bottom; i++) {
3893 UpdateProgress(&pi, i-top);
3894
3895 for (col = 0; col < w-left-right+2; col++) {
3896 nexterr[col] = bits[col] = 0;
3897 }
3898 bit_count = 0;
3899 col = (fs_forward) ? 0 : w-left-right-1;
3900 limitcol = (fs_forward) ? w-left-right : -1;
3901 do {
3902 found_index = INVALID;
3903 pixel = XGetPixel(image, col, i);
3904
3905 if (fullTrueColorMode) {
3906 uint32_t pix=(uint32_t)(unsigned int)pixel;
3907 unsigned int r=0, g=0, b=0;
3908 double dr=(double)0, dg=(double)0, db=(double)0;
3909
3910 r = (pix & tci.r_mask) >> tci.r_shift;
3911 g = (pix & tci.g_mask) >> tci.g_shift;
3912 b = (pix & tci.b_mask) >> tci.b_shift;
3913 dr = ((double)r) / tci.dr_maxval;
3914 dg = ((double)g) / tci.dg_maxval;
3915 db = ((double)b) / tci.db_maxval;
3916 gray = (float)(0.299*dr + 0.587*dg + 0.114*db);
3917 } else {
3918 for (k = 0; k < maxColors; k++) {
3919 if (colorPixels[k] == pixel) {
3920 found_index = k;
3921 break;
3922 }
3923 }
3924 if (found_index == INVALID) {
3925 if (pixel == bg_pixel) {
3926 gray = (float)1.0;
3927 } else {
3928 sprintf(gszMsgBox,
3929 TgLoadString(STID_UNRECOG_GIVEN_PIXEL_VAL_1_USE),
3930 pixel, (long)pixel);
3931 Msg(gszMsgBox);
3932 gray = (float)0.0;
3933 }
3934 } else {
3935 gray = 0.299*((float)tgifColors[found_index].red/maxRGB) +
3936 0.587*((float)tgifColors[found_index].green/maxRGB) +
3937 0.114*((float)tgifColors[found_index].blue/maxRGB);
3938 }
3939 }
3940 sum = ((long)(gray * FS_SCALE)) + thiserr[col+1];
3941 if (sum >= threshval) {
3942 sum = sum-threshval-HALF_FS_SCALE;
3943 } else {
3944 bits[col] = 1; /* black bit */
3945 }
3946 if (fs_forward) {
3947 thiserr[col+2] += (sum*7)>>4;
3948 nexterr[col ] += (sum*3)>>4;
3949 nexterr[col+1] += (sum*5)>>4;
3950 nexterr[col+2] += (sum )>>4;
3951 col++;
3952 } else {
3953 thiserr[col ] += (sum*7)>>4;
3954 nexterr[col+2] += (sum*3)>>4;
3955 nexterr[col+1] += (sum*5)>>4;
3956 nexterr[col ] += (sum )>>4;
3957 col--;
3958 }
3959 } while (col != limitcol);
3960
3961 tmperr = thiserr;
3962 thiserr = nexterr;
3963 nexterr = tmperr;
3964 fs_forward = !fs_forward;
3965
3966 bit_count = 0;
3967 data = 0;
3968
3969 for (j = left; j < w-right; j++) {
3970 if (bits[j]) {
3971 if (whereToPrint == XBM_FILE ||
3972 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
3973 data |= (1<<bit_count);
3974 } else {
3975 data |= (1<<(7-bit_count));
3976 }
3977 }
3978 if (++bit_count == 8) {
3979 if (byte_count++ == 12) {
3980 byte_count = 1;
3981 if (whereToPrint == XBM_FILE ||
3982 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
3983 if (fprintf(fp, "\n ") == EOF) writeFileFailed = TRUE;
3984 }
3985 }
3986 if (whereToPrint == XBM_FILE ||
3987 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
3988 if (fprintf(fp, "0x%c", hexValue[(data>>4) & 0xf]) == EOF) {
3989 writeFileFailed = TRUE;
3990 }
3991 if (i == h-bottom-1 && j == w-right-1) {
3992 if (fprintf(fp, "%c};\n", hexValue[data & 0xf]) == EOF) {
3993 writeFileFailed = TRUE;
3994 }
3995 } else {
3996 if (fprintf(fp, "%c, ", hexValue[data & 0xf]) == EOF) {
3997 writeFileFailed = TRUE;
3998 }
3999 }
4000 } else {
4001 if (fprintf(fp, "%c", (unsigned char)(data & 0x0ff)) == EOF) {
4002 writeFileFailed = TRUE;
4003 }
4004 }
4005 bit_count = 0;
4006 data = 0;
4007 }
4008 }
4009 if (((w-left-right) % 8) != 0) {
4010 if (byte_count++ == 12) {
4011 byte_count = 1;
4012 if (whereToPrint == XBM_FILE ||
4013 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
4014 if (fprintf(fp, "\n ") == EOF) writeFileFailed = TRUE;
4015 }
4016 }
4017 if (whereToPrint == XBM_FILE ||
4018 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
4019 for (j=((w-left-right)%8); j < 8; j++) data |= (1<<j);
4020
4021 if (fprintf(fp, "0x%c", hexValue[(data>>4) & 0xf]) == EOF) {
4022 writeFileFailed = TRUE;
4023 }
4024 if (i == h-bottom-1) {
4025 if (fprintf(fp, "%c};\n", hexValue[data & 0xf]) == EOF) {
4026 writeFileFailed = TRUE;
4027 }
4028 } else {
4029 if (fprintf(fp, "%c, ", hexValue[data & 0xf]) == EOF) {
4030 writeFileFailed = TRUE;
4031 }
4032 }
4033 } else {
4034 if (fprintf(fp, "%c", (unsigned char)(data & 0x0ff)) == EOF) {
4035 writeFileFailed = TRUE;
4036 }
4037 }
4038 }
4039 }
4040 }
4041
4042 static
DumpXbmNoneHalfToneBody(fp,image,w,h,left,top,right,bottom,bg_pixel)4043 void DumpXbmNoneHalfToneBody(fp, image, w, h, left, top, right, bottom,
4044 bg_pixel)
4045 FILE *fp;
4046 XImage *image;
4047 int w, h, left, top, right, bottom, bg_pixel;
4048 {
4049 int i=0, j=0, k=0, bit_count=0, data=0, pixel=0, byte_count=0;
4050 TrueColorInfo tci;
4051 ProgressInfo pi;
4052
4053 if (thresholdBitmap) {
4054 sprintf(gszMsgBox,
4055 TgLoadCachedString(CSTID_THRESHOLD_BMP_THRESH_DOTS),
4056 bitmapThresholdStr);
4057 Msg(gszMsgBox);
4058 }
4059 if (fullTrueColorMode) {
4060 if (!InitTrueColorInfo(image, &tci, w)) {
4061 return;
4062 }
4063 }
4064 byte_count = 0;
4065 BeginProgress(&pi, h-top-bottom);
4066 for (i=top; i < h-bottom; i++) {
4067 UpdateProgress(&pi, i-top);
4068
4069 bit_count = 0;
4070 data = 0;
4071
4072 for (j = left; j < w-right; j++) {
4073 if (thresholdBitmap) {
4074 pixel = XGetPixel(image, j, i);
4075
4076 if (fullTrueColorMode) {
4077 uint32_t pix=(uint32_t)(unsigned int)pixel;
4078 unsigned int r=0, g=0, b=0;
4079 double dr=(double)0, dg=(double)0, db=(double)0;
4080 double dgray=(double)0;
4081
4082 r = (pix & tci.r_mask) >> tci.r_shift;
4083 g = (pix & tci.g_mask) >> tci.g_shift;
4084 b = (pix & tci.b_mask) >> tci.b_shift;
4085 dr = ((double)r) / tci.dr_maxval;
4086 dg = ((double)g) / tci.dg_maxval;
4087 db = ((double)b) / tci.db_maxval;
4088 dgray = 0.299*dr + 0.587*dg + 0.114*db;
4089 if (dgray < (double)bitmapThreshold) {
4090 if (whereToPrint == XBM_FILE ||
4091 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
4092 data |= (1<<bit_count);
4093 } else {
4094 data |= (1<<(7-bit_count));
4095 }
4096 }
4097 } else {
4098 int found_index=INVALID;
4099 float gray=(float)0;
4100
4101 for (k = 0; k < maxColors; k++) {
4102 if (colorPixels[k] == pixel) {
4103 found_index = k;
4104 break;
4105 }
4106 }
4107 if (found_index == INVALID) {
4108 if (pixel != bg_pixel) {
4109 sprintf(gszMsgBox,
4110 TgLoadString(STID_UNRECOG_GIVEN_PIXEL_VAL_1_USE),
4111 pixel, (long)pixel);
4112 Msg(gszMsgBox);
4113 if (whereToPrint == XBM_FILE ||
4114 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
4115 data |= (1<<bit_count);
4116 } else {
4117 data |= (1<<(7-bit_count));
4118 }
4119 }
4120 } else {
4121 gray = 0.299*((float)tgifColors[found_index].red/maxRGB) +
4122 0.587*((float)tgifColors[found_index].green/maxRGB) +
4123 0.114*((float)tgifColors[found_index].blue/maxRGB);
4124 if (gray < bitmapThreshold) {
4125 if (whereToPrint == XBM_FILE ||
4126 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
4127 data |= (1<<bit_count);
4128 } else {
4129 data |= (1<<(7-bit_count));
4130 }
4131 }
4132 }
4133 }
4134 } else if (XGetPixel(image,j,i) != bg_pixel) {
4135 if (whereToPrint == XBM_FILE ||
4136 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
4137 data |= (1<<bit_count);
4138 } else {
4139 data |= (1<<(7-bit_count));
4140 }
4141 }
4142 if (++bit_count == 8) {
4143 if (byte_count++ == 12) {
4144 byte_count = 1;
4145 if (whereToPrint == XBM_FILE ||
4146 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
4147 if (fprintf(fp, "\n ") == EOF) writeFileFailed = TRUE;
4148 }
4149 }
4150 if (whereToPrint == XBM_FILE ||
4151 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
4152 if (fprintf(fp, "0x%c", hexValue[(data>>4) & 0xf]) == EOF) {
4153 writeFileFailed = TRUE;
4154 }
4155 if (i == h-bottom-1 && j == w-right-1) {
4156 if (fprintf(fp, "%c};\n", hexValue[data & 0xf]) == EOF) {
4157 writeFileFailed = TRUE;
4158 }
4159 } else {
4160 if (fprintf(fp, "%c, ", hexValue[data & 0xf]) == EOF) {
4161 writeFileFailed = TRUE;
4162 }
4163 }
4164 } else {
4165 if (fprintf(fp, "%c", (unsigned char)(data & 0x0ff)) == EOF) {
4166 writeFileFailed = TRUE;
4167 }
4168 }
4169 bit_count = 0;
4170 data = 0;
4171 }
4172 }
4173 if (((w-left-right) % 8) != 0) {
4174 if (byte_count++ == 12) {
4175 byte_count = 1;
4176 if (whereToPrint == XBM_FILE ||
4177 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
4178 if (fprintf(fp, "\n ") == EOF) writeFileFailed = TRUE;
4179 }
4180 }
4181 if (whereToPrint == XBM_FILE ||
4182 (whereToPrint == EPSI_FILE && generateTiffEPSI)) {
4183 for (j=((w-left-right)%8); j < 8; j++) data |= (1<<j);
4184
4185 if (fprintf(fp, "0x%c", hexValue[(data>>4) & 0xf]) == EOF) {
4186 writeFileFailed = TRUE;
4187 }
4188 if (i == h-bottom-1) {
4189 if (fprintf(fp, "%c};\n", hexValue[data & 0xf]) == EOF) {
4190 writeFileFailed = TRUE;
4191 }
4192 } else {
4193 if (fprintf(fp, "%c, ", hexValue[data & 0xf]) == EOF) {
4194 writeFileFailed = TRUE;
4195 }
4196 }
4197 } else {
4198 if (fprintf(fp, "%c", (unsigned char)(data & 0x0ff)) == EOF) {
4199 writeFileFailed = TRUE;
4200 }
4201 }
4202 }
4203 }
4204 }
4205
4206 static
DumpXbmBody(fp,image,w,h,left,top,right,bottom,bg_pixel)4207 void DumpXbmBody(fp, image, w, h, left, top, right, bottom, bg_pixel)
4208 FILE *fp;
4209 XImage *image;
4210 int w, h, left, top, right, bottom, bg_pixel;
4211 {
4212 if (halfToneBitmap) {
4213 DumpXbmHalfToneBody(fp, image, w, h, left, top, right, bottom, bg_pixel);
4214 } else {
4215 DumpXbmNoneHalfToneBody(fp, image, w, h, left, top, right, bottom,
4216 bg_pixel);
4217 }
4218 }
4219
4220 static
GetPixelTrims(w,h,pnLeft,pnTop,pnRight,pnBottom)4221 void GetPixelTrims(w, h, pnLeft, pnTop, pnRight, pnBottom)
4222 int w, h, *pnLeft, *pnTop, *pnRight, *pnBottom;
4223 {
4224 *pnLeft = leftExportPixelTrim;
4225 *pnTop = topExportPixelTrim;
4226 *pnRight = rightExportPixelTrim;
4227 *pnBottom = bottomExportPixelTrim;
4228 if (leftExportPixelTrim+rightExportPixelTrim >= w ||
4229 topExportPixelTrim+bottomExportPixelTrim >= h) {
4230 SetExportPixelTrim(TRUE);
4231 if (leftExportPixelTrim+rightExportPixelTrim >= w ||
4232 topExportPixelTrim+bottomExportPixelTrim >= h) {
4233 sprintf(gszMsgBox, TgLoadString(STID_LARGE_EXP_PXL_TRM_WH_0_USED),
4234 leftExportPixelTrim, topExportPixelTrim, rightExportPixelTrim,
4235 bottomExportPixelTrim, w, h);
4236 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4237 *pnLeft = *pnTop = *pnRight = *pnBottom = 0;
4238 } else {
4239 *pnLeft = leftExportPixelTrim;
4240 *pnTop = topExportPixelTrim;
4241 *pnRight = rightExportPixelTrim;
4242 *pnBottom = bottomExportPixelTrim;
4243 }
4244 }
4245 }
4246
4247 static
BuildXPmColorsFromImage(image,w,h)4248 void BuildXPmColorsFromImage(image, w, h)
4249 XImage *image;
4250 int w, h;
4251 {
4252 int i=0, saved_max_colors=maxColors;
4253
4254 FreeCachedStrings();
4255
4256 maxColors = MAXXPMEXPORTCOLORS;
4257
4258 pixelValue = (int*)malloc((maxColors+3)*sizeof(int));
4259 if (pixelValue == NULL) FailAllocMessage();
4260 colorIndexToDumpIndex = (int*)malloc((maxColors+3)*sizeof(int));
4261 dumpIndexToColorIndex = (int*)malloc((maxColors+3)*sizeof(int));
4262 if (colorIndexToDumpIndex == NULL || dumpIndexToColorIndex == NULL) {
4263 FailAllocMessage();
4264 }
4265 if (maxColors > 20) {
4266 charsPerPixel = 2;
4267 colorChar = (char*)malloc(((maxColors<<1)+6)*sizeof(char));
4268 } else {
4269 charsPerPixel = 1;
4270 colorChar = (char*)malloc((maxColors+3)*sizeof(char));
4271 }
4272 if (colorChar == NULL) FailAllocMessage();
4273 colorStr = (char**)malloc((maxColors+3)*sizeof(char*));
4274 if (colorStr == NULL) FailAllocMessage();
4275 memset(colorStr, 0, (maxColors+3)*sizeof(char*));
4276
4277 for (i = 0; i < maxColors+3; i++) {
4278 colorIndexToDumpIndex[i] = dumpIndexToColorIndex[i] = INVALID;
4279 }
4280 pixelValue[0] = GetDrawingBgPixel(INVALID, INVALID);
4281 if (myFileBgColorStr == NULL) {
4282 colorStr[0] = (char*)malloc((strlen(myBgColorStr)+1)*sizeof(char));
4283 if (colorStr[0] == NULL) FailAllocMessage();
4284 strcpy(colorStr[0], myBgColorStr);
4285 } else {
4286 colorStr[0] = (char*)malloc((strlen(myFileBgColorStr)+1)*sizeof(char));
4287 if (colorStr[0] == NULL) FailAllocMessage();
4288 strcpy(colorStr[0], myFileBgColorStr);
4289 }
4290 numColorsToDump = 1;
4291
4292 if (InitTmpBuckets()) {
4293 SetStringStatus(TgLoadCachedString(CSTID_BLD_COLOR_TBL_FROM_PIXEL_DOTS));
4294 for (i=0; i < h; i++) {
4295 int j=0;
4296
4297 for (j=0; j < w; j++) {
4298 int pixel=XGetPixel(image,j,i);
4299
4300 UpdateColorsLookupTableForPixel(pixel, TRUE);
4301 }
4302 }
4303 CleanUpTmpBuckets();
4304 }
4305 colorChar[0] = '`';
4306 if (charsPerPixel > 1) colorChar[1] = '`';
4307 if (numColorsToDump >= 256) {
4308 for (i=1; i < numColorsToDump; i++) {
4309 if (charsPerPixel == 1) {
4310 colorChar[i] = (char)(((int)('a'))+i-1);
4311 } else {
4312 int left=(int)(i/80), right=(i%80);
4313
4314 if (left >= 31) {
4315 colorChar[i*2] = (char)(((int)('/'))+left-31);
4316 } else {
4317 colorChar[i*2] = (char)(((int)('`'))+left);
4318 }
4319 if (right >= 31) {
4320 colorChar[i*2+1] = (char)(((int)('/'))+right-31);
4321 } else {
4322 colorChar[i*2+1] = (char)(((int)('`'))+right);
4323 }
4324 }
4325 }
4326 } else {
4327 for (i=1; i < numColorsToDump; i++) {
4328 if (charsPerPixel == 1) {
4329 colorChar[i] = (char)(((int)('a'))+i-1);
4330 } else {
4331 colorChar[i*2] = (char)(((int)('a'))+(int)(i/10));
4332 colorChar[i*2+1] = (char)(((int)('0'))+(i%10));
4333 }
4334 }
4335 }
4336 maxColors = saved_max_colors;
4337 }
4338
4339 static
DumpXImageToXpmFile(image,w,h,fname)4340 int DumpXImageToXpmFile(image, w, h, fname)
4341 XImage *image;
4342 int w, h;
4343 char *fname;
4344 {
4345 FILE *fp=fopen(fname, "w");
4346 int bg_pixel=GetDrawingBgPixel(INVALID, INVALID);
4347 int saved_xpm_output_version=xpmOutputVersion;
4348
4349 BuildXPmColorsFromImage(image, w, h);
4350
4351 if (numColorsToDump >= MAXXPMEXPORTCOLORS) {
4352 sprintf(gszMsgBox, TgLoadString(STID_TOO_MANY_COLORS_LIMIT_IS),
4353 numColorsToDump, MAXXPMEXPORTCOLORS);
4354 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4355 return FALSE;
4356 }
4357 if (fp == NULL) {
4358 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
4359 fname);
4360 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4361 return FALSE;
4362 }
4363 if (useXPmVersion1ForImageMap) {
4364 xpmOutputVersion = 1;
4365 }
4366 writeFileFailed = FALSE;
4367
4368 DumpXpmHeader(fp, w, h, TOOL_NAME, 0, 0, 0, 0);
4369
4370 #ifdef NOT_DEFINED
4371 #ifdef _TGIF_DBG
4372 DebugXPmColorsAndExportImage(image, w, h, 0, 0, 0, 0);
4373 #endif /* _TGIF_DBG */
4374 #endif /* NOT_DEFINED */
4375 if (!BuildXPmBuckets(numColorsToDump, pixelValue, dumpIndexToColorIndex,
4376 INVALID, NULL, NULL)) {
4377 fclose(fp);
4378 xpmOutputVersion = saved_xpm_output_version;
4379 return FALSE;
4380 }
4381 if (!DumpXpmBody(fp, image, NULL, w, h, 0, 0, 0, 0, FALSE, bg_pixel)) {
4382 if (!(PRTGIF && cmdLineStdOut &&
4383 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4384 !preDumpSetup)) {
4385 fclose(fp);
4386 }
4387 xpmOutputVersion = saved_xpm_output_version;
4388 return FALSE;
4389 }
4390 fclose(fp);
4391 xpmOutputVersion = saved_xpm_output_version;
4392 if (writeFileFailed) {
4393 return FailAllocPixmapMessage(w, h);
4394 }
4395 return TRUE;
4396 }
4397
DumpXImageToPpmFile(image,w,h,fname,deflate)4398 int DumpXImageToPpmFile(image, w, h, fname, deflate)
4399 XImage *image;
4400 int w, h, deflate;
4401 char *fname;
4402 {
4403 int row=0, col=0;
4404 TrueColorInfo tci;
4405 double dmaxval=(double)255;
4406 unsigned int bytes_per_pixel=image->bits_per_pixel/8;
4407 unsigned char *image_ptr=(unsigned char *)(image->data);
4408 char deflated_fname[MAXPATHLENGTH];
4409 FILE *fp=NULL;
4410 ProgressInfo pi;
4411
4412 *deflated_fname = '\0';
4413 if (!InitTrueColorInfo(image, &tci, w)) {
4414 return FALSE;
4415 }
4416 fp = fopen(fname, "w");
4417 if (fp == NULL) {
4418 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
4419 fname);
4420 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4421 return FALSE;
4422 }
4423 writeFileFailed = FALSE;
4424 if (fprintf(fp, "P6\n%1d %1d\n255\n", w, h) == EOF) writeFileFailed = TRUE;
4425
4426 BeginProgress(&pi, h);
4427 for (row=0; row < h; row++) {
4428 UpdateProgress(&pi, row);
4429 for (col=0; col < w; col++, image_ptr+=bytes_per_pixel) {
4430 uint32_t pixel=0;
4431 unsigned int r=0, g=0, b=0;
4432 double dr=(double)0, dg=(double)0, db=(double)0;
4433 unsigned char buf[3];
4434
4435 memcpy(&pixel, image_ptr, bytes_per_pixel);
4436 r = (pixel & tci.r_mask) >> tci.r_shift;
4437 g = (pixel & tci.g_mask) >> tci.g_shift;
4438 b = (pixel & tci.b_mask) >> tci.b_shift;
4439 dr = ((double)r) * dmaxval / tci.dr_maxval;
4440 dg = ((double)g) * dmaxval / tci.dg_maxval;
4441 db = ((double)b) * dmaxval / tci.db_maxval;
4442 r = round(dr);
4443 g = round(dg);
4444 b = round(db);
4445 buf[0] = (unsigned char)(r&0xff);
4446 buf[1] = (unsigned char)(g&0xff);
4447 buf[2] = (unsigned char)(b&0xff);
4448
4449 if ((int)fwrite(buf, sizeof(char), 3, fp) <= 0) writeFileFailed = TRUE;
4450 }
4451 }
4452 EndProgress(&pi);
4453 fclose(fp);
4454 if (writeFileFailed) {
4455 return FailToWriteFileMessage(fname);
4456 }
4457 if (deflate) {
4458 snprintf(deflated_fname, sizeof(deflated_fname), "%s.ppm.z", fname);
4459 if (!DeflateFile(fname, deflated_fname)) {
4460 unlink(fname);
4461 return FALSE;
4462 }
4463 unlink(fname);
4464 }
4465 return TRUE;
4466 }
4467
4468 static
DumpXImageToPpm6(fp,image,bitmap_image,w,h,left,top,right,bottom)4469 int DumpXImageToPpm6(fp, image, bitmap_image, w, h, left, top, right, bottom)
4470 FILE *fp;
4471 XImage *image, *bitmap_image;
4472 int w, h, left, top, right, bottom;
4473 {
4474 int i=0;
4475 TrueColorInfo tci;
4476 double dmaxval=(double)255;
4477 unsigned int bytes_per_pixel=image->bits_per_pixel/8;
4478 unsigned char *image_ptr=(unsigned char *)(image->data);
4479 ProgressInfo pi;
4480
4481 if (!InitTrueColorInfo(image, &tci, w)) {
4482 return FALSE;
4483 }
4484 if (fprintf(fp, "P6\n%1d %1d\n255\n", w, h) == EOF) writeFileFailed = TRUE;
4485
4486 image_ptr += (bytes_per_pixel*top*w);
4487 BeginProgress(&pi, h-top-bottom);
4488 for (i=top; i < h-bottom; i++, image_ptr+=bytes_per_pixel*right) {
4489 int j=0;
4490
4491 UpdateProgress(&pi, i-top);
4492 for (j=left, image_ptr+=(bytes_per_pixel*left); j < w-right; j++,
4493 image_ptr+=bytes_per_pixel) {
4494 uint32_t pixel=0;
4495 unsigned int r=0, g=0, b=0;
4496 double dr=(double)0, dg=(double)0, db=(double)0;
4497 unsigned char buf[3];
4498
4499 memcpy(&pixel, image_ptr, bytes_per_pixel);
4500 r = (pixel & tci.r_mask) >> tci.r_shift;
4501 g = (pixel & tci.g_mask) >> tci.g_shift;
4502 b = (pixel & tci.b_mask) >> tci.b_shift;
4503 dr = ((double)r) * dmaxval / tci.dr_maxval;
4504 dg = ((double)g) * dmaxval / tci.dg_maxval;
4505 db = ((double)b) * dmaxval / tci.db_maxval;
4506 r = round(dr);
4507 g = round(dg);
4508 b = round(db);
4509 buf[0] = (unsigned char)(r&0xff);
4510 buf[1] = (unsigned char)(g&0xff);
4511 buf[2] = (unsigned char)(b&0xff);
4512
4513 if ((int)fwrite(buf, sizeof(char), 3, fp) <= 0) writeFileFailed = TRUE;
4514 }
4515 }
4516 EndProgress(&pi);
4517
4518 return TRUE;
4519 }
4520
DumpXBitmapFile(nInImageProc,nDumpPpmPreferred,nPageNumInFileName)4521 void DumpXBitmapFile(nInImageProc, nDumpPpmPreferred, nPageNumInFileName)
4522 int nInImageProc, nDumpPpmPreferred, nPageNumInFileName;
4523 { /* called when printing in the xbm or xpm format */
4524 int ltx=0, lty=0, w=0, h=0, short_name=FALSE;
4525 int left=0, top=0, right=0, bottom=0;
4526 int bg_pixel=GetDrawingBgPixel(INVALID, INVALID);
4527 char xbm_file_name[MAXPATHLENGTH<<1], *rest=NULL, name[MAXPATHLENGTH+1];
4528 FILE *fp=NULL;
4529 Pixmap pixmap=None;
4530 XImage *image=NULL, *bitmap_image=NULL;
4531
4532 dumpPpmPreferred = nDumpPpmPreferred;
4533
4534 if (nInImageProc) {
4535 *gszImageProcXPmFile = '\0';
4536 if (MkTempFile(xbm_file_name, sizeof(xbm_file_name), tmpDir,
4537 TOOL_NAME) == NULL) {
4538 return;
4539 }
4540 strcpy(name, "unnamed");
4541 if ((short_name=IsPrefix(bootDir, xbm_file_name, &rest))) ++rest;
4542 } else {
4543 strcpy(name, curFileName);
4544 GetRealBaseName(name);
4545 sprintf(xbm_file_name, "%s%c%s", curDir, DIR_SEP, name);
4546 if (PRTGIF) {
4547 char *tmp_name=(char*)name;
4548
4549 if (whereToPrint == PPM_FILE || dumpPpmPreferred) {
4550 SetOutputFileName(xbm_file_name,
4551 colorDump?"ppm":"pbm", NULL, &tmp_name);
4552 } else {
4553 SetOutputFileName(xbm_file_name,
4554 colorDump?XPM_FILE_EXT:XBM_FILE_EXT, NULL, &tmp_name);
4555 }
4556 } else {
4557 if (whereToPrint == PPM_FILE || dumpPpmPreferred) {
4558 SetOutputFileName(xbm_file_name,
4559 colorDump?"ppm":"pbm", &short_name, &rest);
4560 } else {
4561 SetOutputFileName(xbm_file_name,
4562 colorDump?XPM_FILE_EXT:XBM_FILE_EXT, &short_name, &rest);
4563 }
4564 }
4565 }
4566 if (PRTGIF && cmdLineStdOut &&
4567 !(whereToPrint == EPSI_FILE && generateTiffEPSI) && !preDumpSetup) {
4568 fp = stdout;
4569 } else if ((fp=fopen(xbm_file_name, "w")) == NULL) {
4570 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FOR_WRITE_PRINT),
4571 (short_name ? rest : xbm_file_name));
4572 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4573 return;
4574 }
4575 if (colorDump) InitImageMap();
4576 Msg(TgLoadCachedString(CSTID_GENERATING_IMAGE));
4577
4578 /* if we are print one page per file, don't redraw */
4579 if ((pixmap=DrawAllOnPixmap(<x, <y, &w, &h, !nPageNumInFileName)) ==
4580 None) {
4581 if (!(PRTGIF && cmdLineStdOut &&
4582 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4583 !preDumpSetup)) {
4584 fclose(fp);
4585 unlink(xbm_file_name);
4586 }
4587 return;
4588 }
4589
4590 sprintf(gszMsgBox, TgLoadString(STID_PRINTING_INTO_NAMED_FILE),
4591 (short_name ? rest : xbm_file_name));
4592 Msg(gszMsgBox);
4593
4594 GetPixelTrims(w, h, &left, &top, &right, &bottom);
4595
4596 if ((image=XGetImage(mainDisplay, pixmap, left, top,
4597 w-left-right, h-top-bottom, AllPlanes, ZPixmap)) == NULL) {
4598 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME, INFO_MB);
4599 if (!(PRTGIF && cmdLineStdOut &&
4600 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4601 !preDumpSetup)) {
4602 fclose(fp);
4603 unlink(xbm_file_name);
4604 }
4605 XFreePixmap(mainDisplay, pixmap);
4606 return;
4607 }
4608 if (nInImageProc && topSel != NULL && topSel == botSel &&
4609 topSel->obj->type == OBJ_XPM) {
4610 /* if ((bitmap_image=XGetImage(mainDisplay,
4611 topSel->obj->detail.xpm->bitmap, left, top,
4612 w-left-right, h-top-bottom, 1, ZPixmap)) == NULL) {
4613 Msg("Cannot generate image, print aborted!");
4614 if (!(PRTGIF && cmdLineStdOut &&
4615 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4616 !preDumpSetup)) {
4617 fclose(fp);
4618 unlink(xbm_file_name);
4619 }
4620 XDestroyImage(image);
4621 XFreePixmap(mainDisplay, pixmap);
4622 return;
4623 } */
4624 }
4625 if (left != 0 || top != 0 || right != 0 || bottom != 0) {
4626 sprintf(gszMsgBox, TgLoadString(STID_APPLY_EXP_PXL_TRM_VALS),
4627 left, top, right, bottom);
4628 Msg(gszMsgBox);
4629 }
4630 if (whereToPrint == EPSI_FILE && generateTiffEPSI &&
4631 pageStyle == LANDSCAPE) {
4632 /* for landscape mode TiffEPSI, we need to rotate the image */
4633 XImage *rotated_image=RotateImageForLandscape(image, &w, &h, &left, &top,
4634 &right, &bottom);
4635
4636 if (rotated_image == NULL) {
4637 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME,
4638 INFO_MB);
4639 if (!(PRTGIF && cmdLineStdOut &&
4640 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4641 !preDumpSetup)) {
4642 fclose(fp);
4643 unlink(xbm_file_name);
4644 }
4645 if (bitmap_image != NULL) XDestroyImage(bitmap_image);
4646 XDestroyImage(image);
4647 XFreePixmap(mainDisplay, pixmap);
4648 return;
4649 }
4650 XDestroyImage(image);
4651 image = rotated_image;
4652 }
4653 writeFileFailed = FALSE;
4654 if (colorDump && nInImageProc && gnConvolving) {
4655 #ifdef _TGIF_DBG /* debug, do not translate */
4656 fprintf(stderr,
4657 "Warning (unexpected): gnConvolving is TRUE in DumpXBitmapFile.\n");
4658 #endif /* _TGIF_DBG */
4659 if (!DoConvolution(fp, image, bitmap_image, w, h, NULL)) {
4660 if (!(PRTGIF && cmdLineStdOut &&
4661 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4662 !preDumpSetup)) {
4663 fclose(fp);
4664 unlink(xbm_file_name);
4665 }
4666 if (bitmap_image != NULL) XDestroyImage(bitmap_image);
4667 XDestroyImage(image);
4668 XFreePixmap(mainDisplay, pixmap);
4669 return;
4670 }
4671 } else if (colorDump) {
4672 if (dumpPpmPreferred) {
4673 /* don't do anything here, do it below */
4674 } else {
4675 int saved_xpm_output_version=xpmOutputVersion;
4676
4677 if (whereToPrint==GIF_FILE || whereToPrint==HTML_FILE ||
4678 whereToPrint==PNG_FILE || whereToPrint==JPEG_FILE ||
4679 whereToPrint==PPM_FILE) {
4680 if (useXPmVersion1ForImageMap) {
4681 xpmOutputVersion = 1;
4682 }
4683 }
4684 BuildXPmColors(image, w, h, left, top, right, bottom, FALSE);
4685
4686 if (numColorsToDump >= MAXXPMEXPORTCOLORS) {
4687 sprintf(gszMsgBox, TgLoadString(STID_TOO_MANY_COLORS_LIMIT_IS),
4688 numColorsToDump, MAXXPMEXPORTCOLORS);
4689 if (PRTGIF) {
4690 fprintf(stderr, "%s\n", gszMsgBox);
4691 } else {
4692 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4693 }
4694 if (!(PRTGIF && cmdLineStdOut &&
4695 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4696 !preDumpSetup)) {
4697 fclose(fp);
4698 unlink(xbm_file_name);
4699 }
4700 if (bitmap_image != NULL) XDestroyImage(bitmap_image);
4701 XDestroyImage(image);
4702 XFreePixmap(mainDisplay, pixmap);
4703 return;
4704 }
4705 DumpXpmHeader(fp, w, h, name, left, top, right, bottom);
4706
4707 xpmOutputVersion = saved_xpm_output_version;
4708 }
4709 } else {
4710 DumpXbmHeader(fp, w, h, name, left, top, right, bottom);
4711 }
4712 SaveStatusStrings();
4713 if (colorDump && nInImageProc && gnConvolving) {
4714 } else if (colorDump) {
4715 if (dumpPpmPreferred) {
4716 if (!DumpXImageToPpm6(fp, image, bitmap_image, w, h, left, top,
4717 right, bottom)) {
4718 if (!(PRTGIF && cmdLineStdOut &&
4719 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4720 !preDumpSetup)) {
4721 fclose(fp);
4722 }
4723 if (!(PRTGIF && cmdLineStdOut &&
4724 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4725 !preDumpSetup)) {
4726 unlink(xbm_file_name);
4727 }
4728 if (bitmap_image != NULL) XDestroyImage(bitmap_image);
4729 XDestroyImage(image);
4730 XFreePixmap(mainDisplay, pixmap);
4731
4732 return;
4733 }
4734 } else {
4735 #ifdef NOT_DEFINED
4736 #ifdef _TGIF_DBG
4737 DebugXPmColorsAndExportImage(image, w, h, left, top, right, bottom);
4738 #endif /* _TGIF_DBG */
4739 #endif /* NOT_DEFINED */
4740 if (!BuildXPmBuckets(numColorsToDump, pixelValue,
4741 dumpIndexToColorIndex, INVALID, NULL, NULL)) {
4742 if (!(PRTGIF && cmdLineStdOut && !(whereToPrint == EPSI_FILE &&
4743 generateTiffEPSI) && !preDumpSetup)) {
4744 fclose(fp);
4745 unlink(xbm_file_name);
4746 }
4747 if (bitmap_image != NULL) XDestroyImage(bitmap_image);
4748 XDestroyImage(image);
4749 XFreePixmap(mainDisplay, pixmap);
4750 return;
4751 }
4752 if (!DumpXpmBody(fp, image, bitmap_image, w, h, left, top, right,
4753 bottom, nInImageProc, bg_pixel)) {
4754 if (!(PRTGIF && cmdLineStdOut &&
4755 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4756 !preDumpSetup)) {
4757 fclose(fp);
4758 }
4759 if (!(PRTGIF && cmdLineStdOut &&
4760 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4761 !preDumpSetup)) {
4762 unlink(xbm_file_name);
4763 }
4764 if (bitmap_image != NULL) XDestroyImage(bitmap_image);
4765 XDestroyImage(image);
4766 XFreePixmap(mainDisplay, pixmap);
4767
4768 return;
4769 }
4770 }
4771 } else {
4772 DumpXbmBody(fp, image, w, h, left, top, right, bottom, bg_pixel);
4773 }
4774 RestoreStatusStrings();
4775 if (!(PRTGIF && cmdLineStdOut &&
4776 !(whereToPrint == EPSI_FILE && generateTiffEPSI) && !preDumpSetup)) {
4777 fclose(fp);
4778 }
4779 XDestroyImage(image);
4780 XFreePixmap(mainDisplay, pixmap);
4781
4782 if (writeFileFailed) {
4783 writeFileFailed = FALSE;
4784 FailToWriteFileMessage(xbm_file_name);
4785 } else {
4786 if (whereToPrint == PPM_FILE || dumpPpmPreferred) {
4787 sprintf(gszMsgBox, TgLoadString(STID_FORMAT_FILE_WH_PRINTED_INTO),
4788 (colorDump ? "PPM" : "PBM"), w-left-right, h-top-bottom,
4789 (short_name ? rest : xbm_file_name));
4790 } else {
4791 sprintf(gszMsgBox, TgLoadString(STID_FORMAT_FILE_WH_PRINTED_INTO),
4792 (colorDump ? "XPM" : "XBM"), w-left-right, h-top-bottom,
4793 (short_name ? rest : xbm_file_name));
4794 }
4795 if (PRTGIF && !cmdLineStdOut) {
4796 if (!cmdLineQuiet) {
4797 fprintf(stderr, "%s\n", gszMsgBox);
4798 }
4799 } else {
4800 Msg(gszMsgBox);
4801 }
4802 if (colorDump && (whereToPrint==GIF_FILE || whereToPrint==HTML_FILE ||
4803 whereToPrint==PNG_FILE || whereToPrint==JPEG_FILE ||
4804 (dumpPpmPreferred && whereToPrint==XBM_FILE))) {
4805 int src_is_ppm=dumpPpmPreferred;
4806
4807 SaveStatusStrings();
4808 GenerateImageMap(xbm_file_name, src_is_ppm, ltx+left, lty+top,
4809 ltx+w-right, lty+h-bottom, nPageNumInFileName);
4810 RestoreStatusStrings();
4811 if (!(PRTGIF && cmdLineStdOut &&
4812 !(whereToPrint == EPSI_FILE && generateTiffEPSI) &&
4813 !preDumpSetup)) {
4814 unlink(xbm_file_name);
4815 }
4816 }
4817 }
4818 if (nInImageProc) {
4819 strcpy(gszImageProcXPmFile, xbm_file_name);
4820 if (gnConvolving) {
4821 CleanUpConvolution();
4822 }
4823 }
4824 if (bitmap_image != NULL) XDestroyImage(bitmap_image);
4825 }
4826
DumpXImageToFile(image,w,h,fname,ext)4827 int DumpXImageToFile(image, w, h, fname, ext)
4828 XImage *image;
4829 int w, h;
4830 char *fname, *ext;
4831 {
4832 if (fullTrueColorMode && HasZlibSupport()) {
4833 if (DumpXImageToPpmFile(image, w, h, fname, TRUE)) {
4834 if (ext != NULL) strcpy(ext, ".ppm.z");
4835 return TRUE;
4836 }
4837 }
4838 if (ext != NULL) strcpy(ext, ".xpm");
4839
4840 return DumpXImageToXpmFile(image, w, h, fname);
4841 }
4842
4843 static
FailedExportXPixmapDeckToGIF(count,gif_fp,gif_fname,tmp_fnames)4844 void FailedExportXPixmapDeckToGIF(count, gif_fp, gif_fname, tmp_fnames)
4845 int count;
4846 FILE *gif_fp;
4847 char *gif_fname, *tmp_fnames;
4848 {
4849 if (gif_fp != NULL) fclose(gif_fp);
4850 if (*gif_fname != '\0') unlink(gif_fname);
4851 if (tmp_fnames != NULL) {
4852 int i=0, index=0;
4853
4854 for (i=0, index=0; i < count; i++, index += MAXPATHLENGTH) {
4855 char *psz=NULL;
4856
4857 if (tmp_fnames[index] == '\0') {
4858 break;
4859 }
4860 unlink(&tmp_fnames[index]);
4861 if ((psz=UtilStrRChr(&tmp_fnames[index], '.')) != NULL) {
4862 *psz = '\0';
4863 unlink(&tmp_fnames[index]);
4864 }
4865 }
4866 free(tmp_fnames);
4867 }
4868 }
4869
ExportXPixmapDeckToGIF()4870 void ExportXPixmapDeckToGIF()
4871 {
4872 struct ObjRec *obj_ptr=NULL, *xpm_obj=NULL;
4873 struct ObjRec *saved_top_obj=topObj, *saved_bot_obj=botObj;
4874 int i=0, first_one=TRUE, w=(-1), h=(-1), count=0, index=0, len=0, ok=TRUE;
4875 int short_name=FALSE, bytes_read=0, watch_cursor=watchCursorOnMainWindow;
4876 char *tmp_fnames=NULL, *cmd=NULL, *rest=NULL, gif_fname[MAXPATHLENGTH];
4877 char buf[1024];
4878 FILE *gif_fp=NULL, *pfp=NULL;
4879
4880 if (!curDirIsLocal) {
4881 MsgBox(TgLoadString(STID_CANNOT_PRINT_REMOTE_FILE), TOOL_NAME, INFO_MB);
4882 return;
4883 } else if (!curFileDefined) {
4884 sprintf(gszMsgBox, TgLoadString(STID_NO_CUR_FILE_CANNOT_GEN_FORMAT),
4885 "GIF"),
4886 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4887 return;
4888 }
4889 if (topSel == NULL || topSel != botSel) {
4890 MsgBox(TgLoadString(STID_SEL_XPM_DECK_TO_EXPORT), TOOL_NAME, INFO_MB);
4891 return;
4892 }
4893 obj_ptr = topSel->obj;
4894 if (obj_ptr->type != OBJ_GROUP && obj_ptr->type != OBJ_SYM &&
4895 obj_ptr->type != OBJ_ICON) {
4896 MsgBox(TgLoadString(STID_SEL_XPM_DECK_TO_EXPORT), TOOL_NAME, INFO_MB);
4897 return;
4898 }
4899 for (xpm_obj=obj_ptr->detail.r->first; xpm_obj != NULL;
4900 xpm_obj=xpm_obj->next) {
4901 if (xpm_obj->type == OBJ_XPM) {
4902 if (first_one) {
4903 w = xpm_obj->obbox.rbx-xpm_obj->obbox.ltx;
4904 h = xpm_obj->obbox.rby-xpm_obj->obbox.lty;
4905 first_one = FALSE;
4906 } else {
4907 if (w != xpm_obj->obbox.rbx-xpm_obj->obbox.ltx ||
4908 h != xpm_obj->obbox.rby-xpm_obj->obbox.lty) {
4909 sprintf(gszMsgBox,
4910 TgLoadString(STID_MANY_SZ_FAIL_XPM_DESK_EXPORT), w, h);
4911 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4912 return;
4913 }
4914 }
4915 count++;
4916 }
4917 }
4918 tmp_fnames = (char*)malloc(count*MAXPATHLENGTH*sizeof(char));
4919 if (tmp_fnames == NULL) FailAllocMessage();
4920
4921 curPage->top = curPage->bot = topObj = botObj = NULL;
4922
4923 SaveStatusStrings();
4924 HighLightReverse();
4925 RemoveAllSel();
4926 PushPageInfo();
4927
4928 InitImageMap();
4929
4930 SetWatchCursor(drawWindow);
4931 SetWatchCursor(mainWindow);
4932
4933 len = strlen(xpmDeckToGifAnimCmd)+5;
4934 for (xpm_obj=obj_ptr->detail.r->first; xpm_obj != NULL;
4935 xpm_obj=xpm_obj->next) {
4936 if (xpm_obj->type == OBJ_XPM) {
4937 int saved_colordump=colorDump, saved_wheretoprint=whereToPrint;
4938 int saved_xpm_output_version=xpmOutputVersion;
4939 int dump_ppm_preferred=FALSE;
4940
4941 curPage->top = curPage->bot = topObj = botObj = DupObj(xpm_obj);
4942 topSel = botSel = SelectThisObject(topObj);
4943 UpdSelBBox();
4944
4945 if (useXPmVersion1ForXPmDeck) {
4946 xpmOutputVersion = 1;
4947 }
4948 *gszImageProcXPmFile = '\0';
4949 gnConvolving = FALSE;
4950
4951 colorDump = TRUE;
4952 whereToPrint = XBM_FILE;
4953 gnInImageProc = TRUE;
4954
4955 dump_ppm_preferred = fullTrueColorMode &&
4956 (whereToPrint==XBM_FILE && xpmOutputVersion == 3);
4957 DumpXBitmapFile(gnInImageProc, dump_ppm_preferred, FALSE);
4958
4959 RemoveAllSel();
4960 DelAllObj();
4961 gnInImageProc = FALSE;
4962 whereToPrint = saved_wheretoprint;
4963 colorDump = saved_colordump;
4964 xpmOutputVersion = saved_xpm_output_version;
4965 if (*gszImageProcXPmFile == '\0') {
4966 break;
4967 }
4968 sprintf(&tmp_fnames[index], "%s.gif", gszImageProcXPmFile);
4969 if (!ConvertXpmToGif(gszImageProcXPmFile, &tmp_fnames[index], FALSE,
4970 GIF_FILE)) {
4971 unlink(gszImageProcXPmFile);
4972 break;
4973 }
4974 len += strlen(&tmp_fnames[index])+1;
4975
4976 index += MAXPATHLENGTH;
4977 }
4978 }
4979 SetDefaultCursor(mainWindow);
4980 ShowCursor();
4981
4982 *gif_fname = '\0';
4983 SetOutputFileName(gif_fname, GetExportExt(GIF_FILE), &short_name, &rest);
4984 gif_fp = fopen(gif_fname,"w");
4985 if (gif_fp == NULL) {
4986 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_OPEN_FILE_FOR_WRITING),
4987 ((short_name && *outputDir=='\0') ? rest : gif_fname));
4988 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
4989 FailedExportXPixmapDeckToGIF(count, gif_fp, gif_fname, tmp_fnames);
4990 ok = FALSE;
4991 }
4992 if (ok) {
4993 cmd = (char*)malloc(len+1);
4994 strcpy(cmd, xpmDeckToGifAnimCmd);
4995 len = strlen(cmd);
4996 for (i=0, index=0; i < count; i++, index += MAXPATHLENGTH) {
4997 if (tmp_fnames[index] == '\0') {
4998 break;
4999 }
5000 sprintf(&cmd[len], " %s", &tmp_fnames[index]);
5001 len += strlen(&cmd[len]);
5002 }
5003 if (FindProgramInPath(cmd, NULL, FALSE)) {
5004 sprintf(gszMsgBox, TgLoadCachedString(CSTID_EXECUTING_GIVEN_PROGRAM),
5005 xpmDeckToGifAnimCmd);
5006 SetStringStatus(gszMsgBox);
5007 XSync(mainDisplay, False);
5008 if ((pfp=(FILE*)popen(cmd, "r")) == NULL) {
5009 sprintf(gszMsgBox, TgLoadString(STID_CANNOT_EXEC_FORMAT_NOT_GEN),
5010 cmd, "GIF");
5011 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
5012 FailedExportXPixmapDeckToGIF(count, gif_fp, gif_fname, tmp_fnames);
5013 ok = FALSE;
5014 } else {
5015 if (!watch_cursor) {
5016 SetWatchCursor(drawWindow);
5017 SetWatchCursor(mainWindow);
5018 }
5019 while ((bytes_read=fread(buf, sizeof(char), sizeof(buf), pfp)) >
5020 0) {
5021 if ((int)fwrite(buf, sizeof(char), bytes_read, gif_fp) <= 0) {
5022 writeFileFailed = TRUE;
5023 break;
5024 }
5025 }
5026 pclose(pfp);
5027 if (!watch_cursor) {
5028 SetDefaultCursor(mainWindow);
5029 ShowCursor();
5030 }
5031 fclose(gif_fp);
5032 gif_fp = NULL;
5033 if (writeFileFailed) {
5034 FailToWriteFileMessage(
5035 ((short_name && *outputDir=='\0') ? rest : gif_fname));
5036 FailedExportXPixmapDeckToGIF(count, gif_fp, gif_fname,
5037 tmp_fnames);
5038 ok = FALSE;
5039 }
5040 }
5041 }
5042 }
5043 if (ok) {
5044 /*
5045 * GIF generated, set gif_fname to NULL so that the GIF file
5046 * doesn't get deleted FailedExportXPixmapDeckToGIF()
5047 */
5048 *gif_fname = '\0';
5049 FailedExportXPixmapDeckToGIF(count, gif_fp, gif_fname, tmp_fnames);
5050 }
5051 curPage->top = topObj = saved_top_obj;
5052 curPage->bot = botObj = saved_bot_obj;
5053 PopPageInfo();
5054
5055 RedrawAnArea(botObj, obj_ptr->bbox.ltx-GRID_ABS_SIZE(1),
5056 obj_ptr->bbox.lty-GRID_ABS_SIZE(1),
5057 obj_ptr->bbox.rbx+GRID_ABS_SIZE(1),
5058 obj_ptr->bbox.rby+GRID_ABS_SIZE(1));
5059 topSel = botSel = SelectThisObject(obj_ptr);
5060 UpdSelBBox();
5061 HighLightForward();
5062 RestoreStatusStrings();
5063 }
5064
DumpBitmap(FP,image,data,image_w,image_h,transformed,orig_x,orig_y,adj_x,pmtrx,indent)5065 void DumpBitmap(FP, image, data, image_w, image_h, transformed, orig_x, orig_y,
5066 adj_x, pmtrx, indent)
5067 FILE *FP;
5068 XImage *image;
5069 char *data;
5070 int image_w, image_h, transformed, orig_x, orig_y, adj_x, indent;
5071 struct MtrxRec *pmtrx;
5072 {
5073 register int m;
5074 int row, h_blocks, v_blocks, nibbles_per_row;
5075
5076 h_blocks = ((image_w&0xff) == 0) ? (image_w>>8) : ((image_w>>8)+1);
5077 v_blocks = ((image_h&0xff) == 0) ? (image_h>>8) : ((image_h>>8)+1);
5078 nibbles_per_row = ((image_w%4)==0) ? (int)(image_w>>2) : (int)(image_w>>2)+1;
5079
5080 for (m=0; m < indent; m++) fputc(' ', FP);
5081 fprintf(FP, "%s\n", gPsCmd[PS_GSAVE]);
5082
5083 for (m=0; m < indent; m++) fputc(' ', FP);
5084 if (transformed) {
5085 fprintf(FP, " %1d %1d %s\n", orig_x, orig_y, gPsCmd[PS_TRANSLATE]);
5086 } else {
5087 fprintf(FP, " %1d %1d %s %.3f %.3f %s %1d %s\n\n",
5088 orig_x, orig_y, gPsCmd[PS_TRANSLATE], pmtrx->dump_h_scale,
5089 pmtrx->dump_v_scale, gPsCmd[PS_SCALE], pmtrx->degree,
5090 gPsCmd[PS_ROTATE]);
5091 }
5092
5093 for (row=0; row < v_blocks; row++) {
5094 int y, col, block_h;
5095
5096 y = row<<8;
5097 block_h = (row == v_blocks-1) ? image_h-y : 0x100;
5098
5099 for (col=0; col < h_blocks; col++) {
5100 int i, j, x, num_nibbles, nibble_count, block_w;
5101
5102 x = col<<8;
5103 block_w = (col == h_blocks-1) ? image_w-x : 0x100;
5104
5105 num_nibbles = ((block_w%4) == 0) ? (int)(block_w>>2) :
5106 (int)(block_w>>2)+1;
5107
5108 for (m=0; m < indent; m++) fputc(' ', FP);
5109 fprintf(FP, " %s\n", gPsCmd[PS_GSAVE]);
5110
5111 for (m=0; m < indent; m++) fputc(' ', FP);
5112 fprintf(FP, " %1d %1d %s\n", x+adj_x, y, gPsCmd[PS_TRANSLATE]);
5113
5114 for (m=0; m < indent; m++) fputc(' ', FP);
5115 fprintf(FP, " %1d %1d true [1 0 0 1 0 0]\n", block_w, block_h);
5116
5117 for (m=0; m < indent; m++) fputc(' ', FP);
5118 fprintf(FP, " {<");
5119
5120 if (PRTGIF && !cmdLineOpenDisplay) {
5121 nibble_count = 0;
5122 for (i=0; i < block_h; i++) {
5123 for (j=0; j < num_nibbles; j++) {
5124 if (nibble_count++ == 64) {
5125 nibble_count = 1;
5126 fprintf(FP, "\n");
5127 for (m=0; m < indent; m++) fputc(' ', FP);
5128 fprintf(FP, " ");
5129 }
5130 fprintf(FP, "%c", data[(i+y)*nibbles_per_row+j+(x>>2)]);
5131 }
5132 if ((num_nibbles & 0x1) == 1) {
5133 if (nibble_count++ == 64) {
5134 nibble_count = 1;
5135 fprintf(FP, "\n");
5136 for (m=0; m < indent; m++) fputc(' ', FP);
5137 fprintf(FP, " ");
5138 }
5139 fprintf(FP, "0");
5140 }
5141 }
5142 } else {
5143 nibble_count = 0;
5144 for (i=0; i < block_h; i++) {
5145 int bit_count=0, data;
5146
5147 data = 0;
5148 for (j=0; j < block_w; j++) {
5149 data = (XGetPixel(image, j+x, i+y) == 1) ? (data<<1) | 1 :
5150 (data<<1);
5151 if (++bit_count == 4) {
5152 if (nibble_count++ == 64) {
5153 nibble_count = 1;
5154 fprintf(FP, "\n");
5155 for (m=0; m < indent; m++) fputc(' ', FP);
5156 fprintf(FP, " ");
5157 }
5158 fprintf(FP, "%c", hexValue[data]);
5159 bit_count = 0;
5160 data = 0;
5161 }
5162 }
5163 if ((block_w % 4) != 0) {
5164 data <<= (4 - (block_w % 4));
5165 if (nibble_count++ == 64) {
5166 nibble_count = 1;
5167 fprintf(FP, "\n");
5168 for (m=0; m < indent; m++) fputc(' ', FP);
5169 fprintf(FP, " ");
5170 }
5171 fprintf(FP, "%c", hexValue[data]);
5172 }
5173 if ((num_nibbles & 0x1) == 1) {
5174 if (nibble_count++ == 64) {
5175 nibble_count = 1;
5176 fprintf(FP, "\n");
5177 for (m=0; m < indent; m++) fputc(' ', FP);
5178 fprintf(FP, " ");
5179 }
5180 fprintf(FP, "0");
5181 }
5182 }
5183 }
5184 fprintf(FP, ">}\n");
5185
5186 for (m=0; m < indent; m++) fputc(' ', FP);
5187 fprintf(FP, " %s\n", gPsCmd[PS_IMAGEMASK]);
5188
5189 for (m=0; m < indent; m++) fputc(' ', FP);
5190 fprintf(FP, " %s\n", gPsCmd[PS_GRESTORE]);
5191
5192 if (row!=v_blocks-1 || col!=h_blocks-1) {
5193 fprintf(FP, "\n");
5194 }
5195 }
5196 }
5197 for (m=0; m < indent; m++) fputc(' ', FP);
5198 fprintf(FP, "%s\n", gPsCmd[PS_GRESTORE]);
5199 }
5200
DumpXBmObj(FP,ObjPtr)5201 void DumpXBmObj(FP, ObjPtr)
5202 FILE *FP;
5203 struct ObjRec *ObjPtr;
5204 { /* called when printing in the PostScript format */
5205 int ltx, lty, rbx, rby, w, h, trans_pat, fill, image_w, image_h;
5206 int color_index, flip, orig_x=ObjPtr->x, orig_y=ObjPtr->y;
5207 Pixmap bitmap=None;
5208 XImage *image=NULL;
5209 struct XBmRec *xbm_ptr=ObjPtr->detail.xbm;
5210 struct MtrxRec mtrx;
5211
5212 if (xbm_ptr->real_type == XBM_EPS) {
5213 DumpEPSObj(FP, ObjPtr);
5214 if (preDumpSetup) hasReadHexString = TRUE;
5215 return;
5216 }
5217
5218 if (ObjPtr->ctm == NULL) {
5219 ltx = ObjPtr->obbox.ltx;
5220 lty = ObjPtr->obbox.lty;
5221 rbx = ObjPtr->obbox.rbx;
5222 rby = ObjPtr->obbox.rby;
5223 } else {
5224 ltx = ObjPtr->orig_obbox.ltx;
5225 lty = ObjPtr->orig_obbox.lty;
5226 rbx = ObjPtr->orig_obbox.rbx;
5227 rby = ObjPtr->orig_obbox.rby;
5228 }
5229
5230 trans_pat = ObjPtr->trans_pat;
5231 bitmap = xbm_ptr->bitmap;
5232 fill = xbm_ptr->fill;
5233 flip = xbm_ptr->flip;
5234 image_w = xbm_ptr->image_w;
5235 image_h = xbm_ptr->image_h;
5236
5237 w = rbx - ltx;
5238 h = rby - lty;
5239
5240 if (!(PRTGIF && !cmdLineOpenDisplay)) {
5241 if ((image=xbm_ptr->image) == NULL) {
5242 if ((image=xbm_ptr->image=XGetImage(mainDisplay, bitmap, 0, 0,
5243 image_w, image_h, 1, ZPixmap)) == NULL) {
5244 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME,
5245 INFO_MB);
5246 return;
5247 }
5248 }
5249 }
5250 color_index = ObjPtr->color;
5251
5252 if (ObjPtr->ctm == NULL) {
5253 memset(&mtrx, 0, sizeof(struct MtrxRec));
5254 mtrx.image_w = (float)image_w; mtrx.image_h = (float)image_h;
5255 mtrx.w = (float)w; mtrx.h = (float)h;
5256 mtrx.rotate = ROTATE0; mtrx.flip = flip;
5257
5258 CalcTransform(&mtrx);
5259
5260 orig_x = (mtrx.transformed_w >= 0.0) ? ltx : ltx+w;
5261 orig_y = (mtrx.transformed_h >= 0.0) ? lty : lty+h;
5262 }
5263 fprintf(FP, "%% XBM\n");
5264 if (ObjPtr->ctm != NULL) {
5265 float m[6];
5266
5267 fprintf(FP, "%s\n", gPsCmd[PS_GSAVE]);
5268 m[CTM_SX] = ((float)ObjPtr->ctm->m[CTM_SX])/((float)1000.0);
5269 m[CTM_SY] = ((float)ObjPtr->ctm->m[CTM_SY])/((float)1000.0);
5270 m[CTM_SIN] = ((float)ObjPtr->ctm->m[CTM_SIN])/((float)1000.0);
5271 m[CTM_MSIN] = ((float)ObjPtr->ctm->m[CTM_MSIN])/((float)1000.0);
5272 fprintf(FP, " %1d %1d %s\n", ObjPtr->x, ObjPtr->y,
5273 gPsCmd[PS_TRANSLATE]);
5274 fprintf(FP, " [%.3f %.3f %.3f %.3f %1d %1d] %s\n",
5275 m[CTM_SX], m[CTM_SIN], m[CTM_MSIN], m[CTM_SY],
5276 ObjPtr->ctm->t[CTM_TX], ObjPtr->ctm->t[CTM_TY], gPsCmd[PS_CONCAT]);
5277 fprintf(FP, " %1d %s %1d %s %s\n",
5278 ObjPtr->x, gPsCmd[PS_NEG], ObjPtr->y, gPsCmd[PS_NEG],
5279 gPsCmd[PS_TRANSLATE]);
5280 }
5281 DumpRGBColorLine(FP, color_index, 0, TRUE);
5282
5283 switch (fill) {
5284 case NONEPAT: break;
5285 case SOLIDPAT:
5286 DumpRectPath(FP, ltx, lty, rbx, rby, 0, FALSE);
5287 fprintf(FP, "%s\n", gPsCmd[PS_FILL]);
5288 break;
5289 case BACKPAT:
5290 if (!trans_pat) {
5291 DumpRectPath(FP, ltx, lty, rbx, rby, 0, FALSE);
5292 fprintf(FP, "1 %s %s\n\n", gPsCmd[PS_SETGRAY], gPsCmd[PS_FILL]);
5293 DumpRGBColorLine(FP, color_index, 0, TRUE);
5294 }
5295 break;
5296 default:
5297 /* patterned */
5298 fprintf(FP, "%s\n", gPsCmd[PS_GSAVE]);
5299 if (colorDump || !useGray) {
5300 if (preDumpSetup) PSUseColorPattern();
5301 if (!trans_pat) {
5302 DumpRectPath(FP, ltx, lty, rbx, rby, 3, FALSE);
5303 fprintf(FP, "1 %s %s\n\n", gPsCmd[PS_SETGRAY], gPsCmd[PS_FILL]);
5304 DumpRGBColorLine(FP, color_index, 3, TRUE);
5305 }
5306 DumpRectPath(FP, ltx, lty, rbx, rby, 3, FALSE);
5307 fprintf(FP, "%s %s\n", gPsCmd[PS_EOCLIP], gPsCmd[PS_NEWPATH]);
5308 DumpPatFill(FP, fill, ObjPtr->bbox, 3, TRUE);
5309 } else {
5310 GrayCheck(fill);
5311 fprintf(FP, " %s %s\n", GrayStr(fill), gPsCmd[PS_SETGRAY]);
5312 DumpRectPath(FP, ltx, lty, rbx, rby, 3, FALSE);
5313 fprintf(FP, "%s\n", gPsCmd[PS_FILL]);
5314 }
5315 fprintf(FP, "%s\n", gPsCmd[PS_GRESTORE]);
5316 break;
5317 }
5318 DumpBitmap(FP, image, ObjPtr->detail.xbm->data, image_w, image_h,
5319 (ObjPtr->ctm!=0), orig_x, orig_y, 0, &mtrx, 0);
5320
5321 if (ObjPtr->ctm != NULL) fprintf(FP, "%s\n", gPsCmd[PS_GRESTORE]);
5322 fprintf(FP, "\n");
5323 }
5324
NeedsToCacheXBmObj(ObjPtr)5325 int NeedsToCacheXBmObj(ObjPtr)
5326 struct ObjRec *ObjPtr;
5327 {
5328 register struct XBmRec *xbm_ptr=ObjPtr->detail.xbm;
5329 int w, h;
5330
5331 w = ObjPtr->obbox.rbx - ObjPtr->obbox.ltx;
5332 h = ObjPtr->obbox.rby - ObjPtr->obbox.lty;
5333
5334 return (ObjPtr->ctm != NULL || zoomScale != 0 ||
5335 xbm_ptr->image_w != w || xbm_ptr->image_h != h || xbm_ptr->flip != 0
5336 );
5337 }
5338
5339 static
DrawHiddenXBm(win,ctm,vs,x,y,w,h,s)5340 void DrawHiddenXBm(win, ctm, vs, x, y, w, h, s)
5341 Window win;
5342 struct XfrmMtrxRec *ctm;
5343 XPoint *vs;
5344 int x, y, w, h;
5345 char *s;
5346 {
5347 int str_w, len, sx, sy;
5348 XGCValues values;
5349
5350 values.foreground = GetDrawingFgPixel(INVALID, INVALID);
5351 values.function = GXcopy;;
5352 values.fill_style = FillSolid;
5353 #ifdef NO_THIN_LINE
5354 values.line_width = 1;
5355 #else
5356 values.line_width = 0;
5357 #endif
5358 values.font = rulerFontPtr->fid;
5359 values.line_style = LineSolid;
5360
5361 XChangeGC(mainDisplay, drawGC,
5362 GCForeground | GCFunction | GCFillStyle | GCLineWidth | GCFont |
5363 GCLineStyle, &values);
5364 if (ctm != NULL) {
5365 XDrawLines(mainDisplay, win, drawGC, vs, 5, CoordModeOrigin);
5366 } else {
5367 XDrawRectangle(mainDisplay, win, drawGC, x, y, w, h);
5368 }
5369
5370 len = strlen(s);
5371 str_w = rulerFontWidth*len;
5372 if (str_w < w && rulerFontHeight < h) {
5373 sx = x + ((w-str_w)>>1);
5374 sy = y + ((h-rulerFontHeight)>>1);
5375 XDrawString(mainDisplay, win, drawGC, sx, sy+rulerFontAsc, s, len);
5376 }
5377 XSetFont(mainDisplay, drawGC, canvasFontPtr->fid);
5378 }
5379
DrawXBmObj(win,XOff,YOff,ObjPtr)5380 void DrawXBmObj(win, XOff, YOff, ObjPtr)
5381 Window win;
5382 int XOff, YOff;
5383 struct ObjRec *ObjPtr;
5384 {
5385 int ltx, lty, rbx, rby, w, h, scr_w, scr_h, fill, trans_pat;
5386 int real_x_off, real_y_off;
5387 char s[80];
5388 struct XBmRec *xbm_ptr=ObjPtr->detail.xbm;
5389 XGCValues values;
5390
5391 if (userDisableRedraw) return;
5392
5393 if (ObjPtr->prev != NULL && ObjPtr->prev->type == OBJ_XBM &&
5394 ObjPtr->prev->detail.xbm->real_type == XBM_XBM &&
5395 ObjPtr->prev->detail.xbm->fill != NONEPAT &&
5396 Inside(ObjPtr->obbox, ObjPtr->prev->obbox)) {
5397 return;
5398 }
5399 trans_pat = ObjPtr->trans_pat;
5400 fill = xbm_ptr->fill;
5401
5402 w = ObjPtr->obbox.rbx - ObjPtr->obbox.ltx;
5403 h = ObjPtr->obbox.rby - ObjPtr->obbox.lty;
5404
5405 real_x_off = (zoomedIn ? XOff : (XOff>>zoomScale)<<zoomScale);
5406 real_y_off = (zoomedIn ? YOff : (YOff>>zoomScale)<<zoomScale);
5407 ltx = ZOOMED_SIZE(ObjPtr->obbox.ltx - real_x_off);
5408 lty = ZOOMED_SIZE(ObjPtr->obbox.lty - real_y_off);
5409 rbx = ZOOMED_SIZE(ObjPtr->obbox.rbx - real_x_off);
5410 rby = ZOOMED_SIZE(ObjPtr->obbox.rby - real_y_off);
5411 scr_w = rbx - ltx;
5412 scr_h = rby - lty;
5413
5414 if (xbm_ptr->real_type==XBM_XBM && fill != NONEPAT) {
5415 values.foreground = GetDrawingBgPixel(fill, colorPixels[ObjPtr->color]);
5416 values.function = GXcopy;
5417 values.fill_style = (trans_pat ? FillStippled : FillOpaqueStippled);
5418 values.stipple = patPixmap[fill];
5419 XChangeGC(mainDisplay, drawGC,
5420 GCForeground | GCFunction | GCFillStyle | GCStipple, &values);
5421 if (ObjPtr->ctm != NULL) {
5422 XFillPolygon(mainDisplay, win, drawGC, ObjPtr->rotated_obbox, 5,
5423 Convex, CoordModeOrigin);
5424 } else {
5425 XFillRectangle(mainDisplay, win, drawGC, ltx, lty, scr_w, scr_h);
5426 }
5427 }
5428 if (!mapShown) {
5429 if (xbm_ptr->real_type == XBM_EPS) {
5430 DrawHiddenXBm(win, ObjPtr->ctm, ObjPtr->rotated_obbox,
5431 ltx, lty, scr_w, scr_h, xbm_ptr->filename);
5432 } else {
5433 sprintf(s, "(%1dx%1d)", xbm_ptr->image_w, xbm_ptr->image_h);
5434 DrawHiddenXBm(win, ObjPtr->ctm, ObjPtr->rotated_obbox,
5435 ltx, lty, scr_w, scr_h, s);
5436 }
5437 return;
5438 }
5439 if (NeedsToCacheXBmObj(ObjPtr) && xbm_ptr->cached_bitmap == None) {
5440 MakeCachedBitmap(ObjPtr);
5441 }
5442 if (xbm_ptr->real_type==XBM_XBM || (xbm_ptr->real_type==XBM_EPS &&
5443 xbm_ptr->bitmap!=None)) {
5444 values.foreground = colorPixels[ObjPtr->color];
5445 values.function = GXcopy;
5446 values.fill_style = FillStippled;
5447 values.ts_x_origin = ltx;
5448 values.ts_y_origin = lty;
5449
5450 if (ObjPtr->ctm==NULL && zoomScale==0 &&
5451 xbm_ptr->flip==0 && xbm_ptr->image_w==w && xbm_ptr->image_h==h) {
5452 values.stipple = xbm_ptr->bitmap;
5453 } else {
5454 if (xbm_ptr->cached_bitmap == None) return;
5455 values.stipple = xbm_ptr->cached_bitmap;
5456 }
5457
5458 XChangeGC(mainDisplay, drawGC,
5459 GCForeground | GCFunction | GCFillStyle | GCStipple |
5460 GCTileStipXOrigin | GCTileStipYOrigin, &values);
5461 XFillRectangle(mainDisplay, win, drawGC, ltx, lty, scr_w, scr_h);
5462 XSetTSOrigin(mainDisplay, drawGC, 0, 0);
5463 } else if (xbm_ptr->real_type==XBM_EPS && xbm_ptr->bitmap==None) {
5464 DrawHiddenXBm(win, ObjPtr->ctm, ObjPtr->rotated_obbox,
5465 ltx, lty, rbx-ltx, rby-lty, xbm_ptr->filename);
5466 }
5467 }
5468
CreateXBmObj(ImageW,ImageH,W,H,bitmap,image)5469 struct ObjRec *CreateXBmObj(ImageW, ImageH, W, H, bitmap, image)
5470 int ImageW, ImageH, W, H;
5471 Pixmap bitmap;
5472 XImage *image;
5473 {
5474 struct XBmRec *xbm_ptr;
5475 struct ObjRec *obj_ptr;
5476
5477 xbm_ptr = (struct XBmRec *)malloc(sizeof(struct XBmRec));
5478 if (xbm_ptr == NULL) FailAllocMessage();
5479 memset(xbm_ptr, 0, sizeof(struct XBmRec));
5480
5481 xbm_ptr->image = image;
5482 xbm_ptr->image_w = ImageW;
5483 xbm_ptr->image_h = ImageH;
5484 xbm_ptr->bitmap = bitmap;
5485 xbm_ptr->data = NULL;
5486
5487 xbm_ptr->eps_w = xbm_ptr->eps_h = 0;
5488
5489 xbm_ptr->fill = objFill;
5490 xbm_ptr->flip = xbm_ptr->cached_flip = 0;
5491 xbm_ptr->cached_zoom = 0;
5492 xbm_ptr->cached_bitmap = None;
5493 xbm_ptr->cached_w = xbm_ptr->cached_h = 0;
5494
5495 xbm_ptr->real_type = XBM_XBM;
5496 xbm_ptr->filename = NULL;
5497 xbm_ptr->epsflines = NULL;
5498 xbm_ptr->num_epsf_lines = 0;
5499
5500 obj_ptr = (struct ObjRec *)malloc(sizeof(struct ObjRec));
5501 if (obj_ptr == NULL) FailAllocMessage();
5502 memset(obj_ptr, 0, sizeof(struct ObjRec));
5503
5504 obj_ptr->bbox.ltx = obj_ptr->obbox.ltx = obj_ptr->x = drawOrigX;
5505 obj_ptr->bbox.lty = obj_ptr->obbox.lty = obj_ptr->y = drawOrigY;
5506 obj_ptr->bbox.rbx = obj_ptr->obbox.rbx = W + drawOrigX;
5507 obj_ptr->bbox.rby = obj_ptr->obbox.rby = H + drawOrigY;
5508 obj_ptr->type = OBJ_XBM;
5509 obj_ptr->color = colorIndex;
5510 if (mainDisplay != NULL) {
5511 UtilStrCpyN(obj_ptr->color_str, sizeof(obj_ptr->color_str),
5512 colorMenuItems[colorIndex]);
5513 }
5514 obj_ptr->id = objId++;
5515 obj_ptr->dirty = FALSE;
5516 obj_ptr->rotation = 0;
5517 obj_ptr->locked = FALSE;
5518 obj_ptr->detail.xbm = xbm_ptr;
5519 obj_ptr->fattr = obj_ptr->lattr = NULL;
5520 obj_ptr->ctm = NULL;
5521 obj_ptr->invisible = FALSE;
5522 obj_ptr->trans_pat = transPat;
5523
5524 if (importXBmRV) InvertXBmObject(obj_ptr);
5525 return (obj_ptr);
5526 }
5527
5528 static
CopyXBmProperties(DestXbmObj,SrcXbmObj)5529 void CopyXBmProperties(DestXbmObj, SrcXbmObj)
5530 struct ObjRec *DestXbmObj, *SrcXbmObj;
5531 {
5532 struct XBmRec *dest_xbm_ptr=DestXbmObj->detail.xbm;
5533 struct XBmRec *src_xbm_ptr=SrcXbmObj->detail.xbm;
5534
5535 dest_xbm_ptr->fill = src_xbm_ptr->fill;
5536 DestXbmObj->color = SrcXbmObj->color;
5537 memcpy(DestXbmObj->color_str, SrcXbmObj->color_str,
5538 sizeof(DestXbmObj->color_str));
5539 DestXbmObj->trans_pat = SrcXbmObj->trans_pat;
5540 }
5541
5542 static
FinishBreakUpXBitmap(obj_ptr,cols_and_rows,cols,rows)5543 int FinishBreakUpXBitmap(obj_ptr, cols_and_rows, cols, rows)
5544 struct ObjRec *obj_ptr;
5545 int cols_and_rows, cols, rows;
5546 {
5547 struct XBmRec *xbm_ptr=obj_ptr->detail.xbm;
5548 int y, image_w=xbm_ptr->image_w, image_h=xbm_ptr->image_h;
5549 int chunk_w=0, chunk_h=0, total_chunks=0;
5550 int orig_x=obj_ptr->x, orig_y=obj_ptr->y;
5551
5552 if (cols_and_rows) {
5553 chunk_w = (int)(image_w / cols);
5554 chunk_h = (int)(image_h / rows);
5555 } else {
5556 chunk_w = cols;
5557 chunk_h = rows;
5558 }
5559 for (y=0; y < image_h; y += chunk_h) {
5560 int h=min(image_h-y,chunk_h), x;
5561
5562 for (x=0; x < image_w; x += chunk_w) {
5563 int w=min(image_w-x,chunk_w);
5564 struct ObjRec *new_obj_ptr;
5565 Pixmap dest_bitmap=None;
5566 XImage *dest_image=NULL;
5567
5568 if (w <= 0 || h <= 0 ||
5569 !ExtractBitmap(xbm_ptr->bitmap, xbm_ptr->image, x, y, w, h,
5570 &dest_bitmap, &dest_image)) {
5571 continue;
5572 }
5573 total_chunks++;
5574 new_obj_ptr = CreateXBmObj(w, h, w, h, dest_bitmap, dest_image);
5575 CopyXBmProperties(new_obj_ptr, obj_ptr);
5576 AdjObjBBox(new_obj_ptr);
5577 MoveObj(new_obj_ptr, orig_x+x, orig_y+y);
5578 AddObj(NULL, topObj, new_obj_ptr);
5579 }
5580 }
5581 if (total_chunks > 0) {
5582 int i;
5583
5584 RemoveAllSel();
5585 UnlinkObj(obj_ptr);
5586 FreeObj(obj_ptr);
5587
5588 for (i=0, obj_ptr=topObj; obj_ptr != NULL && i < total_chunks; i++,
5589 obj_ptr=obj_ptr->next) {
5590 AddObjIntoSel(obj_ptr, botSel, NULL, &topSel, &botSel);
5591 }
5592 }
5593 return (total_chunks > 0);
5594 }
5595
BreakUpXBitmap(obj_ptr,cols_and_rows,cols,rows)5596 void BreakUpXBitmap(obj_ptr, cols_and_rows, cols, rows)
5597 struct ObjRec *obj_ptr;
5598 int cols_and_rows, cols, rows;
5599 {
5600 struct XBmRec *xbm_ptr=obj_ptr->detail.xbm;
5601
5602 if (xbm_ptr->real_type == XBM_EPS) {
5603 MsgBox(TgLoadString(STID_CANNOT_BREAKUP_EPS), TOOL_NAME, INFO_MB);
5604 return;
5605 }
5606 HighLightReverse();
5607 PrepareToReplaceAnObj(obj_ptr);
5608 if (FinishBreakUpXBitmap(obj_ptr, cols_and_rows, cols, rows)) {
5609 UpdSelBBox();
5610 RecordCmd(CMD_ONE_TO_MANY, NULL, topSel, botSel, numObjSelected);
5611 SetFileModified(TRUE);
5612 justDupped = FALSE;
5613 } else {
5614 AbortPrepareCmd(CMD_REPLACE);
5615 }
5616 HighLightForward();
5617 }
5618
DumpXBmData(FP,bitmap,image,W,H)5619 void DumpXBmData(FP, bitmap, image, W, H)
5620 FILE *FP;
5621 Pixmap bitmap;
5622 XImage **image;
5623 int W, H;
5624 {
5625 register int nibble_count, bit_count, data, i, j;
5626
5627 if (*image == NULL) {
5628 if ((*image=XGetImage(mainDisplay,bitmap,0,0,W,H,1,ZPixmap)) == NULL) {
5629 MsgBox(TgLoadString(STID_XGETIMAGE_MAY_RUN_OUT_VMEM), TOOL_NAME,
5630 INFO_MB);
5631 return;
5632 }
5633 }
5634
5635 nibble_count = 0;
5636
5637 for (i=0; i < H; i++) {
5638 bit_count = 0;
5639 data = 0;
5640
5641 for (j=0; j < W; j++) {
5642 data = (XGetPixel(*image, j, i) == 1) ? (data<<1) | 1 : (data<<1);
5643
5644 if (++bit_count == 4) {
5645 if (nibble_count++ == 64) {
5646 nibble_count = 1;
5647 if (fprintf(FP, "\n ") == EOF) writeFileFailed = TRUE;
5648 }
5649 if (fprintf(FP, "%c", hexValue[data]) == EOF) {
5650 writeFileFailed = TRUE;
5651 }
5652 bit_count = 0;
5653 data = 0;
5654 }
5655 }
5656 if ((W % 4) != 0) {
5657 data <<= (4 - (W % 4));
5658 if (nibble_count++ == 64) {
5659 nibble_count = 1;
5660 if (fprintf(FP, "\n ") == EOF) writeFileFailed = TRUE;
5661 }
5662 if (fprintf(FP, "%c", hexValue[data]) == EOF) writeFileFailed = TRUE;
5663 }
5664 }
5665 }
5666
SaveXBmObj(FP,ObjPtr)5667 void SaveXBmObj(FP, ObjPtr)
5668 FILE *FP;
5669 struct ObjRec *ObjPtr;
5670 {
5671 register int i;
5672 int ltx, lty, rbx, rby, image_w, image_h;
5673 int no_bitmap, compressed=FALSE;
5674 struct XBmRec *xbm_ptr=ObjPtr->detail.xbm;
5675
5676 no_bitmap = (xbm_ptr->real_type==XBM_EPS &&
5677 !(xbm_ptr->save_epsf && xbm_ptr->bitmap != None));
5678
5679 ltx = ObjPtr->obbox.ltx; lty = ObjPtr->obbox.lty;
5680 rbx = ObjPtr->obbox.rbx; rby = ObjPtr->obbox.rby;
5681 if (no_bitmap) {
5682 image_w = xbm_ptr->eps_w;
5683 image_h = xbm_ptr->eps_h;
5684 } else {
5685 image_w = xbm_ptr->image_w;
5686 image_h = xbm_ptr->image_h;
5687 }
5688 if (fprintf(FP, "xbm('%s','',", colorMenuItems[ObjPtr->color]) == EOF) {
5689 writeFileFailed = TRUE;
5690 }
5691 if (fprintf(FP,
5692 "%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,%1d,0,%1d,%1d,%1d,%1d,%1d,%1d,",
5693 ltx, lty, rbx, rby, xbm_ptr->fill, ObjPtr->id, ObjPtr->rotation,
5694 image_w, image_h, xbm_ptr->flip, xbm_ptr->real_type,
5695 xbm_ptr->llx, xbm_ptr->lly, xbm_ptr->urx, xbm_ptr->ury) == EOF) {
5696 writeFileFailed = TRUE;
5697 }
5698 if (fprintf(FP,
5699 "%1d,%1d,%1d,%1d,%1d,%1d,%1d,\n ",
5700 no_bitmap, ObjPtr->locked, xbm_ptr->save_epsf, compressed,
5701 ObjPtr->ctm!=NULL, ObjPtr->invisible, ObjPtr->trans_pat) == EOF) {
5702 writeFileFailed = TRUE;
5703 }
5704 switch (xbm_ptr->real_type) {
5705 case XBM_XBM:
5706 if (fprintf(FP, "\"\",\"\",") == EOF) writeFileFailed = TRUE;
5707 break;
5708 case XBM_EPS:
5709 if (fprintf(FP, "\"%s\",\"%s\",", xbm_ptr->write_date,
5710 xbm_ptr->filename) == EOF) {
5711 writeFileFailed = TRUE;
5712 }
5713 break;
5714 }
5715 if (xbm_ptr->save_epsf) {
5716 if (fprintf(FP, "%1d,[", xbm_ptr->num_epsf_lines) == EOF) {
5717 writeFileFailed = TRUE;
5718 }
5719 for (i = 0; i < xbm_ptr->num_epsf_lines; i++) {
5720 if (fprintf(FP, "\n \"%s\"%s,", xbm_ptr->epsflines[i],
5721 (i==xbm_ptr->num_epsf_lines-1 ? "]" : "")) == EOF) {
5722 writeFileFailed = TRUE;
5723 }
5724 }
5725 }
5726 if (!no_bitmap) {
5727 if (fprintf(FP, "\n \"") == EOF) writeFileFailed = TRUE;
5728 DumpXBmData(FP, xbm_ptr->bitmap, &(xbm_ptr->image), image_w, image_h);
5729 if (fprintf(FP, "\",") == EOF) writeFileFailed = TRUE;
5730 }
5731 if (ObjPtr->ctm != NULL && fprintf(FP,
5732 "[\n %1d,%1d,%1d,%1d,%1d,%1d,%g,%g,%g,%g,%1d,%1d],",
5733 ObjPtr->x, ObjPtr->y,
5734 ObjPtr->orig_obbox.ltx, ObjPtr->orig_obbox.lty,
5735 ObjPtr->orig_obbox.rbx, ObjPtr->orig_obbox.rby,
5736 ObjPtr->ctm->m[CTM_SX], ObjPtr->ctm->m[CTM_SIN],
5737 ObjPtr->ctm->m[CTM_MSIN], ObjPtr->ctm->m[CTM_SY],
5738 ObjPtr->ctm->t[CTM_TX], ObjPtr->ctm->t[CTM_TY]) == EOF) {
5739 writeFileFailed = TRUE;
5740 }
5741 if (serializingFile) SaveCreatorID(FP, ObjPtr, " ");
5742 SaveAttrs(FP, ObjPtr->lattr);
5743 if (fprintf(FP, ")") == EOF) writeFileFailed = TRUE;
5744 }
5745
5746 static
ReadTransformAndAdjustForXBm(FP,ObjPtr,xbm_ptr,transformed,rotate,flip)5747 int ReadTransformAndAdjustForXBm(FP, ObjPtr, xbm_ptr, transformed, rotate, flip)
5748 FILE *FP;
5749 struct ObjRec **ObjPtr;
5750 struct XBmRec *xbm_ptr;
5751 int transformed, rotate, flip;
5752 {
5753 if (fileVersion >= 33 && transformed) {
5754 char inbuf[MAXSTRING];
5755 struct XfrmMtrxRec *ctm=NULL;
5756 int real_x=0, real_y=0;
5757 struct BBRec orig_obbox;
5758
5759 (void)fgets(inbuf, MAXSTRING, FP);
5760 scanLineNum++;
5761 InitScan(inbuf, "\t\n, ");
5762
5763 ctm = (struct XfrmMtrxRec *)malloc(sizeof(struct XfrmMtrxRec));
5764 if (ctm == NULL) FailAllocMessage();
5765 if (GETINT("xbitmap", real_x, "real_x") == INVALID ||
5766 GETINT("xbitmap", real_y, "real_y") == INVALID ||
5767 GETINT("xbitmap", orig_obbox.ltx, "orig_obbox.ltx") == INVALID ||
5768 GETINT("xbitmap", orig_obbox.lty, "orig_obbox.lty") == INVALID ||
5769 GETINT("xbitmap", orig_obbox.rbx, "orig_obbox.rbx") == INVALID ||
5770 GETINT("xbitmap", orig_obbox.rby, "orig_obbox.rby") == INVALID ||
5771 GETDBL("xbitmap", ctm->m[CTM_SX], "CTM_SX") == INVALID ||
5772 GETDBL("xbitmap", ctm->m[CTM_SIN], "CTM_SIN") == INVALID ||
5773 GETDBL("xbitmap", ctm->m[CTM_MSIN], "CTM_MSIN") == INVALID ||
5774 GETDBL("xbitmap", ctm->m[CTM_SY], "CTM_SY") == INVALID ||
5775 GETINT("xbitmap", ctm->t[CTM_TX], "CTM_TX") == INVALID ||
5776 GETINT("xbitmap", ctm->t[CTM_TY], "CTM_TY") == INVALID) {
5777 return FALSE;
5778 }
5779 (*ObjPtr)->ctm = ctm;
5780 if (ctm != NULL) {
5781 memcpy(&(*ObjPtr)->orig_obbox, &orig_obbox, sizeof(struct BBRec));
5782 (*ObjPtr)->x = real_x;
5783 (*ObjPtr)->y = real_y;
5784 GetTransformedOBBoxOffsetVs(*ObjPtr, (*ObjPtr)->rotated_obbox);
5785 }
5786 }
5787 if (fileVersion < 33 && (rotate != ROTATE0 || flip != NO_FLIP)) {
5788 int ltx, lty, rbx, rby;
5789 double dz=(double)0, d1=(double)1000.0, dm1=((double)-1000.0);
5790
5791 if (rotate == ROTATE90 || rotate == ROTATE270) {
5792 int h=(*ObjPtr)->obbox.rbx-(*ObjPtr)->obbox.ltx;
5793 int w=(*ObjPtr)->obbox.rby-(*ObjPtr)->obbox.lty;
5794
5795 (*ObjPtr)->obbox.rby = (*ObjPtr)->obbox.lty + h;
5796 (*ObjPtr)->obbox.rbx = (*ObjPtr)->obbox.ltx + w;
5797 }
5798 ltx = ((*ObjPtr)->obbox.ltx); lty = ((*ObjPtr)->obbox.lty);
5799 rbx = ((*ObjPtr)->obbox.rbx); rby = ((*ObjPtr)->obbox.rby);
5800 SetRotatePivotByObject(*ObjPtr);
5801
5802 if ((*ObjPtr)->ctm == NULL) {
5803 int image_w=0, image_h=0;
5804
5805 if (xbm_ptr->bitmap == None) {
5806 image_w = xbm_ptr->eps_w;
5807 image_h = xbm_ptr->eps_h;
5808 } else {
5809 image_w = xbm_ptr->image_w;
5810 image_h = xbm_ptr->image_h;
5811 }
5812 if (image_w != rbx-ltx || image_h != rby-lty) {
5813 float fval=(float)0;
5814 double dx_scale=(double)0, dy_scale=(double)0;
5815 struct XfrmMtrxRec ctm;
5816
5817 memset(&ctm, 0, sizeof(struct XfrmMtrxRec));
5818 fval = ((float)(rbx-ltx))/((float)image_w)*((float)1000.0);
5819 dx_scale = (double)fval;
5820 fval = ((float)(rby-lty))/((float)image_h)*((float)1000.0);
5821 dy_scale = (double)fval;
5822 (*ObjPtr)->obbox.rbx = ltx+image_w;
5823 (*ObjPtr)->obbox.rby = lty+image_h;
5824 ShearObj(*ObjPtr, CORNER_RB, dz, dz, dx_scale, dy_scale,
5825 NULL, NULL);
5826 }
5827 }
5828 if (flip & HORI_EVEN) {
5829 ShearObj(*ObjPtr, CORNER_LEFT, dz, dz, dm1, d1,
5830 <x, <y);
5831 }
5832 if (flip & VERT_EVEN) {
5833 ShearObj(*ObjPtr, CORNER_TOP, dz, dz, d1, dm1,
5834 <x, <y);
5835 }
5836 if (rotate == ROTATE0) {
5837 if (flip & (HORI_ODD | VERT_ODD)) {
5838 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
5839 if (flip & HORI_ODD) {
5840 ShearObj(*ObjPtr, CORNER_LEFT, dz, dz, dm1, d1,
5841 <x, <y);
5842 }
5843 if (flip & VERT_ODD) {
5844 ShearObj(*ObjPtr, CORNER_TOP, dz, dz, d1, dm1,
5845 <x, <y);
5846 }
5847 RotateObj(*ObjPtr, CORNER_LT, COUNTER90, <x, <y);
5848 }
5849 } else {
5850 switch (rotate) {
5851 case ROTATE90:
5852 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
5853 if (flip & HORI_ODD) {
5854 ShearObj(*ObjPtr, CORNER_LEFT, dz, dz, dm1, d1,
5855 <x, <y);
5856 }
5857 if (flip & VERT_ODD) {
5858 ShearObj(*ObjPtr, CORNER_TOP, dz, dz, d1, dm1,
5859 <x, <y);
5860 }
5861 break;
5862 case ROTATE180:
5863 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
5864 if (flip & HORI_ODD) {
5865 ShearObj(*ObjPtr, CORNER_LEFT, dz, dz, dm1, d1,
5866 <x, <y);
5867 }
5868 if (flip & VERT_ODD) {
5869 ShearObj(*ObjPtr, CORNER_TOP, dz, dz, d1, dm1,
5870 <x, <y);
5871 }
5872 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
5873 break;
5874 case ROTATE270:
5875 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
5876 if (flip & HORI_ODD) {
5877 ShearObj(*ObjPtr, CORNER_LEFT, dz, dz, dm1, d1,
5878 <x, <y);
5879 }
5880 if (flip & VERT_ODD) {
5881 ShearObj(*ObjPtr, CORNER_TOP, dz, dz, d1, dm1,
5882 <x, <y);
5883 }
5884 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
5885 RotateObj(*ObjPtr, CORNER_LT, CLOCKWISE90, <x, <y);
5886 break;
5887 }
5888 }
5889 xbm_ptr->flip = NO_FLIP;
5890 }
5891 return TRUE;
5892 }
5893
ReadXBmObj(FP,Inbuf,ObjPtr)5894 void ReadXBmObj(FP, Inbuf, ObjPtr)
5895 FILE *FP;
5896 char *Inbuf;
5897 struct ObjRec **ObjPtr;
5898 {
5899 struct XBmRec *xbm_ptr=NULL;
5900 char color_str[40], bg_color_str[40], *s, inbuf[MAXSTRING], *c_ptr;
5901 int ltx, lty, rbx, rby, i, j, k, data=0, color_index;
5902 int nibble_count, bit_count, num_nibbles, fill, trans_pat=FALSE;
5903 int rotation=0, new_alloc, id=0, image_w=0, image_h=0;
5904 int rotate=ROTATE0, flip=NO_FLIP, real_type=XBM_XBM, len;
5905 int no_bitmap=FALSE, llx=0, lly=0, urx=0, ury=0;
5906 int locked=FALSE, save_epsf=FALSE, compressed=FALSE;
5907 int num_epsf_lines=0, transform_read=FALSE;
5908 int transformed=FALSE, invisible=FALSE;
5909 Pixmap bitmap;
5910 char **epsflines=NULL;
5911 char *xbm_data, write_date[32], *filename;
5912 XImage *image;
5913
5914 *ObjPtr = NULL;
5915
5916 s = FindChar((int)'(', Inbuf);
5917 s = ParseStr(s, (int)',', color_str, sizeof(color_str));
5918 if (fileVersion >= 37) {
5919 s = ParseStr(s, (int)',', bg_color_str, sizeof(bg_color_str));
5920 }
5921 InitScan(s, "\t\n, ");
5922
5923 if (fileVersion <= 8) {
5924 sprintf(inbuf, TgLoadCachedString(CSTID_INVALID_FILEVER_FOR_XBM),
5925 fileVersion);
5926 if (PRTGIF) {
5927 fprintf(stderr, "%s\n", inbuf);
5928 } else {
5929 Msg(inbuf);
5930 }
5931 return;
5932 } else if (fileVersion <= 13) {
5933 if (GETINT("xbitmap", ltx, "ltx") == INVALID ||
5934 GETINT("xbitmap", lty, "lty") == INVALID ||
5935 GETINT("xbitmap", rbx, "rbx") == INVALID ||
5936 GETINT("xbitmap", rby, "rby") == INVALID ||
5937 GETINT("xbitmap", fill, "fill") == INVALID ||
5938 GETINT("xbitmap", id, "id") == INVALID) {
5939 return;
5940 }
5941 if (id >= objId) objId = id+1;
5942 } else if (fileVersion <= 22) {
5943 if (GETINT("xbitmap", ltx, "ltx") == INVALID ||
5944 GETINT("xbitmap", lty, "lty") == INVALID ||
5945 GETINT("xbitmap", rbx, "rbx") == INVALID ||
5946 GETINT("xbitmap", rby, "rby") == INVALID ||
5947 GETINT("xbitmap", fill, "fill") == INVALID ||
5948 GETINT("xbitmap", id, "id") == INVALID ||
5949 GETINT("xbitmap", rotation, "rotation") == INVALID) {
5950 return;
5951 }
5952 if (id >= objId) objId = id+1;
5953 } else if (fileVersion <= 23) {
5954 if (GETINT("xbitmap", ltx, "ltx") == INVALID ||
5955 GETINT("xbitmap", lty, "lty") == INVALID ||
5956 GETINT("xbitmap", rbx, "rbx") == INVALID ||
5957 GETINT("xbitmap", rby, "rby") == INVALID ||
5958 GETINT("xbitmap", fill, "fill") == INVALID ||
5959 GETINT("xbitmap", id, "id") == INVALID ||
5960 GETINT("xbitmap", rotation, "rotation") == INVALID ||
5961 GETINT("xbitmap", image_w, "image_w") == INVALID ||
5962 GETINT("xbitmap", image_h, "image_h") == INVALID ||
5963 GETINT("xbitmap", rotate, "rotate") == INVALID ||
5964 GETINT("xbitmap", flip, "flip") == INVALID) {
5965 return;
5966 }
5967 if (id >= objId) objId = id+1;
5968 } else if (fileVersion <= 25) {
5969 if (GETINT("xbitmap", ltx, "ltx") == INVALID ||
5970 GETINT("xbitmap", lty, "lty") == INVALID ||
5971 GETINT("xbitmap", rbx, "rbx") == INVALID ||
5972 GETINT("xbitmap", rby, "rby") == INVALID ||
5973 GETINT("xbitmap", fill, "fill") == INVALID ||
5974 GETINT("xbitmap", id, "id") == INVALID ||
5975 GETINT("xbitmap", rotation, "rotation") == INVALID ||
5976 GETINT("xbitmap", image_w, "image_w") == INVALID ||
5977 GETINT("xbitmap", image_h, "image_h") == INVALID ||
5978 GETINT("xbitmap", rotate, "rotate") == INVALID ||
5979 GETINT("xbitmap", flip, "flip") == INVALID ||
5980 GETINT("xbitmap", real_type, "real_type") == INVALID ||
5981 GETINT("xbitmap", llx, "llx") == INVALID ||
5982 GETINT("xbitmap", lly, "lly") == INVALID ||
5983 GETINT("xbitmap", urx, "urx") == INVALID ||
5984 GETINT("xbitmap", ury, "ury") == INVALID ||
5985 GETINT("xbitmap", no_bitmap, "no_bitmap") == INVALID) {
5986 return;
5987 }
5988 if (id >= objId) objId = id+1;
5989 } else if (fileVersion <= 28) {
5990 if (GETINT("xbitmap", ltx, "ltx") == INVALID ||
5991 GETINT("xbitmap", lty, "lty") == INVALID ||
5992 GETINT("xbitmap", rbx, "rbx") == INVALID ||
5993 GETINT("xbitmap", rby, "rby") == INVALID ||
5994 GETINT("xbitmap", fill, "fill") == INVALID ||
5995 GETINT("xbitmap", id, "id") == INVALID ||
5996 GETINT("xbitmap", rotation, "rotation") == INVALID ||
5997 GETINT("xbitmap", image_w, "image_w") == INVALID ||
5998 GETINT("xbitmap", image_h, "image_h") == INVALID ||
5999 GETINT("xbitmap", rotate, "rotate") == INVALID ||
6000 GETINT("xbitmap", flip, "flip") == INVALID ||
6001 GETINT("xbitmap", real_type, "real_type") == INVALID ||
6002 GETINT("xbitmap", llx, "llx") == INVALID ||
6003 GETINT("xbitmap", lly, "lly") == INVALID ||
6004 GETINT("xbitmap", urx, "urx") == INVALID ||
6005 GETINT("xbitmap", ury, "ury") == INVALID ||
6006 GETINT("xbitmap", no_bitmap, "no_bitmap") == INVALID ||
6007 GETINT("xbitmap", locked, "locked") == INVALID) {
6008 return;
6009 }
6010 if (id >= objId) objId = id+1;
6011 } else if (fileVersion <= 32) {
6012 if (GETINT("xbitmap", ltx, "ltx") == INVALID ||
6013 GETINT("xbitmap", lty, "lty") == INVALID ||
6014 GETINT("xbitmap", rbx, "rbx") == INVALID ||
6015 GETINT("xbitmap", rby, "rby") == INVALID ||
6016 GETINT("xbitmap", fill, "fill") == INVALID ||
6017 GETINT("xbitmap", id, "id") == INVALID ||
6018 GETINT("xbitmap", rotation, "rotation") == INVALID ||
6019 GETINT("xbitmap", image_w, "image_w") == INVALID ||
6020 GETINT("xbitmap", image_h, "image_h") == INVALID ||
6021 GETINT("xbitmap", rotate, "rotate") == INVALID ||
6022 GETINT("xbitmap", flip, "flip") == INVALID ||
6023 GETINT("xbitmap", real_type, "real_type") == INVALID ||
6024 GETINT("xbitmap", llx, "llx") == INVALID ||
6025 GETINT("xbitmap", lly, "lly") == INVALID ||
6026 GETINT("xbitmap", urx, "urx") == INVALID ||
6027 GETINT("xbitmap", ury, "ury") == INVALID ||
6028 GETINT("xbitmap", no_bitmap, "no_bitmap") == INVALID ||
6029 GETINT("xbitmap", locked, "locked") == INVALID ||
6030 GETINT("xbitmap", save_epsf, "save_epsf") == INVALID) {
6031 return;
6032 }
6033 if (id >= objId) objId = id+1;
6034 } else if (fileVersion <= 34) {
6035 if (GETINT("xbitmap", ltx, "ltx") == INVALID ||
6036 GETINT("xbitmap", lty, "lty") == INVALID ||
6037 GETINT("xbitmap", rbx, "rbx") == INVALID ||
6038 GETINT("xbitmap", rby, "rby") == INVALID ||
6039 GETINT("xbitmap", fill, "fill") == INVALID ||
6040 GETINT("xbitmap", id, "id") == INVALID ||
6041 GETINT("xbitmap", rotation, "rotation") == INVALID ||
6042 GETINT("xbitmap", image_w, "image_w") == INVALID ||
6043 GETINT("xbitmap", image_h, "image_h") == INVALID ||
6044 GETINT("xbitmap", rotate, "rotate") == INVALID ||
6045 GETINT("xbitmap", flip, "flip") == INVALID ||
6046 GETINT("xbitmap", real_type, "real_type") == INVALID ||
6047 GETINT("xbitmap", llx, "llx") == INVALID ||
6048 GETINT("xbitmap", lly, "lly") == INVALID ||
6049 GETINT("xbitmap", urx, "urx") == INVALID ||
6050 GETINT("xbitmap", ury, "ury") == INVALID ||
6051 GETINT("xbitmap", no_bitmap, "no_bitmap") == INVALID ||
6052 GETINT("xbitmap", locked, "locked") == INVALID ||
6053 GETINT("xbitmap", save_epsf, "save_epsf") == INVALID ||
6054 GETINT("xbitmap", compressed, "compressed") == INVALID ||
6055 GETINT("xbitmap", transformed, "transformed") == INVALID ||
6056 GETINT("xbitmap", invisible, "invisible") == INVALID) {
6057 return;
6058 }
6059 if (id >= objId) objId = id+1;
6060 } else {
6061 if (GETINT("xbitmap", ltx, "ltx") == INVALID ||
6062 GETINT("xbitmap", lty, "lty") == INVALID ||
6063 GETINT("xbitmap", rbx, "rbx") == INVALID ||
6064 GETINT("xbitmap", rby, "rby") == INVALID ||
6065 GETINT("xbitmap", fill, "fill") == INVALID ||
6066 GETINT("xbitmap", id, "id") == INVALID ||
6067 GETINT("xbitmap", rotation, "rotation") == INVALID ||
6068 GETINT("xbitmap", image_w, "image_w") == INVALID ||
6069 GETINT("xbitmap", image_h, "image_h") == INVALID ||
6070 GETINT("xbitmap", rotate, "rotate") == INVALID ||
6071 GETINT("xbitmap", flip, "flip") == INVALID ||
6072 GETINT("xbitmap", real_type, "real_type") == INVALID ||
6073 GETINT("xbitmap", llx, "llx") == INVALID ||
6074 GETINT("xbitmap", lly, "lly") == INVALID ||
6075 GETINT("xbitmap", urx, "urx") == INVALID ||
6076 GETINT("xbitmap", ury, "ury") == INVALID ||
6077 GETINT("xbitmap", no_bitmap, "no_bitmap") == INVALID ||
6078 GETINT("xbitmap", locked, "locked") == INVALID ||
6079 GETINT("xbitmap", save_epsf, "save_epsf") == INVALID ||
6080 GETINT("xbitmap", compressed, "compressed") == INVALID ||
6081 GETINT("xbitmap", transformed, "transformed") == INVALID ||
6082 GETINT("xbitmap", invisible, "invisible") == INVALID ||
6083 GETINT("xbitmap", trans_pat, "trans_pat") == INVALID) {
6084 return;
6085 }
6086 if (id >= objId) objId = id+1;
6087 }
6088 if (fileVersion <= 22) {
6089 image_w = rbx-ltx;
6090 image_h = rby-lty;
6091 rotate = ROTATE0;
6092 flip = 0;
6093 }
6094 if (fileVersion >= 24) {
6095 char *tmp_str, *s, *s1;
6096
6097 (void)fgets(inbuf, MAXSTRING, FP);
6098 scanLineNum++;
6099
6100 tmp_str = FindChar((int)'"', inbuf);
6101 s = s1 = ReadString(tmp_str);
6102 s1++;
6103 *(--s) = '\0';
6104 len = strlen(tmp_str);
6105 if (len > 24) {
6106 (void)sprintf(gszMsgBox,
6107 TgLoadCachedString(CSTID_FIELD_TOO_LONG_IN_OBJ_TRUNC),
6108 scanFileName, scanLineNum, "write_date", "xbm");
6109 if (PRTGIF) {
6110 fprintf(stderr, "%s\n", gszMsgBox);
6111 } else {
6112 Msg(gszMsgBox);
6113 }
6114 tmp_str[23] = '\0';
6115 }
6116 strcpy(write_date, tmp_str);
6117
6118 tmp_str = FindChar((int)'"', s1);
6119 s = ReadString(tmp_str);
6120 *(--s) = '\0';
6121 len = strlen(tmp_str);
6122 filename = (char*)malloc((len+1)*sizeof(char));
6123 if (filename == NULL) FailAllocMessage();
6124 strcpy(filename, tmp_str);
6125 if (save_epsf) {
6126 if (sscanf(&s[2], "%d", &num_epsf_lines) != 1) {
6127 sprintf(gszMsgBox,
6128 TgLoadCachedString(CSTID_FILE_LINE_BAD_FLD_IN_OBJ_STR),
6129 scanFileName, scanLineNum, "num_epsf_lines", "xbm", &s[2]);
6130 if (PRTGIF) {
6131 fprintf(stderr, "%s\n", gszMsgBox);
6132 } else {
6133 Msg(gszMsgBox);
6134 }
6135 return;
6136 }
6137 epsflines = (char**)malloc(num_epsf_lines*sizeof(char*));
6138 if (epsflines == NULL) FailAllocMessage();
6139 for (i=0; i < num_epsf_lines; i++) {
6140 if (fgets(inbuf, MAXSTRING, FP) == NULL) {
6141 sprintf(gszMsgBox,
6142 TgLoadString(STID_UNEXPECTED_EOF_IN_ABORT_READ),
6143 scanLineNum, scanFileName, "ReadXBmObj()");
6144 if (PRTGIF) {
6145 fprintf(stderr, "%s\n", gszMsgBox);
6146 } else {
6147 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
6148 }
6149 return;
6150 }
6151 scanLineNum++;
6152 len = strlen(inbuf);
6153 if ((c_ptr=strchr(inbuf, '"')) == NULL) {
6154 sprintf(gszMsgBox,
6155 TgLoadCachedString(CSTID_MALFORMED_LINE_NUM_IN_FILE),
6156 scanLineNum, scanFileName);
6157 if (PRTGIF) {
6158 fprintf(stderr, "%s\n", gszMsgBox);
6159 } else {
6160 Msg(gszMsgBox);
6161 }
6162 return;
6163 }
6164 c_ptr++;
6165 len -= (c_ptr-inbuf);
6166 if (c_ptr[len-1] != '\n') {
6167 int cur_size=2*MAXSTRING-1, done=FALSE;
6168 char *line=(char*)malloc((cur_size+1)*sizeof(char));
6169
6170 if (line == NULL) FailAllocMessage();
6171 strcpy(line, c_ptr);
6172 c_ptr = &(line[len]);
6173
6174 while (!done && fgets(inbuf, MAXSTRING, FP) != NULL) {
6175 len = strlen(inbuf);
6176 if (inbuf[len-1] == '\r' || inbuf[len-1] == '\n') {
6177 done = TRUE;
6178 inbuf[len-1] = '\0';
6179 strcpy(c_ptr, inbuf);
6180 } else {
6181 int n=c_ptr-line;
6182
6183 cur_size += MAXSTRING-1;
6184 line = (char*)realloc(line, cur_size+1);
6185 c_ptr = line + n;
6186 strcpy(c_ptr, inbuf);
6187 c_ptr += MAXSTRING-1;
6188 }
6189 }
6190 if (!done) {
6191 sprintf(gszMsgBox,
6192 TgLoadString(STID_UNEXPECTED_EOF_IN_ABORT_READ),
6193 scanLineNum, scanFileName, "ReadXBmObj()");
6194 if (PRTGIF) {
6195 fprintf(stderr, "%s\n", gszMsgBox);
6196 } else {
6197 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
6198 }
6199 return;
6200 }
6201 epsflines[i] = line;
6202 len = strlen(line);
6203 } else {
6204 c_ptr[--len] = '\0';
6205 epsflines[i] = (char*)malloc((len+1)*sizeof(char));
6206 if (epsflines[i] == NULL) FailAllocMessage();
6207 strncpy(epsflines[i], c_ptr, len);
6208 epsflines[i][len] = '\0';
6209 }
6210 for (c_ptr=(&(epsflines[i])[len]); c_ptr != epsflines[i] &&
6211 *c_ptr != '"'; c_ptr--) ;
6212 if (*c_ptr != '"') {
6213 sprintf(gszMsgBox,
6214 TgLoadCachedString(CSTID_MALFORMED_LINE_NUM_IN_FILE),
6215 scanLineNum, scanFileName);
6216 if (PRTGIF) {
6217 fprintf(stderr, "%s\n", gszMsgBox);
6218 } else {
6219 MsgBox(gszMsgBox, TOOL_NAME, INFO_MB);
6220 }
6221 return;
6222 }
6223 *c_ptr = '\0';
6224 }
6225 }
6226 } else {
6227 *write_date = '\0';
6228 filename = NULL;
6229 }
6230 fill = UpgradePenFill(fill);
6231
6232 *ObjPtr = (struct ObjRec *)malloc(sizeof(struct ObjRec));
6233 if (*ObjPtr == NULL) FailAllocMessage();
6234 memset(*ObjPtr, 0, sizeof(struct ObjRec));
6235 xbm_ptr = (struct XBmRec *)malloc(sizeof(struct XBmRec));
6236 if (xbm_ptr == NULL) FailAllocMessage();
6237 memset(xbm_ptr, 0, sizeof(struct XBmRec));
6238
6239 color_index = QuickFindColorIndex(*ObjPtr, color_str, &new_alloc, TRUE);
6240
6241 (*ObjPtr)->color = color_index;
6242 if (mainDisplay != NULL) {
6243 UtilStrCpyN((*ObjPtr)->color_str, sizeof((*ObjPtr)->color_str),
6244 colorMenuItems[color_index]);
6245 }
6246 (*ObjPtr)->dirty = FALSE;
6247 (*ObjPtr)->id = id;
6248 (*ObjPtr)->rotation = rotation;
6249 (*ObjPtr)->locked = locked;
6250 (*ObjPtr)->type = OBJ_XBM;
6251 (*ObjPtr)->obbox.ltx = (*ObjPtr)->bbox.ltx = (*ObjPtr)->x = ltx;
6252 (*ObjPtr)->obbox.lty = (*ObjPtr)->bbox.lty = (*ObjPtr)->y = lty;
6253 (*ObjPtr)->obbox.rbx = (*ObjPtr)->bbox.rbx = rbx;
6254 (*ObjPtr)->obbox.rby = (*ObjPtr)->bbox.rby = rby;
6255 (*ObjPtr)->detail.xbm = xbm_ptr;
6256 (*ObjPtr)->ctm = NULL;
6257 (*ObjPtr)->invisible = invisible;
6258 (*ObjPtr)->trans_pat = trans_pat;
6259
6260 xbm_ptr->bitmap = None;
6261 xbm_ptr->image = NULL;
6262 xbm_ptr->cached_bitmap = None;
6263 xbm_ptr->cached_zoom = 0;
6264 xbm_ptr->data = NULL;
6265 xbm_ptr->fill = fill;
6266 xbm_ptr->flip = flip;
6267 xbm_ptr->cached_flip = 0;
6268 xbm_ptr->cached_w = xbm_ptr->cached_h = 0;
6269 xbm_ptr->image_w = image_w;
6270 xbm_ptr->image_h = image_h;
6271 xbm_ptr->llx = llx; xbm_ptr->lly = lly;
6272 xbm_ptr->urx = urx; xbm_ptr->ury = ury;
6273
6274 xbm_ptr->real_type = real_type;
6275 strcpy(xbm_ptr->write_date, write_date);
6276 xbm_ptr->filename = filename;
6277 xbm_ptr->epsflines = epsflines;
6278 xbm_ptr->num_epsf_lines = num_epsf_lines;
6279 xbm_ptr->save_epsf = save_epsf;
6280
6281 if (no_bitmap && xbm_ptr->real_type==XBM_EPS) {
6282 float file_llx=0.0, file_lly=0.0, file_urx=0.0, file_ury=0.0;
6283
6284 xbm_ptr->eps_w = xbm_ptr->image_w;
6285 xbm_ptr->eps_h = xbm_ptr->image_h;
6286 xbm_ptr->image_w = 0;
6287 xbm_ptr->image_h = 0;
6288
6289 if (!(PRTGIF && !cmdLineOpenDisplay)) {
6290 transform_read = TRUE;
6291 if (!ReadTransformAndAdjustForXBm(FP, ObjPtr, xbm_ptr, transformed,
6292 rotate, flip)) {
6293 return;
6294 }
6295 if (MyReadEPSFile(xbm_ptr->filename, &image_w, &image_h,
6296 &(xbm_ptr->bitmap), &(xbm_ptr->image),
6297 (save_epsf ? &(xbm_ptr->num_epsf_lines) : NULL),
6298 (save_epsf ? &(xbm_ptr->epsflines) : NULL),
6299 &(xbm_ptr->epsf_level), &file_llx, &file_lly, &file_urx,
6300 &file_ury, xbm_ptr->write_date) != BitmapSuccess) {
6301 return;
6302 } else if (xbm_ptr->bitmap == None) {
6303 xbm_ptr->eps_w = (file_urx >= file_llx) ?
6304 (int)(file_urx-file_llx) : (int)(file_llx-file_urx);
6305 xbm_ptr->eps_h = (file_ury >= file_lly) ?
6306 (int)(file_ury-file_lly) : (int)(file_lly-file_ury);
6307 } else {
6308 xbm_ptr->image_w = image_w;
6309 xbm_ptr->image_h = image_h;
6310 /* same as above! */
6311 xbm_ptr->eps_w = (file_urx >= file_llx) ?
6312 (int)(file_urx-file_llx) : (int)(file_llx-file_urx);
6313 xbm_ptr->eps_h = (file_ury >= file_lly) ?
6314 (int)(file_ury-file_lly) : (int)(file_lly-file_ury);
6315 }
6316 xbm_ptr->llx = (int)(file_llx*1000.0);
6317 xbm_ptr->lly = (int)(file_lly*1000.0);
6318 xbm_ptr->urx = (int)(file_urx*1000.0);
6319 xbm_ptr->ury = (int)(file_ury*1000.0);
6320 }
6321 } else {
6322 if (xbm_ptr->real_type == XBM_EPS) {
6323 float file_llx=((float)xbm_ptr->llx)/1000.0;
6324 float file_lly=((float)xbm_ptr->lly)/1000.0;
6325 float file_urx=((float)xbm_ptr->urx)/1000.0;
6326 float file_ury=((float)xbm_ptr->ury)/1000.0;
6327
6328 /* same as above! */
6329 xbm_ptr->eps_w = (file_urx >= file_llx) ?
6330 (int)(file_urx-file_llx) : (int)(file_llx-file_urx);
6331 xbm_ptr->eps_h = (file_ury >= file_lly) ?
6332 (int)(file_ury-file_lly) : (int)(file_lly-file_ury);
6333 } else {
6334 xbm_ptr->eps_w = xbm_ptr->eps_h = 0;
6335 }
6336 num_nibbles = ((image_w % 4) == 0) ? (int)(image_w>>2) :
6337 (int)(image_w>>2)+1;
6338
6339 (void)fgets(inbuf, MAXSTRING, FP);
6340 scanLineNum++;
6341 c_ptr = &inbuf[5];
6342 nibble_count = 0;
6343
6344 if (PRTGIF && !cmdLineOpenDisplay) {
6345 xbm_data = (char*)malloc((image_h*num_nibbles)*sizeof(char));
6346 if (xbm_data == NULL) FailAllocMessage();
6347 for (i = 0; i < image_h; i++) {
6348 for (j = 0; j < num_nibbles; j++) {
6349 if (nibble_count++ == 64) {
6350 (void)fgets(inbuf, MAXSTRING, FP);
6351 scanLineNum++;
6352 c_ptr = &inbuf[5];
6353 nibble_count = 1;
6354 }
6355 xbm_data[i*num_nibbles+j] = *c_ptr++;
6356 }
6357 }
6358 xbm_ptr->data = xbm_data;
6359 } else {
6360 bitmap = XCreatePixmap(mainDisplay, dummyBitmap, image_w, image_h, 1);
6361 XFillRectangle(mainDisplay, bitmap, xbmGC, 0, 0, image_w, image_h);
6362 image = XGetImage(mainDisplay,bitmap,0,0,image_w,image_h,1,ZPixmap);
6363
6364 for (i = 0; i < image_h; i++) {
6365 bit_count = 0;
6366 for (j = 0; j < num_nibbles; j++) {
6367 if (nibble_count++ == 64) {
6368 (void)fgets(inbuf, MAXSTRING, FP);
6369 scanLineNum++;
6370 c_ptr = &inbuf[5];
6371 nibble_count = 1;
6372 }
6373 if (*c_ptr >= '0' && *c_ptr <= '9') {
6374 data = (int)(*c_ptr++) - (int)('0');
6375 } else if (*c_ptr >= 'a' && *c_ptr <= 'f') {
6376 data = (int)(*c_ptr++) - (int)('a') + 10;
6377 }
6378 for (k = 0; k < 4; k++) {
6379 if (bit_count++ == image_w) break;
6380
6381 if (data & (1<<(3-k))) {
6382 XPutPixel(image, j*4+k, i, 1);
6383 }
6384 }
6385 }
6386 }
6387 XPutImage(mainDisplay,bitmap,xbmGC,image,0,0,0,0,image_w,image_h);
6388 xbm_ptr->bitmap = bitmap;
6389 xbm_ptr->image = image;
6390 }
6391 }
6392 if (!transform_read && !ReadTransformAndAdjustForXBm(FP, ObjPtr, xbm_ptr,
6393 transformed, rotate, flip)) {
6394 return;
6395 }
6396 if (!transform_read && (!(PRTGIF && !cmdLineOpenDisplay)) &&
6397 (*ObjPtr)->ctm == NULL) {
6398 struct BBRec orig_obbox;
6399
6400 SetBBRec(&orig_obbox, ltx, lty, rbx, rby);
6401 SetEPSObjCTM(*ObjPtr, &orig_obbox);
6402 }
6403 }
6404
SetXBmPropMask(ObjPtr,plMask,plSkip,pProp)6405 void SetXBmPropMask(ObjPtr, plMask, plSkip, pProp)
6406 struct ObjRec *ObjPtr;
6407 long *plMask, *plSkip;
6408 struct PropertiesRec *pProp;
6409 {
6410 struct XBmRec *xbm_ptr=ObjPtr->detail.xbm;
6411
6412 SetCTMPropertyMask(ObjPtr->ctm, plMask, plSkip, pProp);
6413
6414 if (xbm_ptr->real_type != XBM_EPS) {
6415 SetIntPropertyMask(PROP_MASK_COLOR, ObjPtr->color,
6416 colorMenuItems[ObjPtr->color], plMask, plSkip, pProp);
6417 }
6418 }
6419
FreeXBmObj(ObjPtr)6420 void FreeXBmObj(ObjPtr)
6421 struct ObjRec *ObjPtr;
6422 {
6423 register struct XBmRec *xbm_ptr=ObjPtr->detail.xbm;
6424 register int i;
6425
6426 if (xbm_ptr->bitmap != None) XFreePixmap(mainDisplay, xbm_ptr->bitmap);
6427 if (xbm_ptr->image != NULL) XDestroyImage(xbm_ptr->image);
6428 if (xbm_ptr->cached_bitmap != None) {
6429 XFreePixmap(mainDisplay, xbm_ptr->cached_bitmap);
6430 }
6431 xbm_ptr->bitmap = None;
6432 xbm_ptr->image = NULL;
6433 xbm_ptr->cached_bitmap = None;
6434 xbm_ptr->cached_zoom = 0;
6435 if (xbm_ptr->data != NULL) free(xbm_ptr->data);
6436 if (xbm_ptr->filename != NULL) free(xbm_ptr->filename);
6437 if (xbm_ptr->real_type == XBM_EPS) {
6438 for (i = 0; i < xbm_ptr->num_epsf_lines; i++) {
6439 if (xbm_ptr->epsflines[i] != NULL) {
6440 free(xbm_ptr->epsflines[i]);
6441 }
6442 }
6443 if (xbm_ptr->epsflines != NULL) free(xbm_ptr->epsflines);
6444 }
6445 free(xbm_ptr);
6446 free(ObjPtr);
6447 }
6448