~ubuntu-branches/ubuntu/precise/apvlv/precise-201112121632

« back to all changes in this revision

Viewing changes to .pc/00git_poppler_render_to_pixbuf.patch/src/ApvlvFile.cpp

  • Committer: Martin Pitt
  • Date: 2011-12-12 15:53:07 UTC
  • Revision ID: martin.pitt@canonical.com-20111212155307-szy7zc5ok727jfrc
Add 00git_poppler_render_to_pixbuf.patch: Add poppler_render_to_pixbuf
function for poppler no gdkpixbuf support. Patch taken from upstream git
head.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
* This file is part of the apvlv package
 
3
* Copyright (C) <2008>  <Alf>
 
4
*
 
5
* Contact: Alf <naihe2010@gmail.com>
 
6
*
 
7
* This program is free software; you can redistribute it and/or modify
 
8
* it under the terms of the GNU General Public License as published by
 
9
* the Free Software Foundation; either version 2 of the License, or
 
10
* (at your option) any later version.
 
11
*
 
12
* This program is distributed in the hope that it will be useful,
 
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
* GNU General Public License for more details.
 
16
*
 
17
* You should have received a copy of the GNU General Public License along
 
18
* with this program; if not, write to the Free Software Foundation, Inc.,
 
19
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 
20
*
 
21
*/
 
22
/* @CFILE ApvlvFile.cpp xxxxxxxxxxxxxxxxxxxxxxxxxx.
 
23
*
 
24
*  Author: Alf <naihe2010@gmail.com>
 
25
*/
 
26
/* @date Created: 2009/11/20 19:38:30 Alf*/
 
27
 
 
28
#include "ApvlvFile.hpp"
 
29
#include "ApvlvUtil.hpp"
 
30
#include "ApvlvView.hpp"
 
31
 
 
32
#ifdef HAVE_LIBUMD
 
33
#define LIBUMD_ENABLE_GTK
 
34
#include <umd.h>
 
35
#endif
 
36
#include <glib.h>
 
37
 
 
38
#include <sys/stat.h>
 
39
#include <iostream>
 
40
#include <fstream>
 
41
 
 
42
namespace apvlv
 
