beta-0.89.2
[luatex.git] / source / libs / poppler / poppler-src / splash / SplashFontEngine.cc
blob73ef8de087797cea7899b426203d6e6b1a23c33b
1 //========================================================================
2 //
3 // SplashFontEngine.cc
4 //
5 //========================================================================
7 //========================================================================
8 //
9 // Modified under the Poppler project - http://poppler.freedesktop.org
11 // All changes made under the Poppler project to this file are licensed
12 // under GPL version 2 or later
14 // Copyright (C) 2006 Takashi Iwai <tiwai@suse.de>
15 // Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
16 // Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net>
17 // Copyright (C) 2009 Albert Astals Cid <aacid@kde.org>
18 // Copyright (C) 2011 Andreas Hartmetz <ahartmetz@gmail.com>
19 // Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
20 // Copyright (C) 2015 Dmytro Morgun <lztoad@gmail.com>
22 // To see a description of the changes please see the Changelog file that
23 // came with your tarball or type make ChangeLog if you are building from git
25 //========================================================================
27 #include <config.h>
29 #ifdef USE_GCC_PRAGMAS
30 #pragma implementation
31 #endif
33 #if HAVE_T1LIB_H
34 #include <t1lib.h>
35 #endif
37 #include <stdlib.h>
38 #include <stdio.h>
39 #ifdef HAVE_UNISTD_H
40 # include <unistd.h>
41 #endif
42 #include "goo/gmem.h"
43 #include "goo/GooString.h"
44 #include "SplashMath.h"
45 #include "SplashT1FontEngine.h"
46 #include "SplashFTFontEngine.h"
47 #include "SplashFontFile.h"
48 #include "SplashFontFileID.h"
49 #include "SplashFont.h"
50 #include "SplashFontEngine.h"
52 #ifdef VMS
53 #if (__VMS_VER < 70000000)
54 extern "C" int unlink(char *filename);
55 #endif
56 #endif
58 #ifdef VMS
59 #if (__VMS_VER < 70000000)
60 extern "C" int unlink(char *filename);
61 #endif
62 #endif
64 //------------------------------------------------------------------------
65 // SplashFontEngine
66 //------------------------------------------------------------------------
68 SplashFontEngine::SplashFontEngine(
69 #if HAVE_T1LIB_H
70 GBool enableT1lib,
71 #endif
72 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
73 GBool enableFreeType,
74 GBool enableFreeTypeHinting,
75 GBool enableSlightHinting,
76 #endif
77 GBool aa) {
78 int i;
80 for (i = 0; i < splashFontCacheSize; ++i) {
81 fontCache[i] = NULL;
84 #if HAVE_T1LIB_H
85 if (enableT1lib) {
86 t1Engine = SplashT1FontEngine::init(aa);
87 } else {
88 t1Engine = NULL;
90 #endif
91 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
92 if (enableFreeType) {
93 ftEngine = SplashFTFontEngine::init(aa, enableFreeTypeHinting, enableSlightHinting);
94 } else {
95 ftEngine = NULL;
97 #endif
100 SplashFontEngine::~SplashFontEngine() {
101 int i;
103 for (i = 0; i < splashFontCacheSize; ++i) {
104 if (fontCache[i]) {
105 delete fontCache[i];
109 #if HAVE_T1LIB_H
110 if (t1Engine) {
111 delete t1Engine;
113 #endif
114 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
115 if (ftEngine) {
116 delete ftEngine;
118 #endif
121 SplashFontFile *SplashFontEngine::getFontFile(SplashFontFileID *id) {
122 SplashFontFile *fontFile;
123 int i;
125 for (i = 0; i < splashFontCacheSize; ++i) {
126 if (fontCache[i]) {
127 fontFile = fontCache[i]->getFontFile();
128 if (fontFile && fontFile->getID()->matches(id)) {
129 return fontFile;
133 return NULL;
136 SplashFontFile *SplashFontEngine::loadType1Font(SplashFontFileID *idA,
137 SplashFontSrc *src,
138 const char **enc) {
139 SplashFontFile *fontFile;
141 fontFile = NULL;
142 #if HAVE_T1LIB_H
143 if (!fontFile && t1Engine) {
144 fontFile = t1Engine->loadType1Font(idA, src, enc);
146 #endif
147 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
148 if (!fontFile && ftEngine) {
149 fontFile = ftEngine->loadType1Font(idA, src, enc);
151 #endif
153 // delete the (temporary) font file -- with Unix hard link
154 // semantics, this will remove the last link; otherwise it will
155 // return an error, leaving the file to be deleted later (if
156 // loadXYZFont failed, the file will always be deleted)
157 if (src->isFile)
158 src->unref();
160 return fontFile;
163 SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA,
164 SplashFontSrc *src,
165 const char **enc) {
166 SplashFontFile *fontFile;
168 fontFile = NULL;
169 #if HAVE_T1LIB_H
170 if (!fontFile && t1Engine) {
171 fontFile = t1Engine->loadType1CFont(idA, src, enc);
173 #endif
174 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
175 if (!fontFile && ftEngine) {
176 fontFile = ftEngine->loadType1CFont(idA, src, enc);
178 #endif
180 // delete the (temporary) font file -- with Unix hard link
181 // semantics, this will remove the last link; otherwise it will
182 // return an error, leaving the file to be deleted later (if
183 // loadXYZFont failed, the file will always be deleted)
184 if (src->isFile)
185 src->unref();
187 return fontFile;
190 SplashFontFile *SplashFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
191 SplashFontSrc *src,
192 const char **enc) {
193 SplashFontFile *fontFile;
195 fontFile = NULL;
196 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
197 if (!fontFile && ftEngine) {
198 fontFile = ftEngine->loadOpenTypeT1CFont(idA, src, enc);
200 #endif
202 // delete the (temporary) font file -- with Unix hard link
203 // semantics, this will remove the last link; otherwise it will
204 // return an error, leaving the file to be deleted later (if
205 // loadXYZFont failed, the file will always be deleted)
206 if (src->isFile)
207 src->unref();
209 return fontFile;
212 SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA,
213 SplashFontSrc *src) {
214 SplashFontFile *fontFile;
216 fontFile = NULL;
217 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
218 if (!fontFile && ftEngine) {
219 fontFile = ftEngine->loadCIDFont(idA, src);
221 #endif
223 // delete the (temporary) font file -- with Unix hard link
224 // semantics, this will remove the last link; otherwise it will
225 // return an error, leaving the file to be deleted later (if
226 // loadXYZFont failed, the file will always be deleted)
227 if (src->isFile)
228 src->unref();
230 return fontFile;
233 SplashFontFile *SplashFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA,
234 SplashFontSrc *src,
235 int *codeToGID,
236 int codeToGIDLen) {
237 SplashFontFile *fontFile;
239 fontFile = NULL;
240 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
241 if (!fontFile && ftEngine) {
242 fontFile = ftEngine->loadOpenTypeCFFFont(idA, src, codeToGID, codeToGIDLen);
244 #endif
246 // delete the (temporary) font file -- with Unix hard link
247 // semantics, this will remove the last link; otherwise it will
248 // return an error, leaving the file to be deleted later (if
249 // loadXYZFont failed, the file will always be deleted)
250 if (src->isFile)
251 src->unref();
253 return fontFile;
256 SplashFontFile *SplashFontEngine::loadTrueTypeFont(SplashFontFileID *idA,
257 SplashFontSrc *src,
258 int *codeToGID,
259 int codeToGIDLen,
260 int faceIndex) {
261 SplashFontFile *fontFile;
263 fontFile = NULL;
264 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
265 if (!fontFile && ftEngine) {
266 fontFile = ftEngine->loadTrueTypeFont(idA, src,
267 codeToGID, codeToGIDLen, faceIndex);
269 #endif
271 if (!fontFile) {
272 gfree(codeToGID);
275 // delete the (temporary) font file -- with Unix hard link
276 // semantics, this will remove the last link; otherwise it will
277 // return an error, leaving the file to be deleted later (if
278 // loadXYZFont failed, the file will always be deleted)
279 if (src->isFile)
280 src->unref();
282 return fontFile;
285 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
286 GBool SplashFontEngine::getAA() {
287 return (ftEngine == NULL) ? gFalse : ftEngine->getAA();
290 void SplashFontEngine::setAA(GBool aa) {
291 if (ftEngine != NULL) {
292 ftEngine->setAA(aa);
295 #endif
297 SplashFont *SplashFontEngine::getFont(SplashFontFile *fontFile,
298 SplashCoord *textMat,
299 SplashCoord *ctm) {
300 SplashCoord mat[4];
301 SplashFont *font;
302 int i, j;
304 mat[0] = textMat[0] * ctm[0] + textMat[1] * ctm[2];
305 mat[1] = -(textMat[0] * ctm[1] + textMat[1] * ctm[3]);
306 mat[2] = textMat[2] * ctm[0] + textMat[3] * ctm[2];
307 mat[3] = -(textMat[2] * ctm[1] + textMat[3] * ctm[3]);
308 if (!splashCheckDet(mat[0], mat[1], mat[2], mat[3], 0.01)) {
309 // avoid a singular (or close-to-singular) matrix
310 mat[0] = 0.01; mat[1] = 0;
311 mat[2] = 0; mat[3] = 0.01;
314 font = fontCache[0];
315 if (font && font->matches(fontFile, mat, textMat)) {
316 return font;
318 for (i = 1; i < splashFontCacheSize; ++i) {
319 font = fontCache[i];
320 if (font && font->matches(fontFile, mat, textMat)) {
321 for (j = i; j > 0; --j) {
322 fontCache[j] = fontCache[j-1];
324 fontCache[0] = font;
325 return font;
328 font = fontFile->makeFont(mat, textMat);
329 if (fontCache[splashFontCacheSize - 1]) {
330 delete fontCache[splashFontCacheSize - 1];
332 for (j = splashFontCacheSize - 1; j > 0; --j) {
333 fontCache[j] = fontCache[j-1];
335 fontCache[0] = font;
336 return font;