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…
==============================================================================
--- 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…
==============================================================================
--- 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: