mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 08:30:21 +00:00
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:
parent
52ccdffece
commit
ce78c454eb
4 changed files with 370 additions and 198 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ static DRVFN gadrvfn[] =
|
|||
{INDEX_DrvFree, (PFN)BmfdFree},
|
||||
{INDEX_DrvQueryGlyphAttrs, (PFN)BmfdQueryGlyphAttrs},
|
||||
{INDEX_DrvQueryFontData, (PFN)BmfdQueryFontData},
|
||||
{INDEX_DrvDestroyFont, (PFN)BmfdDestroyFont},
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue