Coverage Report

Created: 2023-09-25 06:41

/src/xpdf-4.04/splash/SplashFontEngine.cc
Line
Count
Source (jump to first uncovered line)
1
//========================================================================
2
//
3
// SplashFontEngine.cc
4
//
5
// Copyright 2003-2013 Glyph & Cog, LLC
6
//
7
//========================================================================
8
9
#include <aconf.h>
10
11
#ifdef USE_GCC_PRAGMAS
12
#pragma implementation
13
#endif
14
15
#include <stdlib.h>
16
#include <stdio.h>
17
#ifndef _WIN32
18
#  include <unistd.h>
19
#endif
20
#include "gmem.h"
21
#include "gmempp.h"
22
#include "GString.h"
23
#include "GList.h"
24
#include "SplashMath.h"
25
#include "SplashFTFontEngine.h"
26
#include "SplashFontFile.h"
27
#include "SplashFontFileID.h"
28
#include "SplashFont.h"
29
#include "SplashFontEngine.h"
30
31
#ifdef VMS
32
#if (__VMS_VER < 70000000)
33
extern "C" int unlink(char *filename);
34
#endif
35
#endif
36
37
//------------------------------------------------------------------------
38
// SplashFontEngine
39
//------------------------------------------------------------------------
40
41
SplashFontEngine::SplashFontEngine(
42
#if HAVE_FREETYPE_H
43
           GBool enableFreeType,
44
           Guint freeTypeFlags,
45
#endif
46
0
           GBool aa) {
47
0
  int i;
48
49
0
  for (i = 0; i < splashFontCacheSize; ++i) {
50
0
    fontCache[i] = NULL;
51
0
  }
52
0
  badFontFiles = new GList();
53
54
0
#if HAVE_FREETYPE_H
55
0
  if (enableFreeType) {
56
0
    ftEngine = SplashFTFontEngine::init(aa, freeTypeFlags);
57
0
  } else {
58
0
    ftEngine = NULL;
59
0
  }
60
0
#endif
61
0
}
62
63
0
SplashFontEngine::~SplashFontEngine() {
64
0
  int i;
65
66
0
  for (i = 0; i < splashFontCacheSize; ++i) {
67
0
    if (fontCache[i]) {
68
0
      delete fontCache[i];
69
0
    }
70
0
  }
71
0
  deleteGList(badFontFiles, SplashFontFileID);
72
73
0
#if HAVE_FREETYPE_H
74
0
  if (ftEngine) {
75
0
    delete ftEngine;
76
0
  }
77
0
#endif
78
0
}
79
80
0
SplashFontFile *SplashFontEngine::getFontFile(SplashFontFileID *id) {
81
0
  SplashFontFile *fontFile;
82
0
  int i;
83
84
0
  for (i = 0; i < splashFontCacheSize; ++i) {
85
0
    if (fontCache[i]) {
86
0
      fontFile = fontCache[i]->getFontFile();
87
0
      if (fontFile && fontFile->getID()->matches(id)) {
88
0
  return fontFile;
89
0
      }
90
0
    }
91
0
  }
92
0
  return NULL;
93
0
}
94
95
0
GBool SplashFontEngine::checkForBadFontFile(SplashFontFileID *id) {
96
0
  for (int i = 0; i < badFontFiles->getLength(); ++i) {
97
0
    if (((SplashFontFileID *)badFontFiles->get(i))->matches(id)) {
98
0
      return gTrue;
99
0
    }
100
0
  }
101
0
  return gFalse;
102
0
}
103
104
SplashFontFile *SplashFontEngine::loadType1Font(SplashFontFileID *idA,
105
#if LOAD_FONTS_FROM_MEM
106
            GString *fontBuf,
107
#else
108
            char *fileName,
109
            GBool deleteFile,
110
#endif
111
0
            const char **enc) {
112
0
  SplashFontFile *fontFile;
113
114
0
  fontFile = NULL;
115
0
#if HAVE_FREETYPE_H
116
0
  if (!fontFile && ftEngine) {
117
0
    fontFile = ftEngine->loadType1Font(idA,
118
#if LOAD_FONTS_FROM_MEM
119
               fontBuf,
120
#else
121
0
               fileName, deleteFile,
122
0
#endif
123
0
               enc);
124
0
  }
125
0
#endif
126
127
0
#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__)
128
  // delete the (temporary) font file -- with Unix hard link
129
  // semantics, this will remove the last link; otherwise it will
130
  // return an error, leaving the file to be deleted later (if
131
  // loadXYZFont failed, the file will always be deleted)
132
0
  if (deleteFile) {
133
0
    unlink(fontFile ? fontFile->fileName->getCString() : fileName);
134
0
  }
135
0
#endif
136
137
0
  if (!fontFile) {
138
0
    badFontFiles->append(idA);
139
0
  }
140
141
0
  return fontFile;
142
0
}
143
144
SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA,
145
#if LOAD_FONTS_FROM_MEM
146
             GString *fontBuf,