43
  {
 
44
#ifndef MAX
 
45
#define MAX(a,b)        ((a) > (b) ? (a) : (b))
 
46
#endif
 
47
 
 
48
  ApvlvFile::ApvlvFile (const char *filename, bool check)
 
49
  {
 
50
    mIndex = NULL;
 
51
 
 
52
    mRawdata = NULL;
 
53
    mRawdataSize = 0;
 
54
  }
 
55
 
 
56
  ApvlvFile::~ApvlvFile ()
 
57
  {
 
58
    if (mRawdata != NULL)
 
59
      {
 
60
        delete[]mRawdata;
 
61
        mRawdata = NULL;
 
62
      }
 
63
  }
 
64
 
 
65
  ApvlvFile *ApvlvFile::newfile (const char *filename, bool check)
 
66
  {
 
67
    ApvlvFile *file = NULL;
 
68
    static const char *type_phrase[] =
 
69
    {
 
70
      ".PDF",
 
71
      ".umd",
 
72
      ".djvu"
 
73
    };
 
74
 
 
75
    size_t i;
 
76
    for (i = 0; i < 3; ++ i)
 
77
      {
 
78
        if (strcasecmp (filename + strlen (filename) - strlen (type_phrase[i]),
 
79
                        type_phrase[i]) == 0)
 
80
          {
 
81
            break;
 
82
          }
 
83
      }
 
84
 
 
85
    if (i == 3)
 
86
      {
 
87
        debug ("not a valid file: %s, treate as a PDF file", filename);
 
88
        i = 0;
 
89
      }
 
90
 
 
91
    try
 
92
      {
 
93
        switch (i)
 
94
          {
 
95
          case 0:
 
96
            file = new ApvlvPDF (filename);
 
97
            break;
 
98
 
 
99
          case 1:
 
100
            file = new ApvlvUMD (filename);
 
101
            break;
 
102
 
 
103
          case 2:
 
104
            file = new ApvlvDJVU (filename);
 
105
            break;
 
106
 
 
107
          default:
 
108
            ;
 
109
          }
 
110
      }
 
111
 
 
112
    catch (bad_alloc e)
 
113
      {
 
114
        delete file;
 
115
        file = NULL;
 
116
      }
 
117
 
 
118
    return file;
 
119
  }
 
120
 
 
121
  ApvlvPDF::ApvlvPDF (const char *filename, bool check):ApvlvFile (filename,
 
122
          check)
 
123
  {
 
124
    gchar *wfilename;
 
125
 
 
126
    if (filename == NULL
 
127
        || *filename == '\0'
 
128
        || g_file_test (filename, G_FILE_TEST_IS_REGULAR) == FALSE
 
129
        || (wfilename =
 
130
              g_locale_from_utf8 (filename, -1, NULL, NULL, NULL)) == NULL)
 
131
      {
 
132
        gView->errormessage ("filename error: %s",
 
133
                             filename ? filename : "No name");
 
134
        throw std::bad_alloc ();
 
135
      }
 
136
 
 
137
    size_t filelen;
 
138
    struct stat sbuf;
 
139
    int rt = stat (wfilename, &sbuf);
 
140
    if (rt < 0)
 
141
      {
 
142
        gView->errormessage ("Can't stat the PDF file: %s.", filename);
 
143
        throw std::bad_alloc ();
 
144
      }
 
145
    filelen = sbuf.st_size;
 
146
 
 
147
    if (mRawdata != NULL && mRawdataSize < filelen)
 
148
      {
 
149
        delete[]mRawdata;
 
150
        mRawdata = NULL;
 
151
      }
 
152
 
 
153
    if (mRawdata == NULL)
 
154
      {
 
155
        mRawdata = new char[filelen];
 
156
        mRawdataSize = filelen;
 
157
      }
 
158
 
 
159
    ifstream ifs (wfilename, ios::binary);
 
160
    if (ifs.is_open ())
 
161
      {
 
162
        ifs.read (mRawdata, filelen);
 
163
        ifs.close ();
 
164
      }
 
165
 
 
166
    g_free (wfilename);
 
167
 
 
168
    GError *error = NULL;
 
169
    mDoc = poppler_document_new_from_data (mRawdata, filelen, NULL, &error);
 
170
 
 
171
    if (mDoc == NULL && error && error->code == POPPLER_ERROR_ENCRYPTED)
 
172
      {
 
173
        GtkWidget *dia = gtk_message_dialog_new (NULL,
 
174
                         GTK_DIALOG_DESTROY_WITH_PARENT,
 
175
                         GTK_MESSAGE_QUESTION,
 
176
                         GTK_BUTTONS_OK_CANCEL,
 
177
                         "%s", error->message);
 
178
        g_error_free (error);
 
179
 
 
180
 
 
181
        GtkWidget *entry = gtk_entry_new ();
 
182
        gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
 
183
        gtk_entry_set_invisible_char (GTK_ENTRY (entry), '*');
 
184
        gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dia)->vbox), entry, TRUE,
 
185
                            TRUE, 10);
 
186
        gtk_widget_show (entry);
 
187
 
 
188
        int ret = gtk_dialog_run (GTK_DIALOG (dia));
 
189
        if (ret == GTK_RESPONSE_OK)
 
190
          {
 
191
            gchar *ans = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry));
 
192
            if (ans != NULL)
 
193
              {
 
194
                mDoc =
 
195
                  poppler_document_new_from_data (mRawdata, filelen, ans,
 
196
                                                  NULL);
 
197
              }
 
198
          }
 
199
 
 
200
        gtk_widget_destroy (dia);
 
201
      }
 
202
 
 
203
    if (mDoc == NULL)
 
204
      {
 
205
        throw std::bad_alloc ();
 
206
      }
 
207
  }
 
208
 
 
209
  ApvlvPDF::~ApvlvPDF ()
 
210
  {
 
211
    if (mDoc)
 
212
      {
 
213
        g_object_unref (mDoc);
 
214
      }
 
215
  }
 
216
 
 
217
  bool ApvlvPDF::writefile (const char *filename)
 
