Author: tkreuzer
Date: Thu May  5 15:01:51 2011
New Revision: 51589

URL: http://svn.reactos.org/svn/reactos?rev=51589&view=rev
Log:
[GDI FONT DRIVER]
- Fix size of the buffer returned in FtfdInitGlyphSet
- Fix counting of glyph runs
- Handle checksums in OTF/TTF tables
- Implement FtfdQueryTrueTypeTable
- Delete sprintf.c

Removed:
    branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/sprintf.c
Modified:
    branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/CMakeLists.txt
    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
    branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/opentype.c
    branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/todo.txt

Modified: 
branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/CMakeLists.txt
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/CMakeLists.txt?rev=51589&r1=51588&r2=51589&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/CMakeLists.txt 
[iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/CMakeLists.txt 
[iso-8859-1] Thu May  5 15:01:51 2011
@@ -5,7 +5,6 @@
 
 add_library(ftfd SHARED
     enable.c
-    file.c
     font.c
     glyph.c
     opentype.c

Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/font.c?rev=51589&r1=51588&r2=51589&view=diff
==============================================================================
--- 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] Thu May  5 15:01:51 2011
@@ -230,8 +230,9 @@
                            pifi->achVendId,
                            4);
 
+
     DbgPrint("Finished with the ifi: %p\n", pifi);
-    __debugbreak();
+    //__debugbreak();
 
     return TRUE;
 }
@@ -244,17 +245,19 @@
     FT_Face ftface = pface->ftface;
     FD_GLYPHSET *pGlyphSet;
     FT_UInt index;
-    ULONG i, j, cjSize;
+    ULONG i, cRuns, cjSize;
     HGLYPH * phglyphs;
     WCHAR wcCurrent, wcPrev;
 
     DbgPrint("FtfdInitGlyphSet()\n");
 
-    /* Calculate FD_GLYPHSET size */
-    cjSize = sizeof(FD_GLYPHSET) + (pface->cRuns - 1) * sizeof(WCRUN);
+    /* Calculate FD_GLYPHSET size (incl. HGLYPH array!) */
+    cjSize = FIELD_OFFSET(FD_GLYPHSET, awcrun)
+             + pface->cRuns * sizeof(WCRUN)
+             + pface->cMappings * sizeof(HGLYPH);
 
     /* Allocate the FD_GLYPHSET structure plus an array of HGLYPHs */
-    pGlyphSet = EngAllocMem(0, cjSize + pface->cMappings * sizeof(HGLYPH), 
TAG_GLYPHSET);
+    pGlyphSet = EngAllocMem(0, cjSize, TAG_GLYPHSET);
     if (!pGlyphSet)
     {
         DbgPrint("EngAllocMem() failed.\n");
@@ -272,7 +275,7 @@
 
     /* Loop through all character mappings */
     wcPrev = wcCurrent = (WCHAR)FT_Get_First_Char(ftface, &index);
-    for (i = 0, j = 0; i < pface->cMappings && index; i++)
+    for (i = 0, cRuns = 0; i < pface->cMappings && index; i++)
     {
         /* Use index as glyph handle */
         phglyphs[i] = (HGLYPH)index;
@@ -281,16 +284,16 @@
         if (wcCurrent == wcPrev + 1)
         {
             /* Append to current WCRUN */
-            pGlyphSet->awcrun[j].cGlyphs++;
+            pGlyphSet->awcrun[cRuns - 1].cGlyphs++;
         }
         else
         {
             /* Add a new WCRUN */
-            pGlyphSet->awcrun[j].wcLow = wcCurrent;
-            pGlyphSet->awcrun[j].cGlyphs = 1;
-            pGlyphSet->awcrun[j].phg = &phglyphs[i];
-            j++;
-            //DbgPrint("adding new run i=%ld, j=%ld, wc=%x\n", i, j, 
wcCurrent);
+            cRuns++;
+            pGlyphSet->awcrun[cRuns - 1].wcLow = wcCurrent;
+            pGlyphSet->awcrun[cRuns - 1].cGlyphs = 1;
+            pGlyphSet->awcrun[cRuns - 1].phg = &phglyphs[i];
+            //DbgPrint("adding new run i=%ld, cRuns=%ld, wc=%x\n", i, cRuns, 
wcCurrent);
         }
 
         /* Get the next charcode and index */