147
#else
148
             char *fileName,
149
             GBool deleteFile,
150
#endif
151
             int *codeToGID,
152
0
             const char **enc) {
153
0
  SplashFontFile *fontFile;
154
155
0
  fontFile = NULL;
156
0
  if (!fontFile) {
157
0
    gfree(codeToGID);
158
0
  }
159
0
#if HAVE_FREETYPE_H
160
0
  if (!fontFile && ftEngine) {
161
0
    fontFile = ftEngine->loadType1CFont(idA,
162
#if LOAD_FONTS_FROM_MEM
163
          fontBuf,
164
#else
165
0
          fileName, deleteFile,
166
0
#endif
167
0
          enc);
168
0
  }
169
0
#endif
170
171
0
#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__)
172
  // delete the (temporary) font file -- with Unix hard link
173
  // semantics, this will remove the last link; otherwise it will
174
  // return an error, leaving the file to be deleted later (if
175
  // loadXYZFont failed, the file will always be deleted)
176
0
  if (deleteFile) {
177
0
    unlink(fontFile ? fontFile->fileName->getCString() : fileName);
178
0
  }
179
0
#endif
180
181
0
  if (!fontFile) {
182
0
    badFontFiles->append(idA);
183
0
  }
184
185
0
  return fontFile;
186
0
}
187
188
SplashFontFile *SplashFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
189
#if LOAD_FONTS_FROM_MEM
190
                  GString *fontBuf,
191
#else
192
                  char *fileName,
193
                  GBool deleteFile,
194
#endif
195
                  int *codeToGID,
196
0
                  const char **enc) {
197
0
  SplashFontFile *fontFile;
198
199
0
  fontFile = NULL;
200
0
  if (!fontFile) {
201
0
    gfree(codeToGID);
202
0
  }
203
0
#if HAVE_FREETYPE_H
204
0
  if (!fontFile && ftEngine) {
205
0
    fontFile = ftEngine->loadOpenTypeT1CFont(idA,
206
#if LOAD_FONTS_FROM_MEM
207
               fontBuf,
208
#else
209
0
               fileName, deleteFile,
210
0
#endif
211
0
               enc);
212
0
  }
213
0
#endif
214
215
0
#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__)
216
  // delete the (temporary) font file -- with Unix hard link
217
  // semantics, this will remove the last link; otherwise it will
218
  // return an error, leaving the file to be deleted later (if
219
  // loadXYZFont failed, the file will always be deleted)
220
0
  if (deleteFile) {
221
0
    unlink(fontFile ? fontFile->fileName->getCString() : fileName);
222
0
  }
223
0
#endif
224
225
0
  if (!fontFile) {
226
0
    badFontFiles->append(idA);
227
0
  }
228
229
0
  return fontFile;
230
0
}
231
232
SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA,
233
#if LOAD_FONTS_FROM_MEM
234
                GString *fontBuf,
235
#else
236
                char *fileName,
237
                GBool deleteFile,
238
#endif
239
                int *codeToGID,
240
0
                int codeToGIDLen) {
241
0
  SplashFontFile *fontFile;
242
243
0
  fontFile = NULL;
244
0
#if HAVE_FREETYPE_H
245
0
  if (!fontFile && ftEngine) {
246
0
    fontFile = ftEngine->loadCIDFont(idA,
247
#if LOAD_FONTS_FROM_MEM
248
             fontBuf,
249
#else
250
0
             fileName, deleteFile,
251
0
#endif
252
0
             codeToGID, codeToGIDLen);
253
0
  }
254
0
#endif
255
256
0
  if (!fontFile) {
257
0
    gfree(codeToGID);
258
0
  }
259
260
0
#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__)
261
  // delete the (temporary) font file -- with Unix hard link
262
  // semantics, this will remove the last link; otherwise it will
263
  // return an error, leaving the file to be deleted later (if
264
  // loadXYZFont failed, the file will always be deleted)
265
0
  if (deleteFile) {
266
0
    unlink(fontFile ? fontFile->fileName->getCString() : fileName);
267
0
  }
268
0
#endif
269
270
0
  if (!fontFile) {
271
0
    badFontFiles->append(idA);
272
0
  }
273
274
0
  return fontFile;
275
0
}
276
277
SplashFontFile *SplashFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA,
278
#if LOAD_FONTS_FROM_MEM
279
                  GString *fontBuf,
280
#else
281
                  char *fileName,
282
                  GBool deleteFile,
283
#endif
284
                  int *codeToGID,