218
  {
 
219
    debug ("write %p to %s", this, filename);
 
220
    gchar *path = absolutepath (filename);
 
221
    if (path == NULL)
 
222
      {
 
223
        debug ("filename error: %s", filename);
 
224
        return false;
 
225
      }
 
226
 
 
227
    GError *error = NULL;
 
228
    gchar *uri = g_filename_to_uri (path, NULL, &error);
 
229
    g_free (path);
 
230
    if (uri == NULL && error)
 
231
      {
 
232
        debug ("%d: %s", error->code, error->message);
 
233
        return false;
 
234
      }
 
235
 
 
236
    if (mDoc && uri != NULL)
 
237
      {
 
238
        gboolean ret = poppler_document_save (mDoc, uri, NULL);
 
239
        debug ("write pdf: %p to %s, return %d", mDoc, uri, ret);
 
240
        g_free (uri);
 
241
        return ret == TRUE ? true : false;
 
242
      }
 
243
    return false;
 
244
  }
 
245
 
 
246
  bool ApvlvPDF::pagesize (int pn, int rot, double *x, double *y)
 
247
  {
 
248
    PopplerPage *page = poppler_document_get_page (mDoc, pn);
 
249
    if (page != NULL)
 
250
      {
 
251
        if (rot == 90 || rot == 270)
 
252
          {
 
253
            poppler_page_get_size (page, y, x);
 
254
          }
 
255
        else
 
256
          {
 
257
            poppler_page_get_size (page, x, y);
 
258
          }
 
259
        return true;
 
260
      }
 
261
    return false;
 
262
  }
 
263
 
 
264
  int ApvlvPDF::pagesum ()
 
265
  {
 
266
    return mDoc ? poppler_document_get_n_pages (mDoc) : 0;
 
267
  }
 
268
 
 
269
  ApvlvPoses *ApvlvPDF::pagesearch (int pn, const char *str, bool reverse)
 
270
  {
 
271
    PopplerPage *page = poppler_document_get_page (mDoc, pn);
 
272
    if (page == NULL)
 
273
      {
 
274
        return NULL;
 
275
      }
 
276
 
 
277
//    debug ("search %s", str);
 
278
 
 
279
    GList *list = poppler_page_find_text (page, str);
 
280
    if (list == NULL)
 
281
      {
 
282
        return NULL;
 
283
      }
 
284
 
 
285
    if (reverse)
 
286
      {
 
287
        list = g_list_reverse (list);
 
288
      }
 
289
 
 
290
    ApvlvPoses *poses = new ApvlvPoses;
 
291
    for (GList * tmp = list; tmp != NULL; tmp = g_list_next (tmp))
 
292
      {
 
293
        PopplerRectangle *rect = (PopplerRectangle *) tmp->data;
 
294
//      debug ("results: %f-%f,%f-%f", rect->x1, rect->x2, rect->y1,
 
295
//             rect->y2);
 
296
        ApvlvPos pos = { rect->x1, rect->x2, rect->y1, rect->y2 };
 
297
        poses->push_back (pos);
 
298
      }
 
299
 
 
300
    return poses;
 
301
  }
 
302
 
 
303
  bool ApvlvPDF::pagetext (int pn, int x1, int y1, int x2, int y2, char **out)
 
304
  {
 
305
    PopplerPage *page = poppler_document_get_page (mDoc, pn);
 
306
#if POPPLER_CHECK_VERSION(0, 15, 1)
 
307
    PopplerRectangle rect = { x1, y2, x2, y1 };
 
308
    *out = poppler_page_get_selected_text (page, POPPLER_SELECTION_WORD, &rect);
 
309
#else
 
310
    PopplerRectangle rect = { x1, y1, x2, y2 };
 
311
    *out = poppler_page_get_text (page, POPPLER_SELECTION_WORD, &rect);
 
312
#endif
 
313
    if (*out != NULL)
 
314
      {
 
315
        return true;
 
316
      }
 
317
    return false;
 
318
  }
 
319
 
 
320
  bool ApvlvPDF::render (int pn, int ix, int iy, double zm, int rot,
 
321
                         GdkPixbuf * pix, char *buffer)
 
322
  {
 
323
    PopplerPage *tpage;
 
324
 
 
325
    if ((tpage = poppler_document_get_page (mDoc, pn)) == NULL)
 
326
      {
 
327
        debug ("no this page: %d", pn);
 
328
        return false;
 
329
      }
 
330
 
 
331
    poppler_page_render_to_pixbuf (tpage, 0, 0, ix, iy, zm, rot, pix);
 
332
    return true;
 
333
  }
 
