From ce78c454eb4b3aabe7c5797cebd0ec4eae7edaab Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sun, 8 Mar 2009 03:09:10 +0000 Subject: [PATCH] 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 --- reactos/drivers/video/font/bmfd/bmfd.h | 22 +- reactos/drivers/video/font/bmfd/enable.c | 1 + reactos/drivers/video/font/bmfd/font.c | 116 +++--- reactos/drivers/video/font/bmfd/glyph.c | 429 +++++++++++++++-------- 4 files changed, 370 insertions(+), 198 deletions(-) diff --git a/reactos/drivers/video/font/bmfd/bmfd.h b/reactos/drivers/video/font/bmfd/bmfd.h index dd03bba8ad4..9163253e9d7 100644 --- a/reactos/drivers/video/font/bmfd/bmfd.h +++ b/reactos/drivers/video/font/bmfd/bmfd.h @@ -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); + diff --git a/reactos/drivers/video/font/bmfd/enable.c b/reactos/drivers/video/font/bmfd/enable.c index f1abad7caf9..2cc7222fd9d 100644 --- a/reactos/drivers/video/font/bmfd/enable.c +++ b/reactos/drivers/video/font/bmfd/enable.c @@ -21,6 +21,7 @@ static DRVFN gadrvfn[] = {INDEX_DrvFree, (PFN)BmfdFree}, {INDEX_DrvQueryGlyphAttrs, (PFN)BmfdQueryGlyphAttrs}, {INDEX_DrvQueryFontData, (PFN)BmfdQueryFontData}, + {INDEX_DrvDestroyFont, (PFN)BmfdDestroyFont}, }; diff --git a/reactos/drivers/video/font/bmfd/font.c b/reactos/drivers/video/font/bmfd/font.c index 960084bab4d..ec7f8f5e062 100644 --- a/reactos/drivers/video/font/bmfd/font.c +++ b/reactos/drivers/video/font/bmfd/font.c @@ -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; +} diff --git a/reactos/drivers/video/font/bmfd/glyph.c b/reactos/drivers/video/font/bmfd/glyph.c index 7802dc3f4f5..b3a7a7bab6b 100644 --- a/reactos/drivers/video/font/bmfd/glyph.c +++ b/reactos/drivers/video/font/bmfd/glyph.c @@ -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;