2 * PROJECT: ReactOS win32 subsystem
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: GDI font driver for bitmap fonts
5 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
17 pc
= EngAllocMem(0, cjView
, 'tmp ');
18 memcpy(pc
, pvView
, cjView
);
25 /** Public Interface **********************************************************/
43 ULONG cjSize
, cNumFaces
;
45 DbgPrint("FtfdLoadFontFile()\n");
47 /* Check parameters */
50 DbgPrint("Only 1 File is allowed, got %ld!\n", cFiles
);
54 /* Map the font file */
55 if (!EngMapFontFileFD(*piFile
, (PULONG
*)&pvView
, &cjView
))
57 DbgPrint("Could not map font file!\n");
62 pvView
= HackFixup(pvView
, cjView
);
64 fterror
= FT_New_Memory_Face(gftlibrary
, pvView
, cjView
, 0, &ftface
);
67 DbgPrint("No faces found in file\n");
70 EngUnmapFontFileFD(*piFile
);
76 /* Get number of faces from the first face */
77 cNumFaces
= ftface
->num_faces
;
79 cjSize
= sizeof(FTFD_FILE
) + cNumFaces
* sizeof(FT_Face
);
80 pfile
= EngAllocMem(0, cjSize
, 'dftF');
83 DbgPrint("EngAllocMem() failed.\n");
86 EngUnmapFontFileFD(*piFile
);
92 pfile
->cNumFaces
= cNumFaces
;
93 pfile
->iFile
= *piFile
;
94 pfile
->pvView
= pvView
;
95 pfile
->cjView
= cjView
;
97 for (i
= 0; i
< pfile
->cNumFaces
; i
++)
99 pfile
->aftface
[i
] = ftface
;
100 FT_Select_Charmap(ftface
, FT_ENCODING_UNICODE
);
103 DbgPrint("Success! Returning %ld faces\n", cNumFaces
);
105 return (ULONG_PTR
)pfile
;
113 PFTFD_FILE pfile
= (PFTFD_FILE
)iFile
;
116 DbgPrint("FtfdUnloadFontFile()\n");
119 EngFreeMem(pfile
->pvView
);
122 for (i
= 0; i
< pfile
->cNumFaces
; i
++)
124 FT_Done_Face(pfile
->aftface
[i
]);
127 /* Unmap the font file */
128 EngUnmapFontFileFD(pfile
->iFile
);
130 /* Free the memory that was allocated for the font */
145 PFTFD_FILE pfile
= (PFTFD_FILE
)iFile
;
147 DbgPrint("FtfdQueryFontFile(ulMode=%ld)\n", ulMode
);
152 case QFF_DESCRIPTION
:
158 /* return the number of faces in the file */
159 return pfile
->cNumFaces
;
175 PFTFD_FILE pfile
= (PFTFD_FILE
)iFile
;
176 PFTFD_IFIMETRICS pifiX
;
182 DbgPrint("FtfdQueryFont()\n");
184 /* Validate parameters */
185 if (iFace
> pfile
->cNumFaces
|| !pid
)
187 DbgPrint("iFace > pfile->cNumFaces || !pid\n");
191 fterror
= FT_New_Memory_Face(gftlibrary
,
198 DbgPrint("FT_New_Memory_Face failed\n");
202 /* Allocate the ifi metrics structure */
203 pifiX
= EngAllocMem(FL_ZERO_MEMORY
, sizeof(FTFD_IFIMETRICS
), TAG_IFIMETRICS
);
206 DbgPrint("EngAllocMem() failed.\n");
207 FT_Done_Face(ftface
);
211 /* Fill IFIMETRICS */
213 pifi
->cjThis
= sizeof(FTFD_IFIMETRICS
);
214 pifi
->cjIfiExtra
= 0;
216 /* Relative offsets */
217 pifi
->dpwszFamilyName
= FIELD_OFFSET(FTFD_IFIMETRICS
, wszFamilyName
);
218 pifi
->dpwszStyleName
= FIELD_OFFSET(FTFD_IFIMETRICS
, wszStyleName
);
219 pifi
->dpwszFaceName
= FIELD_OFFSET(FTFD_IFIMETRICS
, wszFaceName
);
220 pifi
->dpwszUniqueName
= FIELD_OFFSET(FTFD_IFIMETRICS
, wszFaceName
);
221 pifi
->dpCharSets
= FIELD_OFFSET(FTFD_IFIMETRICS
, ajCharSet
);
225 pifi
->jWinCharSet
= ANSI_CHARSET
;
226 pifiX
->ajCharSet
[0] = pifi
->jWinCharSet
;
227 for (i
= 1; i
< 16; i
++)
229 pifiX
->ajCharSet
[i
] = DEFAULT_CHARSET
;
233 pifi
->lItalicAngle
= 0;
235 pifi
->jWinPitchAndFamily
= VARIABLE_PITCH
| FF_DONTCARE
; // FIXME
236 pifi
->usWinWeight
= FW_MEDIUM
; // FIXME
237 pifi
->flInfo
= FM_INFO_TECH_TRUETYPE
| FM_INFO_ARB_XFORMS
|
238 FM_INFO_1BPP
| FM_INFO_4BPP
|
239 FM_INFO_RETURNS_OUTLINES
|
240 FM_INFO_RETURNS_BITMAPS
|
241 FM_INFO_RIGHT_HANDED
;
242 pifi
->fsSelection
= 0;
245 /* Font resolution */
246 pifi
->fwdUnitsPerEm
= ftface
->units_per_EM
;
247 pifi
->fwdLowestPPEm
= 8; // FIXME
250 pifi
->fwdWinAscender
= ftface
->ascender
;
251 pifi
->fwdWinDescender
= - ftface
->descender
;
252 pifi
->fwdMacAscender
= pifi
->fwdWinAscender
;
253 pifi
->fwdMacDescender
= - pifi
->fwdWinDescender
;
254 pifi
->fwdMacLineGap
= 0;
255 pifi
->fwdTypoAscender
= pifi
->fwdWinAscender
;
256 pifi
->fwdTypoDescender
= 0; // FIXME!!! - pifi->fwdWinDescender;
257 pifi
->fwdTypoLineGap
= 0;
258 pifi
->fwdAveCharWidth
= 1085; // FIXME
259 pifi
->fwdMaxCharInc
= ftface
->max_advance_width
;
260 pifi
->fwdCapHeight
= pifi
->fwdUnitsPerEm
/ 2;
261 pifi
->fwdXHeight
= pifi
->fwdUnitsPerEm
/ 4;
262 pifi
->fwdSubscriptXSize
= 0;
263 pifi
->fwdSubscriptYSize
= 0;
264 pifi
->fwdSubscriptXOffset
= 0;
265 pifi
->fwdSubscriptYOffset
= 0;
266 pifi
->fwdSuperscriptXSize
= 0;
267 pifi
->fwdSuperscriptYSize
= 0;
268 pifi
->fwdSuperscriptXOffset
= 0;
269 pifi
->fwdSuperscriptYOffset
= 0;
270 pifi
->fwdUnderscoreSize
= 1;
271 pifi
->fwdUnderscorePosition
= -1;
272 pifi
->fwdStrikeoutSize
= 1;
273 pifi
->fwdStrikeoutPosition
= pifi
->fwdXHeight
+ 1;
275 pifi
->ptlBaseline
.x
= 1;
276 pifi
->ptlBaseline
.y
= 0;
277 pifi
->ptlAspect
.x
= 1;
278 pifi
->ptlAspect
.y
= 1;
279 pifi
->ptlCaret
.x
= 0;
280 pifi
->ptlCaret
.y
= 1;
282 /* Set the biggest characters bounding box */
283 pifi
->rclFontBox
.left
= ftface
->bbox
.xMin
;
284 pifi
->rclFontBox
.right
= ftface
->bbox
.xMax
;
285 pifi
->rclFontBox
.top
= ftface
->bbox
.yMax
;
286 pifi
->rclFontBox
.bottom
= ftface
->bbox
.yMin
;
288 /* Special characters */
289 pifi
->chFirstChar
= 0x1c; // FIXME
290 pifi
->chLastChar
= 0x79;
291 pifi
->chDefaultChar
= 0x1d;
292 pifi
->chBreakChar
= 0x1e;
293 pifi
->wcFirstChar
= 0x1e;
294 pifi
->wcLastChar
= 0x79;
295 pifi
->wcDefaultChar
= 0x1d;
296 pifi
->wcBreakChar
= 0x1e;
299 *(DWORD
*)&pifi
->achVendId
= 0x30303030; // FIXME
300 pifi
->cKerningPairs
= 0;
301 pifi
->ulPanoseCulture
= FM_PANOSE_CULTURE_LATIN
;
302 // pifi->panose = panose;
304 EngMultiByteToUnicodeN(pifiX
->wszFamilyName
,
308 strnlen(ftface
->family_name
, MAX_PATH
));
310 EngMultiByteToUnicodeN(pifiX
->wszStyleName
,
314 strnlen(ftface
->style_name
, MAX_PATH
));
316 EngMultiByteToUnicodeN(pifiX
->wszFaceName
,
320 strnlen(ftface
->family_name
, MAX_PATH
));
322 FT_Done_Face(ftface
);
324 DbgPrint("Finished with the ifi: %p\n", pifiX
);
337 DbgPrint("FtfdQueryFontCaps()\n");
339 /* We need room for 2 ULONGs */
345 /* We only support 1 bpp */
347 pulCaps
[1] = QC_1BIT
;
362 PFTFD_FILE pfile
= (PFTFD_FILE
)iFile
;
366 FD_GLYPHSET
*pGlyphSet
;
368 ULONG i
, j
, cGlyphs
, cRuns
, cjSize
;
372 DbgPrint("FtfdQueryFontTree()\n");
374 fterror
= FT_New_Memory_Face(gftlibrary
,
381 DbgPrint("FT_New_Memory_Face() failed.\n");
385 /* Get initial value for cGlyphs from ftface */
386 cGlyphs
= ftface
->num_glyphs
+ 1;
388 /* Allocate a buffer for the char codes and glyph indexes */
389 pcp
= EngAllocMem(0, cGlyphs
* sizeof(FTFD_CHARPAIR
), 'pcp ');
392 DbgPrint("EngAllocMem() failed.\n");
396 /* Gather char codes and indexes and count WCRUNs */
397 pcp
[0].code
= FT_Get_First_Char(ftface
, &pcp
[0].index
);
398 charcode
= pcp
[0].code
;
399 for (i
= 1, cRuns
= 1; charcode
&& i
< cGlyphs
; i
++)
401 charcode
= FT_Get_Next_Char(ftface
, charcode
, &pcp
[i
].index
);
402 DbgPrint("charcode=0x%lx, index=0x%lx\n", charcode
, pcp
[i
].index
);
403 pcp
[i
].code
= charcode
;
404 if (charcode
!= pcp
[i
- 1].code
+ 1)
410 /* Update cGlyphs to real value */
413 /* Calculate FD_GLYPHSET size */
414 cjSize
= sizeof(FD_GLYPHSET
)
415 + (cRuns
- 1) * sizeof(WCRUN
)
416 + cGlyphs
* sizeof(HGLYPH
);
418 /* Allocate the FD_GLYPHSET structure */
419 pGlyphSet
= EngAllocMem(0, cjSize
, TAG_GLYPHSET
);
422 DbgPrint("EngAllocMem() failed.\n");
426 /* Initialize FD_GLYPHSET */
427 pGlyphSet
->cjThis
= cjSize
;
428 pGlyphSet
->flAccel
= 0;
429 pGlyphSet
->cGlyphsSupported
= cGlyphs
;
430 pGlyphSet
->cRuns
= cRuns
;
432 /* Initialize 1st WCRUN */
433 pwcrun
= pGlyphSet
->awcrun
;
434 phglyphs
= (PHGLYPH
)&pGlyphSet
->awcrun
[cRuns
];
435 pwcrun
[0].wcLow
= pcp
[0].code
;
436 pwcrun
[0].cGlyphs
= 1;
437 pwcrun
[0].phg
= &phglyphs
[0];
438 phglyphs
[0] = pcp
[0].index
;
440 DbgPrint("pcp[0].index = 0x%lx\n", pcp
[0].index
);
442 /* Walk through all supported chars */
443 for (i
= 1, j
= 0; i
< cGlyphs
; i
++)
445 /* Use glyph index as HGLYPH */
446 phglyphs
[i
] = pcp
[i
].index
;
448 /* Check whether we can append the wchar to a run */
449 if (pcp
[i
].code
== pcp
[i
- 1].code
+ 1)
451 /* Append to current WCRUN */
456 /* Add a new WCRUN */
457 DbgPrint("adding new run\n");
459 pwcrun
[j
].wcLow
= pcp
[i
].code
;
460 pwcrun
[j
].cGlyphs
= 1;
461 pwcrun
[j
].phg
= &phglyphs
[i
];
465 /* Free the temporary buffer */
468 /* Set *pid to the allocated structure for use in FtfdFree */
469 *pid
= (ULONG_PTR
)pGlyphSet
;
471 DbgPrint("pGlyphSet=%p\n", pGlyphSet
);
483 DbgPrint("FtfdFree()\n");
486 EngFreeMem((PVOID
)id
);