Author: tkreuzer
Date: Mon May 9 19:54:07 2011
New Revision: 51660
URL:
http://svn.reactos.org/svn/reactos?rev=51660&view=rev
Log:
[GDI FONT DRIVER]
- Implement retrieving kerning pairs. since the freetype suport for kerning is
verylimited, it is done completely without freetype suport, by usig the TrueType
'kern' table.
For some unknown reason Windows likes to have the kerning pairs as WCHARs instead of glyph
handles, as they are provided. This is quite bad, as in theory there could be multiple
mappings from WCHARs to the same glyph. But this should probably almost never happen in
combination with kerning, so we use a short path and simply translate the glyph indices
into WCHARs as if it was unambiguous. Code is completely untested due to the lack of a
font with kerning data.
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/tttables.c
branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/tttables.h
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] Mon May
9 19:54:07 2011
@@ -263,8 +263,18 @@
ULONG i, cRuns, cjSize;
HGLYPH * phglyphs;
WCHAR wcCurrent, wcPrev;
+ PWCHAR pwcReverseTable;
TRACE("FtfdInitGlyphSet()\n");
+
+ /* Allocate an array of WCHARs */
+ pwcReverseTable = EngAllocMem(0, pface->ftface->num_glyphs, 'dftF');
+ if (!pwcReverseTable)
+ {
+ WARN("EngAllocMem() failed.\n");
+ return NULL;
+ }
+
/* Calculate FD_GLYPHSET size (incl. HGLYPH array!) */
cjSize = FIELD_OFFSET(FD_GLYPHSET, awcrun)
@@ -292,6 +302,9 @@
wcPrev = wcCurrent = (WCHAR)FT_Get_First_Char(ftface, &index);
for (i = 0, cRuns = 0; i < pface->cMappings && index; i++)
{
+ /* Create an entry in the reverse lookup table */
+ pwcReverseTable[index] = wcCurrent;
+
/* Use index as glyph handle */
phglyphs[i] = (HGLYPH)index;
@@ -317,15 +330,10 @@
TRACE("Done with font tree, %d runs\n", pGlyphSet->cRuns);
pface->pGlyphSet = pGlyphSet;
+ pface->pwcReverseTable = pwcReverseTable;
return pGlyphSet;
}
-VOID
-FtfdInitKerningPairs(
- PFTFD_FACE pface)
-{
- //WARN("unimplemented\n");
-}
static
ULONG
@@ -633,7 +641,7 @@
return NULL;
}
- /* get pointer to the requested face */
+ /* Get pointer to the requested face */
pface = pfile->apface[iFace - 1];
switch (iMode)
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] Mon May
9 19:54:07 2011
@@ -17,6 +17,7 @@
#include FT_TYPE1_TABLES_H
#include FT_MULTIPLE_MASTERS_H
#include FT_TRIGONOMETRY_H
+
extern FT_Library gftlibrary;
@@ -92,6 +93,7 @@
ULONG cGlyphs;
ULONG cMappings;
ULONG cRuns;
+ PWCHAR pwcReverseTable;
FD_GLYPHSET *pGlyphSet;
FD_KERNINGPAIR *pKerningPairs;
FTFD_IFIMETRICS ifiex;
@@ -329,3 +331,8 @@
FtfdGetWinMetrics(
PFTFD_FACE pface,
PIFIMETRICS pifi);
+
+VOID
+NTAPI
+FtfdInitKerningPairs(
+ PFTFD_FACE pface);
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/tttables.c
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers…
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/tttables.c [iso-8859-1]
(original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/tttables.c [iso-8859-1] Mon
May 9 19:54:07 2011
@@ -315,7 +315,6 @@
PTT_OS2_DATA pOs2;
/* Get the OS/2 table for the face */
- // FIXME: get the right table for the face, when multiple faces
pOs2 = FtfdFindTrueTypeTable(pvView, pfile->cjView, pface->iFace,
'2/SO', NULL);
if (!pOs2)
{
@@ -364,6 +363,133 @@
return TRUE;
}
+ULONG
+NTAPI
+FtfdGetNumberOfKerningPairs(
+ PFTFD_FACE pface)
+{
+ PFTFD_FILE pfile = pface->pfile;
+ PTT_KERNING_TABLE pKerning;
+ PTT_KERNING_SUBTABLE pSubTable;
+ ULONG i, nPairs = 0;
+
+__debugbreak();
+
+ /* Get the kern table for the face */
+ pKerning = FtfdFindTrueTypeTable(pfile->pvView,
+ pfile->cjView,
+ pface->iFace,
+ 'nrek',
+ NULL);
+ if (!pKerning)
+ {
+ WARN("Couldn't find kerning table\n");
+ return 0;
+ }
+
+ if (pKerning->usVersion != 0)
+ {
+ WARN("Found unknown version %lx\n", pKerning->usVersion);
+ return 0;
+ }
+
+ /* Start with the first subtable */
+ pSubTable = &pKerning->subtable;
+
+ /* Loop all subtables */
+ for (i = 0; i < pKerning->nTables; i++)
+ {
+ nPairs += GETW(&pSubTable->format0.nPairs);
+ pSubTable = (PVOID)((PCHAR)pSubTable + pSubTable->usLength);
+ }
+
+ TRACE("Got %ld kerning pairs\n", nPairs);
+ return nPairs;
+}
+
+VOID
+NTAPI
+FtfdInitKerningPairs(
+ PFTFD_FACE pface)
+{
+ PFTFD_FILE pfile = pface->pfile;
+ PTT_KERNING_TABLE pKernTable;
+ PTT_KERNING_SUBTABLE pSubTable;
+ ULONG i, j, cPairs = 0;
+ FD_KERNINGPAIR *pKernPair;
+ HGLYPH hgLeft, hgRight;
+
+__debugbreak();
+
+ /* Get the kern table for the face */
+ pKernTable = FtfdFindTrueTypeTable(pfile->pvView,
+ pfile->cjView,
+ pface->iFace,
+ 'nrek',
+ NULL);
+
+ if (!pKernTable || pKernTable->usVersion != 0)
+ {
+ TRACE("Couldn't find kerning table\n");
+ return;
+ }
+
+ // FIXME: do an overflow check
+ /* Loop all subtables */
+ pSubTable = &pKernTable->subtable;
+ for (i = 0; i < pKernTable->nTables; i++)
+ {
+ /* Only type 0 is interesting */
+ if (GETW(&pSubTable->usVersion) == 0)
+ cPairs += GETW(&pSubTable->format0.nPairs);
+ }
+
+ if (cPairs == 0)
+ {
+ return;
+ }
+
+ /* Allocate an FD_KERNINGPAIR array */
+ pKernPair = EngAllocMem(0, (cPairs + 1) * sizeof(FD_KERNINGPAIR), '1234');
+ pface->pKerningPairs = pKernPair;
+ if (!pKernPair)
+ {
+ WARN("EngAllocMem failed\n");
+ return;
+ }
+
+ /* Loop all subtables again */
+ pSubTable = &pKernTable->subtable;
+ for (i = 0; i < pKernTable->nTables; i++)
+ {
+ /* Only type 0 is interesting */
+ if (GETW(&pSubTable->usVersion) != 0) continue;
+
+ /* Loop all kern pairs in the table */
+ for (j = 0; j < GETW(&pSubTable->format0.nPairs); j++)
+ {
+ /* Get the glyph handles for the kerning */
+ hgLeft = GETW(&pSubTable->format0.akernpair[j].usLeft);
+ hgRight = GETW(&pSubTable->format0.akernpair[j].usRight);
+
+ /* Windows wants WCHARs, convert them */
+ pKernPair->wcFirst = pface->pwcReverseTable[hgLeft];
+ pKernPair->wcSecond = pface->pwcReverseTable[hgLeft];
+ pKernPair->fwdKern =
GETW(&pSubTable->format0.akernpair[j].fwdValue);
+ pKernPair++;
+ }
+
+ /* Go to next subtable */
+ pSubTable = (PVOID)((PCHAR)pSubTable + pSubTable->usLength);
+ }
+
+ /* Zero terminate last FD_KERNINGPAIR entry */
+ pKernPair->wcFirst = 0;
+ pKernPair->wcSecond = 0;
+ pKernPair->fwdKern = 0;
+
+ pface->ifiex.ifi.cKerningPairs = cPairs;
+}
/** Public Interface **********************************************************/
Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/tttables.h
URL:
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers…
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/tttables.h [iso-8859-1]
(original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/tttables.h [iso-8859-1] Mon
May 9 19:54:07 2011
@@ -14,6 +14,8 @@
return (((ULONG)pj[0]) << 24) | (((ULONG)pj[1]) << 16) |
(((ULONG)pj[2]) << 8) | ((ULONG)pj[3]);
}
+
+#include <pshpack1.h>
typedef struct _TT_COLLECTION
{
@@ -43,7 +45,6 @@
} TT_FILE_HEADER, *PTT_FILE_HEADER;
-#include <pshpack1.h>
typedef struct _TT_OS2_DATA
{
USHORT version; // 0x0004
@@ -92,4 +93,38 @@
USHORT usBreakChar;
USHORT usMaxContext;
} TT_OS2_DATA, *PTT_OS2_DATA;
+
+typedef struct _TT_KERNPAIR
+{
+ USHORT usLeft;
+ USHORT usRight;
+ FWORD fwdValue;
+} TT_KERNPAIR, *PTT_KERNPAIR;
+
+typedef struct _TT_KERNING_FORMAT_0
+{
+ USHORT nPairs;
+ USHORT usSearchRange;
+ USHORT usEntrySelector;
+ USHORT usRangeShift;
+ TT_KERNPAIR akernpair[1];
+} TT_KERNING_FORMAT_0, *PTT_KERNING_FORMAT_0;
+
+typedef struct _TT_KERNING_SUBTABLE
+{
+ USHORT usVersion;
+ USHORT usLength;
+ USHORT usCoverage;
+ ////
+ TT_KERNING_FORMAT_0 format0;
+} TT_KERNING_SUBTABLE, *PTT_KERNING_SUBTABLE;
+
+typedef struct _TT_KERNING_TABLE
+{
+ USHORT usVersion;
+ USHORT nTables;
+ ////
+ TT_KERNING_SUBTABLE subtable;
+} TT_KERNING_TABLE, *PTT_KERNING_TABLE;
+
#include <poppack.h>