[ros-diffs] [tkreuzer] 39905: 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.

tkreuzer at svn.reactos.org tkreuzer at svn.reactos.org
Sun Mar 8 04:09:11 CET 2009


Author: tkreuzer
Date: Sun Mar  8 06:09:10 2009
New Revision: 39905

URL: http://svn.reactos.org/svn/reactos?rev=39905&view=rev
Log:
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.

Modified:
    trunk/reactos/drivers/video/font/bmfd/bmfd.h
    trunk/reactos/drivers/video/font/bmfd/enable.c
    trunk/reactos/drivers/video/font/bmfd/font.c
    trunk/reactos/drivers/video/font/bmfd/glyph.c

Modified: trunk/reactos/drivers/video/font/bmfd/bmfd.h
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/video/font/bmfd/bmfd.h?rev=39905&r1=39904&r2=39905&view=diff
==============================================================================
--- trunk/reactos/drivers/video/font/bmfd/bmfd.h [iso-8859-1] (original)
+++ trunk/reactos/drivers/video/font/bmfd/bmfd.h [iso-8859-1] Sun Mar  8 06:09:10 2009
@@ -225,7 +225,7 @@
     WORD wAscent;
     WORD wDescent;
     FLONG flInfo;
-} DRVFACE, *PDRVFACE;
+} BMFD_FACE, *PBMFD_FACE;
 
 typedef struct
 {
@@ -234,8 +234,17 @@
     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 @@
     WCHAR wszFamilyName[LF_FACESIZE];
     WCHAR wszFaceName[LF_FACESIZE];
     WCHAR wszStyleName[MAX_STYLESIZE];
-} DRVIFIMETRICS, *PDRVIFIMETRICS;
+} BMFD_IFIMETRICS, *PBMFD_IFIMETRICS;
 
 
 /** Function prototypes *******************************************************/
@@ -357,3 +366,8 @@
 	PVOID pv,
 	ULONG cjSize);
 
+VOID
+APIENTRY
+BmfdDestroyFont(
+    IN FONTOBJ *pfo);
+

Modified: trunk/reactos/drivers/video/font/bmfd/enable.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/video/font/bmfd/enable.c?rev=39905&r1=39904&r2=39905&view=diff
==============================================================================
--- trunk/reactos/drivers/video/font/bmfd/enable.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/video/font/bmfd/enable.c [iso-8859-1] Sun Mar  8 06:09:10 2009
@@ -21,6 +21,7 @@
     {INDEX_DrvFree,				(PFN)BmfdFree},
     {INDEX_DrvQueryGlyphAttrs,	(PFN)BmfdQueryGlyphAttrs},
     {INDEX_DrvQueryFontData,	(PFN)BmfdQueryFontData},
+    {INDEX_DrvDestroyFont,	    (PFN)BmfdDestroyFont},
 };
 
 

Modified: trunk/reactos/drivers/video/font/bmfd/font.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/video/font/bmfd/font.c?rev=39905&r1=39904&r2=39905&view=diff
==============================================================================
--- trunk/reactos/drivers/video/font/bmfd/font.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/video/font/bmfd/font.c [iso-8859-1] Sun Mar  8 06:09:10 2009
@@ -28,7 +28,7 @@
 static
 BOOL
 FillFaceInfo(
-    PDRVFACE pface,
+    PBMFD_FACE pface,
     PFONTINFO16 pFontInfo)
 {
     CHAR ansi[4];
@@ -124,7 +124,7 @@
     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 @@
             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 @@
                 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 @@
         type_id = GETVAL(pTInfo->type_id);
     }
 
-    return pfont;
+    return pfile;
 }
 
 /** Public Interface **********************************************************/
@@ -242,7 +242,7 @@
     ULONG ulLangID,
     ULONG ulFastCheckSum)
 {
-    PDRVFONT pfont = NULL;
+    PBMFD_FILE pfile = NULL;
     PVOID pvView;
     ULONG cjView;
 
@@ -266,16 +266,16 @@
     DbgPrint("mapped font file to %p, site if %ld\n", pvView, cjView);
 
     /* Try to parse a .fon file */
-    pfont = ParseFonFile(pvView, cjView);
-
-    if (!pfont)
+    pfile = ParseFonFile(pvView, cjView);
+
+    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 @@
         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 @@
 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 @@
     ULONG cjBuf,
     ULONG *pulBuf)
 {
-    PDRVFONT pfont = (PDRVFONT)iFile;
+    PBMFD_FILE pfile = (PBMFD_FILE)iFile;
 
     DbgPrint("BmfdQueryFontFile()\n");
 //    DbgBreakPoint();
@@ -330,7 +330,7 @@
         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 @@
 
         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 @@
     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 @@
 //    DbgBreakPoint();
 
     /* Check parameters, we only support QFT_GLYPHSET */
-    if (!iFace || iFace > pfont->cNumFaces || iMode != QFT_GLYPHSET)
-    {
-        DbgPrint("iFace = %ld, cNumFaces = %ld\n", iFace, pfont->cNumFaces);
+    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 = &pfont->aface[iFace - 1];
+    pface = &pfile->aface[iFace - 1];
 
     /* Get the number of characters in the face */
     cGlyphs = pface->cGlyphs;
@@ -514,43 +514,43 @@
     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 @@
     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 @@
     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 @@
 }
 
 
-
+VOID
+APIENTRY
+BmfdDestroyFont(
+    IN FONTOBJ *pfo)
+{
+    /* Free the font realization info */
+    EngFreeMem(pfo->pvProducer);
+    pfo->pvProducer = NULL;
+}

Modified: trunk/reactos/drivers/video/font/bmfd/glyph.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/video/font/bmfd/glyph.c?rev=39905&r1=39904&r2=39905&view=diff
==============================================================================
--- trunk/reactos/drivers/video/font/bmfd/glyph.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/video/font/bmfd/glyph.c [iso-8859-1] Sun Mar  8 06:09:10 2009
@@ -7,48 +7,299 @@
 
 #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;
-
-    /* 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;
-
-    /* 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 */
-}
+    PFONTINFO16 pFontInfo;
+    ULONG xScale, yScale;
+
+    if (pfddm)
+    {
+        if (cjSize < sizeof(FD_DEVICEMETRICS))
+        {
+            /* Not enough space, fail */
+            return FD_ERROR;
+        }
+
+        pFontInfo = pfont->pface->pFontInfo;
+        
+        xScale = pfont->xScale;
+        yScale = pfont->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->lMinA = 0;
+        pfddm->lMinC = 0;
+        pfddm->lMinD = 0;
+
+        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;
+        }
+
+        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 **********************************************************/
 
@@ -74,10 +325,9 @@
     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 @@
     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;



More information about the Ros-diffs mailing list