Author: tkreuzer Date: Sun May 22 21:26:22 2011 New Revision: 51853
URL: http://svn.reactos.org/svn/reactos?rev=51853&view=rev Log: [GDI FONT DRIVER] - Calculate bounding box in fixpoints and round up/down - Make sure the bitmaps don't exceed the previously calculated maximum size. Webdings has suchs glyphs for unknown reasons. - Handle 0 pixel bitmaps by only zeroing the 1st byte of the destination bitmap - Pass ponter to GLYPHBITS structure to FtfdCopyBits and use its size instead of freetype's glyph size
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/copybits.c branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/ftfd.h branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/glyph.c branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/todo.txt
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/copybits.c URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers/... ============================================================================== --- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/copybits.c [iso-8859-1] (original) +++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/copybits.c [iso-8859-1] Sun May 22 21:26:22 2011 @@ -11,19 +11,19 @@ static VOID FtfdCopyBits_S1D1( - BYTE *pjDest, + GLYPHBITS *pgb, FT_Bitmap *ftbitmap) { ULONG ulRows, ulDstDelta, ulSrcDelta; PBYTE pjDstLine, pjSrcLine;
- pjDstLine = pjDest; - ulDstDelta = (ftbitmap->width + 7) / 8; + pjDstLine = pgb->aj; + ulDstDelta = (pgb->sizlBitmap.cx + 7) / 8;
pjSrcLine = ftbitmap->buffer; ulSrcDelta = abs(ftbitmap->pitch);
- ulRows = ftbitmap->rows; + ulRows = pgb->sizlBitmap.cy; while (ulRows--) { /* Copy one line */ @@ -38,7 +38,7 @@ static VOID FtfdCopyBits_S8D1( - BYTE *pjDest, + GLYPHBITS *pgb, FT_Bitmap *ftbitmap) { __debugbreak(); @@ -48,7 +48,7 @@ static VOID FtfdCopyBits_S1D4( - BYTE *pjDest, + GLYPHBITS *pgb, FT_Bitmap *ftbitmap) { ULONG ulRows, ulSrcDelta; @@ -56,15 +56,15 @@
//__debugbreak();
- pjDstLine = pjDest; + pjDstLine = pgb->aj;
pjSrcLine = ftbitmap->buffer; ulSrcDelta = abs(ftbitmap->pitch);
- ulRows = ftbitmap->rows; + ulRows = pgb->sizlBitmap.cy; while (ulRows--) { - ULONG ulWidth = ftbitmap->width; + ULONG ulWidth = pgb->sizlBitmap.cx; BYTE j, *pjSrc; static USHORT ausExpand[] = {0x0000, 0x000f, 0x00f0, 0x00ff, 0x0f00, 0x0f0f, 0x0ff0, 0x0fff, @@ -102,19 +102,19 @@ static VOID FtfdCopyBits_S8D4( - BYTE *pjDest, + GLYPHBITS *pgb, FT_Bitmap *ftbitmap) { ULONG ulRows, ulDstDelta, ulSrcDelta; PBYTE pjDstLine, pjSrcLine;
- pjDstLine = pjDest; - ulDstDelta = (ftbitmap->width*4 + 7) / 8; + pjDstLine = pgb->aj; + ulDstDelta = (pgb->sizlBitmap.cx*4 + 7) / 8;
pjSrcLine = ftbitmap->buffer; ulSrcDelta = abs(ftbitmap->pitch);
- ulRows = ftbitmap->rows; + ulRows = pgb->sizlBitmap.cy; while (ulRows--) { ULONG ulWidth = ulDstDelta; @@ -127,7 +127,7 @@ j = (*pjSrc++) & 0xf0;
/* Get the 2nd pixel */ - if (ulWidth > 0 || !(ftbitmap->width & 1)) + if (ulWidth > 0 || !(pgb->sizlBitmap.cx & 1)) j |= (*pjSrc++) >> 4; *pjDstLine++ = j; } @@ -137,24 +137,30 @@ } }
-void +VOID NTAPI FtfdCopyBits( BYTE jBppDst, - BYTE *pjDest, + GLYPHBITS *pgb, FT_Bitmap *ftbitmap) { + /* handle empty bitmaps */ + if (ftbitmap->width == 0 || ftbitmap->rows == 0) + { + pgb->aj[0] = 0; + return; + }
if (jBppDst == 1) { if (ftbitmap->pixel_mode == FT_PIXEL_MODE_MONO) { - FtfdCopyBits_S1D1(pjDest, ftbitmap); + FtfdCopyBits_S1D1(pgb, ftbitmap); } else if (ftbitmap->pixel_mode == FT_PIXEL_MODE_GRAY && ftbitmap->num_grays == 256) { - FtfdCopyBits_S8D1(pjDest, ftbitmap); + FtfdCopyBits_S8D1(pgb, ftbitmap); } else { @@ -167,12 +173,12 @@ { if (ftbitmap->pixel_mode == FT_PIXEL_MODE_MONO) { - FtfdCopyBits_S1D4(pjDest, ftbitmap); + FtfdCopyBits_S1D4(pgb, ftbitmap); } else if (ftbitmap->pixel_mode == FT_PIXEL_MODE_GRAY && ftbitmap->num_grays == 256) { - FtfdCopyBits_S8D4(pjDest, ftbitmap); + FtfdCopyBits_S8D4(pgb, ftbitmap); } else {
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 21:26:22 2011 @@ -125,7 +125,7 @@ POINTL ptlStrikeout; POINTL ptlULThickness; POINTL ptlSOThickness; - POINTL aptlBBox[4]; + POINTL aptfxBBox[4]; }; }; FIX fxMaxAscender; @@ -147,7 +147,7 @@ FT_Face ftface; FD_XFORM fdxQuantized; FTFD_DEVICEMETRICS metrics; - RECTL rclBBox; + RECTL rcfxBBox; SIZEL sizlMax; POINTEF ptefBase; POINTEF ptefSide; @@ -349,5 +349,5 @@ NTAPI FtfdCopyBits( BYTE jBppDst, - BYTE *pjDest, + GLYPHBITS *pgb, FT_Bitmap *ftbitmap);
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 21:26:22 2011 @@ -237,14 +237,14 @@ pmetrics->ptlULThickness.y = pface->ifiex.ifi.fwdUnderscoreSize; pmetrics->ptlSOThickness.x = 0; pmetrics->ptlSOThickness.y = pface->ifiex.ifi.fwdStrikeoutSize; - 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; + pmetrics->aptfxBBox[0].x = ftface->bbox.xMin << 4; + pmetrics->aptfxBBox[0].y = ftface->bbox.yMin << 4; + pmetrics->aptfxBBox[1].x = ftface->bbox.xMax << 4; + pmetrics->aptfxBBox[1].y = ftface->bbox.yMin << 4; + pmetrics->aptfxBBox[2].x = ftface->bbox.xMax << 4; + pmetrics->aptfxBBox[2].y = ftface->bbox.yMax << 4; + pmetrics->aptfxBBox[3].x = ftface->bbox.xMin << 4; + pmetrics->aptfxBBox[3].y = ftface->bbox.yMax << 4;
/* Transform all coordinates into device space */ if (!XFORMOBJ_bApplyXform(pxo, XF_LTOL, 8, pmetrics->aptl, pmetrics->aptl)) @@ -254,23 +254,29 @@ 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; + /* Extract the bounding box in FIX device coordinates */ + pfont->rcfxBBox.left = min(pmetrics->aptfxBBox[0].x, pmetrics->aptfxBBox[1].x); + pfont->rcfxBBox.left = min(pfont->rcfxBBox.left, pmetrics->aptfxBBox[2].x); + pfont->rcfxBBox.left = min(pfont->rcfxBBox.left, pmetrics->aptfxBBox[3].x); + pfont->rcfxBBox.right = max(pmetrics->aptfxBBox[0].x, pmetrics->aptfxBBox[1].x); + pfont->rcfxBBox.right = max(pfont->rcfxBBox.right, pmetrics->aptfxBBox[2].x); + pfont->rcfxBBox.right = max(pfont->rcfxBBox.right, pmetrics->aptfxBBox[3].x); + pfont->rcfxBBox.top = min(pmetrics->aptfxBBox[0].y, pmetrics->aptfxBBox[1].y); + pfont->rcfxBBox.top = min(pfont->rcfxBBox.top, pmetrics->aptfxBBox[2].y); + pfont->rcfxBBox.top = min(pfont->rcfxBBox.top, pmetrics->aptfxBBox[3].y); + pfont->rcfxBBox.bottom = max(pmetrics->aptfxBBox[0].y, pmetrics->aptfxBBox[1].y); + pfont->rcfxBBox.bottom = max(pfont->rcfxBBox.bottom, pmetrics->aptfxBBox[2].y); + pfont->rcfxBBox.bottom = max(pfont->rcfxBBox.bottom, pmetrics->aptfxBBox[3].y); + + /* Round the bounding box margings to pixels */ + pfont->rcfxBBox.left = pfont->rcfxBBox.left & ~0xf; + pfont->rcfxBBox.top = pfont->rcfxBBox.top & ~0xf; + pfont->rcfxBBox.right = (pfont->rcfxBBox.right + 0xf) & ~0xf; + pfont->rcfxBBox.bottom = (pfont->rcfxBBox.bottom + 0xf) & ~0xf; + + /* Calculate maximum extents in pixels */ + pfont->sizlMax.cx = (pfont->rcfxBBox.right - pfont->rcfxBBox.left) >> 4; + pfont->sizlMax.cy = (pfont->rcfxBBox.bottom - pfont->rcfxBBox.top) >> 4;
/* Fixup some minimum values */ if (pmetrics->ptlULThickness.y <= 0) pmetrics->ptlULThickness.y = 1; @@ -309,7 +315,6 @@ PFTFD_FONT pfont = FtfdGetFontInstance(pfo); PFTFD_FACE pface = pfont->pface; FT_Face ftface = pfont->ftface; - XFORMOBJ *pxo;
TRACE("FtfdQueryMaxExtents\n");
@@ -322,9 +327,6 @@ WARN("cjSize = %ld\n", cjSize); return FD_ERROR; } - - /* Get the XFORMOBJ */ - pxo = FONTOBJ_pxoGetXform(pfo);
/* Accelerator flags (ignored atm) */ pfddm->flRealizedType = 0; @@ -416,6 +418,7 @@ { PFTFD_FONT pfont = pfo->pvProducer; FT_GlyphSlot ftglyph = pfont->ftface->glyph; + SIZEL sizlBitmap;
pgd->gdf.pgb = pvGlyphData; pgd->hg = hg; @@ -436,15 +439,23 @@ /* D is the glyph advance width */ pgd->fxD = ftglyph->advance.x / 4; // FIXME: should be projected on the x-axis
+ /* Get the bitnmap size */ + sizlBitmap.cx = ftglyph->bitmap.width; + sizlBitmap.cy = ftglyph->bitmap.rows; + + /* Make the bitmap at least 1x1 pixel large */ + if (sizlBitmap.cx == 0) sizlBitmap.cx++; + if (sizlBitmap.cy == 0) sizlBitmap.cy++; + + /* Don't let the bitmap be larger than the maximum */ + sizlBitmap.cx = min(sizlBitmap.cx, pfont->sizlMax.cx); + sizlBitmap.cy = min(sizlBitmap.cy, pfont->sizlMax.cy); + /* This is the box in which the bitmap fits */ pgd->rclInk.left = ftglyph->bitmap_left; pgd->rclInk.top = -ftglyph->bitmap_top; - 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++; + pgd->rclInk.right = pgd->rclInk.left + sizlBitmap.cx; + pgd->rclInk.bottom = pgd->rclInk.top + sizlBitmap.cy;
/* FIX representation of bitmap top and bottom */ pgd->fxInkBottom = (-pgd->rclInk.bottom) << 4; @@ -456,12 +467,6 @@ 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(); }
@@ -485,13 +490,9 @@ 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; - } + /* Don't let the bitmap be larger than the maximum */ + pgb->sizlBitmap.cx = min(pgb->sizlBitmap.cx, pfont->sizlMax.cx); + pgb->sizlBitmap.cy = min(pgb->sizlBitmap.cy, pfont->sizlMax.cy);
cjBitmapSize = BITMAP_SIZE(pgb->sizlBitmap.cx, pgb->sizlBitmap.cy, @@ -505,7 +506,7 @@ }
/* Copy the bitmap */ - FtfdCopyBits(pfont->jBpp, pgb->aj, &ftglyph->bitmap); + FtfdCopyBits(pfont->jBpp, pgb, &ftglyph->bitmap);
//TRACE("QueryGlyphBits hg=%lx, (%ld,%ld) cjSize=%ld, need %ld\n", // hg, pgb->sizlBitmap.cx, pgb->sizlBitmap.cy, cjSize,
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/todo.txt URL: http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers/... ============================================================================== --- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/todo.txt [iso-8859-1] (original) +++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/todo.txt [iso-8859-1] Sun May 22 21:26:22 2011 @@ -7,8 +7,8 @@ - FtfdDisablePDEV: 100% done - FtfdEscape: unimplemented, probably unneccessary - FtfdLoadFontFile: 95% done -- FtfdQueryFont: 70% done, depends on FtfdInitIfiMetrics -- FtfdQueryFontTree: 70% done, depends on FtfdInitGlyphSet and FtfdInitKerningPairs +- FtfdQueryFont: 80% done, depends on FtfdInitIfiMetrics +- FtfdQueryFontTree: 90% done, depends on FtfdInitGlyphSet and FtfdInitKerningPairs - FtfdUnloadFontFile: 100% done, depends on FtfdDestroyFace - FtfdQueryFontFile: 50% - implement QFF_DESCRIPTION, unimportant @@ -32,21 +32,18 @@ ------------------- - FtfdInitIfiMetrics: 80% done - handle other font types than TTF/OTF - - dpwszFamilyName, dpwszStyleName, dpwszFaceName: locale - - dpwszUniqueName: get from 'name' table + - localized dpwszFamilyName, dpwszStyleName, dpwszFaceName + - get dpwszUniqueName from 'name' table - dpFontSim: implement - - dpCharSets: implement - fwdMacLineGap: from hhea table - fwdMaxCharInc: check/fix - fwdCapHeight: check/fix - - fwdUnderscorePosition: fix - - chFirstChar, chLastChar, chDefaultChar, chBreakChar: fix - - wcDefaultChar, wcBreakChar: fix - ptlBaseline: fix - ptlCaret: use hhea table caretSlopeRun, caretSlopeRise - Put most important charset into slot 0
-- FtfdInitGlyphSet: 100% done +- FtfdInitGlyphSet: 90% done + - completely handle symbol and other charsets - FtfdInitKerningPairs: 90% done - Should we do complete glyph -> unicode expansion?
@@ -55,6 +52,7 @@ - FtfdCreateFontInstance: 95% - FtfdGetFontInstance: 100% done - FtfdQueryMaxExtents: 90% done + - check lNonLinear* and lMin*
- FtfdLoadGlyph: 80% done - hande accelerator flags for bitmap / outline @@ -62,17 +60,20 @@ - handle vertical layout - handle ptqD for rotation / skewing
-- FtfdQueryGlyphBits: 90% depends on FtfdCopyBitmap4Bpp and FtfdCopyBitmap1Bpp +- FtfdQueryGlyphBits: 90% depends on FtfdCopyBits
- FtfdQueryGlyphOutline: unimplemented -- FtfdCopyBitmap4Bpp: 90 % +- FtfdCopyBits: 70 % depends on FtfdCopyBits_S1D1, FtfdCopyBits_S1D4, + FtfdCopyBits_S8D1, FtfdCopyBits_S8D4 + +- FtfdCopyBits_S1D1: 95 % + - Can we use full memcpy? +- FtfdCopyBits_S1D4: 100 % +- FtfdCopyBits_S8D1: unimpemented +- FtfdCopyBits_S8D4: 90% - add rounding - - Could need optimization -- FtfdCopyBitmap1Bpp: 90 % - - Can we use full memcpy?
When replacing the original ttf driver ----------------------------------------------- -- Horizontal metrics are broken -- Marlett symbols are wrong +- arrow symbol in startmenu is broken