Changeset 461


Ignore:
Timestamp:
Aug 27, 2010, 11:00:52 AM (10 years ago)
Author:
Silvan Scherrer
Message:

poppler update to 0.14.2

Location:
trunk
Files:
25 added
2 deleted
77 edited

Legend:

Unmodified
Added
Removed
  • trunk/Lucide/changelog

    r443 r461  
     11.3.3:
     2  - added backwards search (ticket #190)
     3  - fixed goto page handling (ticket #198)
     4  - some other small fixes
     5  - WPI: made http links clickable
     6
     7
    181.3.2:
    29  - WPI: Fixed mismatch between the package names and actual plugins they contain.
  • trunk/Lucide/plugins/lupoppler/lupoppler.cpp

    r450 r461  
    104104extern "C" char * EXPENTRY getDescription()
    105105{
    106     return "PDF plugin, based on poppler library v0.12.4";
     106    return "PDF plugin, based on poppler library v0.14.2";
    107107}
    108108
  • trunk/README.DEV

    r438 r461  
    126126    which is useful when something does not work like you want.
    127127
     128
     129USEFUL LINKS
     130
     131  * poppler library is found on poppler.freedesktop.org
     132  * djvu library is found djvu.sourceforge.net
     133  * jpeg library www.ijg.com
  • trunk/poppler/mypoppler/_lucide.readme

    r290 r461  
    1 All changes of the org sources are marked with
    2 /* Lucide */
     1lucide is based on oppler 0.14.2
  • trunk/poppler/mypoppler/fofi/FoFiType1.cc

    r257 r461  
    1616// Copyright (C) 2005, 2008 Albert Astals Cid <aacid@kde.org>
    1717// Copyright (C) 2005 Kristian HÞgsberg <krh@redhat.com>
     18// Copyright (C) 2010 Jakub Wilk <ubanus@users.sf.net>
    1819//
    1920// To see a description of the changes please see the Changelog file that
     
    193194  char c;
    194195  int n, code, i, j;
     196  char *tokptr;
    195197
    196198  for (i = 1, line = (char *)file;
     
    203205      buf[255] = '\0';
    204206      if ((p = strchr(buf+9, '/')) &&
    205           (p = strtok(p+1, " \t\n\r"))) {
     207          (p = strtok_r(p+1, " \t\n\r", &tokptr))) {
    206208        name = copyString(p);
    207209      }
     
    271273          }
    272274        } else {
    273           if (strtok(buf, " \t") &&
    274               (p = strtok(NULL, " \t\n\r")) && !strcmp(p, "def")) {
     275          if (strtok_r(buf, " \t", &tokptr) &&
     276              (p = strtok_r(NULL, " \t\n\r", &tokptr)) && !strcmp(p, "def")) {
    275277            break;
    276278          }
  • trunk/poppler/mypoppler/fofi/FoFiType1C.cc

    r277 r461  
    1414// under GPL version 2 or later
    1515//
    16 // Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
     16// Copyright (C) 2009, 2010 Albert Astals Cid <aacid@kde.org>
    1717//
    1818// To see a description of the changes please see the Changelog file that
     
    805805    //~ font up by FD; as a kludge we ignore CID 0, which is .notdef
    806806    fd = 0;
    807     for (j = i==0 ? 1 : 0; j < 256 && i+j < nCIDs; ++j) {
    808       if (cidMap[i+j] >= 0) {
    809         fd = fdSelect[cidMap[i+j]];
    810         break;
     807    if (fdSelect != NULL) {
     808      for (j = i==0 ? 1 : 0; j < 256 && i+j < nCIDs; ++j) {
     809        if (cidMap[i+j] >= 0) {
     810          fd = fdSelect[cidMap[i+j]];
     811          break;
     812        }
    811813      }
    812814    }
  • trunk/poppler/mypoppler/goo/GooMutex.h

    r290 r461  
    4848#define gUnlockMutex(m) LeaveCriticalSection(m)
    4949
    50 /* Lucide */
    5150#elif defined(OS2)
    5251
  • trunk/poppler/mypoppler/goo/GooString.cc

    r277 r461  
    1919// Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
    2020// Copyright (C) 2007 Jeff Muizelaar <jeff@infidigm.net>
    21 // Copyright (C) 2008, 2009 Albert Astals Cid <aacid@kde.org>
     21// Copyright (C) 2008-2010 Albert Astals Cid <aacid@kde.org>
    2222//
    2323// To see a description of the changes please see the Changelog file that
     
    198198}
    199199
    200 GooString::GooString(GooString *str) {
     200GooString::GooString(const GooString *str) {
    201201  s = NULL;
    202202  length = 0;
     
    685685}
    686686
    687 int GooString::cmp(GooString *str) {
     687int GooString::cmp(GooString *str) const {
    688688  int n1, n2, i, x;
    689689  char *p1, *p2;
     
    700700}
    701701
    702 int GooString::cmpN(GooString *str, int n) {
     702int GooString::cmpN(GooString *str, int n) const {
    703703  int n1, n2, i, x;
    704704  char *p1, *p2;
     
    720720}
    721721
    722 int GooString::cmp(const char *sA) {
     722int GooString::cmp(const char *sA) const {
    723723  int n1, i, x;
    724724  const char *p1, *p2;
     
    740740}
    741741
    742 int GooString::cmpN(const char *sA, int n) {
     742int GooString::cmpN(const char *sA, int n) const {
    743743  int n1, i, x;
    744744  const char *p1, *p2;
  • trunk/poppler/mypoppler/goo/GooString.h

    r277 r461  
    1818// Copyright (C) 2006 Kristian HÞgsberg <krh@redhat.com>
    1919// Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
    20 // Copyright (C) 2008, 2009 Albert Astals Cid <aacid@kde.org>
     20// Copyright (C) 2008-2010 Albert Astals Cid <aacid@kde.org>
    2121//
    2222// To see a description of the changes please see the Changelog file that
     
    4343
    4444  // Create a string from a C string.
    45   GooString(const char *sA);
     45  explicit GooString(const char *sA);
    4646
    4747  // Create a string from <lengthA> chars at <sA>.  This string
     
    5959
    6060  // Copy a string.
    61   GooString(GooString *str);
    62   GooString *copy() { return new GooString(this); }
     61  explicit GooString(const GooString *str);
     62  GooString *copy() const { return new GooString(this); }
    6363
    6464  // Concatenate two strings.
     
    9999
    100100  // Get C string.
    101   char *getCString() { return s; }
     101  char *getCString() const { return s; }
    102102
    103103  // Get <i>th character.
     
    132132
    133133  // Compare two strings:  -1:<  0:=  +1:>
    134   int cmp(GooString *str);
    135   int cmpN(GooString *str, int n);
    136   int cmp(const char *sA);
    137   int cmpN(const char *sA, int n);
     134  int cmp(GooString *str) const;
     135  int cmpN(GooString *str, int n) const;
     136  int cmp(const char *sA) const;
     137  int cmpN(const char *sA, int n) const;
    138138
    139139  GBool hasUnicodeMarker(void);
     
    146146
    147147private:
     148  GooString(const GooString &other);
     149  GooString& operator=(const GooString &other);
     150
    148151  // you can tweak this number for a different speed/memory usage tradeoffs.
    149152  // In libc malloc() rounding is 16 so it's best to choose a value that
  • trunk/poppler/mypoppler/goo/GooTimer.cc

    r257 r461  
    77// Copyright 2005 Jonathan Blandford <jrb@redhat.com>
    88// Copyright 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
     9// Copyright 2010 Hib Eris <hib@hiberis.nl>
    910// Inspired by gtimer.c in glib, which is Copyright 2000 by the GLib Team
    1011//
     
    3334#ifdef HAVE_GETTIMEOFDAY
    3435  gettimeofday(&start_time, NULL);
    35 #elif defined(_MSC_VER)
     36#elif defined(_WIN32)
    3637  QueryPerformanceCounter(&start_time);
    3738#endif
     
    4243#ifdef HAVE_GETTIMEOFDAY
    4344  gettimeofday(&end_time, NULL);
    44 #elif defined(_MSC_VER)
     45#elif defined(_WIN32)
    4546  QueryPerformanceCounter(&end_time);
    4647#endif
     
    7172  return total;
    7273}
    73 #elif defined(_MSC_VER)
     74#elif defined(_WIN32)
    7475double GooTimer::getElapsed()
    7576{
  • trunk/poppler/mypoppler/goo/GooTimer.h

    r257 r461  
    77// Copyright 2005 Jonathan Blandford <jrb@redhat.com>
    88// Copyright 2007 Krzysztof Kowalczyk <kkowalczyk@gmail.com>
     9// Copyright 2010 Hib Eris <hib@hiberis.nl>
    910// Inspired by gtimer.c in glib, which is Copyright 2000 by the GLib Team
    1011//
     
    2324#endif
    2425
    25 #ifdef _MSC_VER
     26#ifdef _WIN32
    2627#include <windows.h>
    2728#endif
     
    4546  struct timeval start_time;
    4647  struct timeval end_time;
    47 #elif defined(_MSC_VER)
     48#elif defined(_WIN32)
    4849  LARGE_INTEGER start_time;
    4950  LARGE_INTEGER end_time;
  • trunk/poppler/mypoppler/goo/GooVector.h

    r257 r461  
    11//========================================================================
    22//
    3 // This file comes from pdftohtml project
    4 // http://pdftohtml.sourceforge.net
     3// GooVector.h
    54//
    6 // Copyright from:
    7 // Gueorgui Ovtcharov
    8 // Rainer Dorsch <http://www.ra.informatik.uni-stuttgart.de/~rainer/>
    9 // Mikhail Kruk <meshko@cs.brandeis.edu>
     5// This file is licensed under the GPLv2 or later
     6//
     7// Copyright 2010 David Benjamin <davidben@mit.edu>
     8// Copyright 2010 Albert Astals Cid <aacid@kde.org>
    109//
    1110//========================================================================
    1211
    13 #ifndef GOO_VECTOR_H
    14 #define GOO_VECTOR_H
    15 #include "goo/gtypes.h"
    1612
    1713
    18 template<class T>
    19 class GooVector{
    20 private:
    21    
    22    int _size;
    23    T*  last;
    24    T*  storage;
    25  
    26    void resize(){
    27      if (_size==0) _size=2;else _size=2*_size;
    28       T *tmp=new T[_size];
    29      if (storage){
    30        last=copy(storage,last,tmp);
    31        delete [] storage;
    32       }
    33      else last=tmp;
    34      storage=tmp;
    35     }
     14#ifndef GOO_GOOVECTOR_H
     15#define GOO_GOOVECTOR_H
    3616
    37    T* copy(T* src1,T* src2,T* dest){
    38      T* tmp=src1;
    39      T* d=dest;
    40       while(tmp!=src2){
    41         *d=*tmp;
    42          d++;tmp++;
    43        }
    44       return d;
    45    }
    46 
    47 public:
    48  typedef T* iterator;
    49 
    50  GooVector(){
    51   _size=0;
    52   last=0;
    53   storage=0;
    54 }
    55 
    56 
    57 
    58 virtual ~GooVector(){
    59   delete[] storage ;
    60 
    61 
    62 void reset(){
    63   last=storage;
    64 }
    65 
    66 int size(){
    67   return (last-storage);
    68 }   
    69 void push_back(const T& elem){
    70   if (!storage||(size() >=_size)) resize();
    71         *last=elem;
    72          last++;
    73  
    74      
    75 }
    76 
    77 
    78 T pop_back() {
    79     if (last!=storage) last--;
    80 
    81     return *last;
    82 }
    83 
    84 
    85 T operator[](unsigned int i){
    86  return *(storage+i);
    87 }
    88  
    89 
    90 GBool isEmpty() const{
    91  return !_size || (last==storage) ;
    92 }
    93 
    94 
    95 
    96 iterator begin() const{
    97  return storage;
    98 }
    99 
    100 iterator end() const {
    101   return last;
    102 }
    103 };
     17#ifdef USE_GCC_PRAGMAS
     18#pragma interface
    10419#endif
    10520
     21#include <new> // vector implementations need placement-new
    10622
     23#include <assert.h>
     24#include <stdlib.h>
    10725
    108    
     26/* Mostly STL-compatible vector class. Should correctly call constructors and
     27 * destructors, but does not carefully handle alignment requirements. */
     28
     29template<class T> class GooVector {
     30public:
     31  /* various STL-compatible typedefs */
     32  typedef T value_type;
     33  typedef T* pointer;
     34  typedef T& reference;
     35  typedef const T& const_reference;
     36  typedef size_t size_type;
     37  typedef int difference_type;
     38  typedef T* iterator;
     39  typedef const T* const_iterator;
     40  // TODO: reverse_iterator, if we feel like it
    10941 
    110  
     42  GooVector() : m_data(NULL), m_capacity(0), m_size(0) {}
     43  explicit GooVector(size_type n) : m_data(NULL), m_capacity(0), m_size(0) {
     44    resize(n);
     45  }
     46  explicit GooVector(size_type n, const T& t) : m_data(NULL), m_capacity(0), m_size(0) {
     47    resize(n, t);
     48  }
     49  explicit GooVector(const GooVector& gv) : m_data(NULL), m_capacity(0), m_size(0) {
     50    reserve(gv.size());
     51    for (size_type i = 0; i < m_size; i++) {
     52      push_back(gv[i]);
     53    }
     54  }
    11155
     56  ~GooVector() {
     57    clear();
     58  }
    11259
     60  iterator begin() { return m_data; }
     61  const_iterator begin() const { return m_data; }
     62  iterator end() { return m_data + m_size; }
     63  const_iterator end() const { return m_data + m_size; }
    11364
     65  size_type size() const { return m_size; }
     66  size_type capacity() const { return m_capacity; }
     67
     68  bool empty() const { return m_size == 0; }
     69
     70  reference operator[] (size_type n) { return m_data[n]; }
     71  const_reference operator[] (size_type n) const { return m_data[n]; }
     72
     73  reference at(size_type n) {
     74    assert(n < m_size);
     75    return m_data[n];
     76  }
     77  const_reference at(size_type n) const {
     78    assert(n < m_size);
     79    return m_data[n];
     80  }
     81
     82  reference front() { assert(!empty()); return m_data[0]; }
     83  const_reference front() const { assert(!empty()); return m_data[0]; }
     84
     85  reference back() { assert(!empty()); return m_data[m_size-1]; }
     86  const_reference back() const { assert(!empty()); return m_data[m_size-1]; }
     87
     88  void push_back(const T& v) {
     89    reserve(m_size + 1);
     90    place_new(m_data + m_size, v);
     91    m_size++;
     92  }
     93  void pop_back() {
     94    assert(!empty());
     95    m_size--;
     96    destruct(m_data + m_size);
     97  }
     98
     99  void clear() {
     100    for (size_t i = 0; i < m_size; i++) {
     101      destruct(m_data + i);
     102    }
     103    m_size = 0;
     104    free(m_data);
     105    m_data = NULL;
     106    m_capacity = 0;
     107  }
     108
     109  void reserve(size_type cap) {
     110    if (m_capacity >= cap) return;
     111    // make sure we always at least double
     112    if (m_capacity*2 > cap)
     113      cap = m_capacity*2;
     114    resize_internal(cap);
     115  }
     116
     117  void resize(size_type n) { resize(n, T()); }
     118  void resize(size_type n, const T& t) {
     119    reserve(n);
     120    while (m_size < n)
     121      push_back(t);
     122    while (m_size > n)
     123      pop_back();
     124  }
     125
     126private:
     127  T *m_data;
     128  size_type m_capacity;
     129  size_type m_size;
     130
     131  inline void destruct(T *obj) {
     132    obj->~T();
     133  }
     134  inline void place_new(T *loc, const T& v) {
     135    new (loc) T(v);
     136  }
     137
     138  inline void resize_internal(size_type new_cap) {
     139    assert(new_cap >= m_capacity);
     140    // To be correct with ctors and dtors, we do not use realloc and friends.
     141    // A more efficient implementation would specialize for POD types and just
     142    // realloc() or something. Meh, if we care, we ought to use just STL's
     143    T *new_data = (T*) malloc(sizeof(T) * new_cap);
     144    assert(new_data);
     145    // Move over old data
     146    if (m_data) {
     147      for (size_type i = 0; i < m_size; i++) {
     148        place_new(new_data + i, m_data[i]);
     149        destruct(m_data + i);
     150      }
     151      free(m_data);
     152    }
     153    // And set the new values
     154    m_data = new_data;
     155    m_capacity = new_cap;
     156  }
     157};
     158
     159#endif
  • trunk/poppler/mypoppler/goo/PNGWriter.cc

    r277 r461  
    88// Copyright (C) 2009 Shen Liang <shenzhuxi@gmail.com>
    99// Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
     10// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
     11// Copyright (C) 2010 Adrian Johnson <ajohnson@redneon.com>
    1012//
    1113//========================================================================
     
    2729}
    2830
    29 bool PNGWriter::init(FILE *f, int width, int height)
     31bool PNGWriter::init(FILE *f, int width, int height, int hDPI, int vDPI)
    3032{
    3133        /* initialize stuff */
     
    6365        png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, interlace_type, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
    6466
     67        // PNG_RESOLUTION_UNKNOWN means dots per inch
     68        png_set_pHYs(png_ptr, info_ptr, hDPI, vDPI, PNG_RESOLUTION_UNKNOWN);
     69
    6570        png_write_info(png_ptr, info_ptr);
    6671        if (setjmp(png_jmpbuf(png_ptr))) {
     
    7277}
    7378
    74 bool PNGWriter::writePointers(png_bytep *rowPointers)
     79bool PNGWriter::writePointers(unsigned char **rowPointers, int rowCount)
    7580{
    7681        png_write_image(png_ptr, rowPointers);
     
    8489}
    8590
    86 bool PNGWriter::writeRow(png_bytep *row)
     91bool PNGWriter::writeRow(unsigned char **row)
    8792{
    8893        // Write the row to the file
  • trunk/poppler/mypoppler/goo/PNGWriter.h

    r277 r461  
    88// Copyright (C) 2009 Shen Liang <shenzhuxi@gmail.com>
    99// Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
     10// Copyright (C) 2009 Stefan Thomas <thomas@eload24.com>
     11// Copyright (C) 2010 Adrian Johnson <ajohnson@redneon.com>
    1012//
    1113//========================================================================
     
    2022#include <cstdio>
    2123#include <png.h>
     24#include "ImgWriter.h"
    2225
    23 class PNGWriter
     26class PNGWriter : public ImgWriter
    2427{
    2528        public:
     
    2730                ~PNGWriter();
    2831               
    29                 bool init(FILE *f, int width, int height);
     32                bool init(FILE *f, int width, int height, int hDPI, int vDPI);
    3033               
    31                 bool writePointers(png_bytep *rowPointers);
    32                 bool writeRow(png_bytep *row);
     34                bool writePointers(unsigned char **rowPointers, int rowCount);
     35                bool writeRow(unsigned char **row);
    3336               
    3437                bool close();
  • trunk/poppler/mypoppler/goo/gfile.cc

    r292 r461  
    1919// Copyright (C) 2006 Kristian HÞgsberg <krh@redhat.com>
    2020// Copyright (C) 2008 Adam Batkin <adam@batkin.net>
    21 // Copyright (C) 2008 Hib Eris <hib@hiberis.nl>
     21// Copyright (C) 2008, 2010 Hib Eris <hib@hiberis.nl>
    2222// Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
    2323// Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
     
    4242#  include <limits.h>
    4343#  include <string.h>
    44 /* Lucide */
    4544#  if !defined(VMS) && !defined(ACORN) && !defined(MACOS) && !defined(OS2)
    4645#    include <pwd.h>
     
    6665  return new GooString("SYS$LOGIN:");
    6766
    68 /* Lucide */
    6967#elif defined(__EMX__) || defined(_WIN32) || defined(OS2)
    7068  //---------- OS/2+EMX and Win32 ----------
     
    216214  return path;
    217215
    218 /* Lucide */
    219216#elif defined(__EMX__) || defined(OS2)
    220217  //---------- OS/2+EMX ----------
     
    304301  return new GooString();
    305302
    306 /* Lucide */
    307303#elif defined(__EMX__) || defined(_WIN32) || defined(OS2)
    308304  //---------- OS/2+EMX and Win32 ----------
     
    349345         (path[0] == '[' && path[1] != '.' && path[1] != '-');
    350346
    351 /* Lucide */
    352347#elif defined(__EMX__) || defined(_WIN32) || defined(OS2)
    353348  //---------- OS/2+EMX and Win32 ----------
     
    382377#elif defined(_WIN32)
    383378  //---------- Win32 ----------
    384   char buf[_MAX_PATH];
     379  char buf[MAX_PATH];
    385380  char *fp;
    386381
    387382  buf[0] = '\0';
    388   if (!GetFullPathName(path->getCString(), _MAX_PATH, buf, &fp)) {
     383  if (!GetFullPathName(path->getCString(), MAX_PATH, buf, &fp)) {
    389384    path->clear();
    390385    return path;
     
    404399  return path;
    405400
    406 /* Lucide */
    407401#elif defined(OS2)
    408402  //---------- OS/2 -----------
     
    516510  delete s;
    517511  return gFalse;
    518 /* Lucide */
     512
    519513#elif defined(VMS) || defined(__EMX__) || defined(ACORN) || defined(MACOS) || defined(OS2)
    520514  //---------- non-Unix ----------
  • trunk/poppler/mypoppler/goo/gfile.h

    r290 r461  
    6262#      include <ndir.h>
    6363#    endif
    64 /* Lucide */
    6564#    if HAVE_DIRECT_H
    6665#      include <direct.h>
  • trunk/poppler/mypoppler/goo/gstrtod.cc

    r367 r461  
    2323#include "gstrtod.h"
    2424
    25 /* Lucide */
     25#if !defined(OS2)
     26#include <clocale>
     27#include <cerrno>
     28#include <cstdlib>
     29#include <cstring>
     30#else
    2631#include <locale.h>
    2732#include <errno.h>
    2833#include <stdlib.h>
    2934#include <string.h>
     35#endif
    3036
    3137#define ascii_isspace(c) \
  • trunk/poppler/mypoppler/goo/gtypes.h

    r2 r461  
    66 * Copyright 1996-2003 Glyph & Cog, LLC
    77 */
     8
     9//========================================================================
     10//
     11// Modified under the Poppler project - http://poppler.freedesktop.org
     12//
     13// All changes made under the Poppler project to this file are licensed
     14// under GPL version 2 or later
     15//
     16// Copyright (C) 2010 Patrick Spendrin <ps_ml@gmx.de>
     17//
     18// To see a description of the changes please see the Changelog file that
     19// came with your tarball or type make ChangeLog if you are building from git
     20//
     21//========================================================================
    822
    923#ifndef GTYPES_H
     
    1832#define gFalse 0
    1933
     34#ifdef _MSC_VER
     35#pragma warning(disable: 4800) /* 'type' : forcing value to bool 'true' or 'false' (performance warning) */
     36#endif
     37
    2038/*
    2139 * These have stupid names to avoid conflicts with <sys/types.h>,
  • trunk/poppler/mypoppler/poppler/Annot.cc

    r277 r461  
    1616// Copyright (C) 2006 Scott Turner <scotty1024@mac.com>
    1717// Copyright (C) 2007, 2008 Julien Rebetez <julienr@svn.gnome.org>
    18 // Copyright (C) 2007-2009 Albert Astals Cid <aacid@kde.org>
    19 // Copyright (C) 2007-2009 Carlos Garcia Campos <carlosgc@gnome.org>
     18// Copyright (C) 2007-2010 Albert Astals Cid <aacid@kde.org>
     19// Copyright (C) 2007-2010 Carlos Garcia Campos <carlosgc@gnome.org>
    2020// Copyright (C) 2007, 2008 Iñigo Martínez <inigomartinez@gmail.com>
    2121// Copyright (C) 2007 Jeff Muizelaar <jeff@infidigm.net>
     
    6060#include "FileSpec.h"
    6161#include "DateInfo.h"
     62#include "Link.h"
    6263#include <string.h>
    63 
    64 #define annotFlagHidden    0x0002
    65 #define annotFlagPrint     0x0004
    66 #define annotFlagNoView    0x0020
    6764
    6865#define fieldFlagReadOnly           0x00000001
     
    9390// = (4 * (sqrt(2) - 1) / 3) * r
    9491#define bezierCircle 0.55228475
     92
     93// Ensures that x is between the limits set by low and high.
     94// If low is greater than high the result is undefined.
     95#define CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
    9596
    9697AnnotLineEndingStyle parseAnnotLineEndingStyle(GooString *string) {
     
    324325
    325326  if ((arrayLength % 8) == 0) {
    326     int i = 0;
     327    int i;
    327328
    328329    quadsLength = arrayLength / 8;
     
    331332    memset(quads, 0, quadsLength * sizeof(AnnotQuadrilateral *));
    332333
    333     while (i < (quadsLength) && correct) {
    334       for (int j = 0; j < 8 && correct; j++) {
     334    for (i = 0; i < quadsLength; i++) {
     335      for (int j = 0; j < 8; j++) {
    335336        Object obj;
    336337        if (array->get(i * 8 + j, &obj)->isNum()) {
    337           quadArray[j] = obj.getNum();
    338           if (j % 2 == 1) {
    339               if (quadArray[j] < rect->y1 || quadArray[j] > rect->y2)
    340                   correct = gFalse;
    341           } else {
    342               if (quadArray[j] < rect->x1 || quadArray[j] > rect->x2)
    343                   correct = gFalse;
    344           }
     338          if (j % 2 == 1)
     339            quadArray[j] = CLAMP (obj.getNum(), rect->y1, rect->y2);
     340          else
     341            quadArray[j] = CLAMP (obj.getNum(), rect->x1, rect->x2);
    345342        } else {
    346343            correct = gFalse;
     344            obj.free();
     345            error (-1, "Invalid QuadPoint in annot");
     346            break;
    347347        }
    348348        obj.free();
    349349      }
    350350
    351       if (correct)
    352         quads[i] = new AnnotQuadrilateral(quadArray[0], quadArray[1],
    353                                           quadArray[2], quadArray[3],
    354                                           quadArray[4], quadArray[5],
    355                                           quadArray[6], quadArray[7]);
    356       i++;
     351      if (!correct)
     352        break;
     353
     354      quads[i] = new AnnotQuadrilateral(quadArray[0], quadArray[1],
     355                                        quadArray[2], quadArray[3],
     356                                        quadArray[4], quadArray[5],
     357                                        quadArray[6], quadArray[7]);
    357358    }
    358359
     
    612613AnnotColor::AnnotColor() {
    613614  length = 0;
    614   values = NULL;
    615615}
    616616
    617617AnnotColor::AnnotColor(double gray) {
    618618  length = 1;
    619   values = (double *) gmallocn (length, sizeof(double));
    620619
    621620  values[0] = gray;
     
    624623AnnotColor::AnnotColor(double r, double g, double b) {
    625624  length = 3;
    626   values = (double *) gmallocn (length, sizeof(double));
    627625
    628626  values[0] = r;
     
    633631AnnotColor::AnnotColor(double c, double m, double y, double k) {
    634632  length = 4;
    635   values = (double *) gmallocn (length, sizeof(double));
    636633
    637634  values[0] = c;
     
    641638}
    642639
    643 AnnotColor::AnnotColor(Array *array) {
    644   // TODO: check what Acrobat does in the case of having more than 5 numbers.
    645   if (array->getLength() < 5) {
    646     length = array->getLength();
    647     values = (double *) gmallocn (length, sizeof(double));
    648 
    649     for(int i = 0; i < length; i++) { 
    650       Object obj1;
    651 
    652       if (array->get(i, &obj1)->isNum()) {
    653         values[i] = obj1.getNum();
    654 
    655         if (values[i] < 0 || values[i] > 1)
    656           values[i] = 0;
    657       } else {
     640// If <adjust> is +1, color is brightened;
     641// if <adjust> is -1, color is darkened;
     642// otherwise color is not modified.
     643AnnotColor::AnnotColor(Array *array, int adjust) {
     644  int i;
     645
     646  length = array->getLength();
     647  if (length > 4)
     648    length = 4;
     649
     650  for (i = 0; i < length; i++) {
     651    Object obj1;
     652
     653    if (array->get(i, &obj1)->isNum()) {
     654      values[i] = obj1.getNum();
     655
     656      if (values[i] < 0 || values[i] > 1)
    658657        values[i] = 0;
    659       }
    660       obj1.free();
    661     }
    662   } else {
    663     values = NULL;
    664     length = 0;
    665   }
    666 }
    667 
    668 AnnotColor::~AnnotColor() {
    669   if (values)
    670     gfree (values);
     658    } else {
     659      values[i] = 0;
     660    }
     661    obj1.free();
     662  }
     663
     664  if (length == 4) {
     665    adjust = -adjust;
     666  }
     667  if (adjust > 0) {
     668    for (i = 0; i < length; ++i) {
     669      values[i] = 0.5 * values[i] + 0.5;
     670    }
     671  } else if (adjust < 0) {
     672    for (i = 0; i < length; ++i) {
     673      values[i] = 0.5 * values[i];
     674    }
     675  }
    671676}
    672677
     
    900905  appearBuf = NULL;
    901906  fontSize = 0;
     907
     908  appearance.initNull();
    902909
    903910  //----- parse the rectangle
     
    940947  obj1.free();
    941948
    942   /* TODO: Page Object indirect reference (should be parsed ?) */
    943   pageDict = NULL;
    944   /*if (dict->lookup("P", &obj1)->isDict()) {
    945     pageDict = NULL;
    946   } else {
    947     pageDict = NULL;
    948   }
    949   obj1.free();
    950   */
     949  if (dict->lookupNF("P", &obj1)->isRef()) {
     950    Ref ref = obj1.getRef();
     951
     952    page = catalog ? catalog->findPage (ref.num, ref.gen) : -1;
     953  } else {
     954    page = 0;
     955  }
     956  obj1.free();
    951957
    952958  if (dict->lookup("NM", &obj1)->isString()) {
     
    10811087  if (new_color) {
    10821088    Object obj1, obj2;
    1083     double *values = new_color->getValues();
     1089    const double *values = new_color->getValues();
    10841090
    10851091    obj1.initArray(xref);
     
    11221128    delete contents;
    11231129
    1124   if (pageDict)
    1125     delete pageDict;
    1126 
    11271130  if (name)
    11281131    delete name;
     
    11451148}
    11461149
    1147 // Set the current fill or stroke color, based on <a> (which should
    1148 // have 1, 3, or 4 elements).  If <adjust> is +1, color is brightened;
    1149 // if <adjust> is -1, color is darkened; otherwise color is not
    1150 // modified.
    1151 void Annot::setColor(Array *a, GBool fill, int adjust) {
    1152   Object obj1;
    1153   double color[4];
    1154   int nComps, i;
    1155 
    1156   nComps = a->getLength();
    1157   if (nComps > 4) {
    1158     nComps = 4;
    1159   }
    1160   for (i = 0; i < nComps && i < 4; ++i) {
    1161     if (a->get(i, &obj1)->isNum()) {
    1162       color[i] = obj1.getNum();
    1163     } else {
    1164       color[i] = 0;
    1165     }
    1166     obj1.free();
    1167   }
    1168   if (nComps == 4) {
    1169     adjust = -adjust;
    1170   }
    1171   if (adjust > 0) {
    1172     for (i = 0; i < nComps; ++i) {
    1173       color[i] = 0.5 * color[i] + 0.5;
    1174     }
    1175   } else if (adjust < 0) {
    1176     for (i = 0; i < nComps; ++i) {
    1177       color[i] = 0.5 * color[i];
    1178     }
    1179   }
    1180   if (nComps == 4) {
     1150void Annot::setColor(AnnotColor *color, GBool fill) {
     1151  const double *values = color->getValues();
     1152
     1153  switch (color->getSpace()) {
     1154  case AnnotColor::colorCMYK:
    11811155    appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:c}\n",
    1182         color[0], color[1], color[2], color[3],
    1183         fill ? 'k' : 'K');
    1184   } else if (nComps == 3) {
     1156                       values[0], values[1], values[2], values[3],
     1157                       fill ? 'k' : 'K');
     1158    break;
     1159  case AnnotColor::colorRGB:
    11851160    appearBuf->appendf("{0:.2f} {1:.2f} {2:.2f} {3:s}\n",
    1186         color[0], color[1], color[2],
    1187         fill ? "rg" : "RG");
    1188   } else {
     1161                       values[0], values[1], values[2],
     1162                       fill ? "rg" : "RG");
     1163    break;
     1164  case AnnotColor::colorGray:
    11891165    appearBuf->appendf("{0:.2f} {1:c}\n",
    1190         color[0],
    1191         fill ? 'g' : 'G');
     1166                       values[0],
     1167                       fill ? 'g' : 'G');
     1168    break;
     1169  case AnnotColor::colorTransparent:
     1170  default:
     1171    break;
    11921172  }
    11931173}
     
    12671247}
    12681248
    1269 void Annot::draw(Gfx *gfx, GBool printing) {
    1270   Object obj;
    1271 
     1249void Annot::createForm(double *bbox, GBool transparencyGroup, Object *resDict, Object *aStream) {
     1250  Object obj1, obj2;
     1251  Object appearDict;
     1252
     1253  appearDict.initDict(xref);
     1254  appearDict.dictSet("Length", obj1.initInt(appearBuf->getLength()));
     1255  appearDict.dictSet("Subtype", obj1.initName("Form"));
     1256  obj1.initArray(xref);
     1257  obj1.arrayAdd(obj2.initReal(bbox[0]));
     1258  obj1.arrayAdd(obj2.initReal(bbox[1]));
     1259  obj1.arrayAdd(obj2.initReal(bbox[2]));
     1260  obj1.arrayAdd(obj2.initReal(bbox[3]));
     1261  appearDict.dictSet("BBox", &obj1);
     1262  if (transparencyGroup) {
     1263    Object transDict;
     1264    transDict.initDict(xref);
     1265    transDict.dictSet("S", obj1.initName("Transparency"));
     1266    appearDict.dictSet("Group", &transDict);
     1267  }
     1268  if (resDict)
     1269    appearDict.dictSet("Resources", resDict);
     1270
     1271  MemStream *mStream = new MemStream(copyString(appearBuf->getCString()), 0,
     1272                                     appearBuf->getLength(), &appearDict);
     1273  mStream->setNeedFree(gTrue);
     1274  aStream->initStream(mStream);
     1275}
     1276
     1277void Annot::createResourcesDict(char *formName, Object *formStream,
     1278                                char *stateName,
     1279                                double opacity, char *blendMode,
     1280                                Object *resDict) {
     1281  Object gsDict, stateDict, formDict, obj1;
     1282
     1283  gsDict.initDict(xref);
     1284  if (opacity != 1) {
     1285    gsDict.dictSet("CA", obj1.initReal(opacity));
     1286    gsDict.dictSet("ca", obj1.initReal(opacity));
     1287  }
     1288  if (blendMode)
     1289    gsDict.dictSet("BM", obj1.initName(blendMode));
     1290  stateDict.initDict(xref);
     1291  stateDict.dictSet(stateName, &gsDict);
     1292  formDict.initDict(xref);
     1293  formDict.dictSet(formName, formStream);
     1294
     1295  resDict->initDict(xref);
     1296  resDict->dictSet("ExtGState", &stateDict);
     1297  resDict->dictSet("XObject", &formDict);
     1298}
     1299
     1300GBool Annot::isVisible(GBool printing) {
    12721301  // check the flags
    1273   if ((flags & annotFlagHidden) ||
    1274       (printing && !(flags & annotFlagPrint)) ||
    1275       (!printing && (flags & annotFlagNoView))) {
    1276     return;
     1302  if ((flags & flagHidden) ||
     1303      (printing && !(flags & flagPrint)) ||
     1304      (!printing && (flags & flagNoView))) {
     1305    return gFalse;
    12771306  }
    12781307
     
    12801309  if (optContentConfig && oc.isRef()) {
    12811310    if (! optContentConfig->optContentIsVisible(&oc))
    1282       return;
    1283   }
     1311      return gFalse;
     1312  }
     1313
     1314  return gTrue;
     1315}
     1316
     1317void Annot::draw(Gfx *gfx, GBool printing) {
     1318  Object obj;
     1319
     1320  if (!isVisible (printing))
     1321    return;
    12841322
    12851323  // draw the appearance stream
    12861324  appearance.fetch(xref, &obj);
    1287   gfx->drawAnnot(&obj, (type == typeLink) ? border : (AnnotBorder *)NULL, color,
     1325  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
    12881326      rect->x1, rect->y1, rect->x2, rect->y2);
    12891327  obj.free();
     
    16141652}
    16151653
     1654#define ANNOT_TEXT_AP_NOTE                                                    \
     1655  "3.602 24 m 20.398 24 l 22.387 24 24 22.387 24 20.398 c 24 3.602 l 24\n"    \
     1656  "1.613 22.387 0 20.398 0 c 3.602 0 l 1.613 0 0 1.613 0 3.602 c 0 20.398\n"  \
     1657  "l 0 22.387 1.613 24 3.602 24 c h\n"                                        \
     1658  "3.602 24 m f\n"                                                            \
     1659  "0.533333 0.541176 0.521569 RG 2 w\n"                                       \
     1660  "1 J\n"                                                                     \
     1661  "1 j\n"                                                                     \
     1662  "[] 0.0 d\n"                                                                \
     1663  "4 M 9 18 m 4 18 l 4 7 4 4 6 3 c 20 3 l 18 4 18 7 18 18 c 17 18 l S\n"      \
     1664  "1.5 w\n"                                                                   \
     1665  "0 j\n"                                                                     \
     1666  "10 16 m 14 21 l S\n"                                                       \
     1667  "1.85625 w\n"                                                               \
     1668  "1 j\n"                                                                     \
     1669  "15.07 20.523 m 15.07 19.672 14.379 18.977 13.523 18.977 c 12.672 18.977\n" \
     1670  "11.977 19.672 11.977 20.523 c 11.977 21.379 12.672 22.07 13.523 22.07 c\n" \
     1671  "14.379 22.07 15.07 21.379 15.07 20.523 c h\n"                              \
     1672  "15.07 20.523 m S\n"                                                        \
     1673  "1 w\n"                                                                     \
     1674  "0 j\n"                                                                     \
     1675  "6.5 13.5 m 15.5 13.5 l S\n"                                                \
     1676  "6.5 10.5 m 13.5 10.5 l S\n"                                                \
     1677  "6.801 7.5 m 15.5 7.5 l S\n"                                                \
     1678  "0.729412 0.741176 0.713725 RG 2 w\n"                                       \
     1679  "1 j\n"                                                                     \
     1680  "9 19 m 4 19 l 4 8 4 5 6 4 c 20 4 l 18 5 18 8 18 19 c 17 19 l S\n"          \
     1681  "1.5 w\n"                                                                   \
     1682  "0 j\n"                                                                     \
     1683  "10 17 m 14 22 l S\n"                                                       \
     1684  "1.85625 w\n"                                                               \
     1685  "1 j\n"                                                                     \
     1686  "15.07 21.523 m 15.07 20.672 14.379 19.977 13.523 19.977 c 12.672 19.977\n" \
     1687  "11.977 20.672 11.977 21.523 c 11.977 22.379 12.672 23.07 13.523 23.07 c\n" \
     1688  "14.379 23.07 15.07 22.379 15.07 21.523 c h\n"                              \
     1689  "15.07 21.523 m S\n"                                                        \
     1690  "1 w\n"                                                                     \
     1691  "0 j\n"                                                                     \
     1692  "6.5 14.5 m 15.5 14.5 l S\n"                                                \
     1693  "6.5 11.5 m 13.5 11.5 l S\n"                                                \
     1694  "6.801 8.5 m 15.5 8.5 l S\n"
     1695
     1696#define ANNOT_TEXT_AP_COMMENT                                                   \
     1697  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"      \
     1698  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"    \
     1699  "l 1 21.523 2.477 23 4.301 23 c h\n"                                          \
     1700  "4.301 23 m f\n"                                                              \
     1701  "0.533333 0.541176 0.521569 RG 2 w\n"                                         \
     1702  "0 J\n"                                                                       \
     1703  "1 j\n"                                                                       \
     1704  "[] 0.0 d\n"                                                                  \
     1705  "4 M 8 20 m 16 20 l 18.363 20 20 18.215 20 16 c 20 13 l 20 10.785 18.363 9\n" \
     1706  "16 9 c 13 9 l 8 3 l 8 9 l 8 9 l 5.637 9 4 10.785 4 13 c 4 16 l 4 18.215\n"   \
     1707  "5.637 20 8 20 c h\n"                                                         \
     1708  "8 20 m S\n"                                                                  \
     1709  "0.729412 0.741176 0.713725 RG 8 21 m 16 21 l 18.363 21 20 19.215 20 17\n"    \
     1710  "c 20 14 l 20 11.785 18.363 10\n"                                             \
     1711  "16 10 c 13 10 l 8 4 l 8 10 l 8 10 l 5.637 10 4 11.785 4 14 c 4 17 l 4\n"     \
     1712  "19.215 5.637 21 8 21 c h\n"                                                  \
     1713  "8 21 m S\n"
     1714
     1715#define ANNOT_TEXT_AP_KEY                                                    \
     1716  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"   \
     1717  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n" \
     1718  "l 1 21.523 2.477 23 4.301 23 c h\n"                                       \
     1719  "4.301 23 m f\n"                                                           \
     1720  "0.533333 0.541176 0.521569 RG 2 w\n"                                      \
     1721  "1 J\n"                                                                    \
     1722  "0 j\n"                                                                    \
     1723  "[] 0.0 d\n"                                                               \
     1724  "4 M 11.895 18.754 m 13.926 20.625 17.09 20.496 18.961 18.465 c 20.832\n"  \
     1725  "16.434 20.699 13.27 18.668 11.398 c 17.164 10.016 15.043 9.746 13.281\n"  \
     1726  "10.516 c 12.473 9.324 l 11.281 10.078 l 9.547 8.664 l 9.008 6.496 l\n"    \
     1727  "7.059 6.059 l 6.34 4.121 l 5.543 3.668 l 3.375 4.207 l 2.938 6.156 l\n"   \
     1728  "10.57 13.457 l 9.949 15.277 10.391 17.367 11.895 18.754 c h\n"            \
     1729  "11.895 18.754 m S\n"                                                      \
     1730  "1.5 w\n"                                                                  \
     1731  "16.059 15.586 m 16.523 15.078 17.316 15.043 17.824 15.512 c 18.332\n"     \
     1732  "15.98 18.363 16.77 17.895 17.277 c 17.43 17.785 16.637 17.816 16.129\n"   \
     1733  "17.352 c 15.621 16.883 15.59 16.094 16.059 15.586 c h\n"                  \
     1734  "16.059 15.586 m S\n"                                                      \
     1735  "0.729412 0.741176 0.713725 RG 2 w\n"                                      \
     1736  "11.895 19.754 m 13.926 21.625 17.09 21.496 18.961 19.465 c 20.832\n"      \
     1737  "17.434 20.699 14.27 18.668 12.398 c 17.164 11.016 15.043 10.746 13.281\n" \
     1738  "11.516 c 12.473 10.324 l 11.281 11.078 l 9.547 9.664 l 9.008 7.496 l\n"   \
     1739  "7.059 7.059 l 6.34 5.121 l 5.543 4.668 l 3.375 5.207 l 2.938 7.156 l\n"   \
     1740  "10.57 14.457 l 9.949 16.277 10.391 18.367 11.895 19.754 c h\n"            \
     1741  "11.895 19.754 m S\n"                                                      \
     1742  "1.5 w\n"                                                                  \
     1743  "16.059 16.586 m 16.523 16.078 17.316 16.043 17.824 16.512 c 18.332\n"     \
     1744  "16.98 18.363 17.77 17.895 18.277 c 17.43 18.785 16.637 18.816 16.129\n"   \
     1745  "18.352 c 15.621 17.883 15.59 17.094 16.059 16.586 c h\n"                  \
     1746  "16.059 16.586 m S\n"
     1747
     1748#define ANNOT_TEXT_AP_HELP                                                        \
     1749  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"        \
     1750  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"      \
     1751  "l 1 21.523 2.477 23 4.301 23 c h\n"                                            \
     1752  "4.301 23 m f\n"                                                                \
     1753  "0.533333 0.541176 0.521569 RG 2.5 w\n"                                         \
     1754  "1 J\n"                                                                         \
     1755  "1 j\n"                                                                         \
     1756  "[] 0.0 d\n"                                                                    \
     1757  "4 M 8.289 16.488 m 8.824 17.828 10.043 18.773 11.473 18.965 c 12.902 19.156\n" \
     1758  "14.328 18.559 15.195 17.406 c 16.062 16.254 16.242 14.723 15.664 13.398\n"     \
     1759  "c S\n"                                                                         \
     1760  "0 j\n"                                                                         \
     1761  "12 8 m 12 12 16 11 16 15 c S\n"                                                \
     1762  "1.539286 w\n"                                                                  \
     1763  "1 j\n"                                                                         \
     1764  "q 1 0 0 -0.999991 0 24 cm\n"                                                   \
     1765  "12.684 20.891 m 12.473 21.258 12.004 21.395 11.629 21.196 c 11.254\n"          \
     1766  "20.992 11.105 20.531 11.297 20.149 c 11.488 19.77 11.945 19.61 12.332\n"       \
     1767  "19.789 c 12.719 19.969 12.891 20.426 12.719 20.817 c S Q\n"                    \
     1768  "0.729412 0.741176 0.713725 RG 2.5 w\n"                                         \
     1769  "8.289 17.488 m 9.109 19.539 11.438 20.535 13.488 19.711 c 15.539 18.891\n"     \
     1770  "16.535 16.562 15.711 14.512 c 15.699 14.473 15.684 14.438 15.664 14.398\n"     \
     1771  "c S\n"                                                                         \
     1772  "0 j\n"                                                                         \
     1773  "12 9 m 12 13 16 12 16 16 c S\n"                                                \
     1774  "1.539286 w\n"                                                                  \
     1775  "1 j\n"                                                                         \
     1776  "q 1 0 0 -0.999991 0 24 cm\n"                                                   \
     1777  "12.684 19.891 m 12.473 20.258 12.004 20.395 11.629 20.195 c 11.254\n"          \
     1778  "19.992 11.105 19.531 11.297 19.149 c 11.488 18.77 11.945 18.61 12.332\n"       \
     1779  "18.789 c 12.719 18.969 12.891 19.426 12.719 19.817 c S Q\n"
     1780
     1781#define ANNOT_TEXT_AP_NEW_PARAGRAPH                                               \
     1782  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"        \
     1783  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"      \
     1784  "l 1 21.523 2.477 23 4.301 23 c h\n"                                            \
     1785  "4.301 23 m f\n"                                                                \
     1786  "0.533333 0.541176 0.521569 RG 4 w\n"                                           \
     1787  "0 J\n"                                                                         \
     1788  "2 j\n"                                                                         \
     1789  "[] 0.0 d\n"                                                                    \
     1790  "4 M q 1 0 0 -1 0 24 cm\n"                                                      \
     1791  "9.211 11.988 m 8.449 12.07 7.711 11.707 7.305 11.059 c 6.898 10.41\n"          \
     1792  "6.898 9.59 7.305 8.941 c 7.711 8.293 8.449 7.93 9.211 8.012 c S Q\n"           \
     1793  "1.004413 w\n"                                                                  \
     1794  "1 J\n"                                                                         \
     1795  "1 j\n"                                                                         \
     1796  "q 1 0 0 -0.991232 0 24 cm\n"                                                   \
     1797  "18.07 11.511 m 15.113 10.014 l 12.199 11.602 l 12.711 8.323 l 10.301\n"        \
     1798  "6.045 l 13.574 5.517 l 14.996 2.522 l 16.512 5.474 l 19.801 5.899 l\n"         \
     1799  "17.461 8.252 l 18.07 11.511 l h\n"                                             \
     1800  "18.07 11.511 m S Q\n"                                                          \
     1801  "2 w\n"                                                                         \
     1802  "0 j\n"                                                                         \
     1803  "11 17 m 10 17 l 10 3 l S\n"                                                    \
     1804  "14 3 m 14 13 l S\n"                                                            \
     1805  "0.729412 0.741176 0.713725 RG 4 w\n"                                           \
     1806  "0 J\n"                                                                         \
     1807  "2 j\n"                                                                         \
     1808  "q 1 0 0 -1 0 24 cm\n"                                                          \
     1809  "9.211 10.988 m 8.109 11.105 7.125 10.309 7.012 9.211 c 6.895 8.109\n"          \
     1810  "7.691 7.125 8.789 7.012 c 8.93 6.996 9.07 6.996 9.211 7.012 c S Q\n"           \
     1811  "1.004413 w\n"                                                                  \
     1812  "1 J\n"                                                                         \
     1813  "1 j\n"                                                                         \
     1814  "q 1 0 0 -0.991232 0 24 cm\n"                                                   \
     1815  "18.07 10.502 m 15.113 9.005 l 12.199 10.593 l 12.711 7.314 l 10.301\n"         \
     1816  "5.036 l 13.574 4.508 l 14.996 1.513 l 16.512 4.465 l 19.801 4.891 l\n"         \
     1817  "17.461 7.243 l 18.07 10.502 l h\n"                                             \
     1818  "18.07 10.502 m S Q\n"                                                          \
     1819  "2 w\n"                                                                         \
     1820  "0 j\n"                                                                         \
     1821  "11 18 m 10 18 l 10 4 l S\n"                                                    \
     1822  "14 4 m 14 14 l S\n"
     1823
     1824#define ANNOT_TEXT_AP_PARAGRAPH                                              \
     1825  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"   \
     1826  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n" \
     1827  "l 1 21.523 2.477 23 4.301 23 c h\n"                                       \
     1828  "4.301 23 m f\n"                                                           \
     1829  "0.533333 0.541176 0.521569 RG 2 w\n"                                      \
     1830  "1 J\n"                                                                    \
     1831  "1 j\n"                                                                    \
     1832  "[] 0.0 d\n"                                                               \
     1833  "4 M 15 3 m 15 18 l 11 18 l 11 3 l S\n"                                    \
     1834  "4 w\n"                                                                    \
     1835  "q 1 0 0 -1 0 24 cm\n"                                                     \
     1836  "9.777 10.988 m 8.746 10.871 7.973 9.988 8 8.949 c 8.027 7.91 8.844\n"     \
     1837  "7.066 9.879 7.004 c S Q\n"                                                \
     1838  "0.729412 0.741176 0.713725 RG 2 w\n"                                      \
     1839  "15 4 m 15 19 l 11 19 l 11 4 l S\n"                                        \
     1840  "4 w\n"                                                                    \
     1841  "q 1 0 0 -1 0 24 cm\n"                                                     \
     1842  "9.777 9.988 m 8.746 9.871 7.973 8.988 8 7.949 c 8.027 6.91 8.844 6.066\n" \
     1843  "9.879 6.004 c S Q\n"
     1844
     1845#define ANNOT_TEXT_AP_INSERT                                                 \
     1846  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"   \
     1847  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n" \
     1848  "l 1 21.523 2.477 23 4.301 23 c h\n"                                       \
     1849  "4.301 23 m f\n"                                                           \
     1850  "0.533333 0.541176 0.521569 RG 2 w\n"                                      \
     1851  "1 J\n"                                                                    \
     1852  "0 j\n"                                                                    \
     1853  "[] 0.0 d\n"                                                               \
     1854  "4 M 12 18.012 m 20 18 l S\n"                                              \
     1855  "9 10 m 17 10 l S\n"                                                       \
     1856  "12 14.012 m 20 14 l S\n"                                                  \
     1857  "12 6.012 m 20 6.012 l S\n"                                                \
     1858  "4 12 m 6 10 l 4 8 l S\n"                                                  \
     1859  "4 12 m 4 8 l S\n"                                                         \
     1860  "0.729412 0.741176 0.713725 RG 12 19.012 m 20 19 l S\n"                    \
     1861  "9 11 m 17 11 l S\n"                                                       \
     1862  "12 15.012 m 20 15 l S\n"                                                  \
     1863  "12 7.012 m 20 7.012 l S\n"                                                \
     1864  "4 13 m 6 11 l 4 9 l S\n"                                                  \
     1865  "4 13 m 4 9 l S\n"
     1866
     1867#define ANNOT_TEXT_AP_CROSS                                                  \
     1868  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"   \
     1869  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n" \
     1870  "l 1 21.523 2.477 23 4.301 23 c h\n"                                       \
     1871  "4.301 23 m f\n"                                                           \
     1872  "0.533333 0.541176 0.521569 RG 2.5 w\n"                                    \
     1873  "1 J\n"                                                                    \
     1874  "0 j\n"                                                                    \
     1875  "[] 0.0 d\n"                                                               \
     1876  "4 M 18 5 m 6 17 l S\n"                                                    \
     1877  "6 5 m 18 17 l S\n"                                                        \
     1878  "0.729412 0.741176 0.713725 RG 18 6 m 6 18 l S\n"                          \
     1879  "6 6 m 18 18 l S\n"
     1880
     1881#define ANNOT_TEXT_AP_CIRCLE                                                      \
     1882  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"        \
     1883  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"      \
     1884  "l 1 21.523 2.477 23 4.301 23 c h\n"                                            \
     1885  "4.301 23 m f\n"                                                                \
     1886  "0.533333 0.541176 0.521569 RG 2.5 w\n"                                         \
     1887  "1 J\n"                                                                         \
     1888  "1 j\n"                                                                         \
     1889  "[] 0.0 d\n"                                                                    \
     1890  "4 M 19.5 11.5 m 19.5 7.359 16.141 4 12 4 c 7.859 4 4.5 7.359 4.5 11.5 c 4.5\n" \
     1891  "15.641 7.859 19 12 19 c 16.141 19 19.5 15.641 19.5 11.5 c h\n"                 \
     1892  "19.5 11.5 m S\n"                                                               \
     1893  "0.729412 0.741176 0.713725 RG 19.5 12.5 m 19.5 8.359 16.141 5 12 5 c\n"        \
     1894  "7.859 5 4.5 8.359 4.5 12.5 c 4.5\n"                                            \
     1895  "16.641 7.859 20 12 20 c 16.141 20 19.5 16.641 19.5 12.5 c h\n"                 \
     1896  "19.5 12.5 m S\n"
     1897
     1898void AnnotText::draw(Gfx *gfx, GBool printing) {
     1899  Object obj;
     1900  double ca = 1;
     1901
     1902  if (!isVisible (printing))
     1903    return;
     1904
     1905  double rectx2 = rect->x2;
     1906  double recty2 = rect->y2;
     1907  if (appearance.isNull()) {
     1908    ca = opacity;
     1909
     1910    appearBuf = new GooString ();
     1911
     1912    appearBuf->append ("q\n");
     1913    if (color)
     1914      setColor(color, gTrue);
     1915    else
     1916      appearBuf->append ("1 1 1 rg\n");
     1917    if (!icon->cmp("Note"))
     1918      appearBuf->append (ANNOT_TEXT_AP_NOTE);
     1919    else if (!icon->cmp("Comment"))
     1920      appearBuf->append (ANNOT_TEXT_AP_COMMENT);
     1921    else if (!icon->cmp("Key"))
     1922      appearBuf->append (ANNOT_TEXT_AP_KEY);
     1923    else if (!icon->cmp("Help"))
     1924      appearBuf->append (ANNOT_TEXT_AP_HELP);
     1925    else if (!icon->cmp("NewParagraph"))
     1926      appearBuf->append (ANNOT_TEXT_AP_NEW_PARAGRAPH);
     1927    else if (!icon->cmp("Paragraph"))
     1928      appearBuf->append (ANNOT_TEXT_AP_PARAGRAPH);
     1929    else if (!icon->cmp("Insert"))
     1930      appearBuf->append (ANNOT_TEXT_AP_INSERT);
     1931    else if (!icon->cmp("Cross"))
     1932      appearBuf->append (ANNOT_TEXT_AP_CROSS);
     1933    else if (!icon->cmp("Circle"))
     1934      appearBuf->append (ANNOT_TEXT_AP_CIRCLE);
     1935    appearBuf->append ("Q\n");
     1936
     1937    double bbox[4];
     1938    bbox[0] = bbox[1] = 0;
     1939    bbox[2] = bbox[3] = 24;
     1940    if (ca == 1) {
     1941      createForm(bbox, gFalse, NULL, &appearance);
     1942    } else {
     1943      Object aStream, resDict;
     1944
     1945      createForm(bbox, gTrue, NULL, &aStream);
     1946      delete appearBuf;
     1947
     1948      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
     1949      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
     1950      createForm(bbox, gFalse, &resDict, &appearance);
     1951    }
     1952    delete appearBuf;
     1953
     1954    rectx2 = rect->x1 + 24;
     1955    recty2 = rect->y1 + 24;
     1956  }
     1957
     1958  // draw the appearance stream
     1959  appearance.fetch(xref, &obj);
     1960  gfx->drawAnnot(&obj, border, color,
     1961                 rect->x1, rect->y1, rectx2, recty2);
     1962  obj.free();
     1963}
     1964
    16161965//------------------------------------------------------------------------
    16171966// AnnotLink
     
    16962045  Object obj;
    16972046
    1698   // check the flags
    1699   if ((flags & annotFlagHidden) ||
    1700       (printing && !(flags & annotFlagPrint)) ||
    1701       (!printing && (flags & annotFlagNoView))) {
     2047  if (!isVisible (printing))
    17022048    return;
    1703   }
    17042049
    17052050  // draw the appearance stream
     
    20222367  }
    20232368  obj1.free();
     2369}
     2370
     2371void AnnotLine::draw(Gfx *gfx, GBool printing) {
     2372  Object obj;
     2373  double ca = 1;
     2374
     2375  if (!isVisible (printing))
     2376    return;
     2377
     2378  /* Some documents like pdf_commenting_new.pdf,
     2379   * have y1 = y2 but line_width > 0, acroread
     2380   * renders the lines in such cases even though
     2381   * the annot bbox is empty. We adjust the bbox here
     2382   * to avoid having an empty bbox so that lines
     2383   * are rendered
     2384   */
     2385  if (rect->y1 == rect->y2)
     2386    rect->y2 += border ? border->getWidth() : 1;
     2387
     2388  if (appearance.isNull()) {
     2389    ca = opacity;
     2390
     2391    appearBuf = new GooString ();
     2392    appearBuf->append ("q\n");
     2393    if (color)
     2394      setColor(color, gFalse);
     2395
     2396    if (border) {
     2397      int i, dashLength;
     2398      double *dash;
     2399
     2400      switch (border->getStyle()) {
     2401      case AnnotBorder::borderDashed:
     2402        appearBuf->append("[");
     2403        dashLength = border->getDashLength();
     2404        dash = border->getDash();
     2405        for (i = 0; i < dashLength; ++i)
     2406          appearBuf->appendf(" {0:.2f}", dash[i]);
     2407        appearBuf->append(" ] 0 d\n");
     2408        break;
     2409      default:
     2410        appearBuf->append("[] 0 d\n");
     2411        break;
     2412      }
     2413      appearBuf->appendf("{0:.2f} w\n", border->getWidth());
     2414    }
     2415    appearBuf->appendf ("{0:.2f} {1:.2f} m\n", coord1->getX() - rect->x1, coord1->getY() - rect->y1);
     2416    appearBuf->appendf ("{0:.2f} {1:.2f} l\n", coord2->getX() - rect->x1, coord2->getY() - rect->y1);
     2417    // TODO: Line ending, caption, leader lines
     2418    appearBuf->append ("S\n");
     2419    appearBuf->append ("Q\n");
     2420
     2421    double bbox[4];
     2422    bbox[0] = bbox[1] = 0;
     2423    bbox[2] = rect->x2 - rect->x1;
     2424    bbox[3] = rect->y2 - rect->y1;
     2425    if (ca == 1) {
     2426      createForm(bbox, gFalse, NULL, &appearance);
     2427    } else {
     2428      Object aStream, resDict;
     2429
     2430      createForm(bbox, gTrue, NULL, &aStream);
     2431      delete appearBuf;
     2432
     2433      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
     2434      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
     2435      createForm(bbox, gFalse, &resDict, &appearance);
     2436    }
     2437    delete appearBuf;
     2438  }
     2439
     2440  // draw the appearance stream
     2441  appearance.fetch(xref, &obj);
     2442  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
     2443                 rect->x1, rect->y1, rect->x2, rect->y2);
     2444  obj.free();
    20242445}
    20252446
     
    20972518    quadrilaterals = new AnnotQuadrilaterals(obj1.getArray(), rect);
    20982519  } else {
     2520    error(-1, "Bad Annot Text Markup QuadPoints");
    20992521    quadrilaterals = NULL;
     2522    ok = gFalse;
    21002523  }
    21012524  obj1.free();
     
    21062529    delete quadrilaterals;
    21072530  }
     2531}
     2532
     2533
     2534
     2535void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
     2536  Object obj;
     2537  double ca = 1;
     2538  int i;
     2539  Object obj1, obj2;
     2540
     2541  if (!isVisible (printing))
     2542    return;
     2543
     2544  if (appearance.isNull() || type == typeHighlight) {
     2545    ca = opacity;
     2546
     2547    appearBuf = new GooString ();
     2548
     2549    switch (type) {
     2550    case typeUnderline:
     2551      if (color) {
     2552        setColor(color, gFalse);
     2553        setColor(color, gTrue);
     2554      }
     2555
     2556      for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
     2557        double x1, y1, x2, y2, x3, y3;
     2558        double x, y;
     2559
     2560        x1 = quadrilaterals->getX1(i);
     2561        y1 = quadrilaterals->getY1(i);
     2562        x2 = quadrilaterals->getX2(i);
     2563        y2 = quadrilaterals->getY2(i);
     2564        x3 = quadrilaterals->getX3(i);
     2565        y3 = quadrilaterals->getY3(i);
     2566
     2567        x = x1 - rect->x1;
     2568        y = y3 - rect->y1;
     2569        appearBuf->append ("[]0 d 2 w\n");
     2570        appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x, y);
     2571        appearBuf->appendf ("{0:.2f} {1:.2f} l\n", x + (x2 - x1), y);
     2572        appearBuf->append ("S\n");
     2573      }
     2574      break;
     2575    case typeStrikeOut:
     2576      if (color) {
     2577        setColor(color, gFalse);
     2578        setColor(color, gTrue);
     2579      }
     2580
     2581      for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
     2582        double x1, y1, x2, y2, x3, y3;
     2583        double x, y;
     2584        double h2;
     2585
     2586        x1 = quadrilaterals->getX1(i);
     2587        y1 = quadrilaterals->getY1(i);
     2588        x2 = quadrilaterals->getX2(i);
     2589        y2 = quadrilaterals->getY2(i);
     2590        x3 = quadrilaterals->getX3(i);
     2591        y3 = quadrilaterals->getY3(i);
     2592        h2 = (y1 - y3) / 2.0;
     2593
     2594        x = x1 - rect->x1;
     2595        y = (y3 - rect->y1) + h2;
     2596        appearBuf->append ("[]0 d 2 w\n");
     2597        appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x, y);
     2598        appearBuf->appendf ("{0:.2f} {1:.2f} l\n", x + (x2 - x1), y);
     2599        appearBuf->append ("S\n");
     2600      }
     2601      break;
     2602    case typeSquiggly:
     2603      // TODO
     2604    default:
     2605    case typeHighlight:
     2606      appearance.free();
     2607
     2608      if (color)
     2609        setColor(color, gTrue);
     2610
     2611      for (i = 0; i < quadrilaterals->getQuadrilateralsLength(); ++i) {
     2612        double x1, y1, x2, y2, x3, y3, x4, y4;
     2613        double h4;
     2614
     2615        x1 = quadrilaterals->getX1(i);
     2616        y1 = quadrilaterals->getY1(i);
     2617        x2 = quadrilaterals->getX2(i);
     2618        y2 = quadrilaterals->getY2(i);
     2619        x3 = quadrilaterals->getX3(i);
     2620        y3 = quadrilaterals->getY3(i);
     2621        x4 = quadrilaterals->getX4(i);
     2622        y4 = quadrilaterals->getY4(i);
     2623        h4 = (y1 - y3) / 4.0;
     2624
     2625        appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x3, y3);
     2626        appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
     2627                            x3 - h4, y3 + h4, x1 - h4, y1 - h4, x1, y1);
     2628        appearBuf->appendf ("{0:.2f} {1:.2f} l\n", x2, y2);
     2629        appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
     2630                            x2 + h4, y2 - h4, x4 + h4, y4 + h4, x4, y4);
     2631        appearBuf->append ("f\n");
     2632      }
     2633
     2634      Object aStream, resDict;
     2635      double bbox[4];
     2636      bbox[0] = rect->x1;
     2637      bbox[1] = rect->y1;
     2638      bbox[2] = rect->x2;
     2639      bbox[3] = rect->y2;
     2640      createForm(bbox, gTrue, NULL, &aStream);
     2641      delete appearBuf;
     2642
     2643      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
     2644      createResourcesDict("Fm0", &aStream, "GS0", 1, "Multiply", &resDict);
     2645      if (ca == 1) {
     2646        createForm(bbox, gFalse, &resDict, &appearance);
     2647      } else {
     2648        createForm(bbox, gTrue, &resDict, &aStream);
     2649        delete appearBuf;
     2650
     2651        appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
     2652        createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
     2653        createForm(bbox, gFalse, &resDict, &appearance);
     2654      }
     2655      delete appearBuf;
     2656      break;
     2657    }
     2658  }
     2659
     2660  // draw the appearance stream
     2661  appearance.fetch(xref, &obj);
     2662  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
     2663                 rect->x1, rect->y1, rect->x2, rect->y2);
     2664  obj.free();
    21082665}
    21092666
     
    30153572  int dashLength, ff, quadding, comb, nOptions, topIdx, i, j;
    30163573  GBool modified;
     3574  AnnotColor aColor;
    30173575
    30183576  if (widget == NULL || !widget->getField () || !widget->getField ()->getObj ()->isDict ())
     
    30433601    if (mkDict->lookup("BG", &obj1)->isArray() &&
    30443602        obj1.arrayGetLength() > 0) {
    3045       setColor(obj1.getArray(), gTrue, 0);
     3603      AnnotColor aColor = AnnotColor (obj1.getArray());
     3604      setColor(&aColor, gTrue);
    30463605      appearBuf->appendf("0 0 {0:.2f} {1:.2f} re f\n",
    30473606          rect->x2 - rect->x1, rect->y2 - rect->y1);
     
    30913650            case AnnotBorder::borderUnderlined:
    30923651              appearBuf->appendf("{0:.2f} w\n", w);
    3093               setColor(obj1.getArray(), gFalse, 0);
     3652              aColor = AnnotColor (obj1.getArray());
     3653              setColor(&aColor, gFalse);
    30943654              drawCircle(0.5 * dx, 0.5 * dy, r - 0.5 * w, gFalse);
    30953655              break;
     
    30973657            case AnnotBorder::borderInset:
    30983658              appearBuf->appendf("{0:.2f} w\n", 0.5 * w);
    3099               setColor(obj1.getArray(), gFalse, 0);
     3659              aColor = AnnotColor (obj1.getArray());
     3660              setColor(&aColor, gFalse);
    31003661              drawCircle(0.5 * dx, 0.5 * dy, r - 0.25 * w, gFalse);
    3101               setColor(obj1.getArray(), gFalse,
    3102                   border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
     3662              aColor = AnnotColor (obj1.getArray(),
     3663                                   border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
     3664              setColor(&aColor, gFalse);
    31033665              drawCircleTopLeft(0.5 * dx, 0.5 * dy, r - 0.75 * w);
    3104               setColor(obj1.getArray(), gFalse,
    3105                   border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
     3666              aColor = AnnotColor (obj1.getArray(),
     3667                                   border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
     3668              setColor(&aColor, gFalse);
    31063669              drawCircleBottomRight(0.5 * dx, 0.5 * dy, r - 0.75 * w);
    31073670              break;
     
    31213684            case AnnotBorder::borderSolid:
    31223685              appearBuf->appendf("{0:.2f} w\n", w);
    3123               setColor(obj1.getArray(), gFalse, 0);
     3686              aColor = AnnotColor (obj1.getArray());
     3687              setColor(&aColor, gFalse);
    31243688              appearBuf->appendf("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re s\n",
    31253689                  0.5 * w, dx - w, dy - w);
     
    31273691            case AnnotBorder::borderBeveled:
    31283692            case AnnotBorder::borderInset:
    3129               setColor(obj1.getArray(), gTrue,
    3130                   border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
     3693              aColor = AnnotColor (obj1.getArray(),
     3694                                   border->getStyle() == AnnotBorder::borderBeveled ? 1 : -1);
     3695              setColor(&aColor, gTrue);
    31313696              appearBuf->append("0 0 m\n");
    31323697              appearBuf->appendf("0 {0:.2f} l\n", dy);
     
    31363701              appearBuf->appendf("{0:.2f} {0:.2f} l\n", w);
    31373702              appearBuf->append("f\n");
    3138               setColor(obj1.getArray(), gTrue,
    3139                   border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
     3703              aColor = AnnotColor (obj1.getArray(),
     3704                                   border->getStyle() == AnnotBorder::borderBeveled ? -1 : 1);
     3705              setColor(&aColor, gTrue);
    31403706              appearBuf->append("0 0 m\n");
    31413707              appearBuf->appendf("{0:.2f} 0 l\n", dx);
     
    31483714            case AnnotBorder::borderUnderlined:
    31493715              appearBuf->appendf("{0:.2f} w\n", w);
    3150               setColor(obj1.getArray(), gFalse, 0);
     3716              aColor = AnnotColor (obj1.getArray());
     3717              setColor(&aColor, gFalse);
    31513718              appearBuf->appendf("0 0 m {0:.2f} 0 l s\n", dx);
    31523719              break;
     
    32113778                dx = rect->x2 - rect->x1;
    32123779                dy = rect->y2 - rect->y1;
    3213                 setColor(obj3.getArray(), gTrue, 0);
     3780                aColor = AnnotColor (obj1.getArray());
     3781                setColor(&aColor, gTrue);
    32143782                drawCircle(0.5 * dx, 0.5 * dy, 0.2 * (dx < dy ? dx : dy),
    32153783                    gTrue);
     
    34213989  Object obj;
    34223990
    3423   // check the flags
    3424   if ((flags & annotFlagHidden) ||
    3425       (printing && !(flags & annotFlagPrint)) ||
    3426       (!printing && (flags & annotFlagNoView))) {
     3991  if (!isVisible (printing))
    34273992    return;
    3428   }
    34293993
    34303994  addDingbatsResource = gFalse;
     
    34874051  type = typeMovie;
    34884052  initialize(xrefA, catalog, dict);
    3489 
    3490   movie = new Movie();
    3491   movie->parseAnnotMovie(this);
    34924053}
    34934054
     
    34954056  if (title)
    34964057    delete title;
    3497   if (fileName)
    3498     delete fileName;
    34994058  delete movie;
    3500 
    3501   if (posterStream && (!posterStream->decRef())) {
    3502     delete posterStream;
    3503   }
    35044059}
    35054060
     
    35154070
    35164071  Object movieDict;
    3517   Object aDict;
    3518 
    3519   // default values
    3520   fileName = NULL;
    3521   width = 0;
    3522   height = 0;
    3523   rotationAngle = 0;
    3524   rate = 1.0;
    3525   volume = 1.0;
    3526   showControls = false;
    3527   repeatMode = repeatModeOnce;
    3528   synchronousPlay = false;
    3529  
    3530   hasFloatingWindow = false;
    3531   isFullscreen = false;
    3532   FWScaleNum = 1;
    3533   FWScaleDenum = 1;
    3534   FWPosX = 0.5;
    3535   FWPosY = 0.5;
    3536 
    35374072  if (dict->lookup("Movie", &movieDict)->isDict()) {
    35384073    Object obj2;
    3539     if (getFileSpecNameForPlatform(movieDict.dictLookup("F", &obj1), &obj2)) {
    3540       fileName = obj2.getString()->copy();
    3541       obj2.free();
    3542     }
    3543     obj1.free();
    3544 
    3545     if (movieDict.dictLookup("Aspect", &obj1)->isArray()) {
    3546       Array* aspect = obj1.getArray();
    3547       if (aspect->getLength() >= 2) {
    3548         Object tmp;
    3549         if( aspect->get(0, &tmp)->isNum() ) {
    3550           width = (int)floor( aspect->get(0, &tmp)->getNum() + 0.5 );
    3551         }
    3552         tmp.free();
    3553         if( aspect->get(1, &tmp)->isNum() ) {
    3554           height = (int)floor( aspect->get(1, &tmp)->getNum() + 0.5 );
    3555         }
    3556         tmp.free();
    3557       }
    3558     }
    3559     obj1.free();
    3560 
    3561     if (movieDict.dictLookup("Rotate", &obj1)->isInt()) {
    3562       // round up to 90°
    3563       rotationAngle = (((obj1.getInt() + 360) % 360) % 90) * 90;
    3564     }
    3565     obj1.free();
    3566 
    3567     //
    3568     // movie poster
    3569     //
    3570     posterType = posterTypeNone;
    3571     posterStream = NULL;
    3572     if (!movieDict.dictLookup("Poster", &obj1)->isNone()) {
    3573       if (obj1.isBool()) {
    3574         GBool v = obj1.getBool();
    3575         if (v)
    3576           posterType = posterTypeFromMovie;
    3577       }
    3578      
    3579       if (obj1.isStream()) {
    3580         posterType = posterTypeStream;
    3581        
    3582         // "copy" stream
    3583         posterStream = obj1.getStream();
    3584         posterStream->incRef();
    3585       }
    3586 
    3587       obj1.free();
    3588     }
    3589 
     4074    dict->lookup("A", &obj2);
     4075    if (obj2.isDict())
     4076      movie = new Movie (&movieDict, &obj2);
     4077    else
     4078      movie = new Movie (&movieDict);
     4079    if (!movie->isOk()) {
     4080      delete movie;
     4081      movie = NULL;
     4082      ok = gFalse;
     4083    }
     4084    obj2.free();
     4085  } else {
     4086    error(-1, "Bad Annot Movie");
     4087    ok = gFalse;
    35904088  }
    35914089  movieDict.free();
    3592 
    3593 
    3594   // activation dictionary parsing ...
    3595 
    3596   if (dict->lookup("A", &aDict)->isDict()) {
    3597     if (!aDict.dictLookup("Start", &obj1)->isNone()) {
    3598       if (obj1.isInt()) {
    3599         // If it is representable as an integer (subject to the implementation limit for
    3600         // integers, as described in Appendix C), it should be specified as such.
    3601 
    3602         start.units = obj1.getInt();
    3603       }
    3604       if (obj1.isString()) {
    3605         // If it is not representable as an integer, it should be specified as an 8-byte
    3606         // string representing a 64-bit twos-complement integer, most significant
    3607         // byte first.
    3608 
    3609         // UNSUPPORTED
    3610       }
    3611 
    3612       if (obj1.isArray()) {
    3613         Array* a = obj1.getArray();
    3614 
    3615         Object tmp;
    3616         a->get(0, &tmp);
    3617         if (tmp.isInt()) {
    3618           start.units = tmp.getInt();
    3619         }
    3620         if (tmp.isString()) {
    3621           // UNSUPPORTED
    3622         }
    3623         tmp.free();
    3624 
    3625         a->get(1, &tmp);
    3626         if (tmp.isInt()) {
    3627           start.units_per_second = tmp.getInt();
    3628         }
    3629         tmp.free();
    3630       }
    3631     }
    3632     obj1.free();
    3633 
    3634     if (!aDict.dictLookup("Duration", &obj1)->isNone()) {
    3635       if (obj1.isInt()) {
    3636         duration.units = obj1.getInt();
    3637       }
    3638       if (obj1.isString()) {
    3639         // UNSUPPORTED
    3640       }
    3641 
    3642       if (obj1.isArray()) {
    3643         Array* a = obj1.getArray();
    3644 
    3645         Object tmp;
    3646         a->get(0, &tmp);
    3647         if (tmp.isInt()) {
    3648           duration.units = tmp.getInt();
    3649         }
    3650         if (tmp.isString()) {
    3651           // UNSUPPORTED
    3652         }
    3653         tmp.free();
    3654 
    3655         a->get(1, &tmp);
    3656         if (tmp.isInt()) {
    3657           duration.units_per_second = tmp.getInt();
    3658         }
    3659         tmp.free();
    3660       }
    3661     }
    3662     obj1.free();
    3663 
    3664     if (aDict.dictLookup("Rate", &obj1)->isNum()) {
    3665       rate = obj1.getNum();
    3666     }
    3667     obj1.free();
    3668 
    3669     if (aDict.dictLookup("Volume", &obj1)->isNum()) {
    3670       volume = obj1.getNum();
    3671     }
    3672     obj1.free();
    3673 
    3674     if (aDict.dictLookup("ShowControls", &obj1)->isBool()) {
    3675       showControls = obj1.getBool();
    3676     }
    3677     obj1.free();
    3678 
    3679     if (aDict.dictLookup("Synchronous", &obj1)->isBool()) {
    3680       synchronousPlay = obj1.getBool();
    3681     }
    3682     obj1.free();
    3683 
    3684     if (aDict.dictLookup("Mode", &obj1)->isName()) {
    3685       char* name = obj1.getName();
    3686       if (!strcmp(name, "Once"))
    3687         repeatMode = repeatModeOnce;
    3688       if (!strcmp(name, "Open"))
    3689         repeatMode = repeatModeOpen;
    3690       if (!strcmp(name, "Repeat"))
    3691         repeatMode = repeatModeRepeat;
    3692       if (!strcmp(name,"Palindrome"))
    3693         repeatMode = repeatModePalindrome;
    3694     }
    3695     obj1.free();
    3696 
    3697     if (aDict.dictLookup("FWScale", &obj1)->isArray()) {
    3698       // the presence of that entry implies that the movie is to be played
    3699       // in a floating window
    3700       hasFloatingWindow = true;
    3701 
    3702       Array* scale = obj1.getArray();
    3703       if (scale->getLength() >= 2) {
    3704         Object tmp;
    3705         if (scale->get(0, &tmp)->isInt()) {
    3706           FWScaleNum = tmp.getInt();
    3707         }
    3708         tmp.free();
    3709         if (scale->get(1, &tmp)->isInt()) {
    3710           FWScaleDenum = tmp.getInt();
    3711         }
    3712         tmp.free();
    3713       }
    3714 
    3715       // detect fullscreen mode
    3716       if ((FWScaleNum == 999) && (FWScaleDenum == 1)) {
    3717         isFullscreen = true;
    3718       }
    3719     }
    3720     obj1.free();
    3721 
    3722     if (aDict.dictLookup("FWPosition", &obj1)->isArray()) {
    3723       Array* pos = obj1.getArray();
    3724       if (pos->getLength() >= 2) {
    3725         Object tmp;
    3726         if (pos->get(0, &tmp)->isNum()) {
    3727           FWPosX = tmp.getNum();
    3728         }
    3729         tmp.free();
    3730         if (pos->get(1, &tmp)->isNum()) {
    3731           FWPosY = tmp.getNum();
    3732         }
    3733         tmp.free();
    3734       }
    3735     }
    3736   }
    3737   aDict.free();
    3738 }
    3739 
    3740 void AnnotMovie::getMovieSize(int& width, int& height) {
    3741   width = this->width;
    3742   height = this->height;
    3743 }
    3744 
    3745 void AnnotMovie::getZoomFactor(int& num, int& denum) {
    3746   num = FWScaleNum;
    3747   denum = FWScaleDenum;
    3748 }
    3749 
     4090}
     4091
     4092void AnnotMovie::draw(Gfx *gfx, GBool printing) {
     4093  Object obj;
     4094
     4095  if (!isVisible (printing))
     4096    return;
     4097
     4098  if (appearance.isNull() && movie->getShowPoster()) {
     4099    int width, height;
     4100    Object poster;
     4101    movie->getPoster(&poster);
     4102    movie->getAspect(&width, &height);
     4103
     4104    if (width != -1 && height != -1 && !poster.isNone()) {
     4105      MemStream *mStream;
     4106
     4107      appearBuf = new GooString ();
     4108      appearBuf->append ("q\n");
     4109      appearBuf->appendf ("{0:d} 0 0 {1:d} 0 0 cm\n", width, height);
     4110      appearBuf->append ("/MImg Do\n");
     4111      appearBuf->append ("Q\n");
     4112
     4113      Object imgDict;
     4114      imgDict.initDict(xref);
     4115      imgDict.dictSet ("MImg", &poster);
     4116
     4117      Object resDict;
     4118      resDict.initDict(xref);
     4119      resDict.dictSet ("XObject", &imgDict);
     4120
     4121      Object formDict, obj1, obj2;
     4122      formDict.initDict(xref);
     4123      formDict.dictSet("Length", obj1.initInt(appearBuf->getLength()));
     4124      formDict.dictSet("Subtype", obj1.initName("Form"));
     4125      formDict.dictSet("Name", obj1.initName("FRM"));
     4126      obj1.initArray(xref);
     4127      obj1.arrayAdd(obj2.initInt(0));
     4128      obj1.arrayAdd(obj2.initInt(0));
     4129      obj1.arrayAdd(obj2.initInt(width));
     4130      obj1.arrayAdd(obj2.initInt(height));
     4131      formDict.dictSet("BBox", &obj1);
     4132      obj1.initArray(xref);
     4133      obj1.arrayAdd(obj2.initInt(1));
     4134      obj1.arrayAdd(obj2.initInt(0));
     4135      obj1.arrayAdd(obj2.initInt(0));
     4136      obj1.arrayAdd(obj2.initInt(1));
     4137      obj1.arrayAdd(obj2.initInt(-width / 2));
     4138      obj1.arrayAdd(obj2.initInt(-height / 2));
     4139      formDict.dictSet("Matrix", &obj1);
     4140      formDict.dictSet("Resources", &resDict);
     4141
     4142      Object aStream;
     4143      mStream = new MemStream(copyString(appearBuf->getCString()), 0,
     4144                              appearBuf->getLength(), &formDict);
     4145      mStream->setNeedFree(gTrue);
     4146      aStream.initStream(mStream);
     4147      delete appearBuf;
     4148
     4149      Object objDict;
     4150      objDict.initDict(xref);
     4151      objDict.dictSet ("FRM", &aStream);
     4152
     4153      resDict.initDict(xref);
     4154      resDict.dictSet ("XObject", &objDict);
     4155
     4156      appearBuf = new GooString ();
     4157      appearBuf->append ("q\n");
     4158      appearBuf->appendf ("0 0 {0:d} {1:d} re W n\n", width, height);
     4159      appearBuf->append ("q\n");
     4160      appearBuf->appendf ("0 0 {0:d} {1:d} re W n\n", width, height);
     4161      appearBuf->appendf ("1 0 0 1 {0:d} {1:d} cm\n", width / 2, height / 2);
     4162      appearBuf->append ("/FRM Do\n");
     4163      appearBuf->append ("Q\n");
     4164      appearBuf->append ("Q\n");
     4165
     4166      double bbox[4];
     4167      bbox[0] = bbox[1] = 0;
     4168      bbox[2] = width;
     4169      bbox[3] = height;
     4170      createForm(bbox, gFalse, &resDict, &appearance);
     4171      delete appearBuf;
     4172    }
     4173    poster.free();
     4174  }
     4175
     4176  // draw the appearance stream
     4177  appearance.fetch(xref, &obj);
     4178  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
     4179                 rect->x1, rect->y1, rect->x2, rect->y2);
     4180  obj.free();
     4181}
    37504182
    37514183//------------------------------------------------------------------------
     
    37734205  if (appearCharacs)
    37744206    delete appearCharacs;
    3775 
    3776   action.free();
     4207  if (action)
     4208    delete action;
     4209
    37774210  additionAction.free();
    37784211}
     
    37874220  obj1.free();
    37884221
    3789   dict->lookup("A", &action);
     4222  action = NULL;
     4223  if (dict->lookup("A", &obj1)->isDict()) {
     4224    action = LinkAction::parseAction(&obj1, catalog->getBaseURI());
     4225    if (action->getKind() == actionRendition && page == 0) {
     4226      error (-1, "Invalid Rendition action: associated screen annotation without P");
     4227      delete action;
     4228      action = NULL;
     4229      ok = gFalse;
     4230    }
     4231  }
    37904232
    37914233  dict->lookup("AA", &additionAction);
     
    39004342  obj1.free();
    39014343
     4344}
     4345
     4346void AnnotGeometry::draw(Gfx *gfx, GBool printing) {
     4347  Object obj;
     4348  double ca = 1;
     4349
     4350  if (!isVisible (printing))
     4351    return;
     4352
     4353  if (appearance.isNull()) {
     4354    ca = opacity;
     4355
     4356    appearBuf = new GooString ();
     4357    appearBuf->append ("q\n");
     4358    if (color)
     4359      setColor(color, gFalse);
     4360
     4361    if (border) {
     4362      int i, dashLength;
     4363      double *dash;
     4364
     4365      switch (border->getStyle()) {
     4366      case AnnotBorder::borderDashed:
     4367        appearBuf->append("[");
     4368        dashLength = border->getDashLength();
     4369        dash = border->getDash();
     4370        for (i = 0; i < dashLength; ++i)
     4371          appearBuf->appendf(" {0:.2f}", dash[i]);
     4372        appearBuf->append(" ] 0 d\n");
     4373        break;
     4374      default:
     4375        appearBuf->append("[] 0 d\n");
     4376        break;
     4377      }
     4378      appearBuf->appendf("{0:.2f} w\n", border->getWidth());
     4379    }
     4380
     4381    if (interiorColor)
     4382      setColor(interiorColor, gTrue);
     4383
     4384    if (type == typeSquare) {
     4385      appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} re\n",
     4386                          border->getWidth() / 2.0, border->getWidth() / 2.0,
     4387                          (rect->x2 - rect->x1) - border->getWidth(),
     4388                          (rect->y2 - rect->y1) - border->getWidth());
     4389    } else {
     4390      double width, height;
     4391      double b;
     4392      double x1, y1, x2, y2, x3, y3;
     4393
     4394      width = rect->x2 - rect->x1;
     4395      height = rect->y2 - rect->y1;
     4396      b = border->getWidth() / 2.0;
     4397
     4398      x1 = b;
     4399      y1 = height / 2.0;
     4400      appearBuf->appendf ("{0:.2f} {1:.2f} m\n", x1, y1);
     4401
     4402      y1 += height / 4.0;
     4403      x2 = width / 4.0;
     4404      y2 = height - b;
     4405      x3 = width / 2.0;
     4406      y3 = y2;
     4407      appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
     4408                          x1, y1, x2, y2, x3, y3);
     4409      x2 = width - b;
     4410      y2 = y1;
     4411      x1 = x3 + (width / 4.0);
     4412      y1 = y3;
     4413      x3 = x2;
     4414      y3 = height / 2.0;
     4415      appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
     4416                          x1, y1, x2, y2, x3, y3);
     4417
     4418      x2 = x1;
     4419      y2 = b;
     4420      x1 = x3;
     4421      y1 = height / 4.0;
     4422      x3 = width / 2.0;
     4423      y3 = b;
     4424      appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
     4425                          x1, y1, x2, y2, x3, y3);
     4426
     4427      x2 = b;
     4428      y2 = y1;
     4429      x1 = width / 4.0;
     4430      y1 = b;
     4431      x3 = b;
     4432      y3 = height / 2.0;
     4433      appearBuf->appendf ("{0:.2f} {1:.2f} {2:.2f} {3:.2f} {4:.2f} {5:.2f} c\n",
     4434                          x1, y1, x2, y2, x3, y3);
     4435
     4436    }
     4437
     4438    if (interiorColor)
     4439      appearBuf->append ("b\n");
     4440    else
     4441      appearBuf->append ("S\n");
     4442    appearBuf->append ("Q\n");
     4443
     4444    double bbox[4];
     4445    bbox[0] = bbox[1] = 0;
     4446    bbox[2] = rect->x2 - rect->x1;
     4447    bbox[3] = rect->y2 - rect->y1;
     4448    if (ca == 1) {
     4449      createForm(bbox, gFalse, NULL, &appearance);
     4450    } else {
     4451      Object aStream;
     4452
     4453      createForm(bbox, gTrue, NULL, &aStream);
     4454      delete appearBuf;
     4455
     4456      Object resDict;
     4457      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
     4458      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
     4459      createForm(bbox, gFalse, &resDict, &appearance);
     4460    }
     4461    delete appearBuf;
     4462  }
     4463
     4464  // draw the appearance stream
     4465  appearance.fetch(xref, &obj);
     4466  gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
     4467                 rect->x1, rect->y1, rect->x2, rect->y2);
     4468  obj.free();
    39024469}
    39034470
     
    41934760}
    41944761
     4762#define ANNOT_FILE_ATTACHMENT_AP_PUSHPIN                                         \
     4763  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"       \
     4764  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"     \
     4765  "l 1 21.523 2.477 23 4.301 23 c h\n"                                           \
     4766  "4.301 23 m f\n"                                                               \
     4767  "0.533333 0.541176 0.521569 RG 2 w\n"                                          \
     4768  "1 J\n"                                                                        \
     4769  "1 j\n"                                                                        \
     4770  "[] 0.0 d\n"                                                                   \
     4771  "4 M 5 4 m 6 5 l S\n"                                                          \
     4772  "2 w\n"                                                                        \
     4773  "11 14 m 9 12 l 6 12 l 13 5 l 13 8 l 15 10 l 18 11 l 20 11 l 12 19 l 12\n"     \
     4774  "17 l 11 14 l h\n"                                                             \
     4775  "11 14 m S\n"                                                                  \
     4776  "3 w\n"                                                                        \
     4777  "6 5 m 9 8 l S\n"                                                              \
     4778  "0.729412 0.741176 0.713725 RG 2 w\n"                                          \
     4779  "5 5 m 6 6 l S\n"                                                              \
     4780  "2 w\n"                                                                        \
     4781  "11 15 m 9 13 l 6 13 l 13 6 l 13 9 l 15 11 l 18 12 l 20 12 l 12 20 l 12\n"     \
     4782  "18 l 11 15 l h\n"                                                             \
     4783  "11 15 m S\n"                                                                  \
     4784  "3 w\n"                                                                        \
     4785  "6 6 m 9 9 l S\n"
     4786
     4787#define ANNOT_FILE_ATTACHMENT_AP_PAPERCLIP                                       \
     4788  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"       \
     4789  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"     \
     4790  "l 1 21.523 2.477 23 4.301 23 c h\n"                                           \
     4791  "4.301 23 m f\n"                                                               \
     4792  "0.533333 0.541176 0.521569 RG 2 w\n"                                          \
     4793  "1 J\n"                                                                        \
     4794  "1 j\n"                                                                        \
     4795  "[] 0.0 d\n"                                                                   \
     4796  "4 M 16.645 12.035 m 12.418 7.707 l 10.902 6.559 6.402 11.203 8.09 12.562 c\n" \
     4797  "14.133 18.578 l 14.949 19.387 16.867 19.184 17.539 18.465 c 20.551\n"         \
     4798  "15.23 l 21.191 14.66 21.336 12.887 20.426 12.102 c 13.18 4.824 l 12.18\n"     \
     4799  "3.82 6.25 2.566 4.324 4.461 c 3 6.395 3.383 11.438 4.711 12.801 c 9.648\n"    \
     4800  "17.887 l S\n"                                                                 \
     4801  "0.729412 0.741176 0.713725 RG 16.645 13.035 m 12.418 8.707 l\n"               \
     4802  "10.902 7.559 6.402 12.203 8.09 13.562 c\n"                                    \
     4803  "14.133 19.578 l 14.949 20.387 16.867 20.184 17.539 19.465 c 20.551\n"         \
     4804  "16.23 l 21.191 15.66 21.336 13.887 20.426 13.102 c 13.18 5.824 l 12.18\n"     \
     4805  "4.82 6.25 3.566 4.324 5.461 c 3 7.395 3.383 12.438 4.711 13.801 c 9.648\n"    \
     4806  "18.887 l S\n"
     4807
     4808#define ANNOT_FILE_ATTACHMENT_AP_GRAPH                                           \
     4809  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"       \
     4810  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"     \
     4811  "l 1 21.523 2.477 23 4.301 23 c h\n"                                           \
     4812  "4.301 23 m f\n"                                                               \
     4813  "0.533333 0.541176 0.521569 RG 1 w\n"                                          \
     4814  "1 J\n"                                                                        \
     4815  "0 j\n"                                                                        \
     4816  "[] 0.0 d\n"                                                                   \
     4817  "4 M 18.5 15.5 m 18.5 13.086 l 16.086 15.5 l 18.5 15.5 l h\n"                  \
     4818  "18.5 15.5 m S\n"                                                              \
     4819  "7 7 m 10 11 l 13 9 l 18 15 l S\n"                                             \
     4820  "0.729412 0.741176 0.713725 RG 7 8 m 10 12 l 13 10 l 18 16 l S\n"              \
     4821  "18.5 16.5 m 18.5 14.086 l 16.086 16.5 l 18.5 16.5 l h\n"                      \
     4822  "18.5 16.5 m S\n"                                                              \
     4823  "0.533333 0.541176 0.521569 RG 2 w\n"                                          \
     4824  "1 j\n"                                                                        \
     4825  "3 19 m 3 3 l 21 3 l S\n"                                                      \
     4826  "0.729412 0.741176 0.713725 RG 3 20 m 3 4 l 21 4 l S\n"
     4827
     4828#define ANNOT_FILE_ATTACHMENT_AP_TAG                                             \
     4829  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"       \
     4830  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"     \
     4831  "l 1 21.523 2.477 23 4.301 23 c h\n"                                           \
     4832  "4.301 23 m f\n"                                                               \
     4833  "0.533333 0.541176 0.521569 RG 0.999781 w\n"                                   \
     4834  "1 J\n"                                                                        \
     4835  "1 j\n"                                                                        \
     4836  "[] 0.0 d\n"                                                                   \
     4837  "4 M q 1 0 0 -1 0 24 cm\n"                                                     \
     4838  "8.492 8.707 m 8.492 9.535 7.82 10.207 6.992 10.207 c 6.164 10.207 5.492\n"    \
     4839  "9.535 5.492 8.707 c 5.492 7.879 6.164 7.207 6.992 7.207 c 7.82 7.207\n"       \
     4840  "8.492 7.879 8.492 8.707 c h\n"                                                \
     4841  "8.492 8.707 m S Q\n"                                                          \
     4842  "2 w\n"                                                                        \
     4843  "20.078 11.414 m 20.891 10.602 20.785 9.293 20.078 8.586 c 14.422 2.93 l\n"    \
     4844  "13.715 2.223 12.301 2.223 11.594 2.93 c 3.816 10.707 l 3.109 11.414\n"        \
     4845  "2.402 17.781 3.816 19.195 c 5.23 20.609 11.594 19.902 12.301 19.195 c\n"      \
     4846  "20.078 11.414 l h\n"                                                          \
     4847  "20.078 11.414 m S\n"                                                          \
     4848  "0.729412 0.741176 0.713725 RG 20.078 12.414 m\n"                              \
     4849  "20.891 11.605 20.785 10.293 20.078 9.586 c 14.422 3.93 l\n"                   \
     4850  "13.715 3.223 12.301 3.223 11.594 3.93 c 3.816 11.707 l 3.109 12.414\n"        \
     4851  "2.402 18.781 3.816 20.195 c 5.23 21.609 11.594 20.902 12.301 20.195 c\n"      \
     4852  "20.078 12.414 l h\n"                                                          \
     4853  "20.078 12.414 m S\n"                                                          \
     4854  "0.533333 0.541176 0.521569 RG 1 w\n"                                          \
     4855  "0 j\n"                                                                        \
     4856  "11.949 13.184 m 16.191 8.941 l S\n"                                           \
     4857  "0.729412 0.741176 0.713725 RG 11.949 14.184 m 16.191 9.941 l S\n"             \
     4858  "0.533333 0.541176 0.521569 RG 14.07 6.82 m 9.828 11.062 l S\n"                \
     4859  "0.729412 0.741176 0.713725 RG 14.07 7.82 m 9.828 12.062 l S\n"                \
     4860  "0.533333 0.541176 0.521569 RG 6.93 15.141 m 8 20 14.27 20.5 16 20.5 c\n"      \
     4861  "18.094 20.504 19.5 20 19.5 18 c 19.5 16.699 20.91 16.418 22.5 16.5 c S\n"     \
     4862  "0.729412 0.741176 0.713725 RG 0.999781 w\n"                                   \
     4863  "1 j\n"                                                                        \
     4864  "q 1 0 0 -1 0 24 cm\n"                                                         \
     4865  "8.492 7.707 m 8.492 8.535 7.82 9.207 6.992 9.207 c 6.164 9.207 5.492\n"       \
     4866  "8.535 5.492 7.707 c 5.492 6.879 6.164 6.207 6.992 6.207 c 7.82 6.207\n"       \
     4867  "8.492 6.879 8.492 7.707 c h\n"                                                \
     4868  "8.492 7.707 m S Q\n"                                                          \
     4869  "1 w\n"                                                                        \
     4870  "0 j\n"                                                                        \
     4871  "6.93 16.141 m 8 21 14.27 21.5 16 21.5 c 18.094 21.504 19.5 21 19.5 19 c\n"    \
     4872  "19.5 17.699 20.91 17.418 22.5 17.5 c S\n"
     4873
     4874void AnnotFileAttachment::draw(Gfx *gfx, GBool printing) {
     4875  Object obj;
     4876  double ca = 1;
     4877
     4878  if (!isVisible (printing))
     4879    return;
     4880
     4881  if (appearance.isNull()) {
     4882    ca = opacity;
     4883
     4884    appearBuf = new GooString ();
     4885
     4886    appearBuf->append ("q\n");
     4887    if (color)
     4888      setColor(color, gTrue);
     4889    else
     4890      appearBuf->append ("1 1 1 rg\n");
     4891    if (!name->cmp("PushPin"))
     4892      appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_PUSHPIN);
     4893    else if (!name->cmp("Paperclip"))
     4894      appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_PAPERCLIP);
     4895    else if (!name->cmp("Graph"))
     4896      appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_GRAPH);
     4897    else if (!name->cmp("Tag"))
     4898      appearBuf->append (ANNOT_FILE_ATTACHMENT_AP_TAG);
     4899    appearBuf->append ("Q\n");
     4900
     4901    double bbox[4];
     4902    bbox[0] = bbox[1] = 0;
     4903    bbox[2] = bbox[3] = 24;
     4904    if (ca == 1) {
     4905      createForm (bbox, gFalse, NULL, &appearance);
     4906    } else {
     4907      Object aStream;
     4908
     4909      createForm (bbox, gTrue, NULL, &aStream);
     4910      delete appearBuf;
     4911
     4912      Object resDict;
     4913      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
     4914      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
     4915      createForm(bbox, gFalse, &resDict, &appearance);
     4916    }
     4917    delete appearBuf;
     4918  }
     4919
     4920  // draw the appearance stream
     4921  appearance.fetch(xref, &obj);
     4922  gfx->drawAnnot(&obj, border, color,
     4923                 rect->x1, rect->y1, rect->x2, rect->y2);
     4924  obj.free();
     4925}
     4926
    41954927//------------------------------------------------------------------------
    41964928// AnnotSound
     
    42414973  }
    42424974  obj1.free();
     4975}
     4976
     4977#define ANNOT_SOUND_AP_SPEAKER                                               \
     4978  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"   \
     4979  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n" \
     4980  "l 1 21.523 2.477 23 4.301 23 c h\n"                                       \
     4981  "4.301 23 m f\n"                                                           \
     4982  "0.533333 0.541176 0.521569 RG 2 w\n"                                      \
     4983  "0 J\n"                                                                    \
     4984  "1 j\n"                                                                    \
     4985  "[] 0.0 d\n"                                                               \
     4986  "4 M 4 14 m 4.086 8.043 l 7 8 l 11 4 l 11 18 l 7 14 l 4 14 l h\n"          \
     4987  "4 14 m S\n"                                                               \
     4988  "1 w\n"                                                                    \
     4989  "1 J\n"                                                                    \
     4990  "0 j\n"                                                                    \
     4991  "13.699 15.398 m 14.699 13.398 14.699 9.398 13.699 7.398 c S\n"            \
     4992  "18.199 19.398 m 21.199 17.398 21.199 5.398 18.199 3.398 c S\n"            \
     4993  "16 17.398 m 18 16.398 18 7.398 16 5.398 c S\n"                            \
     4994  "0.729412 0.741176 0.713725 RG 2 w\n"                                      \
     4995  "0 J\n"                                                                    \
     4996  "1 j\n"                                                                    \
     4997  "4 15 m 4.086 9.043 l 7 9 l 11 5 l 11 19 l 7 15 l 4 15 l h\n"              \
     4998  "4 15 m S\n"                                                               \
     4999  "1 w\n"                                                                    \
     5000  "1 J\n"                                                                    \
     5001  "0 j\n"                                                                    \
     5002  "13.699 16 m 14.699 14 14.699 10 13.699 8 c S\n"                           \
     5003  "18.199 20 m 21.199 18 21.199 6 18.199 4 c S\n"                            \
     5004  "16 18 m 18 17 18 8 16 6 c S\n"
     5005
     5006#define ANNOT_SOUND_AP_MIC                                                        \
     5007  "4.301 23 m 19.699 23 l 21.523 23 23 21.523 23 19.699 c 23 4.301 l 23\n"        \
     5008  "2.477 21.523 1 19.699 1 c 4.301 1 l 2.477 1 1 2.477 1 4.301 c 1 19.699\n"      \
     5009  "l 1 21.523 2.477 23 4.301 23 c h\n"                                            \
     5010  "4.301 23 m f\n"                                                                \
     5011  "0.533333 0.541176 0.521569 RG 2 w\n"                                           \
     5012  "1 J\n"                                                                         \
     5013  "0 j\n"                                                                         \
     5014  "[] 0.0 d\n"                                                                    \
     5015  "4 M 12 20 m 12 20 l 13.656 20 15 18.656 15 17 c 15 13 l 15 11.344 13.656 10\n" \
     5016  "12 10 c 12 10 l 10.344 10 9 11.344 9 13 c 9 17 l 9 18.656 10.344 20 12\n"      \
     5017  "20 c h\n"                                                                      \
     5018  "12 20 m S\n"                                                                   \
     5019  "1 w\n"                                                                         \
     5020  "17.5 14.5 m 17.5 11.973 l 17.5 8.941 15.047 6.5 12 6.5 c 8.953 6.5 6.5\n"      \
     5021  "8.941 6.5 11.973 c 6.5 14.5 l S\n"                                             \
     5022  "2 w\n"                                                                         \
     5023  "0 J\n"                                                                         \
     5024  "12 6.52 m 12 3 l S\n"                                                          \
     5025  "1 J\n"                                                                         \
     5026  "8 3 m 16 3 l S\n"                                                              \
     5027  "0.729412 0.741176 0.713725 RG 12 21 m 12 21 l 13.656 21 15 19.656 15 18 c\n"   \
     5028  "15 14 l 15 12.344 13.656 11 12 11 c 12 11 l 10.344 11 9 12.344 9 14 c\n"       \
     5029  "9 18 l 9 19.656 10.344 21 12 21 c h\n"                                         \
     5030  "12 21 m S\n"                                                                   \
     5031  "1 w\n"                                                                         \
     5032  "17.5 15.5 m 17.5 12.973 l 17.5 9.941 15.047 7.5 12 7.5 c 8.953 7.5 6.5\n"      \
     5033  "9.941 6.5 12.973 c 6.5 15.5 l S\n"                                             \
     5034  "2 w\n"                                                                         \
     5035  "0 J\n"                                                                         \
     5036  "12 7.52 m 12 4 l S\n"                                                          \
     5037  "1 J\n"                                                                         \
     5038  "8 4 m 16 4 l S\n"
     5039
     5040void AnnotSound::draw(Gfx *gfx, GBool printing) {
     5041  Object obj;
     5042  double ca = 1;
     5043
     5044  if (!isVisible (printing))
     5045    return;
     5046
     5047  if (appearance.isNull()) {
     5048    ca = opacity;
     5049
     5050    appearBuf = new GooString ();
     5051
     5052    appearBuf->append ("q\n");
     5053    if (color)
     5054      setColor(color, gTrue);
     5055    else
     5056      appearBuf->append ("1 1 1 rg\n");
     5057    if (!name->cmp("Speaker"))
     5058      appearBuf->append (ANNOT_SOUND_AP_SPEAKER);
     5059    else if (!name->cmp("Mic"))
     5060      appearBuf->append (ANNOT_SOUND_AP_MIC);
     5061    appearBuf->append ("Q\n");
     5062
     5063    double bbox[4];
     5064    bbox[0] = bbox[1] = 0;
     5065    bbox[2] = bbox[3] = 24;
     5066    if (ca == 1) {
     5067      createForm(bbox, gFalse, NULL, &appearance);
     5068    } else {
     5069      Object aStream, resDict;
     5070
     5071      createForm(bbox, gTrue, NULL, &aStream);
     5072      delete appearBuf;
     5073
     5074      appearBuf = new GooString ("/GS0 gs\n/Fm0 Do");
     5075      createResourcesDict("Fm0", &aStream, "GS0", ca, NULL, &resDict);
     5076      createForm(bbox, gFalse, &resDict, &appearance);
     5077    }
     5078    delete appearBuf;
     5079  }
     5080
     5081  // draw the appearance stream
     5082  appearance.fetch(xref, &obj);
     5083  gfx->drawAnnot(&obj, border, color,
     5084                 rect->x1, rect->y1, rect->x2, rect->y2);
     5085  obj.free();
    42435086}
    42445087
  • trunk/poppler/mypoppler/poppler/Annot.h

    r277 r461  
    1616// Copyright (C) 2006 Scott Turner <scotty1024@mac.com>
    1717// Copyright (C) 2007, 2008 Julien Rebetez <julienr@svn.gnome.org>
    18 // Copyright (C) 2007-2009 Carlos Garcia Campos <carlosgc@gnome.org>
     18// Copyright (C) 2007-2010 Carlos Garcia Campos <carlosgc@gnome.org>
    1919// Copyright (C) 2007, 2008 Iñigo Martínez <inigomartinez@gmail.com>
    2020// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
     
    4646class PDFRectangle;
    4747class Movie;
     48class LinkAction;
    4849class OCGs;
    4950class Sound;
     
    291292  AnnotColor(double r, double g, double b);
    292293  AnnotColor(double c, double m, double y, double k);
    293   AnnotColor(Array *array);
    294   ~AnnotColor();
     294  AnnotColor(Array *array, int adjust = 0);
    295295
    296296  AnnotColorSpace getSpace() const { return (AnnotColorSpace) length; }
    297   double *getValues() const { return values; }
    298 
    299 private:
    300 
    301   double *values;
     297  const double *getValues() const { return values; }
     298
     299private:
     300
     301  double values[4];
    302302  int length;
    303303};
     
    515515  PDFRectangle *getRect() const { return rect; }
    516516  GooString *getContents() const { return contents; }
    517   Dict *getPageDict() const { return pageDict; }
     517  int getPageNum() const { return page; }
    518518  GooString *getName() const { return name; }
    519519  GooString *getModified() const { return modified; }
     
    535535
    536536protected:
    537   void setColor(Array *a, GBool fill, int adjust);
     537  void setColor(AnnotColor *color, GBool fill);
    538538  void drawCircle(double cx, double cy, double r, GBool fill);
    539539  void drawCircleTopLeft(double cx, double cy, double r);
    540540  void drawCircleBottomRight(double cx, double cy, double r);
     541  void createForm(double *bbox, GBool transparencyGroup, Object *resDict, Object *aStream);
     542  void createResourcesDict(char *formName, Object *formStream, char *stateName,
     543                           double opacity, char *blendMode, Object *resDict);
     544  GBool isVisible(GBool printing);
    541545
    542546  // Updates the field key of the annotation dictionary
     
    552556  // optional data
    553557  GooString *contents;              // Contents
    554   Dict *pageDict;                   // P
     558  int       page;                   // P
    555559  GooString *name;                  // NM
    556560  GooString *modified;              // M
     
    671675  ~AnnotText();
    672676
     677  virtual void draw(Gfx *gfx, GBool printing);
     678
    673679  // getters
    674680  GBool getOpen() const { return open; }
     
    698704class AnnotMovie: public Annot {
    699705 public:
    700   enum PosterType {
    701     posterTypeNone,
    702     posterTypeStream,
    703     posterTypeFromMovie
    704   };
    705 
    706   enum RepeatMode {
    707     repeatModeOnce,
    708     repeatModeOpen,
    709     repeatModeRepeat,
    710     repeatModePalindrome
    711   };
    712 
    713   struct Time {
    714     Time() { units_per_second = 0; }
    715     Gulong units;
    716     int units_per_second; // 0 : defined by movie
    717   };
    718 
    719706  AnnotMovie(XRef *xrefA, PDFRectangle *rect, Movie *movieA, Catalog *catalog);
    720707  AnnotMovie(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj);
    721708  ~AnnotMovie();
    722709
     710  virtual void draw(Gfx *gfx, GBool printing);
     711
    723712  GooString* getTitle() { return title; }
    724   GooString* getFileName() { return fileName; }
    725   int getRotationAngle() { return rotationAngle; }
    726 
    727   PosterType getPosterType() { return posterType; }
    728   Stream* getPosterStream() { return posterStream; }
    729 
    730   Time getStart() { return start; }
    731   Time getDuration() { return duration; }
    732   double getRate() { return rate; }
    733   double getVolume() { return volume; }
    734 
    735   GBool getShowControls() { return showControls; }
    736   RepeatMode getRepeatMode() { return repeatMode; }
    737   GBool getSynchronousPlay() { return synchronousPlay; }
    738 
    739   GBool needFloatingWindow() { return hasFloatingWindow; }
    740   GBool needFullscreen() { return isFullscreen; }
    741  
    742  
    743   void getMovieSize(int& width, int& height);
    744   void getZoomFactor(int& num, int& denum);
    745   void getWindowPosition(double& x, double& y) { x = FWPosX; y = FWPosY; }
    746 
    747713  Movie* getMovie() { return movie; }
    748714
     
    751717
    752718  GooString* title;      // T
    753   GooString* fileName;   // Movie/F
    754 
    755   int width;             // Movie/Aspect
    756   int height;            // Movie/Aspect
    757   int rotationAngle;     // Movie/Rotate
    758 
    759   PosterType posterType; // Movie/Poster
    760   Stream* posterStream;
    761 
    762   Time start;            // A/Start
    763   Time duration;         // A/Duration
    764   double rate;           // A/Rate
    765   double volume;         // A/Volume
    766  
    767   GBool showControls;    // A/ShowControls
    768  
    769   RepeatMode repeatMode; // A/Mode
    770  
    771   GBool synchronousPlay; // A/Synchronous
    772 
    773   // floating window
    774   GBool hasFloatingWindow;
    775   unsigned short FWScaleNum; // A/FWScale
    776   unsigned short FWScaleDenum;
    777   GBool isFullscreen;
    778 
    779   double FWPosX;         // A/FWPosition
    780   double FWPosY;
    781 
    782   Movie* movie;
     719  Movie* movie;          // Movie + A
    783720};
    784721
     
    798735
    799736  AnnotAppearanceCharacs *getAppearCharacs() { return appearCharacs; }
    800   Object* getAction() { return &action; }
     737  LinkAction* getAction() { return action; }
    801738  Object* getAdditionActions() { return &additionAction; }
    802739
     
    809746  AnnotAppearanceCharacs* appearCharacs; // MK
    810747
    811   Object action;                         // A
     748  LinkAction *action;                    // A
    812749  Object additionAction;                 // AA
    813750};
     
    926863  AnnotLine(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj);
    927864  ~AnnotLine();
     865
     866  virtual void draw(Gfx *gfx, GBool printing);
    928867
    929868  // getters
     
    981920  virtual ~AnnotTextMarkup();
    982921
     922  virtual void draw(Gfx *gfx, GBool printing);
     923
    983924  AnnotQuadrilaterals *getQuadrilaterals() const { return quadrilaterals; }
    984925
     
    1021962  AnnotGeometry(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj);
    1022963  ~AnnotGeometry();
     964
     965  virtual void draw(Gfx *gfx, GBool printing);
    1023966
    1024967  // getters
     
    11471090  ~AnnotFileAttachment();
    11481091
     1092  virtual void draw(Gfx *gfx, GBool printing);
     1093
    11491094  // getters
    11501095  Object *getFile() { return &file; }
     
    11721117  AnnotSound(XRef *xrefA, Dict *dict, Catalog *catalog, Object *obj);
    11731118  ~AnnotSound();
     1119
     1120  virtual void draw(Gfx *gfx, GBool printing);
    11741121
    11751122  // getters
  • trunk/poppler/mypoppler/poppler/ArthurOutputDev.cc

    r277 r461  
    1616// Copyright (C) 2005 Brad Hards <bradh@frogmouth.net>
    1717// Copyright (C) 2005-2009 Albert Astals Cid <aacid@kde.org>
    18 // Copyright (C) 2008 Pino Toscano <pino@kde.org>
     18// Copyright (C) 2008, 2010 Pino Toscano <pino@kde.org>
    1919// Copyright (C) 2009 Carlos Garcia Campos <carlosgc@gnome.org>
    2020// Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
     
    5050//------------------------------------------------------------------------
    5151
     52#ifdef HAVE_SPLASH
    5253#include "splash/SplashFontFileID.h"
    5354#include "splash/SplashFontFile.h"
     
    7879};
    7980
    80 
     81#endif
    8182
    8283//------------------------------------------------------------------------
     
    9596ArthurOutputDev::~ArthurOutputDev()
    9697{
     98#ifdef HAVE_SPLASH
    9799  delete m_fontEngine;
     100#endif
    98101}
    99102
    100103void ArthurOutputDev::startDoc(XRef *xrefA) {
    101104  xref = xrefA;
     105#ifdef HAVE_SPLASH
    102106  delete m_fontEngine;
    103107  m_fontEngine = new SplashFontEngine(
     
    110114#endif
    111115  m_painter->testRenderHint(QPainter::TextAntialiasing));
     116#endif
    112117}
    113118
     
    162167void ArthurOutputDev::updateLineDash(GfxState *state)
    163168{
    164   // qDebug() << "updateLineDash";
     169  double *dashPattern;
     170  int dashLength;
     171  double dashStart;
     172  state->getLineDash(&dashPattern, &dashLength, &dashStart);
     173  QVector<qreal> pattern(dashLength);
     174  for (int i = 0; i < dashLength; ++i) {
     175    pattern[i] = dashPattern[i];
     176  }
     177  m_currentPen.setDashPattern(pattern);
     178  m_currentPen.setDashOffset(dashStart);
     179  m_painter->setPen(m_currentPen);
    165180}
    166181
     
    204219void ArthurOutputDev::updateMiterLimit(GfxState *state)
    205220{
    206   // We can't do mitre (or Miter) limit with Qt4 yet.
    207   // the limit is in state->getMiterLimit() when we get there
     221  m_currentPen.setMiterLimit(state->getMiterLimit());
     222  m_painter->setPen(m_currentPen);
    208223}
    209224
     
    250265void ArthurOutputDev::updateFont(GfxState *state)
    251266{
     267#ifdef HAVE_SPLASH
    252268  GfxFont *gfxFont;
    253269  GfxFontType fontType;
     
    475491 err1:
    476492  return;
     493#endif
    477494}
    478495
     
    541558                               double originX, double originY,
    542559                               CharCode code, int nBytes, Unicode *u, int uLen) {
     560#ifdef HAVE_SPLASH
    543561  double x1, y1;
    544562//   SplashPath *path;
     
    583601          ++i;
    584602        }
    585 #ifdef __GNUC__
    586 #warning FIX THIS
    587 #endif
     603// FIXME fix this
    588604//      else if (fontPath->flags[i] & splashPathArcCW) {
    589605//        qDebug() << "Need to implement arc";
     
    637653    */
    638654  }
     655#endif
    639656}
    640657
  • trunk/poppler/mypoppler/poppler/ArthurOutputDev.h

    r277 r461  
    4343class SplashFont;
    4444class SplashFontEngine;
    45 class SplashGlyphBitmap;
     45struct SplashGlyphBitmap;
    4646
    4747//------------------------------------------------------------------------
  • trunk/poppler/mypoppler/poppler/CairoFontEngine.cc

    r290 r461  
    1919// Copyright (C) 2005 Martin Kretzschmar <martink@gnome.org>
    2020// Copyright (C) 2005, 2009 Albert Astals Cid <aacid@kde.org>
    21 // Copyright (C) 2006, 2007 Carlos Garcia Campos <carlosgc@gnome.org>
     21// Copyright (C) 2006, 2007, 2010 Carlos Garcia Campos <carlosgc@gnome.org>
    2222// Copyright (C) 2007 Koji Otani <sho@bbr.jp>
    2323// Copyright (C) 2008, 2009 Chris Wilson <chris@chris-wilson.co.uk>
    2424// Copyright (C) 2008 Adrian Johnson <ajohnson@redneon.com>
    2525// Copyright (C) 2009 Darren Kenny <darren.kenny@sun.com>
     26// Copyright (C) 2010 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
     27// Copyright (C) 2010 Jan KÃŒmmel <jan+freedesktop@snorc.org>
    2628//
    2729// To see a description of the changes please see the Changelog file that
     
    165167_ft_new_face_uncached (FT_Library lib,
    166168                       const char *filename,
     169                       char *font_data,
     170                       int font_data_len,
    167171                       FT_Face *face_out,
    168172                       cairo_font_face_t **font_face_out)
     
    171175  cairo_font_face_t *font_face;
    172176
    173   if (FT_New_Face (lib, filename, 0, &face))
    174     return gFalse;
     177  if (font_data == NULL) {
     178    if (FT_New_Face (lib, filename, 0, &face))
     179      return gFalse;
     180  } else {
     181    if (FT_New_Memory_Face (lib, (unsigned char *)font_data, font_data_len, 0, &face))
     182      return gFalse;
     183  }
    175184
    176185  font_face = cairo_ft_font_face_create_for_ft_face (face,
     
    257266_ft_new_face (FT_Library lib,
    258267              const char *filename,
     268              char *font_data,
     269              int font_data_len,
    259270              FT_Face *face_out,
    260271              cairo_font_face_t **font_face_out)
     
    264275  struct _ft_face_data tmpl;
    265276
    266   /* if we fail to mmap the file, just pass it to FreeType instead */
    267   tmpl.fd = open (filename, O_RDONLY);
    268   if (tmpl.fd == -1)
    269     return _ft_new_face_uncached (lib, filename, face_out, font_face_out);
    270 
    271   if (fstat (tmpl.fd, &st) == -1) {
    272     close (tmpl.fd);
    273     return _ft_new_face_uncached (lib, filename, face_out, font_face_out);
    274   }
    275 
    276   tmpl.bytes = (unsigned char *) mmap (NULL, st.st_size,
    277                                        PROT_READ, MAP_PRIVATE,
    278                                        tmpl.fd, 0);
    279   if (tmpl.bytes == MAP_FAILED) {
    280     close (tmpl.fd);
    281     return _ft_new_face_uncached (lib, filename, face_out, font_face_out);
     277  tmpl.fd = -1;
     278
     279  if (font_data == NULL) {
     280    /* if we fail to mmap the file, just pass it to FreeType instead */
     281    tmpl.fd = open (filename, O_RDONLY);
     282    if (tmpl.fd == -1)
     283      return _ft_new_face_uncached (lib, filename, font_data, font_data_len, face_out, font_face_out);
     284
     285    if (fstat (tmpl.fd, &st) == -1) {
     286      close (tmpl.fd);
     287      return _ft_new_face_uncached (lib, filename, font_data, font_data_len, face_out, font_face_out);
     288    }
     289
     290    tmpl.bytes = (unsigned char *) mmap (NULL, st.st_size,
     291                                         PROT_READ, MAP_PRIVATE,
     292                                         tmpl.fd, 0);
     293    if (tmpl.bytes == MAP_FAILED) {
     294      close (tmpl.fd);
     295      return _ft_new_face_uncached (lib, filename, font_data, font_data_len, face_out, font_face_out);
     296    }
     297    tmpl.size = st.st_size;
     298  } else {
     299    tmpl.bytes = (unsigned char*) font_data;
     300    tmpl.size = font_data_len;
    282301  }
    283302
    284303  /* check to see if this is a duplicate of any of the currently open fonts */
    285304  tmpl.lib = lib;
    286   tmpl.size = st.st_size;
    287305  tmpl.hash = _djb_hash (tmpl.bytes, tmpl.size);
    288306
    289307  for (l = _ft_open_faces; l; l = l->next) {
    290308    if (_ft_face_data_equal (l, &tmpl)) {
     309      if (tmpl.fd != -1) {
     310#if defined(__SUNPRO_CC) && defined(__sun) && defined(__SVR4)
     311        munmap ((char*)tmpl.bytes, tmpl.size);
     312#else
     313        munmap (tmpl.bytes, tmpl.size);
     314#endif
     315        close (tmpl.fd);
     316      }
     317      *face_out = l->face;
     318      *font_face_out = cairo_font_face_reference (l->font_face);
     319      return gTrue;
     320    }
     321  }
     322
     323  /* not a dup, open and insert into list */
     324  if (FT_New_Memory_Face (lib,
     325                          (FT_Byte *) tmpl.bytes, tmpl.size,
     326                          0, &tmpl.face))
     327  {
     328    if (tmpl.fd != -1) {
    291329#if defined(__SUNPRO_CC) && defined(__sun) && defined(__SVR4)
    292330      munmap ((char*)tmpl.bytes, tmpl.size);
     
    294332      munmap (tmpl.bytes, tmpl.size);
    295333#endif
     334
    296335      close (tmpl.fd);
    297       *face_out = l->face;
    298       *font_face_out = cairo_font_face_reference (l->font_face);
    299       return gTrue;
    300     }
    301   }
    302 
    303   /* not a dup, open and insert into list */
    304   if (FT_New_Memory_Face (lib,
    305                           (FT_Byte *) tmpl.bytes, tmpl.size,
    306                           0, &tmpl.face))
    307   {
    308 #if defined(__SUNPRO_CC) && defined(__sun) && defined(__SVR4)
    309     munmap ((char*)tmpl.bytes, tmpl.size);
    310 #else
    311     munmap (tmpl.bytes, tmpl.size);
    312 #endif
    313 
    314     close (tmpl.fd);
     336    }
    315337    return gFalse;
    316338  }
     
    347369CairoFreeTypeFont::CairoFreeTypeFont(Ref ref,
    348370                                     cairo_font_face_t *cairo_font_face,
    349                                      FT_Face face,
    350371                                     Gushort *codeToGID,
    351372                                     int codeToGIDLen,
     
    355376                                                                   codeToGIDLen,
    356377                                                                   substitute,
    357                                                                    gTrue),
    358                                                          face(face) { }
     378                                                                   gTrue) { }
    359379
    360380CairoFreeTypeFont::~CairoFreeTypeFont() { }
     
    364384  Ref embRef;
    365385  Object refObj, strObj;
    366   GooString *tmpFileName, *fileName;
     386  GooString *fileName;
     387  char *fileNameC;
     388  char *font_data;
     389  int font_data_len;
    367390  DisplayFontParam *dfp;
    368   FILE *tmpFile;
    369   int c, i, n;
     391  int i, n;
    370392  GfxFontType fontType;
    371393  char **enc;
     
    383405  codeToGID = NULL;
    384406  codeToGIDLen = 0;
     407  font_data = NULL;
     408  font_data_len = 0;
     409  fileName = NULL;
     410  fileNameC = NULL;
    385411
    386412  GBool substitute = gFalse;
     
    389415  fontType = gfxFont->getType();
    390416
    391   tmpFileName = NULL;
    392 
    393417  if (gfxFont->getEmbeddedFontID(&embRef)) {
    394     if (!openTempFile(&tmpFileName, &tmpFile, "wb")) {
    395       error(-1, "Couldn't create temporary font file");
     418    font_data = gfxFont->readEmbFontFile(xref, &font_data_len);
     419    if (NULL == font_data)
    396420      goto err2;
    397     }
    398    
    399     refObj.initRef(embRef.num, embRef.gen);
    400     refObj.fetch(xref, &strObj);
    401     refObj.free();
    402     if (!strObj.isStream()) {
    403       error(-1, "Embedded font object is wrong type");
    404       strObj.free();
    405       fclose(tmpFile);
    406       goto err2;
    407     }
    408     strObj.streamReset();
    409     while ((c = strObj.streamGetChar()) != EOF) {
    410       fputc(c, tmpFile);
    411     }
    412     strObj.streamClose();
    413     strObj.free();
    414     fclose(tmpFile);
    415     fileName = tmpFileName;
    416    
    417421  } else if (!(fileName = gfxFont->getExtFontFile())) {
    418422    // look for a display font mapping or a substitute font
     
    440444  }
    441445
     446  if (fileName != NULL) {
     447    fileNameC = fileName->getCString();
     448  }
     449
    442450  switch (fontType) {
    443451  case fontType1:
    444452  case fontType1C:
    445453  case fontType1COT:
    446     if (! _ft_new_face (lib, fileName->getCString(), &face, &font_face)) {
     454    if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, &face, &font_face)) {
    447455      error(-1, "could not create type1 face");
    448456      goto err2;
     
    472480      }
    473481    } else {
    474       ff = FoFiTrueType::load(fileName->getCString());
     482      if (font_data != NULL) {
     483        ff = FoFiTrueType::make(font_data, font_data_len);
     484      } else {
     485        ff = FoFiTrueType::load(fileNameC);
     486      }
    475487      if (! ff)
    476488        goto err2;
     
    481493    /* Fall through */
    482494  case fontTrueType:
    483     if (!(ff = FoFiTrueType::load(fileName->getCString()))) {
     495    if (font_data != NULL) {
     496      ff = FoFiTrueType::make(font_data, font_data_len);
     497    } else {
     498      ff = FoFiTrueType::load(fileNameC);
     499    }
     500    if (! ff) {
    484501      error(-1, "failed to load truetype font\n");
    485502      goto err2;
     
    491508    }
    492509    delete ff;
    493     if (! _ft_new_face (lib, fileName->getCString(), &face, &font_face)) {
     510    if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, &face, &font_face)) {
    494511      error(-1, "could not create truetype face\n");
    495512      goto err2;
     
    505522    if (!useCIDs)
    506523    {
    507       if ((ff1c = FoFiType1C::load(fileName->getCString()))) {
     524      if (font_data != NULL) {
     525        ff1c = FoFiType1C::make(font_data, font_data_len);
     526      } else {
     527        ff1c = FoFiType1C::load(fileNameC);
     528      }
     529      if (ff1c) {
    508530        codeToGID = ff1c->getCIDToGIDMap(&codeToGIDLen);
    509531        delete ff1c;
     
    511533    }
    512534
    513     if (! _ft_new_face (lib, fileName->getCString(), &face, &font_face)) {
     535    if (! _ft_new_face (lib, fileNameC, font_data, font_data_len, &face, &font_face)) {
    514536      gfree(codeToGID);
    515537      codeToGID = NULL;
     
    520542   
    521543  default:
    522     printf ("font type %d not handled\n", (int)fontType);
     544    fprintf (stderr, "font type %d not handled\n", (int)fontType);
    523545    goto err2;
    524546    break;
    525547  }
    526548
    527   // delete the (temporary) font file -- with Unix hard link
    528   // semantics, this will remove the last link; otherwise it will
    529   // return an error, leaving the file to be deleted later
    530   if (fileName == tmpFileName) {
    531     unlink (fileName->getCString());
    532     delete tmpFileName;
    533   }
    534 
    535549  return new CairoFreeTypeFont(ref,
    536                        font_face, face,
     550                       font_face,
    537551                       codeToGID, codeToGIDLen,
    538552                       substitute);
     
    540554 err2:
    541555  /* hmm? */
    542   printf ("some font thing failed\n");
     556  fprintf (stderr, "some font thing failed\n");
    543557  return NULL;
    544558}
  • trunk/poppler/mypoppler/poppler/CairoFontEngine.h

    r277 r461  
    1818// Copyright (C) 2005 Albert Astals Cid <aacid@kde.org>
    1919// Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
    20 // Copyright (C) 2006 Carlos Garcia Campos <carlosgc@gnome.org>
     20// Copyright (C) 2006, 2010 Carlos Garcia Campos <carlosgc@gnome.org>
    2121// Copyright (C) 2008 Adrian Johnson <ajohnson@redneon.com>
    2222//
     
    7676
    7777private:
    78   CairoFreeTypeFont(Ref ref, cairo_font_face_t *cairo_font_face, FT_Face face,
     78  CairoFreeTypeFont(Ref ref, cairo_font_face_t *cairo_font_face,
    7979            Gushort *codeToGID, int codeToGIDLen, GBool substitute);
    80   FT_Face face;
    8180};
    8281
  • trunk/poppler/mypoppler/poppler/CairoOutputDev.cc

    r290 r461  
    1919// Copyright (C) 2005, 2009 Albert Astals Cid <aacid@kde.org>
    2020// Copyright (C) 2005 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
    21 // Copyright (C) 2006-2009 Carlos Garcia Campos <carlosgc@gnome.org>
     21// Copyright (C) 2006-2010 Carlos Garcia Campos <carlosgc@gnome.org>
    2222// Copyright (C) 2008 Carl Worth <cworth@cworth.org>
    23 // Copyright (C) 2008, 2009 Adrian Johnson <ajohnson@redneon.com>
     23// Copyright (C) 2008-2010 Adrian Johnson <ajohnson@redneon.com>
    2424// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
    2525// Copyright (C) 2008, 2009 Chris Wilson <chris@chris-wilson.co.uk>
    2626// Copyright (C) 2008 Hib Eris <hib@hiberis.nl>
    27 // Copyright (C) 2009 David Benjamin <davidben@mit.edu>
     27// Copyright (C) 2009, 2010 David Benjamin <davidben@mit.edu>
    2828//
    2929// To see a description of the changes please see the Changelog file that
     
    5959#include "CairoOutputDev.h"
    6060#include "CairoFontEngine.h"
     61#include "CairoRescaleBox.h"
    6162//------------------------------------------------------------------------
    6263
     
    124125  glyphs = NULL;
    125126  fill_pattern = NULL;
     127  fill_color.r = fill_color.g = fill_color.b = 0;
    126128  stroke_pattern = NULL;
     129  stroke_color.r = stroke_color.g = stroke_color.b = 0;
    127130  stroke_opacity = 1.0;
    128131  fill_opacity = 1.0;
     
    224227  /* set up some per page defaults */
    225228  cairo_pattern_destroy(fill_pattern);
     229  cairo_pattern_destroy(stroke_pattern);
     230
    226231  fill_pattern = cairo_pattern_create_rgb(0., 0., 0.);
    227 
    228   cairo_pattern_destroy(stroke_pattern);
    229   stroke_pattern = cairo_pattern_create_rgb(0., 0., 0.);
     232  stroke_pattern = cairo_pattern_reference(fill_pattern);
    230233
    231234  if (text)
     
    270273
    271274  MaskStack* ms = maskStack;
    272   if (mask)
    273     cairo_pattern_destroy(mask);
    274 
    275275  if (ms) {
     276    if (mask)
     277      cairo_pattern_destroy(mask);
    276278    mask = ms->mask;
    277279    maskStack = ms->next;
     
    419421
    420422void CairoOutputDev::updateFillColor(GfxState *state) {
     423  GfxRGB color = fill_color;
     424
    421425  state->getFillRGB(&fill_color);
    422 
    423   cairo_pattern_destroy(fill_pattern);
    424   fill_pattern = cairo_pattern_create_rgba(fill_color.r / 65535.0,
    425                                            fill_color.g / 65535.0,
    426                                            fill_color.b / 65535.0,
    427                                            fill_opacity);
    428 
    429   LOG(printf ("fill color: %d %d %d\n",
    430               fill_color.r, fill_color.g, fill_color.b));
     426  if (color.r != fill_color.r ||
     427      color.g != fill_color.g ||
     428      color.b != fill_color.b)
     429  {
     430    cairo_pattern_destroy(fill_pattern);
     431    fill_pattern = cairo_pattern_create_rgba(colToDbl(fill_color.r),
     432                                             colToDbl(fill_color.g),
     433                                             colToDbl(fill_color.b),
     434                                             fill_opacity);
     435
     436    LOG(printf ("fill color: %d %d %d\n",
     437                fill_color.r, fill_color.g, fill_color.b));
     438  }
    431439}
    432440
    433441void CairoOutputDev::updateStrokeColor(GfxState *state) {
     442  GfxRGB color = stroke_color;
     443
    434444  state->getStrokeRGB(&stroke_color);
    435 
    436   cairo_pattern_destroy(stroke_pattern);
    437   stroke_pattern = cairo_pattern_create_rgba(stroke_color.r / 65535.0,
    438                                              stroke_color.g / 65535.0,
    439                                              stroke_color.b / 65535.0,
    440                                              stroke_opacity);
    441  
    442   LOG(printf ("stroke color: %d %d %d\n",
    443               stroke_color.r, stroke_color.g, stroke_color.b));
     445  if (color.r != stroke_color.r ||
     446      color.g != stroke_color.g ||
     447      color.b != stroke_color.b)
     448  {
     449    cairo_pattern_destroy(stroke_pattern);
     450    stroke_pattern = cairo_pattern_create_rgba(colToDbl(stroke_color.r),
     451                                               colToDbl(stroke_color.g),
     452                                               colToDbl(stroke_color.b),
     453                                               stroke_opacity);
     454
     455    LOG(printf ("stroke color: %d %d %d\n",
     456                stroke_color.r, stroke_color.g, stroke_color.b));
     457  }
    444458}
    445459
    446460void CairoOutputDev::updateFillOpacity(GfxState *state) {
     461  double opacity = fill_opacity;
     462
    447463  fill_opacity = state->getFillOpacity();
    448 
    449   cairo_pattern_destroy(fill_pattern);
    450   fill_pattern = cairo_pattern_create_rgba(fill_color.r / 65535.0,
    451                                            fill_color.g / 65535.0,
    452                                            fill_color.b / 65535.0,
    453                                            fill_opacity);
    454 
    455   LOG(printf ("fill opacity: %f\n", fill_opacity));
     464  if (opacity != fill_opacity) {
     465    cairo_pattern_destroy(fill_pattern);
     466    fill_pattern = cairo_pattern_create_rgba(colToDbl(fill_color.r),
     467                                             colToDbl(fill_color.g),
     468                                             colToDbl(fill_color.b),
     469                                             fill_opacity);
     470
     471    LOG(printf ("fill opacity: %f\n", fill_opacity));
     472  }
    456473}
    457474
    458475void CairoOutputDev::updateStrokeOpacity(GfxState *state) {
     476  double opacity = stroke_opacity;
     477
    459478  stroke_opacity = state->getStrokeOpacity();
    460 
    461   cairo_pattern_destroy(stroke_pattern);
    462   stroke_pattern = cairo_pattern_create_rgba(stroke_color.r / 65535.0,
    463                                              stroke_color.g / 65535.0,
    464                                              stroke_color.b / 65535.0,
    465                                              stroke_opacity);
    466  
    467   LOG(printf ("stroke opacity: %f\n", stroke_opacity));
     479  if (opacity != stroke_opacity) {
     480    cairo_pattern_destroy(stroke_pattern);
     481    stroke_pattern = cairo_pattern_create_rgba(colToDbl(stroke_color.r),
     482                                               colToDbl(stroke_color.g),
     483                                               colToDbl(stroke_color.b),
     484                                               stroke_opacity);
     485
     486    LOG(printf ("stroke opacity: %f\n", stroke_opacity));
     487  }
    468488}
    469489
     
    472492
    473493  cairo_pattern_add_color_stop_rgba(fill_pattern, offset,
    474                                     fill_color.r / 65535.0,
    475                                     fill_color.g / 65535.0,
    476                                     fill_color.b / 65535.0,
     494                                    colToDbl(fill_color.r),
     495                                    colToDbl(fill_color.g),
     496                                    colToDbl(fill_color.b),
    477497                                    fill_opacity);
    478498  LOG(printf ("fill color stop: %f (%d, %d, %d)\n",
     
    481501
    482502void CairoOutputDev::updateBlendMode(GfxState *state) {
    483 #ifdef CAIRO_HAS_BLEND_MODES
     503#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4)
    484504  switch (state->getBlendMode()) {
    485505  default:
     
    534554  }
    535555  LOG(printf ("blend mode: %d\n", (int)state->getBlendMode()));
    536 #endif /* CAIRO_HAS_BLEND_MODES */
     556#endif /* CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 4) */
    537557}
    538558
     
    599619  GfxSubpath *subpath;
    600620  int i, j;
     621  cairo_new_path (cairo);
    601622  for (i = 0; i < path->getNumSubpaths(); ++i) {
    602623    subpath = path->getSubpath(i);
     
    626647
    627648void CairoOutputDev::stroke(GfxState *state) {
     649  if (inType3Char) {
     650      GfxGray gray;
     651      state->getFillGray(&gray);
     652      if (colToDbl(gray) > 0.5)
     653          return;
     654  }
     655
    628656  doPath (cairo, state, state->getPath());
    629657  cairo_set_source (cairo, stroke_pattern);
     
    637665
    638666void CairoOutputDev::fill(GfxState *state) {
     667  if (inType3Char) {
     668      GfxGray gray;
     669      state->getFillGray(&gray);
     670      if (colToDbl(gray) > 0.5)
     671          return;
     672  }
     673
    639674  doPath (cairo, state, state->getPath());
    640675  cairo_set_fill_rule (cairo, CAIRO_FILL_RULE_WINDING);
     
    642677  LOG(printf ("fill\n"));
    643678  //XXX: how do we get the path
    644   cairo_fill (cairo);
     679  if (mask) {
     680    cairo_clip (cairo);
     681    cairo_mask (cairo, mask);
     682  } else {
     683    cairo_fill (cairo);
     684  }
    645685  if (cairo_shape) {
    646686    cairo_set_fill_rule (cairo_shape, CAIRO_FILL_RULE_WINDING);
     
    678718  cairo_t *old_cairo;
    679719  double xMin, yMin, xMax, yMax;
    680 
    681   if (xStep != bbox[2] || yStep != bbox[3])
     720  double width, height;
     721  int surface_width, surface_height;
     722
     723  width = bbox[2] - bbox[0];
     724  height = bbox[3] - bbox[1];
     725
     726  if (xStep != width || yStep != height)
    682727    return gFalse;
    683728  /* TODO: implement the other cases here too */
    684729
     730  surface_width = (int) ceil (width);
     731  surface_height = (int) ceil (height);
     732
    685733  surface = cairo_surface_create_similar (cairo_get_target (cairo),
    686734                                          CAIRO_CONTENT_COLOR_ALPHA,
    687                                           bbox[2], bbox[3]);
     735                                          surface_width, surface_height);
    688736  if (cairo_surface_status (surface))
    689737    return gFalse;
     
    707755  state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax);
    708756  cairo_rectangle (cairo, xMin, yMin, xMax - xMin, yMax - yMin);
     757
     758  cairo_matrix_init_scale (&matrix, surface_width / width, surface_height / height);
     759  cairo_pattern_set_matrix (pattern, &matrix);
    709760
    710761  cairo_matrix_init (&matrix, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
     
    734785  else
    735786    cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_PAD);
     787
     788  LOG (printf ("axial-sh\n"));
    736789
    737790  // TODO: use the actual stops in the shading in the case
     
    765818    cairo_pattern_set_extend (fill_pattern, CAIRO_EXTEND_NONE);
    766819
     820  LOG (printf ("radial-sh\n"));
     821
    767822  return gFalse;
    768823}
     
    796851  }
    797852
     853}
     854
     855void CairoOutputDev::clipToStrokePath(GfxState *state) {
     856  LOG(printf("clip-to-stroke-path\n"));
    798857}
    799858
     
    10661125  css->next = groupColorSpaceStack;
    10671126  groupColorSpaceStack = css;
     1127
     1128  LOG(printf ("begin transparency group. knockout: %s\n", knockout ? "yes":"no"));
     1129
    10681130  if (knockout) {
    10691131    knockoutCount++;
     
    11031165
    11041166void CairoOutputDev::endTransparencyGroup(GfxState * /*state*/) {
    1105 
    11061167  if (group)
    11071168    cairo_pattern_destroy(group);
    11081169  group = cairo_pop_group (cairo);
     1170
     1171  LOG(printf ("end transparency group\n"));
    11091172
    11101173  if (groupColorSpaceStack->next && groupColorSpaceStack->next->knockout) {
     
    11171180void CairoOutputDev::paintTransparencyGroup(GfxState * /*state*/, double * /*bbox*/) {
    11181181  cairo_set_source (cairo, group);
     1182
     1183  LOG(printf ("paint transparency group\n"));
    11191184
    11201185  if (!mask) {
     
    11741239  cairo_pattern_destroy(mask);
    11751240
     1241  LOG(printf ("set softMask\n"));
     1242
    11761243  if (alpha == false) {
    11771244    /* We need to mask according to the luminocity of the group.
     
    12051272    groupColorSpaceStack->cs->getRGB(backdropColor, &backdropColorRGB);
    12061273    /* paint the backdrop */
    1207     cairo_set_source_rgb(maskCtx, backdropColorRGB.r / 65535.0,
    1208                          backdropColorRGB.g / 65535.0,
    1209                          backdropColorRGB.b / 65535.0);
    1210 
     1274    cairo_set_source_rgb(maskCtx,
     1275                         colToDbl(backdropColorRGB.r),
     1276                         colToDbl(backdropColorRGB.g),
     1277                         colToDbl(backdropColorRGB.b));
     1278    cairo_paint(maskCtx);
    12111279
    12121280    cairo_matrix_t mat;
     
    12161284    /* make the device offset of the new mask match that of the group */
    12171285    double x_offset, y_offset;
    1218     cairo_surface_t *pats;
    1219     cairo_pattern_get_surface(group, &pats);
    1220     cairo_surface_get_device_offset(pats, &x_offset, &y_offset);
     1286    if (cairo_get_group_target(cairo) == cairo_get_target(cairo)) {
     1287      cairo_surface_get_device_offset(cairo_get_group_target(cairo), &x_offset, &y_offset);
     1288    } else {
     1289      cairo_surface_t *pats;
     1290      cairo_pattern_get_surface(group, &pats);
     1291      cairo_surface_get_device_offset(pats, &x_offset, &y_offset);
     1292    }
    12211293    cairo_surface_set_device_offset(source, x_offset, y_offset);
    12221294
     
    12531325    /* setup the new mask pattern */
    12541326    mask = cairo_pattern_create_for_surface(source);
    1255     cairo_matrix_t patMatrix;
    1256     cairo_pattern_get_matrix(group, &patMatrix);
    1257     cairo_pattern_set_matrix(mask, &patMatrix);
     1327
     1328    if (cairo_get_group_target(cairo) == cairo_get_target(cairo)) {
     1329      cairo_pattern_set_matrix(mask, &mat);
     1330    } else {
     1331      cairo_matrix_t patMatrix;
     1332      cairo_pattern_get_matrix(group, &patMatrix);
     1333      cairo_pattern_set_matrix(mask, &patMatrix);
     1334    }
    12581335
    12591336    cairo_surface_destroy(source);
     
    12921369}
    12931370
     1371/* Taken from cairo/doc/tutorial/src/singular.c */
     1372static void
     1373get_singular_values (const cairo_matrix_t *matrix,
     1374                     double               *major,
     1375                     double               *minor)
     1376{
     1377        double xx = matrix->xx, xy = matrix->xy;
     1378        double yx = matrix->yx, yy = matrix->yy;
     1379
     1380        double a = xx*xx+yx*yx;
     1381        double b = xy*xy+yy*yy;
     1382        double k = xx*xy+yx*yy;
     1383
     1384        double f = (a+b) * .5;
     1385        double g = (a-b) * .5;
     1386        double delta = sqrt (g*g + k*k);
     1387
     1388        if (major)
     1389                *major = sqrt (f + delta);
     1390        if (minor)
     1391                *minor = sqrt (f - delta);
     1392}
     1393
     1394void CairoOutputDev::getScaledSize(int  orig_width,
     1395                                   int  orig_height,
     1396                                   int *scaledWidth,
     1397                                   int *scaledHeight) {
     1398  cairo_matrix_t matrix;
     1399  cairo_get_matrix(cairo, &matrix);
     1400
     1401  double xScale;
     1402  double yScale;
     1403  if (orig_width > orig_height)
     1404    get_singular_values (&matrix, &xScale, &yScale);
     1405  else
     1406    get_singular_values (&matrix, &yScale, &xScale);
     1407
     1408  int tx, tx2, ty, ty2; /* the integer co-oridinates of the resulting image */
     1409  if (xScale >= 0) {
     1410    tx = splashRound(matrix.x0 - 0.01);
     1411    tx2 = splashRound(matrix.x0 + xScale + 0.01) - 1;
     1412  } else {
     1413    tx = splashRound(matrix.x0 + 0.01) - 1;
     1414    tx2 = splashRound(matrix.x0 + xScale - 0.01);
     1415  }
     1416  *scaledWidth = abs(tx2 - tx) + 1;
     1417  //scaledWidth = splashRound(fabs(xScale));
     1418  if (*scaledWidth == 0) {
     1419    // technically, this should draw nothing, but it generally seems
     1420    // better to draw a one-pixel-wide stripe rather than throwing it
     1421    // away
     1422    *scaledWidth = 1;
     1423  }
     1424  if (yScale >= 0) {
     1425    ty = splashFloor(matrix.y0 + 0.01);
     1426    ty2 = splashCeil(matrix.y0 + yScale - 0.01);
     1427  } else {
     1428    ty = splashCeil(matrix.y0 - 0.01);
     1429    ty2 = splashFloor(matrix.y0 + yScale + 0.01);
     1430  }
     1431  *scaledHeight = abs(ty2 - ty);
     1432  if (*scaledHeight == 0) {
     1433    *scaledHeight = 1;
     1434  }
     1435}
     1436
     1437cairo_surface_t *CairoOutputDev::downscaleSurface(cairo_surface_t *orig_surface) {
     1438  cairo_surface_t *dest_surface;
     1439  unsigned char *dest_buffer;
     1440  int dest_stride;
     1441  unsigned char *orig_buffer;
     1442  int orig_width, orig_height;
     1443  int orig_stride;
     1444  int scaledHeight;
     1445  int scaledWidth;
     1446  GBool res;
     1447
     1448  if (printing)
     1449    return NULL;
     1450
     1451  orig_width = cairo_image_surface_get_width (orig_surface);
     1452  orig_height = cairo_image_surface_get_height (orig_surface);
     1453  getScaledSize (orig_width, orig_height, &scaledWidth, &scaledHeight);
     1454  if (scaledWidth >= orig_width || scaledHeight >= orig_height)
     1455    return NULL;
     1456
     1457  dest_surface = cairo_surface_create_similar (orig_surface,
     1458                                               cairo_surface_get_content (orig_surface),
     1459                                               scaledWidth, scaledHeight);
     1460  dest_buffer = cairo_image_surface_get_data (dest_surface);
     1461  dest_stride = cairo_image_surface_get_stride (dest_surface);
     1462
     1463  orig_buffer = cairo_image_surface_get_data (orig_surface);
     1464  orig_stride = cairo_image_surface_get_stride (orig_surface);
     1465
     1466  res = downscale_box_filter((uint32_t *)orig_buffer,
     1467                             orig_stride, orig_width, orig_height,
     1468                             scaledWidth, scaledHeight, 0, 0,
     1469                             scaledWidth, scaledHeight,
     1470                             (uint32_t *)dest_buffer, dest_stride);
     1471  if (!res) {
     1472    cairo_surface_destroy (dest_surface);
     1473    return NULL;
     1474  }
     1475
     1476  return dest_surface;
     1477
     1478}
     1479
     1480cairo_filter_t
     1481CairoOutputDev::getFilterForSurface(cairo_surface_t *image,
     1482                                    GBool interpolate)
     1483{
     1484  if (interpolate)
     1485    return CAIRO_FILTER_BILINEAR;
     1486
     1487  int orig_width = cairo_image_surface_get_width (image);
     1488  int orig_height = cairo_image_surface_get_height (image);
     1489  if (orig_width == 0 || orig_height == 0)
     1490          return CAIRO_FILTER_NEAREST;
     1491
     1492  int scaled_width, scaled_height;
     1493  getScaledSize (orig_width, orig_height, &scaled_width, &scaled_height);
     1494
     1495  /* When scale factor is >= 400% we don't interpolate. See bugs #25268, #9860 */
     1496  if (scaled_width / orig_width >= 4 || scaled_height / orig_height >= 4)
     1497          return CAIRO_FILTER_NEAREST;
     1498
     1499  return CAIRO_FILTER_BILINEAR;
     1500}
     1501
    12941502void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
    12951503                                   int width, int height, GBool invert,
     
    13011509  /* work around a cairo bug when scaling 1x1 surfaces */
    13021510  if (width == 1 && height == 1) {
     1511    ImageStream *imgStr;
     1512    Guchar pix;
     1513    int invert_bit;
     1514
     1515    imgStr = new ImageStream(str, width, 1, 1);
     1516    imgStr->reset();
     1517    imgStr->getPixel(&pix);
     1518    imgStr->close();
     1519    delete imgStr;
     1520
     1521    invert_bit = invert ? 1 : 0;
     1522    if (pix ^ invert_bit)
     1523      return;
     1524
    13031525    cairo_save (cairo);
    13041526    cairo_rectangle (cairo, 0., 0., width, height);
     
    13141536  }
    13151537
     1538  if (state->getFillColorSpace()->getMode() == csPattern)
     1539    cairo_push_group_with_content (cairo, CAIRO_CONTENT_ALPHA);
     1540
    13161541  /* shape is 1.0 for painted areas, 0.0 for unpainted ones */
    13171542
     
    13241549  } else {
    13251550    drawImageMaskRegular(state, ref, str, width, height, invert, interpolate, inlineImg);
     1551  }
     1552
     1553  if (state->getFillColorSpace()->getMode() == csPattern) {
     1554    if (mask)
     1555      cairo_pattern_destroy (mask);
     1556    mask = cairo_pop_group (cairo);
    13261557  }
    13271558}
     
    13401571  int invert_bit;
    13411572  int row_stride;
     1573  cairo_filter_t filter;
    13421574
    13431575  /* TODO: Do we want to cache these? */
     
    13651597    }
    13661598  }
     1599
     1600  filter = getFilterForSurface (image, interpolate);
    13671601
    13681602  cairo_surface_mark_dirty (image);
     
    13741608  LOG (printf ("drawImageMask %dx%d\n", width, height));
    13751609
    1376   /* we should actually be using CAIRO_FILTER_NEAREST here. However,
    1377    * cairo doesn't yet do minifaction filtering causing scaled down
    1378    * images with CAIRO_FILTER_NEAREST to look really bad */
    1379   cairo_pattern_set_filter (pattern,
    1380                             interpolate ? CAIRO_FILTER_BEST : CAIRO_FILTER_FAST);
    1381   cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
     1610  cairo_pattern_set_filter (pattern, filter);
     1611
     1612  if (!printing)
     1613    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
    13821614
    13831615  cairo_matrix_init_translate (&matrix, 0, height);
    13841616  cairo_matrix_scale (&matrix, width, -height);
    13851617  cairo_pattern_set_matrix (pattern, &matrix);
     1618  if (cairo_pattern_status (pattern)) {
     1619    cairo_pattern_destroy (pattern);
     1620    goto cleanup;
     1621  }
    13861622
    13871623  if (state->getFillColorSpace()->getMode() == csPattern) {
    13881624    mask = cairo_pattern_reference (pattern);
    1389   } else {
     1625  } else if (!printing) {
    13901626    cairo_save (cairo);
    13911627    cairo_rectangle (cairo, 0., 0., 1., 1.);
     
    13931629    cairo_mask (cairo, pattern);
    13941630    cairo_restore (cairo);
     1631  } else {
     1632    cairo_mask (cairo, pattern);
    13951633  }
    13961634
     
    13981636    cairo_save (cairo_shape);
    13991637    cairo_set_source (cairo_shape, pattern);
    1400     cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
    1401     cairo_fill (cairo_shape);
     1638    if (!printing) {
     1639      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
     1640      cairo_fill (cairo_shape);
     1641    } else {
     1642      cairo_mask (cairo_shape, pattern);
     1643    }
    14021644    cairo_restore (cairo_shape);
    14031645  }
     
    16451887    cairo_matrix_scale (&matrix, scaledWidth, -scaledHeight);
    16461888    cairo_pattern_set_matrix (pattern, &matrix);
     1889    if (cairo_pattern_status (pattern)) {
     1890      cairo_pattern_destroy (pattern);
     1891      imgStr->close();
     1892      delete imgStr;
     1893      return;
     1894    }
    16471895
    16481896    mask = cairo_pattern_reference (pattern);
     
    17121960  int x, y;
    17131961  int invert_bit;
     1962  cairo_filter_t filter;
     1963  cairo_filter_t maskFilter;
    17141964
    17151965  maskImgStr = new ImageStream(maskStr, maskWidth, 1, 1);
     
    17421992  delete maskImgStr;
    17431993
     1994  maskFilter = getFilterForSurface (maskImage, maskInterpolate);
     1995
    17441996  cairo_surface_mark_dirty (maskImage);
    17451997  maskPattern = cairo_pattern_create_for_surface (maskImage);
     
    17752027  }
    17762028
     2029  filter = getFilterForSurface (image, interpolate);
     2030
    17772031  cairo_surface_mark_dirty (image);
    17782032  pattern = cairo_pattern_create_for_surface (image);
     
    17832037  LOG (printf ("drawMaskedImage %dx%d\n", width, height));
    17842038
    1785   cairo_pattern_set_filter (pattern,
    1786                             interpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
    1787   cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
    1788   cairo_pattern_set_filter (maskPattern,
    1789                             maskInterpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
    1790   cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
     2039  cairo_pattern_set_filter (pattern, filter);
     2040  cairo_pattern_set_filter (maskPattern, maskFilter);
     2041
     2042  if (!printing) {
     2043    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
     2044    cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
     2045  }
    17912046
    17922047  cairo_matrix_init_translate (&matrix, 0, height);
    17932048  cairo_matrix_scale (&matrix, width, -height);
    17942049  cairo_pattern_set_matrix (pattern, &matrix);
     2050  if (cairo_pattern_status (pattern)) {
     2051    cairo_pattern_destroy (pattern);
     2052    cairo_pattern_destroy (maskPattern);
     2053    goto cleanup;
     2054  }
    17952055
    17962056  cairo_matrix_init_translate (&maskMatrix, 0, maskHeight);
    17972057  cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight);
    17982058  cairo_pattern_set_matrix (maskPattern, &maskMatrix);
    1799 
    1800   cairo_save (cairo);
    1801   cairo_set_source (cairo, pattern);
    1802   cairo_rectangle (cairo, 0., 0., 1., 1.);
    1803   cairo_clip (cairo);
    1804   cairo_mask (cairo, maskPattern);
    1805   cairo_restore (cairo);
     2059  if (cairo_pattern_status (maskPattern)) {
     2060    cairo_pattern_destroy (maskPattern);
     2061    cairo_pattern_destroy (pattern);
     2062    goto cleanup;
     2063  }
     2064
     2065  if (!printing) {
     2066    cairo_save (cairo);
     2067    cairo_set_source (cairo, pattern);
     2068    cairo_rectangle (cairo, 0., 0., 1., 1.);
     2069    cairo_clip (cairo);
     2070    cairo_mask (cairo, maskPattern);
     2071    cairo_restore (cairo);
     2072  } else {
     2073    cairo_set_source (cairo, pattern);
     2074    cairo_mask (cairo, maskPattern);
     2075  }
    18062076
    18072077  if (cairo_shape) {
    18082078    cairo_save (cairo_shape);
    18092079    cairo_set_source (cairo_shape, pattern);
    1810     cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
    1811     cairo_fill (cairo_shape);
     2080    if (!printing) {
     2081      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
     2082      cairo_fill (cairo_shape);
     2083    } else {
     2084      cairo_mask (cairo_shape, pattern);
     2085    }
    18122086    cairo_restore (cairo_shape);
    18132087  }
     
    18422116  Guchar *pix;
    18432117  int y;
     2118  cairo_filter_t filter;
     2119  cairo_filter_t maskFilter;
    18442120
    18452121  maskImgStr = new ImageStream(maskStr, maskWidth,
     
    18652141  maskImgStr->close();
    18662142  delete maskImgStr;
     2143
     2144  maskFilter = getFilterForSurface (maskImage, maskInterpolate);
    18672145
    18682146  cairo_surface_mark_dirty (maskImage);
     
    18992177  }
    19002178
     2179  filter = getFilterForSurface (image, interpolate);
     2180
    19012181  cairo_surface_mark_dirty (image);
    19022182  pattern = cairo_pattern_create_for_surface (image);
     
    19072187  LOG (printf ("drawSoftMaskedImage %dx%d\n", width, height));
    19082188
    1909   //XXX: should set mask filter
    1910   cairo_pattern_set_filter (pattern,
    1911                             interpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
    1912   cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
    1913   cairo_pattern_set_filter (maskPattern,
    1914                             maskInterpolate ? CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
    1915   cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
     2189  cairo_pattern_set_filter (pattern, filter);
     2190  cairo_pattern_set_filter (maskPattern, maskFilter);
     2191
     2192  if (!printing) {
     2193    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
     2194    cairo_pattern_set_extend (maskPattern, CAIRO_EXTEND_PAD);
     2195  }
    19162196
    19172197  cairo_matrix_init_translate (&matrix, 0, height);
    19182198  cairo_matrix_scale (&matrix, width, -height);
    19192199  cairo_pattern_set_matrix (pattern, &matrix);
     2200  if (cairo_pattern_status (pattern)) {
     2201    cairo_pattern_destroy (pattern);
     2202    cairo_pattern_destroy (maskPattern);
     2203    goto cleanup;
     2204  }
    19202205
    19212206  cairo_matrix_init_translate (&maskMatrix, 0, maskHeight);
    19222207  cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight);
    19232208  cairo_pattern_set_matrix (maskPattern, &maskMatrix);
    1924 
    1925   cairo_save (cairo);
     2209  if (cairo_pattern_status (maskPattern)) {
     2210    cairo_pattern_destroy (maskPattern);
     2211    cairo_pattern_destroy (pattern);
     2212    goto cleanup;
     2213  }
     2214
     2215  if (fill_opacity != 1.0)
     2216    cairo_push_group (cairo);
     2217  else
     2218    cairo_save (cairo);
     2219
    19262220  cairo_set_source (cairo, pattern);
    1927   cairo_rectangle (cairo, 0., 0.,
    1928                    MIN (width, maskWidth) / (double)width,
    1929                    MIN (height, maskHeight) / (double)height);
    1930   cairo_clip (cairo);
     2221  if (!printing) {
     2222    cairo_rectangle (cairo, 0., 0.,
     2223                     MIN (width, maskWidth) / (double)width,
     2224                     MIN (height, maskHeight) / (double)height);
     2225    cairo_clip (cairo);
     2226  }
    19312227  cairo_mask (cairo, maskPattern);
     2228
     2229  if (fill_opacity != 1.0) {
     2230    cairo_pop_group_to_source (cairo);
     2231    cairo_save (cairo);
     2232    if (!printing) {
     2233      cairo_rectangle (cairo, 0., 0.,
     2234                       MIN (width, maskWidth) / (double)width,
     2235                       MIN (height, maskHeight) / (double)height);
     2236      cairo_clip (cairo);
     2237    }
     2238    cairo_paint_with_alpha (cairo, fill_opacity);
     2239  }
    19322240  cairo_restore (cairo);
    19332241
     
    19352243    cairo_save (cairo_shape);
    19362244    cairo_set_source (cairo_shape, pattern);
    1937     cairo_rectangle (cairo_shape, 0., 0.,
    1938                      MIN (width, maskWidth) / (double)width,
    1939                      MIN (height, maskHeight) / (double)height);
    1940     cairo_fill (cairo_shape);
     2245    if (!printing) {
     2246      cairo_rectangle (cairo_shape, 0., 0.,
     2247                       MIN (width, maskWidth) / (double)width,
     2248                       MIN (height, maskHeight) / (double)height);
     2249      cairo_fill (cairo_shape);
     2250    } else {
     2251      cairo_mask (cairo_shape, pattern);
     2252    }
    19412253    cairo_restore (cairo_shape);
    19422254  }
     
    19482260  imgStr->close();
    19492261  delete imgStr;
     2262}
     2263
     2264GBool CairoOutputDev::getStreamData (Stream *str, char **buffer, int *length)
     2265{
     2266  int len, i;
     2267  char *strBuffer;
     2268
     2269  len = 0;
     2270  str->close();
     2271  str->reset();
     2272  while (str->getChar() != EOF) len++;
     2273  if (len == 0)
     2274    return gFalse;
     2275
     2276  strBuffer = (char *)gmalloc (len);
     2277
     2278  str->close();
     2279  str->reset();
     2280  for (i = 0; i < len; ++i)
     2281    strBuffer[i] = str->getChar();
     2282
     2283  *buffer = strBuffer;
     2284  *length = len;
     2285
     2286  return gTrue;
    19502287}
    19512288
     
    19632300  int stride, i;
    19642301  GfxRGB *lookup = NULL;
     2302  cairo_filter_t filter = CAIRO_FILTER_BILINEAR;
    19652303
    19662304  /* TODO: Do we want to cache these? */
     
    20442382  gfree(lookup);
    20452383
     2384  LOG (printf ("drawImage %dx%d\n", width, height));
     2385
     2386  cairo_surface_t *scaled_surface;
     2387
     2388  scaled_surface = downscaleSurface (image);
     2389  if (scaled_surface) {
     2390    if (cairo_surface_status (scaled_surface))
     2391      goto cleanup;
     2392    cairo_surface_destroy (image);
     2393    image = scaled_surface;
     2394    width = cairo_image_surface_get_width (image);
     2395    height = cairo_image_surface_get_height (image);
     2396  } else {
     2397    filter = getFilterForSurface (image, interpolate);
     2398  }
     2399
    20462400  cairo_surface_mark_dirty (image);
     2401
     2402#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 6)
     2403  if (printing && (str->getKind() == strDCT || str->getKind() == strJPX)) {
     2404    char *strBuffer;
     2405    int len;
     2406
     2407    if (getStreamData (str->getNextStream(), &strBuffer, &len)) {
     2408      cairo_status_t st;
     2409      st = cairo_surface_set_mime_data (image,
     2410                                        str->getKind() == strDCT ?
     2411                                        CAIRO_MIME_TYPE_JPEG : CAIRO_MIME_TYPE_JP2,
     2412                                        (const unsigned char *)strBuffer, len,
     2413                                        gfree, strBuffer);
     2414      if (st)
     2415        gfree (strBuffer);
     2416    }
     2417  }
     2418#endif /* CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 9, 6) */
     2419
    20472420  pattern = cairo_pattern_create_for_surface (image);
    20482421  cairo_surface_destroy (image);
     
    20502423    goto cleanup;
    20512424
    2052   LOG (printf ("drawImage %dx%d\n", width, height));
    2053 
    2054   cairo_pattern_set_filter (pattern,
    2055                             interpolate ?
    2056                             CAIRO_FILTER_BILINEAR : CAIRO_FILTER_FAST);
    2057   cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
     2425  cairo_pattern_set_filter (pattern, filter);
     2426
     2427  if (!printing)
     2428    cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD);
    20582429
    20592430  cairo_matrix_init_translate (&matrix, 0, height);
    20602431  cairo_matrix_scale (&matrix, width, -height);
    20612432  cairo_pattern_set_matrix (pattern, &matrix);
     2433  if (cairo_pattern_status (pattern)) {
     2434    cairo_pattern_destroy (pattern);
     2435    goto cleanup;
     2436  }
    20622437
    20632438  if (!mask && fill_opacity != 1.0) {
     
    20712446  cairo_save (cairo);
    20722447  cairo_set_source (cairo, pattern);
    2073   cairo_rectangle (cairo, 0., 0., 1., 1.);
     2448  if (printing)
     2449    cairo_rectangle (cairo, 0., 0., width, height);
     2450  else
     2451    cairo_rectangle (cairo, 0., 0., 1., 1.);
    20742452  if (maskPattern) {
    20752453    cairo_clip (cairo);
     
    20852463    cairo_save (cairo_shape);
    20862464    cairo_set_source (cairo_shape, pattern);
    2087     cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
     2465    if (printing)
     2466      cairo_rectangle (cairo_shape, 0., 0., width, height);
     2467    else
     2468      cairo_rectangle (cairo_shape, 0., 0., 1., 1.);
    20882469    cairo_fill (cairo_shape);
    20892470    cairo_restore (cairo_shape);
  • trunk/poppler/mypoppler/poppler/CairoOutputDev.h

    r277 r461  
    1818// Copyright (C) 2005, 2006 Kristian HÞgsberg <krh@redhat.com>
    1919// Copyright (C) 2005 Nickolay V. Shmyrev <nshmyrev@yandex.ru>
    20 // Copyright (C) 2006-2009 Carlos Garcia Campos <carlosgc@gnome.org>
     20// Copyright (C) 2006-2010 Carlos Garcia Campos <carlosgc@gnome.org>
    2121// Copyright (C) 2008, 2009 Adrian Johnson <ajohnson@redneon.com>
    2222// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
     
    157157  virtual void fill(GfxState *state);
    158158  virtual void eoFill(GfxState *state);
     159  virtual void clipToStrokePath(GfxState *state);
    159160  virtual GBool tilingPatternFill(GfxState *state, Object *str,
    160161                                  int paintType, Dict *resDict,
     
    269270protected:
    270271  void doPath(cairo_t *cairo, GfxState *state, GfxPath *path);
     272  cairo_surface_t *downscaleSurface(cairo_surface_t *orig_surface);
     273  void getScaledSize(int orig_width, int orig_height,
     274                     int *scaledWidth, int *scaledHeight);
     275  cairo_filter_t getFilterForSurface(cairo_surface_t *image,
     276                                     GBool interpolate);
     277  GBool getStreamData (Stream *str, char **buffer, int *length);
    271278 
    272279  GfxRGB fill_color, stroke_color;
  • trunk/poppler/mypoppler/poppler/Catalog.cc

    r277 r461  
    1515//
    1616// Copyright (C) 2005 Kristian HÞgsberg <krh@redhat.com>
    17 // Copyright (C) 2005-2009 Albert Astals Cid <aacid@kde.org>
     17// Copyright (C) 2005-2010 Albert Astals Cid <aacid@kde.org>
    1818// Copyright (C) 2005 Jeff Muizelaar <jrmuizel@nit.ca>
    1919// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
     
    2323// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
    2424// Copyright (C) 2008 Pino Toscano <pino@kde.org>
     25// Copyright (C) 2009 Ilya Gorenbein <igorenbein@finjan.com>
     26// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
    2527//
    2628// To see a description of the changes please see the Changelog file that
     
    7173  form = NULL;
    7274  optContent = NULL;
     75  pageMode = pageModeNull;
     76  pageLayout = pageLayoutNull;
     77  destNameTree = NULL;
     78  embeddedFileNameTree = NULL;
     79  jsNameTree = NULL;
    7380
    7481  xref->getCatalog(&catDict);
     
    7986  // get the AcroForm dictionary
    8087  catDict.dictLookup("AcroForm", &acroForm);
    81 
    82   // load Forms
    83   if (acroForm.isDict()) {
    84     form = new Form(xref,&acroForm);
    85   }
    86 
    8788
    8889  // read page tree
     
    100101    error(-1, "Page count in top-level pages object is wrong type (%s)",
    101102          obj.getTypeName());
    102     goto err3;
    103   }
    104   pagesSize = numPages0 = (int)obj.getNum();
     103    pagesSize = numPages0 = 0;
     104  } else {
     105    pagesSize = numPages0 = (int)obj.getNum();
     106  }
    105107  obj.free();
    106108  pages = (Page **)gmallocn(pagesSize, sizeof(Page *));
     
    126128  pagesDict.free();
    127129
    128   // read named destination dictionary
    129   catDict.dictLookup("Dests", &dests);
    130 
    131   // read root of named destination tree - PDF1.6 table 3.28
    132   if (catDict.dictLookup("Names", &obj)->isDict()) {
    133     obj.dictLookup("Dests", &obj2);
    134     destNameTree.init(xref, &obj2);
    135     obj2.free();
    136     obj.dictLookup("EmbeddedFiles", &obj2);
    137     embeddedFileNameTree.init(xref, &obj2);
    138     obj2.free();
    139     obj.dictLookup("JavaScript", &obj2);
    140     jsNameTree.init(xref, &obj2);
    141     obj2.free();
    142   }
    143   obj.free();
    144 
    145   if (catDict.dictLookup("PageLabels", &obj)->isDict())
    146     pageLabelInfo = new PageLabelInfo(&obj, numPages);
    147   obj.free();
    148 
    149   // read page mode
    150   pageMode = pageModeNone;
    151   if (catDict.dictLookup("PageMode", &obj)->isName()) {
    152     if (obj.isName("UseNone"))
    153       pageMode = pageModeNone;
    154     else if (obj.isName("UseOutlines"))
    155       pageMode = pageModeOutlines;
    156     else if (obj.isName("UseThumbs"))
    157       pageMode = pageModeThumbs;
    158     else if (obj.isName("FullScreen"))
    159       pageMode = pageModeFullScreen;
    160     else if (obj.isName("UseOC"))
    161       pageMode = pageModeOC;
    162     else if (obj.isName("UseAttachments"))
    163       pageMode = pageModeAttach;
    164   }
    165   obj.free();
    166 
    167   pageLayout = pageLayoutNone;
    168   if (catDict.dictLookup("PageLayout", &obj)->isName()) {
    169     if (obj.isName("SinglePage"))
    170       pageLayout = pageLayoutSinglePage;
    171     if (obj.isName("OneColumn"))
    172       pageLayout = pageLayoutOneColumn;
    173     if (obj.isName("TwoColumnLeft"))
    174       pageLayout = pageLayoutTwoColumnLeft;
    175     if (obj.isName("TwoColumnRight"))
    176       pageLayout = pageLayoutTwoColumnRight;
    177     if (obj.isName("TwoPageLeft"))
    178       pageLayout = pageLayoutTwoPageLeft;
    179     if (obj.isName("TwoPageRight"))
    180       pageLayout = pageLayoutTwoPageRight;
    181   }
    182   obj.free();
    183 
    184130  // read base URI
    185131  if (catDict.dictLookup("URI", &obj)->isDict()) {
     
    190136  }
    191137  obj.free();
    192 
    193   // get the metadata stream
    194   catDict.dictLookup("Metadata", &metadata);
    195 
    196   // get the structure tree root
    197   catDict.dictLookup("StructTreeRoot", &structTreeRoot);
    198 
    199   // get the outline dictionary
    200   catDict.dictLookup("Outlines", &outline);
    201138
    202139  // get the Optional Content dictionary
     
    211148
    212149  // perform form-related loading after all widgets have been loaded
    213   if (form)
    214     form->postWidgetsLoad();
     150  if (getForm())
     151    getForm()->postWidgetsLoad();
    215152
    216153  catDict.free();
    217154  return;
    218155
    219  err3:
    220   obj.free();
    221156 err2:
    222157  pagesDict.free();
    223158 err1:
    224159  catDict.free();
    225   dests.initNull();
    226160  ok = gFalse;
    227161}
     
    240174  }
    241175  dests.free();
    242   destNameTree.free();
    243   embeddedFileNameTree.free();
    244   jsNameTree.free();
     176  delete destNameTree;
     177  delete embeddedFileNameTree;
     178  delete jsNameTree;
    245179  if (baseURI) {
    246180    delete baseURI;
     
    260194  Object obj;
    261195  int c;
     196
     197  if (metadata.isNone()) {
     198    Object catDict;
     199
     200    xref->getCatalog(&catDict);
     201    if (catDict.isDict()) {
     202      catDict.dictLookup("Metadata", &metadata);
     203    } else {
     204      error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
     205      metadata.initNull();
     206    }
     207    catDict.free();
     208  }
    262209
    263210  if (!metadata.isStream()) {
     
    293240    error(-1, "Kids object (page %d) is wrong type (%s)",
    294241          start+1, kids.getTypeName());
    295     goto err1;
     242    return start;
    296243  }
    297244  for (i = 0; i < kids.arrayGetLength(); ++i) {
     
    310257    if (kid.isDict("Page")) {
    311258      attrs2 = new PageAttrs(attrs1, kid.getDict());
    312       page = new Page(xref, start+1, kid.getDict(), kidRef.getRef(), attrs2, form);
     259      page = new Page(xref, start+1, kid.getDict(), kidRef.getRef(), attrs2, getForm());
    313260      if (!page->isOk()) {
    314261        ++start;
     
    353300  kid.free();
    354301  kidRef.free();
    355  err1:
    356302  kids.free();
    357303  delete attrs1;
     
    377323  // try named destination dictionary then name tree
    378324  found = gFalse;
    379   if (dests.isDict()) {
    380     if (!dests.dictLookup(name->getCString(), &obj1)->isNull())
     325  if (getDests()->isDict()) {
     326    if (!getDests()->dictLookup(name->getCString(), &obj1)->isNull())
    381327      found = gTrue;
    382328    else
     
    384330  }
    385331  if (!found) {
    386     if (destNameTree.lookup(name, &obj1))
     332    if (getDestNameTree()->lookup(name, &obj1))
    387333      found = gTrue;
    388334    else
     
    418364    Object efDict;
    419365    Object obj;
    420     obj = embeddedFileNameTree.getValue(i);
     366    obj = getEmbeddedFileNameTree()->getValue(i);
    421367    EmbFile *embeddedFile = 0;
    422368    if (obj.isRef()) {
    423         GooString desc(embeddedFileNameTree.getName(i));
     369        GooString desc(getEmbeddedFileNameTree()->getName(i));
    424370        embeddedFile = new EmbFile(obj.fetch(xref, &efDict), &desc);
    425371        efDict.free();
     
    433379GooString *Catalog::getJS(int i)
    434380{
    435   Object obj = jsNameTree.getValue(i);
     381  Object obj = getJSNameTree()->getValue(i);
    436382  if (obj.isRef()) {
    437383    Ref r = obj.getRef();
     
    475421}
    476422
     423Catalog::PageMode Catalog::getPageMode() {
     424
     425  if (pageMode == pageModeNull) {
     426
     427    Object catDict, obj;
     428
     429    pageMode = pageModeNone;
     430
     431    xref->getCatalog(&catDict);
     432    if (!catDict.isDict()) {
     433      error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
     434      catDict.free();
     435      return pageMode;
     436    }
     437
     438    if (catDict.dictLookup("PageMode", &obj)->isName()) {
     439      if (obj.isName("UseNone"))
     440        pageMode = pageModeNone;
     441      else if (obj.isName("UseOutlines"))
     442        pageMode = pageModeOutlines;
     443      else if (obj.isName("UseThumbs"))
     444        pageMode = pageModeThumbs;
     445      else if (obj.isName("FullScreen"))
     446        pageMode = pageModeFullScreen;
     447      else if (obj.isName("UseOC"))
     448        pageMode = pageModeOC;
     449      else if (obj.isName("UseAttachments"))
     450        pageMode = pageModeAttach;
     451    }
     452    obj.free();
     453    catDict.free();
     454  }
     455  return pageMode;
     456}
     457
     458Catalog::PageLayout Catalog::getPageLayout() {
     459
     460  if (pageLayout == pageLayoutNull) {
     461
     462    Object catDict, obj;
     463
     464    pageLayout = pageLayoutNone;
     465
     466    xref->getCatalog(&catDict);
     467    if (!catDict.isDict()) {
     468      error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
     469      catDict.free();
     470      return pageLayout;
     471    }
     472
     473    pageLayout = pageLayoutNone;
     474    if (catDict.dictLookup("PageLayout", &obj)->isName()) {
     475      if (obj.isName("SinglePage"))
     476        pageLayout = pageLayoutSinglePage;
     477      if (obj.isName("OneColumn"))
     478        pageLayout = pageLayoutOneColumn;
     479      if (obj.isName("TwoColumnLeft"))
     480        pageLayout = pageLayoutTwoColumnLeft;
     481      if (obj.isName("TwoColumnRight"))
     482        pageLayout = pageLayoutTwoColumnRight;
     483      if (obj.isName("TwoPageLeft"))
     484        pageLayout = pageLayoutTwoPageLeft;
     485      if (obj.isName("TwoPageRight"))
     486        pageLayout = pageLayoutTwoPageRight;
     487    }
     488    obj.free();
     489    catDict.free();
     490  }
     491  return pageLayout;
     492}
     493
    477494NameTree::NameTree()
    478495{
     
    480497  length = 0;
    481498  entries = NULL;
     499}
     500
     501NameTree::~NameTree()
     502{
     503  int i;
     504
     505  for (i = 0; i < length; i++)
     506    delete entries[i];
     507
     508  gfree(entries);
    482509}
    483510
     
    591618}
    592619
    593 void NameTree::free()
    594 {
    595   int i;
    596 
    597   for (i = 0; i < length; i++)
    598     delete entries[i];
    599 
    600   gfree(entries);
    601 }
    602 
    603620GBool Catalog::labelToIndex(GooString *label, int *index)
    604621{
    605622  char *end;
    606623
    607   if (pageLabelInfo != NULL) {
    608     if (!pageLabelInfo->labelToIndex(label, index))
     624  PageLabelInfo *pli = getPageLabelInfo();
     625  if (pli != NULL) {
     626    if (!pli->labelToIndex(label, index))
    609627      return gFalse;
    610628  } else {
     
    627645    return gFalse;
    628646
    629   if (pageLabelInfo != NULL) {
    630     return pageLabelInfo->indexToLabel(index, label);
     647  PageLabelInfo *pli = getPageLabelInfo();
     648  if (pli != NULL) {
     649    return pli->indexToLabel(index, label);
    631650  } else {
    632651    snprintf(buffer, sizeof (buffer), "%d", index + 1);
     
    738757    m_mimetype = new GooString();
    739758}
     759
     760PageLabelInfo *Catalog::getPageLabelInfo()
     761{
     762  if (!pageLabelInfo) {
     763    Object catDict;
     764    Object obj;
     765
     766    xref->getCatalog(&catDict);
     767    if (!catDict.isDict()) {
     768      error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
     769      catDict.free();
     770      return NULL;
     771    }
     772
     773    if (catDict.dictLookup("PageLabels", &obj)->isDict()) {
     774      pageLabelInfo = new PageLabelInfo(&obj, getNumPages());
     775    }
     776    obj.free();
     777    catDict.free();
     778  }
     779
     780  return pageLabelInfo;
     781}
     782
     783Object *Catalog::getStructTreeRoot()
     784{
     785  if (structTreeRoot.isNone())
     786  {
     787     Object catDict;
     788
     789     xref->getCatalog(&catDict);
     790     if (catDict.isDict()) {
     791       catDict.dictLookup("StructTreeRoot", &structTreeRoot);
     792     } else {
     793       error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
     794       structTreeRoot.initNull();
     795     }
     796     catDict.free();
     797  }
     798
     799  return &structTreeRoot;
     800}
     801
     802Object *Catalog::getOutline()
     803{
     804  if (outline.isNone())
     805  {
     806     Object catDict;
     807
     808     xref->getCatalog(&catDict);
     809     if (catDict.isDict()) {
     810       catDict.dictLookup("Outlines", &outline);
     811     } else {
     812       error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
     813       outline.initNull();
     814     }
     815     catDict.free();
     816  }
     817
     818  return &outline;
     819}
     820
     821Object *Catalog::getDests()
     822{
     823  if (dests.isNone())
     824  {
     825     Object catDict;
     826
     827     xref->getCatalog(&catDict);
     828     if (catDict.isDict()) {
     829       catDict.dictLookup("Dests", &dests);
     830     } else {
     831       error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
     832       dests.initNull();
     833     }
     834     catDict.free();
     835  }
     836
     837  return &dests;
     838}
     839
     840Form *Catalog::getForm()
     841{
     842  if (!form) {
     843    if (acroForm.isDict()) {
     844      form = new Form(xref,&acroForm);
     845    }
     846  }
     847
     848  return form;
     849}
     850
     851Object *Catalog::getNames()
     852{
     853  if (names.isNone())
     854  {
     855     Object catDict;
     856
     857     xref->getCatalog(&catDict);
     858     if (catDict.isDict()) {
     859       catDict.dictLookup("Names", &names);
     860     } else {
     861       error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName());
     862       names.initNull();
     863     }
     864     catDict.free();
     865  }
     866
     867  return &names;
     868}
     869
     870NameTree *Catalog::getDestNameTree()
     871{
     872  if (!destNameTree) {
     873
     874    destNameTree = new NameTree();
     875
     876    if (getNames()->isDict()) {
     877       Object obj;
     878
     879       getNames()->dictLookup("Dests", &obj);
     880       destNameTree->init(xref, &obj);
     881       obj.free();
     882    }
     883
     884  }
     885
     886  return destNameTree;
     887}
     888
     889NameTree *Catalog::getEmbeddedFileNameTree()
     890{
     891  if (!embeddedFileNameTree) {
     892
     893    embeddedFileNameTree = new NameTree();
     894
     895    if (getNames()->isDict()) {
     896       Object obj;
     897
     898       getNames()->dictLookup("EmbeddedFiles", &obj);
     899       embeddedFileNameTree->init(xref, &obj);
     900       obj.free();
     901    }
     902
     903  }
     904
     905  return embeddedFileNameTree;
     906}
     907
     908NameTree *Catalog::getJSNameTree()
     909{
     910  if (!jsNameTree) {
     911
     912    jsNameTree = new NameTree();
     913
     914    if (getNames()->isDict()) {
     915       Object obj;
     916
     917       getNames()->dictLookup("JavaScript", &obj);
     918       jsNameTree->init(xref, &obj);
     919       obj.free();
     920    }
     921
     922  }
     923
     924  return jsNameTree;
     925}
     926
  • trunk/poppler/mypoppler/poppler/Catalog.h

    r277 r461  
    1515//
    1616// Copyright (C) 2005 Kristian HÞgsberg <krh@redhat.com>
    17 // Copyright (C) 2005, 2007, 2009 Albert Astals Cid <aacid@kde.org>
     17// Copyright (C) 2005, 2007, 2009, 2010 Albert Astals Cid <aacid@kde.org>
    1818// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
    1919// Copyright (C) 2005, 2006, 2008 Brad Hards <bradh@frogmouth.net>
    2020// Copyright (C) 2007 Julien Rebetez <julienr@svn.gnome.org>
    2121// Copyright (C) 2008 Pino Toscano <pino@kde.org>
     22// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
    2223//
    2324// To see a description of the changes please see the Changelog file that
     
    5051public:
    5152  NameTree();
     53  ~NameTree();
    5254  void init(XRef *xref, Object *tree);
    5355  void parse(Object *tree);
    5456  GBool lookup(GooString *name, Object *obj);
    55   void free();
    5657  int numEntries() { return length; };
    5758  // iterator accessor
     
    164165
    165166  // Return the structure tree root object.
    166   Object *getStructTreeRoot() { return &structTreeRoot; }
     167  Object *getStructTreeRoot();
    167168
    168169  // Find a page, given its object ID.  Returns page number, or 0 if
     
    174175  LinkDest *findDest(GooString *name);
    175176
    176   Object *getDests() { return &dests; }
     177  Object *getDests();
    177178
    178179  // Get the number of embedded files
    179   int numEmbeddedFiles() { return embeddedFileNameTree.numEntries(); }
     180  int numEmbeddedFiles() { return getEmbeddedFileNameTree()->numEntries(); }
    180181
    181182  // Get the i'th file embedded (at the Document level) in the document
     
    183184
    184185  // Get the number of javascript scripts
    185   int numJS() { return jsNameTree.numEntries(); }
     186  int numJS() { return getJSNameTree()->numEntries(); }
    186187
    187188  // Get the i'th JavaScript script (at the Document level) in the document
     
    192193  GBool indexToLabel(int index, GooString *label);
    193194
    194   Object *getOutline() { return &outline; }
     195  Object *getOutline();
    195196
    196197  Object *getAcroForm() { return &acroForm; }
     
    198199  OCGs *getOptContentConfig() { return optContent; }
    199200
    200   Form* getForm() { return form; }
     201  Form* getForm();
    201202
    202203  enum PageMode {
     
    206207    pageModeFullScreen,
    207208    pageModeOC,
    208     pageModeAttach
     209    pageModeAttach,
     210    pageModeNull
    209211  };
    210212  enum PageLayout {
     
    215217    pageLayoutTwoColumnRight,
    216218    pageLayoutTwoPageLeft,
    217     pageLayoutTwoPageRight
     219    pageLayoutTwoPageRight,
     220    pageLayoutNull
    218221  };
    219222
    220223  // Returns the page mode.
    221   PageMode getPageMode() { return pageMode; }
    222   PageLayout getPageLayout() { return pageLayout; }
     224  PageMode getPageMode();
     225  PageLayout getPageLayout();
    223226
    224227private:
     228
     229  // Get page label info.
     230  PageLabelInfo *getPageLabelInfo();
    225231
    226232  XRef *xref;                   // the xref table for this PDF file
     
    231237  int pagesSize;                // size of pages array
    232238  Object dests;                 // named destination dictionary
    233   NameTree destNameTree;        // named destination name-tree
    234   NameTree embeddedFileNameTree;  // embedded file name-tree
    235   NameTree jsNameTree;          // Java Script name-tree
     239  Object names;                 // named names dictionary
     240  NameTree *destNameTree;       // named destination name-tree
     241  NameTree *embeddedFileNameTree;  // embedded file name-tree
     242  NameTree *jsNameTree;         // Java Script name-tree
    236243  GooString *baseURI;           // base URI for URI-type links
    237244  Object metadata;              // metadata stream
     
    248255                   char *alreadyRead);
    249256  Object *findDestInTree(Object *tree, GooString *name, Object *obj);
     257
     258  Object *getNames();
     259  NameTree *getDestNameTree();
     260  NameTree *getEmbeddedFileNameTree();
     261  NameTree *getJSNameTree();
     262
    250263};
    251264
  • trunk/poppler/mypoppler/poppler/CharCodeToUnicode.cc

    r277 r461  
    1919// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
    2020// Copyright (C) 2008 Vasile Gaburici <gaburici@cs.umd.edu>
     21// Copyright (C) 2010 William Bader <williambader@hotmail.com>
     22// Copyright (C) 2010 Jakub Wilk <ubanus@users.sf.net>
    2123//
    2224// To see a description of the changes please see the Changelog file that
     
    125127  CharCodeToUnicode *ctu;
    126128  int line, n, i;
     129  char *tokptr;
    127130
    128131  if (!(f = fopen(fileName->getCString(), "r"))) {
     
    143146  while (getLine(buf, sizeof(buf), f)) {
    144147    ++line;
    145     if (!(tok = strtok(buf, " \t\r\n")) ||
     148    if (!(tok = strtok_r(buf, " \t\r\n", &tokptr)) ||
    146149        sscanf(tok, "%x", &u0) != 1) {
    147150      error(-1, "Bad line (%d) in unicodeToUnicode file '%s'",
     
    150153    }
    151154    n = 0;
    152     while ((tok = strtok(NULL, " \t\r\n"))) {
     155    while ((tok = strtok_r(NULL, " \t\r\n", &tokptr))) {
    153156      if (n >= uBufSize)
    154157      {
     
    308311          break;
    309312        }
    310         if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
    311               n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) {
     313        if (!(((n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>') ||
     314               (n1 == 4 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0')) &&
     315              ((n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>') ||
     316               (n2 == 4 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0')))) {
    312317          error(-1, "Illegal entry in bfrange block in ToUnicode CMap");
    313318          continue;
  • trunk/poppler/mypoppler/poppler/DCTStream.cc

    r277 r461  
    66//
    77// Copyright 2005 Jeff Muizelaar <jeff@infidigm.net>
    8 // Copyright 2005-2009 Albert Astals Cid <aacid@kde.org>
     8// Copyright 2005-2010 Albert Astals Cid <aacid@kde.org>
    99// Copyright 2009 Ryszard Trojnacki <rysiek@menel.com>
     10// Copyright 2010 Carlos Garcia Campos <carlosgc@gnome.org>
    1011//
    1112//========================================================================
     
    2122  int c;
    2223  struct str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
    23   if (src->abort) return FALSE;
    2424  if (src->index == 0) {
    2525    c = 0xFF;
     
    6060DCTStream::DCTStream(Stream *strA, int colorXformA) :
    6161  FilterStream(strA) {
     62  colorXform = colorXformA;
    6263  init();
    6364}
     
    7172  j_decompress_ptr cinfo = (j_decompress_ptr)error;
    7273  str_src_mgr * src = (struct str_src_mgr *)cinfo->src;
    73   src->abort = true;
     74  longjmp(src->setjmp_buffer, 1);
    7475}
    7576
     
    8788  src.str = str;
    8889  src.index = 0;
    89   src.abort = false;
    9090  current = NULL;
    9191  limit = NULL;
     
    123123      {
    124124        error(-1, "Could not find start of jpeg data");
    125         src.abort = true;
    126125        return;
    127126      }
     
    140139  }
    141140
    142   jpeg_read_header(&cinfo, TRUE);
    143   if (src.abort) return;
    144 
    145   if (!jpeg_start_decompress(&cinfo))
    146   {
    147     src.abort = true;
    148     return;
    149   }
    150 
    151   row_stride = cinfo.output_width * cinfo.output_components;
    152   row_buffer = cinfo.mem->alloc_sarray((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
     141  if (!setjmp(src.setjmp_buffer)) {
     142    jpeg_read_header(&cinfo, TRUE);
     143
     144    // figure out color transform
     145    if (colorXform == -1 && !cinfo.saw_Adobe_marker) {
     146      if (cinfo.num_components == 3) {
     147        if (cinfo.saw_JFIF_marker) {
     148          colorXform = 1;
     149        } else if (cinfo.cur_comp_info[0]->component_id == 82 &&
     150                   cinfo.cur_comp_info[1]->component_id == 71 &&
     151                   cinfo.cur_comp_info[2]->component_id == 66) { // ASCII "RGB"
     152          colorXform = 0;
     153        } else {
     154          colorXform = 1;
     155        }
     156      } else {
     157        colorXform = 0;
     158      }
     159    } else if (cinfo.saw_Adobe_marker) {
     160      colorXform = cinfo.Adobe_transform;
     161    }
     162
     163    switch (cinfo.num_components) {
     164    case 3:
     165            cinfo.jpeg_color_space = colorXform ? JCS_YCbCr : JCS_RGB;
     166            break;
     167    case 4:
     168            cinfo.jpeg_color_space = colorXform ? JCS_YCCK : JCS_CMYK;
     169            break;
     170    }
     171
     172    jpeg_start_decompress(&cinfo);
     173
     174    row_stride = cinfo.output_width * cinfo.output_components;
     175    row_buffer = cinfo.mem->alloc_sarray((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1);
     176  }
    153177}
    154178
    155179int DCTStream::getChar() {
    156   if (src.abort) return EOF;
    157  
    158180  int c;
    159181
     
    161183    if (cinfo.output_scanline < cinfo.output_height)
    162184    {
    163       if (!jpeg_read_scanlines(&cinfo, row_buffer, 1)) return EOF;
    164       current = &row_buffer[0][0];
    165       limit = &row_buffer[0][(cinfo.output_width - 1) * cinfo.output_components] + cinfo.output_components;
     185      if (!setjmp(src.setjmp_buffer))
     186      {
     187        if (!jpeg_read_scanlines(&cinfo, row_buffer, 1)) return EOF;
     188        current = &row_buffer[0][0];
     189        limit = &row_buffer[0][(cinfo.output_width - 1) * cinfo.output_components] + cinfo.output_components;
     190      }
     191      else return EOF;
    166192    }
    167193    else return EOF;
     
    173199
    174200int DCTStream::lookChar() {
    175   if (src.abort) return EOF;
    176  
    177201  return *current;
    178202}
  • trunk/poppler/mypoppler/poppler/DCTStream.h

    r277 r461  
    77// Copyright 2005 Jeff Muizelaar <jeff@infidigm.net>
    88// Copyright 2005 Martin Kretzschmar <martink@gnome.org>
    9 // Copyright 2005-2007, 2009 Albert Astals Cid <aacid@kde.org>
     9// Copyright 2005-2007, 2009, 2010 Albert Astals Cid <aacid@kde.org>
     10// Copyright 2010 Carlos Garcia Campos <carlosgc@gnome.org>
    1011//
    1112//========================================================================
     
    2728#include <stdlib.h>
    2829#include <stddef.h>
     30#include <setjmp.h>
    2931#ifdef HAVE_UNISTD_H
    3032#include <unistd.h>
     
    4951    Stream *str;
    5052    int index;
    51     bool abort;
     53    jmp_buf setjmp_buffer;
    5254};
    5355
     
    6971  void init();
    7072
     73  int colorXform;
    7174  JSAMPLE *current;
    7275  JSAMPLE *limit;
  • trunk/poppler/mypoppler/poppler/Form.cc

    r277 r461  
    66//
    77// Copyright 2006-2008 Julien Rebetez <julienr@svn.gnome.org>
    8 // Copyright 2007-2009 Albert Astals Cid <aacid@kde.org>
     8// Copyright 2007-2010 Albert Astals Cid <aacid@kde.org>
    99// Copyright 2007-2008 Carlos Garcia Campos <carlosgc@gnome.org>
    1010// Copyright 2007 Adrian Johnson <ajohnson@redneon.com>
     
    991991{
    992992  if (!content) return NULL;
    993   return new GooString(*content);
     993  return new GooString(content);
    994994}
    995995
  • trunk/poppler/mypoppler/poppler/Function.cc

    r277 r461  
    1414// under GPL version 2 or later
    1515//
    16 // Copyright (C) 2006, 2008, 2009 Albert Astals Cid <aacid@kde.org>
     16// Copyright (C) 2006, 2008-2010 Albert Astals Cid <aacid@kde.org>
    1717// Copyright (C) 2006 Jeff Muizelaar <jeff@infidigm.net>
    1818//
     
    10131013  } else {
    10141014    j = n - j;
    1015     obj = stack[sp + n - 1];
    1016     for (k = sp + n - 1; k > sp; --k) {
    1017       stack[k] = stack[k-1];
    1018     }
    1019     stack[sp] = obj;
     1015    for (i = 0; i < j; ++i) {
     1016      obj = stack[sp + n - 1];
     1017      for (k = sp + n - 1; k > sp; --k) {
     1018        stack[k] = stack[k-1];
     1019      }
     1020      stack[sp] = obj;
     1021    }
    10201022  }
    10211023}
  • trunk/poppler/mypoppler/poppler/Gfx.cc

    r277 r461  
    1515//
    1616// Copyright (C) 2005 Jonathan Blandford <jrb@redhat.com>
    17 // Copyright (C) 2005-2009 Albert Astals Cid <aacid@kde.org>
     17// Copyright (C) 2005-2010 Albert Astals Cid <aacid@kde.org>
    1818// Copyright (C) 2006 Thorkild Stray <thorkild@ifi.uio.no>
    1919// Copyright (C) 2006 Kristian HÞgsberg <krh@redhat.com>
    20 // Copyright (C) 2006-2009 Carlos Garcia Campos <carlosgc@gnome.org>
     20// Copyright (C) 2006-2010 Carlos Garcia Campos <carlosgc@gnome.org>
    2121// Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
    2222// Copyright (C) 2007, 2008 Brad Hards <bradh@kde.org>
     
    2929// Copyright (C) 2008 Hib Eris <hib@hiberis.nl>
    3030// Copyright (C) 2009 M Joonas Pihlaja <jpihlaja@cc.helsinki.fi>
    31 // Copyright (C) 2009 Thomas Freitag <Thomas.Freitag@alfa.de>
     31// Copyright (C) 2009, 2010 Thomas Freitag <Thomas.Freitag@alfa.de>
    3232// Copyright (C) 2009 William Bader <williambader@hotmail.com>
    33 // Copyright (C) 2009 David Benjamin <davidben@mit.edu>
     33// Copyright (C) 2009, 2010 David Benjamin <davidben@mit.edu>
     34// Copyright (C) 2010 Nils Höglund <nils.hoglund@gmail.com>
    3435//
    3536// To see a description of the changes please see the Changelog file that
     
    308309//------------------------------------------------------------------------
    309310
    310 GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) {
     311GfxResources::GfxResources(XRef *xref, Dict *resDict, GfxResources *nextA) :
     312    gStateCache(2, xref) {
    311313  Object obj1, obj2;
    312314  Ref r;
     
    481483
    482484GBool GfxResources::lookupGState(char *name, Object *obj) {
     485  if (!lookupGStateNF(name, obj))
     486    return gFalse;
     487
     488  if (!obj->isRef())
     489    return gTrue;
     490 
     491  const Ref ref = obj->getRef();
     492  if (!gStateCache.lookup(ref, obj)->isNull())
     493    return gTrue;
     494  obj->free();
     495
     496  gStateCache.put(ref)->copy(obj);
     497  return gTrue;
     498}
     499
     500GBool GfxResources::lookupGStateNF(char *name, Object *obj) {
    483501  GfxResources *resPtr;
    484502
    485503  for (resPtr = this; resPtr; resPtr = resPtr->next) {
    486504    if (resPtr->gStateDict.isDict()) {
    487       if (!resPtr->gStateDict.dictLookup(name, obj)->isNull()) {
     505      if (!resPtr->gStateDict.dictLookupNF(name, obj)->isNull()) {
    488506        return gTrue;
    489507      }
     
    526544  out = outA;
    527545  state = new GfxState(hDPI, vDPI, box, rotate, out->upsideDown());
     546  stackHeight = 1;
     547  pushStateGuard();
    528548  fontChanged = gFalse;
    529549  clip = clipNone;
     
    578598  out = outA;
    579599  state = new GfxState(72, 72, box, 0, gFalse);
     600  stackHeight = 1;
     601  pushStateGuard();
    580602  fontChanged = gFalse;
    581603  clip = clipNone;
     
    602624
    603625Gfx::~Gfx() {
     626  while (stateGuards.size()) {
     627    popStateGuard();
     628  }
     629  // There shouldn't be more saves, but pop them if there were any
    604630  while (state->hasSaves()) {
     631    error(-1, "Found state under last state guard. Popping.");
    605632    restoreState();
    606633  }
     
    650677
    651678  // scan a sequence of objects
     679  pushStateGuard();
    652680  updateLevel = lastAbortCheck = 0;
    653681  numArgs = 0;
    654682  parser->getObj(&obj);
    655683  while (!obj.isEOF()) {
     684    commandAborted = gFalse;
    656685
    657686    // got a command - execute it
     
    701730      }
    702731
     732      // did the command throw an exception
     733      if (commandAborted) {
     734        // don't propogate; recursive drawing comes from Form XObjects which
     735        // should probably be drawn in a separate context anyway for caching
     736        commandAborted = gFalse;
     737        break;
     738      }
     739
    703740      // check for an abort
    704741      if (abortCheckCbk) {
     
    748785  }
    749786
     787  popStateGuard();
     788
    750789  // update display
    751790  if (topLevel && updateLevel > 0) {
     
    773812    if (numArgs < op->numArgs) {
    774813      error(getPos(), "Too few (%d) args to '%s' operator", numArgs, name);
     814      commandAborted = gTrue;
    775815      return;
    776816    }
     
    12581298  GfxColor color;
    12591299
    1260   if (textHaveCSPattern) {
     1300  if (textHaveCSPattern && drawText) {
    12611301    GBool needFill = out->deviceHasTextClip(state);
    12621302    out->endTextObject(state);
     
    12651305    }
    12661306    out->restoreState(state);
    1267     state->setFillPattern(NULL);
    1268     state->setFillColorSpace(new GfxDeviceGrayColorSpace());
    1269     out->updateFillColorSpace(state);
    1270     color.c[0] = dblToCol(args[0].getNum());
    1271     state->setFillColor(&color);
    1272     out->updateFillColor(state);
     1307  }
     1308  state->setFillPattern(NULL);
     1309  state->setFillColorSpace(new GfxDeviceGrayColorSpace());
     1310  out->updateFillColorSpace(state);
     1311  color.c[0] = dblToCol(args[0].getNum());
     1312  state->setFillColor(&color);
     1313  out->updateFillColor(state);
     1314  if (textHaveCSPattern) {
    12731315    out->beginTextObject(state);
    12741316    out->updateRender(state);
     
    12761318    out->updateTextPos(state);
    12771319    textHaveCSPattern = gFalse;
    1278   } else {
    1279     state->setFillPattern(NULL);
    1280     state->setFillColorSpace(new GfxDeviceGrayColorSpace());
    1281     out->updateFillColorSpace(state);
    1282     color.c[0] = dblToCol(args[0].getNum());
    1283     state->setFillColor(&color);
    1284     out->updateFillColor(state);
    12851320  }
    12861321}
     
    13011336  int i;
    13021337
     1338  if (textHaveCSPattern && drawText) {
     1339    GBool needFill = out->deviceHasTextClip(state);
     1340    out->endTextObject(state);
     1341    if (needFill) {
     1342      doPatternFill(gTrue);
     1343    }
     1344    out->restoreState(state);
     1345  }
     1346  state->setFillPattern(NULL);
     1347  state->setFillColorSpace(new GfxDeviceCMYKColorSpace());
     1348  out->updateFillColorSpace(state);
     1349  for (i = 0; i < 4; ++i) {
     1350    color.c[i] = dblToCol(args[i].getNum());
     1351  }
     1352  state->setFillColor(&color);
     1353  out->updateFillColor(state);
    13031354  if (textHaveCSPattern) {
    1304     colorSpaceText = new GfxDeviceCMYKColorSpace();
    1305     for (i = 0; i < 4; ++i) {
    1306       colorText.c[i] = dblToCol(args[i].getNum());
    1307     }
    1308   } else {
    1309     state->setFillPattern(NULL);
    1310     state->setFillColorSpace(new GfxDeviceCMYKColorSpace());
    1311     out->updateFillColorSpace(state);
    1312     for (i = 0; i < 4; ++i) {
    1313       color.c[i] = dblToCol(args[i].getNum());
    1314     }
    1315     state->setFillColor(&color);
    1316     out->updateFillColor(state);
     1355    out->beginTextObject(state);
     1356    out->updateRender(state);
     1357    out->updateTextMat(state);
     1358    out->updateTextPos(state);
     1359    textHaveCSPattern = gFalse;
    13171360  }
    13181361}
     
    13361379  int i;
    13371380
     1381  if (textHaveCSPattern && drawText) {
     1382    GBool needFill = out->deviceHasTextClip(state);
     1383    out->endTextObject(state);
     1384    if (needFill) {
     1385      doPatternFill(gTrue);
     1386    }
     1387    out->restoreState(state);
     1388  }
     1389  state->setFillPattern(NULL);
     1390  state->setFillColorSpace(new GfxDeviceRGBColorSpace());
     1391  out->updateFillColorSpace(state);
     1392  for (i = 0; i < 3; ++i) {
     1393    color.c[i] = dblToCol(args[i].getNum());
     1394  }
     1395  state->setFillColor(&color);
     1396  out->updateFillColor(state);
    13381397  if (textHaveCSPattern) {
    1339     colorSpaceText = new GfxDeviceRGBColorSpace();
    1340     for (i = 0; i < 3; ++i) {
    1341       colorText.c[i] = dblToCol(args[i].getNum());
    1342     }
    1343   } else {
    1344     state->setFillPattern(NULL);
    1345     state->setFillColorSpace(new GfxDeviceRGBColorSpace());
    1346     out->updateFillColorSpace(state);
    1347     for (i = 0; i < 3; ++i) {
    1348       color.c[i] = dblToCol(args[i].getNum());
    1349     }
    1350     state->setFillColor(&color);
    1351     out->updateFillColor(state);
     1398    out->beginTextObject(state);
     1399    out->updateRender(state);
     1400    out->updateTextMat(state);
     1401    out->updateTextPos(state);
     1402    textHaveCSPattern = gFalse;
    13521403  }
    13531404}
     
    13721423  GfxColor color;
    13731424
    1374   state->setFillPattern(NULL);
    13751425  res->lookupColorSpace(args[0].getName(), &obj);
    13761426  if (obj.isNull()) {
     
    13811431  obj.free();
    13821432  if (colorSpace) {
     1433    if (textHaveCSPattern && drawText) {
     1434      GBool needFill = out->deviceHasTextClip(state);
     1435      out->endTextObject(state);
     1436      if (needFill) {
     1437        doPatternFill(gTrue);
     1438      }
     1439      out->restoreState(state);
     1440    }
     1441    state->setFillPattern(NULL);
    13831442    state->setFillColorSpace(colorSpace);
    13841443    out->updateFillColorSpace(state);
     
    13861445    state->setFillColor(&color);
    13871446    out->updateFillColor(state);
    1388     if (drawText) {
    1389       if (colorSpace->getMode() == csPattern) {
    1390         colorSpaceText = NULL;
    1391         textHaveCSPattern = gTrue;
    1392         out->beginTextObject(state);
    1393       } else if (textHaveCSPattern) {
    1394         GBool needFill = out->deviceHasTextClip(state);
    1395         out->endTextObject(state);
    1396         if (needFill) {
    1397           doPatternFill(gTrue);
    1398         }
    1399         out->beginTextObject(state);
    1400         out->updateRender(state);
    1401         out->updateTextMat(state);
    1402         out->updateTextPos(state);
    1403         textHaveCSPattern = gFalse;
    1404       }
     1447    if (textHaveCSPattern) {
     1448      out->beginTextObject(state);
     1449      out->updateRender(state);
     1450      out->updateTextMat(state);
     1451      out->updateTextPos(state);
     1452      textHaveCSPattern = colorSpace->getMode() == csPattern;
     1453    } else if (drawText && out->supportTextCSPattern(state)) {
     1454      out->beginTextObject(state);
     1455      textHaveCSPattern = gTrue;
    14051456