~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/poppler/qt4/src/poppler-private.cc

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* poppler-private.cc: qt interface to poppler
 
2
 * Copyright (C) 2005, Net Integration Technologies, Inc.
 
3
 * Copyright (C) 2006, 2011 by Albert Astals Cid <aacid@kde.org>
 
4
 * Copyright (C) 2008, 2010, 2011 by Pino Toscano <pino@kde.org>
 
5
 * Inspired on code by
 
6
 * Copyright (C) 2004 by Albert Astals Cid <tsdgeos@terra.es>
 
7
 * Copyright (C) 2004 by Enrico Ros <eros.kde@email.it>
 
8
 *
 
9
 * This program is free software; you can redistribute it and/or modify
 
10
 * it under the terms of the GNU General Public License as published by
 
11
 * the Free Software Foundation; either version 2, or (at your option)
 
12
 * any later version.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License
 
20
 * along with this program; if not, write to the Free Software
 
21
 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
 
22
 */
 
23
 
 
24
#include "poppler-private.h"
 
25
 
 
26
#include <QtCore/QByteArray>
 
27
#include <QtCore/QDebug>
 
28
#include <QtCore/QVariant>
 
29
 
 
30
#include <Link.h>
 
31
#include <Outline.h>
 
32
#include <UnicodeMap.h>
 
