f90da327a9
* BUG: PdfDocument.HasIndex does not return TRUE anymore when there is an index whose length is null. * BUG: Fix PdfIndex.HasChildren that sometimes returned TRUE when there was no children. * BUG: Fix PdfIndex.MoveChild() accordingly. git-svn-id: svn://localhost/gambas/trunk@1900 867c0c6c-44f3-4631-809d-bfa615b0a4ec
1482 lines
32 KiB
C++
1482 lines
32 KiB
C++
/***************************************************************************
|
|
|
|
CPdfDocument.cpp
|
|
|
|
gb.pdf Component
|
|
|
|
(C) 2005-2007 Daniel Campos Fernández <dcamposf@gmail.com>
|
|
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 1, or (at your option)
|
|
any later version.
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 1, or (at your option)
|
|
any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
***************************************************************************/
|
|
|
|
#define __CPDFDOCUMENT_C
|
|
|
|
#include "CPdfDocument.h"
|
|
|
|
#include "gambas.h"
|
|
#include "main.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdint.h>
|
|
#include <math.h>
|
|
|
|
#include <PDFDoc.h>
|
|
#include <Stream.h>
|
|
#include <ErrorCodes.h>
|
|
#include <Page.h>
|
|
#include <Catalog.h>
|
|
#include <TextOutputDev.h>
|
|
#include <SplashOutputDev.h>
|
|
#include <splash/SplashBitmap.h>
|
|
#include <goo/GooList.h>
|
|
#include <Outline.h>
|
|
#include <Link.h>
|
|
#include <Gfx.h>
|
|
|
|
/*****************************************************************************
|
|
|
|
Translations from Poppler universe to Gambas universe
|
|
|
|
******************************************************************************/
|
|
typedef struct
|
|
{
|
|
int32_t x0;
|
|
int32_t y0;
|
|
int32_t x1;
|
|
int32_t y1;
|
|
} FoundRect;
|
|
|
|
static void aux_return_string_info(void *_object, const char *key)
|
|
{
|
|
Object obj;
|
|
Object dst;
|
|
GooString *goo_value;
|
|
Dict *info_dict;
|
|
char *tmpstr;
|
|
|
|
THIS->doc->getDocInfo (&obj);
|
|
if (!obj.isDict()) { GB.ReturnNewZeroString(""); return; }
|
|
|
|
info_dict=obj.getDict();
|
|
info_dict->lookup ((char *)key, &dst);
|
|
if (!dst.isString ()) { GB.ReturnNewZeroString(""); }
|
|
else {
|
|
goo_value = dst.getString();
|
|
|
|
if (goo_value->hasUnicodeMarker())
|
|
{
|
|
GB.ConvString (&tmpstr,goo_value->getCString()+2,goo_value->getLength()-2,"UTF-16BE","UTF-8");
|
|
GB.ReturnNewZeroString(tmpstr);
|
|
}
|
|
else
|
|
GB.ReturnNewString(goo_value->getCString(),goo_value->getLength());
|
|
}
|
|
dst.free();
|
|
obj.free();
|
|
}
|
|
|
|
static void aux_return_date_info(void *_object, const char *key)
|
|
{
|
|
// TODO: Y2K effect
|
|
GB_DATE_SERIAL ds;
|
|
GB_DATE ret;
|
|
Object obj;
|
|
Object dst;
|
|
GooString *goo;
|
|
Dict *info_dict;
|
|
char *datestr=NULL,*tofree=NULL;
|
|
int nnum;
|
|
|
|
THIS->doc->getDocInfo (&obj);
|
|
if (!obj.isDict()) { GB.ReturnNull(); return; }
|
|
|
|
info_dict=obj.getDict();
|
|
info_dict->lookup ((char *)key, &dst);
|
|
if (!dst.isString ()) { GB.ReturnNull(); }
|
|
else {
|
|
goo = dst.getString();
|
|
if (goo->hasUnicodeMarker())
|
|
GB.ConvString (&datestr,goo->getCString()+2,goo->getLength()-2,"UTF-16BE","UTF-8");
|
|
else
|
|
{
|
|
GB.NewString(&datestr,goo->getCString(),goo->getLength());
|
|
tofree=datestr;
|
|
}
|
|
|
|
if (!datestr) { GB.ReturnNull(); }
|
|
else
|
|
{
|
|
if (datestr[0] == 'D' && datestr[1] == ':') datestr += 2;
|
|
nnum=sscanf(datestr, "%4hd%2hd%2hd%2hd%2hd%2hd",&ds.year, &ds.month, \
|
|
&ds.day, &ds.hour, &ds.min, &ds.sec);
|
|
if (nnum != 6) { GB.ReturnNull(); }
|
|
else
|
|
{
|
|
if (GB.MakeDate(&ds,&ret))
|
|
GB.ReturnNull();
|
|
else
|
|
GB.ReturnDate(&ret);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
if (tofree) GB.FreeString(&tofree);
|
|
dst.free();
|
|
obj.free();
|
|
}
|
|
|
|
static void aux_return_unicode_string(Unicode *uni, int32_t len)
|
|
{
|
|
int32_t bc;
|
|
char *ret=NULL;
|
|
|
|
for (bc=0; bc<len; bc++)
|
|
GB.AddString(&ret,(const char*)&uni[bc],0);
|
|
|
|
GB.ReturnNewString(ret,0);
|
|
GB.FreeString(&ret);
|
|
}
|
|
|
|
static LinkDest *get_dest(LinkAction *act)
|
|
{
|
|
switch (act->getKind())
|
|
{
|
|
case actionGoTo: return ((LinkGoTo*)act)->getDest();
|
|
case actionGoToR: return ((LinkGoToR*)act)->getDest();
|
|
default: return 0;
|
|
}
|
|
}
|
|
|
|
static uint32_t aux_get_page_from_action(void *_object, LinkAction *act)
|
|
{
|
|
// TODO: NamedDest
|
|
|
|
Ref pref;
|
|
LinkDest *dest = get_dest(act);
|
|
if (!dest)
|
|
return 0;
|
|
|
|
if (dest->isPageRef())
|
|
{
|
|
if (dest->isPageRef() )
|
|
{
|
|
pref= dest->getPageRef();
|
|
return THIS->doc->findPage(pref.num, pref.gen);
|
|
}
|
|
else
|
|
return dest->getPageNum();
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
static void aux_get_dimensions_from_action(LinkAction *act,int *left, int32_t *right, int32_t *top, int32_t *bottom)
|
|
{
|
|
LinkDest *dest = get_dest(act);
|
|
if (!dest)
|
|
{
|
|
if (left) *left=0;
|
|
if (right) *right=0;
|
|
if (top) *top=0;
|
|
if (bottom) *bottom=0;
|
|
return;
|
|
}
|
|
|
|
if (left) *left=(int32_t)dest->getLeft();
|
|
if (right) *right=(int32_t)dest->getRight();
|
|
if (top) *top=(int32_t)dest->getTop();
|
|
if (bottom) *bottom=(int32_t)dest->getBottom();
|
|
}
|
|
|
|
static double aux_get_zoom_from_action(LinkAction *act)
|
|
{
|
|
LinkDest *dest = get_dest(act);
|
|
if (dest)
|
|
return dest->getZoom();
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
static char* aux_get_target_from_action(LinkAction *act)
|
|
{
|
|
char *vl=NULL;
|
|
char *uni=NULL;
|
|
GooString *tmp=NULL;
|
|
|
|
switch (act->getKind())
|
|
{
|
|
case actionGoToR:
|
|
tmp=((LinkGoToR*)act)->getFileName(); break;
|
|
|
|
case actionLaunch:
|
|
tmp=((LinkLaunch*)act)->getFileName(); break;
|
|
|
|
case actionURI:
|
|
tmp=((LinkURI*)act)->getURI(); break;
|
|
|
|
case actionNamed:
|
|
tmp=((LinkNamed*)act)->getName(); break;
|
|
|
|
case actionMovie:
|
|
#if POPPLER_VERSION_0_8
|
|
tmp=((LinkMovie*)act)->getAnnotTitle(); break;
|
|
#else
|
|
tmp=((LinkMovie*)act)->getTitle(); break;
|
|
#endif
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (!tmp) return NULL;
|
|
|
|
if (tmp->hasUnicodeMarker())
|
|
{
|
|
GB.ConvString (&uni,tmp->getCString()+2,tmp->getLength()-2,"UTF-16BE","UTF-8");
|
|
GB.AddString (&vl,uni,0);
|
|
}
|
|
else
|
|
GB.AddString(&vl,tmp->getCString(),tmp->getLength());
|
|
|
|
|
|
return vl;
|
|
|
|
}
|
|
|
|
/*****************************************************************************
|
|
|
|
PDF document
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
static void free_all(void *_object)
|
|
{
|
|
if (THIS->doc)
|
|
{
|
|
delete THIS->doc;
|
|
THIS->doc=NULL;
|
|
}
|
|
|
|
if (THIS->dev)
|
|
{
|
|
delete THIS->dev;
|
|
THIS->dev=NULL;
|
|
}
|
|
|
|
if (THIS->buf)
|
|
{
|
|
GB.ReleaseFile(THIS->buf,THIS->len);
|
|
THIS->buf=NULL;
|
|
}
|
|
|
|
if (THIS->Found)
|
|
{
|
|
GB.FreeArray(POINTER(&THIS->Found));
|
|
THIS->Found=NULL;
|
|
}
|
|
|
|
if (THIS->links)
|
|
{
|
|
delete THIS->links;
|
|
THIS->links=NULL;
|
|
}
|
|
|
|
if (THIS->pindex)
|
|
{
|
|
GB.FreeArray(POINTER(&THIS->pindex));
|
|
GB.FreeArray(POINTER(&THIS->oldindex));
|
|
THIS->pindex=NULL;
|
|
THIS->oldindex=NULL;
|
|
}
|
|
|
|
THIS->index=NULL;
|
|
THIS->currpage=-1;
|
|
}
|
|
|
|
BEGIN_METHOD_VOID (PDFDOCUMENT_free)
|
|
|
|
free_all(_object);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_PROPERTY(PDFDOCUMENT_scale)
|
|
|
|
if (READ_PROPERTY){ GB.ReturnFloat(THIS->scale); return; }
|
|
|
|
if (VPROP(GB_FLOAT)>0) { THIS->scale = VPROP(GB_FLOAT); return; }
|
|
|
|
GB.Error("Zoom must be a positive value");
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFDOCUMENT_rotation)
|
|
|
|
int32_t rot;
|
|
|
|
if (READ_PROPERTY)
|
|
{
|
|
GB.ReturnInteger(THIS->rotation);
|
|
return;
|
|
}
|
|
|
|
rot=VPROP(GB_INTEGER);
|
|
|
|
while (rot<0) rot+=360;
|
|
while (rot>=360) rot-=360;
|
|
|
|
switch (rot)
|
|
{
|
|
case 0:
|
|
case 90:
|
|
case 180:
|
|
case 270:
|
|
THIS->rotation = VPROP(GB_INTEGER);
|
|
break;
|
|
}
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
int32_t open_document (void *_object, char *sfile, int32_t lfile)
|
|
{
|
|
SplashColor white;
|
|
PDFDoc *test;
|
|
MemStream *stream;
|
|
Object obj;
|
|
Outline *outline;
|
|
char *buf=NULL;
|
|
int32_t len=0;
|
|
int32_t ret;
|
|
|
|
|
|
if ( GB.LoadFile(sfile,lfile,&buf,&len) ) return -1;
|
|
|
|
obj.initNull();
|
|
stream=new MemStream(buf,0,(Guint)len,&obj);
|
|
test=new PDFDoc (stream,0,0);
|
|
|
|
if (!test->isOk())
|
|
{
|
|
GB.ReleaseFile(buf,len);
|
|
ret=test->getErrorCode();
|
|
delete test;
|
|
test=NULL;
|
|
if (ret == errEncrypted) return -2;
|
|
return -3;
|
|
}
|
|
|
|
free_all(_object);
|
|
|
|
THIS->doc=test;
|
|
THIS->buf=buf;
|
|
THIS->len=len;
|
|
|
|
white[0] = 0xFF; white[1] = 0xFF; white[2] = 0xFF;
|
|
THIS->dev=new SplashOutputDev(splashModeRGB8, 3, gFalse, white);
|
|
|
|
THIS->dev->startDoc(THIS->doc->getXRef ());
|
|
|
|
outline=THIS->doc->getOutline();
|
|
if (outline) THIS->index=outline->getItems();
|
|
|
|
//if (THIS->index)
|
|
// if (!THIS->index->getLength()) THIS->index=NULL;
|
|
|
|
THIS->currindex=0;
|
|
THIS->currpage=-1;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
BEGIN_METHOD(PDFDOCUMENT_new, GB_STRING File)
|
|
|
|
THIS->scale = 1;
|
|
THIS->rotation = 0;
|
|
|
|
if (!MISSING(File))
|
|
{
|
|
switch (open_document( _object, STRING(File), LENGTH(File)) )
|
|
{
|
|
case -1: GB.Error("File not found"); return;
|
|
case -2: GB.Error("PDF is encrypted"); return;
|
|
case -3: GB.Error("Bad PDF File"); return;
|
|
}
|
|
}
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD (PDFDOCUMENT_open, GB_STRING File;)
|
|
|
|
switch (open_document( _object, STRING(File), LENGTH(File)) )
|
|
{
|
|
case -1: GB.Error("File not found"); return;
|
|
case -2: GB.Error("PDF is encrypted"); return;
|
|
case -3: GB.Error("Bad PDF File"); return;
|
|
}
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD_VOID(PDFDOCUMENT_close)
|
|
|
|
free_all(_object);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD(PDFDOCUMENT_get,GB_INTEGER index;)
|
|
|
|
if (!THIS->doc || (VARG(index)<1) || ( VARG(index)>THIS->doc->getNumPages() ) )
|
|
{
|
|
GB.Error("Invalid page number");
|
|
GB.ReturnNull();
|
|
return;
|
|
}
|
|
|
|
if (THIS->currpage != (uint32_t)VARG(index) )
|
|
{
|
|
if (THIS->Found)
|
|
{
|
|
GB.FreeArray(POINTER(&THIS->Found));
|
|
THIS->Found=NULL;
|
|
}
|
|
|
|
if (THIS->links)
|
|
{
|
|
delete THIS->links;
|
|
THIS->links=NULL;
|
|
}
|
|
|
|
THIS->page=THIS->doc->getCatalog()->getPage(VARG(index));
|
|
THIS->currpage=VARG(index);
|
|
}
|
|
|
|
RETURN_SELF();
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_PROPERTY(PDFDOCUMENT_ready)
|
|
|
|
GB.ReturnBoolean( (bool)THIS->doc );
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFDOCUMENT_count)
|
|
|
|
GB.ReturnInteger( (int32_t) (THIS->doc ? THIS->doc->getNumPages() : 0));
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFDOCUMENT_info)
|
|
|
|
if (THIS->doc) RETURN_SELF();
|
|
else GB.ReturnNull();
|
|
|
|
END_PROPERTY
|
|
|
|
/*****************************************************************************
|
|
|
|
PDF document information
|
|
|
|
******************************************************************************/
|
|
|
|
BEGIN_PROPERTY(PDFINFO_title)
|
|
|
|
aux_return_string_info(_object,"Title");
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_format)
|
|
|
|
char *ctx=NULL;
|
|
|
|
GB.Alloc(POINTER(&ctx),16*sizeof(char));
|
|
snprintf(ctx,16*sizeof(char),"%.2g",THIS->doc->getPDFVersion());
|
|
GB.ReturnNewZeroString(ctx);
|
|
GB.Free(POINTER(&ctx));
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_author)
|
|
|
|
aux_return_string_info(_object,"Author");
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_subject)
|
|
|
|
aux_return_string_info(_object,"Subject");
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_keywords)
|
|
|
|
aux_return_string_info(_object,"Keywords");
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_creator)
|
|
|
|
aux_return_string_info(_object,"Creator");
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_producer)
|
|
|
|
aux_return_string_info(_object,"Producer");
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_linearized)
|
|
|
|
GB.ReturnBoolean(THIS->doc->isLinearized());
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_layout)
|
|
|
|
Catalog *catalog;
|
|
|
|
catalog=THIS->doc->getCatalog();
|
|
if (!catalog) { GB.ReturnInteger(Catalog::pageLayoutNone); return; }
|
|
if (!catalog->isOk()) { GB.ReturnInteger(Catalog::pageLayoutNone); return; }
|
|
|
|
GB.ReturnInteger(catalog->getPageLayout());
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_mode)
|
|
|
|
Catalog *catalog;
|
|
|
|
catalog=THIS->doc->getCatalog();
|
|
if (!catalog) { GB.ReturnInteger(Catalog::pageModeNone); return; }
|
|
if (!catalog->isOk()) { GB.ReturnInteger(Catalog::pageModeNone); return; }
|
|
|
|
GB.ReturnInteger(catalog->getPageMode());
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_canprint)
|
|
|
|
GB.ReturnBoolean(THIS->doc->okToPrint());
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_canmodify)
|
|
|
|
GB.ReturnBoolean(THIS->doc->okToChange());
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_cancopy)
|
|
|
|
GB.ReturnBoolean(THIS->doc->okToCopy());
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_canaddnotes)
|
|
|
|
GB.ReturnBoolean(THIS->doc->okToAddNotes());
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_creation)
|
|
|
|
aux_return_date_info(_object,"CreationDate");
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINFO_modification)
|
|
|
|
aux_return_date_info(_object,"ModDate");
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
/*****************************************************************************
|
|
|
|
PDF document index
|
|
|
|
******************************************************************************/
|
|
|
|
|
|
BEGIN_PROPERTY(PDFDOCUMENT_has_index)
|
|
|
|
GB.ReturnBoolean(THIS->index && THIS->index->getLength());
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFDOCUMENT_index)
|
|
|
|
if (!THIS->index) { GB.ReturnNull(); return; }
|
|
|
|
THIS->action=((OutlineItem*)THIS->index->get(THIS->currindex))->getAction();
|
|
RETURN_SELF();
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINDEX_count)
|
|
|
|
GB.ReturnInteger(THIS->index->getLength());
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINDEX_has_children)
|
|
|
|
OutlineItem *item;
|
|
|
|
item = (OutlineItem *)THIS->index->get (THIS->currindex);
|
|
GB.ReturnBoolean(item->getKids() && item->getKids()->getLength());
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINDEX_is_open)
|
|
|
|
OutlineItem *item;
|
|
|
|
item = (OutlineItem *)THIS->index->get (THIS->currindex);
|
|
|
|
if (READ_PROPERTY)
|
|
{ GB.ReturnBoolean(item->isOpen()); return; }
|
|
|
|
if (VPROP(GB_INTEGER)) item->open();
|
|
else item->close();
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFINDEX_title)
|
|
|
|
OutlineItem *item;
|
|
|
|
item = (OutlineItem *)THIS->index->get (THIS->currindex);
|
|
aux_return_unicode_string(item->getTitle(),item->getTitleLength());
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
BEGIN_METHOD_VOID(PDFINDEX_root)
|
|
|
|
Outline *outline;
|
|
|
|
outline=THIS->doc->getOutline();
|
|
if (outline) THIS->index=outline->getItems();
|
|
THIS->currindex=0;
|
|
if (THIS->pindex) { GB.FreeArray(POINTER(&THIS->pindex)); THIS->pindex=NULL; }
|
|
if (THIS->oldindex) { GB.FreeArray(POINTER(&THIS->oldindex)); THIS->oldindex=NULL; }
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD_VOID(PDFINDEX_prev)
|
|
|
|
if (!THIS->currindex) { GB.ReturnBoolean(true); return; }
|
|
|
|
THIS->currindex--;
|
|
GB.ReturnBoolean(false);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD_VOID(PDFINDEX_next)
|
|
|
|
if ( (THIS->currindex+1) >= (uint32_t)THIS->index->getLength() )
|
|
{ GB.ReturnBoolean(true); return; }
|
|
|
|
THIS->currindex++;
|
|
GB.ReturnBoolean(false);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD_VOID(PDFINDEX_child)
|
|
|
|
OutlineItem *item;
|
|
|
|
item = (OutlineItem *)THIS->index->get (THIS->currindex);
|
|
|
|
if (!item->hasKids() || item->getKids()->getLength() == 0) { GB.ReturnBoolean(true); return; }
|
|
|
|
if (THIS->pindex)
|
|
{
|
|
GB.Add(POINTER(&THIS->pindex));
|
|
GB.Add(POINTER(&THIS->oldindex));
|
|
}
|
|
else
|
|
{
|
|
GB.NewArray(POINTER(&THIS->pindex),sizeof(void*),1);
|
|
GB.NewArray(POINTER(&THIS->oldindex),sizeof(uint32_t),1);
|
|
}
|
|
|
|
if (!item->isOpen()) item->open();
|
|
THIS->pindex[GB.Count(POINTER(THIS->pindex))-1]=(void*)THIS->index;
|
|
THIS->oldindex[GB.Count(POINTER(THIS->pindex))-1]=THIS->currindex;
|
|
THIS->index=item->getKids();
|
|
THIS->currindex=0;
|
|
|
|
GB.ReturnBoolean(false);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_METHOD_VOID(PDFINDEX_parent)
|
|
|
|
if (!THIS->pindex) { GB.ReturnBoolean(true); return; }
|
|
|
|
THIS->index=(GooList*)THIS->pindex[GB.Count(POINTER(THIS->pindex))-1];
|
|
THIS->currindex=THIS->oldindex[GB.Count(POINTER(THIS->pindex))-1];
|
|
if (GB.Count(POINTER(THIS->pindex))==1)
|
|
{
|
|
GB.FreeArray(POINTER(&THIS->pindex));
|
|
GB.FreeArray(POINTER(&THIS->oldindex));
|
|
THIS->oldindex=NULL;
|
|
THIS->pindex=NULL;
|
|
}
|
|
else
|
|
{
|
|
GB.Remove(POINTER(&THIS->pindex),GB.Count(POINTER(THIS->pindex))-1,1);
|
|
GB.Remove(POINTER(&THIS->oldindex),GB.Count(POINTER(THIS->oldindex))-1,1);
|
|
}
|
|
|
|
GB.ReturnBoolean(false);
|
|
|
|
END_METHOD
|
|
|
|
/*****************************************************************************
|
|
|
|
PDF pages
|
|
|
|
******************************************************************************/
|
|
|
|
BEGIN_PROPERTY (PDFPAGE_width)
|
|
|
|
if ( (THIS->rotation==90) || (THIS->rotation==270) )
|
|
GB.ReturnInteger((int32_t)(THIS->page->getMediaHeight()*THIS->scale));
|
|
else
|
|
GB.ReturnInteger((int32_t)(THIS->page->getMediaWidth()*THIS->scale));
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY (PDFPAGE_height)
|
|
|
|
if ( (THIS->rotation==90) || (THIS->rotation==270) )
|
|
GB.ReturnInteger((int32_t)(THIS->page->getMediaWidth()*THIS->scale));
|
|
else
|
|
GB.ReturnInteger((int32_t)(THIS->page->getMediaHeight()*THIS->scale));
|
|
|
|
END_PROPERTY
|
|
|
|
static uint32_t *get_page_data(CPDFDOCUMENT *_object, int32_t x, int32_t y, int32_t *width, int32_t *height, double scale, int32_t rotation)
|
|
{
|
|
SplashBitmap *map;
|
|
uint32_t *data;
|
|
int32_t w, h;
|
|
int32_t rw;
|
|
int32_t rh;
|
|
|
|
if ( (THIS->rotation==90) || (THIS->rotation==270) )
|
|
{
|
|
rh=(int32_t)(THIS->page->getMediaWidth()*THIS->scale);
|
|
rw=(int32_t)(THIS->page->getMediaHeight()*THIS->scale);
|
|
}
|
|
else
|
|
{
|
|
rw=(int32_t)(THIS->page->getMediaWidth()*THIS->scale);
|
|
rh=(int32_t)(THIS->page->getMediaHeight()*THIS->scale);
|
|
}
|
|
|
|
w = *width;
|
|
h = *height;
|
|
|
|
if (w < 0) w = rw;
|
|
if (h < 0) h = rh;
|
|
|
|
if (x<0) x=0;
|
|
if (y<0) y=0;
|
|
if (w<1) w=1;
|
|
if (h<1) h=1;
|
|
|
|
|
|
if ( (x+w) > rw ) w=rw-x;
|
|
if ( (y+h) > rh ) h=rh-y;
|
|
|
|
if ( (w<0) || (h<0) ) return NULL;
|
|
|
|
THIS->page->displaySlice(THIS->dev,72.0*scale,72.0*scale,
|
|
rotation,
|
|
gFalse,
|
|
gTrue,
|
|
x,y,w,h,
|
|
gFalse,
|
|
THIS->doc->getCatalog ());
|
|
|
|
map=THIS->dev->getBitmap();
|
|
|
|
data=(uint32_t*)map->getDataPtr();
|
|
|
|
|
|
*width = w;
|
|
*height = h;
|
|
|
|
return data;
|
|
}
|
|
|
|
BEGIN_METHOD(PDFPAGE_image, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)
|
|
|
|
uint32_t *data;
|
|
int32_t x,y, w, h;
|
|
|
|
x = VARGOPT(x, 0);
|
|
y = VARGOPT(y, 0);
|
|
w = VARGOPT(w, -1);
|
|
h = VARGOPT(h, -1);
|
|
|
|
data = get_page_data(THIS, x, y, &w, &h, THIS->scale, THIS->rotation);
|
|
if (!data) { GB.ReturnNull(); return; }
|
|
/*GB.Image.Create(&img, data, w, h, GB_IMAGE_RGB);
|
|
GB.ReturnObject(img);*/
|
|
|
|
GB.ReturnObject(IMAGE.Create(w, h, GB_IMAGE_RGB, (unsigned char *)data));
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_PROPERTY (PDFPAGE_property_image)
|
|
|
|
int32_t w=-1;
|
|
int32_t h=-1;
|
|
uint32_t *data;
|
|
|
|
data = get_page_data(THIS, 0, 0, &w, &h, THIS->scale, THIS->rotation);
|
|
if (!data) { GB.ReturnNull(); return; }
|
|
/*GB.Image.Create(&img, data, w, h, GB_IMAGE_RGB);
|
|
GB.ReturnObject(img);*/
|
|
|
|
GB.ReturnObject(IMAGE.Create(w, h, GB_IMAGE_RGB, (unsigned char *)data));
|
|
|
|
END_PROPERTY
|
|
|
|
|
|
/*BEGIN_METHOD(PDFPAGE_picture, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)
|
|
|
|
GB_IMAGE img = NULL;
|
|
uint32_t *data;
|
|
int32_t x,y, w, h;
|
|
|
|
x = VARGOPT(x, 0);
|
|
y = VARGOPT(y, 0);
|
|
w = VARGOPT(w, -1);
|
|
h = VARGOPT(h, -1);
|
|
|
|
data = get_page_data(THIS, x, y, &w, &h, THIS->scale, THIS->rotation);
|
|
if (!data) { GB.ReturnNull(); return; }
|
|
GB.Picture.Create(&img, data, w, h, GB_IMAGE_RGB);
|
|
GB.ReturnObject(img);
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_PROPERTY (PDFPAGE_property_picture)
|
|
|
|
int32_t w=-1;
|
|
int32_t h=-1;
|
|
GB_IMAGE img = NULL;
|
|
uint32_t *data;
|
|
|
|
data = get_page_data(THIS, 0, 0, &w, &h, THIS->scale, THIS->rotation);
|
|
if (!data) { GB.ReturnNull(); return; }
|
|
GB.Picture.Create(&img, data, w, h, GB_IMAGE_RGB);
|
|
GB.ReturnObject(img);
|
|
|
|
END_PROPERTY*/
|
|
|
|
BEGIN_METHOD(PDFPAGE_select, GB_INTEGER X; GB_INTEGER Y; GB_INTEGER W; GB_INTEGER H)
|
|
|
|
TextOutputDev *dev;
|
|
GooString *str;
|
|
Gfx *gfx;
|
|
int32_t x,y,w,h;
|
|
|
|
x = VARGOPT(X, 0);
|
|
y = VARGOPT(Y, 0);
|
|
w = VARGOPT(W, (int32_t)THIS->page->getMediaWidth());
|
|
h = VARGOPT(H, (int32_t)THIS->page->getMediaHeight());
|
|
|
|
dev = new TextOutputDev (NULL, gTrue, gFalse, gFalse);
|
|
gfx = THIS->page->createGfx(dev,72.0,72.0,0,gFalse,gTrue,-1, -1, -1, -1, \
|
|
gFalse,THIS->doc->getCatalog (),NULL, NULL, NULL, NULL);
|
|
|
|
THIS->page->display(gfx);
|
|
dev->endPage();
|
|
|
|
str=dev->getText((double)x,(double)y,(double)(w+x),(double)(h+y));
|
|
|
|
delete gfx;
|
|
delete dev;
|
|
|
|
if (!str)
|
|
{
|
|
GB.ReturnNewZeroString("");
|
|
return;
|
|
}
|
|
|
|
GB.ReturnNewString(str->getCString(),str->getLength());
|
|
delete str;
|
|
|
|
END_METHOD
|
|
|
|
/*****************************************************************************
|
|
|
|
Bookmarks of a PDF page
|
|
|
|
******************************************************************************/
|
|
void aux_fill_links(void *_object)
|
|
{
|
|
Object obj;
|
|
|
|
THIS->links = new Links (THIS->page->getAnnots (&obj),THIS->doc->getCatalog()->getBaseURI ());
|
|
obj.free();
|
|
}
|
|
|
|
BEGIN_PROPERTY (PDFPAGELINKS_count)
|
|
|
|
if (!THIS->links) aux_fill_links(_object);
|
|
if (!THIS->links) { GB.ReturnInteger(0); return; }
|
|
GB.ReturnInteger(THIS->links->getNumLinks());
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_METHOD (PDFPAGELINKS_get,GB_INTEGER ind;)
|
|
|
|
bool pok=true;
|
|
|
|
if (!THIS->links) aux_fill_links(_object);
|
|
if (!THIS->links) pok=false;
|
|
else
|
|
{
|
|
if (VARG(ind)<0) pok=false;
|
|
else
|
|
{
|
|
if (VARG(ind)>=THIS->links->getNumLinks()) pok=false;
|
|
}
|
|
}
|
|
|
|
if (!pok) { GB.Error("Out of bounds"); GB.ReturnNull(); return; }
|
|
|
|
THIS->lcurrent=VARG(ind);
|
|
THIS->action=THIS->links->getLink(THIS->lcurrent)->getAction();
|
|
|
|
RETURN_SELF();
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_PROPERTY (PDFPAGELINKDATA_parameters)
|
|
|
|
if (THIS->action->getKind() != actionLaunch )
|
|
{
|
|
GB.ReturnNewZeroString("");
|
|
return;
|
|
}
|
|
|
|
GB.ReturnNewZeroString(((LinkLaunch*)THIS->action)->getParams()->getCString());
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY (PDFPAGELINKDATA_uri)
|
|
|
|
char *uri;
|
|
|
|
uri=aux_get_target_from_action(THIS->action);
|
|
|
|
GB.ReturnNewZeroString(uri);
|
|
if (uri) GB.FreeString(&uri);
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFPAGELINKDATA_left)
|
|
|
|
int32_t vl;
|
|
|
|
aux_get_dimensions_from_action(THIS->action,&vl, NULL, NULL, NULL);
|
|
GB.ReturnInteger(vl);
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFPAGELINKDATA_right)
|
|
|
|
int32_t vl;
|
|
|
|
aux_get_dimensions_from_action(THIS->action,NULL,&vl, NULL, NULL);
|
|
GB.ReturnInteger(vl);
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFPAGELINKDATA_top)
|
|
|
|
int32_t vl;
|
|
|
|
aux_get_dimensions_from_action(THIS->action,NULL,NULL,&vl, NULL);
|
|
GB.ReturnInteger(vl);
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFPAGELINKDATA_bottom)
|
|
|
|
int32_t vl;
|
|
|
|
aux_get_dimensions_from_action(THIS->action,NULL, NULL, NULL,&vl);
|
|
|
|
GB.ReturnInteger(vl);
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFPAGELINKDATA_zoom)
|
|
|
|
GB.ReturnFloat(aux_get_zoom_from_action(THIS->action));
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY(PDFPAGELINKDATA_page)
|
|
|
|
GB.ReturnInteger(aux_get_page_from_action(_object,THIS->action));
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY (PDFPAGELINKDATA_type)
|
|
|
|
GB.ReturnInteger ( (int32_t)THIS->action->getKind() );
|
|
|
|
END_PROPERTY
|
|
|
|
void aux_get_link_dimensions(void *_object,int32_t *left, int32_t *top, int32_t *width, int32_t *height)
|
|
{
|
|
double l,t,w,h;
|
|
double pw,ph;
|
|
|
|
pw=THIS->page->getMediaWidth();
|
|
ph=THIS->page->getMediaHeight();
|
|
|
|
THIS->links->getLink(THIS->lcurrent)->getRect(&l, &t, &w, &h);
|
|
w=w-l;
|
|
h=h-t;
|
|
|
|
switch (THIS->rotation)
|
|
{
|
|
case 0:
|
|
if (left) *left=(int32_t)(l*THIS->scale);
|
|
if (top) *top=(int32_t)((ph-t-h)*THIS->scale);
|
|
if (width) *width=(int32_t)(w*THIS->scale);
|
|
if (height) *height=(int32_t)(h*THIS->scale);
|
|
break;
|
|
|
|
case 90:
|
|
if (top) *top=(int32_t)(l*THIS->scale);
|
|
if (left) *left=(int32_t)(t*THIS->scale);
|
|
if (height) *height=(int32_t)(w*THIS->scale);
|
|
if (width) *width=(int32_t)(h*THIS->scale);
|
|
break;
|
|
|
|
case 180:
|
|
if (left) *left=(int32_t)((l-w)*THIS->scale);
|
|
if (top) *top=(int32_t)(t*THIS->scale);
|
|
if (width) *width=(int32_t)(w*THIS->scale);
|
|
if (height) *height=(int32_t)(h*THIS->scale);
|
|
break;
|
|
|
|
case 270:
|
|
if (top) *top=(int32_t)((pw-l-w)*THIS->scale);
|
|
if (left) *left=(int32_t)((ph-t-h)*THIS->scale);
|
|
if (height) *height=(int32_t)(w*THIS->scale);
|
|
if (width) *width=(int32_t)(h*THIS->scale);
|
|
break;
|
|
}
|
|
|
|
}
|
|
|
|
BEGIN_PROPERTY (PDFPAGELINK_width)
|
|
|
|
int32_t vl;
|
|
|
|
aux_get_link_dimensions(_object,NULL,NULL,&vl,NULL);
|
|
GB.ReturnInteger(vl);
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY (PDFPAGELINK_height)
|
|
|
|
int32_t vl;
|
|
|
|
aux_get_link_dimensions(_object,NULL,NULL,NULL,&vl);
|
|
GB.ReturnInteger(vl);
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY (PDFPAGELINK_left)
|
|
|
|
int32_t vl;
|
|
|
|
aux_get_link_dimensions(_object,&vl,NULL,NULL,NULL);
|
|
GB.ReturnInteger(vl);
|
|
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY (PDFPAGELINK_top)
|
|
|
|
int32_t vl;
|
|
|
|
aux_get_link_dimensions(_object,NULL,&vl,NULL,NULL);
|
|
GB.ReturnInteger(vl);
|
|
|
|
END_PROPERTY
|
|
|
|
/*****************************************************************************
|
|
|
|
Finding a text in a PDF page
|
|
|
|
******************************************************************************/
|
|
|
|
BEGIN_METHOD (PDFPAGE_find,GB_STRING Text; GB_BOOLEAN Sensitive;)
|
|
|
|
TextOutputDev *textdev;
|
|
double x0=0, y0=0;
|
|
double x1, y1;
|
|
FoundRect *el;
|
|
Unicode *block=NULL;
|
|
int32_t nlen=0;
|
|
bool sensitive=false;
|
|
|
|
// TODO: Use UCS-4BE on big endian systems?
|
|
if (GB.ConvString ((char **)(void *)&block,STRING(Text),LENGTH(Text),"UTF-8","UCS-4LE"))
|
|
{
|
|
GB.Error("Invalid UTF-8 string");
|
|
return;
|
|
}
|
|
|
|
nlen=GB.StringLength((char*)block)/sizeof(Unicode);
|
|
|
|
if (!MISSING(Sensitive)) sensitive=VARG(Sensitive);
|
|
|
|
textdev = new TextOutputDev (NULL, true, false, false);
|
|
THIS->page->display (textdev, 72, 72, 0, false, false, false, THIS->doc->getCatalog());
|
|
|
|
if (THIS->Found) { GB.FreeArray(POINTER(&THIS->Found)); THIS->Found=NULL; }
|
|
|
|
while (textdev->findText (block,nlen,gFalse,gTrue,gTrue,gFalse,sensitive,gFalse,&x0,&y0,&x1,&y1))
|
|
{
|
|
if (!THIS->Found) {
|
|
GB.NewArray(POINTER(&THIS->Found),sizeof(FoundRect),1);
|
|
}
|
|
else {
|
|
GB.Add(POINTER(&THIS->Found));
|
|
}
|
|
|
|
el=(FoundRect*)&((FoundRect*)THIS->Found)[GB.Count(POINTER(THIS->Found))-1];
|
|
|
|
switch (THIS->rotation)
|
|
{
|
|
case 0:
|
|
el->x0=(int32_t)(x0*THIS->scale);
|
|
el->y0=(int32_t)(y0*THIS->scale);
|
|
el->x1=(int32_t)((x1-x0)*THIS->scale);
|
|
el->y1=(int32_t)((y1-y0)*THIS->scale);
|
|
break;
|
|
|
|
case 90:
|
|
el->y1=(int32_t)((x1-x0)*THIS->scale);
|
|
el->x1=(int32_t)(y1-y0);
|
|
el->y0=(int32_t)(x0*THIS->scale);
|
|
el->x0=(int32_t)((THIS->page->getMediaHeight()-y0-el->x1)*THIS->scale);
|
|
el->x1=(int32_t)(el->x1*THIS->scale);
|
|
break;
|
|
|
|
case 180:
|
|
el->x1=(int32_t)(x1-x0);
|
|
el->y1=(int32_t)(y1-y0);
|
|
el->x0=(int32_t)((THIS->page->getMediaWidth()-x0-el->x1)*THIS->scale);
|
|
el->y0=(int32_t)((THIS->page->getMediaHeight()-y0-el->y1)*THIS->scale);
|
|
el->x1=(int32_t)(el->x1*THIS->scale);
|
|
el->y1=(int32_t)(el->y1*THIS->scale);
|
|
break;
|
|
|
|
case 270:
|
|
el->x1=(int32_t)((y1-y0)*THIS->scale);
|
|
el->y1=(int32_t)(x1-x0);
|
|
el->x0=(int32_t)(y0*THIS->scale);
|
|
el->y0=(int32_t)((THIS->page->getMediaWidth()-x0-el->y1)*THIS->scale);
|
|
el->y1=(int32_t)(el->y1*THIS->scale);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
delete textdev;
|
|
|
|
|
|
END_METHOD
|
|
|
|
|
|
BEGIN_METHOD (PDFPAGERESULT_get,GB_INTEGER Index;)
|
|
|
|
bool bok=true;
|
|
|
|
if (!THIS->Found) bok=false;
|
|
else
|
|
{
|
|
if (VARG(Index)<0) bok=false;
|
|
if (VARG(Index)>= GB.Count(POINTER(THIS->Found)) ) bok=false;
|
|
}
|
|
if (!bok) { GB.Error("Out of bounds"); GB.ReturnNull(); return; }
|
|
|
|
THIS->fcurrent=VARG(Index);
|
|
RETURN_SELF();
|
|
|
|
END_METHOD
|
|
|
|
BEGIN_PROPERTY (PDFPAGERESULT_count)
|
|
|
|
if (!THIS->Found) { GB.ReturnInteger(0); return; }
|
|
GB.ReturnInteger( GB.Count(POINTER(THIS->Found)) );
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY (PDFPAGERESULT_width)
|
|
|
|
FoundRect *el=(FoundRect*)&((FoundRect*)THIS->Found)[THIS->fcurrent];
|
|
GB.ReturnInteger((int32_t)el->x1);
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY (PDFPAGERESULT_height)
|
|
|
|
FoundRect *el=(FoundRect*)&((FoundRect*)THIS->Found)[THIS->fcurrent];
|
|
GB.ReturnInteger((int32_t)el->y1);
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY (PDFPAGERESULT_left)
|
|
|
|
FoundRect *el=(FoundRect*)&((FoundRect*)THIS->Found)[THIS->fcurrent];
|
|
GB.ReturnInteger((int32_t)el->x0);
|
|
|
|
END_PROPERTY
|
|
|
|
BEGIN_PROPERTY (PDFPAGERESULT_top)
|
|
|
|
FoundRect *el=(FoundRect*)&((FoundRect*)THIS->Found)[THIS->fcurrent];
|
|
GB.ReturnInteger((int32_t)el->y0);
|
|
|
|
END_PROPERTY
|
|
|
|
/**********************************************************************
|
|
|
|
Gambas Interface
|
|
|
|
***********************************************************************/
|
|
|
|
|
|
GB_DESC PdfResultItemDesc[]=
|
|
{
|
|
GB_DECLARE(".PdfResultItem",0), GB_VIRTUAL_CLASS(),
|
|
|
|
GB_PROPERTY_READ("Left","i",PDFPAGERESULT_left),
|
|
GB_PROPERTY_READ("Top","i",PDFPAGERESULT_top),
|
|
GB_PROPERTY_READ("Width","i",PDFPAGERESULT_width),
|
|
GB_PROPERTY_READ("Height","i",PDFPAGERESULT_height),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
GB_DESC PdfResultDesc[]=
|
|
{
|
|
GB_DECLARE(".PdfResult",0), GB_VIRTUAL_CLASS(),
|
|
|
|
GB_METHOD("_get",".PdfResultItem",PDFPAGERESULT_get,"(Index)i"),
|
|
GB_PROPERTY_READ("Count","i",PDFPAGERESULT_count),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
|
|
GB_DESC PdfLinkDataDesc[]=
|
|
{
|
|
GB_DECLARE(".PdfLinkData",0), GB_VIRTUAL_CLASS(),
|
|
|
|
GB_PROPERTY_READ("Type","i",PDFPAGELINKDATA_type),
|
|
GB_PROPERTY_READ("Target","s",PDFPAGELINKDATA_uri),
|
|
GB_PROPERTY_READ("Parameters","s",PDFPAGELINKDATA_parameters),
|
|
GB_PROPERTY_READ("Page","i",PDFPAGELINKDATA_page),
|
|
GB_PROPERTY_READ("Left","i",PDFPAGELINKDATA_left),
|
|
GB_PROPERTY_READ("Top","i",PDFPAGELINKDATA_top),
|
|
GB_PROPERTY_READ("Right","i",PDFPAGELINKDATA_right),
|
|
GB_PROPERTY_READ("Bottom","i",PDFPAGELINKDATA_bottom),
|
|
GB_PROPERTY_READ("Zoom","f",PDFPAGELINKDATA_zoom),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
GB_DESC PdfLinkDesc[]=
|
|
{
|
|
GB_DECLARE(".PdfLink",0), GB_VIRTUAL_CLASS(),
|
|
|
|
GB_PROPERTY_READ("Left","i",PDFPAGELINK_left),
|
|
GB_PROPERTY_READ("Top","i",PDFPAGELINK_top),
|
|
GB_PROPERTY_READ("Width","i",PDFPAGELINK_width),
|
|
GB_PROPERTY_READ("Height","i",PDFPAGELINK_height),
|
|
GB_PROPERTY_SELF("Data",".PdfLinkData"),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
GB_DESC PdfIndexDesc[]=
|
|
{
|
|
GB_DECLARE(".PdfIndex",0), GB_VIRTUAL_CLASS(),
|
|
|
|
GB_PROPERTY("Expanded","b",PDFINDEX_is_open),
|
|
GB_PROPERTY_READ("Count","i",PDFINDEX_count),
|
|
GB_PROPERTY_READ("HasChildren","b",PDFINDEX_has_children),
|
|
GB_PROPERTY_READ("Title","s",PDFINDEX_title),
|
|
|
|
GB_PROPERTY_SELF("Data",".PdfLinkData"),
|
|
GB_METHOD("MovePrevious","b",PDFINDEX_prev,0),
|
|
GB_METHOD("MoveNext","b",PDFINDEX_next,0),
|
|
GB_METHOD("MoveChild","b",PDFINDEX_child,0),
|
|
GB_METHOD("MoveParent","b",PDFINDEX_parent,0),
|
|
GB_METHOD("MoveRoot",0,PDFINDEX_root,0),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
|
|
GB_DESC PdfPageDesc[]=
|
|
{
|
|
GB_DECLARE(".PdfPage",0), GB_VIRTUAL_CLASS(),
|
|
|
|
GB_PROPERTY_READ("W","f",PDFPAGE_width),
|
|
GB_PROPERTY_READ("H","f",PDFPAGE_height),
|
|
GB_PROPERTY_READ("Width","f",PDFPAGE_width),
|
|
GB_PROPERTY_READ("Height","f",PDFPAGE_height),
|
|
GB_PROPERTY_READ("Image","Image",PDFPAGE_property_image),
|
|
GB_PROPERTY_SELF("Result",".PdfResult"),
|
|
|
|
GB_METHOD("GetImage","Image",PDFPAGE_image,"[(X)i(Y)i(Width)i(Height)i]"),
|
|
GB_METHOD("Find","b",PDFPAGE_find,"(Text)s[(CaseSensitive)b]"),
|
|
GB_METHOD("Select","s",PDFPAGE_select,"[(X)i(Y)i(W)i(H)i]"),
|
|
|
|
GB_METHOD("_get",".PdfLink",PDFPAGELINKS_get,"(Index)i"),
|
|
GB_PROPERTY_READ("Count","i",PDFPAGELINKS_count),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
GB_DESC PdfDocumentInfo[] =
|
|
{
|
|
GB_DECLARE(".PdfInfo",0), GB_VIRTUAL_CLASS(),
|
|
|
|
GB_PROPERTY_READ("Title","s",PDFINFO_title),
|
|
GB_PROPERTY_READ("Format","s",PDFINFO_format),
|
|
GB_PROPERTY_READ("Author","s",PDFINFO_author),
|
|
GB_PROPERTY_READ("Subject","s",PDFINFO_subject),
|
|
GB_PROPERTY_READ("Keywords","s",PDFINFO_keywords),
|
|
GB_PROPERTY_READ("Creator","s",PDFINFO_creator),
|
|
GB_PROPERTY_READ("Producer","s",PDFINFO_producer),
|
|
GB_PROPERTY_READ("CreationDate","d",PDFINFO_creation),
|
|
GB_PROPERTY_READ("ModificationDate","d",PDFINFO_modification),
|
|
GB_PROPERTY_READ("Linearized","b",PDFINFO_linearized),
|
|
GB_PROPERTY_READ("Layout","i",PDFINFO_layout),
|
|
GB_PROPERTY_READ("Mode","i",PDFINFO_mode),
|
|
GB_PROPERTY_READ("CanCopy","b",PDFINFO_cancopy),
|
|
GB_PROPERTY_READ("CanModify","b",PDFINFO_canmodify),
|
|
GB_PROPERTY_READ("CanPrint","b",PDFINFO_canprint),
|
|
GB_PROPERTY_READ("CanAddNotes","b",PDFINFO_canaddnotes),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
GB_DESC PdfLayoutDesc[] =
|
|
{
|
|
|
|
GB_DECLARE("PdfLayout", 0), GB_NOT_CREATABLE(),
|
|
|
|
GB_CONSTANT("Unset","i",Catalog::pageLayoutNone),
|
|
GB_CONSTANT("SinglePage","i",Catalog::pageLayoutSinglePage),
|
|
GB_CONSTANT("OneColumn","i",Catalog::pageLayoutOneColumn),
|
|
GB_CONSTANT("TwoColumnLeft","i",Catalog::pageLayoutTwoColumnLeft),
|
|
GB_CONSTANT("TwoColumnRight","i",Catalog::pageLayoutTwoColumnRight),
|
|
GB_CONSTANT("TwoPageLeft","i",Catalog::pageLayoutTwoPageLeft),
|
|
GB_CONSTANT("TwoPageRight","i",Catalog::pageLayoutTwoPageRight),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
|
|
GB_DESC PdfModeDesc[] =
|
|
{
|
|
GB_DECLARE("PdfPageMode",0), GB_NOT_CREATABLE(),
|
|
|
|
GB_CONSTANT("Unset","i",Catalog::pageModeNone),
|
|
GB_CONSTANT("UseOutlines","i",Catalog::pageModeOutlines),
|
|
GB_CONSTANT("UseThumbs","i",Catalog::pageModeThumbs),
|
|
GB_CONSTANT("FullScreen","i",Catalog::pageModeFullScreen),
|
|
GB_CONSTANT("UseOC","i",Catalog::pageModeOC),
|
|
GB_CONSTANT("UseAttachments","i",Catalog::pageModeAttach),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
GB_DESC PdfDocumentDesc[] =
|
|
{
|
|
|
|
GB_DECLARE("PdfDocument", sizeof(CPDFDOCUMENT)),
|
|
|
|
GB_CONSTANT("Unknown","i",actionUnknown), /* unknown action */
|
|
GB_CONSTANT("Goto","i",actionGoTo), /* go to destination */
|
|
GB_CONSTANT("GotoRemote","i",actionGoToR), /* go to destination in new file */
|
|
GB_CONSTANT("Launch","i",actionLaunch), /* launch app or open doc. */
|
|
GB_CONSTANT("Uri","i",actionURI), /* URI */
|
|
GB_CONSTANT("Named","i",actionNamed), /* named action*/
|
|
GB_CONSTANT("Movie","i",actionMovie), /* movie action */
|
|
|
|
GB_CONSTANT("Normal","i",0),
|
|
GB_CONSTANT("Sideways","i",90),
|
|
GB_CONSTANT("Inverted","i",180),
|
|
GB_CONSTANT("SidewaysInverted","i",270),
|
|
|
|
GB_METHOD("_new", 0, PDFDOCUMENT_new, "[(File)s]"),
|
|
GB_METHOD("_free", 0, PDFDOCUMENT_free, 0),
|
|
|
|
GB_METHOD("Open",0,PDFDOCUMENT_open,"(File)s"),
|
|
GB_METHOD("Close",0,PDFDOCUMENT_close,0),
|
|
GB_METHOD("_get",".PdfPage",PDFDOCUMENT_get,"(Index)i"),
|
|
|
|
GB_PROPERTY("Zoom", "f", PDFDOCUMENT_scale),
|
|
GB_PROPERTY("Orientation", "i", PDFDOCUMENT_rotation),
|
|
|
|
GB_PROPERTY_READ("Ready","b",PDFDOCUMENT_ready),
|
|
GB_PROPERTY_READ("Count","i",PDFDOCUMENT_count),
|
|
GB_PROPERTY_READ("HasIndex","b",PDFDOCUMENT_has_index),
|
|
GB_PROPERTY_READ("Index",".PdfIndex",PDFDOCUMENT_index),
|
|
GB_PROPERTY_READ("Info",".PdfInfo",PDFDOCUMENT_info),
|
|
|
|
GB_END_DECLARE
|
|
};
|
|
|
|
|