@@ -693,8 +696,61 @@
     PBYTE *ppjTable,
     ULONG *pcjTable)
 {
+    PFTFD_FILE pfile = (PFTFD_FILE)diFile;
+    PBYTE pjTable, pjData;
+    ULONG cjTable;
+
     DbgPrint("FtfdQueryTrueTypeTable\n");
     __debugbreak();
+
+    /* Check if this file supports TrueType tables */
+    if (pfile->ulFileFormat != FILEFMT_TTF &&
+        pfile->ulFileFormat != FILEFMT_OTF)
+    {
+        DbgPrint("File format doesn't support true type tables\n");
+        return FD_ERROR;
+    }
+
+    /* Check if the whole file is requested */
+    if (ulTag == 0)
+    {
+        /* Requested the whole file */
+        pjTable = pfile->pvView;
+        cjTable = pfile->cjView;
+    }
+    else
+    {
+        /* Search for the table */
+        pjTable = OtfFindTable(pfile->pvView, pfile->cjView, ulTag, &cjTable);
+        if (!pjTable)
+        {
+            DbgPrint("Couldn't find the requested table\n");
+            return FD_ERROR;
+        }
+    }
+
+    // FIXME: handle ulFont
+
+    /* Check for overflow and if the offset and size fit into the view */
+    pjData = pjTable + dpStart;
+    if ( (pjData < pjTable) || (pjData + cjBuf < pjData) ||
+         (pjData + cjBuf > (PBYTE)pfile->pvView + pfile->cjView) )
+    {
+        DbgPrint("Overflow: dpStart=0x%lx, cjBuf=0x%lx\n", dpStart, cjBuf);
+        return FD_ERROR;
+    }
+
+    /* Check if we shall copy data */
+    if (pjBuf)
+    {
+        /* Copy the data to the buffer */
+        RtlCopyMemory(pjBuf, pjTable + dpStart, cjBuf);
+    }
+
+    /* Return requested pointers */
+    if (ppjTable) *ppjTable = pjTable;
+    if (pcjTable) *pcjTable = cjTable;
+
     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/video/font/ftfd/ftfd.h?rev=51589&r1=51588&r2=51589&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] Thu May  5 15:01:51 2011
@@ -262,3 +262,11 @@
 OtfGetIfiMetrics(
     PFTFD_FACE pface,
     PIFIMETRICS pifi);
+
+PVOID
+NTAPI
+OtfFindTable(
+    PVOID pvView,
+    ULONG cjView,
+    ULONG ulTag,
+    PULONG pulLength);

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=51589&r1=51588&r2=51589&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] Thu May  5 15:01:51 2011
@@ -46,10 +46,15 @@
     {
         /* Failure! */
         DbgPrint("Error creating face\n");
+        EngFreeMem(pfont);
         return NULL;
     }
 
+    pfont->ftface = ftface;
+
     pxo = FONTOBJ_pxoGetXform(pfo);
