Author: tkreuzer
Date: Sun Aug 14 08:52:14 2011
New Revision: 53219
URL:
http://svn.reactos.org/svn/reactos?rev=53219&view=rev
Log:
[GDI FONT DRIVER]
Revert unwanted changes
Modified:
branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/CMakeLists.txt
branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/enable.c
branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c
branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/ftfd.h
branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/glyph.c
branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/rosglue.c
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/CMakeLists.txt
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers…
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/CMakeLists.txt [iso-8859-1]
(original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/CMakeLists.txt [iso-8859-1]
Sun Aug 14 08:52:14 2011
@@ -5,10 +5,11 @@
add_library(ftfd SHARED
enable.c
+ copybits.c
font.c
glyph.c
+ tttables.c
rosglue.c
- sprintf.c
${CMAKE_CURRENT_BINARY_DIR}/ftfd.def)
set_entrypoint(ftfd FtfdEnableDriver@12)
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/enable.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers…
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/enable.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/enable.c [iso-8859-1] Sun Aug
14 08:52:14 2011
@@ -1,7 +1,7 @@
/*
* PROJECT: ReactOS win32 subsystem
* LICENSE: GPL - See COPYING in the top level directory
- * PURPOSE: GDI font driver for bitmap fonts
+ * PURPOSE: GDI font driver based on freetype
* PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
*/
@@ -9,22 +9,28 @@
static DRVFN gadrvfn[] =
{
- {INDEX_DrvEnablePDEV, (PFN)FtfdEnablePDEV},
- {INDEX_DrvCompletePDEV, (PFN)FtfdCompletePDEV},
- {INDEX_DrvDisablePDEV, (PFN)FtfdDisablePDEV},
- {INDEX_DrvLoadFontFile, (PFN)FtfdLoadFontFile},
- {INDEX_DrvUnloadFontFile, (PFN)FtfdUnloadFontFile},
- {INDEX_DrvQueryFontFile, (PFN)FtfdQueryFontFile},
- {INDEX_DrvQueryFontCaps, (PFN)FtfdQueryFontCaps},
- {INDEX_DrvQueryFontTree, (PFN)FtfdQueryFontTree},
- {INDEX_DrvQueryFont, (PFN)FtfdQueryFont},
- {INDEX_DrvFree, (PFN)FtfdFree},
- {INDEX_DrvQueryGlyphAttrs, (PFN)FtfdQueryGlyphAttrs},
- {INDEX_DrvQueryFontData, (PFN)FtfdQueryFontData},
+ {INDEX_DrvEnablePDEV, (PFN)FtfdEnablePDEV},
+ {INDEX_DrvCompletePDEV, (PFN)FtfdCompletePDEV},
+ {INDEX_DrvDisablePDEV, (PFN)FtfdDisablePDEV},
+ {INDEX_DrvLoadFontFile, (PFN)FtfdLoadFontFile},
+ {INDEX_DrvUnloadFontFile, (PFN)FtfdUnloadFontFile},
+ {INDEX_DrvQueryFontFile, (PFN)FtfdQueryFontFile},
+ {INDEX_DrvQueryFontCaps, (PFN)FtfdQueryFontCaps},
+ {INDEX_DrvQueryFontTree, (PFN)FtfdQueryFontTree},
+ {INDEX_DrvQueryFont, (PFN)FtfdQueryFont},
+ {INDEX_DrvDestroyFont, (PFN)FtfdDestroyFont},
+// {INDEX_DrvFree, (PFN)FtfdFree},
+ {INDEX_DrvQueryGlyphAttrs, (PFN)FtfdQueryGlyphAttrs},
+ {INDEX_DrvQueryFontData, (PFN)FtfdQueryFontData},
+ {INDEX_DrvQueryAdvanceWidths, (PFN)FtfdQueryAdvanceWidths},
+ {INDEX_DrvQueryTrueTypeOutline, (PFN)FtfdQueryTrueTypeOutline},
+ {INDEX_DrvQueryTrueTypeTable, (PFN)FtfdQueryTrueTypeTable},
+ {INDEX_DrvEscape, (PFN)FtfdEscape},
+ {INDEX_DrvFontManagement, (PFN)FtfdFontManagement},
+ {INDEX_DrvGetTrueTypeFile, (PFN)FtfdGetTrueTypeFile},
};
FT_Library gftlibrary;
-
BOOL
APIENTRY
@@ -33,9 +39,12 @@
ULONG cj,
PDRVENABLEDATA pded)
{
- FT_Error fterror;
+ FT_Error fterror;
- DbgPrint("FtfdEnableDriver()\n");
+ TRACE("FtfdEnableDriver()\n");
+
+//__debugbreak();
+
/* Check parameter */
if (cj < sizeof(DRVENABLEDATA))
@@ -47,7 +56,7 @@
fterror = FT_Init_FreeType(&gftlibrary);
if (fterror)
{
- DbgPrint("an error occurred during library initialization: %ld.\n",
fterror);
+ WARN("Failed to initialize freetype library: %ld.\n", fterror);
return FALSE;
}
@@ -76,9 +85,7 @@
IN LPWSTR pwszDeviceName,
IN HANDLE hDriver)
{
- DbgPrint("FtfdEnablePDEV(hdev=%p)\n", hdev);
- __debugbreak();
-
+ TRACE("FtfdEnablePDEV(hdev=%p)\n", hdev);
/* Return a dummy DHPDEV */
return (PVOID)1;
@@ -91,7 +98,7 @@
IN DHPDEV dhpdev,
IN HDEV hdev)
{
- DbgPrint("FtfdCompletePDEV()\n");
+ TRACE("FtfdCompletePDEV()\n");
/* Nothing to do */
}
@@ -101,6 +108,22 @@
FtfdDisablePDEV(
IN DHPDEV dhpdev)
{
- DbgPrint("FtfdDisablePDEV()\n");
+ TRACE("FtfdDisablePDEV()\n");
/* Nothing to do */
}
+
+ULONG
+APIENTRY
+FtfdEscape(
+ SURFOBJ *pso,
+ ULONG iEsc,
+ ULONG cjIn,
+ PVOID pvIn,
+ ULONG cjOut,
+ PVOID pvOut)
+{
+ TRACE("FtfdEscape\n");
+ __debugbreak();
+ return 0;
+}
+
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers…
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c [iso-8859-1] Sun Aug
14 08:52:14 2011
@@ -1,26 +1,512 @@
/*
* PROJECT: ReactOS win32 subsystem
* LICENSE: GPL - See COPYING in the top level directory
- * PURPOSE: GDI font driver for bitmap fonts
+ * PURPOSE: GDI font driver based on freetype
* PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
*/
#include "ftfd.h"
+static
+FWORD
+CalculateAveCharWidth(
+ FT_Face ftface)
+{
+ ULONG cGlyphs = 0, ulAccumCharWidth = 0;
+ WCHAR wc;
+ FT_UInt index;
+ FT_Error fterror;
+
+ /* Loop all glyphs from 'a' to 'z' */
+ for (wc = L'a'; wc <= L'z'; wc++)
+ {
+ /* Load the glyph into the glyph slot */
+ fterror = FT_Load_Char(ftface, wc, FT_LOAD_NO_SCALE|FT_LOAD_NO_BITMAP);
+ if (fterror) break;
+
+ /* Calculate accumulative char width */
+ ulAccumCharWidth += ftface->glyph->metrics.width;
+ cGlyphs++;
+ }
+
+ /* Check if an error occured */
+ if (wc <= L'z')
+ {
+ TRACE("using all glyphs\n");
+
+ /* Start over */
+ ulAccumCharWidth = 0;
+ cGlyphs = 0;
+
+ /* Loop all glyphs in the font */
+ for (index = 0; index <= (UINT)ftface->num_glyphs; index++)
+ {
+ /* Load the glyph into the glyph slot */
+ fterror = FT_Load_Glyph(ftface, index, FT_LOAD_NO_SCALE|FT_LOAD_NO_BITMAP);
+ if (fterror) continue;
+
+ /* Calculate accumulative char width */
+ ulAccumCharWidth += ftface->glyph->metrics.width; // FIXME: weighted
+ cGlyphs++;
+ }
+ }
+
+ /* Return the average glyph width */
+ return (FWORD)(ulAccumCharWidth / cGlyphs);
+}
+
+BOOL
+NTAPI
+FtfdInitIfiMetrics(
+ PFTFD_FACE pface)
+{
+ PFTFD_IFIMETRICS pifiex;
+ PIFIMETRICS pifi;
+ FT_Face ftface;
+ FT_Error fterror;
+ PS_FontInfoRec fontinfo;
+ ULONG i;
+
+ TRACE("FtfdInitIfiMetrics()\n");
+
+ /* Get the freetype face pointer */
+ ftface = pface->ftface;
+
+ /* Init header */
+ pifiex = &pface->ifiex;
+ pifi = &pface->ifiex.ifi;
+ pifi->cjThis = sizeof(FTFD_IFIMETRICS);
+ pifi->cjIfiExtra = 0;
+
+ /* Set relative offsets */
+ pifi->dpwszFamilyName = FIELD_OFFSET(FTFD_IFIMETRICS, awcFamilyName);
+ pifi->dpwszStyleName = FIELD_OFFSET(FTFD_IFIMETRICS, awcStyleName);
+ pifi->dpwszFaceName = FIELD_OFFSET(FTFD_IFIMETRICS, awcFaceName);
+ pifi->dpwszUniqueName = FIELD_OFFSET(FTFD_IFIMETRICS, awcUniqueName);
+ pifi->dpCharSets = FIELD_OFFSET(FTFD_IFIMETRICS, ajCharSet);
+ pifi->dpFontSim = 0;
+
+ /* Initialize charsets */
+ pifi->jWinCharSet = ANSI_CHARSET;
+ pifiex->ajCharSet[0] = pifi->jWinCharSet;
+ for (i = 1; i < 16; i++)
+ {
+ pifiex->ajCharSet[i] = DEFAULT_CHARSET;
+ }
+
+ pifi->lEmbedId = 0;
+ pifi->lCharBias = 0;
+
+ /* Feature flags */
+ pifi->flInfo = FM_INFO_RETURNS_BITMAPS | FM_INFO_1BPP | FM_INFO_4BPP;
+ if (pface->ulFontFormat == FMT_TYPE1)
+ pifi->flInfo |= FM_INFO_TECH_TYPE1;
+ if (pface->ulFontFormat == FMT_CFF)
+ pifi->flInfo |= FM_INFO_TECH_TYPE1 | FM_INFO_TECH_CFF;
+ if (pface->ulFontFormat == FMT_TRUETYPE)
+ pifi->flInfo |= FM_INFO_TECH_TRUETYPE;
+ else
+ pifi->flInfo |= FM_INFO_TECH_OUTLINE_NOT_TRUETYPE;
+ if (pface->cRuns > 1)
+ pifi->flInfo |= FM_INFO_NOT_CONTIGUOUS;
+ if (pface->ulFontFormat != FMT_FNT)
+ pifi->flInfo |= /*FM_INFO_RETURNS_OUTLINES |*/ FM_INFO_ARB_XFORMS;
+ pifi->flInfo |= FM_INFO_RIGHT_HANDED; // FIXME: how to determine?
+
+ /* Font resolution */
+ pifi->fwdUnitsPerEm = ftface->units_per_EM;
+ pifi->fwdLowestPPEm = 3;
+
+ /* Font metrics */
+ pifi->fwdMacAscender = ftface->ascender;
+ pifi->fwdMacDescender = ftface->descender;
+ pifi->fwdMacLineGap = 0;
+ pifi->fwdMaxCharInc = ftface->max_advance_width;
+ pifi->fwdUnderscoreSize = ftface->underline_thickness;
+ pifi->fwdUnderscorePosition = ftface->underline_position;
+
+ pifi->ptlBaseline.x = 1; // FIXME
+ pifi->ptlBaseline.y = 0; // FIXME
+ pifi->ptlAspect.x = 1;
+ pifi->ptlAspect.y = 1;
+ pifi->ptlCaret.x = 0; // FIXME
+ pifi->ptlCaret.y = 1; // FIXME
+
+ /* Set the biggest characters bounding box */
+ pifi->rclFontBox.left = ftface->bbox.xMin;
+ pifi->rclFontBox.right = ftface->bbox.xMax;
+ pifi->rclFontBox.top = ftface->bbox.yMax;
+ pifi->rclFontBox.bottom = ftface->bbox.yMin;
+
+ pifi->ulPanoseCulture = FM_PANOSE_CULTURE_LATIN;
+
+ /* Try to get OS/2 TrueType or OpenType metrics */
+ if (!FtfdGetWinMetrics(pface, pifi))
+ {
+ /* No success, use fallback */
+
+ /* Font style flags */
+ pifi->fsType = 0;
+ pifi->fsSelection = FM_SEL_REGULAR;
+ pifi->usWinWeight = FW_REGULAR;
+ if (ftface->style_flags & FT_STYLE_FLAG_BOLD)
+ {
+ pifi->fsSelection &= ~FM_SEL_REGULAR;
+ pifi->fsSelection |= FM_SEL_BOLD;
+ pifi->usWinWeight = FW_BOLD;
+ }
+ if (ftface->style_flags & FT_STYLE_FLAG_ITALIC)
+ {
+ pifi->fsSelection &= ~FM_SEL_REGULAR;
+ pifi->fsSelection |= FM_SEL_ITALIC;
+ }
+
+ /* Metrics */
+ pifi->fwdWinAscender = (ftface->ascender * 213) / 170;
+ pifi->fwdWinDescender = -(ftface->descender * 213) / 170;
+ pifi->fwdTypoAscender = ftface->ascender;
+ pifi->fwdTypoDescender = ftface->descender;
+ pifi->fwdTypoLineGap = pifi->fwdUnitsPerEm / 10;
+ pifi->fwdCapHeight = pifi->fwdUnitsPerEm / 2;
+ pifi->fwdXHeight = pifi->fwdUnitsPerEm / 4;
+ pifi->fwdSubscriptXSize = 0;
+ pifi->fwdSubscriptYSize = 0;
+ pifi->fwdSubscriptXOffset = 0;
+ pifi->fwdSubscriptYOffset = 0;
+ pifi->fwdSuperscriptXSize = 0;
+ pifi->fwdSuperscriptYSize = 0;
+ pifi->fwdSuperscriptXOffset = 0;
+ pifi->fwdSuperscriptYOffset = 0;
+ pifi->fwdStrikeoutSize = pifi->fwdUnderscoreSize;
+ pifi->fwdStrikeoutPosition = pifi->fwdMacAscender / 3;
+ pifi->fwdAveCharWidth = CalculateAveCharWidth(ftface);
+
+ /* Special characters */
+ pifi->wcDefaultChar = 0x001F;
+ pifi->wcBreakChar = 0x0020;
+
+ pifi->panose.bFamilyType = PAN_FAMILY_TEXT_DISPLAY;
+ pifi->panose.bSerifStyle = PAN_ANY;
+ pifi->panose.bWeight = PAN_ANY;
+ pifi->panose.bProportion = PAN_ANY;
+ pifi->panose.bContrast = PAN_ANY;
+ pifi->panose.bStrokeVariation = PAN_ANY;
+ pifi->panose.bArmStyle = PAN_ANY;
+ pifi->panose.bLetterform = PAN_ANY;
+ pifi->panose.bMidline = PAN_ANY;
+ pifi->panose.bXHeight = PAN_ANY;
+
+ *(DWORD*)&pifi->achVendId = 'nknU';
+ }
+
+ /* Copy unicode values to ansi values */
+ pifi->chDefaultChar = (CHAR)pifi->wcDefaultChar;
+ pifi->chBreakChar = (CHAR)pifi->wcBreakChar;
+ pifi->chFirstChar = (CHAR)pifi->wcFirstChar;
+ if (pifi->wcFirstChar > 0xff) pifi->chFirstChar = 0xff;
+ pifi->chLastChar = (CHAR)pifi->wcLastChar;
+ if (pifi->wcLastChar > 0xff) pifi->chLastChar = 0xff;
+
+ /* Try to get type1 info from freetype */
+ fterror = FT_Get_PS_Font_Info(pface->ftface, &fontinfo);
+ if (fterror == 0)
+ {
+ /* Set italic angle */
+ pifi->lItalicAngle = fontinfo.italic_angle;
+ }
+ else
+ {
+ /* Set fallback values */
+ pifi->lItalicAngle = 0;
+ }
+
+ /* Get the win family */
+ if (pifi->panose.bFamilyType == PAN_FAMILY_SCRIPT)
+ pifi->jWinPitchAndFamily = FF_SCRIPT;
+ else if (pifi->panose.bFamilyType == PAN_FAMILY_DECORATIVE)
+ pifi->jWinPitchAndFamily = FF_DECORATIVE;
+ else if (pifi->panose.bProportion == PAN_PROP_MODERN)
+ pifi->jWinPitchAndFamily = FF_MODERN;
+ else if (pifi->panose.bSerifStyle <= PAN_SERIF_ROUNDED)
+ pifi->jWinPitchAndFamily = FF_SWISS;
+ else
+ pifi->jWinPitchAndFamily = FF_ROMAN;
+
+ /* Set pitch */
+ pifi->jWinPitchAndFamily |= FT_IS_FIXED_WIDTH(ftface) ? FIXED_PITCH :
+ VARIABLE_PITCH;
+
+ /* Convert the special characters from unicode to ansi */
+ EngUnicodeToMultiByteN(&pifi->chFirstChar, 4, NULL, &pifi->wcFirstChar,
8);
+
+ /* This one seems to be hardcoded to 0xff */
+ pifi->chLastChar = 0xff;
+
+ /* Convert names to unicode */
+ EngMultiByteToUnicodeN(pifiex->awcFamilyName,
+ sizeof(pifiex->awcFamilyName),
+ NULL,
+ ftface->family_name,
+ strnlen(ftface->family_name, MAX_PATH));
+
+ EngMultiByteToUnicodeN(pifiex->awcStyleName,
+ sizeof(pifiex->awcStyleName),
+ NULL,
+ ftface->style_name,
+ strnlen(ftface->style_name, MAX_PATH));
+
+ EngMultiByteToUnicodeN(pifiex->awcFaceName,
+ sizeof(pifiex->awcFaceName),
+ NULL,
+ ftface->family_name,
+ strnlen(ftface->family_name, MAX_PATH));
+
+ /* Create a unique name */
+ wcscpy(pifiex->awcUniqueName, L"1.000;????;");
+ wcsncat(pifiex->awcUniqueName, pifiex->awcFamilyName, LF_FACESIZE);
+ pifiex->awcUniqueName[0] = L'0' + HIWORD(pface->ulFontRevision) % 10;
+ pifiex->awcUniqueName[2] = L'0' + (LOWORD(pface->ulFontRevision) / 100)
% 10;
+ pifiex->awcUniqueName[3] = L'0' + (LOWORD(pface->ulFontRevision) / 10)
% 10;
+ pifiex->awcUniqueName[4] = L'0' + LOWORD(pface->ulFontRevision) % 10;
+ EngMultiByteToUnicodeN(pifiex->awcUniqueName+6, 8, NULL, pifi->achVendId, 4);
+
+ //__debugbreak();
+ return TRUE;
+}
+
PVOID
-HackFixup(
- PVOID pvView,
- ULONG cjView)
-{
- CHAR *pc;
-
- pc = EngAllocMem(0, cjView, 'tmp ');
- memcpy(pc, pvView, cjView);
-
- *pc = 0;
-
- return pc;
-}
+APIENTRY
+FtfdInitGlyphSet(
+ PFTFD_FACE pface)
+{
+ FT_Face ftface = pface->ftface;
+ FD_GLYPHSET *pGlyphSet;
+ FT_UInt index;
+ ULONG i, cRuns, cjSize;
+ HGLYPH * phglyphs;
+ WCHAR wcCurrent, wcPrev;
+ PWCHAR pwcReverseTable;
+
+ TRACE("FtfdInitGlyphSet()\n");
+
+ /* Allocate an array of WCHARs */
+ cjSize = pface->cGlyphs * sizeof(WCHAR);
+ pwcReverseTable = EngAllocMem(0, cjSize, 'dftF');
+ if (!pwcReverseTable)
+ {
+ WARN("EngAllocMem() failed.\n");
+ return NULL;
+ }
+
+ /* Calculate FD_GLYPHSET size (incl. HGLYPH array!) */
+ cjSize = FIELD_OFFSET(FD_GLYPHSET, awcrun)
+ + pface->cRuns * sizeof(WCRUN)
+ + pface->cMappings * sizeof(HGLYPH);
+
+ /* Allocate the FD_GLYPHSET structure plus an array of HGLYPHs */
+ pGlyphSet = EngAllocMem(0, cjSize, TAG_GLYPHSET);
+ if (!pGlyphSet)
+ {
+ WARN("EngAllocMem() failed.\n");
+ return NULL;
+ }
+
+ /* Get a pointer to the HGLYPH array */
+ phglyphs = (PHGLYPH)&pGlyphSet->awcrun[pface->cRuns];
+
+ /* Initialize FD_GLYPHSET */
+ pGlyphSet->cjThis = cjSize;
+ pGlyphSet->flAccel = GS_16BIT_HANDLES;
+ pGlyphSet->cGlyphsSupported = pface->cMappings;
+ pGlyphSet->cRuns = pface->cRuns;
+
+ /* Loop through all character mappings */
+ wcPrev = wcCurrent = (WCHAR)FT_Get_First_Char(ftface, &index);
+ for (i = 0, cRuns = 0; i < pface->cMappings && index; i++)
+ {
+ /* Create an entry in the reverse lookup table */
+ ASSERT(index < pface->cGlyphs);
+ pwcReverseTable[index] = wcCurrent;
+
+ /* Use index as glyph handle */
+ phglyphs[i] = (HGLYPH)index;
+
+ /* Check whether we can append the wchar to a run */
+ if (wcCurrent == wcPrev + 1)
+ {
+ /* Append to current WCRUN */
+ pGlyphSet->awcrun[cRuns - 1].cGlyphs++;
+ }
+ else
+ {
+ /* Add a new WCRUN */
+ cRuns++;
+ pGlyphSet->awcrun[cRuns - 1].wcLow = wcCurrent - pface->wcCharBias;
+ pGlyphSet->awcrun[cRuns - 1].cGlyphs = 1;
+ pGlyphSet->awcrun[cRuns - 1].phg = &phglyphs[i];
+ }
+
+ /* Get the next charcode and index */
+ wcPrev = wcCurrent;
+ wcCurrent = (WCHAR)FT_Get_Next_Char(ftface, wcCurrent, &index);
+ }
+
+ TRACE("Done with font tree, %d runs\n", pGlyphSet->cRuns);
+ pface->pGlyphSet = pGlyphSet;
+ pface->pwcReverseTable = pwcReverseTable;
+ return pGlyphSet;
+}
+
+
+static
+ULONG
+FtfdGetFontFormat(FT_Face ftface)
+{
+ const char *pstrFormat;
+
+ /* FreeType only provides a string :-/ */
+ pstrFormat = FT_Get_X11_Font_Format(ftface);
+ if (strcmp(pstrFormat, "TrueType") == 0) return FMT_TRUETYPE;
+ if (strcmp(pstrFormat, "Type 1") == 0) return FMT_TYPE1;
+ if (strcmp(pstrFormat, "CFF") == 0) return FMT_CFF;
+ if (strcmp(pstrFormat, "Windows FNT") == 0) return FMT_FNT;
+ if (strcmp(pstrFormat, "BDF") == 0) return FMT_BDF;
+ if (strcmp(pstrFormat, "PCF") == 0) return FMT_PCF;
+ if (strcmp(pstrFormat, "Type 42") == 0) return FMT_TYPE42;
+ if (strcmp(pstrFormat, "CID Type 1") == 0) return FMT_CIDTYPE1;
+ if (strcmp(pstrFormat, "PFR") == 0) return FMT_PFR;
+ return FMT_UNKNOWN;
+}
+
+static
+ULONG
+FtfdGetFileFormat(
+ PFTFD_FILE pfile)
+{
+ ULONG ulFontFormat = pfile->apface[0]->ulFontFormat;
+
+ if (ulFontFormat == FMT_CFF) return FILEFMT_OTF;
+ if (ulFontFormat == FMT_FNT) return FILEFMT_FNT;
+ if (ulFontFormat == FMT_TRUETYPE)
+ {
+ if (*(DWORD*)pfile->pvView == 'OTTO') return FILEFMT_OTF;
+ return FILEFMT_TTF;
+ }
+
+ __debugbreak();
+ return 0;
+}
+
+PFTFD_FACE
+NTAPI
+FtfdCreateFace(
+ PFTFD_FILE pfile,
+ ULONG iFace,
+ FT_Face ftface)
+{
+ PFTFD_FACE pface;
+ FT_Error fterror;
+ ULONG ulEncoding, ulAccumCharWidth = 0;
+ WCHAR wcCurrent, wcPrev;
+ FT_UInt index;
+
+ /* Try to load a unicode charmap */
+ ulEncoding = FT_ENCODING_UNICODE;
+ fterror = FT_Select_Charmap(ftface, ulEncoding);
+ if (fterror)
+ {
+ /* Check if we have any charmaps at all */
+ if (ftface->num_charmaps == 0)
+ {
+ WARN("There are no charmaps available!\n");
+ return NULL;
+ }
+
+ /* Load first charmap instead */
+ ulEncoding = ftface->charmaps[0]->encoding;
+ fterror = FT_Select_Charmap(ftface, ulEncoding);
+ if (fterror)
+ {
+ WARN("Could not load a charmap\n");
+ return NULL;
+ }
+
+ TRACE("Loaded charmap with encoding %.4s\n", &ulEncoding);
+ }
+
+ pface = EngAllocMem(FL_ZERO_MEMORY, sizeof(FTFD_FACE), 'dftF');
+ if (!pface)
+ {
+ WARN("Couldn't allcate a face\n");
+ return NULL;
+ }
+
+ /* Set basic fields */
+ pface->pfile = pfile;
+ pface->iFace = iFace;
+ pface->ftface = ftface;
+ pface->cGlyphs = ftface->num_glyphs;
+ pface->ulEncoding = ulEncoding;
+
+ /* Set char bias, FIXME: use lCharBias? other encodings? */
+ pface->wcCharBias = ulEncoding == FT_ENCODING_MS_SYMBOL ? 0xf000 : 0;
+
+ /* Get the font format */
+ pface->ulFontFormat = FtfdGetFontFormat(ftface);
+
+ /* Start with 0 runs and 0 mappings */
+ pface->cMappings = 0;
+ pface->cRuns = 0;
+
+ /* Loop through all character mappings */
+ wcPrev = wcCurrent = (WCHAR)FT_Get_First_Char(ftface, &index);
+ pface->ifiex.ifi.wcFirstChar = wcCurrent - pface->wcCharBias;;
+ while (index)
+ {
+ /* Count the mapping */
+ pface->cMappings++;
+
+ /* If character is not subsequent, count a new run */
+ if (wcCurrent != wcPrev + 1) pface->cRuns++;
+ wcPrev = wcCurrent;
+
+ /* Get the next charcode and index */
+ wcCurrent = (WCHAR)FT_Get_Next_Char(ftface, wcCurrent, &index);
+ }
+
+ /* Save the last character */
+ pface->ifiex.ifi.wcLastChar = wcPrev - pface->wcCharBias;;
+
+ /* Initialize IFIMETRICS */
+ FtfdInitIfiMetrics(pface);
+
+ /* Initialize glyphset */
+ FtfdInitGlyphSet(pface);
+
+ /* Initialize kerning pairs */
+ FtfdInitKerningPairs(pface);
+
+ return pface;
+}
+
+static
+VOID
+FtfdDestroyFace(
+ PFTFD_FACE pface)
+{
+ /* Cleanup the freetype face */
+ FT_Done_Face(pface->ftface);
+
+ /* Free the glyphset structure */
+ EngFreeMem(pface->pGlyphSet);
+
+ /* Free the kerning pairs structure */
+ if (pface->pKerningPairs) EngFreeMem(pface->pKerningPairs);
+
+ /* Finally free the face structure */
+ EngFreeMem(pface);
+}
+
/** Public Interface **********************************************************/
@@ -36,121 +522,142 @@
ULONG ulFastCheckSum)
{
PVOID pvView;
- ULONG cjView, i;
+ ULONG cjView, cjSize, cNumFaces, i;
FT_Error fterror;
FT_Face ftface;
- PFTFD_FILE pfile;
- ULONG cjSize, cNumFaces;
-
- DbgPrint("FtfdLoadFontFile()\n");
+ PFTFD_FILE pfile = NULL;
+
+ TRACE("FtfdLoadFontFile()\n");
+//__debugbreak();
+//return 0;
/* Check parameters */
if (cFiles != 1)
{
- DbgPrint("Only 1 File is allowed, got %ld!\n", cFiles);
+ WARN("Only 1 File is allowed, got %ld!\n", cFiles);
return HFF_INVALID;
}
/* Map the font file */
if (!EngMapFontFileFD(*piFile, (PULONG*)&pvView, &cjView))
{
- DbgPrint("Could not map font file!\n");
+ WARN("Could not map font file!\n");
return HFF_INVALID;
}
- // HACK!!!
- pvView = HackFixup(pvView, cjView);
-
+ /* Load the first face */
fterror = FT_New_Memory_Face(gftlibrary, pvView, cjView, 0, &ftface);
if (fterror)
{
- DbgPrint("No faces found in file\n");
-
- /* Unmap the file */
- EngUnmapFontFileFD(*piFile);
-
/* Failure! */
- return HFF_INVALID;
+ WARN("No faces found in file\n");
+ goto error;
}
/* Get number of faces from the first face */
cNumFaces = ftface->num_faces;
- cjSize = sizeof(FTFD_FILE) + cNumFaces * sizeof(FT_Face);
+ /* Allocate the file structure */
+ cjSize = sizeof(FTFD_FILE) + cNumFaces * sizeof(PVOID);
pfile = EngAllocMem(0, cjSize, 'dftF');
if (!pfile)
{
- DbgPrint("EngAllocMem() failed.\n");
-
- /* Unmap the file */
- EngUnmapFontFileFD(*piFile);
-
/* Failure! */
- return HFF_INVALID;
- }
-
+ WARN("EngAllocMem() failed.\n");
+ goto error;
+ }
+
+ /* Initialize the file structure */
pfile->cNumFaces = cNumFaces;
pfile->iFile = *piFile;
- pfile->pvView = pvView;
- pfile->cjView = cjView;
-
- for (i = 0; i < pfile->cNumFaces; i++)
- {
- pfile->aftface[i] = ftface;
- FT_Select_Charmap(ftface, FT_ENCODING_UNICODE);
- }
-
- DbgPrint("Success! Returning %ld faces\n", cNumFaces);
-
+ pfile->pvView = *ppvView;
+ pfile->cjView = *pcjView;
+ pfile->ulFastCheckSum = ulFastCheckSum;
+
+ /* Create a face */
+ pfile->apface[0] = FtfdCreateFace(pfile, 1, ftface);
+ if (!pfile->apface[0])
+ {
+ WARN("FtfdCreateFace() failed.\n");
+ goto error;
+ }
+
+ /* Get the file format */
+ pfile->ulFileFormat = FtfdGetFileFormat(pfile);
+
+ /* Check for design vector */
+ if (pdv)
+ {
+ /* Check if the font format supports it */
+ if (pfile->apface[0]->ulFontFormat != FMT_TYPE1)
+ {
+ WARN("Design vector is not supported\n");
+ goto error;
+ }
+
+ /* Verify the design vector, just in case ... */
+ if (pdv->dvReserved != STAMP_DESIGNVECTOR ||
+ pdv->dvNumAxes > MM_MAX_NUMAXES)
+ {
+ WARN("Design vector is invalid\n");
+ goto error;
+ }
+
+ /* Copy design vector */
+ pfile->dv = *pdv;
+ }
+ else
+ {
+ /* Mark as not present */
+ pfile->dv.dvReserved = 0;
+ }
+
+ /* Loop all additional faces in this file */
+ for (i = 1; i < cNumFaces; i++)
+ {
+ /* Load the face */
+ fterror = FT_New_Memory_Face(gftlibrary, *ppvView, *pcjView, i, &ftface);
+ if (fterror)
+ {
+ WARN("error\n");
+ __debugbreak();
+ goto error;
+ }
+
+ /* Store the face in the file structure */
+ pfile->apface[i] = FtfdCreateFace(pfile, i + 1, ftface);
+ }
+
+ TRACE("Success! Returning %ld faces\n", cNumFaces);
return (ULONG_PTR)pfile;
-}
-
-BOOL
-APIENTRY
-FtfdUnloadFontFile(
- IN ULONG_PTR iFile)
-{
- PFTFD_FILE pfile = (PFTFD_FILE)iFile;
- ULONG i;
-
- DbgPrint("FtfdUnloadFontFile()\n");
-
- // HACK!!!
- EngFreeMem(pfile->pvView);
-
- /* Cleanup faces */
- for (i = 0; i < pfile->cNumFaces; i++)
- {
- FT_Done_Face(pfile->aftface[i]);
- }
-
- /* Unmap the font file */
- EngUnmapFontFileFD(pfile->iFile);
-
- /* Free the memory that was allocated for the font */
- EngFreeMem(pfile);
-
- return TRUE;
-}
-
+
+error:
+ if (pfile) EngFreeMem(pfile);
+
+ /* Unmap the file */
+ EngUnmapFontFileFD(*piFile);
+
+ /* Failure! */
+ return HFF_INVALID;
+}
LONG
APIENTRY
FtfdQueryFontFile(
- ULONG_PTR iFile,
+ ULONG_PTR diFile,
ULONG ulMode,
ULONG cjBuf,
ULONG *pulBuf)
{
- PFTFD_FILE pfile = (PFTFD_FILE)iFile;
-
- DbgPrint("FtfdQueryFontFile(ulMode=%ld)\n", ulMode);
-// __debugbreak();
+ PFTFD_FILE pfile = (PFTFD_FILE)diFile;
+
+ TRACE("FtfdQueryFontFile(ulMode=%ld)\n", ulMode);
switch (ulMode)
{
case QFF_DESCRIPTION:
{
+ WARN("QFF_DESCRIPTION unimplemented\n");
return 0;
}
@@ -162,171 +669,99 @@
return FD_ERROR;
}
-
PIFIMETRICS
APIENTRY
FtfdQueryFont(
IN DHPDEV dhpdev,
- IN ULONG_PTR iFile,
+ IN ULONG_PTR diFile,
IN ULONG iFace,
IN ULONG_PTR *pid)
{
- PFTFD_FILE pfile = (PFTFD_FILE)iFile;
- PFTFD_IFIMETRICS pifiX;
- PIFIMETRICS pifi;
- FT_Face ftface;
- FT_Error fterror;
- ULONG i;
-
- DbgPrint("FtfdQueryFont()\n");
+ PFTFD_FILE pfile = (PFTFD_FILE)diFile;
+ PFTFD_FACE pface = pfile->apface[iFace - 1];
+
+ TRACE("FtfdQueryFont()\n");
/* Validate parameters */
if (iFace > pfile->cNumFaces || !pid)
{
- DbgPrint("iFace > pfile->cNumFaces || !pid\n");
+ WARN("iFace > pfile->cNumFaces || !pid\n");
return NULL;
}
- fterror = FT_New_Memory_Face(gftlibrary,
- pfile->pvView,
- pfile->cjView,
- iFace - 1,
- &ftface);
- if (fterror)
- {
- DbgPrint("FT_New_Memory_Face failed\n");
+ /* Nothing to free */
+ *pid = 0;
+
+ /* Return pointer to the IFIMETRICS */
+ return &pface->ifiex.ifi;
+}
+
+PVOID
+APIENTRY
+FtfdQueryFontTree(
+ DHPDEV dhpdev,
+ ULONG_PTR diFile,
+ ULONG iFace,
+ ULONG iMode,
+ ULONG_PTR *pid)
+{
+ PFTFD_FILE pfile = (PFTFD_FILE)diFile;
+ PFTFD_FACE pface;
+
+ TRACE("FtfdQueryFontTree(iMode=%ld)\n", iMode);
+
+ /* Validate parameters */
+ if (iFace > pfile->cNumFaces || !pid)
+ {
+ WARN("iFace > pfile->cNumFaces || !pid\n");
return NULL;
}
- /* Allocate the ifi metrics structure */
- pifiX = EngAllocMem(FL_ZERO_MEMORY, sizeof(FTFD_IFIMETRICS), TAG_IFIMETRICS);
- if (!pifiX)
- {
- DbgPrint("EngAllocMem() failed.\n");
- FT_Done_Face(ftface);
- return NULL;
- }
-
- /* Fill IFIMETRICS */
- pifi = &pifiX->ifim;
- pifi->cjThis = sizeof(FTFD_IFIMETRICS);
- pifi->cjIfiExtra = 0;
-
- /* Relative offsets */
- pifi->dpwszFamilyName = FIELD_OFFSET(FTFD_IFIMETRICS, wszFamilyName);
- pifi->dpwszStyleName = FIELD_OFFSET(FTFD_IFIMETRICS, wszStyleName);
- pifi->dpwszFaceName = FIELD_OFFSET(FTFD_IFIMETRICS, wszFaceName);
- pifi->dpwszUniqueName = FIELD_OFFSET(FTFD_IFIMETRICS, wszFaceName);
- pifi->dpCharSets = FIELD_OFFSET(FTFD_IFIMETRICS, ajCharSet);
- pifi->dpFontSim = 0;
-
- /* Charsets */
- pifi->jWinCharSet = ANSI_CHARSET;
- pifiX->ajCharSet[0] = pifi->jWinCharSet;
- for (i = 1; i < 16; i++)
- {
- pifiX->ajCharSet[i] = DEFAULT_CHARSET;
- }
-
- pifi->lEmbedId = 0;
- pifi->lItalicAngle = 0;
- pifi->lCharBias = 0;
- pifi->jWinPitchAndFamily = VARIABLE_PITCH | FF_DONTCARE; // FIXME
- pifi->usWinWeight = FW_MEDIUM; // FIXME
- pifi->flInfo = FM_INFO_TECH_TRUETYPE | FM_INFO_ARB_XFORMS |
- FM_INFO_1BPP | FM_INFO_4BPP |
- FM_INFO_RETURNS_OUTLINES |
- FM_INFO_RETURNS_BITMAPS |
- FM_INFO_RIGHT_HANDED;
- pifi->fsSelection = 0;
- pifi->fsType = 0;
-
- /* Font resolution */
- pifi->fwdUnitsPerEm = ftface->units_per_EM;
- pifi->fwdLowestPPEm = 8; // FIXME
-
- /* Font metrics */
- pifi->fwdWinAscender = ftface->ascender;
- pifi->fwdWinDescender = - ftface->descender;
- pifi->fwdMacAscender = pifi->fwdWinAscender;
- pifi->fwdMacDescender = - pifi->fwdWinDescender;
- pifi->fwdMacLineGap = 0;
- pifi->fwdTypoAscender = pifi->fwdWinAscender;
- pifi->fwdTypoDescender = 0; // FIXME!!! - pifi->fwdWinDescender;
- pifi->fwdTypoLineGap = 0;
- pifi->fwdAveCharWidth = 1085; // FIXME
- pifi->fwdMaxCharInc = ftface->max_advance_width;
- pifi->fwdCapHeight = pifi->fwdUnitsPerEm / 2;
- pifi->fwdXHeight = pifi->fwdUnitsPerEm / 4;
- pifi->fwdSubscriptXSize = 0;
- pifi->fwdSubscriptYSize = 0;
- pifi->fwdSubscriptXOffset = 0;
- pifi->fwdSubscriptYOffset = 0;
- pifi->fwdSuperscriptXSize = 0;
- pifi->fwdSuperscriptYSize = 0;
- pifi->fwdSuperscriptXOffset = 0;
- pifi->fwdSuperscriptYOffset = 0;
- pifi->fwdUnderscoreSize = 1;
- pifi->fwdUnderscorePosition = -1;
- pifi->fwdStrikeoutSize = 1;
- pifi->fwdStrikeoutPosition = pifi->fwdXHeight + 1;
-
- pifi->ptlBaseline.x = 1;
- pifi->ptlBaseline.y = 0;
- pifi->ptlAspect.x = 1;
- pifi->ptlAspect.y = 1;
- pifi->ptlCaret.x = 0;
- pifi->ptlCaret.y = 1;
-
- /* Set the biggest characters bounding box */
- pifi->rclFontBox.left = ftface->bbox.xMin;
- pifi->rclFontBox.right = ftface->bbox.xMax;
- pifi->rclFontBox.top = ftface->bbox.yMax;
- pifi->rclFontBox.bottom = ftface->bbox.yMin;
-
- /* Special characters */
- pifi->chFirstChar = 0x1c; // FIXME
- pifi->chLastChar = 0x79;
- pifi->chDefaultChar = 0x1d;
- pifi->chBreakChar = 0x1e;
- pifi->wcFirstChar = 0x1e;
- pifi->wcLastChar = 0x79;
- pifi->wcDefaultChar = 0x1d;
- pifi->wcBreakChar = 0x1e;
-
-
- *(DWORD*)&pifi->achVendId = 0x30303030; // FIXME
- pifi->cKerningPairs = 0;
- pifi->ulPanoseCulture = FM_PANOSE_CULTURE_LATIN;
-// pifi->panose = panose;
-
- EngMultiByteToUnicodeN(pifiX->wszFamilyName,
- LF_FACESIZE,
- NULL,
- ftface->family_name,
- strnlen(ftface->family_name, MAX_PATH));
-
- EngMultiByteToUnicodeN(pifiX->wszStyleName,
- LF_FACESIZE,
- NULL,
- ftface->style_name,
- strnlen(ftface->style_name, MAX_PATH));
-
- EngMultiByteToUnicodeN(pifiX->wszFaceName,
- LF_FACESIZE,
- NULL,
- ftface->family_name,
- strnlen(ftface->family_name, MAX_PATH));
-
- FT_Done_Face(ftface);
-
- DbgPrint("Finished with the ifi: %p\n", pifiX);
- __debugbreak();
-
- return pifi;
-}
-
+ /* Get pointer to the requested face */
+ pface = pfile->apface[iFace - 1];
+
+ switch (iMode)
+ {
+ case QFT_GLYPHSET:
+ *pid = 0;
+ return pface->pGlyphSet;
+
+ case QFT_KERNPAIRS:
+ *pid = 0;
+ return pface->pKerningPairs;
+
+ default:
+ WARN("Invalid iMode: %ld\n", iMode);
+ }
+
+ return NULL;
+}
+
+BOOL
+APIENTRY
+FtfdUnloadFontFile(
+ IN ULONG_PTR diFile)
+{
+ PFTFD_FILE pfile = (PFTFD_FILE)diFile;
+ ULONG i;
+
+ TRACE("FtfdUnloadFontFile()\n");
+
+ /* Cleanup faces */
+ for (i = 0; i < pfile->cNumFaces; i++)
+ {
+ FtfdDestroyFace(pfile->apface[i]);
+ }
+
+ /* Unmap the font file */
+ EngUnmapFontFileFD(pfile->iFile);
+
+ /* Free the memory that was allocated for the file */
+ EngFreeMem(pfile);
+
+ return TRUE;
+}
LONG
APIENTRY
@@ -334,7 +769,7 @@
ULONG culCaps,
ULONG *pulCaps)
{
- DbgPrint("FtfdQueryFontCaps()\n");
+ TRACE("FtfdQueryFontCaps()\n");
/* We need room for 2 ULONGs */
if (culCaps < 2)
@@ -342,150 +777,24 @@
return FD_ERROR;
}
- /* We only support 1 bpp */
+ /* We only support bitmaps for now */
pulCaps[0] = 2;
- pulCaps[1] = QC_1BIT;
+ pulCaps[1] = QC_1BIT | QC_4BIT;
return 2;
}
-PVOID
-APIENTRY
-FtfdQueryFontTree(
- DHPDEV dhpdev,
- ULONG_PTR iFile,
- ULONG iFace,
- ULONG iMode,
- ULONG_PTR *pid)
-{
- PFTFD_FILE pfile = (PFTFD_FILE)iFile;
- FT_Face ftface;
- FT_Error fterror;
- FTFD_CHARPAIR *pcp;
- FD_GLYPHSET *pGlyphSet;
- FT_ULong charcode;
- ULONG i, j, cGlyphs, cRuns, cjSize;
- WCRUN *pwcrun;
- HGLYPH * phglyphs;
-
- DbgPrint("FtfdQueryFontTree()\n");
-
- fterror = FT_New_Memory_Face(gftlibrary,
- pfile->pvView,
- pfile->cjView,
- iFace - 1,
- &ftface);
- if (fterror)
- {
- DbgPrint("FT_New_Memory_Face() failed.\n");
- return NULL;
- }
-
- /* Get inital value for cGlyphs from ftface */
- cGlyphs = ftface->num_glyphs + 1;
-
- /* Allocate a buffer for the char codes and glyph indexes */
- pcp = EngAllocMem(0, cGlyphs * sizeof(FTFD_CHARPAIR), 'pcp ');
- if (!pcp)
- {
- DbgPrint("EngAllocMem() failed.\n");
- return NULL;
- }
-
- /* Gather char codes and indexes and count WCRUNs */
- pcp[0].code = FT_Get_First_Char(ftface, &pcp[0].index);
- charcode = pcp[0].code;
- for (i = 1, cRuns = 1; charcode && i < cGlyphs; i++)
- {
- charcode = FT_Get_Next_Char(ftface, charcode, &pcp[i].index);
- DbgPrint("charcode=0x%lx, index=0x%lx\n", charcode, pcp[i].index);
- pcp[i].code = charcode;
- if (charcode != pcp[i - 1].code + 1)
- {
- cRuns++;
- }
- }
-
- /* Update cGlyphs to real value */
- cGlyphs = i - 1;
-
- /* Calculate FD_GLYPHSET size */
- cjSize = sizeof(FD_GLYPHSET)
- + (cRuns - 1) * sizeof(WCRUN)
- + cGlyphs * sizeof(HGLYPH);
-
- /* Allocate the FD_GLYPHSET structure */
- pGlyphSet = EngAllocMem(0, cjSize, TAG_GLYPHSET);
- if (!pGlyphSet)
- {
- DbgPrint("EngAllocMem() failed.\n");
- return NULL;
- }
-
- /* Initialize FD_GLYPHSET */
- pGlyphSet->cjThis = cjSize;
- pGlyphSet->flAccel = 0;
- pGlyphSet->cGlyphsSupported = cGlyphs;
- pGlyphSet->cRuns = cRuns;
-
- /* Initialize 1st WCRUN */
- pwcrun = pGlyphSet->awcrun;
- phglyphs = (PHGLYPH)&pGlyphSet->awcrun[cRuns];
- pwcrun[0].wcLow = pcp[0].code;
- pwcrun[0].cGlyphs = 1;
- pwcrun[0].phg = &phglyphs[0];
- phglyphs[0] = pcp[0].index;
-
-DbgPrint("pcp[0].index = 0x%lx\n", pcp[0].index);
-
- /* Walk through all supported chars */
- for (i = 1, j = 0; i < cGlyphs; i++)
- {
- /* Use glyph index as HGLYPH */
- phglyphs[i] = pcp[i].index;
-
- /* Check whether we can append the wchar to a run */
- if (pcp[i].code == pcp[i - 1].code + 1)
- {
- /* Append to current WCRUN */
- pwcrun[j].cGlyphs++;
- }
- else
- {
- /* Add a new WCRUN */
- DbgPrint("adding new run\n");
- j++;
- pwcrun[j].wcLow = pcp[i].code;
- pwcrun[j].cGlyphs = 1;
- pwcrun[j].phg = &phglyphs[i];
- }
- }
-
- /* Free the temporary buffer */
- EngFreeMem(pcp);
-
- /* Set *pid to the allocated structure for use in FtfdFree */
- *pid = (ULONG_PTR)pGlyphSet;
-
-DbgPrint("pGlyphSet=%p\n", pGlyphSet);
-__debugbreak();
-
- return pGlyphSet;
-}
-
+#if 0 // not needed atm
VOID
APIENTRY
FtfdFree(
PVOID pv,
ULONG_PTR id)
{
- DbgPrint("FtfdFree()\n");
- if (id)
- {
- EngFreeMem((PVOID)id);
- }
-}
-
-
-
+ TRACE("FtfdFree()\n");
+ EngFreeMem(pv);
+}
+#endif
+
+
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/ftfd.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers…
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/ftfd.h [iso-8859-1]
(original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/ftfd.h [iso-8859-1] Sun Aug
14 08:52:14 2011
@@ -11,41 +11,151 @@
#include <winddi.h>
#include <ft2build.h>
-#include FT_FREETYPE_H
+#include FT_FREETYPE_H
+#include FT_ADVANCES_H
+#include FT_XFREE86_H
+#include FT_TYPE1_TABLES_H
+#include FT_MULTIPLE_MASTERS_H
+#include FT_TRIGONOMETRY_H
+
extern FT_Library gftlibrary;
#define TAG_GLYPHSET 'GlSt'
#define TAG_IFIMETRICS 'Ifim'
+#if 1// DBG
+#define ASSERT(x) \
+ if(!(x)) \
+ { \
+ DbgPrint("Assertion '%s' failed at %s:%i\n", #x, __FILE__,
__LINE__); \
+ __debugbreak(); \
+ }
+#define TRACE DbgPrint
+#define WARN DbgPrint
+#define FATAL DbgPrint
+#else
+#define ASSERT(x)
+#define TRACE(...)
+#define WARN(...)
+#define FATAL(...)
+#endif
+
+/* Helper for FLOATOBJ */
+#ifdef _M_IX86
+#define FLOATOBJ_bIsNull(pf) (((pf)->ul1 == 0) && ((pf)->ul2 == 0))
+#else
+#define FLOATOBJ_bIsNull(pf) (*(pf) == 0)
+#endif
+
/** Driver specific types *****************************************************/
+typedef enum
+{
+ FMT_UNKNOWN,
+ FMT_TRUETYPE,
+ FMT_TYPE1,
+ FMT_CFF,
+ FMT_FNT,
+ FMT_BDF,
+ FMT_PCF,
+ FMT_TYPE42,
+ FMT_CIDTYPE1,
+ FMT_PFR
+} FONT_FORMAT;
+
+typedef enum
+{
+ FILEFMT_TTF, /* TrueType font file */
+ FILEFMT_OTF, /* OpenType font file */
+ FILEFMT_FNT, /* Windows .fnt file */
+} FILE_FORMAT;
+
+//"Bold Italic Underline Strikeout"
+#define MAX_STYLESIZE 35
typedef struct
{
- FT_UInt index;
- FT_ULong code;
-} FTFD_CHARPAIR;
+ IFIMETRICS ifi;
+ BYTE ajCharSet[16];
+ FONTSIM fontsim;
+ WCHAR awcFamilyName[LF_FACESIZE];
+ WCHAR awcFaceName[LF_FACESIZE];
+ WCHAR awcStyleName[MAX_STYLESIZE];
+ WCHAR awcUniqueName[LF_FACESIZE + 11];
+} FTFD_IFIMETRICS, *PFTFD_IFIMETRICS;
typedef struct
+{
+ struct _FTFD_FILE *pfile;
+ FT_Face ftface;
+ ULONG iFace;
+ ULONG ulFontFormat;
+ ULONG cGlyphs;
+ ULONG cMappings;
+ ULONG cRuns;
+ ULONG ulFontRevision;
+ ULONG ulEncoding;
+ WCHAR wcCharBias;
+ PWCHAR pwcReverseTable;
+ FD_GLYPHSET *pGlyphSet;
+ FD_KERNINGPAIR *pKerningPairs;
+ FTFD_IFIMETRICS ifiex;
+} FTFD_FACE, *PFTFD_FACE;
+
+typedef struct _FTFD_FILE
{
PVOID pvView;
ULONG cjView;
ULONG_PTR iFile;
ULONG cNumFaces;
- FT_Face aftface[1];
+ ULONG ulFastCheckSum;
+ ULONG ulFileFormat;
+ DESIGNVECTOR dv;
+ PFTFD_FACE apface[1];
} FTFD_FILE, *PFTFD_FILE;
-//"Bold Italic Underline Strikeout"
-#define MAX_STYLESIZE 35
+typedef struct _FTFD_DEVICEMETRICS
+{
+ union
+ {
+ POINTL aptl[8];
+ struct
+ {
+ POINTL ptlUnderline1;
+ POINTL ptlStrikeout;
+ POINTL ptlULThickness;
+ POINTL ptlSOThickness;
+ POINTL aptfxBBox[4];
+ };
+ };
+ FIX fxMaxAscender;
+ FIX fxMaxDescender;
+} FTFD_DEVICEMETRICS;
+
+typedef struct _POINTEF
+{
+ FLOATOBJ x;
+ FLOATOBJ y;
+} POINTEF, *PPOINTEF;
+
typedef struct
{
- IFIMETRICS ifim;
- BYTE ajCharSet[16];
- FONTSIM fontsim;
- WCHAR wszFamilyName[LF_FACESIZE];
- WCHAR wszFaceName[LF_FACESIZE];
- WCHAR wszStyleName[MAX_STYLESIZE];
-} FTFD_IFIMETRICS, *PFTFD_IFIMETRICS;
+ FONTOBJ *pfo;
+ PFTFD_FILE pfile;
+ PFTFD_FACE pface;
+ ULONG iFace;
+ FT_Face ftface;
+ FD_XFORM fdxQuantized;
+ FTFD_DEVICEMETRICS metrics;
+ RECTL rcfxBBox;
+ SIZEL sizlMax;
+ POINTEF ptefBase;
+ POINTEF ptefSide;
+ SIZEL sizlScale;
+ HGLYPH hgSelected;
+ UCHAR jBpp;
+} FTFD_FONT, *PFTFD_FONT;
+
/** Function prototypes *******************************************************/
@@ -127,6 +237,11 @@
VOID
APIENTRY
+FtfdDestroyFont(
+ FONTOBJ *pfo);
+
+VOID
+APIENTRY
FtfdFree(
PVOID pv,
ULONG_PTR id);
@@ -148,3 +263,91 @@
PVOID pv,
ULONG cjSize);
+BOOL
+APIENTRY
+FtfdQueryAdvanceWidths(
+ DHPDEV dhpdev,
+ FONTOBJ *pfo,
+ ULONG iMode,
+ HGLYPH *phg,
+ PVOID pvWidths,
+ ULONG cGlyphs);
+
+LONG
+APIENTRY
+FtfdQueryTrueTypeOutline(
+ DHPDEV dhpdev,
+ FONTOBJ *pfo,
+ HGLYPH hglyph,
+ BOOL bMetricsOnly,
+ GLYPHDATA *pgldt,
+ ULONG cjBuf,
+ TTPOLYGONHEADER *ppoly);
+
+LONG
+APIENTRY
+FtfdQueryTrueTypeTable(
+ ULONG_PTR iFile,
+ ULONG ulFont,
+ ULONG ulTag,
+ PTRDIFF dpStart,
+ ULONG cjBuf,
+ BYTE *pjBuf,
+ PBYTE *ppjTable,
+ ULONG *pcjTable);
+
+ULONG
+APIENTRY
+FtfdEscape(
+ SURFOBJ *pso,
+ ULONG iEsc,
+ ULONG cjIn,
+ PVOID pvIn,
+ ULONG cjOut,
+ PVOID pvOut);
+
+ULONG
+APIENTRY
+FtfdFontManagement(
+ SURFOBJ *pso,
+ FONTOBJ *pfo,
+ ULONG iMode,
+ ULONG cjIn,
+ PVOID pvIn,
+ ULONG cjOut,
+ PVOID pvOut);
+
+PVOID
+APIENTRY
+FtfdGetTrueTypeFile(
+ ULONG_PTR iFile,
+ ULONG *pcj);
+
+/* Private interface */
+
+PVOID
+NTAPI
+FtfdFindTrueTypeTable(
+ PVOID pvView,
+ ULONG cjView,
+ ULONG iFace,
+ ULONG ulTag,
+ PULONG pulLength);
+
+BOOL
+NTAPI
+FtfdGetWinMetrics(
+ PFTFD_FACE pface,
+ PIFIMETRICS pifi);
+
+VOID
+NTAPI
+FtfdInitKerningPairs(
+ PFTFD_FACE pface);
+
+VOID
+NTAPI
+FtfdCopyBits(
+ BYTE jBppDst,
+ GLYPHBITS *pgb,
+ FT_Bitmap *ftbitmap);
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/glyph.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers…
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/glyph.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/glyph.c [iso-8859-1] Sun Aug
14 08:52:14 2011
@@ -1,23 +1,548 @@
/*
* PROJECT: ReactOS win32 subsystem
* LICENSE: GPL - See COPYING in the top level directory
- * PURPOSE: GDI font driver for bitmap fonts
+ * PURPOSE: GDI font driver based on freetype
* PROGRAMMER: Timo Kreuzer (timo.kreuzer(a)reactos.org)
*/
#include "ftfd.h"
+/** Private Interface *********************************************************/
+
+#define FLOATL_1 0x3f800000
+
+#define BITMAP_SIZE(cx, cy, bpp) \
+ (((((((cx) * (bpp)) + 7) >> 3) * (cy)) + 3) & ~3)
+
+#define GLYPHBITS_SIZE(cx, cy, bpp) \
+ (FIELD_OFFSET(GLYPHBITS, aj) + BITMAP_SIZE(cx, cy, bpp))
+
+static
+FLOATOBJ
+FtfdNormalizeBaseVector(
+ POINTEF *pptef)
+{
+ FLOATOBJ efTmp, efLength;
+ FT_Vector ftvector;
+ LONG lLength;
+
+ /* Optimization for scaling transformations */
+ if (FLOATOBJ_bIsNull(&pptef->y))
+ {
+ efLength = pptef->x;
+ FLOATOBJ_SetLong(&pptef->x, 1);
+ return efLength;
+ }
+
+ if (FLOATOBJ_bIsNull(&pptef->x))
+ {
+ efLength = pptef->y;
+ FLOATOBJ_SetLong(&pptef->y, -1);
+ return efLength;
+ }
+
+ /* Convert the point into a 8.24 fixpoint vector */
+ efTmp = pptef->x;
+ FLOATOBJ_MulLong(&efTmp, 0x01000000);
+ ftvector.x = FLOATOBJ_GetLong(&efTmp);
+ efTmp = pptef->y;
+ FLOATOBJ_MulLong(&efTmp, 0x01000000);
+ ftvector.y = FLOATOBJ_GetLong(&efTmp);
+
+ /* Get the length of the fixpoint vector */
+ lLength = FT_Vector_Length(&ftvector);
+
+ /* Convert the fixpoint back into a FLOATOBJ */
+ FLOATOBJ_SetLong(&efLength, lLength);
+ FLOATOBJ_DivLong(&efLength, 0x01000000);
+
+ /* Now divide the vector by the length */
+ FLOATOBJ_Div(&pptef->x, &efLength);
+ FLOATOBJ_Div(&pptef->y, &efLength);
+
+ /* y axis is inverted! */
+ FLOATOBJ_Neg(&pptef->y);
+
+ /* Return the former length of the vector */
+ return efLength;
+}
+
+PFTFD_FONT
+NTAPI
+FtfdCreateFontInstance(
+ FONTOBJ *pfo)
+{
+ PFTFD_FILE pfile = (PFTFD_FILE)pfo->iFile;
+ PFTFD_FACE pface = pfile->apface[pfo->iFace - 1];
+ PFTFD_FONT pfont;
+ XFORMOBJ* pxo;
+ FLOATOBJ_XFORM fxform;
+ FT_Error fterror;
+ FT_Face ftface;
+ FT_Matrix ftmatrix;
+ ULONG iComplexity;
+ FTFD_DEVICEMETRICS *pmetrics;
+ FLOATOBJ efTemp, efScaleX, efScaleY;
+
+ /* Allocate a font structure */
+ pfont = EngAllocMem(0, sizeof(FTFD_FONT), 0);
+ if (!pfont)
+ {
+ return NULL;
+ }
+
+ /* Set basic fields */
+ pfont->pfo = pfo;
+ pfont->pfile = pfile;
+ pfont->iFace = pfo->iFace;
+ pfont->pface = pface;
+ pfont->hgSelected = -1;
+
+
+ /* Create a freetype face */
+ fterror = FT_New_Memory_Face(gftlibrary,
+ pfile->pvView,
+ pfile->cjView,
+ pfo->iFace - 1,
+ &ftface);
+ if (fterror)
+ {
+ /* Failure! */
+ WARN("Error creating face\n");
+ EngFreeMem(pfont);
+ return NULL;
+ }
+
+ pfont->ftface = ftface;
+
+ /* Set requested number of bits per pixel */
+ pfont->jBpp = pfo->flFontType & FO_GRAY16 ? 4 : 1;
+
+ /* Get the XFORMOBJ from the font */
+ pxo = FONTOBJ_pxoGetXform(pfo);
+ if (!pxo)
+ {
+ WARN("Error there is no XFORMOBJ!\n");
+ EngFreeMem(pfont);
+ return NULL;
+ }
+
+ /* Get a FLOATOBJ_XFORM matrix */
+ iComplexity = XFORMOBJ_iGetFloatObjXform(pxo, &fxform);
+ ASSERT(iComplexity != DDI_ERROR);
+
+ // FIXME: quantize to 16.16 fixpoint
+ pfont->fdxQuantized.eXX = FLOATOBJ_GetFloat(&fxform.eM11);
+ pfont->fdxQuantized.eXY = FLOATOBJ_GetFloat(&fxform.eM12);
+ pfont->fdxQuantized.eYX = FLOATOBJ_GetFloat(&fxform.eM21);
+ pfont->fdxQuantized.eYY = FLOATOBJ_GetFloat(&fxform.eM22);
+
+ /* Get the base vectors (unnormalized) */
+ pfont->ptefBase.x = fxform.eM11;
+ pfont->ptefBase.y = fxform.eM21;
+ pfont->ptefSide.x = fxform.eM12;
+ pfont->ptefSide.y = fxform.eM22;
+
+ /* Normalize the base vectors and get their length */
+ efScaleX = FtfdNormalizeBaseVector(&pfont->ptefBase);
+ efScaleY = FtfdNormalizeBaseVector(&pfont->ptefSide);
+
+ /* Calculate maximum ascender and descender */
+ efTemp = efScaleY;
+ FLOATOBJ_MulLong(&efTemp, pface->ifiex.ifi.fwdWinAscender << 4);
+ pfont->metrics.fxMaxAscender = FLOATOBJ_GetLong(&efTemp);
+ efTemp = efScaleY;
+ FLOATOBJ_MulLong(&efTemp, pface->ifiex.ifi.fwdWinDescender << 4);
+ pfont->metrics.fxMaxDescender = FLOATOBJ_GetLong(&efTemp);
+
+ /* The coordinate transformation given by Windows transforms from font
+ * space to device space. Since we use FT_Set_Char_Size, which allows
+ * higher precision than FT_Set_Pixel_Sizes, we need to convert into
+ * points. So we multiply our scaling coefficients with 72 divided by
+ * the device resolution. We also need a 26.6 fixpoint value, so we
+ * multiply with 64. */
+ FLOATOBJ_MulLong(&efScaleX, 64 * pface->ifiex.ifi.fwdUnitsPerEm * 72);
+ FLOATOBJ_DivLong(&efScaleX, pfo->sizLogResPpi.cx);
+ pfont->sizlScale.cx = FLOATOBJ_GetLong(&efScaleX);
+ FLOATOBJ_MulLong(&efScaleY, 64 * pface->ifiex.ifi.fwdUnitsPerEm * 72);
+ FLOATOBJ_DivLong(&efScaleY, pfo->sizLogResPpi.cy);
+ pfont->sizlScale.cy = FLOATOBJ_GetLong(&efScaleY);
+
+ /* Set the x and y character size for the font */
+ fterror = FT_Set_Char_Size(ftface,
+ pfont->sizlScale.cx,
+ pfont->sizlScale.cy,
+ pfo->sizLogResPpi.cx,
+ pfo->sizLogResPpi.cy);
+ if (fterror)
+ {
+ /* Failure! */
+ WARN("Error setting face size\n");
+ EngFreeMem(pfont);
+ return NULL;
+ }
+
+ /* Check if there is rotation / skewing (cannot use iComplexity!?) */
+ if (!FLOATOBJ_bIsNull(&fxform.eM12) || !FLOATOBJ_bIsNull(&fxform.eM21))
+ {
+ //__debugbreak();
+
+ /* Create a transformation matrix that is applied after the character
+ * scaling. We simply use the normalized base vectors and convert them
+ * to 16.16 fixpoint format */
+
+ efTemp = pfont->ptefBase.x;
+ FLOATOBJ_MulLong(&efTemp, 0x00010000);
+ ftmatrix.xx = FLOATOBJ_GetLong(&efTemp);
+
+ efTemp = pfont->ptefSide.x;
+ FLOATOBJ_MulLong(&efTemp, 0x00010000);
+ ftmatrix.xy = FLOATOBJ_GetLong(&efTemp);
+
+ efTemp = pfont->ptefBase.y;
+ FLOATOBJ_MulLong(&efTemp, 0x00010000);
+ ftmatrix.yx = FLOATOBJ_GetLong(&efTemp);
+
+ efTemp = pfont->ptefSide.y;
+ FLOATOBJ_MulLong(&efTemp, 0x00010000);
+ ftmatrix.yy = FLOATOBJ_GetLong(&efTemp);
+
+ /* Set the transformation matrix */
+ FT_Set_Transform(ftface, &ftmatrix, 0);
+ }
+
+ /* Check if there is a design vector */
+ if (pfile->dv.dvReserved == STAMP_DESIGNVECTOR)
+ {
+ /* Set the coordinates */
+ fterror = FT_Set_MM_Design_Coordinates(ftface,
+ pfile->dv.dvNumAxes,
+ pfile->dv.dvValues);
+ if (fterror)
+ {
+ /* Failure! */
+ WARN("Failed to set design vector\n");
+ EngFreeMem(pfont);
+ return NULL;
+ }
+ }
+
+ /* Prepare required coordinates in font space */
+ pmetrics = &pfont->metrics;
+ pmetrics->ptlUnderline1.x = 0;
+ pmetrics->ptlUnderline1.y = -pface->ifiex.ifi.fwdUnderscorePosition;
+ pmetrics->ptlStrikeout.x = 0;
+ pmetrics->ptlStrikeout.y = -pface->ifiex.ifi.fwdStrikeoutPosition;;
+ pmetrics->ptlULThickness.x = 0;
+ pmetrics->ptlULThickness.y = pface->ifiex.ifi.fwdUnderscoreSize;
+ pmetrics->ptlSOThickness.x = 0;
+ pmetrics->ptlSOThickness.y = pface->ifiex.ifi.fwdStrikeoutSize;
+ pmetrics->aptfxBBox[0].x = ftface->bbox.xMin << 4;
+ pmetrics->aptfxBBox[0].y = ftface->bbox.yMin << 4;
+ pmetrics->aptfxBBox[1].x = ftface->bbox.xMax << 4;
+ pmetrics->aptfxBBox[1].y = ftface->bbox.yMin << 4;
+ pmetrics->aptfxBBox[2].x = ftface->bbox.xMax << 4;
+ pmetrics->aptfxBBox[2].y = ftface->bbox.yMax << 4;
+ pmetrics->aptfxBBox[3].x = ftface->bbox.xMin << 4;
+ pmetrics->aptfxBBox[3].y = ftface->bbox.yMax << 4;
+
+ /* Transform all coordinates into device space */
+ if (!XFORMOBJ_bApplyXform(pxo, XF_LTOL, 8, pmetrics->aptl, pmetrics->aptl))
+ {
+ WARN("Failed apply coordinate transformation.\n");
+ EngFreeMem(pfont);
+ return NULL;
+ }
+
+ /* Extract the bounding box in FIX device coordinates */
+ pfont->rcfxBBox.left = min(pmetrics->aptfxBBox[0].x,
pmetrics->aptfxBBox[1].x);
+ pfont->rcfxBBox.left = min(pfont->rcfxBBox.left, pmetrics->aptfxBBox[2].x);
+ pfont->rcfxBBox.left = min(pfont->rcfxBBox.left, pmetrics->aptfxBBox[3].x);
+ pfont->rcfxBBox.right = max(pmetrics->aptfxBBox[0].x,
pmetrics->aptfxBBox[1].x);
+ pfont->rcfxBBox.right = max(pfont->rcfxBBox.right,
pmetrics->aptfxBBox[2].x);
+ pfont->rcfxBBox.right = max(pfont->rcfxBBox.right,
pmetrics->aptfxBBox[3].x);
+ pfont->rcfxBBox.top = min(pmetrics->aptfxBBox[0].y,
pmetrics->aptfxBBox[1].y);
+ pfont->rcfxBBox.top = min(pfont->rcfxBBox.top, pmetrics->aptfxBBox[2].y);
+ pfont->rcfxBBox.top = min(pfont->rcfxBBox.top, pmetrics->aptfxBBox[3].y);
+ pfont->rcfxBBox.bottom = max(pmetrics->aptfxBBox[0].y,
pmetrics->aptfxBBox[1].y);
+ pfont->rcfxBBox.bottom = max(pfont->rcfxBBox.bottom,
pmetrics->aptfxBBox[2].y);
+ pfont->rcfxBBox.bottom = max(pfont->rcfxBBox.bottom,
pmetrics->aptfxBBox[3].y);
+
+ /* Round the bounding box margings to pixels */
+ pfont->rcfxBBox.left = pfont->rcfxBBox.left & ~0xf;
+ pfont->rcfxBBox.top = pfont->rcfxBBox.top & ~0xf;
+ pfont->rcfxBBox.right = (pfont->rcfxBBox.right + 0xf) & ~0xf;
+ pfont->rcfxBBox.bottom = (pfont->rcfxBBox.bottom + 0xf) & ~0xf;
+
+ /* Calculate maximum extents in pixels */
+ pfont->sizlMax.cx = (pfont->rcfxBBox.right - pfont->rcfxBBox.left) >>
4;
+ pfont->sizlMax.cy = (pfont->rcfxBBox.bottom - pfont->rcfxBBox.top) >>
4;
+
+ /* Fixup some minimum values */
+ if (pmetrics->ptlULThickness.y <= 0) pmetrics->ptlULThickness.y = 1;
+ if (pmetrics->ptlSOThickness.y <= 0) pmetrics->ptlSOThickness.y = 1;
+
+ TRACE("Created font of size %ld (%ld)\n",
+ pfont->sizlScale.cy, (pfont->sizlScale.cy+32)/64);
+ //__debugbreak();
+
+ /* Set the pvProducer member of the fontobj */
+ pfo->pvProducer = pfont;
+ return pfont;
+}
+
+static
+PFTFD_FONT
+FtfdGetFontInstance(
+ FONTOBJ *pfo)
+{
+ PFTFD_FONT pfont = pfo->pvProducer;
+
+ /* Create a font instance if neccessary */
+ if (!pfont) pfont = FtfdCreateFontInstance(pfo);
+
+ /* Return the font instance */
+ return pfont;
+}
+
+ULONG
+NTAPI
+FtfdQueryMaxExtents(
+ FONTOBJ *pfo,
+ PFD_DEVICEMETRICS pfddm,
+ ULONG cjSize)
+{
+ PFTFD_FONT pfont = FtfdGetFontInstance(pfo);
+ PFTFD_FACE pface = pfont->pface;
+ FT_Face ftface = pfont->ftface;
+
+ TRACE("FtfdQueryMaxExtents\n");
+
+ if (pfddm)
+ {
+ /* Verify parameter */
+ if (cjSize < sizeof(FD_DEVICEMETRICS))
+ {
+ /* Not enough space, fail */
+ WARN("cjSize = %ld\n", cjSize);
+ return FD_ERROR;
+ }
+
+ /* Accelerator flags (ignored atm) */
+ pfddm->flRealizedType = 0;
+
+ /* Set fixed width advance */
+ if (FT_IS_FIXED_WIDTH(ftface))
+ pfddm->lD = ftface->max_advance_width;
+ else
+ pfddm->lD = 0;
+
+ /* Copy some values from the font structure */
+ pfddm->fxMaxAscender = pfont->metrics.fxMaxAscender;
+ pfddm->fxMaxDescender = pfont->metrics.fxMaxDescender;
+ pfddm->ptlUnderline1 = pfont->metrics.ptlUnderline1;
+ pfddm->ptlStrikeout = pfont->metrics.ptlStrikeout;
+ pfddm->ptlULThickness = pfont->metrics.ptlULThickness;
+ pfddm->ptlSOThickness = pfont->metrics.ptlSOThickness;
+ pfddm->cxMax = pfont->sizlMax.cx;
+ pfddm->cyMax = pfont->sizlMax.cy;
+
+ /* Convert the base vectors from FLOATOBJ to FLOATL */
+ pfddm->pteBase.x = FLOATOBJ_GetFloat(&pfont->ptefBase.x);
+ pfddm->pteBase.y = FLOATOBJ_GetFloat(&pfont->ptefBase.y);
+ pfddm->pteSide.x = FLOATOBJ_GetFloat(&pfont->ptefSide.x);
+ pfddm->pteSide.y = FLOATOBJ_GetFloat(&pfont->ptefSide.y);
+
+ /* cjGlyphMax is the full size of the GLYPHBITS structure */
+ pfddm->cjGlyphMax = GLYPHBITS_SIZE(pfddm->cxMax,
+ pfddm->cyMax,
+ pfont->jBpp);
+
+ /* Copy the quantized matrix from the font structure */
+ pfddm->fdxQuantized = pfont->fdxQuantized;
+
+ pfddm->lNonLinearExtLeading = 0x80000000;
+ pfddm->lNonLinearIntLeading = 0x80000000; // FIXME
+ pfddm->lNonLinearMaxCharWidth = 0x80000000;
+ pfddm->lNonLinearAvgCharWidth = 0x80000000;
+
+ pfddm->lMinA = 0;
+ pfddm->lMinC = 0;
+ pfddm->lMinD = 0;
+ }
+
+ TRACE("pfddm->fxMaxAscender=%ld, yScale=%ld, height=%ld\n",
+ pfddm->fxMaxAscender, pfont->sizlScale.cy,
+ (pfont->sizlScale.cy+32)/64);
+//__debugbreak();
+
+ /* Return the size of the structure */
+ return sizeof(FD_DEVICEMETRICS);
+}
+
+static
+BOOL
+FtfdLoadGlyph(
+ PFTFD_FONT pfont,
+ HGLYPH hg,
+ ULONG iFormat) // 0 = bitmap, 1 = outline
+{
+ FT_Error fterror;
+
+ /* Check if the glyph needs to be updated */
+ if (pfont->hgSelected != hg)
+ {
+ /* Load the glyph into the freetype face slot */
+ fterror = FT_Load_Glyph(pfont->ftface, hg, 0);
+ if (fterror)
+ {
+ WARN("Couldn't load glyph 0x%lx\n", hg);
+ pfont->hgSelected = -1;
+ return FALSE;
+ }
+
+ /* Update the selected glyph */
+ pfont->hgSelected = hg;
+ }
+
+ return TRUE;
+}
+
+static
+VOID
+FtfdQueryGlyphData(
+ FONTOBJ *pfo,
+ HGLYPH hg,
+ GLYPHDATA *pgd,
+ PVOID pvGlyphData)
+{
+ PFTFD_FONT pfont = pfo->pvProducer;
+ FT_GlyphSlot ftglyph = pfont->ftface->glyph;
+ SIZEL sizlBitmap;
+
+ pgd->gdf.pgb = pvGlyphData;
+ pgd->hg = hg;
+
+ if (1 /* layout horizontal */)
+ {
+ // FIXME: ftglyph->metrics doesn't handle non-orthogonal transformations
+ //
http://www.freetype.org/freetype2/docs/reference/ft2-base_interface.html#FT…
+ pgd->fxA = ftglyph->metrics.horiBearingX;
+ pgd->fxAB = pgd->fxA + ftglyph->metrics.width / 4;
+ }
+ else
+ {
+ pgd->fxA = ftglyph->metrics.vertBearingX;
+ pgd->fxAB = pgd->fxA + ftglyph->metrics.height;
+ }
+
+ /* D is the glyph advance width */
+ pgd->fxD = ftglyph->advance.x / 4; // FIXME: should be projected on the x-axis
+
+ /* Get the bitnmap size */
+ sizlBitmap.cx = ftglyph->bitmap.width;
+ sizlBitmap.cy = ftglyph->bitmap.rows;
+
+ /* Make the bitmap at least 1x1 pixel large */
+ if (sizlBitmap.cx == 0) sizlBitmap.cx++;
+ if (sizlBitmap.cy == 0) sizlBitmap.cy++;
+
+ /* Don't let the bitmap be larger than the maximum */
+ sizlBitmap.cx = min(sizlBitmap.cx, pfont->sizlMax.cx);
+ sizlBitmap.cy = min(sizlBitmap.cy, pfont->sizlMax.cy);
+
+ /* This is the box in which the bitmap fits */
+ pgd->rclInk.left = ftglyph->bitmap_left;
+ pgd->rclInk.top = -ftglyph->bitmap_top;
+ pgd->rclInk.right = pgd->rclInk.left + sizlBitmap.cx;
+ pgd->rclInk.bottom = pgd->rclInk.top + sizlBitmap.cy;
+
+ /* FIX representation of bitmap top and bottom */
+ pgd->fxInkBottom = (-pgd->rclInk.bottom) << 4;
+ pgd->fxInkTop = pgd->rclInk.top << 4;
+
+ // FIXME:
+ pgd->ptqD.x.LowPart = pgd->fxD;
+ pgd->ptqD.x.HighPart = 0;
+ pgd->ptqD.y.LowPart = 0;
+ pgd->ptqD.y.HighPart = 0;
+
+//__debugbreak();
+}
+
+VOID
+FtfdQueryGlyphBits(
+ FONTOBJ *pfo,
+ HGLYPH hg,
+ GLYPHBITS *pgb,
+ ULONG cjSize)
+{
+ PFTFD_FONT pfont = pfo->pvProducer;
+ FT_GlyphSlot ftglyph = pfont->ftface->glyph;
+ ULONG cjBitmapSize;
+
+ pgb->ptlOrigin.x = ftglyph->bitmap_left;
+ pgb->ptlOrigin.y = - ftglyph->bitmap_top;
+ pgb->sizlBitmap.cx = ftglyph->bitmap.width;
+ pgb->sizlBitmap.cy = ftglyph->bitmap.rows;
+
+ /* Make the bitmap at least 1x1 pixel large */
+ if (pgb->sizlBitmap.cx == 0) pgb->sizlBitmap.cx++;
+ if (pgb->sizlBitmap.cy == 0) pgb->sizlBitmap.cy++;
+
+ /* Don't let the bitmap be larger than the maximum */
+ pgb->sizlBitmap.cx = min(pgb->sizlBitmap.cx, pfont->sizlMax.cx);
+ pgb->sizlBitmap.cy = min(pgb->sizlBitmap.cy, pfont->sizlMax.cy);
+
+ cjBitmapSize = BITMAP_SIZE(pgb->sizlBitmap.cx,
+ pgb->sizlBitmap.cy,
+ pfont->jBpp);
+ if (cjBitmapSize + FIELD_OFFSET(GLYPHBITS, aj) > cjSize)
+ {
+ WARN("Buffer too small, got %ld, need %ld\n",
+ cjSize, cjBitmapSize + FIELD_OFFSET(GLYPHBITS, aj));
+ __debugbreak();
+ return;
+ }
+
+ /* Copy the bitmap */
+ FtfdCopyBits(pfont->jBpp, pgb, &ftglyph->bitmap);
+
+ //TRACE("QueryGlyphBits hg=%lx, (%ld,%ld) cjSize=%ld, need %ld\n",
+ // hg, pgb->sizlBitmap.cx, pgb->sizlBitmap.cy, cjSize,
+ // GLYPHBITS_SIZE(pgb->sizlBitmap.cx, pgb->sizlBitmap.cy,
pfont->jBpp));
+}
+
+VOID
+FtfdQueryGlyphOutline(
+ FONTOBJ *pfo,
+ HGLYPH hg,
+ PATHOBJ *ppo,
+ ULONG cjSize)
+{
+ WARN("FtfdQueryGlyphOutline is unimplemented\n");
+ __debugbreak();
+}
+
+BOOL
+FtRenderGlyphBitmap(
+ PFTFD_FONT pfont)
+{
+ FT_Error fterror;
+ FT_Render_Mode mode;
+
+ mode = pfont->jBpp == 1 ? FT_RENDER_MODE_MONO : FT_RENDER_MODE_NORMAL;
+ fterror = FT_Render_Glyph(pfont->ftface->glyph, mode);
+ if (fterror)
+ {
+ WARN("Cound't render glyph\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
/** Public Interface **********************************************************/
-
-PFD_GLYPHATTR
-APIENTRY
-FtfdQueryGlyphAttrs(
- FONTOBJ *pfo,
- ULONG iMode)
-{
- return NULL;
-}
LONG
APIENTRY
@@ -30,5 +555,226 @@
PVOID pv,
ULONG cjSize)
{
+ PFTFD_FONT pfont = FtfdGetFontInstance(pfo);
+ ULONG cx, cy;
+
+ //TRACE("FtfdQueryFontData, iMode=%ld, hg=%lx, pgd=%p, pv=%p,
cjSize=%ld\n",
+ // iMode, hg, pgd, pv, cjSize);
+
+ switch (iMode)
+ {
+ case QFD_GLYPHANDBITMAP:
+ /* Load the requested glyph */
+ if (!FtfdLoadGlyph(pfont, hg, 0)) return FD_ERROR;
+
+ /* Render the glyph bitmap */
+ if (!FtRenderGlyphBitmap(pfont)) return FD_ERROR;
+
+ if (pgd) FtfdQueryGlyphData(pfo, hg, pgd, pv);
+
+
+ if (pv)
+ {
+ FtfdQueryGlyphBits(pfo, hg, pv, cjSize);
+ }
+
+ /* Return the size for a bitmap at least 1x1 pixels */
+ cx = pfont->ftface->glyph->bitmap.width;
+ cy = pfont->ftface->glyph->bitmap.rows;
+ return GLYPHBITS_SIZE(cx > 0 ? cx : 1,
+ cy > 0 ? cy : 1,
+ pfont->jBpp);
+
+ case QFD_GLYPHANDOUTLINE:
+ TRACE("QFD_GLYPHANDOUTLINE\n");
+
+ /* Load the requested glyph */
+ if (!FtfdLoadGlyph(pfont, hg, 1)) return FD_ERROR;
+
+ if (pgd)
+ {
+ FtfdQueryGlyphData(pfo, hg, pgd, pv);
+ }
+
+ if (pv)
+ {
+ FtfdQueryGlyphOutline(pfo, hg, pv, cjSize);
+ }
+ break;
+
+ case QFD_MAXEXTENTS:
+ return FtfdQueryMaxExtents(pfo, pv, cjSize);
+
+ case QFD_TT_GRAY1_BITMAP:
+ TRACE("QFD_TT_GRAY1_BITMAP\n");
+ break;
+ case QFD_TT_GRAY2_BITMAP:
+ TRACE("QFD_TT_GRAY2_BITMAP\n");
+ break;
+ case QFD_TT_GRAY4_BITMAP:
+ TRACE("QFD_TT_GRAY4_BITMAP\n");
+ break;
+ case QFD_TT_GRAY8_BITMAP:
+ TRACE("QFD_TT_GRAY8_BITMAP\n");
+ break;
+ default:
+ WARN("Invalid iMode value: %lx\n", iMode);
+ EngSetLastError(ERROR_INVALID_PARAMETER);
+ return FD_ERROR;
+ }
+
+ __debugbreak();
+
+
return FD_ERROR;
}
+
+PFD_GLYPHATTR
+APIENTRY
+FtfdQueryGlyphAttrs(
+ FONTOBJ *pfo,
+ ULONG iMode)
+{
+ TRACE("FtfdQueryGlyphAttrs\n");
+
+ /* Verify parameters */
+ if (!pfo || iMode != FO_ATTR_MODE_ROTATE)
+ {
+ WARN("Invalid parameters: %p, %ld\n", pfo, iMode);
+ return NULL;
+ }
+
+
+
+ __debugbreak();
+ return NULL;
+}
+
+BOOL
+APIENTRY
+FtfdQueryAdvanceWidths(
+ DHPDEV dhpdev,
+ FONTOBJ *pfo,
+ ULONG iMode,
+ HGLYPH *phg,
+ PVOID pvWidths,
+ ULONG cGlyphs)
+{
+ PFTFD_FONT pfont = FtfdGetFontInstance(pfo);
+ PUSHORT pusWidths = pvWidths;
+ BOOL bResult = TRUE;
+ ULONG i, fl;
+ FT_Face ftface = pfont->ftface;
+ FT_Error fterror;
+ FT_Fixed advance;
+
+ //TRACE("FtfdQueryAdvanceWidths\n");
+
+ /* The selected glyph will be changed */
+ pfont->hgSelected = -1;
+
+ /* Check if fast version is requested */
+ if (0 && iMode == QAW_GETEASYWIDTHS)
+ {
+ fl = FT_ADVANCE_FLAG_FAST_ONLY;
+
+ /* Check if the font layout is vertical */
+ if (ftface->face_flags & FT_FACE_FLAG_VERTICAL)
+ {
+ fl |= FT_LOAD_VERTICAL_LAYOUT;
+ }
+
+ /* Loop all requested glyphs */
+ for (i = 0; i < cGlyphs; i++)
+ {
+ /* Query advance width */
+ fterror = FT_Get_Advances(ftface, (FT_UInt)phg[i], 1, fl, &advance);
+ if (fterror || advance > 0xFFFF)
+ {
+ pusWidths[i] = 0xffff;
+ bResult = FALSE;
+ }
+ else
+ {
+ pusWidths[i] = (USHORT)(advance >> 2);
+ //TRACE("Got advance width: hg=%lx, adv=%lx->%ld\n", phg[i],
advance, pt.x);
+ }
+ }
+ }
+ else
+ {
+ /* Loop all requested glyphs */
+ for (i = 0; i < cGlyphs; i++)
+ {
+ /* Load the glyph */
+ fterror = FT_Load_Glyph(ftface, (FT_UInt)phg[i], 0);
+ if (fterror)
+ {
+ pusWidths[i] = 0xffff;
+ bResult = FALSE; // FIXME: return FALSE or DDI_ERROR?
+ }
+ else
+ {
+ pusWidths[i] = (USHORT)ftface->glyph->advance.x >> 2;
+ }
+ }
+ }
+
+ //__debugbreak();
+ return bResult;
+}
+
+LONG
+APIENTRY
+FtfdQueryTrueTypeOutline(
+ DHPDEV dhpdev,
+ FONTOBJ *pfo,
+ HGLYPH hg,
+ BOOL bMetricsOnly,
+ GLYPHDATA *pgldt,
+ ULONG cjBuf,
+ TTPOLYGONHEADER *ppoly)
+{
+ TRACE("FtfdQueryTrueTypeOutline\n");
+ __debugbreak();
+ return 0;
+}
+
+ULONG
+APIENTRY
+FtfdFontManagement(
+ SURFOBJ *pso,
+ FONTOBJ *pfo,
+ ULONG iMode,
+ ULONG cjIn,
+ PVOID pvIn,
+ ULONG cjOut,
+ PVOID pvOut)
+{
+ TRACE("FtfdFontManagement\n");
+ __debugbreak();
+ return 0;
+}
+
+VOID
+APIENTRY
+FtfdDestroyFont(
+ FONTOBJ *pfo)
+{
+ PFTFD_FONT pfont = pfo->pvProducer;
+
+ TRACE("FtfdDestroyFont()\n");
+
+ /* Nothing to do? */
+ if (!pfont) return;
+
+ /* We don't need this anymore */
+ pfo->pvProducer = NULL;
+
+ /* Cleanup the freetype face for this font */
+ FT_Done_Face(pfont->ftface);
+
+ /* Free the font structure */
+ EngFreeMem(pfont);
+}
+
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/rosglue.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers…
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/rosglue.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/rosglue.c [iso-8859-1] Sun
Aug 14 08:52:14 2011
@@ -29,7 +29,7 @@
va_list args;
va_start(args, Format);
- EngDebugPrint("ft2: ", (PCHAR)Format, args);
+ EngDebugPrint("ftfd: ", (PCHAR)Format, args);
va_end(args);
return 0;
}