33
 
 
34
namespace Poppler {
 
35
 
 
36
namespace Debug {
 
37
 
 
38
    void qDebugDebugFunction(const QString &message, const QVariant & /*closure*/)
 
39
    {
 
40
        qDebug() << message;
 
41
    }
 
42
 
 
43
    PopplerDebugFunc debugFunction = qDebugDebugFunction;
 
44
    QVariant debugClosure;
 
45
 
 
46
}
 
47
 
 
48
    static UnicodeMap *utf8Map = 0;
 
49
 
 
50
    void setDebugErrorFunction(PopplerDebugFunc function, const QVariant &closure)
 
51
    {
 
52
        Debug::debugFunction = function ? function : Debug::qDebugDebugFunction;
 
53
        Debug::debugClosure = closure;
 
54
    }
 
55
 
 
56
    void qt4ErrorFunction(int pos, char *msg, va_list args)
 
57
    {
 
58
        QString emsg;
 
59
        char buffer[1024]; // should be big enough
 
60
 
 
61
        if (pos >= 0)
 
62
        {
 
63
            emsg = QString::fromLatin1("Error (%1): ").arg(pos);
 
64
        }
 
65
        else
 
66
        {
 
67
            emsg = QString::fromLatin1("Error: ");
 
68
        }
 
69
        qvsnprintf(buffer, sizeof(buffer) - 1, msg, args);
 
70
        emsg += QString::fromAscii(buffer);
 
71
        (*Debug::debugFunction)(emsg, Debug::debugClosure);
 
72
    }
 
73
 
 
74
    QString unicodeToQString(Unicode* u, int len) {
 
75
        if (!utf8Map)
 
76
        {
 
77
                GooString enc("UTF-8");
 
78
                utf8Map = globalParams->getUnicodeMap(&enc);
 
79
                utf8Map->incRefCnt();
 
80
        }
 
81
 
 
82
        // ignore the last character if it is 0x0
 
83
        if ((len > 0) && (u[len - 1] == 0))
 
84
        {
 
85
            --len;
 
86
        }
 
87
 
 
88
        GooString convertedStr;
 
89
        for (int i = 0; i < len; ++i)
 
90
        {
 
91
            char buf[8];
 
92
            const int n = utf8Map->mapUnicode(u[i], buf, sizeof(buf));
 
93
            convertedStr.append(buf, n);
 
94
        }
 
95
 
 
96
        return QString::fromUtf8(convertedStr.getCString(), convertedStr.getLength());
 
97
    }
 
98
 
 
99
    QString UnicodeParsedString(GooString *s1) {
 
100
        if ( !s1 || s1->getLength() == 0 )
 
101
            return QString();
 
102
 
 
103
        GBool isUnicode;
 
104
        int i;
 
105
        Unicode u;
 
106
        QString result;
 
107
        if ( ( s1->getChar(0) & 0xff ) == 0xfe && ( s1->getLength() > 1 && ( s1->getChar(1) & 0xff ) == 0xff ) )
 
108
        {
 
109
            isUnicode = gTrue;
 
110
            i = 2;
 
111
            result.reserve( ( s1->getLength() - 2 ) / 2 );
 
112
        }
 
113
        else
 
114
        {
 
115
            isUnicode = gFalse;
 
116
            i = 0;
 
117
            result.reserve( s1->getLength() );
 
118
        }
 
119
        while ( i < s1->getLength() )
 
120
        {
 
121
            if ( isUnicode )
 
122
            {
 
123
                u = ( ( s1->getChar(i) & 0xff ) << 8 ) | ( s1->getChar(i+1) & 0xff );
 
124
                i += 2;
 
125
            }
 
126
            else
 
127
            {
 
128
                u = s1->getChar(i) & 0xff;
 
129
                ++i;
 
130
            }
 
131
            result += QChar( u );
 
132
        }
 
133
        return result;
 
134
    }
 
135
 
 
136
    GooString *QStringToUnicodeGooString(const QString &s) {
 
137
        int len = s.length() * 2 + 2;
 
138
        char *cstring = (char *)gmallocn(len, sizeof(char));
 
139
        cstring[0] = 0xfe;
 
140
        cstring[1] = 0xff;
 
141
        for (int i = 0; i < s.length(); ++i)
 
142
        {
 
143
            cstring[2+i*2] = s.at(i).row();
 
144
            cstring[3+i*2] = s.at(i).cell();
 
145
        }
 
146
        GooString *ret = new GooString(cstring, len);
 
147
        gfree(cstring);
 
148
        return ret;
 
149
    }
 
150
 
 
151
    GooString *QStringToGooString(const QString &s) {
 
152
        int len = s.length();
 
153
        char *cstring = (char *)gmallocn(s.length(), sizeof(char));
 
154
        for (int i = 0; i < len; ++i)
 
155
            cstring[i] = s.at(i).unicode();
 
156
        GooString *ret = new GooString(cstring, len);
 
157
        gfree(cstring);
 
158
        return ret;
 
159
    }
 
160
 
 
161
    void linkActionToTocItem( ::LinkAction * a, DocumentData * doc, QDomElement * e )
 
162
    {
 
163
        if ( !a || !e )
 
164
            return;
 
165
 
 
166
        switch ( a->getKind() )
 
167
        {
 
168
            case actionGoTo:
 
169
            {
 
170
                // page number is contained/referenced in a LinkGoTo
 
171
                LinkGoTo * g = static_cast< LinkGoTo * >( a );
 
172
                LinkDest * destination = g->getDest();
 
173
                if ( !destination && g->getNamedDest() )
 
174
                {
 
175
                    // no 'destination' but an internal 'named reference'. we could
 
176
                    // get the destination for the page now, but it's VERY time consuming,
 
177
                    // so better storing the reference and provide the viewport on demand
 
178
                    GooString *s = g->getNamedDest();
 
179
                    QChar *charArray = new QChar[s->getLength()];
 
180
                    for (int i = 0; i < s->getLength(); ++i) charArray[i] = QChar(s->getCString()[i]);
 
181
                    QString aux(charArray, s->getLength());
 
182
                    e->setAttribute( "DestinationName", aux );
 
183
                    delete[] charArray;
 
184
                }
 
185
                else if ( destination && destination->isOk() )
 
186
                {
 
187
                    LinkDestinationData ldd(destination, NULL, doc, false);
 
188
                    e->setAttribute( "Destination", LinkDestination(ldd).toString() );
 
189
                }
 
190
                break;
 
191
            }
 
192
            case actionGoToR:
 
193
            {
 
194
                // page number is contained/referenced in a LinkGoToR
 
195
                LinkGoToR * g = static_cast< LinkGoToR * >( a );
 
196
                LinkDest * destination = g->getDest();
 
197
                if ( !destination && g->getNamedDest() )
 
198
                {
 
199
                    // no 'destination' but an internal 'named reference'. we could
 
200
                    // get the destination for the page now, but it's VERY time consuming,
 
201
                    // so better storing the reference and provide the viewport on demand
 
202
                    GooString *s = g->getNamedDest();
 
203
                    QChar *charArray = new QChar[s->getLength()];
 
204
                    for (int i = 0; i < s->getLength(); ++i) charArray[i] = QChar(s->getCString()[i]);
 
205
                    QString aux(charArray, s->getLength());
 
206
                    e->setAttribute( "DestinationName", aux );
 
207
                    delete[] charArray;
 
208
                }
 
209
                else if ( destination && destination->isOk() )
 
210
                {
 
211
                    LinkDestinationData ldd(destination, NULL, doc, g->getFileName() != 0);
 
212
                    e->setAttribute( "Destination", LinkDestination(ldd).toString() );
 
213
                }
 
214
                e->setAttribute( "ExternalFileName", g->getFileName()->getCString() );
 
215
                break;
 
216
            }
 
217
            case actionURI:
 
218
            {
 
219
                LinkURI * u = static_cast< LinkURI * >( a );
 
220
                e->setAttribute( "DestinationURI", u->getURI()->getCString() );
 
221
            }
 
222
            default: ;
 
223
        }
 
224
    }
 
225
    
 
226
    DocumentData::~DocumentData()
 
227
    {
 
228
        qDeleteAll(m_embeddedFiles);
 
229
        delete (OptContentModel *)m_optContentModel;
 
230
        delete doc;
 
231
        delete m_outputDev;
 
232
        delete m_fontInfoIterator;
 
233
    
 
234
        count --;
 
235
        if ( count == 0 )
 
236
        {
 
237
            utf8Map = 0;
 
238
            delete globalParams;
 
239
        }
 
240
      }
 
241
    
 
242
    void DocumentData::init(GooString *ownerPassword, GooString *userPassword)
 
243
    {
 
244
        m_fontInfoIterator = 0;
 
245
        m_backend = Document::SplashBackend;
 
246
        m_outputDev = 0;
 
247
        paperColor = Qt::white;
 
248
        m_hints = 0;
 
249
        m_optContentModel = 0;
 
250
        // It might be more appropriate to delete these in PDFDoc
 
251
        delete ownerPassword;
 
252
        delete userPassword;
 
253
      
 
254
        if ( count == 0 )
 
255
        {
 
256
            utf8Map = 0;
 
257
            globalParams = new GlobalParams();
 
258
            setErrorFunction(qt4ErrorFunction);
 
259
        }
 
260
        count ++;
 
261
    }
 
262
 
 
263
 
 
264
    void DocumentData::addTocChildren( QDomDocument * docSyn, QDomNode * parent, GooList * items )
 
265
    {
 
266
        int numItems = items->getLength();
 
267
        for ( int i = 0; i < numItems; ++i )
 
268
        {
 
269
            // iterate over every object in 'items'
 
270
            OutlineItem * outlineItem = (OutlineItem *)items->get( i );
 
271
 
 
272
            // 1. create element using outlineItem's title as tagName
 
273
            QString name;
 
274
            Unicode * uniChar = outlineItem->getTitle();
 
275
            int titleLength = outlineItem->getTitleLength();
 
276
            name = unicodeToQString(uniChar, titleLength);
 
277
            if ( name.isEmpty() )
 
278
                continue;
 
279
 
 
280
            QDomElement item = docSyn->createElement( name );
 
281
            parent->appendChild( item );
 
282
 
 
283
            // 2. find the page the link refers to
 
284
            ::LinkAction * a = outlineItem->getAction();
 
285
            linkActionToTocItem( a, this, &item );
 
286
 
 
287
            item.setAttribute( "Open", QVariant( (bool)outlineItem->isOpen() ).toString() );
 
288
 
 
289
            // 3. recursively descend over children
 
290
            outlineItem->open();
 
291
            GooList * children = outlineItem->getKids();
 
292
            if ( children )
 
293
                addTocChildren( docSyn, &item, children );
 
294
        }
 
295
    }
 
296
 
 
297
}