1 /* poppler-private.h: qt interface to poppler
2  * Copyright (C) 2005, Net Integration Technologies, Inc.
3  * Copyright (C) 2005-2008, Albert Astals Cid <aacid@kde.org>
4  * Copyright (C) 2006, Kristian Høgsberg <krh@bitplanet.net>
5  * Copyright (C) 2006, Wilfried Huss <Wilfried.Huss@gmx.at>
6  * Copyright (C) 2007, Pino Toscano <pino@kde.org>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2, or (at your option)
11  * any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
21  */
22 
23 #include "poppler-private.h"
24 #include "poppler-link-qt3.h"
25 
26 #include <qstring.h>
27 
28 #include <Outline.h>
29 #include <Link.h>
30 
31 namespace Poppler {
32 
33 /* borrowed from kpdf */
unicodeToQString(Unicode * u,int len)34 QString unicodeToQString(Unicode* u, int len)
35 {
36     QString ret;
37     ret.setLength(len);
38     QChar* qch = (QChar*) ret.unicode();
39     for (;len;--len)
40       *qch++ = (QChar) *u++;
41     return ret;
42 }
43 
UnicodeParsedString(GooString * s1)44 QString UnicodeParsedString(GooString *s1)
45 {
46     GBool isUnicode;
47     int i;
48     Unicode u;
49     QString result;
50     if ( ( s1->getChar(0) & 0xff ) == 0xfe && ( s1->getChar(1) & 0xff ) == 0xff )
51     {
52         isUnicode = gTrue;
53         i = 2;
54     }
55     else
56     {
57         isUnicode = gFalse;
58         i = 0;
59     }
60     while ( i < s1->getLength() )
61     {
62         if ( isUnicode )
63         {
64             u = ( ( s1->getChar(i) & 0xff ) << 8 ) | ( s1->getChar(i+1) & 0xff );
65             i += 2;
66         }
67         else
68         {
69             u = s1->getChar(i) & 0xff;
70             ++i;
71         }
72         result += unicodeToQString( &u, 1 );
73     }
74     return result;
75 }
76 
QStringToGooString(const QString & s)77 GooString *QStringToGooString(const QString &s)
78 {
79     int len = s.length();
80     char *cstring = (char *)gmallocn(s.length(), sizeof(char));
81     for (int i = 0; i < len; ++i)
82       cstring[i] = s.at(i).unicode();
83     GooString *ret = new GooString(cstring, len);
84     gfree(cstring);
85     return ret;
86 }
87 
88 
addTocChildren(QDomDocument * docSyn,QDomNode * parent,GooList * items)89 void DocumentData::addTocChildren( QDomDocument * docSyn, QDomNode * parent, GooList * items )
90 {
91     int numItems = items->getLength();
92     for ( int i = 0; i < numItems; ++i )
93     {
94         // iterate over every object in 'items'
95         OutlineItem * outlineItem = (OutlineItem *)items->get( i );
96 
97         // 1. create element using outlineItem's title as tagName
98         QString name;
99         Unicode * uniChar = outlineItem->getTitle();
100         int titleLength = outlineItem->getTitleLength();
101         name = unicodeToQString(uniChar, titleLength);
102         if ( name.isEmpty() )
103             continue;
104 
105         QDomElement item = docSyn->createElement( name );
106         parent->appendChild( item );
107 
108         // 2. find the page the link refers to
109         ::LinkAction * a = outlineItem->getAction();
110         if ( a && ( a->getKind() == actionGoTo || a->getKind() == actionGoToR ) )
111         {
112             // page number is contained/referenced in a LinkGoTo
113             LinkGoTo * g = static_cast< LinkGoTo * >( a );
114             LinkDest * destination = g->getDest();
115             if ( !destination && g->getNamedDest() )
116             {
117                 // no 'destination' but an internal 'named reference'. we could
118                 // get the destination for the page now, but it's VERY time consuming,
119                 // so better storing the reference and provide the viewport on demand
120                 GooString *s = g->getNamedDest();
121                 QChar *charArray = new QChar[s->getLength()];
122                 for (int i = 0; i < s->getLength(); ++i) charArray[i] = QChar(s->getCString()[i]);
123                     QString aux(charArray, s->getLength());
124                     item.setAttribute( "DestinationName", aux );
125                     delete[] charArray;
126                 }
127                 else if ( destination && destination->isOk() )
128                 {
129                     LinkDestinationData ldd(destination, NULL, this);
130                     item.setAttribute( "Destination", LinkDestination(ldd).toString() );
131                 }
132                 if ( a->getKind() == actionGoToR )
133                 {
134                     LinkGoToR * g2 = static_cast< LinkGoToR * >( a );
135                     item.setAttribute( "ExternalFileName", g2->getFileName()->getCString() );
136                 }
137             }
138 
139         // 3. recursively descend over children
140         outlineItem->open();
141         GooList * children = outlineItem->getKids();
142         if ( children )
143             addTocChildren( docSyn, &item, children );
144     }
145 }
146 
147 }
148