+
+    // divide into scaling and rotation / shearing
 
     fterror = FT_Set_Char_Size(ftface,
                                0,
@@ -66,7 +71,6 @@
     /* Set non-orthogonal transformation */
     // FT_Set_Transform
 
-    pfont->ftface = ftface;
 
     /* Set the pvProducer member of the fontobj */
     pfo->pvProducer = pfont;

Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/opentype.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/opentype.c?rev=51589&r1=51588&r2=51589&view=diff
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/opentype.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/opentype.c 
[iso-8859-1] Thu May  5 15:01:51 2011
@@ -9,6 +9,10 @@
 
 #include "ftfd.h"
 #include <freetype/t1tables.h>
+
+// FIXME: we can have unaligned memory access, use:
+#define GETW(px) = (((PUCHAR)px)[1] | ((PUCHAR)px)[0] << 8)
+#define GETD(px) = (GETW((PUCHAR)px + 2) | GETW(px) << 16)
 
 #define SWAPW(x) _byteswap_ushort(x)
 #define SWAPD(x) _byteswap_ulong(x)
@@ -51,7 +55,7 @@
     SHORT      ySuperscriptYOffset;
     SHORT      yStrikeoutSize;
     SHORT      yStrikeoutPosition;
-    union
+    union // 0x30
     {
         struct
         {
@@ -84,6 +88,19 @@
 } OTF_OS2_DATA, *POTF_OS2_DATA;
 #include <poppack.h>
 
+ULONG
+CalcTableChecksum(PVOID pvTable, ULONG cjTable)
+{
+    PULONG pul = pvTable, pulEnd;
+    ULONG ulCheckSum = 0L;
+
+    pulEnd = (PULONG)pvTable + (cjTable + 3) / sizeof(ULONG);
+
+    while (pul < pulEnd) ulCheckSum += SWAPD(*pul++);
+
+    return ulCheckSum;
+}
+
 BOOL
 OtfGetType1FontInfo(
     PFTFD_FACE pface,
@@ -118,7 +135,17 @@
     return TRUE;
 }
 
+/*! \name OtfFindTable
+ *  \brief Searches for a specific table in TrueType and OpenType font files
+ *  \param pvView - The address where the font file is mapped
+ *  \param vjView - Size of the mapped font file
+ *  \param ulTag - Identifier tag of the table to search
+ *  \param pulLength - Pointer to an ULONG that recieves the table length,
+ *                     Can be NULL;
+ *  \return Pointer to the table if successful, NULL if unsuccessful.
+ */
 PVOID
+NTAPI
 OtfFindTable(
     PVOID pvView,
     ULONG cjView,
@@ -126,7 +153,7 @@
     PULONG pulLength)
 {
     POTF_FILE_HEADER pFileHeader = pvView;
-    ULONG i, ulOffset, ulLength, ulNumTables;
+    ULONG i, ulOffset, ulLength, ulNumTables, ulCheckSum;
 
     /* Verify the file header */
     if (pFileHeader->ulIdentifier != 'OTTO' &&
@@ -165,6 +192,13 @@
                 return NULL;
             }
 
+            ulCheckSum = CalcTableChecksum((PUCHAR)pvView + ulOffset, 
ulLength);
+            if (ulCheckSum != SWAPD(pFileHeader->aTableEntries[i].ulCheckSum))
+            {
+                DbgPrint("Checksum mitmatch! %ld, %ld \n", ulOffset, ulLength);
+                return NULL;
+            }
+
             if (pulLength) *pulLength = ulLength;
             return (PUCHAR)pvView + ulOffset;
         }
@@ -174,15 +208,18 @@
     return NULL;
 }
 
+/*! \name OtfGetWinFamily
+ *  \brief Translates IBM font class IDs into a Windows family bitfield
+ *  \param jClassId
+ *  \param jSubclassId
+ *  \ref http://www.microsoft.com/typography/otspec/ibmfc.htm
+ */
 BYTE
 OtfGetWinFamily(BYTE jClassId, BYTE jSubclassId)
 {
-    BYTE jFamily = 0;
-
     switch (jClassId)
     {
         case 0: // Class ID = 0 No Classification
-            /* We rely on the already set value */
             break;
 
         case 1: // Class ID = 1 Oldstyle Serifs
@@ -197,37 +234,141 @@
                 case 6: // Subclass ID = 6 : Dutch Traditional
                 case 7: // Subclass ID = 7 : Contemporary
                 case 8: // Subclass ID = 8 : Calligraphic
-                    jFamily = FF_SCRIPT; break;
-
-                case 15: // Subclass ID = 15 : Miscellaneous
-
+                case 15: // Subclass ID = 15 : Miscellaneous
                 default: // Subclass ID = 9-14 : (reserved for future use)
                     break;
             }
+
         case 2: // Class ID = 2 Transitional Serifs
+            switch (jSubclassId)
+            {
+                case 15: return FF_ROMAN; // 15: Miscellaneous
+                case 0: // Subclass ID = 0 : No Classification
+                case 1: // Subclass ID = 1 : Direct Line
+                case 2: // Subclass ID = 2 : Script
+                default: // Subclass ID = 3-14 : (reserved for future use)
+                    break;
+            }
+
         case 3: // Class ID = 3 Modern Serifs
+            switch (jSubclassId)
+            {
+                case 0: // Subclass ID = 0 : No Classification
+                case 1: // Subclass ID = 1 : Italian
+                case 2: // Subclass ID = 2 : Script
+                case 15: // Subclass ID = 15 : Miscellaneous
+                default: // Subclass ID = 3-14 : (reserved for future use)
+                    break;
+            }
+
         case 4: // Class ID = 4 Clarendon Serifs
+            switch (jSubclassId)
+            {
+                case 0: // Subclass ID = 0 : No Classification
+                case 1: // Subclass ID = 1 : Clarendon
+                case 2: // Subclass ID = 2 : Modern
+                case 3: // Subclass ID = 3 : Traditional
+                case 4: // Subclass ID = 4 : Newspaper
+                case 5: // Subclass ID = 5 : Stub Serif
+                case 6: // Subclass ID = 6 : Monotone
+                case 7: // Subclass ID = 7 : Typewriter
+                case 15: // Subclass ID = 15 : Miscellaneous
+                default: // Subclass ID = 8-14: (reserved for future use)
+                    break;
+            }
+
         case 5: // Class ID = 5 Slab Serifs
-        case 6: // Class ID = 6 (reserved for future use)
+            switch (jSubclassId)
+            {
+                case 0: // Subclass ID = 0 : No Classification
+                case 1: // Subclass ID = 1 : Monotone
+                case 2: // Subclass ID = 2 : Humanist
+                case 3: // Subclass ID = 3 : Geometric
+                case 4: // Subclass ID = 4 : Swiss
+                case 5: // Subclass ID = 5 : Typewriter
+                case 15: // Subclass ID = 15 : Miscellaneous
+                default: // Subclass ID = 6-14 : (reserved for future use)
+                    break;
+            }
+
         case 7: // Class ID = 7 Freeform Serifs
+            switch (jSubclassId)
+            {
+                case 0: // Subclass ID = 0 : No Classification
+                case 1: // Subclass ID = 1 : Modern
+                case 15: // Subclass ID = 15 : Miscellaneous
+                default: // Subclass ID = 2-14 : (reserved for future use)
+                    break;
+            }
+
         case 8: // Class ID = 8 Sans Serif
             switch (jSubclassId)
             {
-                case 15: // Subclass ID = 15 : Miscellaneous
-                    jFamily = FF_SWISS | FF_ROMAN; break;
-                default:
-                    break;
-            }
+                case 0: return FF_SWISS; // 0: No Classification
+                case 5: return FF_SWISS; // 5: Neo-grotesque Gothic
+                case 15: return FF_SWISS|FF_ROMAN; // 15: Miscellaneous
+
+                case 1: // Subclass ID = 1 : IBM Neo-grotesque Gothic
+                case 2: // Subclass ID = 2 : Humanist
+                case 3: // Subclass ID = 3 : Low-x Round Geometric
+                case 4: // Subclass ID = 4 : High-x Round Geometric
+                case 6: // Subclass ID = 6 : Modified Neo-grotesque Gothic
+                case 9: // Subclass ID = 9 : Typewriter Gothic
+                case 10: // Subclass ID = 10 : Matrix
+                default: // Subclass ID = 7-8, 11-14 : (reserved for future 
use)
+                    break;
+            }
+
         case 9: // Class ID = 9 Ornamentals
