Author: tkreuzer Date: Fri May 6 21:57:42 2011 New Revision: 51613
URL: http://svn.reactos.org/svn/reactos?rev=51613&view=rev Log: [GDI FONT DRIVER] - Fix values returned in FtfdQueryAdvanceWidths - Convert bitmap handling to 4bpp (need to investigate why my driver is assumed to return a 4bpp bitmap, while the original driver seems to provide a 1bpp one) - Fix values in FtfdQueryGlyphData - Implement FtfdQueryGlyphBits, returning a 4bpp bitmap - The driver is now capable of basically rendering fonts in 4bpp
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c 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/font.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers/... ============================================================================== --- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c [iso-8859-1] (original) +++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c [iso-8859-1] Fri May 6 21:57:42 2011 @@ -725,7 +725,7 @@ pjTable = OtfFindTable(pfile->pvView, pfile->cjView, ulTag, &cjTable); if (!pjTable) { - DbgPrint("Couldn't find the requested table\n"); + DbgPrint("Couldn't find table '%.4s'\n", (char*)&ulTag); return FD_ERROR; } }
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] Fri May 6 21:57:42 2011 @@ -104,6 +104,7 @@ FT_Face ftface; FD_XFORM fdxQuantized; FTFD_DEVICEMETRICS metrics; + ULONG xScale; HGLYPH hgSelected; ULONG cjSelected; } FTFD_FONT, *PFTFD_FONT;
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] Fri May 6 21:57:42 2011 @@ -11,8 +11,11 @@
#define FLOATL_1 0x3f800000
+#define BITMAP_SIZE(cx, cy, bpp) \ + ((((((cx * bpp) + 7) >> 3) * cy) + 3) & ~3) + #define GLYPHBITS_SIZE(cx, cy, bpp) \ - (FIELD_OFFSET(GLYPHBITS, aj) + ((((cx * bpp) + 31) >> 5) * cy * 4)) + (FIELD_OFFSET(GLYPHBITS, aj) + BITMAP_SIZE(cx, cy, bpp))
PFTFD_FONT NTAPI @@ -62,6 +65,7 @@
pfont->ftface = ftface;
+ /* Get the XFORMOBJ from the font */ pxo = FONTOBJ_pxoGetXform(pfo); if (!pxo) { @@ -83,7 +87,7 @@ __debugbreak(); // FIXME: need to calculate scaling
- /* initialize a matrix */ + /* Initialize a matrix */ ftmatrix.xx = 0x10000 * pface->ifiex.ifi.fwdUnitsPerEm * 72 / pfo->sizLogResPpi.cx; ftmatrix.xy = 0x00000000; @@ -163,7 +167,7 @@ if (pmetrics->ptlULThickness.y <= 0) pmetrics->ptlULThickness.y = 1; if (pmetrics->ptlSOThickness.y <= 0) pmetrics->ptlSOThickness.y = 1;
-DbgPrint("Created font with %ld (%ld)\n", yScale, yScale/64); +DbgPrint("Created font with %ld (%ld)\n", yScale, (yScale+32)/64); //__debugbreak();
/* Set the pvProducer member of the fontobj */ @@ -197,7 +201,6 @@ PFTFD_FONT pfont = FtfdGetFontInstance(pfo); PFTFD_FACE pface = pfont->pface; FT_Face ftface = pfont->ftface; - ULONG cjMaxWidth, cjMaxBitmapSize; XFORMOBJ *pxo;
DbgPrint("FtfdQueryMaxExtents\n"); @@ -232,7 +235,7 @@ else pfddm->lD = 0;
- /* Copy the values from the font structure */ + /* Copy some values from the font structure */ pfddm->fxMaxAscender = pfont->metrics.ptfxMaxAscender.y; pfddm->fxMaxDescender = pfont->metrics.ptfxMaxDescender.y; pfddm->ptlUnderline1 = pfont->metrics.ptlUnderline1; @@ -242,14 +245,8 @@ pfddm->cxMax = pfont->metrics.sizlMax.cx; pfddm->cyMax = pfont->metrics.sizlMax.cy;
- /* 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; + pfddm->cjGlyphMax = GLYPHBITS_SIZE(pfddm->cxMax, pfddm->cyMax, 4);
/* Copy the quantized matrix from the font structure */ pfddm->fdxQuantized = pfont->fdxQuantized; @@ -264,7 +261,7 @@ pfddm->lMinD = 0; }
-__debugbreak(); +//__debugbreak();
/* Return the size of the structure */ return sizeof(FD_DEVICEMETRICS); @@ -315,8 +312,8 @@ if (1 /* layout horizontal */) { pgd->fxA = ftglyph->metrics.horiBearingX; - pgd->fxAB = pgd->fxA + ftglyph->metrics.width; - pgd->fxD = ftglyph->metrics.horiAdvance; + pgd->fxAB = pgd->fxA + ftglyph->metrics.width / 4; + pgd->fxD = ftglyph->metrics.horiAdvance / 4; } else { @@ -325,10 +322,10 @@ pgd->fxD = ftglyph->metrics.vertAdvance; }
- pgd->fxInkTop = 0; pgd->fxInkBottom = 0; + pgd->fxInkTop = pgd->fxInkBottom + (ftglyph->bitmap.rows << 4); pgd->rclInk.left = ftglyph->bitmap_left; - pgd->rclInk.top = ftglyph->bitmap_top; + pgd->rclInk.top = -ftglyph->bitmap_top; pgd->rclInk.right = pgd->rclInk.left + ftglyph->bitmap.width; pgd->rclInk.bottom = pgd->rclInk.top + ftglyph->bitmap.rows;
@@ -336,13 +333,52 @@ if (ftglyph->bitmap.width == 0) pgd->rclInk.right++; if (ftglyph->bitmap.rows == 0) pgd->rclInk.bottom++;
- pgd->ptqD.x.LowPart = 0; - pgd->ptqD.x.HighPart = pgd->fxD; - pgd->ptqD.y.LowPart = 0; + pgd->ptqD.x.LowPart = 0x000000fd; + pgd->ptqD.x.HighPart = 0; + pgd->ptqD.y.LowPart = 0x000000a0; // 0x000000a0 pgd->ptqD.y.HighPart = 0; //pgd->ptqD.x.QuadPart = 0; //pgd->ptqD.y.QuadPart = 0; - +//__debugbreak(); +} + +VOID +FtfdCopyBitmap( + BYTE *pjDest, + FT_Bitmap *ftbitmap) +{ + ULONG ulRows, ulDstDelta, ulSrcDelta; + PBYTE pjDstLine, pjSrcLine; + + + pjDstLine = pjDest; + ulDstDelta = (ftbitmap->width*4 + 7) / 8; + + pjSrcLine = ftbitmap->buffer; + ulSrcDelta = abs(ftbitmap->pitch); + + ulRows = ftbitmap->rows; + while (ulRows--) + { + ULONG ulWidth = ulDstDelta; + BYTE j, *pjSrc; + + pjSrc = pjSrcLine; + while (ulWidth--) + { + /* Get the 1st pixel */ + j = (*pjSrc++) & 0xf0; + + /* Get the 2nd pixel */ + if (ulWidth > 0 || !(ftbitmap->width & 1)) + j |= (*pjSrc++) >> 4; + *pjDstLine++ = j; + } + + /* Go to the next line */ + //pjDstLine += ulDstDelta; + pjSrcLine += ulSrcDelta; + } }
VOID @@ -354,13 +390,30 @@ { PFTFD_FONT pfont = pfo->pvProducer; FT_GlyphSlot ftglyph = pfont->ftface->glyph; - - pgb->ptlOrigin.x = 0; - pgb->ptlOrigin.y = 0; + ULONG cjBitmapSize; + + pgb->ptlOrigin.x = ftglyph->bitmap_left; + pgb->ptlOrigin.y = - ftglyph->bitmap_top; pgb->sizlBitmap.cx = ftglyph->bitmap.width; pgb->sizlBitmap.cy = ftglyph->bitmap.rows;
- DbgPrint("QueryGlyphBits for hg=%lx, cjSize=%ld\n", hg, cjSize); + cjBitmapSize = BITMAP_SIZE(pgb->sizlBitmap.cx, pgb->sizlBitmap.cy, 4); + if (cjBitmapSize + FIELD_OFFSET(GLYPHBITS, aj) > cjSize) + { + DbgPrint("ERROR: buffer too small, got %ld, need %ld\n", + cjSize, cjBitmapSize + FIELD_OFFSET(GLYPHBITS, aj)); + __debugbreak(); + return; + } + + /* Copy the bitmap */ + FtfdCopyBitmap(pgb->aj, &ftglyph->bitmap); + + //RtlCopyMemory(pgb->aj, ftglyph->bitmap.buffer, cjBitmapSize); + + DbgPrint("QueryGlyphBits hg=%lx, (%ld,%ld) cjSize=%ld, need %ld\n", + hg, pgb->sizlBitmap.cx, pgb->sizlBitmap.cy, cjSize, + GLYPHBITS_SIZE(pgb->sizlBitmap.cx, pgb->sizlBitmap.cy, 4));
}
@@ -372,6 +425,22 @@ ULONG cjSize) {
+} + +BOOL +FtRenderGlyphBitmap( + PFTFD_FONT pfont) +{ + FT_Error fterror; + + fterror = FT_Render_Glyph(pfont->ftface->glyph, FT_RENDER_MODE_NORMAL); + if (fterror) + { + DbgPrint("cound't render glyph\n"); + return FALSE; + } + + return TRUE; }
/** Public Interface **********************************************************/ @@ -400,6 +469,8 @@ /* Load the requested glyph */ if (!FtfdLoadGlyph(pfont, hg, 0)) return FD_ERROR;
+ if (!FtRenderGlyphBitmap(pfont)) return FD_ERROR; + if (pgd) FtfdQueryGlyphData(pfo, hg, pgd, pv);
@@ -411,7 +482,7 @@ /* Return the size for a 1bpp bitmap */ return GLYPHBITS_SIZE(pfont->ftface->glyph->bitmap.width, pfont->ftface->glyph->bitmap.rows, - 1); + 4);
case QFD_GLYPHANDOUTLINE: DbgPrint("QFD_GLYPHANDOUTLINE\n"); @@ -446,7 +517,7 @@ DbgPrint("QFD_TT_GRAY8_BITMAP\n"); break; default: - DbgPrint("Impossible iMode value: %lx\n", iMode); + DbgPrint("ERROR: Invalid iMode value: %lx\n", iMode); EngSetLastError(ERROR_INVALID_PARAMETER); return FD_ERROR; } @@ -517,8 +588,9 @@ } else { - //DbgPrint("Got advance width: hg=%lx, adv=%d\n", phg[i], advance >> 12); - pusWidths[i] = (USHORT)advance >> 12; + /* Transform from 16.16 points to 28.4 pixels */ + pusWidths[i] = (USHORT)((advance * 72 / pfo->sizLogResPpi.cx) >> 12); + //DbgPrint("Got advance width: hg=%lx, adv=%lx->%ld\n", phg[i], advance, pt.x); } }