334
 
 
335
  bool ApvlvPDF::pageselectsearch (int pn, int ix, int iy,
 
336
                                   double zm, int rot, GdkPixbuf * pix,
 
337
                                   char *buffer, int sel, ApvlvPoses * poses)
 
338
  {
 
339
    ApvlvPos rect = (*poses)[sel];
 
340
 
 
341
    // Caculate the correct position
 
342
    //debug ("pagex: %f, pagey: %f, x1: %f, y1: %f, x2: %f, y2: %f", pagex, pagey, rect->x1, rect->y1, rect->x2, rect->y2);
 
343
    gint x1 = MAX (rect.x1 * zm + 0.5, 0);
 
344
    gint x2 = MAX (rect.x2 * zm - 0.5, 1);
 
345
    gint y1 = MAX ((iy - rect.y2 * zm) + 0.5, 0);
 
346
    gint y2 = MAX ((iy - rect.y1 * zm) - 0.5, 1);
 
347
    //debug ("x1: %d, y1: %d, x2: %d, y2: %d", x1, y1, x2, y2);
 
348
 
 
349
    // heightlight the selection
 
350
    for (gint y = y1; y < y2; y++)
 
351
      {
 
352
        for (gint x = x1; x < x2; x++)
 
353
          {
 
354
            gint p = (gint) (y * ix * 3 + (x * 3));
 
355
            buffer[p + 0] = 0xff - buffer[p + 0];
 
356
            buffer[p + 1] = 0xff - buffer[p + 0];
 
357
            buffer[p + 2] = 0xff - buffer[p + 0];
 
358
          }
 
359
      }
 
360
 
 
361
    // change the back color of the selection
 
362
    for (ApvlvPoses::const_iterator itr = poses->begin ();
 
363
         itr != poses->end (); itr++)
 
364
      {
 
365
        // Caculate the correct position
 
366
        x1 = (gint) (itr->x1 * zm);
 
367
        x2 = (gint) (itr->x2 * zm);
 
368
        y1 = (gint) (iy - itr->y2 * zm);
 
369
        y2 = (gint) (iy - itr->y1 * zm);
 
370
 
 
371
        for (gint y = y1; y < y2; y++)
 
372
          {
 
373
            for (gint x = x1; x < x2; x++)
 
374
              {
 
375
                gint p = (gint) (y * 3 * ix + (x * 3));
 
376
                buffer[p + 0] = 0xff - buffer[p + 0];
 
377
                buffer[p + 1] = 0xff - buffer[p + 0];
 
378
                buffer[p + 2] = 0xff - buffer[p + 0];
 
379
              }
 
380
          }
 
381
      }
 
382
 
 
383
    return true;
 
384
  }
 
385
 
 
386
  ApvlvLinks *ApvlvPDF::getlinks (int pn)
 
387
  {
 
388
    PopplerPage *page = poppler_document_get_page (mDoc, pn);
 
389
    GList *list = poppler_page_get_link_mapping (page);
 
390
    if (list == NULL)
 
391
      {
 
392
        return NULL;
 
393
      }
 
394
 
 
395
    ApvlvLinks *links = new ApvlvLinks;
 
396
 
 
397
    for (GList * tmp = list; tmp != NULL; tmp = g_list_next (tmp))
 
398
      {
 
399
        PopplerLinkMapping *map = (PopplerLinkMapping *) tmp->data;
 
400
        if (map)
 
401
          {
 
402
            PopplerAction *act = map->action;
 
403
            if (act && *(PopplerActionType *) act == POPPLER_ACTION_GOTO_DEST)
 
404
              {
 
405
                PopplerDest *pd = ((PopplerActionGotoDest *) act)->dest;
 
406
                if (pd->type == POPPLER_DEST_NAMED)
 
407
                  {
 
408
                    PopplerDest *destnew = poppler_document_find_dest (mDoc,
 
409
                                           pd->named_dest);
 
410
                    if (destnew != NULL)
 
411
                      {
 
412
                        ApvlvLink link = { "", destnew->page_num - 1 };
 
413
                        links->insert (links->begin (), link);
 
414
                        poppler_dest_free (destnew);
 
415
                      }
 
416
                  }
 
417
                else
 
418
                  {
 
419
                    ApvlvLink link = { "", pd->page_num - 1 };
 
420
                    links->insert (links->begin (), link);
 
421
                  }
 
422
              }
 
423
          }
 
424
      }
 
425
 
 
426
    return links;
 
427
  }
 
428
 
 
429
  ApvlvFileIndex *ApvlvPDF::new_index ()
 
430
  {
 
431
    if (mIndex != NULL)
 
432
      {
 
433
        debug ("file %p has index: %p, return", this, mIndex);
 
434
        return mIndex;
 
435
      }
 
436
 
 
437
    PopplerIndexIter *itr = poppler_index_iter_new (mDoc);
 
438
    if (itr == NULL)
 
439
      {
 
440
        debug ("no index.");
 
441
        return NULL;
 
442
      }
 
443
 
 
444
    mIndex = new ApvlvFileIndex;
 
445
    walk_poppler_index_iter (mIndex, itr);
 
446
    poppler_index_iter_free (itr);
 
447
 
 
448
    return mIndex;
 
449
  }
 
450
 
 
451
  void ApvlvPDF::free_index (ApvlvFileIndex * index)
 
452
  {
 
453
    delete index;
 
454
  }
 
455
 
 
456
  bool ApvlvPDF::walk_poppler_index_iter (ApvlvFileIndex * titr,
 
457
                                          PopplerIndexIter * iter)
 
458
  {
 
459
    bool has = false;
 
460
    do
 
461
      {
 
462
        has = false;
 
463
        ApvlvFileIndex *index = NULL;
 
464
 
 
465
        PopplerAction *act = poppler_index_iter_get_action (iter);
 
466
        if (act)
 
467
          {
 
468
            if (*(PopplerActionType *) act == POPPLER_ACTION_GOTO_DEST)
 
469
              {
 
470
                PopplerActionGotoDest *pagd = (PopplerActionGotoDest *) act;
 
471
                if (pagd->dest->type == POPPLER_DEST_NAMED)
 
472
                  {
 
473
                    PopplerDest *destnew = poppler_document_find_dest (mDoc,
 
474
                                           pagd->
 
475
                                           dest->
 
476
                                           named_dest);
 
477
                    int pn = 1;
 
478
                    if (destnew != NULL)
 
479
                      {
 
480
                        pn = destnew->page_num - 1;
 
481
                        poppler_dest_free (destnew);
 
482
                      }
 
483
                    index = new ApvlvFileIndex;
 
484
                    index->page = pn;
 
485
                  }
 
486
                else
 
487
                  {
 
488
                    index = new ApvlvFileIndex;
 
489
                    index->page = pagd->dest->page_num - 1;
 
490
                  }
 
491
 
 
492
                if (index != NULL)
 
493
                  {
 
494
                    has = true;
 
495
                    index->title = pagd->title;
 
496
                    titr->children.push_back (*index);
 
497
                    delete index;
 
498
                    index = &(titr->children[titr->children.size () - 1]);
 
499
                    debug ("titr: %p, index: %p", titr, index);
 
500
                  }
 
501
              }
 
502
            poppler_action_free (act);
 
503
          }
 
504
 
 
505
        PopplerIndexIter *child = poppler_index_iter_get_child (iter);
 
506
        if (child)
 
507
          {
 
508
            bool chas = walk_poppler_index_iter (has ? index : titr, child);
 
509
            has = has ? has : chas;
 
510
            poppler_index_iter_free (child);
 
511
          }
 
512
      }
 
513
    while (poppler_index_iter_next (iter));
 
514
    return has;
 
515
  }
 
516
 
 
517
  bool ApvlvPDF::pageprint (int pn, cairo_t * cr)
 
518
  {
 
519
#ifdef WIN32
 
520
    return false;
 
521
#else
 
522
    PopplerPage *page = poppler_document_get_page (mDoc, pn);
 
523
    if (page != NULL)
 
524
      {
 
525
        poppler_page_render_for_printing (page, cr);
 
526
        return true;
 
527
      }
 
528
    else
 
529
      {
 
530
        return false;
 
531
      }
 
532
#endif
 
533
  }
 
534
 
 
535
#ifdef HAVE_LIBDJVU
 
536
  void handle_ddjvu_messages (ddjvu_context_t * ctx, int wait)
 
537
  {
 
538
    const ddjvu_message_t *msg;
 
539
    if (wait)
 
540
      ddjvu_message_wait (ctx);
 
541
    while ((msg = ddjvu_message_peek (ctx)))
 
542
      {
 
543
        debug ("tag: %d", msg->m_any.tag);
 
544
        switch (msg->m_any.tag)
 
545
          {
 
546
          case DDJVU_ERROR:
 
547
            break;
 
548
          case DDJVU_INFO:
 
549
            break;
 
550
          case DDJVU_PAGEINFO:
 
551
            break;
 
552
          default:
 
553
            break;
 
554
          }
 
555
        ddjvu_message_pop (ctx);
 
556
      }
 
557
  }
 
558
#endif
 
559
 
 
560
  ApvlvDJVU::ApvlvDJVU (const char *filename, bool check):ApvlvFile (filename,
 
561
          check)
 
562
  {
 
563
#ifdef HAVE_LIBDJVU
 
564
    mContext = ddjvu_context_create ("apvlv");
 
565
    if (mContext)
 
566
      {
 
567
        mDoc = ddjvu_document_create_by_filename (mContext, filename, FALSE);
 
568
      }
 
569
 
 
570
    if (mDoc != NULL)
 
571
      {
 
572
        if (ddjvu_document_get_type (mDoc) == DDJVU_DOCTYPE_SINGLEPAGE)
 
573
          {
 
574
            debug ("djvu type: %d", ddjvu_document_get_type (mDoc));
 
575
          }
 
576
        else
 
577
          {
 
578
            /*
 
579
               ddjvu_document_release (mDoc);
 
580
               mDoc = NULL;
 
581
               ddjvu_context_release (mContext);
 
582
               mContext = NULL;
 
583
               throw std::bad_alloc (); */
 
584
          }
 
585
      }
 
586
    else
 
587
      {
 
588
        ddjvu_context_release (mContext);
 
589
        mContext = NULL;
 
590
        throw std::bad_alloc ();
 
591
      }
 
592
#else
 
593
    throw std::bad_alloc ();
 
594
#endif
 
595
  }
 
596
 
 
597
  ApvlvDJVU::~ApvlvDJVU ()
 
598
  {
 
599
#ifdef HAVE_LIBDJVU
 
600
    if (mContext)
 
601
      {
 
602
        ddjvu_context_release (mContext);
 
603
      }
 
604
 
 
605
    if (mDoc)
 
606
      {
 
607
        ddjvu_document_release (mDoc);
 
608
      }
 
609
#endif
 
610
  }
 
611
 
 
612
  bool ApvlvDJVU::writefile (const char *filename)
 
613
  {
 
614
#ifdef HAVE_LIBDJVU
 
615
    FILE *fp = fopen (filename, "wb");
 
616
    if (fp != NULL)
 
617
      {
 
618
        ddjvu_job_t *job = ddjvu_document_save (mDoc, fp, 0, NULL);
 
619
        while (!ddjvu_job_done (job))
 
620
          {
 
621
            handle_ddjvu_messages (mContext, TRUE);
 
622
          }
 
623
        fclose (fp);
 
624
        return true;
 
625
      }
 
626
    return false;
 
627
#else
 
628
    return false;
 
629
#endif
 
630
  }
 
631
 
 
632
  bool ApvlvDJVU::pagesize (int pn, int rot, double *x, double *y)
 
633
  {
 
634
#ifdef HAVE_LIBDJVU
 
635
    ddjvu_status_t t;
 
636
    ddjvu_pageinfo_t info[1];
 
637
    while ((t = ddjvu_document_get_pageinfo (mDoc, 0, info)) < DDJVU_JOB_OK)
 
638
      {
 
639
        handle_ddjvu_messages (mContext, true);
 
640
      }
 
641
 
 
642
    if (t == DDJVU_JOB_OK)
 
643
      {
 
644
        *x = info->width;
 
645
        *y = info->height;
 
646
        debug ("djvu page 1: %f-%f", *x, *y);
 
647
      }
 
648
    return true;
 
649
#else
 
650
    return false;
 
651
#endif
 
652
  }
 
653
 
 
654
  int ApvlvDJVU::pagesum ()
 
655
  {
 
656
#ifdef HAVE_LIBDJVU
 
657
    return mDoc ? ddjvu_document_get_pagenum (mDoc) : 0;
 
658
#else
 
659
    return 0;
 
660
#endif
 
661
  }
 
662
 
 
663
  bool ApvlvDJVU::render (int pn, int ix, int iy, double zm, int rot,
 
664
                          GdkPixbuf * pix, char *buffer)
 
665
  {
 
666
#ifdef HAVE_LIBDJVU
 
667
    ddjvu_page_t *tpage;
 
668
 
 
669
    if ((tpage = ddjvu_page_create_by_pageno (mDoc, pn)) == NULL)
 
670
      {
 
671
        debug ("no this page: %d", pn);
 
672
        return false;
 
673
      }
 
674
 
 
675
    ddjvu_rect_t prect[1] = { {0, 0, ix, iy}
 
676
    };
 
677
    ddjvu_rect_t rrect[1] = { {0, 0, ix, iy}
 
678
    };
 
679
    ddjvu_format_t *format =
 
680
      ddjvu_format_create (DDJVU_FORMAT_RGB24, 0, NULL);
 
681
    ddjvu_format_set_row_order (format, TRUE);
 
682
 
 
683
    gint retry = 0;
 
684
    while (retry <= 20 && ddjvu_page_render
 
685
           (tpage, DDJVU_RENDER_COLOR, prect, rrect, format, 3 * ix,
 
686
            (char *) buffer) == FALSE)
 
687
      {
 
688
        usleep (50 * 1000);
 
689
        debug ("fender failed, retry %d", ++retry);
 
690
      }
 
691
 
 
692
    return true;
 
693
#else
 
694
    return false;
 
695
#endif
 
696
  }
 
697
 
 
698
  bool ApvlvDJVU::pageselectsearch (int pn, int ix, int iy, double zm,
 
699
                                    int rot, GdkPixbuf * pix, char *buffer,
 
700
                                    int sel, ApvlvPoses * poses)
 
701
  {
 
702
    return false;
 
703
  }
 
704
 
 
705
  ApvlvPoses *ApvlvDJVU::pagesearch (int pn, const char *str, bool reverse)
 
706
  {
 
707
    return NULL;
 
708
  }
 
709
 
 
710
  ApvlvLinks *ApvlvDJVU::getlinks (int pn)
 
711
  {
 
712
    return NULL;
 
713
  }
 
714
 
 
715
  bool ApvlvDJVU::pagetext (int pn, int x1, int y1, int x2, int y2,
 
716
                            char **out)
 
717
  {
 
718
    return false;
 
719
  }
 
720
 
 
721
  ApvlvFileIndex *ApvlvDJVU::new_index ()
 
722
  {
 
723
    return NULL;
 
724
  }
 
725
 
 
726
  void ApvlvDJVU::free_index (ApvlvFileIndex * index)
 
727
  {
 
728
  }
 
729
 
 
730
  bool ApvlvDJVU::pageprint (int pn, cairo_t * cr)
 
731
  {
 
732
    return false;
 
733
  }
 
734
 
 
735
  ApvlvUMD::ApvlvUMD (const char *filename, bool check):ApvlvFile (filename,
 
736
          check)
 
737
  {
 
738
#ifdef HAVE_LIBUMD
 
739
    gchar * lname = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL);
 
740
    if (lname)
 
741
      {
 
742
        mUmd = umd_new_from_file (lname);
 
743
        g_free (lname);
 
744
      }
 
745
    else
 
746
      {
 
747
        mUmd = umd_new_from_file (filename);
 
748
      }
 
749
 
 
750
    if (mUmd == NULL)
 
751
      {
 
752
        throw std::bad_alloc ();
 
753
      }
 
754
#else
 
755
    throw std::bad_alloc ();
 
756
#endif
 
757
  }
 
758
 
 
759
  ApvlvUMD::~ApvlvUMD ()
 
760
  {
 
761
#ifdef HAVE_LIBUMD
 
762
    if (mUmd)
 
763
      {
 
764
        umd_destroy (mUmd);
 
765
      }
 
766
#endif
 
767
  }
 
768
 
 
769
  bool ApvlvUMD::writefile (const char *filename)
 
770
  {
 
771
#ifdef HAVE_LIBUMD
 
772
    if (umd_write_file (mUmd, filename) == 0)
 
773
      {
 
774
        return true;
 
775
      }
 
776
    return false;
 
777
#else
 
778
    return false;
 
779
#endif
 
780
  }
 
781
 
 
782
  bool ApvlvUMD::pagesize (int pn, int rot, double *x, double *y)
 
783
  {
 
784
#ifdef HAVE_LIBUMD
 
785
    umd_page_t * page;
 
786
 
 
787
    page = umd_get_nth_page (mUmd, pn);
 
788
    if (page)
 
789
      {
 
790
        int ix, iy;
 
791
        umd_page_get_size (page, &ix, &iy);
 
792
        *x = ix;
 
793
        *y = iy;
 
794
        return true;
 
795
      }
 
796
    return false;
 
797
#else
 
798
    return false;
 
799
#endif
 
800
  }
 
801
 
 
802
  int ApvlvUMD::pagesum ()
 
803
  {
 
804
#ifdef HAVE_LIBUMD
 
805
    return mUmd ? umd_get_page_n (mUmd) : 0;
 
806
#else
 
807
    return 0;
 
808
#endif
 
809
  }
 
810
 
 
811
  bool ApvlvUMD::render (int pn, int ix, int iy, double zm, int rot,
 
812
                         GdkPixbuf * pix, char *buffer)
 
813
  {
 
814
#ifdef HAVE_LIBUMD
 
815
    umd_page_t * page;
 
816
 
 
817
    page = umd_get_nth_page (mUmd, pn);
 
818
    if (page)
 
819
      {
 
820
        umd_page_render (page, 0, 0, ix, iy, zm, rot, (unsigned char *) buffer, 3 * ix);
 
821
        return true;
 
822
      }
 
823
    return false;
 
824
#else
 
825
    return false;
 
826
#endif
 
827
  }
 
828
 
 
829
  bool ApvlvUMD::pageselectsearch (int pn, int ix, int iy, double zm,
 
830
                                   int rot, GdkPixbuf * pix, char *buffer,
 
831
                                   int sel, ApvlvPoses * poses)
 
832
  {
 
833
    return false;
 
834
  }
 
835
 
 
836
  ApvlvPoses *ApvlvUMD::pagesearch (int pn, const char *str, bool reverse)
 
837
  {
 
838
    return NULL;
 
839
  }
 
840
 
 
841
  ApvlvLinks *ApvlvUMD::getlinks (int pn)
 
842
  {
 
843
    return NULL;
 
844
  }
 
845
 
 
846
  bool ApvlvUMD::pagetext (int pn, int x1, int y1, int x2, int y2,
 
847
                           char **out)
 
848
  {
 
849
    return false;
 
850
  }
 
851
 
 
852
  ApvlvFileIndex *ApvlvUMD::new_index ()
 
853
  {
 
854
#ifdef HAVE_LIBUMD
 
855
    if (mIndex != NULL)
 
856
      {
 
857
        debug ("file %p has index: %p, return", this, mIndex);
 
858
        return mIndex;
 
859
      }
 
860
 
 
861
    int cpt_n = umd_get_chapter_n (mUmd);
 
862
    if (cpt_n <= 0)
 
863
      {
 
864
        debug ("no index.");
 
865
        return NULL;
 
866
      }
 
867
 
 
868
    mIndex = new ApvlvFileIndex;
 
869
    for (int i = 0;
 
870
         i < cpt_n;
 
871
         ++ i)
 
872
      {
 
873
        umd_chapter_t * chapter = umd_get_nth_chapter (mUmd, i);
 
874
        if (chapter)
 
875
          {
 
876
            ApvlvFileIndex inx;
 
877
 
 
878
            inx.title = chapter->title;
 
879
            inx.page = chapter->page_index;
 
880
 
 
881
            mIndex->children.push_back (inx);
 
882
 
 
883
            free (chapter->title);
 
884
            free (chapter->content);
 
885
            free (chapter);
 
886
          }
 
887
      }
 
888
 
 
889
    return mIndex;
 
890
#else
 
891
    return NULL;
 
892
#endif
 
893
  }
 
894
 
 
895
  void ApvlvUMD::free_index (ApvlvFileIndex * index)
 
896
  {
 
897
#ifdef HAVE_LIBUMD
 
898
    delete mIndex;
 
899
#endif
 
900
  }
 
901
 
 
902
  bool ApvlvUMD::pageprint (int pn, cairo_t * cr)
 
903
  {
 
904
    return false;
 
905
  }
 
906
 
 
907
}