+            switch (jSubclassId)
+            {
+                case 0: // Subclass ID = 0 : No Classification
+                case 1: // Subclass ID = 1 : Engraver
+                case 2: // Subclass ID = 2 : Black Letter
+                case 3: // Subclass ID = 3 : Decorative
+                case 4: // Subclass ID = 4 : Three Dimensional
+                case 15: // Subclass ID = 15 : Miscellaneous
+                default: // Subclass ID = 5-14 : (reserved for future use)
+                    break;
+            }
+
         case 10: // Class ID = 10 Scripts
-        case 11: // Class ID = 11 (reserved for future use)
+            switch (jSubclassId)
+            {
+                case 0: // Subclass ID = 0 : No Classification
+                case 1: // Subclass ID = 1 : Uncial
+                case 2: // Subclass ID = 2 : Brush Joined
+                case 3: // Subclass ID = 3 : Formal Joined
+                case 4: // Subclass ID = 4 : Monotone Joined
+                case 5: // Subclass ID = 5 : Calligraphic
+                case 6: // Subclass ID = 6 : Brush Unjoined
+                case 7: // Subclass ID = 7 : Formal Unjoined
+                case 8: // Subclass ID = 8 : Monotone Unjoined
+                case 15: // Subclass ID = 15 : Miscellaneous
+                default: // Subclass ID = 9-14 : (reserved for future use)
+                    break;
+            }
+
         case 12: // Class ID = 12 Symbolic
+            switch (jSubclassId)
+            {
+                case 0: // Subclass ID = 0 : No Classification
+                case 3: // Subclass ID = 3 : Mixed Serif
+                case 6: // Subclass ID = 6 : Oldstyle Serif
+                case 7: // Subclass ID = 7 : Neo-grotesque Sans Serif
+                case 15: // Subclass ID = 15 : Miscellaneous
+                default: // Subclass ID = 1-2,4-5,8-14  : (reserved for future 
use)
+                    break;
+            }
+
         case 13: // Class ID = 13 Reserved
         case 14: // Class ID = 14 Reserved
+        default: // Class ID = 6,11 (reserved for future use)
             break;
     }
+
 __debugbreak();
-    return jFamily;
+    return 0;
 }
 
 VOID
@@ -259,11 +400,8 @@
     pifi->jWinPitchAndFamily &= 3;
     pifi->jWinPitchAndFamily |= OtfGetWinFamily(pOs2->jClassId, 
pOs2->jSubClassId);
     pifi->usWinWeight = SWAPW(pOs2->usWeightClass);
-    //pifi->flInfo;
     pifi->fsSelection = SWAPW(pOs2->fsSelection);
     pifi->fsType = SWAPW(pOs2->fsType);
-    //pifi->fwdUnitsPerEm;
-    //pifi->fwdLowestPPEm;
     pifi->fwdWinAscender = SWAPW(pOs2->usWinAscent);
     pifi->fwdWinDescender = SWAPW(pOs2->usWinDescent);
     //pifi->fwdMacAscender;
@@ -273,7 +411,6 @@
     pifi->fwdTypoDescender = SWAPW(pOs2->sTypoDescender);
     pifi->fwdTypoLineGap = SWAPW(pOs2->sTypoLineGap);
     pifi->fwdAveCharWidth = SWAPW(pOs2->xAvgCharWidth);
-    //pifi->fwdMaxCharInc;
     pifi->fwdCapHeight = SWAPW(pOs2->sCapHeight);
     pifi->fwdXHeight = SWAPW(pOs2->sxHeight);
     pifi->fwdSubscriptXSize = SWAPW(pOs2->ySubscriptXSize);
@@ -292,17 +429,12 @@
     pifi->wcLastChar = SWAPW(pOs2->usLastCharIndex);
     pifi->wcDefaultChar = SWAPW(pOs2->usDefaultChar);
     pifi->wcBreakChar = SWAPW(pOs2->usBreakChar);
-    //pifi->chFirstChar = (CHAR)pifi->wcFirstChar; // FIXME: convert
-    //pifi->chLastChar = (CHAR)pifi->wcLastChar;
-    pifi->chDefaultChar = (CHAR)pifi->wcDefaultChar;
-    pifi->chBreakChar = (CHAR)pifi->wcBreakChar;
-    //pifi->ptlBaseline;
-    //pifi->ptlAspect;
-    //pifi->ptlCaret;
-    //pifi->rclFontBox;
     *(DWORD*)pifi->achVendId = *(DWORD*)pOs2->achVendID;
-    //pifi->cKerningPairs;
     //pifi->ulPanoseCulture;
     pifi->panose = *(PANOSE*)pOs2->panose;
+
+    /* Convert the special characters from unicode to ansi */
+    EngUnicodeToMultiByteN(&pifi->chFirstChar, 4, NULL, &pifi->wcFirstChar, 3);
+
 }
 

