Author: tkreuzer
Date: Sun May 22 16:07:23 2011
New Revision: 51849

URL: http://svn.reactos.org/svn/reactos?rev=51849&view=rev
Log:
[GDI FONT DRIVER]
- Improve BITMAP_SIZE macro
- Make the bitmaps always at least 1x1 pixel in size (fixes a crash, when 
opening desktop context menu)
- Calculate maximum extents by transforming all 4 coordinates of the bounding 
box. Fixes broken sizes being calculated when the glyph is rotated.

Modified:
    branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/ftfd.h
    branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/glyph.c

Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/ftfd.h
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/ftfd.h?rev=51849&r1=51848&r2=51849&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/ftfd.h 
[iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/ftfd.h 
[iso-8859-1] Sun May 22 16:07:23 2011
@@ -116,7 +116,7 @@
 
 typedef union _FTFD_DEVICEMETRICS
 {
-    POINTL aptl[7];
+    POINTL aptl[10];
     struct
     {
         POINTFIX ptfxMaxAscender;
@@ -125,7 +125,7 @@
         POINTL ptlStrikeout;
         POINTL ptlULThickness;
         POINTL ptlSOThickness;
-        SIZEL sizlMax;
+        POINTL aptlBBox[4];
     };
 } FTFD_DEVICEMETRICS;
 
@@ -144,6 +144,8 @@
     FT_Face ftface;
     FD_XFORM fdxQuantized;
     FTFD_DEVICEMETRICS metrics;
+    RECTL rclBBox;
+    SIZEL sizlMax;
     POINTEF ptefBase;
     POINTEF ptefSide;
     SIZEL sizlScale;

Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/glyph.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/glyph.c?rev=51849&r1=51848&r2=51849&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/glyph.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/glyph.c 
[iso-8859-1] Sun May 22 16:07:23 2011
@@ -12,7 +12,7 @@
 #define FLOATL_1 0x3f800000
 
 #define BITMAP_SIZE(cx, cy, bpp) \
-    ((((((cx * bpp) + 7) >> 3) * cy) + 3) & ~3)
+    (((((((cx) * (bpp)) + 7) >> 3) * (cy)) + 3) & ~3)
 
 #define GLYPHBITS_SIZE(cx, cy, bpp) \
     (FIELD_OFFSET(GLYPHBITS, aj) + BITMAP_SIZE(cx, cy, bpp))
@@ -233,16 +233,40 @@
     pmetrics->ptlULThickness.y = pface->ifiex.ifi.fwdUnderscoreSize;
     pmetrics->ptlSOThickness.x = 0;
     pmetrics->ptlSOThickness.y = pface->ifiex.ifi.fwdStrikeoutSize;
-    pmetrics->sizlMax.cx = ftface->bbox.xMax - ftface->bbox.xMin;
-    pmetrics->sizlMax.cy = ftface->bbox.yMax - ftface->bbox.yMin;
+    pmetrics->aptlBBox[0].x = ftface->bbox.xMin;
+    pmetrics->aptlBBox[0].y = ftface->bbox.yMin;
+    pmetrics->aptlBBox[1].x = ftface->bbox.xMax;
+    pmetrics->aptlBBox[1].y = ftface->bbox.yMin;
+    pmetrics->aptlBBox[2].x = ftface->bbox.xMax;
+    pmetrics->aptlBBox[2].y = ftface->bbox.yMax;
+    pmetrics->aptlBBox[3].x = ftface->bbox.xMin;
+    pmetrics->aptlBBox[3].y = ftface->bbox.yMax;
 
     /* Transform all coordinates into device space */
-    if (!XFORMOBJ_bApplyXform(pxo, XF_LTOL, 7, pmetrics->aptl, pmetrics->aptl))
+    if (!XFORMOBJ_bApplyXform(pxo, XF_LTOL, 10, pmetrics->aptl, 
pmetrics->aptl))
     {
         WARN("Failed apply coordinate transformation.\n");
         EngFreeMem(pfont);
         return NULL;
     }
+
+    /* Extract the bounding box in device coordinates */
+    pfont->rclBBox.left = min(pmetrics->aptlBBox[0].x, 
pmetrics->aptlBBox[1].x);
+    pfont->rclBBox.left = min(pfont->rclBBox.left, pmetrics->aptlBBox[2].x);
+    pfont->rclBBox.left = min(pfont->rclBBox.left, pmetrics->aptlBBox[3].x);
+    pfont->rclBBox.right = max(pmetrics->aptlBBox[0].x, 
pmetrics->aptlBBox[1].x);
+    pfont->rclBBox.right = max(pfont->rclBBox.right, pmetrics->aptlBBox[2].x);
+    pfont->rclBBox.right = max(pfont->rclBBox.right, pmetrics->aptlBBox[3].x);
+    pfont->rclBBox.top = min(pmetrics->aptlBBox[0].y, pmetrics->aptlBBox[1].y);
+    pfont->rclBBox.top = min(pfont->rclBBox.top, pmetrics->aptlBBox[2].y);
+    pfont->rclBBox.top = min(pfont->rclBBox.top, pmetrics->aptlBBox[3].y);
+    pfont->rclBBox.bottom = max(pmetrics->aptlBBox[0].y, 
pmetrics->aptlBBox[1].y);
+    pfont->rclBBox.bottom = max(pfont->rclBBox.bottom, 
pmetrics->aptlBBox[2].y);
+    pfont->rclBBox.bottom = max(pfont->rclBBox.bottom, 
pmetrics->aptlBBox[3].y);
+
+    /* Calculate maximum extents */
+    pfont->sizlMax.cx = pfont->rclBBox.right - pfont->rclBBox.left;
+    pfont->sizlMax.cy = pfont->rclBBox.bottom - pfont->rclBBox.top;
 
     /* Fixup some minimum values */
     if (pmetrics->ptlULThickness.y <= 0) pmetrics->ptlULThickness.y = 1;
@@ -314,8 +338,8 @@
         pfddm->ptlStrikeout = pfont->metrics.ptlStrikeout;
         pfddm->ptlULThickness = pfont->metrics.ptlULThickness;
         pfddm->ptlSOThickness = pfont->metrics.ptlSOThickness;
-        pfddm->cxMax = pfont->metrics.sizlMax.cx;
-        pfddm->cyMax = pfont->metrics.sizlMax.cy;
+        pfddm->cxMax = pfont->sizlMax.cx;
+        pfddm->cyMax = pfont->sizlMax.cy;
 
         /* Convert the base vectors from FLOATOBJ to FLOATL */
         pfddm->pteBase.x = FLOATOBJ_GetFloat(&pfont->ptefBase.x);
@@ -414,19 +438,26 @@
     pgd->rclInk.right = pgd->rclInk.left + ftglyph->bitmap.width;
     pgd->rclInk.bottom = pgd->rclInk.top + ftglyph->bitmap.rows;
 
+    /* Make the bitmap at least 1x1 pixel large */
+    if (ftglyph->bitmap.width == 0) pgd->rclInk.right++;
+    if (ftglyph->bitmap.rows == 0) pgd->rclInk.bottom++;
+
     /* FIX representation of bitmap top and bottom */
     pgd->fxInkBottom = (-pgd->rclInk.bottom) << 4;
     pgd->fxInkTop = pgd->rclInk.top << 4;
-
-    /* Make the bitmap at least 1x1 pixel large */
-    if (ftglyph->bitmap.width == 0) pgd->rclInk.right++;
-    if (ftglyph->bitmap.rows == 0) pgd->rclInk.bottom++;
 
     // FIXME:
     pgd->ptqD.x.LowPart = pgd->fxD;
     pgd->ptqD.x.HighPart = 0;
     pgd->ptqD.y.LowPart = 0;
     pgd->ptqD.y.HighPart = 0;
+
+    if (ftglyph->bitmap.width > pfont->sizlMax.cx ||
+        ftglyph->bitmap.rows > pfont->sizlMax.cy)
+    {
+        __debugbreak();
+    }
+
 //__debugbreak();
 }
 
