source: trunk/src/gdi32/ft2supp.cpp@ 10373

Last change on this file since 10373 was 10373, checked in by sandervl, 22 years ago

Update

File size: 17.8 KB
Line 
1/*
2 * GDI32 FreeType2 Support Class
3 *
4 * Copyright 2003 Innotek Systemberatung GmbH (sandervl@innotek.de)
5 * (stauff@innotek.de)
6 *
7 * Project Odin Software License can be found in LICENSE.TXT
8 *
9 */
10
11/*****************************************************************************
12 * Includes *
13 *****************************************************************************/
14
15#define INCL_DOS
16#define INCL_GPI
17#define INCL_WIN
18#define INCL_SHLERRORS
19#define INCL_WINERRORS
20#include <os2wrap.h> //Odin32 OS/2 api wrappers
21#include <stdlib.h>
22#include <string.h>
23#include <win32type.h>
24#include <dbglog.h>
25#include <win32api.h>
26#include <winconst.h>
27#include <winnls.h>
28#include <heapstring.h>
29#include <winuser32.h>
30#include <odinlx.h>
31#include "oslibgpi.h"
32
33#include "ft2supp.h"
34
35CFT2Module FT2Module;
36
37static BOOL fFT2LIBIntegration = FALSE;
38
39//******************************************************************************
40//******************************************************************************
41void WIN32API SetFreeTypeIntegration(BOOL fEnabled)
42{
43 fFT2LIBIntegration = fEnabled;
44
45 FT2Module.init();
46}
47//******************************************************************************
48// Constructor
49//******************************************************************************
50CFT2Module::CFT2Module(char* sModuleName): bEnabled(FALSE), hftModule(0), pfnGetGlyphIndices(NULL),
51 pfnFt2GetTextExtentW(NULL), pfnFt2EnableFontEngine(NULL),
52 pfnFt2GetGlyphOutline(NULL), pfnFt2CharStringPosAtA(NULL),
53 pfnFt2CharStringPosAtW(NULL), pfnFt2GetFontData(NULL),
54 pfnFt2RegisterUconv(NULL), pfnFt2QueryStringWidthW(NULL),
55 pfnFt2GetVersion(NULL)
56{
57 pszModuleName = sModuleName; //must be static
58}
59//******************************************************************************
60//******************************************************************************
61void CFT2Module::init()
62{
63 APIRET rc;
64 UCHAR Loaderror[ 256 ];
65 LONG major = 0, minor = 0, buildnr = 0;
66
67 if(!fFT2LIBIntegration) {
68 dprintf(("No FT2LIB integration!!"));
69 goto failure;
70 }
71
72 rc = DosLoadModule((PSZ)Loaderror, sizeof(Loaderror), pszModuleName, &hftModule);
73 if (rc != 0)
74 dprintf(("Freetype2 library load error: return code = %u\n", rc));
75 else
76 bEnabled = TRUE;
77
78 if(bEnabled) {
79 pfnFt2GetVersion = (PFN_FT2GETVERSION)QueryProcAddress("Ft2GetVersion");
80 if(!pfnFt2GetVersion) {
81 dprintf(("Ft2GetVersion not found!!"));
82 goto failure;
83 }
84 pfnFt2GetVersion(&major, &minor, &buildnr);
85 if(major != FT2LIB_MAJOR_VERSION) {
86 dprintf(("Incorrect major version %d; expected %d!!", major, FT2LIB_MAJOR_VERSION));
87 goto failure;
88 }
89 if(minor < FT2LIB_MINOR_VERSION) {
90 dprintf(("Incorrect minor version %d; expected >= %d!!", minor, FT2LIB_MINOR_VERSION));
91 goto failure;
92 }
93
94 pfnFt2EnableFontEngine = (PFN_FT2ENABLEFONTENGINE)QueryProcAddress("Ft2EnableFontEngine");
95 if(!pfnFt2EnableFontEngine) dprintf(("Ft2EnableFontEngine not found!!"));
96 else pfnFt2EnableFontEngine(bEnabled);
97
98 pfnGetGlyphIndices = (PFN_FT2GETGLYPHINDICES)QueryProcAddress("Ft2GetGlyphIndices");
99 if(!pfnGetGlyphIndices) dprintf(("Ft2GetGlyphIndices not found!!"));
100
101 pfnFt2GetTextExtentW = (PFN_FT2GETTEXTEXTENTW)QueryProcAddress("Ft2GetTextExtentW");
102 if(!pfnFt2GetTextExtentW) dprintf(("Ft2GetTextExtentW not found!!"));
103
104 pfnFt2CharStringPosAtA = (PFN_FT2CHARSTRINGPOSATA)QueryProcAddress("Ft2CharStringPosAtA");
105 if(!pfnFt2CharStringPosAtA) dprintf(("Ft2CharStringPosAtA not found!!"));
106 pfnFt2CharStringPosAtW = (PFN_FT2CHARSTRINGPOSATW)QueryProcAddress("Ft2CharStringPosAtW");
107 if(!pfnFt2CharStringPosAtW) dprintf(("Ft2CharStringPosAtW not found!!"));
108
109 pfnFt2GetGlyphOutline = (PFN_FT2GETGLYPHOUTLINE)QueryProcAddress("Ft2GetGlyphOutline");
110 if(!pfnFt2GetGlyphOutline) dprintf(("Ft2GetGlyphOutline not found!!"));
111
112 pfnFt2GetFontData = (PFN_FT2GETFONTDATA)QueryProcAddress("Ft2GetFontData");
113 if(!pfnFt2GetFontData) dprintf(("Ft2GetFontData not found!!"));
114
115 pfnFt2QueryFontType = (PFN_FT2QUERYFONTTYPE)QueryProcAddress("Ft2QueryFontType");
116 if(!pfnFt2QueryFontType) dprintf(("Ft2QueryFontType not found!!"));
117
118 pfnFt2QueryStringWidthW = (PFN_FT2QUERYSTRINGWIDTHW)QueryProcAddress("Ft2QueryStringWidthW");
119 if(!pfnFt2QueryStringWidthW) dprintf(("Ft2QueryStringWidthW not found!!"));
120
121 pfnFt2GetCharacterPlacementW = (PFN_FT2GETCHARACTERPLACEMENTW)QueryProcAddress("Ft2GetCharacterPlacementW");
122 if(!pfnFt2GetCharacterPlacementW) dprintf(("pfnFt2GetCharacterPlacementW not found!!"));
123
124 // Do not register functions for Mozilla plugins
125 if(IsDummyExeLoaded() == FALSE)
126 {
127 pfnFt2RegisterUconv = (PFN_FT2REGISTERUCONV)QueryProcAddress("Ft2RegisterUconv");
128 if(pfnFt2RegisterUconv)
129 pfnFt2RegisterUconv(WideCharToMultiByte, MultiByteToWideChar);
130 else dprintf(("Ft2QueryFontType not found!!"));
131 }
132 dprintf(("Freetype2 library enabled state %d",bEnabled));
133 }
134 return;
135
136failure:
137 if(pfnFt2RegisterUconv)
138 pfnFt2RegisterUconv(NULL, NULL);
139 if(pfnFt2EnableFontEngine)
140 pfnFt2EnableFontEngine(FALSE);
141
142 pfnGetGlyphIndices = NULL;
143 pfnFt2GetTextExtentW = NULL;
144 pfnFt2EnableFontEngine = NULL;
145 pfnFt2GetGlyphOutline = NULL;
146 pfnFt2CharStringPosAtA = NULL;
147 pfnFt2CharStringPosAtW = NULL;
148 pfnFt2GetFontData = NULL;
149 pfnFt2RegisterUconv = NULL;
150 pfnFt2QueryStringWidthW= NULL;
151 pfnFt2GetVersion = NULL;
152 bEnabled = FALSE;
153 if (hftModule) {
154 DosFreeModule(hftModule);
155 hftModule = 0;
156 }
157 return;
158}
159//******************************************************************************
160// Destructor
161//******************************************************************************
162CFT2Module::~CFT2Module()
163{
164 if (hftModule)
165 DosFreeModule(hftModule);
166
167 bEnabled = FALSE;
168}
169//******************************************************************************
170//******************************************************************************
171PFN CFT2Module::QueryProcAddress(int ordinal)
172{
173 APIRET rc;
174 PFN ModuleAddr;
175
176 rc = DosQueryProcAddr(hftModule, ordinal, NULL, &ModuleAddr);
177 if (rc != 0) {
178 dprintf(("FreeType2 QueryProcAddr error: return code = %u\n", rc));
179 return 0;
180 }
181 return ModuleAddr;
182}
183//******************************************************************************
184//******************************************************************************
185PFN CFT2Module::QueryProcAddress(char * procname)
186{
187 APIRET rc;
188 PFN ModuleAddr;
189
190 rc = DosQueryProcAddr(hftModule, 0, procname, &ModuleAddr);
191 if (rc != 0) {
192 dprintf(("FreeType2 QueryProcAddr error: return code = %u\n", rc));
193 return 0;
194 }
195 return ModuleAddr;
196}
197//******************************************************************************
198//******************************************************************************
199DWORD CFT2Module::Ft2GetGlyphIndices(HPS hps, LPCWSTR str, int c, LPWORD pgi, DWORD fl)
200{
201 //no fallback
202 return GDI_ERROR;
203}
204//******************************************************************************
205//******************************************************************************
206DWORD CFT2Module::Ft2GetGlyphOutline(HPS hps, UINT glyph, UINT format, LPGLYPHMETRICS lpgm, DWORD buflen, LPVOID buf, const MAT2* lpmat)
207{
208 //no fallback
209 SetLastError(ERROR_INVALID_FUNCTION_W);
210 return GDI_ERROR;
211}
212//******************************************************************************
213//
214// This is basically the same as Ft2QueryTextBoxW, but it behaves as the Win32
215// API GetTextExtent (which ignores character attributes and underhang/overhang)
216//
217// The fallback case is not accurate!! (but the same as our old code)
218//
219//******************************************************************************
220BOOL CFT2Module::Ft2GetTextExtentW(HPS hps, LONG lCount1,LPCWSTR pchString,LONG lCount2,PPOINTLOS2 aptlPoints)
221{
222 DWORD ret;
223 USHORT sel;
224
225 // All FreeType calls should be wrapped for saving FS
226 if(pfnFt2GetTextExtentW)
227 {
228 sel = RestoreOS2FS();
229 ret = pfnFt2GetTextExtentW(hps, lCount1, pchString, lCount2, aptlPoints);
230 SetFS(sel);
231 if(ret || (ret == FALSE && ERRORIDERROR(WinGetLastError(0)) != PMERR_FUNCTION_NOT_SUPPORTED))
232 {
233 //No need for scaling for printer DCs here
234 return ret;
235 }
236 }
237 //else fall back to GPI
238 int len;
239 LPSTR astring;
240
241 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hps);
242
243 len = WideCharToMultiByte( CP_ACP, 0, pchString, lCount1, 0, 0, NULL, NULL );
244 astring = (char *)malloc( len + 1 );
245 lstrcpynWtoA(astring, pchString, len + 1 );
246
247 ret = OSLibGpiQueryTextBox(pHps, lCount1, astring, lCount2, aptlPoints);
248 free(astring);
249 return ret;
250}
251//******************************************************************************
252//******************************************************************************
253BOOL CFT2Module::Ft2CharStringPosAtA(HPS hps,PPOINTLOS2 ptl,PRECTLOS2 rct,ULONG flOptions,LONG lCount,LPCSTR pchString,CONST INT *alAdx, DWORD fuWin32Options)
254{
255 DWORD ret;
256 USHORT sel;
257
258 // All FreeType calls should be wrapped for saving FS
259 if(pfnFt2CharStringPosAtA) {
260 sel = RestoreOS2FS();
261 ret = pfnFt2CharStringPosAtA(hps, ptl,rct,flOptions,lCount,pchString,alAdx, fuWin32Options);
262 SetFS(sel);
263 if(ret || (ret == FALSE && ERRORIDERROR(WinGetLastError(0)) != PMERR_FUNCTION_NOT_SUPPORTED))
264 return ret;
265 }
266 //else fall back to GPI
267 //NOTE: We don't support fuWin32Options in the fallback case
268 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hps);
269 return OSLibGpiCharStringPosAt(pHps,ptl,rct,flOptions,lCount,pchString,alAdx);
270}
271//******************************************************************************
272//******************************************************************************
273BOOL CFT2Module::Ft2CharStringPosAtW(HPS hps, PPOINTLOS2 ptl,PRECTLOS2 rct,ULONG flOptions,LONG lCount,LPCWSTR pchString,CONST INT *alAdx, DWORD fuWin32Options)
274{
275 DWORD ret;
276 USHORT sel;
277
278 // All FreeType calls should be wrapped for saving FS
279 if(pfnFt2CharStringPosAtW) {
280 sel = RestoreOS2FS();
281 ret = pfnFt2CharStringPosAtW(hps, ptl,rct,flOptions,lCount,pchString,alAdx, fuWin32Options);
282 SetFS(sel);
283 if(ret || (ret == FALSE && ERRORIDERROR(WinGetLastError(0)) != PMERR_FUNCTION_NOT_SUPPORTED))
284 return ret;
285 }
286 //else fall back to GPI
287 //NOTE: We don't support fuWin32Options in the fallback case
288 int len;
289 LPSTR astring;
290
291 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hps);
292
293 len = WideCharToMultiByte( CP_ACP, 0, pchString, lCount, 0, 0, NULL, NULL );
294 astring = (char *)malloc( len + 1 );
295 lstrcpynWtoA(astring, pchString, len + 1 );
296
297 ret = OSLibGpiCharStringPosAt(pHps,ptl,rct,flOptions,lCount,astring,alAdx);
298 free(astring);
299 return ret;
300}
301//******************************************************************************
302//******************************************************************************
303DWORD CFT2Module::Ft2GetFontData(HPS hps, DWORD dwTable, DWORD dwOffset,
304 LPVOID lpvBuffer, DWORD cbData)
305{
306 //no fallback
307 SetLastError(ERROR_CALL_NOT_IMPLEMENTED_W);
308 return(GDI_ERROR);
309}
310//******************************************************************************
311// Query the font type current selected into the presentation space, or,
312// when hps == NULL, query the type of the font with the specified name
313//******************************************************************************
314DWORD CFT2Module::Ft2QueryFontType(HPS hps, LPCSTR lpszFontName)
315{
316 DWORD ret;
317 USHORT sel;
318
319 // All FreeType calls should be wrapped for saving FS
320 if(pfnFt2QueryFontType) {
321 sel = RestoreOS2FS();
322 ret = pfnFt2QueryFontType(hps, lpszFontName);
323 SetFS(sel);
324 if(ret || (ret == GDI_ERROR && ERRORIDERROR(WinGetLastError(0)) != PMERR_FUNCTION_NOT_SUPPORTED))
325 return ret;
326 }
327 //no fallback
328 return FT2_FONTTYPE_UNKNOWN;
329}
330//******************************************************************************
331//******************************************************************************
332BOOL CFT2Module::Ft2GetStringWidthW(HDC hdc, LPWSTR lpszString, UINT cbString, PINT pWidthArray)
333{
334 DWORD ret;
335 USHORT sel;
336 pDCData pHps;
337
338 pHps = (pDCData)OSLibGpiQueryDCData(hdc);
339 if(pHps == NULL) {
340 DebugInt3();
341 SetLastError(ERROR_INVALID_HANDLE_W);
342 return 0;
343 }
344
345 // All FreeType calls should be wrapped for saving FS
346 if(pfnFt2QueryStringWidthW) {
347 sel = RestoreOS2FS();
348 ret = pfnFt2QueryStringWidthW((HPS)hdc, lpszString, cbString, (LONG *)pWidthArray);
349 SetFS(sel);
350 if(ret || (ret == GDI_ERROR && ERRORIDERROR(WinGetLastError(0)) != PMERR_FUNCTION_NOT_SUPPORTED))
351 {
352 if(pHps && pHps->isPrinter && pHps->hdc)
353 {//scale for printer dcs
354 LONG alArray[2];
355
356 if(OSLibDevQueryCaps(pHps, OSLIB_CAPS_HORIZONTAL_RESOLUTION, 2, &alArray[0]) &&
357 alArray[0] != alArray[1])
358 {
359 dprintf(("Different hor/vert resolutions (%d,%d)", alArray[0], alArray[1]));
360 for (int i = 0; i < cbString; i++)
361 {
362 pWidthArray[i] = pWidthArray[i] * alArray[0] / alArray[1];
363 }
364 }
365 }
366 return ret;
367 }
368 }
369 //fallback method
370 int c, i;
371 for (i = 0; i < cbString; i++)
372 {
373 if (GetCharWidth32W(hdc, lpszString[i], lpszString[i], (LPINT)&c)) {
374 dprintf(("%c pWidthArray[%d] = %d", lpszString[i], i, c));
375 pWidthArray[i]= c;
376 }
377 else {
378 dprintf(("WARNING: GetCharWidth32W failed for %c!!!", lpszString[i]));
379 pWidthArray[i] = 0;
380 }
381 }
382 return TRUE;
383}
384/*****************************************************************************
385 * Name : DWORD GetCharacterPlacementW
386 * Purpose : The GetCharacterPlacementW function retrieves information about
387 * a character string, such as character widths, caret positioning,
388 * ordering within the string, and glyph rendering. The type of
389 * information returned depends on the dwFlags parameter and is
390 * based on the currently selected font in the given display context.
391 * The function copies the information to the specified GCP_RESULTSW
392 * structure or to one or more arrays specified by the structure.
393 * Parameters: HDC hdc handle to device context
394 * LPCSTR lpString pointer to string
395 * int nCount number of characters in string
396 * int nMaxExtent maximum extent for displayed string
397 * GCP_RESULTSW *lpResults pointer to buffer for placement result
398 * DWORD dwFlags placement flags
399 * Variables :
400 * Result :
401 * Remark :
402 * Status : Partly working
403 *
404 * Author : Borrowed Rewind Code
405 *****************************************************************************/
406DWORD CFT2Module::Ft2GetCharacterPlacementW(HDC hdc,
407 LPCWSTR lpString,
408 int uCount,
409 int nMaxExtent,
410 GCP_RESULTSW *lpResults,
411 DWORD dwFlags)
412{
413 DWORD ret;
414 USHORT sel;
415 SIZE size;
416 UINT i, nSet;
417 pDCData pHps;
418
419 pHps = (pDCData)OSLibGpiQueryDCData(hdc);
420 if(pHps == NULL) {
421 DebugInt3();
422 SetLastError(ERROR_INVALID_HANDLE_W);
423 return 0;
424 }
425
426 dprintf(("%ls, %d, %d, 0x%08lx\n", lpString, uCount, nMaxExtent, dwFlags));
427
428 dprintf(("lStructSize=%ld, lpOutString=%p, lpOrder=%p, lpDx=%p, lpCaretPos=%p, lpClass=%p, lpGlyphs=%p, nGlyphs=%u, nMaxFit=%d\n",
429 lpResults->lStructSize, lpResults->lpOutString, lpResults->lpOrder,
430 lpResults->lpDx, lpResults->lpCaretPos, lpResults->lpClass,
431 lpResults->lpGlyphs, lpResults->nGlyphs, lpResults->nMaxFit));
432
433 if(dwFlags&(~0)) dprintf(("unsupported flags 0x%08lx\n", dwFlags));
434 if(lpResults->lpCaretPos) dprintf(("caret positions not implemented\n"));
435 if(lpResults->lpClass) dprintf(("classes not implemented\n"));
436
437 nSet = (UINT)uCount;
438 if(nSet > lpResults->nGlyphs)
439 nSet = lpResults->nGlyphs;
440
441 /* return number of initialized fields */
442 lpResults->nGlyphs = nSet;
443 lpResults->nMaxFit = nSet;
444
445 /* Treat the case where no special handling was requested in a fastpath way */
446 /* copy will do if the GCP_REORDER flag is not set */
447 if(lpResults->lpOutString)
448 strncpyW( lpResults->lpOutString, lpString, nSet );
449
450 if(lpResults->lpOrder)
451 for(i = 0; i < nSet; i++)
452 lpResults->lpOrder[i] = i;
453
454 //fallback method
455
456 /* FIXME: Will use the placement chars */
457 if (lpResults->lpDx)
458 {
459 Ft2GetStringWidthW(hdc, (LPWSTR)lpString, nSet, lpResults->lpDx);
460 }
461
462 if(lpResults->lpGlyphs)
463 GetGlyphIndicesW(hdc, lpString, nSet, lpResults->lpGlyphs, 0);
464
465 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
466 ret = MAKELONG(size.cx, size.cy);
467 else ret = 0;
468
469 return ret;
470}
471//******************************************************************************
472//******************************************************************************
Note: See TracBrowser for help on using the repository browser.