Removed: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/sprintf.c
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/sprintf.c?rev=51588&view=auto
==============================================================================
--- branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/sprintf.c 
[iso-8859-1] (original)
+++ branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/sprintf.c (removed)
@@ -1,742 +1,0 @@
-/*
- * PROGRAMMERS:     David Welch
- *                  Eric Kohl
- *
- * TODO:
- *   - Verify the implementation of '%Z'.
- */
-
-/*
- *  linux/lib/vsprintf.c
- *
- *  Copyright (C) 1991, 1992  Linus Torvalds
- */
-
-/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */
-/*
- * Wirzenius wrote this portably, Torvalds fucked it up :-)
- */
-
-#define WIN32_NO_STATUS
-#include <windows.h>
-#include <ndk/ntndk.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#define ZEROPAD        1               /* pad with zero */
-#define SIGN   2               /* unsigned/signed long */
-#define PLUS   4               /* show plus */
-#define SPACE  8               /* space if plus */
-#define LEFT   16              /* left justified */
-#define SPECIAL        32              /* 0x */
-#define LARGE  64              /* use 'ABCDEF' instead of 'abcdef' */
-#define REMOVEHEX      256             /* use 256 as remve 0x frim BASE 16  */
-typedef struct {
-    unsigned int mantissal:32;
-    unsigned int mantissah:20;
-    unsigned int exponent:11;
-    unsigned int sign:1;
-} double_t;
-
-static
-__inline
-int
-_isinf(double __x)
-{
-       union
-       {
-               double*   __x;
-               double_t*   x;
-       } x;
-
-       x.__x = &__x;
-       return ( x.x->exponent == 0x7ff  && ( x.x->mantissah == 0 && 
x.x->mantissal == 0 ));
-}
-
-static
-__inline
-int
-_isnan(double __x)
-{
-       union
-       {
-               double*   __x;
-               double_t*   x;
-       } x;
-       x.__x = &__x;
-       return ( x.x->exponent == 0x7ff  && ( x.x->mantissah != 0 || 
x.x->mantissal != 0 ));
-}
-
-
-static
-__inline
-int
-do_div(long long *n, int base)
-{
-    int a;
-    a = ((unsigned long long) *n) % (unsigned) base;
-    *n = ((unsigned long long) *n) / (unsigned) base;
-    return a;
-}
-
-
-static int skip_atoi(const char **s)
-{
-       int i=0;
-
-       while (isdigit(**s))
-               i = i*10 + *((*s)++) - '0';
-       return i;
-}
-
-
-static char *
-number(char * buf, char * end, long long num, int base, int size, int 
precision, int type)
-{
-       char c,sign,tmp[66];
-       const char *digits;
-       const char *small_digits = "0123456789abcdefghijklmnopqrstuvwxyz";
-       const char *large_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-       int i;
-
-       digits = (type & LARGE) ? large_digits : small_digits;
-       if (type & LEFT)
-               type &= ~ZEROPAD;
-       if (base < 2 || base > 36)
-               return 0;
-       c = (type & ZEROPAD) ? '0' : ' ';
-       sign = 0;
-       if (type & SIGN) {
-               if (num < 0) {
-                       sign = '-';
-                       num = -num;
-                       size--;
-               } else if (type & PLUS) {
-                       sign = '+';
-                       size--;
-               } else if (type & SPACE) {
-                       sign = ' ';
-                       size--;
-               }
-       }
-
-       if ((type & SPECIAL) && ((type & REMOVEHEX) == 0)) {
-               if (base == 16)
-                       size -= 2;
-
-       }
-       i = 0;
-       if ((num == 0) && (precision !=0))
-               tmp[i++] = '0';
-       else while (num != 0)
-               tmp[i++] = digits[do_div(&num,base)];
-       if (i > precision)
-               precision = i;
-       size -= precision;
-       if (!(type&(ZEROPAD+LEFT))) {
-               while(size-->0) {
-                       if (buf <= end)
-                               *buf = ' ';
-                       ++buf;
-               }
-       }
-       if (sign) {
-               if (buf <= end)
-                       *buf = sign;
-               ++buf;
-       }
-
-       if ((type & SPECIAL) && ((type & REMOVEHEX) == 0)) {
-                if (base==16) {
-                       if (buf <= end)
-                               *buf = '0';
-                       ++buf;
-                       if (buf <= end)
-                               *buf = digits[33];
-                       ++buf;
-               }
-       }
-
-       if (!(type & LEFT)) {
-               while (size-- > 0) {
-                       if (buf <= end)
-                               *buf = c;
-                       ++buf;
-               }
-       }
-       while (i < precision--) {
-               if (buf <= end)
-                       *buf = '0';
-               ++buf;
-       }
-       while (i-- > 0) {
-               if (buf <= end)
-                       *buf = tmp[i];
-               ++buf;
-       }
-       while (size-- > 0) {
-               if (buf <= end)
-                       *buf = ' ';
-               ++buf;
-       }
-
-       return buf;
-}
-
-static char *
-numberf(char * buf, char * end, double num, int base, int size, int precision, 
int type)
-{
-       char c,sign,tmp[66];
-       const char *digits;
-       const char *small_digits = "0123456789abcdefghijklmnopqrstuvwxyz";
-       const char *large_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
-       int i;
-       long long x;
-
-    /* FIXME
-       the float version of number is direcly copy of number
-    */
-
-       digits = (type & LARGE) ? large_digits : small_digits;
-       if (type & LEFT)
-               type &= ~ZEROPAD;
-       if (base < 2 || base > 36)
-               return 0;
-       c = (type & ZEROPAD) ? '0' : ' ';
-       sign = 0;
-       if (type & SIGN) {
-               if (num < 0) {
-                       sign = '-';
-                       num = -num;
-                       size--;
-               } else if (type & PLUS) {
-                       sign = '+';
-                       size--;
-               } else if (type & SPACE) {
-                       sign = ' ';
-                       size--;
-               }
-       }
-       if (type & SPECIAL)  {
-               if (base == 16)
-                       size -= 2;
-               else if (base == 8)
-                       size--;
-       }
-       i = 0;
-       if (num == 0)
-               tmp[i++] = '0';
-       else while (num != 0)
-    {
-        x = num;
-               tmp[i++] = digits[do_div(&x,base)];
-               num=x;
-    }
-       if (i > precision)
-               precision = i;
-       size -= precision;
-       if (!(type&(ZEROPAD+LEFT))) {
-               while(size-->0) {
-                       if (buf <= end)
-                               *buf = ' ';
-                       ++buf;
-               }
-       }
-       if (sign) {
-               if (buf <= end)
-                       *buf = sign;
-               ++buf;
-       }
-       if (type & SPECIAL) {
-               if (base==8) {
-                       if (buf <= end)
-                               *buf = '0';
-                       ++buf;
-               } else if (base==16) {
-                       if (buf <= end)
-                               *buf = '0';
-                       ++buf;
-                       if (buf <= end)
-                               *buf = digits[33];
-                       ++buf;
-               }
-       }
-       if (!(type & LEFT)) {
-               while (size-- > 0) {
-                       if (buf <= end)
-                               *buf = c;
-                       ++buf;
-               }
-       }
-       while (i < precision--) {
-               if (buf <= end)
-                       *buf = '0';
-               ++buf;
-       }
-       while (i-- > 0) {
-               if (buf <= end)
-                       *buf = tmp[i];
-               ++buf;
-       }
-       while (size-- > 0) {
-               if (buf <= end)
-                       *buf = ' ';
-               ++buf;
-       }
-       return buf;
-}
-
-static char*
-string(char* buf, char* end, const char* s, int len, int field_width, int 
precision, int flags)
-{
-       int i;
-    char c;
-
-    c = (flags & ZEROPAD) ? '0' : ' ';
-
-       if (s == NULL)
-       {
-               s = "<NULL>";
-               len = 6;
-       }
-       else
-       {
-               if (len == -1)
-               {
-                       len = 0;
-                       while ((unsigned int)len < (unsigned int)precision && 
s[len])
-                               len++;
-               }
-               else
-               {
-                       if ((unsigned int)len > (unsigned int)precision)
-                               len = precision;
-               }
-       }
-       if (!(flags & LEFT))
-               while (len < field_width--)
-               {
-                       if (buf <= end)
-                               *buf = c;
-                       ++buf;
-               }
-       for (i = 0; i < len; ++i)
-       {
-               if (buf <= end)
-                       *buf = *s++;
-               ++buf;
-       }
-       while (len < field_width--)
-       {
-               if (buf <= end)
-                       *buf = ' ';
-               ++buf;
-       }
-       return buf;
-}
-
-static char*
-stringw(char* buf, char* end, const wchar_t* sw, int len, int field_width, int 
precision, int flags)
-{
-       int i;
-       char c;
-
-    c = (flags & ZEROPAD) ? '0' : ' ';
-
-       if (sw == NULL)
-       {
-               sw = L"<NULL>";
-               len = 6;
-       }
-       else
-       {
-               if (len == -1)
-               {
-                       len = 0;
-                       while ((unsigned int)len < (unsigned int)precision && 
sw[len])
-                               len++;
-               }
-               else
-               {
-                       if ((unsigned int)len > (unsigned int)precision)
-                               len = precision;
-               }
-       }
-       if (!(flags & LEFT))
-               while (len < field_width--)
-               {
-                       if (buf <= end)
-                               *buf = c;
-                       buf++;
-               }
-       for (i = 0; i < len; ++i)
-       {
-               if (buf <= end)
-                       *buf = (unsigned char)(*sw++);
-               buf++;
-       }
-       while (len < field_width--)
-       {
-               if (buf <= end)
-                       *buf = ' ';
-               buf++;
-       }
-       return buf;
-}
-
-/*
- * @implemented
- */
-int __cdecl _vsnprintf(char *buf, size_t cnt, const char *fmt, va_list args)
-{
-       int len;
-       unsigned long long num;
-       double _double;
-
-       int base;
-       char *str, *end;
-       const char *s;
-       const wchar_t *sw;
-
-       int flags;              /* flags to number() */
-
-       int field_width;        /* width of output field */
-       int precision;          /* min. # of digits for integers; max
-                                  number of chars for from string */
-       int qualifier;          /* 'h', 'l', 'L', 'I' or 'w' for integer fields 
*/
-
-    /* clear the string buffer with zero so we do not need NULL terment it at 
end */
-
-       str = buf;
-       end = buf + cnt - 1;
-       if (end < buf - 1) {
-               end = ((char *) -1);
-               cnt = end - buf + 1;
-       }
-
-       for ( ; *fmt ; ++fmt) {
-               if (*fmt != '%') {
-                       if (str <= end)
-                               *str = *fmt;
-                       ++str;
-                       continue;
-               }
-
-               /* process flags */
-               flags = 0;
-               repeat:
-                       ++fmt;          /* this also skips first '%' */
-                       switch (*fmt) {
-                               case '-': flags |= LEFT; goto repeat;
-                               case '+': flags |= PLUS; goto repeat;
-                               case ' ': flags |= SPACE; goto repeat;
-                               case '#': flags |= SPECIAL; goto repeat;
-                               case '0': flags |= ZEROPAD; goto repeat;
-                       }
-
-               /* get field width */
-               field_width = -1;
-               if (isdigit(*fmt))
-                       field_width = skip_atoi(&fmt);
-               else if (*fmt == '*') {
-                       ++fmt;
-                       /* it's the next argument */
-                       field_width = va_arg(args, int);
-                       if (field_width < 0) {
-                               field_width = -field_width;
-                               flags |= LEFT;
-                       }
-               }
-
-               /* get the precision */
-               precision = -1;
-               if (*fmt == '.') {
-                       ++fmt;
-                       if (isdigit(*fmt))
-                               precision = skip_atoi(&fmt);
-                       else if (*fmt == '*') {
-                               ++fmt;
-                               /* it's the next argument */
-                               precision = va_arg(args, int);
-                       }
-                       if (precision < 0)
-                               precision = 0;
-               }
-
-               /* get the conversion qualifier */
-               qualifier = -1;
-               if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L' || *fmt == 'w') {
-                       qualifier = *fmt;
-                       ++fmt;
-               } else if (*fmt == 'I' && *(fmt+1) == '6' && *(fmt+2) == '4') {
-                       qualifier = *fmt;
-                       fmt += 3;
-               } else if (*fmt == 'I' && *(fmt+1) == '3' && *(fmt+2) == '2') {
-                       qualifier = 'l';
-                       fmt += 3;
-               } else if (*fmt == 'F' && *(fmt+1) == 'p') {
-                       fmt += 1;
-            flags |= REMOVEHEX;
-        }
-
-               /* default base */
-               base = 10;
-
-               switch (*fmt) {
-               case 'c': /* finished */
-             if (qualifier == 'l' || qualifier == 'w') {
-                     wchar_t sw1[2];
-                               /* print unicode string */
-                sw1[0] = (wchar_t) va_arg(args, int);
-                sw1[1] = 0;
-                               str = stringw(str, end, (wchar_t *)&sw1, -1, 
field_width, precision, flags);
-                       } else {
-                char s1[2];
-                               /* print ascii string */
-                s1[0] = ( unsigned char) va_arg(args, int);
-                s1[1] = 0;
-                               str = string(str, end, (char *)&s1, -1,  
field_width, precision, flags);
-                       }
-            continue;
-
-               case 'C': /* finished */
-                       if (!(flags & LEFT))
-                               while (--field_width > 0) {
-                                       if (str <= end)
-                                               *str = ' ';
-                                       ++str;
-                               }
-                       if (qualifier == 'h') {
-                               if (str <= end)
-                                       *str = (unsigned char) va_arg(args, 
int);
-                               ++str;
-                       } else {
-                               if (str <= end)
-                                       *str = (unsigned char)(wchar_t) 
va_arg(args, int);
-                               ++str;
-                       }
-                       while (--field_width > 0) {
-                               if (str <= end)
-                                       *str = ' ';
-                               ++str;
-                       }
-                       continue;
-
-               case 's': /* finished */
-                       if (qualifier == 'l' || qualifier == 'w') {
-                               /* print unicode string */
-                               sw = va_arg(args, wchar_t *);
-                               str = stringw(str, end, sw, -1, field_width, 
precision, flags);
-                       } else {
-                               /* print ascii string */
-                               s = va_arg(args, char *);
-                               str = string(str, end, s, -1,  field_width, 
precision, flags);
-                       }
-                       continue;
-
-               case 'S':
-                       if (qualifier == 'h') {
-                               /* print ascii string */
-                               s = va_arg(args, char *);
-                               str = string(str, end, s, -1,  field_width, 
precision, flags);
-                       } else {
-                               /* print unicode string */
-                               sw = va_arg(args, wchar_t *);
-                               str = stringw(str, end, sw, -1, field_width, 
precision, flags);
-                       }
-                       continue;
-
-               case 'Z':
-                       if (qualifier == 'w') {
-                               /* print counted unicode string */
-                               PUNICODE_STRING pus = va_arg(args, 
PUNICODE_STRING);
-                               if ((pus == NULL) || (pus->Buffer == NULL)) {
-                                       sw = NULL;
-                                       len = -1;
-                               } else {
-                                       sw = pus->Buffer;
-                                       len = pus->Length / sizeof(WCHAR);
-                               }
-                               str = stringw(str, end, sw, len,  field_width, 
precision, flags);
-                       } else {
-                               /* print counted ascii string */
-                               PANSI_STRING pus = va_arg(args, PANSI_STRING);
-                               if ((pus == NULL) || (pus->Buffer == NULL)) {
-                                       s = NULL;
-                                       len = -1;
-                               } else {
-                                       s = pus->Buffer;
-                                       len = pus->Length;
-                               }
-                               str = string(str, end, s, len,  field_width, 
precision, flags);
-                       }
-                       continue;
-
-               case 'p':
-            if ((flags & LARGE) == 0)
-                flags |= LARGE;
-
-                       if (field_width == -1) {
-                               field_width = 2 * sizeof(void *);
-                               flags |= ZEROPAD;
-                       }
-                       str = number(str, end,
-                               (ULONG_PTR) va_arg(args, void *), 16,
-                               field_width, precision, flags);
-                       continue;
-
-               case 'n':
-                       /* FIXME: What does C99 say about the overflow case 
here? */
-                       if (qualifier == 'l') {
-                               long * ip = va_arg(args, long *);
-                               *ip = (str - buf);
-                       } else {
-                               int * ip = va_arg(args, int *);
-                               *ip = (str - buf);
-                       }
-                       continue;
-
-               /* float number formats - set up the flags and "break" */
-        case 'e':
-               case 'E':
-               case 'f':
-               case 'g':
-               case 'G':
-          _double = (double)va_arg(args, double);
-         if ( _isnan(_double) ) {
-            s = "Nan";
-            len = 3;
-            while ( len > 0 ) {
-               if (str <= end)
-                                       *str = *s++;
-                               ++str;
-               len --;
-            }
-         } else if ( _isinf(_double) < 0 ) {
-            s = "-Inf";
-            len = 4;
-            while ( len > 0 ) {
-               if (str <= end)
-                                       *str = *s++;
-                               ++str;
-               len --;
-            }
-         } else if ( _isinf(_double) > 0 ) {
-            s = "+Inf";
-            len = 4;
-            while ( len > 0 ) {
-               if (str <= end)
-                                       *str = *s++;
-                               ++str;
-               len --;
-            }
-         } else {
-            if ( precision == -1 )
-               precision = 6;
-                       str = numberf(str, end, (int)_double, base, 
field_width, precision, flags);
-         }
-
-          continue;
-
-
-               /* integer number formats - set up the flags and "break" */
-               case 'o':
-                       base = 8;
-                       break;
-
-               case 'b':
-                       base = 2;
-                       break;
-
-               case 'X':
-                       flags |= LARGE;
-               case 'x':
-                       base = 16;
-                       break;
-
-               case 'd':
-               case 'i':
-                       flags |= SIGN;
-               case 'u':
-                       break;
-
-               default:
-                       if (*fmt) {
-                               if (str <= end)
-                                       *str = *fmt;
-                               ++str;
-                       } else
-                               --fmt;
-                       continue;
-               }
-
-               if (qualifier == 'I')
-                       num = va_arg(args, unsigned long long);
-               else if (qualifier == 'l') {
-                       if (flags & SIGN)
-                               num = va_arg(args, long);
-                       else
-                               num = va_arg(args, unsigned long);
-               }
-               else if (qualifier == 'h') {
-                       if (flags & SIGN)
-                               num = va_arg(args, int);
-                       else
-                               num = va_arg(args, unsigned int);
-               }
-               else {
-                       if (flags & SIGN)
-                               num = va_arg(args, int);
-                       else
-                               num = va_arg(args, unsigned int);
-               }
-               str = number(str, end, num, base, field_width, precision, 
flags);
-       }
-       if (str <= end)
-               *str = '\0';
-       else if (cnt > 0)
-               /* don't write out a null byte if the buf size is zero */
-               *end = '\0';
-       return str-buf;
-}
-
-
-/*
- * @implemented
- */
-int sprintf(char * buf, const char *fmt, ...)
-{
-       va_list args;
-       int i;
-
-       va_start(args, fmt);
-       i=_vsnprintf(buf,MAXLONG,fmt,args);
-       va_end(args);
-       return i;
-}
-
-
-/*
- * @implemented
- */
-int _snprintf(char * buf, size_t cnt, const char *fmt, ...)
-{
-       va_list args;
-       int i;
-
-       va_start(args, fmt);
-       i=_vsnprintf(buf,cnt,fmt,args);
-       va_end(args);
-       return i;
-}
-
-
-/*
- * @implemented
- */
-int __cdecl vsprintf(char *buf, const char *fmt, va_list args)
-{
-       return _vsnprintf(buf,MAXLONG,fmt,args);
-}
-
-/* EOF */

Modified: branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/todo.txt
URL: 
http://svn.reactos.org/svn/reactos/branches/GSoC_2011/GdiFontDriver/drivers/video/font/ftfd/todo.txt?rev=51589&r1=51588&r2=51589&view=diff
==============================================================================
--- 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] Thu May  5 15:01:51 2011
@@ -14,7 +14,7 @@
 - FtfdQueryFontFile: 50%
     - implement QFF_DESCRIPTION, unimportant
 - FtfdQueryFontCaps: 100% done
-- FtfdQueryTrueTypeTable: unimplemented
+- FtfdQueryTrueTypeTable: 100% done
 - FtfdGetTrueTypeFile: unimplemented
 
 - FtfdQueryFontData: 10%, depends on FtfdLoadGlyph


Reply via email to