@@ -446,6 +477,18 @@
     pgb->sizlBitmap.cx = ftglyph->bitmap.width;
     pgb->sizlBitmap.cy = ftglyph->bitmap.rows;
 
+    /* Make the bitmap at least 1x1 pixel large */
+    if (pgb->sizlBitmap.cx == 0) pgb->sizlBitmap.cx++;
+    if (pgb->sizlBitmap.cy == 0) pgb->sizlBitmap.cy++;
+
+    if (pgb->sizlBitmap.cx > pfont->sizlMax.cx ||
+        pgb->sizlBitmap.cy > pfont->sizlMax.cy)
+    {
+        WARN("The size of the bitmap exceeds the maximum size\n");
+        __debugbreak();
+        return;
+    }
+
     cjBitmapSize = BITMAP_SIZE(pgb->sizlBitmap.cx,
                                pgb->sizlBitmap.cy,
                                pfont->jBpp);
@@ -472,7 +515,8 @@
     PATHOBJ *ppo,
     ULONG cjSize)
 {
-
+    WARN("FtfdQueryGlyphOutline is unimplemented\n");
+    __debugbreak();
 }
 
 BOOL
@@ -507,6 +551,7 @@
     ULONG cjSize)
 {
     PFTFD_FONT pfont = FtfdGetFontInstance(pfo);
+    ULONG cx, cy;
 
     //TRACE("FtfdQueryFontData, iMode=%ld, hg=%lx, pgd=%p, pv=%p, 
cjSize=%ld\n",
     //      iMode, hg, pgd, pv, cjSize);
@@ -528,9 +573,11 @@
                 FtfdQueryGlyphBits(pfo, hg, pv, cjSize);
             }
 
-            /* Return the size for a 1bpp bitmap */
-            return GLYPHBITS_SIZE(pfont->ftface->glyph->bitmap.width,
-                                  pfont->ftface->glyph->bitmap.rows,
+            /* Return the size for a bitmap at least 1x1 pixels */
+            cx = pfont->ftface->glyph->bitmap.width;
+            cy = pfont->ftface->glyph->bitmap.rows;
+            return GLYPHBITS_SIZE(cx > 0 ? cx : 1,
+                                  cy > 0 ? cy : 1,
                                   pfont->jBpp);
 
         case QFD_GLYPHANDOUTLINE:


Reply via email to