Bmfd: Rework code for BmfdQueryFontData, rename some structs, add BMFD_FONT struct, which is associated with a FONTOBJ, rewrite copying bits, so it can do scaling and rotation. Scaled fonts work now. Rotation is not yet finished.

svn path=/trunk/; revision=39905
This commit is contained in:
Timo Kreuzer 2009-03-08 03:09:10 +00:00
parent 52ccdffece
commit ce78c454eb
4 changed files with 370 additions and 198 deletions

View file

@ -225,7 +225,7 @@ typedef struct
WORD wAscent;
WORD wDescent;
FLONG flInfo;
} DRVFACE, *PDRVFACE;
} BMFD_FACE, *PBMFD_FACE;
typedef struct
{
@ -234,8 +234,17 @@ typedef struct
PFONTGROUPHDR pFontDir;
FONTTYPE ulFontType;
ULONG cNumFaces;
DRVFACE aface[1];
} DRVFONT, *PDRVFONT;
BMFD_FACE aface[1];
} BMFD_FILE, *PBMFD_FILE;
typedef struct
{
FONTOBJ *pfo;
PBMFD_FACE pface;
ULONG xScale;
ULONG yScale;
ULONG ulAngle;
} BMFD_FONT, *PBMFD_FONT;
//"Bold Italic Underline Strikeout"
#define MAX_STYLESIZE 35
@ -246,7 +255,7 @@ typedef struct
WCHAR wszFamilyName[LF_FACESIZE];
WCHAR wszFaceName[LF_FACESIZE];
WCHAR wszStyleName[MAX_STYLESIZE];
} DRVIFIMETRICS, *PDRVIFIMETRICS;
} BMFD_IFIMETRICS, *PBMFD_IFIMETRICS;
/** Function prototypes *******************************************************/
@ -357,3 +366,8 @@ BmfdQueryFontData(
PVOID pv,
ULONG cjSize);
VOID
APIENTRY
BmfdDestroyFont(
IN FONTOBJ *pfo);

View file

@ -21,6 +21,7 @@ static DRVFN gadrvfn[] =
{INDEX_DrvFree, (PFN)BmfdFree},
{INDEX_DrvQueryGlyphAttrs, (PFN)BmfdQueryGlyphAttrs},
{INDEX_DrvQueryFontData, (PFN)BmfdQueryFontData},
{INDEX_DrvDestroyFont, (PFN)BmfdDestroyFont},
};

View file

