1 /*
2 **
3 ** doc_misc.c
4 **
5 ** Copyright (C) 1995, 1996, 1997 Johannes Plass
6 ** Copyright (C) 2004 Jose E. Marchesi
7 **
8 ** This program is free software; you can redistribute it and/or modify
9 ** it under the terms of the GNU General Public License as published by
10 ** the Free Software Foundation; either version 3 of the License, or
11 ** (at your option) any later version.
12 **
13 ** This program is distributed in the hope that it will be useful,
14 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
15 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 ** GNU General Public License for more details.
17 **
18 ** You should have received a copy of the GNU General Public License
19 ** along with GNU gv; see the file COPYING.  If not, write to
20 ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 ** Boston, MA 02111-1307, USA.
22 **
23 ** Author:   Johannes Plass (plass@thep.physik.uni-mainz.de)
24 **           Department of Physics
25 **           Johannes Gutenberg-University
26 **           Mainz, Germany
27 **
28 **           Jose E. Marchesi (jemarch@gnu.org)
29 **           GNU Project
30 */
31 #include "ac_config.h"
32 
33 /*
34 #define MESSAGES
35 */
36 #include "message.h"
37 
38 #include <stdlib.h>
39 #include <stdio.h>
40 #include <gv_signal.h>
41 
42 #include "paths.h"
43 #include INC_X11(Intrinsic.h)
44 #include INC_XMU(CharSet.h)
45 #include "Ghostview.h"
46 #include "main_resources.h"
47 
48 #include "types.h"
49 extern Media* gv_medias;
50 #include "ps.h"
51 #include "doc_misc.h"
52 
53 #include "resource.h"
54 
55 /*##################################################################*/
56 /* doc_scanFile */
57 /*##################################################################*/
58 
59 int
doc_scanFile(fPP,docP,filename,filename_raw,filename_dscP,cmd_scan_pdf,filename_uncP,cmd_uncompress,scanstyle,gv_gs_safeDir)60 doc_scanFile(fPP,docP,filename,filename_raw,filename_dscP,cmd_scan_pdf,filename_uncP,cmd_uncompress,scanstyle,gv_gs_safeDir)
61    FILE ** fPP;
62    Document *docP;
63    String filename;
64    String filename_raw;
65    String *filename_dscP;
66    String cmd_scan_pdf;
67    String *filename_uncP;
68    String cmd_uncompress;
69    int scanstyle;
70    int gv_gs_safeDir;
71 {
72    Document d;
73    int i,ret;
74 
75    BEGINMESSAGE(doc_scanFile)
76    d = (Document)NULL;
77    ret = 0;
78    if (*fPP && filename)
79      d = psscan(fPP,filename,filename_raw,filename_dscP,cmd_scan_pdf,filename_uncP,cmd_uncompress,scanstyle,gv_gs_safeDir);
80    if (d) {
81       d->labels_useful=0;
82       d->structured   =0;
83       if ((!d->epsf && d->numpages>0) || (d->epsf && d->numpages>1)) {
84          ret = d->structured = 1;
85          if (d->numpages == 1) d->labels_useful=1;
86          else for (i = 1; i < d->numpages; i++)
87             if (strcmp(d->pages[i-1].label,d->pages[i].label)) { d->labels_useful = 1; break; }
88       }
89    }
90    *docP = d;
91 
92 #  ifdef MESSAGES
93      if (!d) { INFMESSAGE(unsuccessful) }
94      else {
95          INFMESSAGE(successful)
96          if (d->structured)    { INFMESSAGE(structured)    } else { INFMESSAGE(not structured)    }
97          if (d->labels_useful) { INFMESSAGE(labels useful) } else { INFMESSAGE(labels not useful) }
98      }
99 #  endif
100    ENDMESSAGE(doc_scanFile)
101    return ret;
102 }
103 
104 /*##################################################################*/
105 /* doc_putPageInRange */
106 /*##################################################################*/
107 
108 int
doc_putPageInRange(d,pagenumber)109 doc_putPageInRange(d,pagenumber)
110    Document d;
111    int pagenumber;
112 {
113    BEGINMESSAGE(doc_putPageInRange)
114    if (d && d->structured) {
115       if (pagenumber >= d->numpages) pagenumber = d->numpages-1;
116       if (pagenumber < 0) pagenumber = 0;
117    } else pagenumber = 0;
118    ENDMESSAGE(doc_putPageInRange)
119    return pagenumber;
120 }
121 
122 /*############################################################*/
123 /* doc_mediaIsOk */
124 /*############################################################*/
125 
126 int
doc_mediaIsOk(d,pagenumber,m)127 doc_mediaIsOk (d,pagenumber,m)
128   Document d;
129   int pagenumber;
130   int m;
131 {
132   int r=1;
133   int bbox = d ? d->nummedia : 0;
134   BEGINMESSAGE(doc_mediaIsOk)
135   if (m==bbox) {
136     int l;
137     if (doc_boundingBoxOfPage(d,pagenumber,&l,&l,&l,&l) == MEDIA_ID_INVALID)
138       r = 0;
139   } else if (m==MEDIA_ID_INVALID)
140       r = 0;
141   ENDMESSAGE(doc_mediaIsOk)
142   return(r);
143 }
144 
145 /*############################################################*/
146 /* doc_boundingBoxOfPage */
147 /*############################################################*/
148 
149 int
doc_boundingBoxOfPage(d,pagenumber,llxP,llyP,urxP,uryP)150 doc_boundingBoxOfPage(d,pagenumber,llxP,llyP,urxP,uryP)
151   Document d;
152   int pagenumber;
153   int *llxP,*llyP,*urxP,*uryP;
154 {
155   int *dbb = NULL;
156   int retry;
157 
158   BEGINMESSAGE(doc_boundingBoxOfPage)
159 
160   if (!d) {
161     INFMESSAGE(no document) ENDMESSAGE(doc_preferredMediaOfPage)
162     return(MEDIA_ID_INVALID);
163   }
164 
165   retry=1;
166 # define BB_VALID (dbb[URX]>dbb[LLX] && dbb[URY]>dbb[LLY])
167   if (d->structured && 0<=pagenumber && pagenumber<d->numpages)
168     { dbb = d->pages[pagenumber].boundingbox;  if BB_VALID retry=0; }
169   if (retry && d->structured)
170     { dbb = d->default_page_boundingbox; if BB_VALID retry=0; }
171   if (retry)
172     { dbb = d->boundingbox;              if BB_VALID retry=0; }
173 # undef BB_VALID
174   if (!retry) {
175     *llxP=dbb[LLX]; *llyP=dbb[LLY]; *urxP=dbb[URX]; *uryP=dbb[URY];
176     INFMESSAGE(bounding box)
177     ENDMESSAGE(doc_boundingBoxOfPage)
178     return(d->nummedia);
179   }
180   INFMESSAGE(MEDIA_ID_INVALID)
181   ENDMESSAGE(doc_boundingBoxOfPage)
182   return(MEDIA_ID_INVALID);
183 }
184 
185 /*############################################################*/
186 /* doc_preferredMediaOfPage */
187 /*############################################################*/
188 
189 int
doc_preferredMediaOfPage(d,pagenumber,llxP,llyP,urxP,uryP)190 doc_preferredMediaOfPage(d,pagenumber,llxP,llyP,urxP,uryP)
191   Document d;
192   int pagenumber;
193   int *llxP,*llyP,*urxP,*uryP;
194 {
195 # define BB_VALID (dbb[URX]>dbb[LLX] && dbb[URY]>dbb[LLY])
196   int *dbb = NULL;
197   Media media = NULL,dm;
198   int m=MEDIA_ID_INVALID;
199   int found,i,j;
200 
201   BEGINMESSAGE(doc_preferredMediaOfPage)
202 
203   if (!d) {
204     INFMESSAGE(no document) ENDMESSAGE(doc_preferredMediaOfPage)
205     return(MEDIA_ID_INVALID);
206   }
207 
208   found=0;
209   if (!found && d->structured && 0<=pagenumber && pagenumber<d->numpages)
210     { media = (Media) d->pages[pagenumber].media;  if (media) found=1; }
211   if (!found)
212     { media = (Media) d->default_page_media; if (media) found=1; }
213   if (d->structured && 0<=pagenumber && pagenumber<d->numpages)
214     { dbb = d->pages[pagenumber].boundingbox;  if BB_VALID found=-1; }
215   if (!found && d->structured)
216     { dbb = d->default_page_boundingbox; if BB_VALID found=-1; }
217   if (!found)
218     { dbb = d->boundingbox;              if BB_VALID found=-1; }
219 # undef BB_VALID
220 
221   /* try to map bounding box to standard or document pagemedia */
222   if (found==-1 && dbb[LLX]==0 && dbb[LLY]==0) {
223     for (dm=(Media) d->media,i=0; !media && i<d->nummedia; i++,dm++)
224       if (dm->used &&
225           ((dm->width==dbb[URX] || dm->width+1==dbb[URX]) &&
226            (dm->height==dbb[URY] || dm->height+1==dbb[URY]))) media=dm;
227     for (j=0; gv_medias[j] && !media ; j++) {
228        dm = gv_medias[j];
229        if (dm->used==1 &&
230            ((dm->width==dbb[URX] || dm->width+1==dbb[URX]) &&
231             (dm->height==dbb[URY] || dm->height+1==dbb[URY]))) media=dm;
232     }
233     if (media) found=1;
234   }
235 
236   if (found==-1) {
237     *llxP=dbb[LLX]; *llyP=dbb[LLY]; *urxP=dbb[URX]; *uryP=dbb[URY];
238     INFMESSAGE(bounding box)
239     m=d->nummedia;
240   } else if (found==1) {
241     for (dm=(Media)d->media,i=0; i<d->nummedia; i++,dm++)
242       if (media==dm) { m = i; break; }
243     if (m==MEDIA_ID_INVALID) for (i=0; gv_medias[i] ; i++)
244       if (media==gv_medias[i]) { m = i+d->nummedia; break; }
245     if (m!=MEDIA_ID_INVALID) {
246       INFIMESSAGE(doc prefers media,m)
247       *llxP=*llyP=0; *urxP=media->width-1; *uryP=media->height-1;
248     }
249   }
250   INFIMESSAGE(returning media number,m)
251   ENDMESSAGE(doc_preferredMediaOfPage)
252   return(m);
253 }
254 
255 /*##################################################################*/
256 /* doc_preferredOrientationOfPage */
257 /*##################################################################*/
258 
259 int
doc_preferredOrientationOfPage(d,page)260 doc_preferredOrientationOfPage(d,page)
261    Document d;
262    int page;
263 {
264    int o;
265 
266    BEGINMESSAGE(doc_preferredOrientationOfPage)
267    o  = O_UNSPECIFIED;
268    if (d) {
269       if (d->structured && 0<=page && page<d->numpages && d->pages[page].orientation != O_UNSPECIFIED)
270          o = d->pages[page].orientation;
271       else if (d->default_page_orientation != O_UNSPECIFIED)
272          o = d->default_page_orientation;
273       else if (d->orientation != O_UNSPECIFIED)
274          o = d->orientation;
275    }
276    ENDMESSAGE(doc_preferredOrientationOfPage)
277    return(o);
278 }
279 
280 /*############################################################*/
281 /* doc_convStringToPage */
282 /*############################################################*/
283 
284 int
doc_convStringToPage(d,pageLabel)285 doc_convStringToPage(d,pageLabel)
286    Document d;
287    String pageLabel;
288 {
289    int i,j;
290    int page;
291 
292    BEGINMESSAGE(doc_convStringToPage)
293    page=-1;
294    if (pageLabel && d && d->labels_useful) for (i=0; i<d->numpages; i++) {
295       if (d->pageorder == DESCEND) j = d->numpages-1-i;
296       else                         j = i;
297       if (!strcmp(pageLabel,d->pages[j].label)) { page=i; break; }
298    }
299       INFMESSAGE(1)
300    if (page<0 && pageLabel) page=atoi(pageLabel)-1;
301    if (page<0) page=0;
302    IMESSAGE(page)
303    ENDMESSAGE(doc_convStringToPage)
304    return(page);
305 }
306 
307 /*############################################################*/
308 /* doc_convDocOrientToXtOrient */
309 /*############################################################*/
310 
311 XtPageOrientation
doc_convDocOrientToXtOrient(orientation,swapLandscape)312 doc_convDocOrientToXtOrient(orientation,swapLandscape)
313    int orientation;
314    int swapLandscape;
315 {
316    XtPageOrientation ret;
317 
318    BEGINMESSAGE(doc_convDocOrientToXtOrient)
319 
320    switch (orientation) {
321    case O_PORTRAIT:
322       INFMESSAGE(portrait)
323       ret= XtPageOrientationPortrait;
324       break;
325    case O_UPSIDEDOWN:
326       INFMESSAGE(upsidedown)
327       ret = XtPageOrientationUpsideDown;
328       break;
329    case O_LANDSCAPE:
330      if (swapLandscape) {INFMESSAGE(seascape)  ret = XtPageOrientationSeascape; }
331      else               {INFMESSAGE(landscape) ret = XtPageOrientationLandscape;}
332       break;
333    case O_SEASCAPE:
334      if (swapLandscape) {INFMESSAGE(landscape)ret = XtPageOrientationLandscape;}
335       else              {INFMESSAGE(seascape)ret = XtPageOrientationSeascape;}
336       break;
337    case O_UNSPECIFIED:
338       INFMESSAGE(unspecified)
339       ret = XtPageOrientationUnspecified;
340       break;
341    default:
342       INFMESSAGE(doc_convDocOrientToXtOrient: unknown orientation)
343       ret = XtPageOrientationUnspecified;
344       break;
345    }
346    ENDMESSAGE(doc_convDocOrientToXtOrient)
347 
348    return ret;
349 }
350 
351 /*############################################################*/
352 /* doc_convStringToDocOrient */
353 /*############################################################*/
354 
355 int
doc_convStringToDocOrient(ostr)356 doc_convStringToDocOrient(ostr)
357    String ostr;
358 {
359    int o=O_PORTRAIT;
360    BEGINMESSAGE(doc_convStringToDocOrient)
361    if (ostr) {
362 SMESSAGE(ostr)
363 #     define IS_STR(aaa,bbb) (!XmuCompareISOLatin1(aaa,bbb))
364       if      IS_STR(ostr,"Automatic")      { INFMESSAGE(is O_AUTOMATIC)      o = O_AUTOMATIC;  }
365       else if IS_STR(ostr,"Portrait")       { INFMESSAGE(is O_PORTRAIT)       o = O_PORTRAIT;   }
366       else if IS_STR(ostr,"Landscape")      { INFMESSAGE(is O_LANDSCAPE)      o = O_LANDSCAPE;  }
367       else if IS_STR(ostr,"Seascape")       { INFMESSAGE(is O_SEASCAPE)       o = O_SEASCAPE;   }
368       else if IS_STR(ostr,"Upside-Down")    { INFMESSAGE(is O_UPSIDEDOWN)     o = O_UPSIDEDOWN; }
369       else if IS_STR(ostr,"Swap-Landscape") { INFMESSAGE(is O_SWAP_LANDSCAPE) o = O_SWAP_LANDSCAPE; }
370 #     undef IS_STR
371    }
372    ENDMESSAGE(doc_convStringToDocOrient)
373    return o;
374 }
375 
376 /*############################################################*/
377 /* doc_convStringToPageMedia */
378 /*############################################################*/
379 
380 int
doc_convStringToPageMedia(d,mstr)381 doc_convStringToPageMedia(d,mstr)
382    Document d;
383    String mstr;
384 {
385    int media = MEDIA_ID_INVALID;
386    int i;
387 
388    BEGINMESSAGE(doc_convStringToPageMedia)
389    /*### automatic pagemedia evaluation */
390    if (!XmuCompareISOLatin1(mstr,"Automatic")) media = MEDIA_ID_AUTO;
391    /*### document pagemedia */
392    if (media==MEDIA_ID_INVALID  && d && d->nummedia) {
393       for (i = 0; i<d->nummedia; i++)
394           if (!XmuCompareISOLatin1(mstr,d->media[i].name)) media = i;
395    }
396    /*### standard pagemedia */
397    if (media==MEDIA_ID_INVALID) {
398       int num_doc_papersizes=0;
399       if (d) num_doc_papersizes = d->nummedia;
400       for (i=0; gv_medias[i]; i++)
401 	  if (gv_medias[i]->used && !XmuCompareISOLatin1(mstr,gv_medias[i]->name)) media = num_doc_papersizes+i;
402    }
403    IMESSAGE(media)
404    ENDMESSAGE(doc_convStringToPageMedia)
405    return media;
406 }
407