mirror of
https://github.com/reactos/reactos.git
synced 2024-10-03 07:53:49 +00:00
Initial version of a gdi font driver for bitmap fonts (.fon / .fnt). It starts to work, but not yet correctly. Glyphs are truncated. Developed on Windows XP.
svn path=/trunk/; revision=39849
This commit is contained in:
parent
eff51218fb
commit
f1aeddb982
|
@ -4,6 +4,9 @@
|
|||
<directory name="displays">
|
||||
<xi:include href="displays/directory.rbuild" />
|
||||
</directory>
|
||||
<directory name="font">
|
||||
<xi:include href="font/directory.rbuild" />
|
||||
</directory>
|
||||
<directory name="miniport">
|
||||
<xi:include href="miniport/directory.rbuild" />
|
||||
</directory>
|
||||
|
|
359
reactos/drivers/video/font/bmfd/bmfd.h
Normal file
359
reactos/drivers/video/font/bmfd/bmfd.h
Normal file
|
@ -0,0 +1,359 @@
|
|||
/*
|
||||
* PROJECT: ReactOS win32 subsystem
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* PURPOSE: GDI font driver for bitmap fonts
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <windef.h>
|
||||
#include <wingdi.h>
|
||||
#include <winddi.h>
|
||||
|
||||
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||
/* on x86 and x64, unaligned access is allowed, byteorder is LE */
|
||||
#define GETVAL(x) (x)
|
||||
#else
|
||||
// FIXME: BE
|
||||
#define GETVAL(x) \
|
||||
sizeof(x) == 1 ? (x) : \
|
||||
sizeof(x) == 2 ? (((PCHAR)&(x))[0] + (((PCHAR)&(x))[1] << 8)) : \
|
||||
(((PCHAR)&(x))[0] + (((PCHAR)&(x))[1] << 8) + (((PCHAR)&(x))[2] << 16) + \
|
||||
(((PCHAR)&(x))[3] << 24))
|
||||
|
||||
#endif
|
||||
|
||||
#define FDM_MASK \
|
||||
FDM_TYPE_CONST_BEARINGS | FDM_TYPE_ZERO_BEARINGS | \
|
||||
FDM_TYPE_CHAR_INC_EQUAL_BM_BASE | FDM_TYPE_MAXEXT_EQUAL_BM_SIDE | \
|
||||
FDM_TYPE_BM_SIDE_CONST
|
||||
|
||||
#define FM_INFO_MASK \
|
||||
FM_INFO_TECH_BITMAP | FM_INFO_1BPP | FM_INFO_INTEGER_WIDTH | \
|
||||
FM_INFO_RETURNS_BITMAPS | FM_INFO_RIGHT_HANDED | FM_INFO_INTEGRAL_SCALING |\
|
||||
FM_INFO_90DEGREE_ROTATIONS | FM_INFO_OPTICALLY_FIXED_PITCH | FM_INFO_NONNEGATIVE_AC
|
||||
|
||||
#define FLOATL_1 0x3f800000
|
||||
|
||||
#define TAG_PDEV 'veDP'
|
||||
#define TAG_GLYPHSET 'GlSt'
|
||||
#define TAG_IFIMETRICS 'Ifim'
|
||||
#define TAG_FONTINFO 'Font'
|
||||
|
||||
|
||||
/** FON / FNT specific types **************************************************/
|
||||
|
||||
#define IMAGE_DOS_MAGIC 0x594D // FIXME: hack hack hack
|
||||
|
||||
#include <pshpack1.h>
|
||||
typedef struct
|
||||
{
|
||||
WORD offset;
|
||||
WORD length;
|
||||
WORD flags;
|
||||
WORD id;
|
||||
WORD handle;
|
||||
WORD usage;
|
||||
} NE_NAMEINFO, *PNE_NAMEINFO;
|
||||
|
||||
#define NE_RSCTYPE_FONT 0x8008
|
||||
#define NE_RSCTYPE_FONTDIR 0x8007
|
||||
typedef struct
|
||||
{
|
||||
WORD type_id;
|
||||
WORD count;
|
||||
DWORD resloader;
|
||||
NE_NAMEINFO nameinfo[1];
|
||||
} NE_TYPEINFO, *PNE_TYPEINFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD size_shift;
|
||||
NE_TYPEINFO typeinfo[1];
|
||||
} NE_RESTABLE, *PNE_RESTABLE;
|
||||
|
||||
// Values of dfFlags:
|
||||
#define DFF_FIXED 0x0001
|
||||
#define DFF_PROPORTIONAL 0x0002
|
||||
#define DFF_ABCFIXED 0x0004
|
||||
#define DFF_ABCPROPORTIONAL 0x0008
|
||||
#define DFF_1COLOR 0x0010
|
||||
#define DFF_16COLOR 0x0020
|
||||
#define DFF_256COLOR 0x0040
|
||||
#define DFF_RGBCOLOR 0x0080
|
||||
|
||||
// see http://msdn.microsoft.com/en-us/library/ms648014(VS.85).aspx
|
||||
typedef struct _FONTDIRENTRY
|
||||
{
|
||||
WORD dfVersion;
|
||||
DWORD dfSize;
|
||||
char dfCopyright[60];
|
||||
WORD dfType;
|
||||
WORD dfPoints;
|
||||
WORD dfVertRes;
|
||||
WORD dfHorizRes;
|
||||
WORD dfAscent;
|
||||
WORD dfInternalLeading;
|
||||
WORD dfExternalLeading;
|
||||
BYTE dfItalic;
|
||||
BYTE dfUnderline;
|
||||
BYTE dfStrikeOut;
|
||||
WORD dfWeight;
|
||||
BYTE dfCharSet;
|
||||
WORD dfPixWidth;
|
||||
WORD dfPixHeight;
|
||||
BYTE dfPitchAndFamily;
|
||||
WORD dfAvgWidth;
|
||||
WORD dfMaxWidth;
|
||||
BYTE dfFirstChar;
|
||||
BYTE dfLastChar;
|
||||
BYTE dfDefaultChar;
|
||||
BYTE dfBreakChar;
|
||||
WORD dfWidthBytes;
|
||||
DWORD dfDevice;
|
||||
DWORD dfFace;
|
||||
DWORD dfReserved;
|
||||
char szDeviceName[1];
|
||||
char szFaceName[1];
|
||||
} FONTDIRENTRY, *PFONTDIRENTRY;
|
||||
|
||||
typedef struct _DIRENTRY
|
||||
{
|
||||
WORD fontOrdinal;
|
||||
FONTDIRENTRY fde;
|
||||
} DIRENTRY, *PDIRENTRY;
|
||||
|
||||
typedef struct _FONTGROUPHDR
|
||||
{
|
||||
WORD NumberOfFonts;
|
||||
DIRENTRY ade[1];
|
||||
} FONTGROUPHDR, *PFONTGROUPHDR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD dfVersion;
|
||||
DWORD dfSize;
|
||||
CHAR dfCopyright[60];
|
||||
WORD dfType;
|
||||
WORD dfPoints;
|
||||
WORD dfVertRes;
|
||||
WORD dfHorizRes;
|
||||
WORD dfAscent;
|
||||
WORD dfInternalLeading;
|
||||
WORD dfExternalLeading;
|
||||
BYTE dfItalic;
|
||||
BYTE dfUnderline;
|
||||
BYTE dfStrikeOut;
|
||||
WORD dfWeight;
|
||||
BYTE dfCharSet;
|
||||
WORD dfPixWidth;
|
||||
WORD dfPixHeight;
|
||||
BYTE dfPitchAndFamily;
|
||||
WORD dfAvgWidth;
|
||||
WORD dfMaxWidth;
|
||||
BYTE dfFirstChar;
|
||||
BYTE dfLastChar;
|
||||
BYTE dfDefaultChar;
|
||||
BYTE dfBreakChar;
|
||||
WORD dfWidthBytes;
|
||||
DWORD dfDevice;
|
||||
DWORD dfFace;
|
||||
DWORD dfBitsPointer;
|
||||
DWORD dfBitsOffset;
|
||||
BYTE dfReserved;
|
||||
/* Version 3.00: */
|
||||
DWORD dfFlags;
|
||||
WORD dfAspace;
|
||||
WORD dfBspace;
|
||||
WORD dfCspace;
|
||||
DWORD dfColorPointer;
|
||||
DWORD dfReserved1[4];
|
||||
BYTE dfCharTable[1];
|
||||
} FONTINFO16, *LPFONTINFO16, *PFONTINFO16;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD geWidth;
|
||||
WORD geOffset;
|
||||
} GLYPHENTRY20, *PGLYPHENTRY20;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD geWidth;
|
||||
DWORD geOffset;
|
||||
} GLYPHENTRY30, *PGLYPHENTRY30;
|
||||
|
||||
typedef union
|
||||
{
|
||||
GLYPHENTRY20 ge20;
|
||||
GLYPHENTRY30 ge30;
|
||||
} GLYPHENTRY, *PGLYPHENTRY;
|
||||
|
||||
#include <poppack.h>
|
||||
|
||||
|
||||
/** Driver specific types *****************************************************/
|
||||
|
||||
typedef enum
|
||||
{
|
||||
FONTTYPE_FON,
|
||||
FONTTYPE_FNT,
|
||||
} FONTTYPE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PFONTDIRENTRY pFontDirEntry;
|
||||
PFONTINFO16 pFontInfo;
|
||||
PBYTE pCharTable;
|
||||
ULONG cjEntrySize;
|
||||
ULONG ulVersion;
|
||||
PCHAR pszFaceName;
|
||||
PCHAR pszCopyright;
|
||||
ULONG cGlyphs;
|
||||
CHAR chFirstChar;
|
||||
CHAR chLastChar;
|
||||
WCHAR wcFirstChar;
|
||||
WCHAR wcLastChar;
|
||||
WCHAR wcDefaultChar;
|
||||
WCHAR wcBreakChar;
|
||||
WORD wPixHeight;
|
||||
WORD wPixWidth;
|
||||
WORD wWidthBytes;
|
||||
WORD wA;
|
||||
WORD wB;
|
||||
WORD wC;
|
||||
WORD wAscent;
|
||||
WORD wDescent;
|
||||
FLONG flInfo;
|
||||
} DRVFACE, *PDRVFACE;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
PVOID pvView;
|
||||
ULONG_PTR iFile;
|
||||
PFONTGROUPHDR pFontDir;
|
||||
FONTTYPE ulFontType;
|
||||
ULONG cNumFaces;
|
||||
DRVFACE aface[1];
|
||||
} DRVFONT, *PDRVFONT;
|
||||
|
||||
//"Bold Italic Underline Strikeout"
|
||||
#define MAX_STYLESIZE 35
|
||||
typedef struct
|
||||
{
|
||||
IFIMETRICS ifim;
|
||||
BYTE ajCharSet[16];
|
||||
WCHAR wszFamilyName[LF_FACESIZE];
|
||||
WCHAR wszFaceName[LF_FACESIZE];
|
||||
WCHAR wszStyleName[MAX_STYLESIZE];
|
||||
} DRVIFIMETRICS, *PDRVIFIMETRICS;
|
||||
|
||||
|
||||
/** Function prototypes *******************************************************/
|
||||
|
||||
ULONG
|
||||
DbgPrint(IN PCHAR Format, IN ...);
|
||||
|
||||
static __inline__
|
||||
void
|
||||
DbgBreakPoint(void)
|
||||
{
|
||||
asm volatile ("int $3");
|
||||
}
|
||||
|
||||
DHPDEV
|
||||
APIENTRY
|
||||
BmfdEnablePDEV(
|
||||
IN DEVMODEW *pdm,
|
||||
IN LPWSTR pwszLogAddress,
|
||||
IN ULONG cPat,
|
||||
OUT HSURF *phsurfPatterns,
|
||||
IN ULONG cjCaps,
|
||||
OUT ULONG *pdevcaps,
|
||||
IN ULONG cjDevInfo,
|
||||
OUT DEVINFO *pdi,
|
||||
IN HDEV hdev,
|
||||
IN LPWSTR pwszDeviceName,
|
||||
IN HANDLE hDriver);
|
||||
|
||||
VOID
|
||||
APIENTRY
|
||||
BmfdCompletePDEV(
|
||||
IN DHPDEV dhpdev,
|
||||
IN HDEV hdev);
|
||||
|
||||
VOID
|
||||
APIENTRY
|
||||
BmfdDisablePDEV(
|
||||
IN DHPDEV dhpdev);
|
||||
|
||||
ULONG_PTR
|
||||
APIENTRY
|
||||
BmfdLoadFontFile(
|
||||
ULONG cFiles,
|
||||
ULONG_PTR *piFile,
|
||||
PVOID *ppvView,
|
||||
ULONG *pcjView,
|
||||
DESIGNVECTOR *pdv,
|
||||
ULONG ulLangID,
|
||||
ULONG ulFastCheckSum);
|
||||
|
||||
BOOL
|
||||
APIENTRY
|
||||
BmfdUnloadFontFile(
|
||||
IN ULONG_PTR iFile);
|
||||
|
||||
LONG
|
||||
APIENTRY
|
||||
BmfdQueryFontFile(
|
||||
ULONG_PTR iFile,
|
||||
ULONG ulMode,
|
||||
ULONG cjBuf,
|
||||
ULONG *pulBuf);
|
||||
|
||||
LONG
|
||||
APIENTRY
|
||||
BmfdQueryFontCaps(
|
||||
ULONG culCaps,
|
||||
ULONG *pulCaps);
|
||||
|
||||
PVOID
|
||||
APIENTRY
|
||||
BmfdQueryFontTree(
|
||||
DHPDEV dhpdev,
|
||||
ULONG_PTR iFile,
|
||||
ULONG iFace,
|
||||
ULONG iMode,
|
||||
ULONG_PTR *pid);
|
||||
|
||||
PIFIMETRICS
|
||||
APIENTRY
|
||||
BmfdQueryFont(
|
||||
IN DHPDEV dhpdev,
|
||||
IN ULONG_PTR iFile,
|
||||
IN ULONG iFace,
|
||||
IN ULONG_PTR *pid);
|
||||
|
||||
VOID
|
||||
APIENTRY
|
||||
BmfdFree(
|
||||
PVOID pv,
|
||||
ULONG_PTR id);
|
||||
|
||||
PFD_GLYPHATTR
|
||||
APIENTRY
|
||||
BmfdQueryGlyphAttrs(
|
||||
FONTOBJ *pfo,
|
||||
ULONG iMode);
|
||||
|
||||
LONG
|
||||
APIENTRY
|
||||
BmfdQueryFontData(
|
||||
DHPDEV dhpdev,
|
||||
FONTOBJ *pfo,
|
||||
ULONG iMode,
|
||||
HGLYPH hg,
|
||||
OUT GLYPHDATA *pgd,
|
||||
PVOID pv,
|
||||
ULONG cjSize);
|
||||
|
9
reactos/drivers/video/font/bmfd/bmfd.rbuild
Normal file
9
reactos/drivers/video/font/bmfd/bmfd.rbuild
Normal file
|
@ -0,0 +1,9 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
|
||||
<module name="bmfd" type="kernelmodedriver" entrypoint="FonfdEnableDriver@12" installbase="system32" installname="bmfd.dll" crt="static">
|
||||
<library>win32k</library>
|
||||
<library>libcntpr</library>
|
||||
<file>enable.c</file>
|
||||
<file>font.c</file>
|
||||
<file>glyph.c</file>
|
||||
</module>
|
104
reactos/drivers/video/font/bmfd/enable.c
Normal file
104
reactos/drivers/video/font/bmfd/enable.c
Normal file
|
@ -0,0 +1,104 @@
|
|||
/*
|
||||
* PROJECT: ReactOS win32 subsystem
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* PURPOSE: GDI font driver for bitmap fonts
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
#include "bmfd.h"
|
||||
|
||||
static DRVFN gadrvfn[] =
|
||||
{
|
||||
{INDEX_DrvEnablePDEV, (PFN)BmfdEnablePDEV},
|
||||
{INDEX_DrvCompletePDEV, (PFN)BmfdCompletePDEV},
|
||||
{INDEX_DrvDisablePDEV, (PFN)BmfdDisablePDEV},
|
||||
{INDEX_DrvLoadFontFile, (PFN)BmfdLoadFontFile},
|
||||
{INDEX_DrvUnloadFontFile, (PFN)BmfdUnloadFontFile},
|
||||
{INDEX_DrvQueryFontFile, (PFN)BmfdQueryFontFile},
|
||||
{INDEX_DrvQueryFontCaps, (PFN)BmfdQueryFontCaps},
|
||||
{INDEX_DrvQueryFontTree, (PFN)BmfdQueryFontTree},
|
||||
{INDEX_DrvQueryFont, (PFN)BmfdQueryFont},
|
||||
{INDEX_DrvFree, (PFN)BmfdFree},
|
||||
{INDEX_DrvQueryGlyphAttrs, (PFN)BmfdQueryGlyphAttrs},
|
||||
{INDEX_DrvQueryFontData, (PFN)BmfdQueryFontData},
|
||||
};
|
||||
|
||||
|
||||
ULONG
|
||||
DbgPrint(IN PCHAR Format, IN ...)
|
||||
{
|
||||
va_list args;
|
||||
|
||||
va_start(args, Format);
|
||||
EngDebugPrint("Bmfd: ", (PCHAR)Format, args);
|
||||
va_end(args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
APIENTRY
|
||||
BmfdEnableDriver(
|
||||
ULONG iEngineVersion,
|
||||
ULONG cj,
|
||||
PDRVENABLEDATA pded)
|
||||
{
|
||||
DbgPrint("BmfdEnableDriver()\n");
|
||||
|
||||
/* Check parameter */
|
||||
if (cj < sizeof(DRVENABLEDATA))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Fill DRVENABLEDATA */
|
||||
pded->c = sizeof(gadrvfn) / sizeof(DRVFN);
|
||||
pded->pdrvfn = gadrvfn;
|
||||
pded->iDriverVersion = DDI_DRIVER_VERSION_NT5;
|
||||
|
||||
/* Success */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
DHPDEV
|
||||
APIENTRY
|
||||
BmfdEnablePDEV(
|
||||
IN DEVMODEW *pdm,
|
||||
IN LPWSTR pwszLogAddress,
|
||||
IN ULONG cPat,
|
||||
OUT HSURF *phsurfPatterns,
|
||||
IN ULONG cjCaps,
|
||||
OUT ULONG *pdevcaps,
|
||||
IN ULONG cjDevInfo,
|
||||
OUT DEVINFO *pdi,
|
||||
IN HDEV hdev,
|
||||
IN LPWSTR pwszDeviceName,
|
||||
IN HANDLE hDriver)
|
||||
{
|
||||
DbgPrint("BmfdEnablePDEV(hdev=%p)\n", hdev);
|
||||
|
||||
/* Return a dummy DHPDEV */
|
||||
return (PVOID)1;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
APIENTRY
|
||||
BmfdCompletePDEV(
|
||||
IN DHPDEV dhpdev,
|
||||
IN HDEV hdev)
|
||||
{
|
||||
DbgPrint("BmfdCompletePDEV()\n");
|
||||
/* Nothing to do */
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
APIENTRY
|
||||
BmfdDisablePDEV(
|
||||
IN DHPDEV dhpdev)
|
||||
{
|
||||
DbgPrint("BmfdDisablePDEV()\n");
|
||||
/* Nothing to do */
|
||||
}
|
682
reactos/drivers/video/font/bmfd/font.c
Normal file
682
reactos/drivers/video/font/bmfd/font.c
Normal file
|
@ -0,0 +1,682 @@
|
|||
/*
|
||||
* PROJECT: ReactOS win32 subsystem
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* PURPOSE: GDI font driver for bitmap fonts
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
#include "bmfd.h"
|
||||
|
||||
static
|
||||
BOOLEAN
|
||||
IsValidPtr(
|
||||
PVOID p,
|
||||
ULONG cjSize,
|
||||
PVOID pStart,
|
||||
PVOID pEnd,
|
||||
ULONG cjAlign)
|
||||
{
|
||||
if ((ULONG_PTR)p < (ULONG_PTR)pStart ||
|
||||
(ULONG_PTR)p + cjSize >= (ULONG_PTR)pEnd ||
|
||||
(ULONG_PTR)p & (cjAlign -1))
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
BOOL
|
||||
FillFaceInfo(
|
||||
PDRVFACE pface,
|
||||
PFONTINFO16 pFontInfo)
|
||||
{
|
||||
CHAR ansi[4];
|
||||
WCHAR unicode[4];
|
||||
ULONG written;
|
||||
DWORD dfFlags;
|
||||
|
||||
pface->pFontInfo = pFontInfo;
|
||||
pface->ulVersion = GETVAL(pFontInfo->dfVersion);
|
||||
pface->cGlyphs = pFontInfo->dfLastChar - pFontInfo->dfFirstChar + 1;
|
||||
|
||||
/* Convert chars to unicode */
|
||||
ansi[0] = pFontInfo->dfFirstChar;
|
||||
ansi[1] = pFontInfo->dfLastChar;
|
||||
ansi[2] = pFontInfo->dfFirstChar + pFontInfo->dfDefaultChar;
|
||||
ansi[3] = pFontInfo->dfFirstChar + pFontInfo->dfBreakChar;
|
||||
EngMultiByteToUnicodeN(unicode, 4 * sizeof(WCHAR), &written, ansi, 4);
|
||||
pface->wcFirstChar = unicode[0];
|
||||
pface->wcLastChar = unicode[1];
|
||||
pface->wcDefaultChar = unicode[2];
|
||||
pface->wcBreakChar = unicode[3];
|
||||
|
||||
/* Copy some values */
|
||||
pface->wPixHeight = GETVAL(pFontInfo->dfPixHeight);
|
||||
pface->wPixWidth = GETVAL(pFontInfo->dfPixWidth);
|
||||
pface->wWidthBytes = GETVAL(pFontInfo->dfWidthBytes);
|
||||
pface->wAscent = GETVAL(pFontInfo->dfAscent);
|
||||
pface->wDescent = pface->wPixHeight - pface->wAscent;
|
||||
|
||||
/* Some version specific members */
|
||||
if (pface->ulVersion >= 0x300)
|
||||
{
|
||||
dfFlags = GETVAL(pFontInfo->dfFlags);
|
||||
pface->wA = GETVAL(pFontInfo->dfAspace);
|
||||
pface->wB = GETVAL(pFontInfo->dfBspace);
|
||||
pface->wC = GETVAL(pFontInfo->dfCspace);
|
||||
pface->pCharTable = pface->pFontInfo->dfCharTable;
|
||||
pface->cjEntrySize = sizeof(GLYPHENTRY30);
|
||||
}
|
||||
else
|
||||
{
|
||||
dfFlags = DFF_1COLOR;
|
||||
pface->wA = 0;
|
||||
pface->wB = 0;
|
||||
pface->wC = 0;
|
||||
pface->pCharTable = &pface->pFontInfo->dfReserved + 1;
|
||||
pface->cjEntrySize = sizeof(GLYPHENTRY20);
|
||||
}
|
||||
|
||||
pface->flInfo = FM_INFO_MASK;
|
||||
|
||||
/* If dfWidth is non-null, we have a fixed width font */
|
||||
if (dfFlags & DFF_FIXED || pface->wPixWidth)
|
||||
pface->flInfo |= FM_INFO_CONSTANT_WIDTH;
|
||||
|
||||
/* Initialize color depth flags */
|
||||
if (dfFlags & DFF_1COLOR)
|
||||
pface->flInfo |= FM_INFO_1BPP;
|
||||
else if (dfFlags & DFF_16COLOR)
|
||||
pface->flInfo |= FM_INFO_4BPP;
|
||||
else if (dfFlags & DFF_256COLOR)
|
||||
pface->flInfo |= FM_INFO_8BPP;
|
||||
else if (dfFlags & DFF_RGBCOLOR)
|
||||
pface->flInfo |= FM_INFO_24BPP;
|
||||
|
||||
// TODO: walk through all glyphs and veryfy them and calculate max values
|
||||
|
||||
// FIXME: After this point, the whole font data should be verified!
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static
|
||||
PVOID
|
||||
ParseFntFile(
|
||||
PVOID pvView,
|
||||
ULONG cjView)
|
||||
{
|
||||
/* unimplemented */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
PVOID
|
||||
ParseFonFile(
|
||||
PVOID pvView,
|
||||
ULONG cjView)
|
||||
{
|
||||
PIMAGE_DOS_HEADER pDosHeader = pvView;
|
||||
PIMAGE_OS2_HEADER pOs2Header;
|
||||
PNE_RESTABLE pResTable;
|
||||
PNE_TYPEINFO pTInfo;
|
||||
PFONTINFO16 pFontInfo;
|
||||
PCHAR pStart, pEnd;
|
||||
PDRVFONT pfont = NULL;
|
||||
WORD wShift;
|
||||
ULONG i, cjOffset, cjLength;
|
||||
ULONG type_id, count;
|
||||
|
||||
/* Initial margins for valid pointers */
|
||||
pStart = pvView;
|
||||
pEnd = pStart + cjView;
|
||||
|
||||
/* Check for image dos header */
|
||||
if (GETVAL(pDosHeader->e_magic) != IMAGE_DOS_MAGIC)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get pointer to OS2 header and veryfy it is valid */
|
||||
pOs2Header = (PVOID)((PCHAR)pDosHeader + GETVAL(pDosHeader->e_lfanew));
|
||||
pStart += sizeof(IMAGE_DOS_HEADER);
|
||||
if (!IsValidPtr(pOs2Header, sizeof(IMAGE_OS2_HEADER), pStart, pEnd, 4))
|
||||
{
|
||||
DbgPrint("e_lfanew is invalid: 0x%lx\n", pDosHeader->e_lfanew);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get pointer to resource table and verify it is valid */
|
||||
pResTable = (PVOID)((PCHAR)pOs2Header + GETVAL(pOs2Header->ne_rsrctab));
|
||||
pStart = (PCHAR)pOs2Header;
|
||||
if (!IsValidPtr(pResTable, sizeof(NE_RESTABLE), pStart, pEnd, 1))
|
||||
{
|
||||
DbgPrint("pTInfo is invalid: 0x%p\n", pResTable);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
wShift = GETVAL(pResTable->size_shift);
|
||||
pTInfo = pResTable->typeinfo;
|
||||
type_id = GETVAL(pTInfo->type_id);
|
||||
|
||||
/* Loop the resource table to find a font resource */
|
||||
while (type_id)
|
||||
{
|
||||
/* Get number of nameinfo entries */
|
||||
count = GETVAL(pTInfo->count);
|
||||
|
||||
/* Look for a font resource */
|
||||
if (type_id == NE_RSCTYPE_FONT && count > 0)
|
||||
{
|
||||
DbgPrint("Found NE_RSCTYPE_FONT\n");
|
||||
|
||||
/* Allocate an info structure for this font and all faces */
|
||||
cjLength = sizeof(DRVFONT) + (count-1) * sizeof(DRVFACE);
|
||||
pfont = EngAllocMem(0, cjLength, TAG_FONTINFO);
|
||||
if (!pfont)
|
||||
{
|
||||
DbgPrint("Not enough memory: %ld\n", cjLength);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pfont->cNumFaces = count;
|
||||
|
||||
/* Fill all face info structures */
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
cjOffset = GETVAL(pTInfo->nameinfo[i].offset) << wShift;
|
||||
cjLength = GETVAL(pTInfo->nameinfo[i].length) << wShift;
|
||||
pFontInfo = (PVOID)((PCHAR)pDosHeader + cjOffset);
|
||||
|
||||
if (!IsValidPtr(pFontInfo, cjLength, pStart, pEnd, 1))
|
||||
{
|
||||
DbgPrint("pFontInfo is invalid: 0x%p\n", pFontInfo);
|
||||
EngFreeMem(pfont);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Validate FONTINFO and fill face info */
|
||||
if (!FillFaceInfo(&pfont->aface[i], pFontInfo))
|
||||
{
|
||||
DbgPrint("pFontInfo is invalid: 0x%p\n", pFontInfo);
|
||||
EngFreeMem(pfont);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Break out of the loop */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Following pointers must be bigger than this */
|
||||
pStart = (PCHAR)pTInfo;
|
||||
|
||||
/* Goto next entry in resource table */
|
||||
pTInfo = (PVOID)&pTInfo->nameinfo[count];
|
||||
|
||||
/* Verify that the new pTInfo pointer is valid */
|
||||
if (!IsValidPtr(pTInfo, sizeof(NE_TYPEINFO), pStart, pEnd, 1))
|
||||
{
|
||||
DbgPrint("pTInfo is invalid: 0x%p\n", pTInfo);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
type_id = GETVAL(pTInfo->type_id);
|
||||
}
|
||||
|
||||
return pfont;
|
||||
}
|
||||
|
||||
/** Public Interface **********************************************************/
|
||||
|
||||
ULONG_PTR
|
||||
APIENTRY
|
||||
BmfdLoadFontFile(
|
||||
ULONG cFiles,
|
||||
ULONG_PTR *piFile,
|
||||
PVOID *ppvView,
|
||||
ULONG *pcjView,
|
||||
DESIGNVECTOR *pdv,
|
||||
ULONG ulLangID,
|
||||
ULONG ulFastCheckSum)
|
||||
{
|
||||
PDRVFONT pfont = NULL;
|
||||
PVOID pvView;
|
||||
ULONG cjView;
|
||||
|
||||
DbgPrint("BmfdLoadFontFile()\n");
|
||||
DbgBreakPoint();
|
||||
|
||||
/* Check parameters */
|
||||
if (cFiles != 1)
|
||||
{
|
||||
DbgPrint("Only 1 File is allowed, got %ld!\n", cFiles);
|
||||
return HFF_INVALID;
|
||||
}
|
||||
|
||||
/* Map the font file */
|
||||
if (!EngMapFontFileFD(*piFile, (PULONG*)&pvView, &cjView))
|
||||
{
|
||||
DbgPrint("Could not map font file!\n", cFiles);
|
||||
return HFF_INVALID;
|
||||
}
|
||||
|
||||
DbgPrint("mapped font file to %p, site if %ld\n", pvView, cjView);
|
||||
|
||||
/* Try to parse a .fon file */
|
||||
pfont = ParseFonFile(pvView, cjView);
|
||||
|
||||
if (!pfont)
|
||||
{
|
||||
/* Could be a .fnt file */
|
||||
pfont = ParseFntFile(pvView, cjView);
|
||||
}
|
||||
|
||||
/* Check whether we succeeded finding a font */
|
||||
if (!pfont)
|
||||
{
|
||||
DbgPrint("No font data found\n");
|
||||
|
||||
/* Unmap the file */
|
||||
EngUnmapFontFileFD(*piFile);
|
||||
|
||||
/* Failure! */
|
||||
return HFF_INVALID;
|
||||
}
|
||||
|
||||
pfont->iFile = *piFile;
|
||||
pfont->pvView = pvView;
|
||||
|
||||
/* Success, return the pointer to font info structure */
|
||||
return (ULONG_PTR)pfont;
|
||||
}
|
||||
|
||||
BOOL
|
||||
APIENTRY
|
||||
BmfdUnloadFontFile(
|
||||
IN ULONG_PTR iFile)
|
||||
{
|
||||
PDRVFONT pfont = (PDRVFONT)iFile;
|
||||
|
||||
DbgPrint("BmfdUnloadFontFile()\n");
|
||||
|
||||
/* Free the memory that was allocated for the font */
|
||||
EngFreeMem(pfont);
|
||||
|
||||
/* Unmap the font file */
|
||||
EngUnmapFontFileFD(pfont->iFile);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
LONG
|
||||
APIENTRY
|
||||
BmfdQueryFontFile(
|
||||
ULONG_PTR iFile,
|
||||
ULONG ulMode,
|
||||
ULONG cjBuf,
|
||||
ULONG *pulBuf)
|
||||
{
|
||||
PDRVFONT pfont = (PDRVFONT)iFile;
|
||||
|
||||
DbgPrint("BmfdQueryFontFile()\n");
|
||||
// DbgBreakPoint();
|
||||
|
||||
switch (ulMode)
|
||||
{
|
||||
case QFF_DESCRIPTION:
|
||||
{
|
||||
/* We copy the face name of the 1st face */
|
||||
PCHAR pDesc = pfont->aface[0].pszFaceName;
|
||||
ULONG cOutSize;
|
||||
if (pulBuf)
|
||||
{
|
||||
EngMultiByteToUnicodeN((LPWSTR)pulBuf,
|
||||
cjBuf,
|
||||
&cOutSize,
|
||||
pDesc,
|
||||
strnlen(pDesc, LF_FACESIZE));
|
||||
}
|
||||
else
|
||||
{
|
||||
cOutSize = (strnlen(pDesc, LF_FACESIZE) + 1) * sizeof(WCHAR);
|
||||
}
|
||||
return cOutSize;
|
||||
}
|
||||
|
||||
case QFF_NUMFACES:
|
||||
/* return the number of faces in the file */
|
||||
return pfont->cNumFaces;
|
||||
|
||||
default:
|
||||
return FD_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
LONG
|
||||
APIENTRY
|
||||
BmfdQueryFontCaps(
|
||||
ULONG culCaps,
|
||||
ULONG *pulCaps)
|
||||
{
|
||||
DbgPrint("BmfdQueryFontCaps()\n");
|
||||
|
||||
/* We need room for 2 ULONGs */
|
||||
if (culCaps < 2)
|
||||
{
|
||||
return FD_ERROR;
|
||||
}
|
||||
|
||||
/* We only support 1 bpp */
|
||||
pulCaps[0] = 2;
|
||||
pulCaps[1] = QC_1BIT;
|
||||
|
||||
return 2;
|
||||
}
|
||||
|
||||
|
||||
PVOID
|
||||
APIENTRY
|
||||
BmfdQueryFontTree(
|
||||
DHPDEV dhpdev,
|
||||
ULONG_PTR iFile,
|
||||
ULONG iFace,
|
||||
ULONG iMode,
|
||||
ULONG_PTR *pid)
|
||||
{
|
||||
PDRVFONT pfont = (PDRVFONT)iFile;
|
||||
PDRVFACE pface;
|
||||
ULONG i, j, cjOffset, cjSize, cGlyphs, cRuns;
|
||||
CHAR ch, chFirst, ach[256];
|
||||
WCHAR wc, awc[256];
|
||||
PFD_GLYPHSET pGlyphSet;
|
||||
WCRUN *pwcrun;
|
||||
HGLYPH * phglyphs;
|
||||
|
||||
DbgPrint("DrvQueryFontTree(iMode=%ld)\n", iMode);
|
||||
DbgBreakPoint();
|
||||
|
||||
/* Check parameters, we only support QFT_GLYPHSET */
|
||||
if (!iFace || iFace > pfont->cNumFaces || iMode != QFT_GLYPHSET)
|
||||
{
|
||||
DbgPrint("iFace = %ld, cNumFaces = %ld\n", iFace, pfont->cNumFaces);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get a pointer to the face data */
|
||||
pface = &pfont->aface[iFace - 1];
|
||||
|
||||
/* Get the number of characters in the face */
|
||||
cGlyphs = pface->cGlyphs;
|
||||
|
||||
chFirst = pface->pFontInfo->dfFirstChar;
|
||||
|
||||
/* Build array of supported chars */
|
||||
for (i = 0; i < cGlyphs; i++)
|
||||
{
|
||||
ach[i] = chFirst + i;
|
||||
}
|
||||
|
||||
/* Convert the chars to unicode */
|
||||
EngMultiByteToUnicodeN(awc, sizeof(awc), NULL, ach, cGlyphs);
|
||||
|
||||
/* Sort both arrays in wchar order */
|
||||
for (i = 0; i < cGlyphs - 1; i++)
|
||||
{
|
||||
wc = awc[i];
|
||||
for (j = i + 1; j < cGlyphs; j++)
|
||||
{
|
||||
if (awc[j] < wc)
|
||||
{
|
||||
awc[i] = awc[j];
|
||||
awc[j] = wc;
|
||||
wc = awc[i];
|
||||
ch = ach[i];
|
||||
ach[i] = ach[j];
|
||||
ach[j] = ch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Find number of WCRUNs */
|
||||
cRuns = 1;
|
||||
for (i = 1; i < cGlyphs; i++)
|
||||
{
|
||||
if (awc[i] != awc[i - 1] + 1)
|
||||
{
|
||||
cRuns++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Calculate FD_GLYPHSET size */
|
||||
cjSize = sizeof(FD_GLYPHSET)
|
||||
+ (cRuns - 1) * sizeof(WCRUN)
|
||||
+ cGlyphs * sizeof(HGLYPH);
|
||||
|
||||
/* Allocate the FD_GLYPHSET structure */
|
||||
pGlyphSet = EngAllocMem(0, cjSize, TAG_GLYPHSET);
|
||||
if (!pGlyphSet)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Initialize FD_GLYPHSET */
|
||||
pGlyphSet->cjThis = cjSize;
|
||||
pGlyphSet->flAccel = 0;
|
||||
pGlyphSet->cGlyphsSupported = cGlyphs;
|
||||
pGlyphSet->cRuns = cRuns;
|
||||
|
||||
/* Initialize 1st WCRUN */
|
||||
pwcrun = pGlyphSet->awcrun;
|
||||
phglyphs = (PHGLYPH)&pGlyphSet->awcrun[cRuns];
|
||||
pwcrun[0].wcLow = awc[0];
|
||||
pwcrun[0].cGlyphs = 1;
|
||||
pwcrun[0].phg = phglyphs;
|
||||
phglyphs[0] = (HGLYPH)pface->pCharTable;
|
||||
|
||||
/* Walk through all supported chars */
|
||||
for (i = 1, j = 0; i < cGlyphs; i++)
|
||||
{
|
||||
/* Use pointer to glyph entry as hglyph */
|
||||
cjOffset = (ach[i] - chFirst) * pface->cjEntrySize;
|
||||
phglyphs[i] = (HGLYPH)pface->pCharTable + cjOffset;
|
||||
|
||||
/* Check whether we can append the wchar to a run */
|
||||
if (awc[i] == awc[i - 1] + 1)
|
||||
{
|
||||
/* Append to current WCRUN */
|
||||
pwcrun[j].cGlyphs++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Add a new WCRUN */
|
||||
j++;
|
||||
pwcrun[j].wcLow = awc[i];
|
||||
pwcrun[j].cGlyphs = 1;
|
||||
pwcrun[j].phg = &phglyphs[i];
|
||||
}
|
||||
}
|
||||
|
||||
/* Set *pid to the allocated structure for use in BmfdFree */
|
||||
*pid = (ULONG_PTR)pGlyphSet;
|
||||
|
||||
return pGlyphSet;
|
||||
}
|
||||
|
||||
PIFIMETRICS
|
||||
APIENTRY
|
||||
BmfdQueryFont(
|
||||
IN DHPDEV dhpdev,
|
||||
IN ULONG_PTR iFile,
|
||||
IN ULONG iFace,
|
||||
IN ULONG_PTR *pid)
|
||||
{
|
||||
PDRVFONT pfont = (PDRVFONT)iFile;
|
||||
PDRVFACE pface;
|
||||
PFONTINFO16 pFontInfo;
|
||||
PIFIMETRICS pifi;
|
||||
PDRVIFIMETRICS pDrvIM;
|
||||
PANOSE panose = {0};
|
||||
|
||||
DbgPrint("BmfdQueryFont()\n");
|
||||
// DbgBreakPoint();
|
||||
|
||||
/* Validate parameters */
|
||||
if (iFace > pfont->cNumFaces || !pid)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pface = &pfont->aface[iFace - 1];
|
||||
pFontInfo = pface->pFontInfo;
|
||||
|
||||
/* Allocate the structure */
|
||||
pDrvIM = EngAllocMem(FL_ZERO_MEMORY, sizeof(DRVIFIMETRICS), TAG_IFIMETRICS);
|
||||
if (!pDrvIM)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Return a pointer to free it later */
|
||||
*pid = (ULONG_PTR)pDrvIM;
|
||||
|
||||
/* Fill IFIMETRICS */
|
||||
pifi = &pDrvIM->ifim;
|
||||
pifi->cjThis = sizeof(DRVIFIMETRICS);
|
||||
pifi->cjIfiExtra = 0;
|
||||
pifi->dpwszFamilyName = FIELD_OFFSET(DRVIFIMETRICS, wszFamilyName);
|
||||
pifi->dpwszStyleName = FIELD_OFFSET(DRVIFIMETRICS, wszFamilyName);
|
||||
pifi->dpwszFaceName = FIELD_OFFSET(DRVIFIMETRICS, wszFaceName);
|
||||
pifi->dpwszUniqueName = FIELD_OFFSET(DRVIFIMETRICS, wszFaceName);
|
||||
pifi->dpFontSim = 0;
|
||||
pifi->lEmbedId = 0;
|
||||
pifi->lItalicAngle = 0;
|
||||
pifi->lCharBias = 0;
|
||||
pifi->dpCharSets = 0;
|
||||
pifi->jWinCharSet = pFontInfo->dfCharSet;
|
||||
pifi->jWinPitchAndFamily = pFontInfo->dfPitchAndFamily;
|
||||
pifi->usWinWeight = GETVAL(pFontInfo->dfWeight);
|
||||
pifi->flInfo = pface->flInfo;
|
||||
pifi->fsSelection = 0;
|
||||
pifi->fsType = 0;
|
||||
pifi->fwdUnitsPerEm = GETVAL(pFontInfo->dfPixHeight);
|
||||
pifi->fwdLowestPPEm = 0;
|
||||
pifi->fwdWinAscender = GETVAL(pFontInfo->dfAscent);
|
||||
pifi->fwdWinDescender = pifi->fwdUnitsPerEm - pifi->fwdWinAscender;
|
||||
pifi->fwdMacAscender = pifi->fwdWinAscender;
|
||||
pifi->fwdMacDescender = - pifi->fwdWinDescender;
|
||||
pifi->fwdMacLineGap = 0;
|
||||
pifi->fwdTypoAscender = pifi->fwdWinAscender;
|
||||
pifi->fwdTypoDescender = - pifi->fwdWinDescender;
|
||||
pifi->fwdTypoLineGap = 0;
|
||||
pifi->fwdAveCharWidth = GETVAL(pFontInfo->dfAvgWidth);
|
||||
pifi->fwdMaxCharInc = GETVAL(pFontInfo->dfMaxWidth);
|
||||
pifi->fwdCapHeight = pifi->fwdUnitsPerEm / 2;
|
||||
pifi->fwdXHeight = pifi->fwdUnitsPerEm / 4;
|
||||
pifi->fwdSubscriptXSize = 0;
|
||||
pifi->fwdSubscriptYSize = 0;
|
||||
pifi->fwdSubscriptXOffset = 0;
|
||||
pifi->fwdSubscriptYOffset = 0;
|
||||
pifi->fwdSuperscriptXSize = 0;
|
||||
pifi->fwdSuperscriptYSize = 0;
|
||||
pifi->fwdSuperscriptXOffset = 0;
|
||||
pifi->fwdSuperscriptYOffset = 0;
|
||||
pifi->fwdUnderscoreSize = 01;
|
||||
pifi->fwdUnderscorePosition = -1;
|
||||
pifi->fwdStrikeoutSize = 1;
|
||||
pifi->fwdStrikeoutPosition = pifi->fwdXHeight + 1;
|
||||
pifi->chFirstChar = pFontInfo->dfFirstChar;
|
||||
pifi->chLastChar = pFontInfo->dfLastChar;
|
||||
pifi->chDefaultChar = pFontInfo->dfFirstChar + pFontInfo->dfDefaultChar;
|
||||
pifi->chBreakChar = pFontInfo->dfFirstChar + pFontInfo->dfBreakChar;
|
||||
pifi->wcFirstChar = pface->wcFirstChar;
|
||||
pifi->wcLastChar = pface->wcLastChar;
|
||||
pifi->wcDefaultChar = pface->wcDefaultChar;
|
||||
pifi->wcBreakChar = pface->wcBreakChar;
|
||||
pifi->ptlBaseline.x = 1;
|
||||
pifi->ptlBaseline.y = 0;
|
||||
pifi->ptlAspect.x = pFontInfo->dfVertRes; // CHECKME
|
||||
pifi->ptlAspect.y = pFontInfo->dfHorizRes;
|
||||
pifi->ptlCaret.x = 0;
|
||||
pifi->ptlCaret.y = 1;
|
||||
pifi->rclFontBox.left = 0;
|
||||
pifi->rclFontBox.right = pifi->fwdAveCharWidth;
|
||||
pifi->rclFontBox.top = pifi->fwdWinAscender;
|
||||
pifi->rclFontBox.bottom = - pifi->fwdWinDescender;
|
||||
*(DWORD*)&pifi->achVendId = 0x30303030; // FIXME
|
||||
pifi->cKerningPairs = 0;
|
||||
pifi->ulPanoseCulture = FM_PANOSE_CULTURE_LATIN;
|
||||
pifi->panose = panose;
|
||||
|
||||
/* Set char sets */
|
||||
pDrvIM->ajCharSet[0] = pifi->jWinCharSet;
|
||||
pDrvIM->ajCharSet[1] = DEFAULT_CHARSET;
|
||||
|
||||
if (pface->flInfo & FM_INFO_CONSTANT_WIDTH)
|
||||
pifi->jWinPitchAndFamily |= FIXED_PITCH;
|
||||
|
||||
#if 0
|
||||
EngMultiByteToUnicodeN(pDrvIM->wszFaceName,
|
||||
LF_FACESIZE * sizeof(WCHAR),
|
||||
NULL,
|
||||
pFontInfo->,
|
||||
strnlen(pDesc, LF_FACESIZE));
|
||||
#endif
|
||||
wcscpy(pDrvIM->wszFaceName, L"Courier-X");
|
||||
wcscpy(pDrvIM->wszFamilyName, L"Courier-X");
|
||||
|
||||
/* Initialize font weight style flags and string */
|
||||
if (pifi->usWinWeight == FW_REGULAR)
|
||||
{
|
||||
// pifi->fsSelection |= FM_SEL_REGULAR;
|
||||
}
|
||||
else if (pifi->usWinWeight > FW_SEMIBOLD)
|
||||
{
|
||||
pifi->fsSelection |= FM_SEL_BOLD;
|
||||
wcscat(pDrvIM->wszStyleName, L"Bold ");
|
||||
}
|
||||
else if (pifi->usWinWeight <= FW_LIGHT)
|
||||
{
|
||||
wcscat(pDrvIM->wszStyleName, L"Light ");
|
||||
}
|
||||
|
||||
if (pFontInfo->dfItalic)
|
||||
{
|
||||
pifi->fsSelection |= FM_SEL_ITALIC;
|
||||
wcscat(pDrvIM->wszStyleName, L"Italic ");
|
||||
}
|
||||
|
||||
if (pFontInfo->dfUnderline)
|
||||
{
|
||||
pifi->fsSelection |= FM_SEL_UNDERSCORE;
|
||||
wcscat(pDrvIM->wszStyleName, L"Underscore ");
|
||||
}
|
||||
|
||||
if (pFontInfo->dfStrikeOut)
|
||||
{
|
||||
pifi->fsSelection |= FM_SEL_STRIKEOUT;
|
||||
wcscat(pDrvIM->wszStyleName, L"Strikeout ");
|
||||
}
|
||||
|
||||
return pifi;
|
||||
}
|
||||
|
||||
|
||||
VOID
|
||||
APIENTRY
|
||||
BmfdFree(
|
||||
PVOID pv,
|
||||
ULONG_PTR id)
|
||||
{
|
||||
DbgPrint("BmfdFree()\n");
|
||||
if (id)
|
||||
{
|
||||
EngFreeMem((PVOID)id);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
192
reactos/drivers/video/font/bmfd/glyph.c
Normal file
192
reactos/drivers/video/font/bmfd/glyph.c
Normal file
|
@ -0,0 +1,192 @@
|
|||
/*
|
||||
* PROJECT: ReactOS win32 subsystem
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* PURPOSE: GDI font driver for bitmap fonts
|
||||
* PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||
*/
|
||||
|
||||
#include "bmfd.h"
|
||||
|
||||
static
|
||||
VOID
|
||||
FillFDDM(
|
||||
PFD_DEVICEMETRICS pfddm,
|
||||
PFONTINFO16 pFontInfo)
|
||||
{
|
||||
/* Fill FD_DEVICEMETRICS */
|
||||
pfddm->flRealizedType = FDM_MASK;
|
||||
pfddm->pteBase.x = FLOATL_1;
|
||||
pfddm->pteBase.y = 0;
|
||||
pfddm->pteSide.x = 0;
|
||||
pfddm->pteSide.y = FLOATL_1;
|
||||
pfddm->ptlUnderline1.x = 0;
|
||||
pfddm->ptlUnderline1.y = 1;
|
||||
pfddm->ptlStrikeout.x = 0;
|
||||
pfddm->ptlStrikeout.y = -4;
|
||||
pfddm->ptlULThickness.x = 0;
|
||||
pfddm->ptlULThickness.y = 1;
|
||||
pfddm->ptlSOThickness.x = 0;
|
||||
pfddm->ptlSOThickness.y = 1;
|
||||
pfddm->lD = GETVAL(pFontInfo->dfPixWidth);
|
||||
pfddm->cxMax = GETVAL(pFontInfo->dfMaxWidth);
|
||||
pfddm->cyMax = GETVAL(pFontInfo->dfPixHeight);
|
||||
pfddm->cjGlyphMax = pfddm->cyMax * ((pfddm->cxMax + 7) / 8);
|
||||
pfddm->fxMaxAscender = GETVAL(pFontInfo->dfAscent) << 4;
|
||||
pfddm->fxMaxDescender = (pfddm->cyMax << 4) - pfddm->fxMaxAscender;
|
||||
pfddm->lMinA = 0;
|
||||
pfddm->lMinC = 0;
|
||||
pfddm->lMinD = 0;
|
||||
|
||||
/* NOTE: fdxQuantized and NonLinear... stay unchanged */
|
||||
}
|
||||
|
||||
/** Public Interface **********************************************************/
|
||||
|
||||
PFD_GLYPHATTR
|
||||
APIENTRY
|
||||
BmfdQueryGlyphAttrs(
|
||||
FONTOBJ *pfo,
|
||||
ULONG iMode)
|
||||
{
|
||||
DbgPrint("BmfdQueryGlyphAttrs()\n");
|
||||
/* We don't support FO_ATTR_MODE_ROTATE */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LONG
|
||||
APIENTRY
|
||||
BmfdQueryFontData(
|
||||
DHPDEV dhpdev,
|
||||
FONTOBJ *pfo,
|
||||
ULONG iMode,
|
||||
HGLYPH hg,
|
||||
OUT GLYPHDATA *pgd,
|
||||
PVOID pv,
|
||||
ULONG cjSize)
|
||||
{
|
||||
PDRVFONT pfont = (PDRVFONT)pfo->iFile;
|
||||
PDRVFACE pface = &pfont->aface[pfo->iFace - 1];
|
||||
PGLYPHENTRY pge = (PGLYPHENTRY)hg;
|
||||
ULONG ulGlyphOffset, ulWidthBytes, ulPixWidth, ulPixHeight, x, y, cjRow;
|
||||
|
||||
DbgPrint("BmfdQueryFontData(pfo=%p, iMode=%ld, hg=%p, pgd=%p, pv=%p, cjSize=%ld)\n",
|
||||
pfo, iMode, hg, pgd, pv, cjSize);
|
||||
// DbgBreakPoint();
|
||||
|
||||
switch (iMode)
|
||||
{
|
||||
case QFD_GLYPHANDBITMAP: /* 1 */
|
||||
{
|
||||
GLYPHBITS *pgb = pv;
|
||||
BYTE j, *pjGlyphBits;
|
||||
|
||||
// DbgPrint("QFD_GLYPHANDBITMAP, hg=%p, pgd=%p, pv=%p, cjSize=%d\n",
|
||||
// hg, pgd, pv, cjSize);
|
||||
|
||||
if (!hg)
|
||||
{
|
||||
DbgPrint("no glyph handle given!\n");
|
||||
return FD_ERROR;
|
||||
}
|
||||
|
||||
/* Get the bitmap offset depending on file version */
|
||||
if (pface->ulVersion >= 0x300)
|
||||
{
|
||||
ulPixWidth = GETVAL(pge->ge20.geWidth);
|
||||
ulGlyphOffset = GETVAL(pge->ge30.geOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
ulPixWidth = GETVAL(pge->ge30.geWidth);
|
||||
ulGlyphOffset = GETVAL(pge->ge20.geOffset);
|
||||
}
|
||||
ulPixHeight = pface->wPixHeight;
|
||||
|
||||
/* Calculate number of bytes per row for gdi */
|
||||
cjRow = (ulPixWidth + 7) / 8; // FIXME: other bpp values
|
||||
|
||||
if (pgd)
|
||||
{
|
||||
/* Fill GLYPHDATA structure */
|
||||
pgd->gdf.pgb = pgb;
|
||||
pgd->hg = hg;
|
||||
pgd->fxD = (pface->wA + ulPixWidth + pface->wC) << 4;
|
||||
pgd->fxA = pface->wA << 4;
|
||||
pgd->fxAB = (pface->wA + ulPixWidth) << 4;
|
||||
pgd->fxInkTop = pface->wAscent << 4;
|
||||
pgd->fxInkBottom = - (pface->wDescent << 4);
|
||||
pgd->rclInk.top = - pface->wAscent;
|
||||
pgd->rclInk.bottom = pface->wDescent ;
|
||||
pgd->rclInk.left = pface->wA;
|
||||
pgd->rclInk.right = pface->wA + ulPixWidth;
|
||||
pgd->ptqD.x.LowPart = 0;
|
||||
pgd->ptqD.x.HighPart = pgd->fxD;
|
||||
pgd->ptqD.y.LowPart = 0;
|
||||
pgd->ptqD.y.HighPart = 0;
|
||||
}
|
||||
|
||||
if (pgb)
|
||||
{
|
||||
// DbgBreakPoint();
|
||||
|
||||
/* Verify that the buffer is big enough */
|
||||
if (cjSize < ulPixHeight * cjRow)
|
||||
{
|
||||
DbgPrint("Buffer too small (%ld), %ld,%ld\n",
|
||||
cjSize, ulPixWidth, ulPixHeight);
|
||||
return FD_ERROR;
|
||||
}
|
||||
|
||||
/* Fill GLYPHBITS structure */
|
||||
pgb->ptlOrigin.x = pface->wA;
|
||||
pgb->ptlOrigin.y = - pface->wAscent;
|
||||
pgb->sizlBitmap.cx = ulPixWidth;
|
||||
pgb->sizlBitmap.cy = ulPixHeight;
|
||||
|
||||
/* Copy the bitmap bits */
|
||||
pjGlyphBits = (PBYTE)pface->pFontInfo + ulGlyphOffset;
|
||||
ulWidthBytes = pface->wWidthBytes;
|
||||
for (y = 0; y < ulPixHeight; y++)
|
||||
{
|
||||
for (x = 0; x < cjRow; x++)
|
||||
{
|
||||
j = pjGlyphBits[x * ulPixHeight + y];
|
||||
pgb->aj[y * cjRow + x] = j;
|
||||
}
|
||||
}
|
||||
|
||||
DbgPrint("iFace=%ld, ulGlyphOffset=%lx, ulPixHeight=%ld, cjRow=%ld\n",
|
||||
pfo->iFace, ulGlyphOffset, ulPixHeight, cjRow);
|
||||
DbgBreakPoint();
|
||||
}
|
||||
|
||||
/* Return the size of the bitmap buffer */
|
||||
return ulPixHeight * cjRow;
|
||||
}
|
||||
|
||||
case QFD_MAXEXTENTS: /* 3 */
|
||||
{
|
||||
if (pv)
|
||||
{
|
||||
if (cjSize < sizeof(FD_DEVICEMETRICS))
|
||||
{
|
||||
/* Not enough space, fail */
|
||||
return FD_ERROR;
|
||||
}
|
||||
|
||||
/* Fill the PFD_DEVICEMETRICS structure */
|
||||
FillFDDM((PFD_DEVICEMETRICS)pv, pface->pFontInfo);
|
||||
}
|
||||
|
||||
/* Return the size of the structure */
|
||||
return sizeof(FD_DEVICEMETRICS);
|
||||
}
|
||||
|
||||
/* we support nothing else */
|
||||
default:
|
||||
return FD_ERROR;
|
||||
|
||||
}
|
||||
|
||||
return FD_ERROR;
|
||||
}
|
8
reactos/drivers/video/font/directory.rbuild
Normal file
8
reactos/drivers/video/font/directory.rbuild
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE group SYSTEM "../../tools/rbuild/project.dtd">
|
||||
<group xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
<directory name="bmfd">
|
||||
<xi:include href="bmfd/bmfd.rbuild" />
|
||||
</directory>
|
||||
</group>
|
||||
|
Loading…
Reference in a new issue