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>
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 //========================================================================
29 #ifdef USE_GCC_PRAGMAS
30 #pragma implementation
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"
53 #if (__VMS_VER < 70000000)
54 extern "C" int unlink(char *filename
);
59 #if (__VMS_VER < 70000000)
60 extern "C" int unlink(char *filename
);
64 //------------------------------------------------------------------------
66 //------------------------------------------------------------------------
68 SplashFontEngine::SplashFontEngine(
72 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
74 GBool enableFreeTypeHinting
,
75 GBool enableSlightHinting
,
80 for (i
= 0; i
< splashFontCacheSize
; ++i
) {
86 t1Engine
= SplashT1FontEngine::init(aa
);
91 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
93 ftEngine
= SplashFTFontEngine::init(aa
, enableFreeTypeHinting
, enableSlightHinting
);
100 SplashFontEngine::~SplashFontEngine() {
103 for (i
= 0; i
< splashFontCacheSize
; ++i
) {
114 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
121 SplashFontFile
*SplashFontEngine::getFontFile(SplashFontFileID
*id
) {
122 SplashFontFile
*fontFile
;
125 for (i
= 0; i
< splashFontCacheSize
; ++i
) {
127 fontFile
= fontCache
[i
]->getFontFile();
128 if (fontFile
&& fontFile
->getID()->matches(id
)) {
136 SplashFontFile
*SplashFontEngine::loadType1Font(SplashFontFileID
*idA
,
139 SplashFontFile
*fontFile
;
143 if (!fontFile
&& t1Engine
) {
144 fontFile
= t1Engine
->loadType1Font(idA
, src
, enc
);
147 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
148 if (!fontFile
&& ftEngine
) {
149 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)
163 SplashFontFile
*SplashFontEngine::loadType1CFont(SplashFontFileID
*idA
,
166 SplashFontFile
*fontFile
;
170 if (!fontFile
&& t1Engine
) {
171 fontFile
= t1Engine
->loadType1CFont(idA
, src
, enc
);
174 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
175 if (!fontFile
&& ftEngine
) {
176 fontFile
= ftEngine
->loadType1CFont(idA
, src
, enc
);
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)
190 SplashFontFile
*SplashFontEngine::loadOpenTypeT1CFont(SplashFontFileID
*idA
,
193 SplashFontFile
*fontFile
;
196 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
197 if (!fontFile
&& ftEngine
) {
198 fontFile
= ftEngine
->loadOpenTypeT1CFont(idA
, src
, enc
);
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)
212 SplashFontFile
*SplashFontEngine::loadCIDFont(SplashFontFileID
*idA
,
213 SplashFontSrc
*src
) {
214 SplashFontFile
*fontFile
;
217 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
218 if (!fontFile
&& ftEngine
) {
219 fontFile
= ftEngine
->loadCIDFont(idA
, src
);
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)
233 SplashFontFile
*SplashFontEngine::loadOpenTypeCFFFont(SplashFontFileID
*idA
,
237 SplashFontFile
*fontFile
;
240 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
241 if (!fontFile
&& ftEngine
) {
242 fontFile
= ftEngine
->loadOpenTypeCFFFont(idA
, src
, codeToGID
, codeToGIDLen
);
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)
256 SplashFontFile
*SplashFontEngine::loadTrueTypeFont(SplashFontFileID
*idA
,
261 SplashFontFile
*fontFile
;
264 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
265 if (!fontFile
&& ftEngine
) {
266 fontFile
= ftEngine
->loadTrueTypeFont(idA
, src
,
267 codeToGID
, codeToGIDLen
, faceIndex
);
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)
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
) {
297 SplashFont
*SplashFontEngine::getFont(SplashFontFile
*fontFile
,
298 SplashCoord
*textMat
,
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;
315 if (font
&& font
->matches(fontFile
, mat
, textMat
)) {
318 for (i
= 1; i
< splashFontCacheSize
; ++i
) {
320 if (font
&& font
->matches(fontFile
, mat
, textMat
)) {
321 for (j
= i
; j
> 0; --j
) {
322 fontCache
[j
] = fontCache
[j
-1];
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];