LONG APIENTRY BmfdQueryFontFile( ULONG_PTR iFile, ULONG ulMode, ULONG cjBuf, ULONG *pulBuf) { PBMFD_FILE pfile = (PBMFD_FILE)iFile; DbgPrint("BmfdQueryFontFile()\n"); // __debugbreak(); switch (ulMode) { case QFF_DESCRIPTION: { /* We copy the face name of the 1st face */ PCHAR pDesc = pfile->aface[0].pszFaceName; ULONG cOutSize; if (pulBuf) { EngMultiByteToUnicodeN((LPWSTR)pulBuf, cjBuf, &cOutSize, pDesc, strnlen(pDesc, LF_FACESIZE)); } else { cOutSize = (strnlen(pDesc, LF_FACESIZE) + 1) * sizeof(WCHAR); } return cOutSize; } case QFF_NUMFACES: /* return the number of faces in the file */ return pfile->cNumFaces; default: return FD_ERROR; } }
PIFIMETRICS APIENTRY FtfdQueryFont( IN DHPDEV dhpdev, IN ULONG_PTR iFile, 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"); /* Validate parameters */ if (iFace > pfile->cNumFaces || !pid) { DbgPrint("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"); 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; }
PVOID APIENTRY BmfdQueryFontTree( DHPDEV dhpdev, ULONG_PTR iFile, ULONG iFace, ULONG iMode, ULONG_PTR *pid) { PBMFD_FILE pfile = (PBMFD_FILE)iFile; PBMFD_FACE pface; ULONG i, j, cjSize, cGlyphs, cRuns; CHAR ch, chFirst, ach[256]; WCHAR wc, awc[256]; PFD_GLYPHSET pGlyphSet; WCRUN *pwcrun; HGLYPH * phglyphs; DbgPrint("DrvQueryFontTree(iMode=%ld)\n", iMode); // __debugbreak(); /* Check parameters, we only support QFT_GLYPHSET */ if (!iFace || iFace > pfile->cNumFaces || iMode != QFT_GLYPHSET) { DbgPrint("iFace = %ld, cNumFaces = %ld\n", iFace, pfile->cNumFaces); return NULL; } /* Get a pointer to the face data */ pface = &pfile->aface[iFace - 1]; /* Get the number of characters in the face */ cGlyphs = pface->cGlyphs; chFirst = pface->pFontInfo->dfFirstChar; /* Build array of supported chars */ for (i = 0; i < cGlyphs; i++) { ach[i] = chFirst + i; } /* Convert the chars to unicode */ EngMultiByteToUnicodeN(awc, sizeof(awc), NULL, ach, cGlyphs); /* Sort both arrays in wchar order */ for (i = 0; i < cGlyphs - 1; i++) { wc = awc[i]; for (j = i + 1; j < cGlyphs; j++) { if (awc[j] < wc) { awc[i] = awc[j]; awc[j] = wc; wc = awc[i]; ch = ach[i]; ach[i] = ach[j]; ach[j] = ch; } } } /* Find number of WCRUNs */ cRuns = 1; for (i = 1; i < cGlyphs; i++) { if (awc[i] != awc[i - 1] + 1) { cRuns++; } } /* 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) { 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 = awc[0]; pwcrun[0].cGlyphs = 1; pwcrun[0].phg = phglyphs; phglyphs[0] = 0; /* Walk through all supported chars */ for (i = 1, j = 0; i < cGlyphs; i++) { /* Use offset to glyph entry as hglyph */ phglyphs[i] = (ach[i] - chFirst) * pface->cjEntrySize; /* Check whether we can append the wchar to a run */ if (awc[i] == awc[i - 1] + 1) { /* Append to current WCRUN */ pwcrun[j].cGlyphs++; } else { /* Add a new WCRUN */ j++; pwcrun[j].wcLow = awc[i]; pwcrun[j].cGlyphs = 1; pwcrun[j].phg = &phglyphs[i]; } } /* Set *pid to the allocated structure for use in BmfdFree */ *pid = (ULONG_PTR)pGlyphSet; return pGlyphSet; }
static BOOL FillFaceInfo( PBMFD_FACE pface, PFONTINFO16 pFontInfo) { CHAR ansi[4]; WCHAR unicode[4]; ULONG written; DWORD dfFlags; pface->pFontInfo = pFontInfo; pface->ulVersion = GETVAL(pFontInfo->dfVersion); pface->cGlyphs = pFontInfo->dfLastChar - pFontInfo->dfFirstChar + 1; /* Convert chars to unicode */ ansi[0] = pFontInfo->dfFirstChar; ansi[1] = pFontInfo->dfLastChar; ansi[2] = pFontInfo->dfFirstChar + pFontInfo->dfDefaultChar; ansi[3] = pFontInfo->dfFirstChar + pFontInfo->dfBreakChar; EngMultiByteToUnicodeN(unicode, 4 * sizeof(WCHAR), &written, ansi, 4); pface->wcFirstChar = unicode[0]; pface->wcLastChar = unicode[1]; pface->wcDefaultChar = unicode[2]; pface->wcBreakChar = unicode[3]; /* Copy some values */ pface->wPixHeight = GETVAL(pFontInfo->dfPixHeight); pface->wPixWidth = GETVAL(pFontInfo->dfPixWidth); pface->wWidthBytes = GETVAL(pFontInfo->dfWidthBytes); pface->wAscent = GETVAL(pFontInfo->dfAscent); pface->wDescent = pface->wPixHeight - pface->wAscent; /* Some version specific members */ if (pface->ulVersion >= 0x300) { dfFlags = GETVAL(pFontInfo->dfFlags); pface->wA = GETVAL(pFontInfo->dfAspace); pface->wB = GETVAL(pFontInfo->dfBspace); pface->wC = GETVAL(pFontInfo->dfCspace); pface->pCharTable = pface->pFontInfo->dfCharTable; pface->cjEntrySize = sizeof(GLYPHENTRY30); } else { dfFlags = DFF_1COLOR; pface->wA = 0; pface->wB = 0; pface->wC = 0; pface->pCharTable = &pface->pFontInfo->dfReserved + 1; pface->cjEntrySize = sizeof(GLYPHENTRY20); } pface->flInfo = FM_INFO_MASK; /* If dfWidth is non-null, we have a fixed width font */ if (dfFlags & DFF_FIXED || pface->wPixWidth) pface->flInfo |= FM_INFO_CONSTANT_WIDTH; /* Initialize color depth flags */ if (dfFlags & DFF_1COLOR) pface->flInfo |= FM_INFO_1BPP; else if (dfFlags & DFF_16COLOR) pface->flInfo |= FM_INFO_4BPP; else if (dfFlags & DFF_256COLOR) pface->flInfo |= FM_INFO_8BPP; else if (dfFlags & DFF_RGBCOLOR) pface->flInfo |= FM_INFO_24BPP; // TODO: walk through all glyphs and veryfy them and calculate max values // FIXME: After this point, the whole font data should be verified! return TRUE; }