fix remapping behavior. Remapping is only necessary if we are rendering on the workbe...
[AROS-Contrib.git] / arospdf / splash / SplashFontEngine.cc
blobd5013d184308b79e476ebd8ed95a0bf21687c0e3
1 //========================================================================
2 //
3 // SplashFontEngine.cc
4 //
5 //========================================================================
7 #include <aconf.h>
9 #ifdef USE_GCC_PRAGMAS
10 #pragma implementation
11 #endif
13 #if HAVE_T1LIB_H
14 #include <t1lib.h>
15 #endif
17 #include <stdlib.h>
18 #include <stdio.h>
19 #ifndef WIN32
20 # include <unistd.h>
21 #endif
22 #include "gmem.h"
23 #include "GString.h"
24 #include "SplashMath.h"
25 #include "SplashT1FontEngine.h"
26 #include "SplashFTFontEngine.h"
27 #include "SplashFontFile.h"
28 #include "SplashFontFileID.h"
29 #include "SplashFont.h"
30 #include "SplashFontEngine.h"
31 #include <aros/debug.h>
32 #ifdef VMS
33 #if (__VMS_VER < 70000000)
34 extern "C" int unlink(char *filename);
35 #endif
36 #endif
38 //------------------------------------------------------------------------
39 // SplashFontEngine
40 //------------------------------------------------------------------------
42 SplashFontEngine::SplashFontEngine(
43 #if HAVE_T1LIB_H
44 GBool enableT1lib,
45 #endif
46 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
47 GBool enableFreeType,
48 #endif
49 GBool aa) {
50 int i;
52 for (i = 0; i < splashFontCacheSize; ++i) {
53 fontCache[i] = NULL;
56 #if HAVE_T1LIB_H
57 if (enableT1lib) {
58 t1Engine = SplashT1FontEngine::init(aa);
59 } else {
60 t1Engine = NULL;
62 #endif
63 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
64 if (enableFreeType) {
65 ftEngine = SplashFTFontEngine::init(aa);
66 } else {
67 ftEngine = NULL;
69 #endif
72 SplashFontEngine::~SplashFontEngine() {
73 int i;
75 for (i = 0; i < splashFontCacheSize; ++i) {
76 if (fontCache[i]) {
77 delete fontCache[i];
81 #if HAVE_T1LIB_H
82 if (t1Engine) {
83 delete t1Engine;
85 #endif
86 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
87 if (ftEngine) {
88 delete ftEngine;
90 #endif
93 SplashFontFile *SplashFontEngine::getFontFile(SplashFontFileID *id) {
94 SplashFontFile *fontFile;
95 int i;
97 for (i = 0; i < splashFontCacheSize; ++i) {
98 if (fontCache[i]) {
99 fontFile = fontCache[i]->getFontFile();
100 if (fontFile && fontFile->getID()->matches(id)) {
101 return fontFile;
105 return NULL;
108 SplashFontFile *SplashFontEngine::loadType1Font(SplashFontFileID *idA,
109 char *fileName,
110 GBool deleteFile, char **enc) {
111 SplashFontFile *fontFile;
113 fontFile = NULL;
114 #if HAVE_T1LIB_H
115 if (!fontFile && t1Engine) {
116 fontFile = t1Engine->loadType1Font(idA, fileName, deleteFile, enc);
118 #endif
119 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
120 if (!fontFile && ftEngine) {
121 //here we are not sure it's loading right...
122 fontFile = ftEngine->loadType1Font(idA, fileName, deleteFile, enc);
124 #endif
126 #ifndef WIN32
127 // delete the (temporary) font file -- with Unix hard link
128 // semantics, this will remove the last link; otherwise it will
129 // return an error, leaving the file to be deleted later (if
130 // loadXYZFont failed, the file will always be deleted)
131 if (deleteFile) {
132 unlink(fontFile ? fontFile->fileName->getCString() : fileName);
134 #endif
136 return fontFile;
139 SplashFontFile *SplashFontEngine::loadType1CFont(SplashFontFileID *idA,
140 char *fileName,
141 GBool deleteFile,
142 char **enc) {
143 SplashFontFile *fontFile;
145 fontFile = NULL;
146 #if HAVE_T1LIB_H
147 if (!fontFile && t1Engine) {
148 fontFile = t1Engine->loadType1CFont(idA, fileName, deleteFile, enc);
150 #endif
151 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
152 if (!fontFile && ftEngine) {
153 fontFile = ftEngine->loadType1CFont(idA, fileName, deleteFile, enc);
155 #endif
157 #ifndef WIN32
158 // delete the (temporary) font file -- with Unix hard link
159 // semantics, this will remove the last link; otherwise it will
160 // return an error, leaving the file to be deleted later (if
161 // loadXYZFont failed, the file will always be deleted)
162 if (deleteFile) {
163 unlink(fontFile ? fontFile->fileName->getCString() : fileName);
165 #endif
167 return fontFile;
170 SplashFontFile *SplashFontEngine::loadOpenTypeT1CFont(SplashFontFileID *idA,
171 char *fileName,
172 GBool deleteFile,
173 char **enc) {
174 SplashFontFile *fontFile;
176 fontFile = NULL;
177 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
178 if (!fontFile && ftEngine) {
179 fontFile = ftEngine->loadOpenTypeT1CFont(idA, fileName, deleteFile, enc);
181 #endif
183 #ifndef WIN32
184 // delete the (temporary) font file -- with Unix hard link
185 // semantics, this will remove the last link; otherwise it will
186 // return an error, leaving the file to be deleted later (if
187 // loadXYZFont failed, the file will always be deleted)
188 if (deleteFile) {
189 unlink(fontFile ? fontFile->fileName->getCString() : fileName);
191 #endif
193 return fontFile;
196 SplashFontFile *SplashFontEngine::loadCIDFont(SplashFontFileID *idA,
197 char *fileName,
198 GBool deleteFile) {
199 SplashFontFile *fontFile;
201 fontFile = NULL;
202 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
203 if (!fontFile && ftEngine) {
204 fontFile = ftEngine->loadCIDFont(idA, fileName, deleteFile);
206 #endif
208 #ifndef WIN32
209 // delete the (temporary) font file -- with Unix hard link
210 // semantics, this will remove the last link; otherwise it will
211 // return an error, leaving the file to be deleted later (if
212 // loadXYZFont failed, the file will always be deleted)
213 if (deleteFile) {
214 unlink(fontFile ? fontFile->fileName->getCString() : fileName);
216 #endif
218 return fontFile;
221 SplashFontFile *SplashFontEngine::loadOpenTypeCFFFont(SplashFontFileID *idA,
222 char *fileName,
223 GBool deleteFile) {
224 SplashFontFile *fontFile;
226 fontFile = NULL;
227 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
228 if (!fontFile && ftEngine) {
229 fontFile = ftEngine->loadOpenTypeCFFFont(idA, fileName, deleteFile);
231 #endif
233 #ifndef WIN32
234 // delete the (temporary) font file -- with Unix hard link
235 // semantics, this will remove the last link; otherwise it will
236 // return an error, leaving the file to be deleted later (if
237 // loadXYZFont failed, the file will always be deleted)
238 if (deleteFile) {
239 unlink(fontFile ? fontFile->fileName->getCString() : fileName);
241 #endif
243 return fontFile;
246 SplashFontFile *SplashFontEngine::loadTrueTypeFont(SplashFontFileID *idA,
247 char *fileName,
248 GBool deleteFile,
249 Gushort *codeToGID,
250 int codeToGIDLen) {
251 SplashFontFile *fontFile;
253 fontFile = NULL;
254 #if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
255 if (!fontFile && ftEngine) {
256 fontFile = ftEngine->loadTrueTypeFont(idA, fileName, deleteFile,
257 codeToGID, codeToGIDLen);
259 #endif
261 if (!fontFile) {
262 gfree(codeToGID);
265 #ifndef WIN32
266 // delete the (temporary) font file -- with Unix hard link
267 // semantics, this will remove the last link; otherwise it will
268 // return an error, leaving the file to be deleted later (if
269 // loadXYZFont failed, the file will always be deleted)
270 if (deleteFile) {
271 unlink(fontFile ? fontFile->fileName->getCString() : fileName);
273 #endif
275 return fontFile;
278 SplashFont *SplashFontEngine::getFont(SplashFontFile *fontFile,
279 SplashCoord *textMat,
280 SplashCoord *ctm) {
281 SplashCoord mat[4];
282 SplashFont *font;
283 int i, j;
285 mat[0] = textMat[0] * ctm[0] + textMat[1] * ctm[2];
286 mat[1] = -(textMat[0] * ctm[1] + textMat[1] * ctm[3]);
287 mat[2] = textMat[2] * ctm[0] + textMat[3] * ctm[2];
288 mat[3] = -(textMat[2] * ctm[1] + textMat[3] * ctm[3]);
289 if (splashAbs(mat[0] * mat[3] - mat[1] * mat[2]) < 0.01) {
290 // avoid a singular (or close-to-singular) matrix
291 mat[0] = 0.01; mat[1] = 0;
292 mat[2] = 0; mat[3] = 0.01;
295 font = fontCache[0];
296 if (font && font->matches(fontFile, mat, textMat)) {
297 return font;
299 for (i = 1; i < splashFontCacheSize; ++i) {
300 font = fontCache[i];
301 if (font && font->matches(fontFile, mat, textMat)) {
302 for (j = i; j > 0; --j) {
303 fontCache[j] = fontCache[j-1];
305 fontCache[0] = font;
306 return font;
309 font = fontFile->makeFont(mat, textMat);
310 if (fontCache[splashFontCacheSize - 1]) {
311 delete fontCache[splashFontCacheSize - 1];
313 for (j = splashFontCacheSize - 1; j > 0; --j) {
314 fontCache[j] = fontCache[j-1];
316 fontCache[0] = font;
317 return font;