1 //========================================================================
5 //========================================================================
7 //========================================================================
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>
21 // To see a description of the changes please see the Changelog file that
22 // came with your tarball or type make ChangeLog if you are building from git
24 //========================================================================
28 #ifdef USE_GCC_PRAGMAS
29 #pragma implementation
42 #include "goo/GooString.h"
43 #include "SplashMath.h"
44 #include "SplashT1FontEngine.h"
45 #include "SplashFTFontEngine.h"
46 #include "SplashFontFile.h"
47 #include "SplashFontFileID.h"
48 #include "SplashFont.h"
49 #include "SplashFontEngine.h"
52 #if (__VMS_VER < 70000000)
53 extern "C" int unlink(char *filename
);
58 #if (__VMS_VER < 70000000)
59 extern "C" int unlink(char *filename
);
63 //------------------------------------------------------------------------
65 //------------------------------------------------------------------------
67 SplashFontEngine::SplashFontEngine(
71 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
73 GBool enableFreeTypeHinting
,
74 GBool enableSlightHinting
,
79 for (i
= 0; i
< splashFontCacheSize
; ++i
) {
85 t1Engine
= SplashT1FontEngine::init(aa
);
90 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
92 ftEngine
= SplashFTFontEngine::init(aa
, enableFreeTypeHinting
, enableSlightHinting
);
99 SplashFontEngine::~SplashFontEngine() {
102 for (i
= 0; i
< splashFontCacheSize
; ++i
) {
113 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
120 SplashFontFile
*SplashFontEngine::getFontFile(SplashFontFileID
*id
) {
121 SplashFontFile
*fontFile
;
124 for (i
= 0; i
< splashFontCacheSize
; ++i
) {
126 fontFile
= fontCache
[i
]->getFontFile();
127 if (fontFile
&& fontFile
->getID()->matches(id
)) {
135 SplashFontFile
*SplashFontEngine::loadType1Font(SplashFontFileID
*idA
,
138 SplashFontFile
*fontFile
;
142 if (!fontFile
&& t1Engine
) {
143 fontFile
= t1Engine
->loadType1Font(idA
, src
, enc
);
146 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
147 if (!fontFile
&& ftEngine
) {
148 fontFile
= ftEngine
->loadType1Font(idA
, src
, enc
);
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)
164 SplashFontFile
*SplashFontEngine::loadType1CFont(SplashFontFileID
*idA
,
167 SplashFontFile
*fontFile
;
171 if (!fontFile
&& t1Engine
) {
172 fontFile
= t1Engine
->loadType1CFont(idA
, src
, enc
);
175 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
176 if (!fontFile
&& ftEngine
) {
177 fontFile
= ftEngine
->loadType1CFont(idA
, src
, enc
);
182 // delete the (temporary) font file -- with Unix hard link
183 // semantics, this will remove the last link; otherwise it will
184 // return an error, leaving the file to be deleted later (if
185 // loadXYZFont failed, the file will always be deleted)
193 SplashFontFile
*SplashFontEngine::loadOpenTypeT1CFont(SplashFontFileID
*idA
,
196 SplashFontFile
*fontFile
;
199 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
200 if (!fontFile
&& ftEngine
) {
201 fontFile
= ftEngine
->loadOpenTypeT1CFont(idA
, src
, enc
);
205 // delete the (temporary) font file -- with Unix hard link
206 // semantics, this will remove the last link; otherwise it will
207 // return an error, leaving the file to be deleted later (if
208 // loadXYZFont failed, the file will always be deleted)
215 SplashFontFile
*SplashFontEngine::loadCIDFont(SplashFontFileID
*idA
,
216 SplashFontSrc
*src
) {
217 SplashFontFile
*fontFile
;
220 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
221 if (!fontFile
&& ftEngine
) {
222 fontFile
= ftEngine
->loadCIDFont(idA
, src
);
227 // delete the (temporary) font file -- with Unix hard link
228 // semantics, this will remove the last link; otherwise it will
229 // return an error, leaving the file to be deleted later (if
230 // loadXYZFont failed, the file will always be deleted)
238 SplashFontFile
*SplashFontEngine::loadOpenTypeCFFFont(SplashFontFileID
*idA
,
242 SplashFontFile
*fontFile
;
245 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
246 if (!fontFile
&& ftEngine
) {
247 fontFile
= ftEngine
->loadOpenTypeCFFFont(idA
, src
, codeToGID
, codeToGIDLen
);
251 // delete the (temporary) font file -- with Unix hard link
252 // semantics, this will remove the last link; otherwise it will
253 // return an error, leaving the file to be deleted later (if
254 // loadXYZFont failed, the file will always be deleted)
261 SplashFontFile
*SplashFontEngine::loadTrueTypeFont(SplashFontFileID
*idA
,
266 SplashFontFile
*fontFile
;
269 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
270 if (!fontFile
&& ftEngine
) {
271 fontFile
= ftEngine
->loadTrueTypeFont(idA
, src
,
272 codeToGID
, codeToGIDLen
, faceIndex
);
281 // delete the (temporary) font file -- with Unix hard link
282 // semantics, this will remove the last link; otherwise it will
283 // return an error, leaving the file to be deleted later (if
284 // loadXYZFont failed, the file will always be deleted)
292 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
293 GBool
SplashFontEngine::getAA() {
294 return (ftEngine
== NULL
) ? gFalse
: ftEngine
->getAA();
297 void SplashFontEngine::setAA(GBool aa
) {
298 if (ftEngine
!= NULL
) {
304 SplashFont
*SplashFontEngine::getFont(SplashFontFile
*fontFile
,
305 SplashCoord
*textMat
,
311 mat
[0] = textMat
[0] * ctm
[0] + textMat
[1] * ctm
[2];
312 mat
[1] = -(textMat
[0] * ctm
[1] + textMat
[1] * ctm
[3]);
313 mat
[2] = textMat
[2] * ctm
[0] + textMat
[3] * ctm
[2];
314 mat
[3] = -(textMat
[2] * ctm
[1] + textMat
[3] * ctm
[3]);
315 if (!splashCheckDet(mat
[0], mat
[1], mat
[2], mat
[3], 0.01)) {
316 // avoid a singular (or close-to-singular) matrix
317 mat
[0] = 0.01; mat
[1] = 0;
318 mat
[2] = 0; mat
[3] = 0.01;
322 if (font
&& font
->matches(fontFile
, mat
, textMat
)) {
325 for (i
= 1; i
< splashFontCacheSize
; ++i
) {
327 if (font
&& font
->matches(fontFile
, mat
, textMat
)) {
328 for (j
= i
; j
> 0; --j
) {
329 fontCache
[j
] = fontCache
[j
-1];
335 font
= fontFile
->makeFont(mat
, textMat
);
336 if (fontCache
[splashFontCacheSize
- 1]) {
337 delete fontCache
[splashFontCacheSize
- 1];
339 for (j
= splashFontCacheSize
- 1; j
> 0; --j
) {
340 fontCache
[j
] = fontCache
[j
-1];