285
0
                  int codeToGIDLen) {
286
0
  SplashFontFile *fontFile;
287
288
0
  fontFile = NULL;
289
0
#if HAVE_FREETYPE_H
290
0
  if (!fontFile && ftEngine) {
291
0
    fontFile = ftEngine->loadOpenTypeCFFFont(idA,
292
#if LOAD_FONTS_FROM_MEM
293
               fontBuf,
294
#else
295
0
               fileName, deleteFile,
296
0
#endif
297
0
               codeToGID, codeToGIDLen);
298
0
  }
299
0
#endif
300
301
0
  if (!fontFile) {
302
0
    gfree(codeToGID);
303
0
  }
304
305
0
#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__)
306
  // delete the (temporary) font file -- with Unix hard link
307
  // semantics, this will remove the last link; otherwise it will
308
  // return an error, leaving the file to be deleted later (if
309
  // loadXYZFont failed, the file will always be deleted)
310
0
  if (deleteFile) {
311
0
    unlink(fontFile ? fontFile->fileName->getCString() : fileName);
312
0
  }
313
0
#endif
314
315
0
  if (!fontFile) {
316
0
    badFontFiles->append(idA);
317
0
  }
318
319
0
  return fontFile;
320
0
}
321
322
SplashFontFile *SplashFontEngine::loadTrueTypeFont(SplashFontFileID *idA,
323
#if LOAD_FONTS_FROM_MEM
324
               GString *fontBuf,
325
#else
326
               char *fileName,
327
               GBool deleteFile,
328
#endif
329
               int fontNum,
330
               int *codeToGID,
331
               int codeToGIDLen,
332
0
               char *fontName) {
333
0
  SplashFontFile *fontFile;
334
335
0
  fontFile = NULL;
336
0
#if HAVE_FREETYPE_H
337
0
  if (!fontFile && ftEngine) {
338
0
    fontFile = ftEngine->loadTrueTypeFont(idA,
339
#if LOAD_FONTS_FROM_MEM
340
            fontBuf,
341
#else
342
0
            fileName, deleteFile,
343
0
#endif
344
0
            fontNum, codeToGID, codeToGIDLen);
345
0
  }
346
0
#endif
347
348
0
  if (!fontFile) {
349
0
    gfree(codeToGID);
350
0
  }
351
352
0
#if !LOAD_FONTS_FROM_MEM && !defined(_WIN32) && !defined(__ANDROID__)
353
  // delete the (temporary) font file -- with Unix hard link
354
  // semantics, this will remove the last link; otherwise it will
355
  // return an error, leaving the file to be deleted later (if
356
  // loadXYZFont failed, the file will always be deleted)
357
0
  if (deleteFile) {
358
0
    unlink(fontFile ? fontFile->fileName->getCString() : fileName);
359
0
  }
360
0
#endif
361
362
0
  if (!fontFile) {
363
0
    badFontFiles->append(idA);
364
0
  }
365
366
0
  return fontFile;
367
0
}
368
369
SplashFont *SplashFontEngine::getFont(SplashFontFile *fontFile,
370
              SplashCoord *textMat,
371
0
              SplashCoord *ctm) {
372
0
  SplashCoord mat[4];
373
0
  SplashFont *font;
374
0
  int i, j;
375
376
0
  mat[0] = textMat[0] * ctm[0] + textMat[1] * ctm[2];
377
0
  mat[1] = -(textMat[0] * ctm[1] + textMat[1] * ctm[3]);
378
0
  mat[2] = textMat[2] * ctm[0] + textMat[3] * ctm[2];
379
0
  mat[3] = -(textMat[2] * ctm[1] + textMat[3] * ctm[3]);
380
0
  if (!splashCheckDet(mat[0], mat[1], mat[2], mat[3], 0.01)) {
381
    // avoid a singular (or close-to-singular) matrix
382
0
    mat[0] = 0.01;  mat[1] = 0;
383
0
    mat[2] = 0;     mat[3] = 0.01;
384
0
  }
385
386
0
  font = fontCache[0];
387
0
  if (font && font->matches(fontFile, mat, textMat)) {
388
0
    return font;
389
0
  }
390
0
  for (i = 1; i < splashFontCacheSize; ++i) {
391
0
    font = fontCache[i];
392
0
    if (font && font->matches(fontFile, mat, textMat)) {
393
0
      for (j = i; j > 0; --j) {
394
0
  fontCache[j] = fontCache[j-1];
395
0
      }
396
0
      fontCache[0] = font;
397
0
      return font;
398
0
    }
399
0
  }
400
0
  font = fontFile->makeFont(mat, textMat);
401
0
  if (fontCache[splashFontCacheSize - 1]) {
402
0
    delete fontCache[splashFontCacheSize - 1];
403
0
  }
404
0
  for (j = splashFontCacheSize - 1; j > 0; --j) {
405
0
    fontCache[j] = fontCache[j-1];
406
0
  }
407
0
  fontCache[0] = font;
408
0
  return font;
409
0
}