Esempio n. 1
0
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;
    }
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
0
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;
}