@ -28,7 +28,7 @@ IsValidPtr(
static
BOOL
FillFaceInfo(
PDRVFACE pface,
PBMFD_FACE pface,
PFONTINFO16 pFontInfo)
{
CHAR ansi[4];
@ -124,7 +124,7 @@ ParseFonFile(
PNE_TYPEINFO pTInfo;
PFONTINFO16 pFontInfo;
PCHAR pStart, pEnd;
PDRVFONT pfont = NULL;
PBMFD_FILE pfile = NULL;
WORD wShift;
ULONG i, cjOffset, cjLength;
ULONG type_id, count;
@ -173,15 +173,15 @@ ParseFonFile(
DbgPrint("Found NE_RSCTYPE_FONT\n");
/* Allocate an info structure for this font and all faces */
cjLength = sizeof(DRVFONT) + (count-1) * sizeof(DRVFACE);
pfont = EngAllocMem(0, cjLength, TAG_FONTINFO);
if (!pfont)
cjLength = sizeof(BMFD_FILE) + (count-1) * sizeof(BMFD_FACE);
pfile = EngAllocMem(0, cjLength, TAG_FONTINFO);
if (!pfile)
{
DbgPrint("Not enough memory: %ld\n", cjLength);
return NULL;
}
pfont->cNumFaces = count;
pfile->cNumFaces = count;
/* Fill all face info structures */
for (i = 0; i < count; i++)
@ -193,15 +193,15 @@ ParseFonFile(
if (!IsValidPtr(pFontInfo, cjLength, pStart, pEnd, 1))
{
DbgPrint("pFontInfo is invalid: 0x%p\n", pFontInfo);
EngFreeMem(pfont);
EngFreeMem(pfile);
return NULL;
}
/* Validate FONTINFO and fill face info */
if (!FillFaceInfo(&pfont->aface[i], pFontInfo))
if (!FillFaceInfo(&pfile->aface[i], pFontInfo))
{
DbgPrint("pFontInfo is invalid: 0x%p\n", pFontInfo);
EngFreeMem(pfont);
EngFreeMem(pfile);
return NULL;
}
}
@ -226,7 +226,7 @@ ParseFonFile(
type_id = GETVAL(pTInfo->type_id);
}
return pfont;
return pfile;
}
/** Public Interface **********************************************************/
@ -242,7 +242,7 @@ BmfdLoadFontFile(
ULONG ulLangID,
ULONG ulFastCheckSum)
{
PDRVFONT pfont = NULL;
PBMFD_FILE pfile = NULL;
PVOID pvView;
ULONG cjView;
@ -266,16 +266,16 @@ BmfdLoadFontFile(
DbgPrint("mapped font file to %p, site if %ld\n", pvView, cjView);
/* Try to parse a .fon file */
pfont = ParseFonFile(pvView, cjView);
pfile = ParseFonFile(pvView, cjView);
if (!pfont)
if (!pfile)
{
/* Could be a .fnt file */
pfont = ParseFntFile(pvView, cjView);
pfile = ParseFntFile(pvView, cjView);
}
/* Check whether we succeeded finding a font */
if (!pfont)
if (!pfile)
{
DbgPrint("No font data found\n");
@ -286,11 +286,11 @@ BmfdLoadFontFile(
return HFF_INVALID;
}
pfont->iFile = *piFile;
pfont->pvView = pvView;
pfile->iFile = *piFile;
pfile->pvView = pvView;
/* Success, return the pointer to font info structure */
return (ULONG_PTR)pfont;
return (ULONG_PTR)pfile;
}
BOOL
@ -298,15 +298,15 @@ APIENTRY
BmfdUnloadFontFile(
IN ULONG_PTR iFile)
{
PDRVFONT pfont = (PDRVFONT)iFile;
PBMFD_FILE pfile = (PBMFD_FILE)iFile;
DbgPrint("BmfdUnloadFontFile()\n");
/* Free the memory that was allocated for the font */
EngFreeMem(pfont);
EngFreeMem(pfile);
/* Unmap the font file */
EngUnmapFontFileFD(pfont->iFile);
EngUnmapFontFileFD(pfile->iFile);
return TRUE;
}
@ -320,7 +320,7 @@ BmfdQueryFontFile(
ULONG cjBuf,
ULONG *pulBuf)
{
PDRVFONT pfont = (PDRVFONT)iFile;
PBMFD_FILE pfile = (PBMFD_FILE)iFile;
DbgPrint("BmfdQueryFontFile()\n");
// DbgBreakPoint();
@ -330,7 +330,7 @@ BmfdQueryFontFile(
case QFF_DESCRIPTION:
{
/* We copy the face name of the 1st face */
PCHAR pDesc = pfont->aface[0].pszFaceName;
PCHAR pDesc = pfile->aface[0].pszFaceName;
ULONG cOutSize;
if (pulBuf)
{
@ -349,7 +349,7 @@ BmfdQueryFontFile(
case QFF_NUMFACES:
/* return the number of faces in the file */
return pfont->cNumFaces;
return pfile->cNumFaces;
default:
return FD_ERROR;
@ -387,8 +387,8 @@ BmfdQueryFontTree(
ULONG iMode,
ULONG_PTR *pid)
{
PDRVFONT pfont = (PDRVFONT)iFile;
PDRVFACE pface;
PBMFD_FILE pfile = (PBMFD_FILE)iFile;
PBMFD_FACE pface;
ULONG i, j, cjOffset, cjSize, cGlyphs, cRuns;
CHAR ch, chFirst, ach[256];
WCHAR wc, awc[256];
@ -400,14 +400,14 @@ BmfdQueryFontTree(
// DbgBreakPoint();
/* Check parameters, we only support QFT_GLYPHSET */
if (!iFace || iFace > pfont->cNumFaces || iMode != QFT_GLYPHSET)
if (!iFace || iFace > pfile->cNumFaces || iMode != QFT_GLYPHSET)
{
DbgPrint("iFace = %ld, cNumFaces = %ld\n", iFace, pfont->cNumFaces);
DbgPrint("iFace = %ld, cNumFaces = %ld\n", iFace, pfile->cNumFaces);
return NULL;
}
/* Get a pointer to the face data */
pface = &pfont->aface[iFace - 1];
pface = &pfile->aface[iFace - 1];
/* Get the number of characters in the face */
cGlyphs = pface->cGlyphs;
@ -514,43 +514,43 @@ BmfdQueryFont(
IN ULONG iFace,
IN ULONG_PTR *pid)
{
PDRVFONT pfont = (PDRVFONT)iFile;
PDRVFACE pface;
PBMFD_FILE pfile = (PBMFD_FILE)iFile;
PBMFD_FACE pface;
PFONTINFO16 pFontInfo;
PIFIMETRICS pifi;
PDRVIFIMETRICS pDrvIM;
PBMFD_IFIMETRICS pifiX;
PANOSE panose = {0};
DbgPrint("BmfdQueryFont()\n");
// DbgBreakPoint();
/* Validate parameters */
if (iFace > pfont->cNumFaces || !pid)
if (iFace > pfile->cNumFaces || !pid)
{
return NULL;
}
pface = &pfont->aface[iFace - 1];
pface = &pfile->aface[iFace - 1];
pFontInfo = pface->pFontInfo;
/* Allocate the structure */
pDrvIM = EngAllocMem(FL_ZERO_MEMORY, sizeof(DRVIFIMETRICS), TAG_IFIMETRICS);
if (!pDrvIM)
pifiX = EngAllocMem(FL_ZERO_MEMORY, sizeof(BMFD_IFIMETRICS), TAG_IFIMETRICS);
if (!pifiX)
{
return NULL;
}
/* Return a pointer to free it later */
*pid = (ULONG_PTR)pDrvIM;
*pid = (ULONG_PTR)pifiX;
/* Fill IFIMETRICS */
pifi = &pDrvIM->ifim;
pifi->cjThis = sizeof(DRVIFIMETRICS);
pifi = &pifiX->ifim;
pifi->cjThis = sizeof(BMFD_IFIMETRICS);
pifi->cjIfiExtra = 0;
pifi->dpwszFamilyName = FIELD_OFFSET(DRVIFIMETRICS, wszFamilyName);
pifi->dpwszStyleName = FIELD_OFFSET(DRVIFIMETRICS, wszFamilyName);
pifi->dpwszFaceName = FIELD_OFFSET(DRVIFIMETRICS, wszFaceName);
pifi->dpwszUniqueName = FIELD_OFFSET(DRVIFIMETRICS, wszFaceName);
pifi->dpwszFamilyName = FIELD_OFFSET(BMFD_IFIMETRICS, wszFamilyName);
pifi->dpwszStyleName = FIELD_OFFSET(BMFD_IFIMETRICS, wszFamilyName);
pifi->dpwszFaceName = FIELD_OFFSET(BMFD_IFIMETRICS, wszFaceName);
pifi->dpwszUniqueName = FIELD_OFFSET(BMFD_IFIMETRICS, wszFaceName);
pifi->dpFontSim = 0;
pifi->lEmbedId = 0;
pifi->lItalicAngle = 0;
@ -612,21 +612,21 @@ BmfdQueryFont(
pifi->panose = panose;
/* Set char sets */
pDrvIM->ajCharSet[0] = pifi->jWinCharSet;
pDrvIM->ajCharSet[1] = DEFAULT_CHARSET;
pifiX->ajCharSet[0] = pifi->jWinCharSet;
pifiX->ajCharSet[1] = DEFAULT_CHARSET;
if (pface->flInfo & FM_INFO_CONSTANT_WIDTH)
pifi->jWinPitchAndFamily |= FIXED_PITCH;
#if 0
EngMultiByteToUnicodeN(pDrvIM->wszFaceName,
EngMultiByteToUnicodeN(pifiX->wszFaceName,
LF_FACESIZE * sizeof(WCHAR),
NULL,
pFontInfo->,
strnlen(pDesc, LF_FACESIZE));
#endif
wcscpy(pDrvIM->wszFaceName, L"Courier-X");
wcscpy(pDrvIM->wszFamilyName, L"Courier-X");
wcscpy(pifiX->wszFaceName, L"Courier-X");
wcscpy(pifiX->wszFamilyName, L"Courier-X");
/* Initialize font weight style flags and string */
if (pifi->usWinWeight == FW_REGULAR)
@ -636,29 +636,29 @@ BmfdQueryFont(
else if (pifi->usWinWeight > FW_SEMIBOLD)
{
pifi->fsSelection |= FM_SEL_BOLD;
wcscat(pDrvIM->wszStyleName, L"Bold ");
wcscat(pifiX->wszStyleName, L"Bold ");
}
else if (pifi->usWinWeight <= FW_LIGHT)
{
wcscat(pDrvIM->wszStyleName, L"Light ");
wcscat(pifiX->wszStyleName, L"Light ");
}
if (pFontInfo->dfItalic)
{
pifi->fsSelection |= FM_SEL_ITALIC;
wcscat(pDrvIM->wszStyleName, L"Italic ");
wcscat(pifiX->wszStyleName, L"Italic ");
}
if (pFontInfo->dfUnderline)
{
pifi->fsSelection |= FM_SEL_UNDERSCORE;
wcscat(pDrvIM->wszStyleName, L"Underscore ");
wcscat(pifiX->wszStyleName, L"Underscore ");
}
if (pFontInfo->dfStrikeOut)
{
pifi->fsSelection |= FM_SEL_STRIKEOUT;
wcscat(pDrvIM->wszStyleName, L"Strikeout ");
wcscat(pifiX->wszStyleName, L"Strikeout ");
}
return pifi;
@ -679,4 +679,12 @@ BmfdFree(
}
VOID
APIENTRY
BmfdDestroyFont(
IN FONTOBJ *pfo)
{
/* Free the font realization info */
EngFreeMem(pfo->pvProducer);
pfo->pvProducer = NULL;
}

View file

@ -7,49 +7,300 @@
#include "bmfd.h"
static
ULONG
FORCEINLINE
_ReadPixel(
CHAR* pjBits,
ULONG x,
ULONG y,
ULONG ulHeight)
{
CHAR j;
j = pjBits[(x/8) * ulHeight + y];
return (j >> (~x & 0x7)) & 1;
}
VOID
FillFDDM(
FORCEINLINE
_WritePixel(
CHAR* pjBits,
ULONG x,
ULONG y,
ULONG cjRow,
ULONG color)
{
pjBits += y * cjRow;
pjBits += x / 8;
*pjBits |= color << (~x & 0x7);
}
PBMFD_FONT
BmfdGetFontInstance(
FONTOBJ *pfo,
PBMFD_FACE pface)
{
PBMFD_FONT pfont = pfo->pvProducer;
XFORMOBJ *pxo;
FLOATOBJ_XFORM xfo;
if (!pfont)
{
/* Allocate realization info */
pfont = EngAllocMem(0, sizeof(BMFD_FONT), 0);
if (!pfont)
{
return NULL;
}
pxo = FONTOBJ_pxoGetXform(pfo);
XFORMOBJ_iGetFloatObjXform(pxo, &xfo);
pfont->pfo = pfo;
pfont->pface = pface;
pfont->xScale = FLOATOBJ_GetLong(&xfo.eM11);
pfont->yScale = FLOATOBJ_GetLong(&xfo.eM22);
pfont->ulAngle = 0;
/* Set the pvProducer member of the fontobj */
pfo->pvProducer = pfont;
}
return pfont;
}
ULONG
BmfdQueryGlyphAndBitmap(
PBMFD_FONT pfont,
HGLYPH hg,
GLYPHDATA *pgd,
GLYPHBITS *pgb,
ULONG cjSize)
{
PBMFD_FACE pface = pfont->pface;
PGLYPHENTRY pge = (PGLYPHENTRY)hg;
ULONG xSrc, ySrc, cxSrc, cySrc;
ULONG xDst, yDst, cxDst, cyDst;
ULONG xScale, yScale;
ULONG ulGlyphOffset, cjDstRow, color;
PVOID pvSrc0, pvDst0;
if (!pge)
{
DbgPrint("no glyph handle given!\n");
return FD_ERROR;
}
/* Get the bitmap offset depending on file version */
if (pface->ulVersion >= 0x300)
{
cxSrc = GETVAL(pge->ge20.geWidth);
ulGlyphOffset = GETVAL(pge->ge30.geOffset);
}
else
{
cxSrc = GETVAL(pge->ge30.geWidth);
ulGlyphOffset = GETVAL(pge->ge20.geOffset);
}
cySrc = pface->wPixHeight;
/* Pointer to the bitmap bits */
pvSrc0 = (PBYTE)pface->pFontInfo + ulGlyphOffset;
pvDst0 = pgb->aj;
xScale = pfont->xScale;
yScale = pfont->yScale;
/* Calculate extents of destination bitmap */
if (pfont->ulAngle == 90 || pfont->ulAngle == 270)
{
cxDst = cySrc * xScale;
cyDst = cxSrc * yScale;
}
else
{
cxDst = cxSrc * yScale;
cyDst = cySrc * xScale;
}
cjDstRow = (cxDst + 7) / 8;
if (pgd)
{
/* Fill GLYPHDATA structure */
pgd->gdf.pgb = pgb;
pgd->hg = hg;
pgd->fxD = xScale * (pface->wA + cxDst + pface->wC) << 4;
pgd->fxA = xScale * pface->wA << 4;
pgd->fxAB = xScale * (pface->wA + cxDst) << 4;
pgd->fxInkTop = yScale * pface->wAscent << 4;
pgd->fxInkBottom = - yScale * (pface->wDescent << 4);
pgd->rclInk.top = - yScale * pface->wAscent;
pgd->rclInk.bottom = yScale * pface->wDescent;
pgd->rclInk.left = xScale * pface->wA;
pgd->rclInk.right = pgd->rclInk.left + cxDst;
pgd->ptqD.x.LowPart = 0;
pgd->ptqD.x.HighPart = pgd->fxD;
pgd->ptqD.y.LowPart = 0;
pgd->ptqD.y.HighPart = 0;
}
if (pgb)
{
/* Verify that the buffer is big enough */
if (cjSize < FIELD_OFFSET(GLYPHBITS, aj) + cyDst * cjDstRow)
{
DbgPrint("Buffer too small (%ld), %ld,%ld\n",
cjSize, cxSrc, cySrc);
return FD_ERROR;
}
/* Fill GLYPHBITS structure */
pgb->ptlOrigin.x = yScale * pface->wA;
pgb->ptlOrigin.y = - yScale * pface->wAscent;
pgb->sizlBitmap.cx = cxDst;
pgb->sizlBitmap.cy = cyDst;
/* Erase destination surface */
memset(pvDst0, 0, cyDst * cjDstRow);
switch (pfont->ulAngle)
{
case 90:
/* Copy pixels */
for (yDst = 0; yDst < cyDst ; yDst++)
{
xSrc = yDst / yScale;
for (xDst = 0; xDst < cxDst; xDst++)
{
ySrc = (cxDst - xDst) / xScale;
color = _ReadPixel(pvSrc0, xSrc, ySrc, cySrc);
_WritePixel(pvDst0, xDst, yDst, cjDstRow, color);
}
}
break;
case 180:
for (yDst = 0; yDst < cyDst ; yDst++)
{
ySrc = (cyDst - yDst) / yScale;
for (xDst = 0; xDst < cxDst; xDst++)
{
xSrc = (cxDst - xDst) / xScale;
color = _ReadPixel(pvSrc0, xSrc, ySrc, cySrc);
_WritePixel(pvDst0, xDst, yDst, cjDstRow, color);
}
}
break;
case 270:
for (yDst = 0; yDst < cyDst ; yDst++)
{
xSrc = (cyDst - yDst) / yScale;
for (xDst = 0; xDst < cxDst; xDst++)
{
ySrc = xDst / xScale;
color = _ReadPixel(pvSrc0, xSrc, ySrc, cySrc);
_WritePixel(pvDst0, xDst, yDst, cjDstRow, color);
}
}
break;
case 0:
default:
for (yDst = 0; yDst < cyDst ; yDst++)
{
ySrc = yDst / yScale;
for (xDst = 0; xDst < cxDst; xDst++)
{
xSrc = xDst / xScale;
color = _ReadPixel(pvSrc0, xSrc, ySrc, cySrc);
_WritePixel(pvDst0, xDst, yDst, cjDstRow, color);
}
}
}
}
/* Return the size of the GLYPHBITS structure */
return FIELD_OFFSET(GLYPHBITS, aj) + cyDst * cjDstRow;
}
ULONG
BmfdQueryMaxExtents(
PBMFD_FONT pfont,
PFD_DEVICEMETRICS pfddm,
PFONTINFO16 pFontInfo)
ULONG cjSize)
{
ULONG cjMaxWidth, cjMaxBitmapSize;
PFONTINFO16 pFontInfo;
ULONG xScale, yScale;
/* Fill FD_DEVICEMETRICS */
pfddm->flRealizedType = FDM_MASK;
pfddm->pteBase.x = FLOATL_1;
pfddm->pteBase.y = 0;
pfddm->pteSide.x = 0;
pfddm->pteSide.y = FLOATL_1;
pfddm->ptlUnderline1.x = 0;
pfddm->ptlUnderline1.y = 1;
pfddm->ptlStrikeout.x = 0;
pfddm->ptlStrikeout.y = -4;
pfddm->ptlULThickness.x = 0;
pfddm->ptlULThickness.y = 1;
pfddm->ptlSOThickness.x = 0;
pfddm->ptlSOThickness.y = 1;
pfddm->lD = GETVAL(pFontInfo->dfPixWidth);
pfddm->cxMax = GETVAL(pFontInfo->dfMaxWidth);
pfddm->cyMax = GETVAL(pFontInfo->dfPixHeight);
pfddm->fxMaxAscender = GETVAL(pFontInfo->dfAscent) << 4;
pfddm->fxMaxDescender = (pfddm->cyMax << 4) - pfddm->fxMaxAscender;
pfddm->lMinA = 0;
pfddm->lMinC = 0;
pfddm->lMinD = 0;
if (pfddm)
{
if (cjSize < sizeof(FD_DEVICEMETRICS))
{
/* Not enough space, fail */
return FD_ERROR;
}
/* Calculate Width in bytes */
cjMaxWidth = ((pfddm->cxMax + 7) >> 3);
pFontInfo = pfont->pface->pFontInfo;
xScale = pfont->xScale;
yScale = pfont->yScale;
/* Calculate size of the bitmap, rounded to DWORDs */
cjMaxBitmapSize = ((cjMaxWidth * pfddm->cyMax) + 3) & ~3;
/* Fill FD_DEVICEMETRICS */
pfddm->flRealizedType = FDM_MASK;
pfddm->pteBase.x = FLOATL_1;
pfddm->pteBase.y = 0;
pfddm->pteSide.x = 0;
pfddm->pteSide.y = FLOATL_1;
pfddm->ptlUnderline1.x = 0;
pfddm->ptlUnderline1.y = 1;
pfddm->ptlStrikeout.x = 0;
pfddm->ptlStrikeout.y = -4;
pfddm->ptlULThickness.x = 0;
pfddm->ptlULThickness.y = 1;
pfddm->ptlSOThickness.x = 0;
pfddm->ptlSOThickness.y = 1;
pfddm->lMinA = 0;
pfddm->lMinC = 0;
pfddm->lMinD = 0;
/* cjGlyphMax is the full size of the GLYPHBITS structure */
pfddm->cjGlyphMax = FIELD_OFFSET(GLYPHBITS, aj) + cjMaxBitmapSize;
if (pfont->ulAngle == 90 || pfont->ulAngle == 270)
{
pfddm->cxMax = xScale * GETVAL(pFontInfo->dfPixHeight);
pfddm->cyMax = yScale * GETVAL(pFontInfo->dfMaxWidth);
pfddm->fxMaxAscender = yScale * GETVAL(pFontInfo->dfAscent) << 4;
pfddm->fxMaxDescender = (pfddm->cyMax << 4) - pfddm->fxMaxAscender;
}
else
{
pfddm->cxMax = xScale * GETVAL(pFontInfo->dfMaxWidth);
pfddm->cyMax = yScale * GETVAL(pFontInfo->dfPixHeight);
pfddm->fxMaxAscender = yScale * GETVAL(pFontInfo->dfAscent) << 4;
pfddm->fxMaxDescender = (pfddm->cyMax << 4) - pfddm->fxMaxAscender;
}
/* NOTE: fdxQuantized and NonLinear... stay unchanged */
pfddm->lD = pfddm->cxMax;
/* Calculate Width in bytes */
cjMaxWidth = ((pfddm->cxMax + 7) >> 3);
/* Calculate size of the bitmap, rounded to DWORDs */
cjMaxBitmapSize = ((cjMaxWidth * pfddm->cyMax) + 3) & ~3;
/* cjGlyphMax is the full size of the GLYPHBITS structure */
pfddm->cjGlyphMax = FIELD_OFFSET(GLYPHBITS, aj) + cjMaxBitmapSize;
/* NOTE: fdxQuantized and NonLinear... stay unchanged */
}
/* Return the size of the structure */
return sizeof(FD_DEVICEMETRICS);
}
/** Public Interface **********************************************************/
PFD_GLYPHATTR
@ -74,10 +325,9 @@ BmfdQueryFontData(
PVOID pv,
ULONG cjSize)
{
PDRVFONT pfont = (PDRVFONT)pfo->iFile;
PDRVFACE pface = &pfont->aface[pfo->iFace - 1];
PGLYPHENTRY pge = (PGLYPHENTRY)hg;
ULONG ulGlyphOffset, ulWidthBytes, ulPixWidth, ulPixHeight, x, y, cjRow;
PBMFD_FILE pfile = (PBMFD_FILE)pfo->iFile;
PBMFD_FACE pface = &pfile->aface[pfo->iFace - 1];
PBMFD_FONT pfont= BmfdGetFontInstance(pfo, pface);
DbgPrint("BmfdQueryFontData(pfo=%p, iMode=%ld, hg=%p, pgd=%p, pv=%p, cjSize=%ld)\n",
pfo, iMode, hg, pgd, pv, cjSize);
@ -86,112 +336,11 @@ BmfdQueryFontData(
switch (iMode)
{
case QFD_GLYPHANDBITMAP: /* 1 */
{
GLYPHBITS *pgb = pv;
BYTE j, *pjGlyphBits;
// DbgPrint("QFD_GLYPHANDBITMAP, hg=%p, pgd=%p, pv=%p, cjSize=%d\n",
// hg, pgd, pv, cjSize);
if (!hg)
{
DbgPrint("no glyph handle given!\n");
return FD_ERROR;
}
/* Get the bitmap offset depending on file version */
if (pface->ulVersion >= 0x300)
{
ulPixWidth = GETVAL(pge->ge20.geWidth);
ulGlyphOffset = GETVAL(pge->ge30.geOffset);
}
else
{
ulPixWidth = GETVAL(pge->ge30.geWidth);
ulGlyphOffset = GETVAL(pge->ge20.geOffset);
}
ulPixHeight = pface->wPixHeight;
/* Calculate number of bytes per row for gdi */
cjRow = (ulPixWidth + 7) / 8; // FIXME: other bpp values
if (pgd)
{
/* Fill GLYPHDATA structure */
pgd->gdf.pgb = pgb;
pgd->hg = hg;
pgd->fxD = (pface->wA + ulPixWidth + pface->wC) << 4;
pgd->fxA = pface->wA << 4;
pgd->fxAB = (pface->wA + ulPixWidth) << 4;
pgd->fxInkTop = pface->wAscent << 4;
pgd->fxInkBottom = - (pface->wDescent << 4);
pgd->rclInk.top = - pface->wAscent;
pgd->rclInk.bottom = pface->wDescent ;
pgd->rclInk.left = pface->wA;
pgd->rclInk.right = pface->wA + ulPixWidth;
pgd->ptqD.x.LowPart = 0;
pgd->ptqD.x.HighPart = pgd->fxD;
pgd->ptqD.y.LowPart = 0;
pgd->ptqD.y.HighPart = 0;
}
if (pgb)
{
// DbgBreakPoint();
/* Verify that the buffer is big enough */
if (cjSize < FIELD_OFFSET(GLYPHBITS, aj) + ulPixHeight * cjRow)
{
DbgPrint("Buffer too small (%ld), %ld,%ld\n",
cjSize, ulPixWidth, ulPixHeight);
return FD_ERROR;
}
/* Fill GLYPHBITS structure */
pgb->ptlOrigin.x = pface->wA;
pgb->ptlOrigin.y = - pface->wAscent;
pgb->sizlBitmap.cx = ulPixWidth;
pgb->sizlBitmap.cy = ulPixHeight;
/* Copy the bitmap bits */
pjGlyphBits = (PBYTE)pface->pFontInfo + ulGlyphOffset;
ulWidthBytes = pface->wWidthBytes;
for (y = 0; y < ulPixHeight; y++)
{
for (x = 0; x < cjRow; x++)
{
j = pjGlyphBits[x * ulPixHeight + y];
pgb->aj[y * cjRow + x] = j;
}
}
DbgPrint("iFace=%ld, ulGlyphOffset=%lx, ulPixHeight=%ld, cjRow=%ld\n",
pfo->iFace, ulGlyphOffset, ulPixHeight, cjRow);
// DbgBreakPoint();
}
/* Return the size of the GLYPHBITS structure */
return FIELD_OFFSET(GLYPHBITS, aj) + ulPixHeight * cjRow;
}
return BmfdQueryGlyphAndBitmap(pfont, hg, pgd, pv, cjSize);
case QFD_MAXEXTENTS: /* 3 */
{
if (pv)
{
if (cjSize < sizeof(FD_DEVICEMETRICS))
{
/* Not enough space, fail */
return FD_ERROR;
}
/* Fill the PFD_DEVICEMETRICS structure */
FillFDDM((PFD_DEVICEMETRICS)pv, pface->pFontInfo);
}
/* Return the size of the structure */
return sizeof(FD_DEVICEMETRICS);
}
return BmfdQueryMaxExtents(pfont, pv, cjSize);
/* we support nothing else */
default:
return FD_ERROR;