home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Enigma Amiga Life 110
/
EnigmaAmiga110CD.iso
/
indispensabili
/
utility
/
apdf
/
xpdf-0.80
/
xpdf
/
apdfcommon.cc
< prev
next >
Wrap
C/C++ Source or Header
|
1999-06-30
|
16KB
|
755 lines
//========================================================================
//
// Apdfcommon.cc
//
// Copyright 1999 Emmanuel Lesueur
//
//========================================================================
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
#define Object ZZObject
#ifdef __PPC__
# include <powerup/ppcproto/exec.h>
# include <powerup/ppcproto/dos.h>
#else
# include <proto/exec.h>
# include <proto/dos.h>
#endif
#undef Object
#include "parseargs.h"
#include "GString.h"
#include "gmem.h"
#include "Object.h"
#include "Stream.h"
#include "Array.h"
#include "Dict.h"
#include "XRef.h"
#include "Catalog.h"
#include "Page.h"
#include "Link.h"
#include "PDFDoc.h"
#include "AOutputDev.h"
#include "TextOutputDev.h"
#include "PSOutputDev.h"
#include "ImageOutputDev.h"
#include "FontOutputDev.h"
#include "Error.h"
#include "config.h"
#include "AComm.h"
#ifdef __SASC
# undef try
# undef catch
# define try
# define catch(x) if(const char* msg=NULL)
#endif
#ifdef __PPC__
# define LINKAGE
#else
# define LINKAGE extern "C"
#endif
static int userFontMapLen,userFontMapSize;
static char* fontPathInit[]={NULL};
char **fontPath = fontPathInit;
static PDFDoc* doc;
static AGfx* gfx;
static AOutputDev* AOut;
int maxColors;
const char* uncompressCmd;
static FontOutputDev* fOut;
extern FILE* errFile;
static BPTR olddir;
static BPTR lock;
#ifdef POWERUP
extern PPCPort* port68k;
#endif
extern "C" {
unsigned long _MSTEP=0x10000;
}
LINKAGE void clear_fontmap() {
if(userFontMap) {
for(int i=0;i<userFontMapLen;++i) {
gfree(userFontMap[i].pdfFont);
gfree(userFontMap[i].xFont);
}
userFontMap[0].pdfFont=NULL;
userFontMapLen=0;
}
//clearFontMap();
}
void cleanup2() {
CurrentDir(olddir);
UnLock(lock);
delete fOut;
delete AOut;
delete gfx;
delete doc;
clear_fontmap();
gfree(userFontMap);
gfree((void*)uncompressCmd);
Object::memCheck(errFile);
gMemReport(errFile);
}
LINKAGE int init(int colors,const char* gzip) {
int ok=1;
try {
maxColors=colors;
olddir=CurrentDir(0);
CurrentDir(olddir);
errorInit();
atexit(&cleanup2);
userFontMapSize=8;
userFontMap=(FontMapEntry*)gmalloc(userFontMapSize*sizeof(FontMapEntry));
userFontMap->pdfFont=NULL;
uncompressCmd=copyString((char*)gzip);
#ifdef POWERUP
gfx=new AGfx(port68k);
#else
gfx=new AGfx;
#endif
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
ok=0;
}
catch(...) {
printf("Exception caught.");
ok=0;
}
return ok;
}
LINKAGE int create_doc(BPTR dir,const char* filename,size_t maxbuf,size_t blocsz) {
BPTR olddir=CurrentDir(dir);
try {
myFILE::bufsizes(blocsz,maxbuf);
PDFDoc* d=new PDFDoc(new GString((char*)filename));
if(d->isOk()) {
delete doc;
doc=d;
UnLock(lock);
lock=DupLock(dir);
CurrentDir(lock);
return 1;
}
delete d;
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
CurrentDir(olddir);
return 0;
}
#if 0
LINKAGE void do_delete_doc() {
delete doc;
doc=NULL;
}
#endif
LINKAGE int create_output_dev(int depth,struct ColorMap* colormap) {
try {
delete AOut;
AOut=NULL; //in case the following line throws an exception
AOut=new AOutputDev(*gfx, depth, colormap);
AOutputFont::reset();
return 1;
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
return 0;
}
LINKAGE void delete_output_dev() {
delete AOut;
AOut=NULL;
}
LINKAGE int get_info(int* num_pages) {
if(doc) {
*num_pages=doc->getNumPages();
return 1;
} else {
*num_pages=1;
return 0;
}
}
LINKAGE int get_page_size(int page,int* width,int* height) {
if(doc) {
int w=int(doc->getPageWidth(page)+0.5);
int h=int(doc->getPageHeight(page)+0.5);
int r=doc->getPageRotate(page);
if(r==90 || r==270) {
*width=h;
*height=w;
} else {
*width=w;
*height=h;
}
return 1;
} else {
*width=612;
*height=792;
return 0;
}
}
LINKAGE int simple_find(const char* str,int top,int* xmin,int* ymin,int* xmax,int* ymax) {
try {
if(AOut && AOut->findText((char*)str,top,gTrue,xmin,ymin,xmax,ymax))
return 1;
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
return 0;
}
static char* find_str;
static TextOutputDev* find_dev;
LINKAGE void end_find() {
delete find_dev;
find_dev=NULL;
gfree(find_str);
find_str=NULL;
}
LINKAGE int init_find(const char* str) {
try {
find_str=copyString((char*)str);
find_dev=new TextOutputDev(NULL,gFalse);
if(find_dev->isOk())
return 1;
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
end_find();
return 0;
}
LINKAGE int find(int start,int stop,int* xmin,int* ymin,int* xmax,int* ymax,int* page) {
int r=0;
try {
if(find_dev && find_str) {
for(int pg=start;pg<stop;++pg) {
double x1,x2,y1,y2;
doc->displayPage(find_dev,pg,72,0,gFalse);
if(find_dev->findText(find_str,gTrue,gTrue,&x1,&y1,&x2,&y2)) {
r=1;
*page=pg;
break;
}
}
}
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
return r;
}
LINKAGE int chklink(int mx,int my,void** maction,char* str,size_t len) {
int r=0;
try {
double x,y;
LinkAction *action;
const char *s;
if(doc && AOut) {
AOut->cvtDevToUser(mx,my,&x,&y);
if(action=doc->findLink(x,y)) {
if(action!=*maction) {
*maction=action;
s=NULL;
switch(action->getKind()) {
case actionGoTo:
s="[internal link]";
break;
case actionGoToR:
s=((LinkGoToR*)action)->getFileName()->getCString();
break;
case actionLaunch:
s=((LinkLaunch*)action)->getFileName()->getCString();
break;
case actionURI:
s=((LinkURI*)action)->getURI()->getCString();
break;
case actionUnknown:
s="[unknown link]";
break;
}
strncpy(str,s,len-1);
str[len-1]='\0';
}
r=1;
}
}
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
return r;
}
LINKAGE int dolink(int* mx,int* my,int* state,int* page,char* buf,size_t len) {
int r=0;
*state=st_unchanged;
*page=-1;
LinkDest* dest=NULL;
GString* namedDest=NULL;
GString* fileName=NULL;
PDFDoc* d=NULL;
try {
double x,y;
AOut->cvtDevToUser(*mx,*my,&x,&y);
*mx=-1;
*my=-1;
if(LinkAction* action=doc->findLink(x,y)) {
switch(LinkActionKind kind=action->getKind()) {
// GoTo / GoToR action
case actionGoTo:
case actionGoToR:
if(kind==actionGoTo) {
if(dest=((LinkGoTo*)action)->getDest())
dest=dest->copy();
else if(namedDest=((LinkGoTo*)action)->getNamedDest())
namedDest=namedDest->copy();
} else {
if(dest=((LinkGoToR*)action)->getDest())
dest=dest->copy();
else if(namedDest=((LinkGoToR*)action)->getNamedDest())
namedDest=namedDest->copy();
char* s=((LinkGoToR*)action)->getFileName()->getCString();
//~ translate path name for VMS (deal with '/')
/*if (isAbsolutePath(s))
fileName = new GString(s);
else
fileName = appendToPath(grabPath(doc->getFileName()->getCString()), s);*/
fileName=new GString(s);
d=new PDFDoc(fileName);
fileName=NULL;
if(d->isOk()) {
delete doc;
doc=d;
d=NULL;
strncpy(buf,fileName->getCString(),len-1);
buf[len-1]='\0';
*state=st_changed;
*page=1;
} else
break;
}
if(namedDest) {
dest=doc->findDest(namedDest);
//delete namedDest;
//namedDest=NULL;
}
if(!dest) {
if(kind==actionGoToR)
*page=1;
} else {
Ref pageRef;
if(dest->isPageRef()) {
pageRef=dest->getPageRef();
*page=doc->findPage(pageRef.num,pageRef.gen);
} else
*page=dest->getPageNum();
switch(dest->getKind()) {
case destXYZ: {
int dx,dy;
AOut->cvtUserToDev(dest->getLeft(),dest->getTop(),&dx,&dy);
if(dest->getChangeLeft() || dest->getChangeTop()) {
if(dest->getChangeLeft())
*mx=dx;
if(dest->getChangeTop())
*my=dy;
}
//~ what is the zoom parameter?
break;
}
case destFit:
case destFitB:
//~ do fit
*mx=0;
*my=0;
break;
case destFitH:
case destFitBH:
//~ do fit
AOut->cvtUserToDev(0,dest->getTop(),mx,my);
break;
case destFitV:
case destFitBV:
//~ do fit
AOut->cvtUserToDev(dest->getLeft(),0,mx,my);
break;
case destFitR:
//~ do fit
AOut->cvtUserToDev(dest->getLeft(),dest->getTop(),mx,my);
break;
}
//delete dest;
//dest=NULL;
}
r=1;
break;
// Launch action
case actionLaunch: {
fileName=((LinkLaunch *)action)->getFileName();
char* s=fileName->getCString();
if(!strcmp(s+fileName->getLength()-4,".pdf") ||
!strcmp(s+fileName->getLength()-4,".PDF")) {
//~ translate path name for VMS (deal with '/')
/*if (isAbsolutePath(s))
fileName = fileName->copy();
else
fileName = appendToPath(grabPath(doc->getFileName()->getCString()), s);*/
fileName=new GString(s);
d=new PDFDoc(fileName);
fileName=NULL;
if(d->isOk()) {
delete doc;
doc=d;
d=NULL;
strncpy(buf,fileName->getCString(),len-1);
buf[len-1]='\0';
*state=st_changed;
*page=1;
} else
break;
} else {
fileName=fileName->copy();
if(((LinkLaunch*)action)->getParams()) {
fileName->append(' ');
fileName->append(((LinkLaunch*)action)->getParams());
}
fileName->insert(0,"run ");
strncpy(buf,fileName->getCString(),len-1);
buf[len-1]='\0';
*state=st_run;
}
r=1;
break;
}
// URI action
case actionURI:
strncpy(buf,((LinkURI*)action)->getURI()->getCString(),len-1);
buf[len-1]='\0';
*state=st_url;
r=1;
break;
// unknown action type
case actionUnknown:
error(-1,"Unknown link action type: '%s'",((LinkUnknown *)action)->getAction()->getCString());
break;
}
}
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
delete d;
delete dest;
delete namedDest;
delete fileName;
return r;
}
static OutputDev* saveDev;
static int saveZoom;
static int saveRotate;
LINKAGE void end_write() {
delete saveDev;
saveDev=NULL;
}
LINKAGE int init_write(const char* filename,int first_page,int last_page,int zoom,int rotate,int type) {
int r=0;
if(doc) {
try {
switch(type) {
case 0: // Postscript
case 1: // Postscript Level 1
if(doc->okToPrint()) {
psOutLevel1=type==1;
saveDev=new PSOutputDev((char*)filename,doc->getCatalog(),
first_page,last_page,gTrue,gFalse);
}
break;
case 2: // Text
saveDev=new TextOutputDev((char*)filename,gFalse);
zoom=72;
rotate=0;
break;
case 3: // PBM/PPM images
case 4: // JPEG images
saveDev=new ImageOutputDev((char*)filename,type==4);
zoom=72;
rotate=0;
break;
}
saveZoom=zoom;
saveRotate=rotate;
r=saveDev->isOk();
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
if(!r)
end_write();
}
return r;
}
LINKAGE void writefile(int first_page,int last_page) {
if(doc && saveDev) {
try {
doc->displayPages(saveDev,first_page,last_page-1,saveZoom,saveRotate);
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
}
}
LINKAGE char* gettext(int minx,int miny,int maxx,int maxy) {
char* r=NULL;
if(doc && AOut) {
GString* s=NULL;
try {
s=AOut->getText(minx,miny,maxx,maxy);
size_t sz=s->getLength();
if(r=(char*)malloc(sz+1))
strcpy(r,s->getCString());
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
delete s;
}
return r;
}
LINKAGE int show_page(int page,int zoom) {
int r=0;
if(doc && AOut) {
try {
doc->displayPage(AOut,page,zoom,0,gTrue);
r=1;
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
gfx->flush();
}
return r;
}
LINKAGE void add_fontmap(const char* pdffont,
const char* afont,
int m,
int style,
int encoding) {
try {
for(int k=0;k<userFontMapLen;++k)
if(!strcmp(userFontMap[k].pdfFont,pdffont)) {
gfree(userFontMap[k].pdfFont);
gfree(userFontMap[k].xFont);
--userFontMapLen;
if(k!=userFontMapLen)
memmove(userFontMap+k,userFontMap+k+1,(userFontMapLen-k+1)*sizeof(FontMapEntry));
break;
}
if(userFontMapLen>=userFontMapSize-1) {
userFontMapSize+=8;
userFontMap=(FontMapEntry*)grealloc(userFontMap,userFontMapSize*sizeof(FontMapEntry));
}
userFontMap[userFontMapLen].pdfFont=copyString((char*)pdffont);
userFontMap[userFontMapLen].xFont=copyString((char*)afont);
userFontMap[userFontMapLen].mWidth=m;
userFontMap[userFontMapLen].style=style;
userFontMap[userFontMapLen].encoding=encoding;
userFontMap[++userFontMapLen].pdfFont=NULL;
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
}
#if 0
LINKAGE void rem_fontmap(const char* pdffont) {
for(int k=0;k<devFontMapLen;++k)
if(!strcmp(devFontMap[k].pdfFont,pdffont)) {
gfree(devFontMap[k].pdfFont);
gfree(devFontMap[k].devFont);
--devFontMapLen;
if(k!=devFontMapLen)
memmove(devFontMap+k,devFontMap+k+1,(devFontMapLen-k)*sizeof(DevFontMapEntry));
break;
}
}
LINKAGE void set_fontmap() {
//resetFontMap();
}
#endif
LINKAGE void end_scan_fonts() {
delete fOut;
fOut=NULL;
}
LINKAGE int init_scan() {
int r=0;
if(doc) {
try {
end_scan_fonts();
fOut=new FontOutputDev;
r=fOut->isOk();
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
if(r==0)
end_scan_fonts();
}
return r;
}
LINKAGE int scan_fonts(int first_page,int last_page) {
int r=0;
if(doc && fOut) {
try {
doc->displayPages(fOut,first_page,last_page-1,72,0);
r=fOut->size();
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
}
return r;
}
LINKAGE int scan_default_fonts() {
int r=0;
try {
if(fOut) {
delete fOut;
fOut=NULL;
}
fOut=new DefaultFontOutputDev;
if(fOut->isOk())
r=fOut->size();
}
catch(const char* msg) {
printf("Exception: %s\n",msg);
}
catch(...) {
printf("Exception caught.");
}
if(r==0) {
delete fOut;
fOut=NULL;
}
return r;
}
LINKAGE int get_font(int n,char* pdffont,int pdffontlen,
char* afont,int afontlen,
int* m,int* style,int* encoding) {
if(fOut) {
const char* p;
const char* q;
fOut->get(n,p,q,*m,*style,*encoding);
if(p) {
strncpy(pdffont,p,pdffontlen-1);
pdffont[pdffontlen-1]='\0';
strncpy(afont,q,afontlen-1);
afont[afontlen-1]='\0';
return 1;
} else
return 0;
} else
return 0;
}