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