wok-current diff gambas2/stuff/CPdfDocument.cpp @ rev 18440

gambas2: update CPdfDocument.cpp
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Sep 23 19:44:57 2015 +0200 (2015-09-23)
parents
children
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gambas2/stuff/CPdfDocument.cpp	Wed Sep 23 19:44:57 2015 +0200
     1.3 @@ -0,0 +1,1538 @@
     1.4 +/***************************************************************************
     1.5 +
     1.6 +  CPdfDocument.cpp
     1.7 +
     1.8 +  gb.pdf Component
     1.9 +
    1.10 +  (C) 2005-2007 Daniel Campos Fernández <dcamposf@gmail.com>
    1.11 +
    1.12 +
    1.13 +  This program is free software; you can redistribute it and/or modify
    1.14 +  it under the terms of the GNU General Public License as published by
    1.15 +  the Free Software Foundation; either version 1, or (at your option)
    1.16 +  any later version.
    1.17 +
    1.18 +  This program is free software; you can redistribute it and/or modify
    1.19 +  it under the terms of the GNU General Public License as published by
    1.20 +  the Free Software Foundation; either version 1, or (at your option)
    1.21 +  any later version.
    1.22 +
    1.23 +  This program is distributed in the hope that it will be useful,
    1.24 +  but WITHOUT ANY WARRANTY; without even the implied warranty of
    1.25 +  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    1.26 +  GNU General Public License for more details.
    1.27 +
    1.28 +  You should have received a copy of the GNU General Public License
    1.29 +  along with this program; if not, write to the Free Software
    1.30 +  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
    1.31 +
    1.32 +***************************************************************************/
    1.33 +
    1.34 +#define __CPDFDOCUMENT_C
    1.35 +
    1.36 +#include "CPdfDocument.h"
    1.37 +
    1.38 +#include "gambas.h"
    1.39 +#include "main.h"
    1.40 +
    1.41 +#include <stdio.h>
    1.42 +#include <stdint.h>
    1.43 +#include <math.h>
    1.44 +
    1.45 +#include <PDFDoc.h>
    1.46 +#include <Stream.h>
    1.47 +#include <ErrorCodes.h>
    1.48 +#include <Page.h>
    1.49 +#include <Catalog.h>
    1.50 +#include <TextOutputDev.h>
    1.51 +#include <SplashOutputDev.h>
    1.52 +#include <splash/SplashBitmap.h>
    1.53 +#include <goo/GooList.h>
    1.54 +#include <Outline.h>
    1.55 +#include <Link.h>
    1.56 +#include <Gfx.h>
    1.57 +
    1.58 +/*****************************************************************************
    1.59 +
    1.60 + Translations from Poppler universe to Gambas universe
    1.61 +
    1.62 +******************************************************************************/
    1.63 +typedef struct
    1.64 +{
    1.65 +	int32_t x0;
    1.66 +	int32_t y0;
    1.67 +	int32_t x1;
    1.68 +	int32_t y1;
    1.69 +} FoundRect;
    1.70 +
    1.71 +static void aux_return_string_info(void *_object, const char *key)
    1.72 +{
    1.73 +	Object obj;
    1.74 +	Object dst;
    1.75 +	GooString *goo_value;
    1.76 +	Dict *info_dict;
    1.77 +	char *tmpstr;
    1.78 +
    1.79 +	THIS->doc->getDocInfo (&obj);
    1.80 +	if (!obj.isDict()) { GB.ReturnNewZeroString(""); return; }
    1.81 +		
    1.82 +	info_dict=obj.getDict();
    1.83 +	info_dict->lookup ((char *)key, &dst);
    1.84 +	if (!dst.isString ()) { GB.ReturnNewZeroString(""); }
    1.85 +	else {
    1.86 +		goo_value = dst.getString();
    1.87 +
    1.88 +		if (goo_value->hasUnicodeMarker())
    1.89 +		{
    1.90 +			GB.ConvString (&tmpstr,goo_value->getCString()+2,goo_value->getLength()-2,"UTF-16BE","UTF-8");
    1.91 +			GB.ReturnNewZeroString(tmpstr);		
    1.92 +		}		
    1.93 +		else
    1.94 +			GB.ReturnNewString(goo_value->getCString(),goo_value->getLength());		
    1.95 +	}
    1.96 +	dst.free();
    1.97 +	obj.free();		
    1.98 +}
    1.99 +
   1.100 +static void aux_return_date_info(void *_object, const char *key)
   1.101 +{
   1.102 +	// TODO: Y2K effect
   1.103 +	GB_DATE_SERIAL ds;
   1.104 +	GB_DATE ret;
   1.105 +	Object obj;
   1.106 +	Object dst;
   1.107 +	GooString *goo;
   1.108 +	Dict *info_dict;
   1.109 +	char *datestr=NULL,*tofree=NULL;
   1.110 +	int nnum;
   1.111 +
   1.112 +	THIS->doc->getDocInfo (&obj);
   1.113 +	if (!obj.isDict()) { GB.ReturnNull(); return; }
   1.114 +
   1.115 +	info_dict=obj.getDict();
   1.116 +	info_dict->lookup ((char *)key, &dst);
   1.117 +	if (!dst.isString ()) { GB.ReturnNull(); }
   1.118 +	else {
   1.119 +		goo = dst.getString();
   1.120 +		if (goo->hasUnicodeMarker())
   1.121 +			GB.ConvString (&datestr,goo->getCString()+2,goo->getLength()-2,"UTF-16BE","UTF-8");
   1.122 +		else
   1.123 +		{
   1.124 +			GB.NewString(&datestr,goo->getCString(),goo->getLength());
   1.125 +			tofree=datestr;		
   1.126 +		}
   1.127 +
   1.128 +		if (!datestr) { GB.ReturnNull(); }
   1.129 +		else
   1.130 +		{
   1.131 +			if (datestr[0] == 'D' && datestr[1] == ':') datestr += 2;
   1.132 +			nnum=sscanf(datestr, "%4hd%2hd%2hd%2hd%2hd%2hd",&ds.year, &ds.month, \
   1.133 +			                                          &ds.day, &ds.hour, &ds.min, &ds.sec);	
   1.134 +			if (nnum != 6) { GB.ReturnNull(); }
   1.135 +			else
   1.136 +			{
   1.137 +				if (GB.MakeDate(&ds,&ret))
   1.138 +					GB.ReturnNull();
   1.139 +				else
   1.140 +					GB.ReturnDate(&ret);
   1.141 +			}		
   1.142 +		}
   1.143 +		
   1.144 +	}
   1.145 +
   1.146 +	if (tofree) GB.FreeString(&tofree);
   1.147 +	dst.free();
   1.148 +	obj.free();
   1.149 +}
   1.150 +
   1.151 +static void aux_return_unicode_string(Unicode *uni, int32_t  len)
   1.152 +{
   1.153 +	int32_t bc;
   1.154 +	char *ret=NULL;
   1.155 +
   1.156 +	for (bc=0; bc<len; bc++)
   1.157 +		GB.AddString(&ret,(const char*)&uni[bc],0);
   1.158 +
   1.159 +	GB.ReturnNewString(ret,0);
   1.160 +	GB.FreeString(&ret);
   1.161 +}
   1.162 +
   1.163 +static LinkDest *get_dest(LinkAction *act)
   1.164 +{
   1.165 +	switch (act->getKind())
   1.166 +	{
   1.167 +		case actionGoTo: return ((LinkGoTo*)act)->getDest();
   1.168 +		case actionGoToR: return ((LinkGoToR*)act)->getDest();
   1.169 +		default: return 0;
   1.170 +	}
   1.171 +}
   1.172 +
   1.173 +static uint32_t aux_get_page_from_action(void *_object, LinkAction *act)
   1.174 +{
   1.175 +	Ref pref;       
   1.176 +	LinkDest *dest = get_dest(act);
   1.177 +	#if POPPLER_VERSION_0_6
   1.178 +	GooString *name;
   1.179 +	#else
   1.180 +	UGooString *name;
   1.181 +	#endif
   1.182 +
   1.183 +	if (!dest)
   1.184 +	{
   1.185 +		// try to use NamedDest to get dest
   1.186 +		if (!act)
   1.187 +			return 0;
   1.188 +		if (act->getKind () == actionGoTo)
   1.189 +		{
   1.190 +			name = ((LinkGoTo*)act)->getNamedDest();
   1.191 +			if (name)
   1.192 +				dest = THIS->doc->findDest(name);
   1.193 +		}
   1.194 +	}
   1.195 +
   1.196 +	if (!dest)
   1.197 +		return 0;
   1.198 +
   1.199 +	if (dest->isPageRef() )
   1.200 +	{
   1.201 +		pref= dest->getPageRef();
   1.202 +		return THIS->doc->findPage(pref.num, pref.gen);
   1.203 +	}
   1.204 +	else
   1.205 +		return dest->getPageNum();
   1.206 +}
   1.207 +
   1.208 +static void aux_get_dimensions_from_action(LinkAction *act,int *left, int32_t *right, int32_t *top, int32_t *bottom)
   1.209 +{
   1.210 +	LinkDest *dest = get_dest(act);
   1.211 +	if (!dest)
   1.212 +	{
   1.213 +		if (left)   *left=0;
   1.214 +		if (right)  *right=0;
   1.215 +		if (top)    *top=0;
   1.216 +		if (bottom) *bottom=0;
   1.217 +		return;
   1.218 +	}
   1.219 +	
   1.220 +	if (left)   *left=(int32_t)dest->getLeft();
   1.221 +	if (right)  *right=(int32_t)dest->getRight();
   1.222 +	if (top)    *top=(int32_t)dest->getTop();
   1.223 +	if (bottom) *bottom=(int32_t)dest->getBottom();
   1.224 +}
   1.225 +
   1.226 +static double aux_get_zoom_from_action(LinkAction *act)
   1.227 +{
   1.228 +	LinkDest *dest = get_dest(act);
   1.229 +	if (dest)
   1.230 +		return dest->getZoom();
   1.231 +	else
   1.232 +		return 1;
   1.233 +}
   1.234 +
   1.235 +static char* aux_get_target_from_action(LinkAction *act)
   1.236 +{
   1.237 +	char *vl=NULL;
   1.238 +	char *uni=NULL;	
   1.239 +	GooString *tmp=NULL;
   1.240 +
   1.241 +	switch (act->getKind())
   1.242 +	{
   1.243 +		case actionGoToR:
   1.244 +			tmp=((LinkGoToR*)act)->getFileName(); break;
   1.245 +
   1.246 +		case actionLaunch:
   1.247 +			tmp=((LinkLaunch*)act)->getFileName(); break;
   1.248 +
   1.249 +		case actionURI:
   1.250 +			tmp=((LinkURI*)act)->getURI(); break;
   1.251 +			
   1.252 +		case actionNamed:
   1.253 +			tmp=((LinkNamed*)act)->getName(); break;
   1.254 +
   1.255 +		case actionMovie:
   1.256 +			#if POPPLER_VERSION_0_8
   1.257 +			tmp=((LinkMovie*)act)->getAnnotTitle(); break;
   1.258 +			#else
   1.259 +			tmp=((LinkMovie*)act)->getTitle(); break;
   1.260 +			#endif
   1.261 +
   1.262 +		default:
   1.263 +			break;
   1.264 +	}
   1.265 +
   1.266 +	if (!tmp) return NULL;
   1.267 +
   1.268 +	if (tmp->hasUnicodeMarker())
   1.269 +	{
   1.270 +			GB.ConvString (&uni,tmp->getCString()+2,tmp->getLength()-2,"UTF-16BE","UTF-8");
   1.271 +			GB.AddString (&vl,uni,0);	
   1.272 +	}	
   1.273 +	else
   1.274 +			GB.AddString(&vl,tmp->getCString(),tmp->getLength());
   1.275 +	
   1.276 +
   1.277 +	return vl;
   1.278 +
   1.279 +}
   1.280 +
   1.281 +/*****************************************************************************
   1.282 +
   1.283 + PDF document
   1.284 +
   1.285 +******************************************************************************/
   1.286 +
   1.287 +
   1.288 +static void free_all(void *_object)
   1.289 +{
   1.290 +	if (THIS->doc)
   1.291 +	{
   1.292 +		delete THIS->doc;
   1.293 +		THIS->doc=NULL;
   1.294 +	}
   1.295 +
   1.296 +	if (THIS->dev)
   1.297 +	{
   1.298 +		delete THIS->dev;
   1.299 +		THIS->dev=NULL;
   1.300 +	}
   1.301 +
   1.302 +	if (THIS->buf)
   1.303 +	{
   1.304 +		GB.ReleaseFile(&THIS->buf,THIS->len);
   1.305 +		THIS->buf=NULL;
   1.306 +	}
   1.307 +
   1.308 +	if (THIS->Found)
   1.309 +	{		
   1.310 +		GB.FreeArray(POINTER(&THIS->Found));
   1.311 +		THIS->Found=NULL;
   1.312 +	}
   1.313 +
   1.314 +	if (THIS->links)
   1.315 +	{
   1.316 +		delete THIS->links;	
   1.317 +		THIS->links=NULL;
   1.318 +	}
   1.319 +
   1.320 +	if (THIS->pindex)
   1.321 +	{		
   1.322 +		GB.FreeArray(POINTER(&THIS->pindex));
   1.323 +		GB.FreeArray(POINTER(&THIS->oldindex));
   1.324 +		THIS->pindex=NULL;
   1.325 +		THIS->oldindex=NULL;
   1.326 +	}
   1.327 +
   1.328 +	THIS->index=NULL;
   1.329 +	THIS->currpage=-1;
   1.330 +}
   1.331 +
   1.332 +BEGIN_METHOD_VOID (PDFDOCUMENT_free)
   1.333 +
   1.334 +	free_all(_object);
   1.335 +
   1.336 +END_METHOD
   1.337 +
   1.338 +BEGIN_PROPERTY(PDFDOCUMENT_scale)
   1.339 +
   1.340 +	if (READ_PROPERTY){ GB.ReturnFloat(THIS->scale); return; }
   1.341 +	
   1.342 +	if (VPROP(GB_FLOAT)>0) { THIS->scale = VPROP(GB_FLOAT); return; }
   1.343 +
   1.344 +	GB.Error("Zoom must be a positive value");
   1.345 +
   1.346 +END_PROPERTY
   1.347 +
   1.348 +BEGIN_PROPERTY(PDFDOCUMENT_rotation)
   1.349 +
   1.350 +	int32_t rot;
   1.351 +
   1.352 +	if (READ_PROPERTY)
   1.353 +	{
   1.354 +		GB.ReturnInteger(THIS->rotation);
   1.355 +		return;
   1.356 +	}
   1.357 +	
   1.358 +	rot=VPROP(GB_INTEGER);
   1.359 +
   1.360 +	while (rot<0) rot+=360;
   1.361 +	while (rot>=360) rot-=360;
   1.362 +
   1.363 +	switch (rot)
   1.364 +	{
   1.365 +		case 0:
   1.366 +		case 90:
   1.367 +		case 180:
   1.368 +		case 270: 
   1.369 +			THIS->rotation = VPROP(GB_INTEGER);
   1.370 +			break;
   1.371 +	}
   1.372 +
   1.373 +END_PROPERTY
   1.374 +
   1.375 +
   1.376 +int32_t open_document (void *_object, char *sfile, int32_t lfile)
   1.377 +{
   1.378 +	SplashColor white;
   1.379 +	PDFDoc *test;
   1.380 +	MemStream *stream;
   1.381 +	Object obj;
   1.382 +	Outline *outline;
   1.383 +	char *buf=NULL;
   1.384 +	int32_t len=0;
   1.385 +	int32_t ret;
   1.386 +
   1.387 +
   1.388 +	if ( GB.LoadFile(sfile,lfile,&buf,&len) ) return -1;
   1.389 +
   1.390 +	obj.initNull();
   1.391 +	stream=new MemStream(buf,0,(Guint)len,&obj);
   1.392 +	test=new PDFDoc (stream,0,0);
   1.393 +
   1.394 +	if (!test->isOk())
   1.395 +	{
   1.396 +		GB.ReleaseFile(&buf,len);
   1.397 +		ret=test->getErrorCode();
   1.398 +		delete test;
   1.399 +		test=NULL;
   1.400 +		if (ret == errEncrypted) return -2;
   1.401 +		return -3;
   1.402 +	}
   1.403 +
   1.404 +	free_all(_object);
   1.405 +
   1.406 +	THIS->doc=test;
   1.407 +	THIS->buf=buf;
   1.408 +	THIS->len=len;
   1.409 +
   1.410 +	white[0] = 0xFF; white[1] = 0xFF; white[2] = 0xFF;
   1.411 +	THIS->dev=new SplashOutputDev(splashModeRGB8, 3, gFalse, white);
   1.412 +		
   1.413 +	#if POPPLER_VERSION_0_20
   1.414 +	THIS->dev->startDoc(THIS->doc);
   1.415 +	#else
   1.416 +	THIS->dev->startDoc(THIS->doc->getXRef ());
   1.417 +	#endif
   1.418 +
   1.419 +	outline=THIS->doc->getOutline();
   1.420 +	if (outline) THIS->index=outline->getItems();
   1.421 +	
   1.422 +	//if (THIS->index)
   1.423 +	//	if (!THIS->index->getLength()) THIS->index=NULL;
   1.424 +
   1.425 +	THIS->currindex=0;
   1.426 +	THIS->currpage=-1;
   1.427 +
   1.428 +	return 0;
   1.429 +
   1.430 +}
   1.431 +
   1.432 +
   1.433 +BEGIN_METHOD(PDFDOCUMENT_new, GB_STRING File)
   1.434 +
   1.435 +	THIS->scale = 1;
   1.436 +	THIS->rotation = 0;
   1.437 +
   1.438 +	if (!MISSING(File))
   1.439 +	{
   1.440 +		switch (open_document( _object, STRING(File), LENGTH(File)) )
   1.441 +		{
   1.442 +			case -1: GB.Error("File not found"); return;
   1.443 +			case -2: GB.Error("PDF is encrypted"); return;
   1.444 +			case -3: GB.Error("Bad PDF File"); return;
   1.445 +		}
   1.446 +	}
   1.447 +
   1.448 +END_METHOD
   1.449 +
   1.450 +BEGIN_METHOD (PDFDOCUMENT_open, GB_STRING File;)
   1.451 +
   1.452 +	switch (open_document( _object, STRING(File), LENGTH(File)) )
   1.453 +	{
   1.454 +		case -1: GB.Error("File not found"); return;
   1.455 +		case -2: GB.Error("PDF is encrypted"); return;
   1.456 +		case -3: GB.Error("Bad PDF File"); return;
   1.457 +	}
   1.458 +
   1.459 +END_METHOD
   1.460 +
   1.461 +BEGIN_METHOD_VOID(PDFDOCUMENT_close)
   1.462 +
   1.463 +	free_all(_object);
   1.464 +
   1.465 +END_METHOD
   1.466 +
   1.467 +BEGIN_METHOD(PDFDOCUMENT_get,GB_INTEGER index;)
   1.468 +
   1.469 +	if (!THIS->doc || (VARG(index)<1) || ( VARG(index)>THIS->doc->getNumPages() ) )
   1.470 +	{
   1.471 +		GB.Error("Invalid page number");
   1.472 +		GB.ReturnNull();
   1.473 +		return;
   1.474 +	}
   1.475 +
   1.476 +	if (THIS->currpage != (uint32_t)VARG(index) )
   1.477 +	{
   1.478 +		if (THIS->Found)
   1.479 +		{		
   1.480 +			GB.FreeArray(POINTER(&THIS->Found));
   1.481 +			THIS->Found=NULL;
   1.482 +		}
   1.483 +
   1.484 +		if (THIS->links)
   1.485 +		{
   1.486 +			delete THIS->links;	
   1.487 +			THIS->links=NULL;
   1.488 +		}
   1.489 +
   1.490 +		THIS->page=THIS->doc->getCatalog()->getPage(VARG(index));
   1.491 +		THIS->currpage=VARG(index);
   1.492 +	}
   1.493 +		
   1.494 +	RETURN_SELF();
   1.495 +
   1.496 +END_METHOD
   1.497 +
   1.498 +BEGIN_PROPERTY(PDFDOCUMENT_ready)
   1.499 +
   1.500 +	GB.ReturnBoolean( (bool)THIS->doc );
   1.501 +
   1.502 +END_PROPERTY
   1.503 +
   1.504 +BEGIN_PROPERTY(PDFDOCUMENT_count)
   1.505 +
   1.506 +	GB.ReturnInteger( (int32_t) (THIS->doc ? THIS->doc->getNumPages() : 0));
   1.507 +
   1.508 +END_PROPERTY
   1.509 +
   1.510 +BEGIN_PROPERTY(PDFDOCUMENT_info)
   1.511 +
   1.512 +	if (THIS->doc) RETURN_SELF();
   1.513 +	else GB.ReturnNull();
   1.514 +
   1.515 +END_PROPERTY
   1.516 +
   1.517 +/*****************************************************************************
   1.518 +
   1.519 +PDF document information
   1.520 +
   1.521 +******************************************************************************/
   1.522 +
   1.523 +BEGIN_PROPERTY(PDFINFO_title)
   1.524 +
   1.525 +	aux_return_string_info(_object,"Title");
   1.526 +
   1.527 +END_PROPERTY
   1.528 +
   1.529 +BEGIN_PROPERTY(PDFINFO_format)
   1.530 +
   1.531 +	char ctx[16];
   1.532 +	#if POPPLER_VERSION_0_11_3
   1.533 +		snprintf(ctx, sizeof(ctx), "%.2g", THIS->doc->getPDFMajorVersion () + THIS->doc->getPDFMinorVersion() / 10.0);
   1.534 +	#else
   1.535 +		snprintf(ctx, sizeof(ctx), "%.2g", THIS->doc->getPDFVersion());
   1.536 +	#endif
   1.537 +	GB.ReturnNewZeroString(ctx);
   1.538 +
   1.539 +END_PROPERTY
   1.540 +
   1.541 +BEGIN_PROPERTY(PDFINFO_author)
   1.542 +
   1.543 +	aux_return_string_info(_object,"Author");
   1.544 +
   1.545 +END_PROPERTY
   1.546 +
   1.547 +BEGIN_PROPERTY(PDFINFO_subject)
   1.548 +
   1.549 +	aux_return_string_info(_object,"Subject");
   1.550 +
   1.551 +END_PROPERTY
   1.552 +
   1.553 +BEGIN_PROPERTY(PDFINFO_keywords)
   1.554 +
   1.555 +	aux_return_string_info(_object,"Keywords");
   1.556 +
   1.557 +END_PROPERTY
   1.558 +
   1.559 +BEGIN_PROPERTY(PDFINFO_creator)
   1.560 +
   1.561 +	aux_return_string_info(_object,"Creator");
   1.562 +
   1.563 +END_PROPERTY
   1.564 +
   1.565 +BEGIN_PROPERTY(PDFINFO_producer)
   1.566 +
   1.567 +	aux_return_string_info(_object,"Producer");
   1.568 +
   1.569 +END_PROPERTY
   1.570 +
   1.571 +BEGIN_PROPERTY(PDFINFO_linearized)
   1.572 +
   1.573 +	GB.ReturnBoolean(THIS->doc->isLinearized());
   1.574 +
   1.575 +END_PROPERTY
   1.576 +
   1.577 +BEGIN_PROPERTY(PDFINFO_layout)
   1.578 +
   1.579 +	Catalog *catalog;
   1.580 +
   1.581 +	catalog=THIS->doc->getCatalog();
   1.582 +	if (!catalog) { GB.ReturnInteger(Catalog::pageLayoutNone); return; }
   1.583 +	if (!catalog->isOk())  { GB.ReturnInteger(Catalog::pageLayoutNone); return; }
   1.584 +
   1.585 +	GB.ReturnInteger(catalog->getPageLayout());
   1.586 +
   1.587 +END_PROPERTY
   1.588 +
   1.589 +BEGIN_PROPERTY(PDFINFO_mode)
   1.590 +
   1.591 +	Catalog *catalog;
   1.592 +
   1.593 +	catalog=THIS->doc->getCatalog();
   1.594 +	if (!catalog) { GB.ReturnInteger(Catalog::pageModeNone); return; }
   1.595 +	if (!catalog->isOk())  { GB.ReturnInteger(Catalog::pageModeNone); return; }
   1.596 +
   1.597 +	GB.ReturnInteger(catalog->getPageMode());
   1.598 +
   1.599 +
   1.600 +END_PROPERTY
   1.601 +
   1.602 +BEGIN_PROPERTY(PDFINFO_canprint)
   1.603 +	
   1.604 +	GB.ReturnBoolean(THIS->doc->okToPrint());      
   1.605 +
   1.606 +END_PROPERTY
   1.607 +
   1.608 +BEGIN_PROPERTY(PDFINFO_canmodify)
   1.609 +
   1.610 +	GB.ReturnBoolean(THIS->doc->okToChange());
   1.611 +
   1.612 +END_PROPERTY
   1.613 +
   1.614 +BEGIN_PROPERTY(PDFINFO_cancopy)
   1.615 +
   1.616 +	GB.ReturnBoolean(THIS->doc->okToCopy());
   1.617 +
   1.618 +END_PROPERTY
   1.619 +
   1.620 +BEGIN_PROPERTY(PDFINFO_canaddnotes)
   1.621 +
   1.622 +	GB.ReturnBoolean(THIS->doc->okToAddNotes());
   1.623 +
   1.624 +END_PROPERTY
   1.625 +
   1.626 +BEGIN_PROPERTY(PDFINFO_creation)
   1.627 +
   1.628 +	aux_return_date_info(_object,"CreationDate");
   1.629 +
   1.630 +END_PROPERTY
   1.631 +
   1.632 +BEGIN_PROPERTY(PDFINFO_modification)
   1.633 +
   1.634 +	aux_return_date_info(_object,"ModDate");
   1.635 +
   1.636 +END_PROPERTY
   1.637 +
   1.638 +
   1.639 +/*****************************************************************************
   1.640 +
   1.641 +PDF document index
   1.642 +
   1.643 +******************************************************************************/
   1.644 +
   1.645 +
   1.646 +BEGIN_PROPERTY(PDFDOCUMENT_has_index)
   1.647 +
   1.648 +	GB.ReturnBoolean(THIS->index && THIS->index->getLength());
   1.649 +
   1.650 +END_PROPERTY
   1.651 +
   1.652 +BEGIN_PROPERTY(PDFDOCUMENT_index)
   1.653 +
   1.654 +	if (!THIS->index) { GB.ReturnNull(); return; }
   1.655 +	
   1.656 +	THIS->action=((OutlineItem*)THIS->index->get(THIS->currindex))->getAction();
   1.657 +	RETURN_SELF();
   1.658 +
   1.659 +END_PROPERTY
   1.660 +
   1.661 +BEGIN_PROPERTY(PDFINDEX_count)
   1.662 +	
   1.663 +	GB.ReturnInteger(THIS->index->getLength());
   1.664 +
   1.665 +END_PROPERTY
   1.666 +
   1.667 +BEGIN_PROPERTY(PDFINDEX_has_children)
   1.668 +
   1.669 +	OutlineItem *item;
   1.670 +
   1.671 +	item = (OutlineItem *)THIS->index->get (THIS->currindex);
   1.672 +	GB.ReturnBoolean(item->getKids() && item->getKids()->getLength());
   1.673 +
   1.674 +END_PROPERTY
   1.675 +
   1.676 +BEGIN_PROPERTY(PDFINDEX_is_open)
   1.677 +
   1.678 +	OutlineItem *item;
   1.679 +
   1.680 +	item = (OutlineItem *)THIS->index->get (THIS->currindex);
   1.681 +
   1.682 +	if (READ_PROPERTY)
   1.683 +	{	GB.ReturnBoolean(item->isOpen()); return; }
   1.684 +
   1.685 +	if (VPROP(GB_INTEGER)) item->open();
   1.686 +	else item->close();
   1.687 +
   1.688 +END_PROPERTY
   1.689 +
   1.690 +BEGIN_PROPERTY(PDFINDEX_title)
   1.691 +
   1.692 +	OutlineItem *item;
   1.693 +
   1.694 +	item = (OutlineItem *)THIS->index->get (THIS->currindex);
   1.695 +	aux_return_unicode_string(item->getTitle(),item->getTitleLength());
   1.696 +
   1.697 +END_PROPERTY
   1.698 +
   1.699 +
   1.700 +BEGIN_METHOD_VOID(PDFINDEX_root)
   1.701 +
   1.702 +	Outline *outline;
   1.703 +
   1.704 +	outline=THIS->doc->getOutline();
   1.705 +	if (outline) THIS->index=outline->getItems();
   1.706 +	THIS->currindex=0;
   1.707 +	if (THIS->pindex) { GB.FreeArray(POINTER(&THIS->pindex)); THIS->pindex=NULL; }
   1.708 +	if (THIS->oldindex) { GB.FreeArray(POINTER(&THIS->oldindex)); THIS->oldindex=NULL; }
   1.709 +
   1.710 +END_METHOD
   1.711 +
   1.712 +BEGIN_METHOD_VOID(PDFINDEX_prev)
   1.713 +
   1.714 +	if (!THIS->currindex) { GB.ReturnBoolean(true); return; }
   1.715 +
   1.716 +	THIS->currindex--;
   1.717 +	GB.ReturnBoolean(false);
   1.718 +
   1.719 +END_METHOD
   1.720 +
   1.721 +BEGIN_METHOD_VOID(PDFINDEX_next)
   1.722 +
   1.723 +	if ( (THIS->currindex+1) >= (uint32_t)THIS->index->getLength() )
   1.724 +		 { GB.ReturnBoolean(true); return; }
   1.725 +
   1.726 +	THIS->currindex++;
   1.727 +	GB.ReturnBoolean(false);
   1.728 +
   1.729 +END_METHOD
   1.730 +
   1.731 +BEGIN_METHOD_VOID(PDFINDEX_child)
   1.732 +
   1.733 +	OutlineItem *item;
   1.734 +
   1.735 +	item = (OutlineItem *)THIS->index->get (THIS->currindex);
   1.736 +
   1.737 +	if (!item->hasKids() || item->getKids()->getLength() == 0) { GB.ReturnBoolean(true); return; }
   1.738 +
   1.739 +	if (THIS->pindex)
   1.740 +	{
   1.741 +		GB.Add(POINTER(&THIS->pindex));
   1.742 +		GB.Add(POINTER(&THIS->oldindex));
   1.743 +	}
   1.744 +	else
   1.745 +	{
   1.746 +		GB.NewArray(POINTER(&THIS->pindex),sizeof(void*),1);
   1.747 +		GB.NewArray(POINTER(&THIS->oldindex),sizeof(uint32_t),1);
   1.748 +	}	
   1.749 +
   1.750 +	if (!item->isOpen()) item->open(); 
   1.751 +	THIS->pindex[GB.Count(POINTER(THIS->pindex))-1]=(void*)THIS->index;
   1.752 +	THIS->oldindex[GB.Count(POINTER(THIS->pindex))-1]=THIS->currindex;
   1.753 +	THIS->index=item->getKids();	
   1.754 +	THIS->currindex=0;
   1.755 +
   1.756 +	GB.ReturnBoolean(false);
   1.757 +
   1.758 +END_METHOD
   1.759 +
   1.760 +BEGIN_METHOD_VOID(PDFINDEX_parent)
   1.761 +
   1.762 +	if (!THIS->pindex) { GB.ReturnBoolean(true); return; }
   1.763 +
   1.764 +	THIS->index=(GooList*)THIS->pindex[GB.Count(POINTER(THIS->pindex))-1];
   1.765 +	THIS->currindex=THIS->oldindex[GB.Count(POINTER(THIS->pindex))-1];
   1.766 +	if (GB.Count(POINTER(THIS->pindex))==1)
   1.767 +	{
   1.768 +		GB.FreeArray(POINTER(&THIS->pindex));
   1.769 +		GB.FreeArray(POINTER(&THIS->oldindex));
   1.770 +		THIS->oldindex=NULL;
   1.771 +		THIS->pindex=NULL;
   1.772 +	}
   1.773 +	else
   1.774 +	{
   1.775 +		GB.Remove(POINTER(&THIS->pindex),GB.Count(POINTER(THIS->pindex))-1,1);
   1.776 +		GB.Remove(POINTER(&THIS->oldindex),GB.Count(POINTER(THIS->oldindex))-1,1);
   1.777 +	}
   1.778 +
   1.779 +	GB.ReturnBoolean(false);
   1.780 +
   1.781 +END_METHOD
   1.782 +
   1.783 +/*****************************************************************************
   1.784 +
   1.785 + PDF pages
   1.786 +
   1.787 +******************************************************************************/
   1.788 +
   1.789 +BEGIN_PROPERTY (PDFPAGE_width)
   1.790 +
   1.791 +	if ( (THIS->rotation==90) || (THIS->rotation==270) ) 
   1.792 +		GB.ReturnInteger((int32_t)(THIS->page->getMediaHeight()*THIS->scale));
   1.793 +	else
   1.794 +		GB.ReturnInteger((int32_t)(THIS->page->getMediaWidth()*THIS->scale));
   1.795 +
   1.796 +END_PROPERTY
   1.797 +
   1.798 +BEGIN_PROPERTY (PDFPAGE_height)
   1.799 +
   1.800 +	if ( (THIS->rotation==90) || (THIS->rotation==270) )
   1.801 +		GB.ReturnInteger((int32_t)(THIS->page->getMediaWidth()*THIS->scale));
   1.802 +	else	
   1.803 +		GB.ReturnInteger((int32_t)(THIS->page->getMediaHeight()*THIS->scale));
   1.804 +
   1.805 +END_PROPERTY
   1.806 +
   1.807 +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)
   1.808 +{
   1.809 +	SplashBitmap *map;
   1.810 +	uint32_t *data;
   1.811 +	int32_t w, h;
   1.812 +	int32_t rw;
   1.813 +	int32_t rh;
   1.814 +
   1.815 +	if ( (THIS->rotation==90) || (THIS->rotation==270) )
   1.816 +	{
   1.817 +		rh=(int32_t)(THIS->page->getMediaWidth()*THIS->scale);
   1.818 +		rw=(int32_t)(THIS->page->getMediaHeight()*THIS->scale);
   1.819 +	}
   1.820 +	else
   1.821 +	{
   1.822 +		rw=(int32_t)(THIS->page->getMediaWidth()*THIS->scale);
   1.823 +		rh=(int32_t)(THIS->page->getMediaHeight()*THIS->scale);
   1.824 +	}
   1.825 +
   1.826 +	w = *width;
   1.827 +	h = *height;
   1.828 +
   1.829 +	if (w < 0) w = rw;
   1.830 +	if (h < 0) h = rh;
   1.831 +
   1.832 +	if (x<0) x=0;
   1.833 +	if (y<0) y=0;
   1.834 +	if (w<1) w=1;
   1.835 +	if (h<1) h=1;
   1.836 +
   1.837 +
   1.838 +	if ( (x+w) > rw ) w=rw-x;
   1.839 +	if ( (y+h) > rh ) h=rh-y;
   1.840 +
   1.841 +	if ( (w<0) || (h<0) ) return NULL;
   1.842 +
   1.843 +	#if POPPLER_VERSION_0_20
   1.844 +	THIS->page->displaySlice(THIS->dev,72.0*scale,72.0*scale,
   1.845 +			   rotation,
   1.846 +			   gFalse,
   1.847 +			   gTrue,
   1.848 +			   x,y,w,h,
   1.849 +			   gFalse);
   1.850 +	#else
   1.851 +	THIS->page->displaySlice(THIS->dev,72.0*scale,72.0*scale,
   1.852 +			   rotation,
   1.853 +			   gFalse,
   1.854 +			   gTrue,
   1.855 +			   x,y,w,h,
   1.856 +			   gFalse,
   1.857 +			   THIS->doc->getCatalog ());
   1.858 +	#endif
   1.859 +
   1.860 +	map=THIS->dev->getBitmap();
   1.861 +	
   1.862 +	data=(uint32_t*)map->getDataPtr();
   1.863 +
   1.864 +
   1.865 +	*width = w;
   1.866 +	*height = h;
   1.867 +
   1.868 +	return data;
   1.869 +}
   1.870 +
   1.871 +BEGIN_METHOD(PDFPAGE_image, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)
   1.872 +
   1.873 +	GB_IMAGE img = NULL;
   1.874 +	uint32_t *data;
   1.875 +	int32_t x,y, w, h;
   1.876 +
   1.877 +	x = VARGOPT(x, 0);
   1.878 +	y = VARGOPT(y, 0);
   1.879 +	w = VARGOPT(w, -1);
   1.880 +	h = VARGOPT(h, -1);
   1.881 +
   1.882 +	data = get_page_data(THIS, x, y, &w, &h, THIS->scale, THIS->rotation);
   1.883 +	if (!data) { GB.ReturnNull(); return; }
   1.884 +	GB.Image.Create(&img, data, w, h, GB_IMAGE_RGB);
   1.885 +	GB.ReturnObject(img);
   1.886 +
   1.887 +END_METHOD
   1.888 +
   1.889 +BEGIN_PROPERTY (PDFPAGE_property_image)
   1.890 +
   1.891 +	int32_t w=-1;
   1.892 +	int32_t h=-1;
   1.893 +	GB_IMAGE img = NULL;
   1.894 +	uint32_t *data;
   1.895 +
   1.896 +	data = get_page_data(THIS, 0, 0, &w, &h, THIS->scale, THIS->rotation);
   1.897 +	if (!data) { GB.ReturnNull(); return; }
   1.898 +	GB.Image.Create(&img, data, w, h, GB_IMAGE_RGB);
   1.899 +	GB.ReturnObject(img);
   1.900 +
   1.901 +END_PROPERTY
   1.902 +
   1.903 +
   1.904 +BEGIN_METHOD(PDFPAGE_picture, GB_INTEGER x; GB_INTEGER y; GB_INTEGER w; GB_INTEGER h)
   1.905 +
   1.906 +	GB_IMAGE img = NULL;
   1.907 +	uint32_t *data;
   1.908 +	int32_t x,y, w, h;
   1.909 +
   1.910 +	x = VARGOPT(x, 0);
   1.911 +	y = VARGOPT(y, 0);
   1.912 +	w = VARGOPT(w, -1);
   1.913 +	h = VARGOPT(h, -1);
   1.914 +
   1.915 +	data = get_page_data(THIS, x, y, &w, &h, THIS->scale, THIS->rotation);
   1.916 +	if (!data) { GB.ReturnNull(); return; }
   1.917 +	GB.Picture.Create(&img, data, w, h, GB_IMAGE_RGB);
   1.918 +	GB.ReturnObject(img);
   1.919 +
   1.920 +END_METHOD
   1.921 +
   1.922 +BEGIN_PROPERTY (PDFPAGE_property_picture)
   1.923 +
   1.924 +	int32_t w=-1;
   1.925 +	int32_t h=-1;
   1.926 +	GB_IMAGE img = NULL;
   1.927 +	uint32_t *data;
   1.928 +
   1.929 +	data = get_page_data(THIS, 0, 0, &w, &h, THIS->scale, THIS->rotation);
   1.930 +	if (!data) { GB.ReturnNull(); return; }
   1.931 +	GB.Picture.Create(&img, data, w, h, GB_IMAGE_RGB);
   1.932 +	GB.ReturnObject(img);
   1.933 +
   1.934 +END_PROPERTY
   1.935 +
   1.936 +BEGIN_METHOD(PDFPAGE_select, GB_INTEGER X; GB_INTEGER Y; GB_INTEGER W; GB_INTEGER H)
   1.937 +
   1.938 +	TextOutputDev *dev;
   1.939 +	GooString *str;
   1.940 +	Gfx *gfx;
   1.941 +	int32_t x,y,w,h;
   1.942 +
   1.943 +	x = VARGOPT(X, 0);
   1.944 +	y = VARGOPT(Y, 0);
   1.945 +	w = VARGOPT(W, (int32_t)THIS->page->getMediaWidth());
   1.946 +	h = VARGOPT(H, (int32_t)THIS->page->getMediaHeight());
   1.947 +
   1.948 +	#if POPPLER_VERSION_0_20
   1.949 +	dev = new TextOutputDev (NULL, gTrue, 0, gFalse, gFalse);
   1.950 +	gfx = THIS->page->createGfx(dev,72.0,72.0,0,gFalse,gTrue,-1, -1, -1, -1, gFalse, NULL, NULL);
   1.951 +	#else
   1.952 +	dev = new TextOutputDev (NULL, gTrue, gFalse, gFalse);
   1.953 +	gfx = THIS->page->createGfx(dev,72.0,72.0,0,gFalse,gTrue,-1, -1, -1, -1, \
   1.954 +                                gFalse,THIS->doc->getCatalog (),NULL, NULL, NULL, NULL);
   1.955 +	#endif
   1.956 +	
   1.957 +	THIS->page->display(gfx);
   1.958 +	dev->endPage();
   1.959 +
   1.960 +	str=dev->getText((double)x,(double)y,(double)(w+x),(double)(h+y));
   1.961 +
   1.962 +	delete gfx;
   1.963 +	delete dev;
   1.964 +
   1.965 +	if (!str)
   1.966 +	{
   1.967 +		GB.ReturnNewZeroString("");
   1.968 +		return;
   1.969 +	}
   1.970 +	
   1.971 +	GB.ReturnNewString(str->getCString(),str->getLength());	
   1.972 +	delete str;
   1.973 +
   1.974 +END_METHOD
   1.975 +
   1.976 +/*****************************************************************************
   1.977 +
   1.978 + Bookmarks of a PDF page
   1.979 +
   1.980 +******************************************************************************/
   1.981 +
   1.982 +void aux_fill_links(void *_object)
   1.983 +{
   1.984 +	#if POPPLER_VERSION_0_20
   1.985 +	THIS->links = new Links (THIS->page->getAnnots ());
   1.986 +	#elif POPPLER_VERSION_0_17
   1.987 +	THIS->links = new Links (THIS->page->getAnnots (THIS->doc->getCatalog()));
   1.988 +	#else
   1.989 +	Object obj;
   1.990 +	
   1.991 +	THIS->links = new Links (THIS->page->getAnnots (&obj),THIS->doc->getCatalog()->getBaseURI ());
   1.992 +	obj.free();
   1.993 +	#endif
   1.994 +}
   1.995 +
   1.996 +BEGIN_PROPERTY (PDFPAGELINKS_count)
   1.997 +
   1.998 +	if (!THIS->links) aux_fill_links(_object);
   1.999 +	if (!THIS->links) { GB.ReturnInteger(0); return; }
  1.1000 +	GB.ReturnInteger(THIS->links->getNumLinks());
  1.1001 +
  1.1002 +
  1.1003 +END_PROPERTY
  1.1004 +
  1.1005 +BEGIN_METHOD (PDFPAGELINKS_get,GB_INTEGER ind;)
  1.1006 +
  1.1007 +	bool pok=true;
  1.1008 +
  1.1009 +	if (!THIS->links) aux_fill_links(_object);
  1.1010 +	if (!THIS->links) pok=false;
  1.1011 +	else
  1.1012 +	{
  1.1013 +		if (VARG(ind)<0) pok=false;
  1.1014 +		else
  1.1015 +		{
  1.1016 +			if (VARG(ind)>=THIS->links->getNumLinks()) pok=false;
  1.1017 +		}
  1.1018 +	}
  1.1019 +
  1.1020 +	if (!pok) { GB.Error("Out of bounds"); GB.ReturnNull(); return; }
  1.1021 +
  1.1022 +	THIS->lcurrent=VARG(ind);
  1.1023 +	THIS->action=THIS->links->getLink(THIS->lcurrent)->getAction();
  1.1024 +
  1.1025 +	RETURN_SELF();
  1.1026 +
  1.1027 +END_METHOD
  1.1028 +
  1.1029 +BEGIN_PROPERTY (PDFPAGELINKDATA_parameters)
  1.1030 +
  1.1031 +	if (THIS->action->getKind() != actionLaunch )
  1.1032 +	{
  1.1033 +		GB.ReturnNewZeroString("");
  1.1034 +		return;	
  1.1035 +	}
  1.1036 +
  1.1037 +	GB.ReturnNewZeroString(((LinkLaunch*)THIS->action)->getParams()->getCString());
  1.1038 +
  1.1039 +END_PROPERTY
  1.1040 +
  1.1041 +BEGIN_PROPERTY (PDFPAGELINKDATA_uri)
  1.1042 +
  1.1043 +	char *uri;
  1.1044 +
  1.1045 +	uri=aux_get_target_from_action(THIS->action);
  1.1046 +
  1.1047 +	GB.ReturnNewZeroString(uri);
  1.1048 +	if (uri) GB.FreeString(&uri);
  1.1049 +
  1.1050 +END_PROPERTY
  1.1051 +
  1.1052 +BEGIN_PROPERTY(PDFPAGELINKDATA_left)
  1.1053 +
  1.1054 +	int32_t vl;
  1.1055 +
  1.1056 +	aux_get_dimensions_from_action(THIS->action,&vl, NULL, NULL, NULL);
  1.1057 +	GB.ReturnInteger(vl);
  1.1058 +
  1.1059 +END_PROPERTY
  1.1060 +
  1.1061 +BEGIN_PROPERTY(PDFPAGELINKDATA_right)
  1.1062 +
  1.1063 +	int32_t vl;
  1.1064 +
  1.1065 +	aux_get_dimensions_from_action(THIS->action,NULL,&vl, NULL, NULL);
  1.1066 +	GB.ReturnInteger(vl);
  1.1067 +
  1.1068 +END_PROPERTY
  1.1069 +
  1.1070 +BEGIN_PROPERTY(PDFPAGELINKDATA_top)
  1.1071 +
  1.1072 +	int32_t vl;
  1.1073 +
  1.1074 +	aux_get_dimensions_from_action(THIS->action,NULL,NULL,&vl, NULL);
  1.1075 +	GB.ReturnInteger(vl);
  1.1076 +
  1.1077 +END_PROPERTY
  1.1078 +
  1.1079 +BEGIN_PROPERTY(PDFPAGELINKDATA_bottom)
  1.1080 +
  1.1081 +	int32_t vl;
  1.1082 +
  1.1083 +	aux_get_dimensions_from_action(THIS->action,NULL, NULL, NULL,&vl);
  1.1084 +
  1.1085 +	GB.ReturnInteger(vl);
  1.1086 +
  1.1087 +END_PROPERTY
  1.1088 +
  1.1089 +BEGIN_PROPERTY(PDFPAGELINKDATA_zoom)
  1.1090 +
  1.1091 +	GB.ReturnFloat(aux_get_zoom_from_action(THIS->action));
  1.1092 +
  1.1093 +END_PROPERTY
  1.1094 +
  1.1095 +BEGIN_PROPERTY(PDFPAGELINKDATA_page)
  1.1096 +
  1.1097 +	GB.ReturnInteger(aux_get_page_from_action(_object,THIS->action));
  1.1098 +
  1.1099 +END_PROPERTY
  1.1100 +
  1.1101 +BEGIN_PROPERTY (PDFPAGELINKDATA_type)
  1.1102 +
  1.1103 +	GB.ReturnInteger ( (int32_t)THIS->action->getKind() );
  1.1104 +
  1.1105 +END_PROPERTY
  1.1106 +
  1.1107 +BEGIN_PROPERTY(PDFPAGELINKDATA_check)
  1.1108 +
  1.1109 +	if (THIS->action)
  1.1110 +		RETURN_SELF();
  1.1111 +	else
  1.1112 +		GB.ReturnNull();
  1.1113 +
  1.1114 +END_PROPERTY
  1.1115 +
  1.1116 +void aux_get_link_dimensions(void *_object,int32_t *left, int32_t *top, int32_t *width, int32_t *height)
  1.1117 +{
  1.1118 +	double l,t,w,h;
  1.1119 +	double pw,ph;
  1.1120 +
  1.1121 +	pw=THIS->page->getMediaWidth();	
  1.1122 +	ph=THIS->page->getMediaHeight();
  1.1123 +
  1.1124 +	THIS->links->getLink(THIS->lcurrent)->getRect(&l, &t, &w, &h);
  1.1125 +	w=w-l;
  1.1126 +	h=h-t;	
  1.1127 +
  1.1128 +	switch (THIS->rotation)
  1.1129 +	{
  1.1130 +		case 0:
  1.1131 +			if (left) *left=(int32_t)(l*THIS->scale);
  1.1132 +			if (top) *top=(int32_t)((ph-t-h)*THIS->scale);
  1.1133 +			if (width) *width=(int32_t)(w*THIS->scale);
  1.1134 +			if (height) *height=(int32_t)(h*THIS->scale);
  1.1135 +			break;
  1.1136 +	
  1.1137 +		case 90:
  1.1138 +			if (top) *top=(int32_t)(l*THIS->scale);
  1.1139 +			if (left) *left=(int32_t)(t*THIS->scale);
  1.1140 +			if (height) *height=(int32_t)(w*THIS->scale);
  1.1141 +			if (width) *width=(int32_t)(h*THIS->scale);
  1.1142 +			break;
  1.1143 +
  1.1144 +		case 180:
  1.1145 +			if (left) *left=(int32_t)((l-w)*THIS->scale);
  1.1146 +			if (top) *top=(int32_t)(t*THIS->scale);
  1.1147 +			if (width) *width=(int32_t)(w*THIS->scale);
  1.1148 +			if (height) *height=(int32_t)(h*THIS->scale);
  1.1149 +			break;
  1.1150 +
  1.1151 +		case 270:
  1.1152 +			if (top) *top=(int32_t)((pw-l-w)*THIS->scale);
  1.1153 +			if (left) *left=(int32_t)((ph-t-h)*THIS->scale);
  1.1154 +			if (height) *height=(int32_t)(w*THIS->scale);
  1.1155 +			if (width) *width=(int32_t)(h*THIS->scale);
  1.1156 +			break;
  1.1157 +	}
  1.1158 +
  1.1159 +}
  1.1160 +
  1.1161 +BEGIN_PROPERTY (PDFPAGELINK_width)
  1.1162 +
  1.1163 +	int32_t vl;
  1.1164 +	
  1.1165 +	aux_get_link_dimensions(_object,NULL,NULL,&vl,NULL);
  1.1166 +	GB.ReturnInteger(vl);
  1.1167 +
  1.1168 +END_PROPERTY
  1.1169 +
  1.1170 +BEGIN_PROPERTY (PDFPAGELINK_height)
  1.1171 +
  1.1172 +	int32_t vl;
  1.1173 +	
  1.1174 +	aux_get_link_dimensions(_object,NULL,NULL,NULL,&vl);
  1.1175 +	GB.ReturnInteger(vl);
  1.1176 +
  1.1177 +
  1.1178 +END_PROPERTY
  1.1179 +
  1.1180 +BEGIN_PROPERTY (PDFPAGELINK_left)
  1.1181 +
  1.1182 +	int32_t vl;
  1.1183 +	
  1.1184 +	aux_get_link_dimensions(_object,&vl,NULL,NULL,NULL);
  1.1185 +	GB.ReturnInteger(vl);
  1.1186 +	
  1.1187 +
  1.1188 +END_PROPERTY
  1.1189 +
  1.1190 +BEGIN_PROPERTY (PDFPAGELINK_top)
  1.1191 +
  1.1192 +	int32_t vl;
  1.1193 +	
  1.1194 +	aux_get_link_dimensions(_object,NULL,&vl,NULL,NULL);
  1.1195 +	GB.ReturnInteger(vl);
  1.1196 +
  1.1197 +END_PROPERTY
  1.1198 +
  1.1199 +/*****************************************************************************
  1.1200 +
  1.1201 + Finding a text in a PDF page
  1.1202 +
  1.1203 +******************************************************************************/
  1.1204 +
  1.1205 +BEGIN_METHOD (PDFPAGE_find,GB_STRING Text; GB_BOOLEAN Sensitive;)
  1.1206 +
  1.1207 +	TextOutputDev *textdev;
  1.1208 +	double x0=0, y0=0;
  1.1209 +	double x1, y1;
  1.1210 +	FoundRect *el;	
  1.1211 +	Unicode *block=NULL;
  1.1212 +	int32_t nlen=0;
  1.1213 +	bool sensitive=false;
  1.1214 +
  1.1215 +	// TODO: Use UCS-4BE on big endian systems?
  1.1216 +	if (GB.ConvString ((char **)(void *)&block,STRING(Text),LENGTH(Text),"UTF-8","UCS-4LE"))
  1.1217 +	{	
  1.1218 +		GB.Error("Invalid UTF-8 string"); 
  1.1219 +		return;
  1.1220 +	}
  1.1221 +
  1.1222 +	nlen=GB.StringLength((char*)block)/sizeof(Unicode);
  1.1223 +
  1.1224 +	if (!MISSING(Sensitive)) sensitive=VARG(Sensitive);
  1.1225 +
  1.1226 +	#if POPPLER_VERSION_0_20
  1.1227 +	textdev = new TextOutputDev (NULL, true, 0, false, false);
  1.1228 +	THIS->page->display (textdev, 72, 72, 0, false, false, false);
  1.1229 +	#else
  1.1230 +	textdev = new TextOutputDev (NULL, true, false, false);
  1.1231 +	THIS->page->display (textdev, 72, 72, 0, false, false, false, THIS->doc->getCatalog());
  1.1232 +	#endif
  1.1233 +
  1.1234 +	if (THIS->Found) { GB.FreeArray(POINTER(&THIS->Found)); THIS->Found=NULL; }
  1.1235 +
  1.1236 +	#if POPPLER_VERSION_0_20
  1.1237 +	while (textdev->findText (block,nlen,gFalse,gTrue,gTrue,gFalse,sensitive,gFalse,gFalse,&x0,&y0,&x1,&y1))
  1.1238 +	#else
  1.1239 +	while (textdev->findText (block,nlen,gFalse,gTrue,gTrue,gFalse,sensitive,gFalse,&x0,&y0,&x1,&y1))
  1.1240 +	#endif
  1.1241 +	{
  1.1242 +		if (!THIS->Found) {
  1.1243 +			GB.NewArray(POINTER(&THIS->Found),sizeof(FoundRect),1);
  1.1244 +		}		
  1.1245 +		else {
  1.1246 +			GB.Add(POINTER(&THIS->Found));
  1.1247 +		}
  1.1248 +
  1.1249 +		el=(FoundRect*)&((FoundRect*)THIS->Found)[GB.Count(POINTER(THIS->Found))-1];
  1.1250 +		
  1.1251 +		switch (THIS->rotation)
  1.1252 +		{
  1.1253 +			case 0:
  1.1254 +				el->x0=(int32_t)(x0*THIS->scale);
  1.1255 +				el->y0=(int32_t)(y0*THIS->scale);
  1.1256 +				el->x1=(int32_t)((x1-x0)*THIS->scale);
  1.1257 +				el->y1=(int32_t)((y1-y0)*THIS->scale);
  1.1258 +				break;
  1.1259 +
  1.1260 +			case 90:
  1.1261 +				el->y1=(int32_t)((x1-x0)*THIS->scale);
  1.1262 +				el->x1=(int32_t)(y1-y0);
  1.1263 +				el->y0=(int32_t)(x0*THIS->scale);
  1.1264 +				el->x0=(int32_t)((THIS->page->getMediaHeight()-y0-el->x1)*THIS->scale);
  1.1265 +				el->x1=(int32_t)(el->x1*THIS->scale);
  1.1266 +				break;
  1.1267 +
  1.1268 +			case 180:
  1.1269 +				el->x1=(int32_t)(x1-x0);
  1.1270 +				el->y1=(int32_t)(y1-y0);
  1.1271 +				el->x0=(int32_t)((THIS->page->getMediaWidth()-x0-el->x1)*THIS->scale);
  1.1272 +				el->y0=(int32_t)((THIS->page->getMediaHeight()-y0-el->y1)*THIS->scale);
  1.1273 +				el->x1=(int32_t)(el->x1*THIS->scale);
  1.1274 +				el->y1=(int32_t)(el->y1*THIS->scale);
  1.1275 +				break;
  1.1276 +
  1.1277 +			case 270:
  1.1278 +				el->x1=(int32_t)((y1-y0)*THIS->scale);
  1.1279 +				el->y1=(int32_t)(x1-x0);
  1.1280 +				el->x0=(int32_t)(y0*THIS->scale);
  1.1281 +				el->y0=(int32_t)((THIS->page->getMediaWidth()-x0-el->y1)*THIS->scale);
  1.1282 +				el->y1=(int32_t)(el->y1*THIS->scale);
  1.1283 +				break;
  1.1284 +
  1.1285 +		}
  1.1286 +	}
  1.1287 +
  1.1288 +	delete textdev;
  1.1289 +
  1.1290 +
  1.1291 +END_METHOD
  1.1292 +
  1.1293 +
  1.1294 +BEGIN_METHOD (PDFPAGERESULT_get,GB_INTEGER Index;)
  1.1295 +
  1.1296 +	bool bok=true;
  1.1297 +
  1.1298 +	if (!THIS->Found) bok=false;
  1.1299 +	else
  1.1300 +	{
  1.1301 +		if (VARG(Index)<0) bok=false;
  1.1302 +		if (VARG(Index)>= GB.Count(POINTER(THIS->Found)) ) bok=false;
  1.1303 +	}
  1.1304 +	if (!bok) { GB.Error("Out of bounds"); GB.ReturnNull(); return; }
  1.1305 +
  1.1306 +	THIS->fcurrent=VARG(Index);
  1.1307 +	RETURN_SELF();
  1.1308 +
  1.1309 +END_METHOD
  1.1310 +
  1.1311 +BEGIN_PROPERTY (PDFPAGERESULT_count)
  1.1312 +
  1.1313 +	if (!THIS->Found) { GB.ReturnInteger(0); return; } 
  1.1314 +	GB.ReturnInteger( GB.Count(POINTER(THIS->Found)) );
  1.1315 +
  1.1316 +END_PROPERTY
  1.1317 +
  1.1318 +BEGIN_PROPERTY (PDFPAGERESULT_width)
  1.1319 +
  1.1320 +	FoundRect *el=(FoundRect*)&((FoundRect*)THIS->Found)[THIS->fcurrent];
  1.1321 +	GB.ReturnInteger((int32_t)el->x1);
  1.1322 +
  1.1323 +END_PROPERTY
  1.1324 +
  1.1325 +BEGIN_PROPERTY (PDFPAGERESULT_height)
  1.1326 +
  1.1327 +	FoundRect *el=(FoundRect*)&((FoundRect*)THIS->Found)[THIS->fcurrent];
  1.1328 +	GB.ReturnInteger((int32_t)el->y1);
  1.1329 +
  1.1330 +END_PROPERTY
  1.1331 +
  1.1332 +BEGIN_PROPERTY (PDFPAGERESULT_left)
  1.1333 +
  1.1334 +	FoundRect *el=(FoundRect*)&((FoundRect*)THIS->Found)[THIS->fcurrent];
  1.1335 +	GB.ReturnInteger((int32_t)el->x0);
  1.1336 +
  1.1337 +END_PROPERTY
  1.1338 +
  1.1339 +BEGIN_PROPERTY (PDFPAGERESULT_top)
  1.1340 +
  1.1341 +	FoundRect *el=(FoundRect*)&((FoundRect*)THIS->Found)[THIS->fcurrent];
  1.1342 +	GB.ReturnInteger((int32_t)el->y0);
  1.1343 +
  1.1344 +END_PROPERTY
  1.1345 +
  1.1346 +/**********************************************************************
  1.1347 +
  1.1348 +Gambas Interface
  1.1349 +
  1.1350 +***********************************************************************/
  1.1351 +
  1.1352 +
  1.1353 +GB_DESC PdfResultItemDesc[]=
  1.1354 +{
  1.1355 +	GB_DECLARE(".PdfResultItem",0), GB_VIRTUAL_CLASS(),
  1.1356 +
  1.1357 +	GB_PROPERTY_READ("Left","i",PDFPAGERESULT_left),
  1.1358 +	GB_PROPERTY_READ("Top","i",PDFPAGERESULT_top),
  1.1359 +	GB_PROPERTY_READ("Width","i",PDFPAGERESULT_width),
  1.1360 +	GB_PROPERTY_READ("Height","i",PDFPAGERESULT_height),
  1.1361 +
  1.1362 +	GB_END_DECLARE
  1.1363 +};
  1.1364 +
  1.1365 +GB_DESC PdfResultDesc[]=
  1.1366 +{
  1.1367 +	GB_DECLARE(".PdfResult",0), GB_VIRTUAL_CLASS(),
  1.1368 +
  1.1369 +	GB_METHOD("_get",".PdfResultItem",PDFPAGERESULT_get,"(Index)i"),
  1.1370 +	GB_PROPERTY_READ("Count","i",PDFPAGERESULT_count),
  1.1371 +
  1.1372 +	GB_END_DECLARE
  1.1373 +};
  1.1374 +
  1.1375 +
  1.1376 +GB_DESC PdfLinkDataDesc[]=
  1.1377 +{
  1.1378 +	GB_DECLARE(".PdfLinkData",0), GB_VIRTUAL_CLASS(),
  1.1379 +
  1.1380 +	GB_PROPERTY_READ("Type","i",PDFPAGELINKDATA_type),
  1.1381 +	GB_PROPERTY_READ("Target","s",PDFPAGELINKDATA_uri),
  1.1382 +	GB_PROPERTY_READ("Parameters","s",PDFPAGELINKDATA_parameters),
  1.1383 +	GB_PROPERTY_READ("Page","i",PDFPAGELINKDATA_page),
  1.1384 +	GB_PROPERTY_READ("Left","i",PDFPAGELINKDATA_left),
  1.1385 +	GB_PROPERTY_READ("Top","i",PDFPAGELINKDATA_top),
  1.1386 +	GB_PROPERTY_READ("Right","i",PDFPAGELINKDATA_right),
  1.1387 +	GB_PROPERTY_READ("Bottom","i",PDFPAGELINKDATA_bottom),
  1.1388 +	GB_PROPERTY_READ("Zoom","f",PDFPAGELINKDATA_zoom),
  1.1389 +
  1.1390 +	GB_END_DECLARE
  1.1391 +};
  1.1392 +
  1.1393 +GB_DESC PdfLinkDesc[]=
  1.1394 +{
  1.1395 +	GB_DECLARE(".PdfLink",0), GB_VIRTUAL_CLASS(),
  1.1396 +
  1.1397 +	GB_PROPERTY_READ("Left","i",PDFPAGELINK_left),
  1.1398 +	GB_PROPERTY_READ("Top","i",PDFPAGELINK_top),
  1.1399 +	GB_PROPERTY_READ("Width","i",PDFPAGELINK_width),
  1.1400 +	GB_PROPERTY_READ("Height","i",PDFPAGELINK_height),
  1.1401 +	GB_PROPERTY_READ("Data", ".PdfLinkData", PDFPAGELINKDATA_check),
  1.1402 +
  1.1403 +	GB_END_DECLARE
  1.1404 +};
  1.1405 +
  1.1406 +GB_DESC PdfIndexDesc[]=
  1.1407 +{
  1.1408 +	GB_DECLARE(".PdfIndex",0), GB_VIRTUAL_CLASS(),
  1.1409 +
  1.1410 +	GB_PROPERTY("Expanded","b",PDFINDEX_is_open),
  1.1411 +	GB_PROPERTY_READ("Count","i",PDFINDEX_count),
  1.1412 +	GB_PROPERTY_READ("HasChildren","b",PDFINDEX_has_children),
  1.1413 +	GB_PROPERTY_READ("Title","s",PDFINDEX_title),
  1.1414 +
  1.1415 +	GB_PROPERTY_READ("Data", ".PdfLinkData", PDFPAGELINKDATA_check),
  1.1416 +	GB_METHOD("MovePrevious","b",PDFINDEX_prev,0),
  1.1417 +	GB_METHOD("MoveNext","b",PDFINDEX_next,0),
  1.1418 +	GB_METHOD("MoveChild","b",PDFINDEX_child,0),
  1.1419 +	GB_METHOD("MoveParent","b",PDFINDEX_parent,0),
  1.1420 +	GB_METHOD("MoveRoot",0,PDFINDEX_root,0),
  1.1421 +
  1.1422 +	GB_END_DECLARE
  1.1423 +};
  1.1424 +
  1.1425 +
  1.1426 +GB_DESC PdfPageDesc[]=
  1.1427 +{
  1.1428 +	GB_DECLARE(".PdfPage",0), GB_VIRTUAL_CLASS(),
  1.1429 +
  1.1430 +	GB_PROPERTY_READ("W","f",PDFPAGE_width),
  1.1431 +	GB_PROPERTY_READ("H","f",PDFPAGE_height),
  1.1432 +	GB_PROPERTY_READ("Width","f",PDFPAGE_width),
  1.1433 +	GB_PROPERTY_READ("Height","f",PDFPAGE_height),
  1.1434 +	GB_PROPERTY_READ("Picture","Picture",PDFPAGE_property_picture),
  1.1435 +	GB_PROPERTY_READ("Image","Image",PDFPAGE_property_image),
  1.1436 +	GB_PROPERTY_SELF("Result",".PdfResult"),
  1.1437 +
  1.1438 +	GB_METHOD("GetImage","Image",PDFPAGE_image,"[(X)i(Y)i(Width)i(Height)i]"),
  1.1439 +	GB_METHOD("GetPicture","Picture",PDFPAGE_picture,"[(X)i(Y)i(Width)i(Height)i]"),
  1.1440 +	GB_METHOD("Find","b",PDFPAGE_find,"(Text)s[(CaseSensitive)b]"),
  1.1441 +	GB_METHOD("Select","s",PDFPAGE_select,"[(X)i(Y)i(W)i(H)i]"),
  1.1442 +
  1.1443 +	GB_METHOD("_get",".PdfLink",PDFPAGELINKS_get,"(Index)i"),
  1.1444 +	GB_PROPERTY_READ("Count","i",PDFPAGELINKS_count),
  1.1445 +
  1.1446 +	GB_END_DECLARE
  1.1447 +};
  1.1448 +
  1.1449 +GB_DESC PdfDocumentInfo[] =
  1.1450 +{
  1.1451 +	GB_DECLARE(".PdfInfo",0), GB_VIRTUAL_CLASS(),
  1.1452 +
  1.1453 +	GB_PROPERTY_READ("Title","s",PDFINFO_title),
  1.1454 +	GB_PROPERTY_READ("Format","s",PDFINFO_format),
  1.1455 +	GB_PROPERTY_READ("Author","s",PDFINFO_author),
  1.1456 +	GB_PROPERTY_READ("Subject","s",PDFINFO_subject),
  1.1457 +	GB_PROPERTY_READ("Keywords","s",PDFINFO_keywords),
  1.1458 +	GB_PROPERTY_READ("Creator","s",PDFINFO_creator),
  1.1459 +	GB_PROPERTY_READ("Producer","s",PDFINFO_producer),
  1.1460 +	GB_PROPERTY_READ("CreationDate","d",PDFINFO_creation),
  1.1461 +	GB_PROPERTY_READ("ModificationDate","d",PDFINFO_modification),
  1.1462 +	GB_PROPERTY_READ("Linearized","b",PDFINFO_linearized),
  1.1463 +	GB_PROPERTY_READ("Layout","i",PDFINFO_layout),
  1.1464 +	GB_PROPERTY_READ("Mode","i",PDFINFO_mode),
  1.1465 +	GB_PROPERTY_READ("CanCopy","b",PDFINFO_cancopy),
  1.1466 +	GB_PROPERTY_READ("CanModify","b",PDFINFO_canmodify),
  1.1467 +	GB_PROPERTY_READ("CanPrint","b",PDFINFO_canprint),
  1.1468 +	GB_PROPERTY_READ("CanAddNotes","b",PDFINFO_canaddnotes),
  1.1469 +
  1.1470 +	GB_END_DECLARE
  1.1471 +};
  1.1472 +
  1.1473 +GB_DESC PdfLayoutDesc[] =
  1.1474 +{
  1.1475 +
  1.1476 +  GB_DECLARE("PdfLayout", 0), GB_NOT_CREATABLE(),
  1.1477 +
  1.1478 +  GB_CONSTANT("Unset","i",Catalog::pageLayoutNone),
  1.1479 +  GB_CONSTANT("SinglePage","i",Catalog::pageLayoutSinglePage),
  1.1480 +  GB_CONSTANT("OneColumn","i",Catalog::pageLayoutOneColumn),
  1.1481 +  GB_CONSTANT("TwoColumnLeft","i",Catalog::pageLayoutTwoColumnLeft),
  1.1482 +  GB_CONSTANT("TwoColumnRight","i",Catalog::pageLayoutTwoColumnRight),
  1.1483 +  GB_CONSTANT("TwoPageLeft","i",Catalog::pageLayoutTwoPageLeft),
  1.1484 +  GB_CONSTANT("TwoPageRight","i",Catalog::pageLayoutTwoPageRight),
  1.1485 +
  1.1486 +  GB_END_DECLARE
  1.1487 +};
  1.1488 +
  1.1489 +
  1.1490 +GB_DESC PdfModeDesc[] =
  1.1491 +{
  1.1492 +	GB_DECLARE("PdfPageMode",0), GB_NOT_CREATABLE(),
  1.1493 +
  1.1494 +	GB_CONSTANT("Unset","i",Catalog::pageModeNone),
  1.1495 +	GB_CONSTANT("UseOutlines","i",Catalog::pageModeOutlines),
  1.1496 +	GB_CONSTANT("UseThumbs","i",Catalog::pageModeThumbs),
  1.1497 +	GB_CONSTANT("FullScreen","i",Catalog::pageModeFullScreen),
  1.1498 +	GB_CONSTANT("UseOC","i",Catalog::pageModeOC),
  1.1499 +	GB_CONSTANT("UseAttachments","i",Catalog::pageModeAttach),
  1.1500 +
  1.1501 +	GB_END_DECLARE
  1.1502 +};
  1.1503 +
  1.1504 +GB_DESC PdfDocumentDesc[] =
  1.1505 +{
  1.1506 +
  1.1507 +  GB_DECLARE("PdfDocument", sizeof(CPDFDOCUMENT)),
  1.1508 +
  1.1509 +  GB_CONSTANT("Unknown","i",actionUnknown),  /* unknown action */
  1.1510 +  GB_CONSTANT("Goto","i",actionGoTo),        /* go to destination */
  1.1511 +  GB_CONSTANT("GotoRemote","i",actionGoToR), /* go to destination in new file */
  1.1512 +  GB_CONSTANT("Launch","i",actionLaunch),    /* launch app or open doc. */
  1.1513 +  GB_CONSTANT("Uri","i",actionURI),          /* URI */
  1.1514 +  GB_CONSTANT("Named","i",actionNamed),      /* named action*/
  1.1515 +  GB_CONSTANT("Movie","i",actionMovie),      /* movie action */
  1.1516 +
  1.1517 +  GB_CONSTANT("Normal","i",0),
  1.1518 +  GB_CONSTANT("Sideways","i",90),
  1.1519 +  GB_CONSTANT("Inverted","i",180),
  1.1520 +  GB_CONSTANT("SidewaysInverted","i",270),
  1.1521 +
  1.1522 +  GB_METHOD("_new", 0, PDFDOCUMENT_new, "[(File)s]"),
  1.1523 +  GB_METHOD("_free", 0, PDFDOCUMENT_free, 0),
  1.1524 +
  1.1525 +  GB_METHOD("Open",0,PDFDOCUMENT_open,"(File)s"),
  1.1526 +  GB_METHOD("Close",0,PDFDOCUMENT_close,0),
  1.1527 +  GB_METHOD("_get",".PdfPage",PDFDOCUMENT_get,"(Index)i"),
  1.1528 +
  1.1529 +  GB_PROPERTY("Zoom", "f", PDFDOCUMENT_scale),
  1.1530 +  GB_PROPERTY("Orientation", "i", PDFDOCUMENT_rotation),
  1.1531 +
  1.1532 +  GB_PROPERTY_READ("Ready","b",PDFDOCUMENT_ready),
  1.1533 +  GB_PROPERTY_READ("Count","i",PDFDOCUMENT_count),
  1.1534 +  GB_PROPERTY_READ("HasIndex","b",PDFDOCUMENT_has_index),
  1.1535 +  GB_PROPERTY_READ("Index",".PdfIndex",PDFDOCUMENT_index),
  1.1536 +  GB_PROPERTY_READ("Info",".PdfInfo",PDFDOCUMENT_info),
  1.1537 +
  1.1538 +  GB_END_DECLARE
  1.1539 +};
  1.1540 +
  1.1541 +