~ubuntu-branches/debian/experimental/cups-filters/experimental

« back to all changes in this revision

Viewing changes to pdftopdf/P2PCharCodeToUnicode.cxx

  • Committer: Package Import Robot
  • Author(s): Till Kamppeter
  • Date: 2012-07-22 18:57:32 UTC
  • mfrom: (1.1.17)
  • Revision ID: package-import@ubuntu.com-20120722185732-26kkte5p1lth3rt5
Tags: 1.0.20-0bzr1
* New upstream release
   - pdftops: Added another workaround for Kyocera printers: Some
     models get very slow on images which request interpolation,
     so now we remove the image interpolation requests by additional
     PostScript code only inserted for Kyocera printers (LP: #1026974).
   - Made the Poppler-based filters pdftopdf and pdftoopvp build with
     both Poppler 0.18.x and 0.20.x (Upstream bug #1055).
   - Fixes according to Coverity scan results (Upstream bug #1054).
   - Switched build system to autotools. This especially fixes several
     build problems in Gentoo. Also build-tested with CUPS 1.6.0b1.
   - Fixes for compatibility with clang/gcc-4.7.
   - textonly: Filter did not work as a pipe with copies=1 (Upstream bug
     #1032).
   - texttopdf: Avoid trimming the results of FcFontSort(), as this may
     miss some reasonable candidates under certain circumstances. BTW,
     fix passing a non-pointer as a pointer to "result" (Closes: #670055).
   - Corrected documentation. The option for the maximum image rendering
     resolution in pdftops is "pdftops-max-image-resolution", not
     "pdftops-max-image-resolution-default".
* debian/patches/fcfontsort-no-trim.patch: Removed, fixed upstream.
* debian/rules: Updated options for ./configure and make for the new autotools
  build system.
* debian/watch: Switched to bz2 upstream packages.
* debian/rules, debian/copyright, debian/cups-filters.docs: Updated for
  renamed documentation files.
* debian/control, debian/libfontembed1.install,
  debian/libfontembed-dev.install: Added new binary packages for libfontembed.
* debian/copyright: Updated for recent file additions, and rearrangement of
  directories.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
//========================================================================
2
 
//
3
 
// P2PCharCodeToUnicode.cc
4
 
//
5
 
// BBR Inc.
6
 
//
7
 
// Based Poppler CharCodeToUnicode.h
8
 
// Copyright 2001-2003 Glyph & Cog, LLC
9
 
//
10
 
//========================================================================
11
 
 
12
 
#include <config.h>
13
 
 
14
 
#ifdef USE_GCC_PRAGMAS
15
 
#pragma implementation
16
 
#endif
17
 
 
18
 
#include <stdio.h>
19
 
#include <string.h>
20
 
#include "goo/gmem.h"
21
 
#include "goo/GooString.h"
22
 
#include "P2PError.h"
23
 
#include "GlobalParams.h"
24
 
#include "PSTokenizer.h"
25
 
#include "P2PCharCodeToUnicode.h"
26
 
 
27
 
//------------------------------------------------------------------------
28
 
 
29
 
#define maxUnicodeString 8
30
 
 
31
 
struct P2PCharCodeToUnicodeString {
32
 
  CharCode c;
33
 
  Unicode u[maxUnicodeString];
34
 
  int len;
35
 
};
36
 
 
37
 
//------------------------------------------------------------------------
38
 
 
39
 
static int getCharFromFile(void *data) {
40
 
  return fgetc((FILE *)data);
41
 
}
42
 
 
43
 
//------------------------------------------------------------------------
44
 
 
45
 
P2PCharCodeToUnicode *P2PCharCodeToUnicode::parseCMapFromFile(
46
 
    GooString *fileName, int nBits) {
47
 
  P2PCharCodeToUnicode *ctu;
48
 
  FILE *f;
49
 
 
50
 
  ctu = new P2PCharCodeToUnicode();
51
 
  if ((f = globalParams->findToUnicodeFile(fileName))) {
52
 
    ctu->parseCMap1(&getCharFromFile, f, nBits);
53
 
    fclose(f);
54
 
  } else {
55
 
    p2pError(-1, const_cast<char *>("Couldn't find ToUnicode CMap file for '%s'"),
56
 
          fileName->getCString());
57
 
  }
58
 
  return ctu;
59
 
}
60
 
 
61
 
void P2PCharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data,
62
 
                                   int nBits) {
63
 
  PSTokenizer *pst;
64
 
  char tok1[256], tok2[256], tok3[256];
65
 
  int nDigits, n1, n2, n3;
66
 
  CharCode i;
67
 
  CharCode code1, code2;
68
 
  GooString *name;
69
 
  FILE *f;
70
 
 
71
 
  nDigits = nBits / 4;
72
 
  pst = new PSTokenizer(getCharFunc, data);
73
 
  pst->getToken(tok1, sizeof(tok1), &n1);
74
 
  while (pst->getToken(tok2, sizeof(tok2), &n2)) {
75
 
    if (!strcmp(tok2, "usecmap")) {
76
 
      if (tok1[0] == '/') {
77
 
        name = new GooString(tok1 + 1);
78
 
        if ((f = globalParams->findToUnicodeFile(name))) {
79
 
          parseCMap1(&getCharFromFile, f, nBits);
80
 
          fclose(f);
81
 
        } else {
82
 
          p2pError(-1, const_cast<char *>("Couldn't find ToUnicode CMap file for '%s'"),
83
 
                name->getCString());
84
 
        }
85
 
        delete name;
86
 
      }
87
 
      pst->getToken(tok1, sizeof(tok1), &n1);
88
 
    } else if (!strcmp(tok2, "beginbfchar")) {
89
 
      while (pst->getToken(tok1, sizeof(tok1), &n1)) {
90
 
        if (!strcmp(tok1, "endbfchar")) {
91
 
          break;
92
 
        }
93
 
        if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
94
 
            !strcmp(tok2, "endbfchar")) {
95
 
          p2pError(-1, const_cast<char *>("Illegal entry in bfchar block in ToUnicode CMap"));
96
 
          break;
97
 
        }
98
 
        if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
99
 
              tok2[0] == '<' && tok2[n2 - 1] == '>')) {
100
 
          
101
 
          // check there was no line jump inside the token and so the length is 
102
 
          // longer than it should be
103
 
          int countAux = 0;
104
 
          for (int k = 0; k < n1; k++)
105
 
            if (tok1[k] != '\n' && tok1[k] != '\r') countAux++;
106
 
        
107
 
          if (!(countAux == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
108
 
              tok2[0] == '<' && tok2[n2 - 1] == '>')) {
109
 
            p2pError(-1, const_cast<char *>("Illegal entry in bfchar block in ToUnicode CMap"));
110
 
            continue;
111
 
          }
112
 
        }
113
 
        tok1[n1 - 1] = tok2[n2 - 1] = '\0';
114
 
        if (sscanf(tok1 + 1, "%x", &code1) != 1) {
115
 
          p2pError(-1, const_cast<char *>("Illegal entry in bfchar block in ToUnicode CMap"));
116
 
          continue;
117
 
        }
118
 
        addMapping(code1, tok2 + 1, n2 - 2, 0);
119
 
      }
120
 
      pst->getToken(tok1, sizeof(tok1), &n1);
121
 
    } else if (!strcmp(tok2, "beginbfrange")) {
122
 
      while (pst->getToken(tok1, sizeof(tok1), &n1)) {
123
 
        if (!strcmp(tok1, "endbfrange")) {
124
 
          break;
125
 
        }
126
 
        if (!pst->getToken(tok2, sizeof(tok2), &n2) ||
127
 
            !strcmp(tok2, "endbfrange") ||
128
 
            !pst->getToken(tok3, sizeof(tok3), &n3) ||
129
 
            !strcmp(tok3, "endbfrange")) {
130
 
          p2pError(-1, const_cast<char *>("Illegal entry in bfrange block in ToUnicode CMap"));
131
 
          break;
132
 
        }
133
 
        if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
134
 
              n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) {
135
 
          // check there was no line jump inside the token and so the length is 
136
 
          // longer than it should be
137
 
          int countAux = 0;
138
 
          for (int k = 0; k < n1; k++)
139
 
            if (tok1[k] != '\n' && tok1[k] != '\r') countAux++;
140
 
          
141
 
          int countAux2 = 0;
142
 
          for (int k = 0; k < n1; k++)
143
 
            if (tok2[k] != '\n' && tok2[k] != '\r') countAux++;
144
 
          
145
 
          if (!(countAux == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' &&
146
 
              countAux2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) {
147
 
            p2pError(-1, const_cast<char *>("Illegal entry in bfrange block in ToUnicode CMap"));
148
 
            continue;
149
 
          }
150
 
        }
151
 
        tok1[n1 - 1] = tok2[n2 - 1] = '\0';
152
 
        if (sscanf(tok1 + 1, "%x", &code1) != 1 ||
153
 
            sscanf(tok2 + 1, "%x", &code2) != 1) {
154
 
          p2pError(-1, const_cast<char *>("Illegal entry in bfrange block in ToUnicode CMap"));
155
 
          continue;
156
 
        }
157
 
        if (!strcmp(tok3, "[")) {
158
 
          i = 0;
159
 
          while (pst->getToken(tok1, sizeof(tok1), &n1) &&
160
 
                 code1 + i <= code2) {
161
 
            if (!strcmp(tok1, "]")) {
162
 
              break;
163
 
            }
164
 
            if (tok1[0] == '<' && tok1[n1 - 1] == '>') {
165
 
              tok1[n1 - 1] = '\0';
166
 
              addMapping(code1 + i, tok1 + 1, n1 - 2, 0);
167
 
            } else {
168
 
              p2pError(-1, const_cast<char *>("Illegal entry in bfrange block in ToUnicode CMap"));
169
 
            }
170
 
            ++i;
171
 
          }
172
 
        } else if (tok3[0] == '<' && tok3[n3 - 1] == '>') {
173
 
          tok3[n3 - 1] = '\0';
174
 
          for (i = 0; code1 <= code2; ++code1, ++i) {
175
 
            addMapping(code1, tok3 + 1, n3 - 2, i);
176
 
          }
177
 
 
178
 
        } else {
179
 
          p2pError(-1, const_cast<char *>("Illegal entry in bfrange block in ToUnicode CMap"));
180
 
        }
181
 
      }
182
 
      pst->getToken(tok1, sizeof(tok1), &n1);
183
 
    } else {
184
 
      strcpy(tok1, tok2);
185
 
    }
186
 
  }
187
 
  delete pst;
188
 
}
189
 
 
190
 
void P2PCharCodeToUnicode::addMapping(CharCode code, char *uStr, int n,
191
 
                                   int offset) {
192
 
  CharCode oldLen, i;
193
 
  Unicode u;
194
 
  char uHex[5];
195
 
  int j;
196
 
 
197
 
  if (code >= mapLen) {
198
 
    oldLen = mapLen;
199
 
    mapLen = (code + 256) & ~255;
200
 
    map = (Unicode *)greallocn(map, mapLen, sizeof(Unicode));
201
 
    for (i = oldLen; i < mapLen; ++i) {
202
 
      map[i] = 0;
203
 
    }
204
 
  }
205
 
  if (n <= 4) {
206
 
    if (sscanf(uStr, "%x", &u) != 1) {
207
 
      p2pError(-1, const_cast<char *>("Illegal entry in ToUnicode CMap"));
208
 
      return;
209
 
    }
210
 
    map[code] = u + offset;
211
 
  } else {
212
 
    if (sMapLen >= sMapSize) {
213
 
      sMapSize = sMapSize + 16;
214
 
      sMap = (P2PCharCodeToUnicodeString *)
215
 
               greallocn(sMap, sMapSize, sizeof(P2PCharCodeToUnicodeString));
216
 
    }
217
 
    map[code] = 0;
218
 
    sMap[sMapLen].c = code;
219
 
    sMap[sMapLen].len = n / 4;
220
 
    for (j = 0; j < sMap[sMapLen].len && j < maxUnicodeString; ++j) {
221
 
      strncpy(uHex, uStr + j*4, 4);
222
 
      uHex[4] = '\0';
223
 
      if (sscanf(uHex, "%x", &sMap[sMapLen].u[j]) != 1) {
224
 
        p2pError(-1, const_cast<char *>("Illegal entry in ToUnicode CMap"));
225
 
      }
226
 
    }
227
 
    sMap[sMapLen].u[sMap[sMapLen].len - 1] += offset;
228
 
    ++sMapLen;
229
 
  }
230
 
}
231
 
 
232
 
P2PCharCodeToUnicode::P2PCharCodeToUnicode() {
233
 
  CharCode i;
234
 
 
235
 
  mapLen = 256;
236
 
  map = (Unicode *)gmallocn(mapLen, sizeof(Unicode));
237
 
  for (i = 0; i < mapLen; ++i) {
238
 
    map[i] = 0;
239
 
  }
240
 
  sMap = NULL;
241
 
  sMapLen = sMapSize = 0;
242
 
}
243
 
 
244
 
P2PCharCodeToUnicode::~P2PCharCodeToUnicode() {
245
 
  gfree(map);
246
 
  if (sMap) {
247
 
    gfree(sMap);
248
 
  }
249
 
}
250
 
 
251
 
int P2PCharCodeToUnicode::mapToUnicode(CharCode c, Unicode *u, int size) {
252
 
  int i, j;
253
 
 
254
 
  if (c >= mapLen) {
255
 
    return 0;
256
 
  }
257
 
  if (map[c]) {
258
 
    u[0] = map[c];
259
 
    return 1;
260
 
  }
261
 
  for (i = 0; i < sMapLen; ++i) {
262
 
    if (sMap[i].c == c) {
263
 
      for (j = 0; j < sMap[i].len && j < size; ++j) {
264
 
        u[j] = sMap[i].u[j];
265
 
      }
266
 
      return j;
267
 
    }
268
 
  }
269
 
  return 0;
270
 
}