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