mirror of
https://github.com/reactos/reactos.git
synced 2025-05-31 23:18:39 +00:00
Initial font and text support. Fixes to color palette support. Mask and transparent blt support.
svn path=/trunk/; revision=1861
This commit is contained in:
parent
b27e3264a9
commit
c84d5016d1
15 changed files with 484 additions and 176 deletions
|
@ -92,6 +92,31 @@ BOOLEAN DIB_To_4BPP_Bitblt( SURFOBJ *DestSurf, SURFOBJ *SourceSurf,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
SourceBits_8BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x;
|
||||||
|
|
||||||
|
for (j=DestRect->top; j<DestRect->bottom; j++)
|
||||||
|
{
|
||||||
|
SourceLine_8BPP = SourceBits_8BPP;
|
||||||
|
DestLine = DestBits;
|
||||||
|
sx = SourcePoint->x;
|
||||||
|
f1 = sx & 1;
|
||||||
|
f2 = DestRect->left & 1;
|
||||||
|
|
||||||
|
for (i=DestRect->left; i<DestRect->right; i++)
|
||||||
|
{
|
||||||
|
*DestLine = (*DestLine & notmask[i&1]) |
|
||||||
|
((XLATEOBJ_iXlate(ColorTranslation, *SourceLine_8BPP)) << ((4 * (1-(sx & 1)))));
|
||||||
|
if(f2 == 1) { DestLine++; f2 = 0; } else { f2 = 1; }
|
||||||
|
SourceLine_8BPP++;
|
||||||
|
sx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
SourceBits_8BPP += SourceSurf->lDelta;
|
||||||
|
DestBits += DestSurf->lDelta;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case 24:
|
case 24:
|
||||||
SourceBits_24BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x * 3;
|
SourceBits_24BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x * 3;
|
||||||
|
|
||||||
|
|
|
@ -49,13 +49,13 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
|
||||||
BOOL EnumMore;
|
BOOL EnumMore;
|
||||||
PSURFGDI DestGDI, SourceGDI;
|
PSURFGDI DestGDI, SourceGDI;
|
||||||
HSURF hTemp;
|
HSURF hTemp;
|
||||||
PSURFOBJ TempSurf;
|
PSURFOBJ TempSurf = NULL;
|
||||||
BOOLEAN canCopyBits;
|
BOOLEAN canCopyBits;
|
||||||
POINTL TempPoint;
|
POINTL TempPoint;
|
||||||
RECTL TempRect;
|
RECTL TempRect;
|
||||||
SIZEL TempSize;
|
SIZEL TempSize;
|
||||||
|
|
||||||
SourceGDI = AccessInternalObjectFromUserObject(Source);
|
if(Source != NULL) SourceGDI = AccessInternalObjectFromUserObject(Source);
|
||||||
|
|
||||||
// If we don't have to do anything special, we can punt to DrvCopyBits
|
// If we don't have to do anything special, we can punt to DrvCopyBits
|
||||||
// if it exists
|
// if it exists
|
||||||
|
@ -75,23 +75,26 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
|
||||||
|
|
||||||
if (DestGDI->BitBlt!=NULL)
|
if (DestGDI->BitBlt!=NULL)
|
||||||
{
|
{
|
||||||
// The destination is device managed, therefore get the source into a format compatible surface
|
if (Source!=NULL)
|
||||||
TempPoint.x = 0;
|
{
|
||||||
TempPoint.y = 0;
|
// Get the source into a format compatible surface
|
||||||
TempRect.top = 0;
|
TempPoint.x = 0;
|
||||||
TempRect.left = 0;
|
TempPoint.y = 0;
|
||||||
TempRect.bottom = DestRect->bottom - DestRect->top;
|
TempRect.top = 0;
|
||||||
TempRect.right = DestRect->right - DestRect->left;
|
TempRect.left = 0;
|
||||||
TempSize.cx = TempRect.right;
|
TempRect.bottom = DestRect->bottom - DestRect->top;
|
||||||
TempSize.cy = TempRect.bottom;
|
TempRect.right = DestRect->right - DestRect->left;
|
||||||
|
TempSize.cx = TempRect.right;
|
||||||
|
TempSize.cy = TempRect.bottom;
|
||||||
|
|
||||||
hTemp = EngCreateBitmap(TempSize,
|
hTemp = EngCreateBitmap(TempSize,
|
||||||
DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)),
|
DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)),
|
||||||
Dest->iBitmapFormat, 0, NULL);
|
Dest->iBitmapFormat, 0, NULL);
|
||||||
TempSurf = AccessUserObject(hTemp);
|
TempSurf = AccessUserObject(hTemp);
|
||||||
|
|
||||||
// FIXME: Skip creating a TempSurf if we have the same BPP and palette
|
// FIXME: Skip creating a TempSurf if we have the same BPP and palette
|
||||||
EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, SourcePoint, NULL, NULL, NULL, 0);
|
EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, SourcePoint, NULL, NULL, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion,
|
return DestGDI->BitBlt(Dest, TempSurf, Mask, ClipRegion,
|
||||||
NULL, DestRect, &TempPoint,
|
NULL, DestRect, &TempPoint,
|
||||||
|
|
|
@ -22,6 +22,7 @@ BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush,
|
||||||
if(Surface->iType!=STYPE_BITMAP)
|
if(Surface->iType!=STYPE_BITMAP)
|
||||||
{
|
{
|
||||||
// Call the driver's DrvLineTo
|
// Call the driver's DrvLineTo
|
||||||
|
DbgPrint("calling surfgdi's lineto\n");
|
||||||
return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
|
return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
* 21/8/1999: Created
|
* 21/8/1999: Created
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <freetype/freetype.h>
|
||||||
|
|
||||||
typedef struct _BRUSHGDI {
|
typedef struct _BRUSHGDI {
|
||||||
|
|
||||||
} BRUSHGDI;
|
} BRUSHGDI;
|
||||||
|
@ -32,8 +34,10 @@ typedef struct _FLOATGDI {
|
||||||
} FLOATGDI;
|
} FLOATGDI;
|
||||||
|
|
||||||
typedef struct _FONTGDI {
|
typedef struct _FONTGDI {
|
||||||
|
LPCWSTR Filename;
|
||||||
} FONTGDI;
|
FT_Face face;
|
||||||
|
TEXTMETRIC TextMetric;
|
||||||
|
} FONTGDI, *PFONTGDI;
|
||||||
|
|
||||||
typedef struct _PALGDI {
|
typedef struct _PALGDI {
|
||||||
ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
|
ULONG Mode; // PAL_INDEXED, PAL_BITFIELDS, PAL_RGB, PAL_BGR
|
||||||
|
@ -56,6 +60,8 @@ typedef BOOL (*PFN_BitBlt)(PSURFOBJ, PSURFOBJ, PSURFOBJ, PCLIPOBJ,
|
||||||
PXLATEOBJ, PRECTL, PPOINTL, PPOINTL,
|
PXLATEOBJ, PRECTL, PPOINTL, PPOINTL,
|
||||||
PBRUSHOBJ, PPOINTL, ROP4);
|
PBRUSHOBJ, PPOINTL, ROP4);
|
||||||
|
|
||||||
|
typedef BOOL (*PFN_TransparentBlt)(PSURFOBJ, PSURFOBJ, PCLIPOBJ, PXLATEOBJ, PRECTL, PRECTL, ULONG, ULONG);
|
||||||
|
|
||||||
typedef BOOL (*PFN_StretchBlt)(PSURFOBJ, PSURFOBJ, PSURFOBJ, PCLIPOBJ,
|
typedef BOOL (*PFN_StretchBlt)(PSURFOBJ, PSURFOBJ, PSURFOBJ, PCLIPOBJ,
|
||||||
PXLATEOBJ, PCOLORADJUSTMENT, PPOINTL,
|
PXLATEOBJ, PCOLORADJUSTMENT, PPOINTL,
|
||||||
PRECTL, PRECTL, PPOINT, ULONG);
|
PRECTL, PRECTL, PPOINT, ULONG);
|
||||||
|
@ -94,6 +100,7 @@ typedef struct _SURFGDI {
|
||||||
INT BitsPerPixel;
|
INT BitsPerPixel;
|
||||||
|
|
||||||
PFN_BitBlt BitBlt;
|
PFN_BitBlt BitBlt;
|
||||||
|
PFN_TransparentBlt TransparentBlt;
|
||||||
PFN_StretchBlt StretchBlt;
|
PFN_StretchBlt StretchBlt;
|
||||||
PFN_TextOut TextOut;
|
PFN_TextOut TextOut;
|
||||||
PFN_Paint Paint;
|
PFN_Paint Paint;
|
||||||
|
|
|
@ -56,7 +56,7 @@ BOOL EngDeletePalette(IN HPALETTE Palette)
|
||||||
PALGDI *PalGDI;
|
PALGDI *PalGDI;
|
||||||
|
|
||||||
PalGDI = AccessInternalObject(Palette);
|
PalGDI = AccessInternalObject(Palette);
|
||||||
PalObj = AccessInternalObject(Palette);
|
PalObj = AccessUserObject(Palette);
|
||||||
|
|
||||||
EngFreeMem(PalGDI);
|
EngFreeMem(PalGDI);
|
||||||
EngFreeMem(PalObj);
|
EngFreeMem(PalObj);
|
||||||
|
|
|
@ -60,6 +60,7 @@ VOID InitializeHooks(SURFGDI *SurfGDI)
|
||||||
SurfGDI->CopyBits = NULL;
|
SurfGDI->CopyBits = NULL;
|
||||||
SurfGDI->CreateDeviceBitmap = NULL;
|
SurfGDI->CreateDeviceBitmap = NULL;
|
||||||
SurfGDI->SetPalette = NULL;
|
SurfGDI->SetPalette = NULL;
|
||||||
|
SurfGDI->TransparentBlt = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL Size, ULONG Format)
|
HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL Size, ULONG Format)
|
||||||
|
@ -90,6 +91,7 @@ HBITMAP EngCreateBitmap(IN SIZEL Size,
|
||||||
NewBitmap = (PVOID)CreateGDIHandle(SurfGDI, SurfObj);
|
NewBitmap = (PVOID)CreateGDIHandle(SurfGDI, SurfObj);
|
||||||
|
|
||||||
InitializeHooks(SurfGDI);
|
InitializeHooks(SurfGDI);
|
||||||
|
|
||||||
SurfGDI->BitsPerPixel = BitsPerFormat(Format);
|
SurfGDI->BitsPerPixel = BitsPerFormat(Format);
|
||||||
SurfObj->lDelta = Width;
|
SurfObj->lDelta = Width;
|
||||||
SurfObj->cjBits = SurfObj->lDelta * Size.cy;
|
SurfObj->cjBits = SurfObj->lDelta * Size.cy;
|
||||||
|
@ -174,6 +176,7 @@ BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks)
|
||||||
|
|
||||||
// Hook up specified functions
|
// Hook up specified functions
|
||||||
if(Hooks & HOOK_BITBLT) SurfGDI->BitBlt = Dc->DriverFunctions.BitBlt;
|
if(Hooks & HOOK_BITBLT) SurfGDI->BitBlt = Dc->DriverFunctions.BitBlt;
|
||||||
|
if(Hooks & HOOK_TRANSPARENTBLT) SurfGDI->TransparentBlt = Dc->DriverFunctions.TransparentBlt;
|
||||||
if(Hooks & HOOK_STRETCHBLT) SurfGDI->StretchBlt = Dc->DriverFunctions.StretchBlt;
|
if(Hooks & HOOK_STRETCHBLT) SurfGDI->StretchBlt = Dc->DriverFunctions.StretchBlt;
|
||||||
if(Hooks & HOOK_TEXTOUT) SurfGDI->TextOut = Dc->DriverFunctions.TextOut;
|
if(Hooks & HOOK_TEXTOUT) SurfGDI->TextOut = Dc->DriverFunctions.TextOut;
|
||||||
if(Hooks & HOOK_PAINT) SurfGDI->Paint = Dc->DriverFunctions.Paint;
|
if(Hooks & HOOK_PAINT) SurfGDI->Paint = Dc->DriverFunctions.Paint;
|
||||||
|
|
69
reactos/subsys/win32k/eng/transblt.c
Normal file
69
reactos/subsys/win32k/eng/transblt.c
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* COPYRIGHT: See COPYING in the top level directory
|
||||||
|
* PROJECT: ReactOS kernel
|
||||||
|
* PURPOSE: GDI TransparentBlt Function
|
||||||
|
* FILE: subsys/win32k/eng/transblt.c
|
||||||
|
* PROGRAMER: Jason Filby
|
||||||
|
* REVISION HISTORY:
|
||||||
|
* 4/6/2001: Created
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <ddk/winddi.h>
|
||||||
|
#include <ddk/ntddk.h>
|
||||||
|
#include <ntos/minmax.h>
|
||||||
|
#include "brush.h"
|
||||||
|
#include "enum.h"
|
||||||
|
#include "objects.h"
|
||||||
|
|
||||||
|
BOOL EngTransparentBlt(PSURFOBJ Dest, PSURFOBJ Source,
|
||||||
|
PCLIPOBJ Clip, PXLATEOBJ ColorTranslation,
|
||||||
|
PRECTL DestRect, PRECTL SourceRect,
|
||||||
|
ULONG TransparentColor, ULONG Reserved)
|
||||||
|
{
|
||||||
|
PSURFGDI DestGDI = AccessInternalObjectFromUserObject(Dest);
|
||||||
|
HSURF hTemp;
|
||||||
|
PSURFOBJ TempSurf;
|
||||||
|
POINTL TempPoint, SourcePoint;
|
||||||
|
RECTL TempRect;
|
||||||
|
SIZEL TempSize;
|
||||||
|
LONG dx, dy, sx, sy;
|
||||||
|
|
||||||
|
dx = abs(DestRect->right - DestRect->left);
|
||||||
|
dy = abs(DestRect->bottom - DestRect->top);
|
||||||
|
|
||||||
|
sx = abs(SourceRect->right - SourceRect->left);
|
||||||
|
sy = abs(SourceRect->bottom - SourceRect->top);
|
||||||
|
|
||||||
|
if(sx<dx) dx = sx;
|
||||||
|
if(sy<dy) dy = sy;
|
||||||
|
|
||||||
|
if(DestGDI->TransparentBlt != NULL)
|
||||||
|
{
|
||||||
|
// The destination is device managed, therefore get the source into a format compatible surface
|
||||||
|
TempPoint.x = 0;
|
||||||
|
TempPoint.y = 0;
|
||||||
|
TempRect.top = 0;
|
||||||
|
TempRect.left = 0;
|
||||||
|
TempRect.bottom = dy;
|
||||||
|
TempRect.right = dx;
|
||||||
|
TempSize.cx = TempRect.right;
|
||||||
|
TempSize.cy = TempRect.bottom;
|
||||||
|
|
||||||
|
hTemp = EngCreateBitmap(TempSize,
|
||||||
|
DIB_GetDIBWidthBytes(dx, BitsPerFormat(Dest->iBitmapFormat)), Dest->iBitmapFormat, 0, NULL);
|
||||||
|
TempSurf = AccessUserObject(hTemp);
|
||||||
|
|
||||||
|
SourcePoint.x = SourceRect->left;
|
||||||
|
SourcePoint.y = SourceRect->top;
|
||||||
|
|
||||||
|
// FIXME: Skip creating a TempSurf if we have the same BPP and palette
|
||||||
|
EngBitBlt(TempSurf, Source, NULL, NULL, ColorTranslation, &TempRect, &SourcePoint, NULL, NULL, NULL, 0);
|
||||||
|
|
||||||
|
return DestGDI->TransparentBlt(Dest, TempSurf, Clip, NULL, DestRect, SourceRect,
|
||||||
|
TransparentColor, Reserved);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Simulate a transparent blt
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
|
@ -8,6 +8,8 @@
|
||||||
* 8/20/1999: Created
|
* 8/20/1999: Created
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// TODO: Cache XLATEOBJs that are created by EngCreateXlate by checking if the given palettes match a cached list
|
||||||
|
|
||||||
#include <ddk/ntddk.h>
|
#include <ddk/ntddk.h>
|
||||||
#include <ddk/winddi.h>
|
#include <ddk/winddi.h>
|
||||||
#include <ddk/ntddvid.h>
|
#include <ddk/ntddvid.h>
|
||||||
|
@ -46,8 +48,8 @@ ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors,
|
||||||
{
|
{
|
||||||
PVIDEO_CLUTDATA cSourceColor;
|
PVIDEO_CLUTDATA cSourceColor;
|
||||||
PVIDEO_CLUTDATA cDestColors;
|
PVIDEO_CLUTDATA cDestColors;
|
||||||
ULONG bestMatch = 256, idx = 0, i;
|
LONG idx = 0, i, rt;
|
||||||
ULONG rt;
|
ULONG cxRed, cxGreen, cxBlue, BestMatch = 65535;
|
||||||
|
|
||||||
// Simple cache -- only one value because we don't want to waste time
|
// Simple cache -- only one value because we don't want to waste time
|
||||||
// if the colors aren't very sequential
|
// if the colors aren't very sequential
|
||||||
|
@ -58,19 +60,20 @@ ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors,
|
||||||
}
|
}
|
||||||
|
|
||||||
cSourceColor = &SourceColor;
|
cSourceColor = &SourceColor;
|
||||||
|
|
||||||
for (i=0; i<NumColors; i++)
|
for (i=0; i<NumColors; i++)
|
||||||
{
|
{
|
||||||
cDestColors = &DestColors[i];
|
cDestColors = &DestColors[i];
|
||||||
|
|
||||||
rt = ( abs(cSourceColor->Red - cDestColors->Red) +
|
cxRed = abs(cSourceColor->Red - cDestColors->Red) ^ 2;
|
||||||
abs(cSourceColor->Green - cDestColors->Green) +
|
cxGreen = abs(cSourceColor->Green - cDestColors->Green) ^ 2;
|
||||||
abs(cSourceColor->Blue - cDestColors->Blue) ) / 3;
|
cxBlue = abs(cSourceColor->Blue - cDestColors->Blue) ^ 2;
|
||||||
|
|
||||||
if(rt<=bestMatch)
|
rt = /* sqrt */ (cxRed + cxGreen + cxBlue);
|
||||||
|
|
||||||
|
if(rt<=BestMatch)
|
||||||
{
|
{
|
||||||
idx = i;
|
idx = i;
|
||||||
bestMatch = rt;
|
BestMatch = rt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -132,8 +135,17 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
|
||||||
if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
|
if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
|
||||||
{
|
{
|
||||||
XlateObj->flXlate |= XO_TABLE;
|
XlateObj->flXlate |= XO_TABLE;
|
||||||
if (SourcePalType == PAL_INDEXED) IndexedColors = SourcePalGDI->NumColors;
|
if ((SourcePalType == PAL_INDEXED) && (DestPalType == PAL_INDEXED))
|
||||||
if (DestPalType == PAL_INDEXED) IndexedColors = DestPalGDI->NumColors;
|
{
|
||||||
|
if(SourcePalGDI->NumColors > DestPalGDI->NumColors)
|
||||||
|
{
|
||||||
|
IndexedColors = SourcePalGDI->NumColors;
|
||||||
|
} else
|
||||||
|
IndexedColors = DestPalGDI->NumColors;
|
||||||
|
}
|
||||||
|
else if (SourcePalType == PAL_INDEXED) { IndexedColors = SourcePalGDI->NumColors; }
|
||||||
|
else if (DestPalType == PAL_INDEXED) { IndexedColors = DestPalGDI->NumColors; }
|
||||||
|
|
||||||
XlateGDI->translationTable = EngAllocMem(FL_ZERO_MEMORY, sizeof(ULONG)*IndexedColors, NULL);
|
XlateGDI->translationTable = EngAllocMem(FL_ZERO_MEMORY, sizeof(ULONG)*IndexedColors, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: dllmain.c,v 1.18 2001/03/31 15:35:08 jfilby Exp $
|
/* $Id: dllmain.c,v 1.19 2001/05/02 12:33:42 jfilby Exp $
|
||||||
*
|
*
|
||||||
* Entry Point for win32k.sys
|
* Entry Point for win32k.sys
|
||||||
*/
|
*/
|
||||||
|
@ -52,6 +52,8 @@ BOOLEAN
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kInitialize (VOID)
|
W32kInitialize (VOID)
|
||||||
{
|
{
|
||||||
|
DbgPrint("W32kInitialize\n");
|
||||||
|
|
||||||
// FIXME: Retrieve name from registry
|
// FIXME: Retrieve name from registry
|
||||||
EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys");
|
EngLoadImage(L"\\SystemRoot\\system32\\drivers\\vidport.sys");
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
# $Id: makefile,v 1.29 2001/03/31 16:09:17 jfilby Exp $
|
# $Id: makefile,v 1.30 2001/05/02 12:33:42 jfilby Exp $
|
||||||
#
|
#
|
||||||
# WIN32K.SYS build spec
|
# WIN32K.SYS build spec
|
||||||
#
|
#
|
||||||
|
@ -7,7 +7,7 @@ PATH_TO_TOP = ../..
|
||||||
TARGET=win32k
|
TARGET=win32k
|
||||||
|
|
||||||
# from atheos appserver makefile
|
# from atheos appserver makefile
|
||||||
COPTS = -pipe -O3 -I./freetype2-beta8/include -c -Wall
|
COPTS = -pipe -O3 -I./freetype/include -c -Wall
|
||||||
|
|
||||||
CFLAGS = -I.
|
CFLAGS = -I.
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@ CFLAGS = -I.
|
||||||
|
|
||||||
ENG_OBJECTS= eng/debug.o eng/mem.o eng/brush.o eng/bitblt.o eng/clip.o eng/copybits.o \
|
ENG_OBJECTS= eng/debug.o eng/mem.o eng/brush.o eng/bitblt.o eng/clip.o eng/copybits.o \
|
||||||
eng/device.o eng/handle.o eng/lineto.o eng/paint.o eng/palette.o \
|
eng/device.o eng/handle.o eng/lineto.o eng/paint.o eng/palette.o \
|
||||||
eng/surface.o eng/xlate.o
|
eng/surface.o eng/xlate.o eng/transblt.o
|
||||||
MAIN_OBJECTS = main/dllmain.o
|
MAIN_OBJECTS = main/dllmain.o
|
||||||
MISC_OBJECTS = misc/driver.o misc/math.o
|
MISC_OBJECTS = misc/driver.o misc/math.o
|
||||||
LDR_OBJECTS = ldr/loader.o
|
LDR_OBJECTS = ldr/loader.o
|
||||||
|
@ -27,7 +27,11 @@ OBJECTS_OBJECTS = objects/bitmaps.o objects/brush.o objects/cliprgn.o \
|
||||||
objects/region.o objects/text.o objects/wingl.o \
|
objects/region.o objects/text.o objects/wingl.o \
|
||||||
objects/bezier.o objects/objconv.o objects/dib.o objects/palette.o
|
objects/bezier.o objects/objconv.o objects/dib.o objects/palette.o
|
||||||
DIB_OBJECTS = dib/dib4bpp.o dib/dib24bpp.o
|
DIB_OBJECTS = dib/dib4bpp.o dib/dib24bpp.o
|
||||||
FREETYPE_OBJECTS = freetype/grfont.o
|
FREETYPE_OBJECTS = freetype/grfont.o freetype/ctype.o \
|
||||||
|
freetype/ftsystem.o freetype/ftdebug.o freetype/ftinit.o freetype/ftbase.o \
|
||||||
|
freetype/ftglyph.o freetype/ftmm.o freetype/autohint.o freetype/cff.o \
|
||||||
|
freetype/type1cid.o freetype/psnames.o freetype/raster1.o freetype/sfnt.o \
|
||||||
|
freetype/smooth.o freetype/truetype.o freetype/winfnt.o freetype/type1z.o
|
||||||
RESOURCE_OBJECT = $(TARGET).coff
|
RESOURCE_OBJECT = $(TARGET).coff
|
||||||
STUBS_OBJECTS = stubs/stubs.o
|
STUBS_OBJECTS = stubs/stubs.o
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: driver.c,v 1.17 2001/04/15 22:08:23 narnaoud Exp $
|
/* $Id: driver.c,v 1.18 2001/05/02 12:33:42 jfilby Exp $
|
||||||
*
|
*
|
||||||
* GDI Driver support routines
|
* GDI Driver support routines
|
||||||
* (mostly swiped from Wine)
|
* (mostly swiped from Wine)
|
||||||
|
@ -107,6 +107,7 @@ BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
|
||||||
DF->StrokeAndFillPath = (PGD_STROKEANDFILLPATH)DED->pdrvfn[i].pfn;
|
DF->StrokeAndFillPath = (PGD_STROKEANDFILLPATH)DED->pdrvfn[i].pfn;
|
||||||
if(DED->pdrvfn[i].iFunc == INDEX_DrvPaint) DF->Paint = (PGD_PAINT)DED->pdrvfn[i].pfn;
|
if(DED->pdrvfn[i].iFunc == INDEX_DrvPaint) DF->Paint = (PGD_PAINT)DED->pdrvfn[i].pfn;
|
||||||
if(DED->pdrvfn[i].iFunc == INDEX_DrvBitBlt) DF->BitBlt = (PGD_BITBLT)DED->pdrvfn[i].pfn;
|
if(DED->pdrvfn[i].iFunc == INDEX_DrvBitBlt) DF->BitBlt = (PGD_BITBLT)DED->pdrvfn[i].pfn;
|
||||||
|
if(DED->pdrvfn[i].iFunc == INDEX_DrvTransparentBlt) DF->TransparentBlt = (PGD_TRANSPARENTBLT)DED->pdrvfn[i].pfn;
|
||||||
if(DED->pdrvfn[i].iFunc == INDEX_DrvCopyBits) DF->CopyBits = (PGD_COPYBITS)DED->pdrvfn[i].pfn;
|
if(DED->pdrvfn[i].iFunc == INDEX_DrvCopyBits) DF->CopyBits = (PGD_COPYBITS)DED->pdrvfn[i].pfn;
|
||||||
if(DED->pdrvfn[i].iFunc == INDEX_DrvStretchBlt) DF->StretchBlt = (PGD_STRETCHBLT)DED->pdrvfn[i].pfn;
|
if(DED->pdrvfn[i].iFunc == INDEX_DrvStretchBlt) DF->StretchBlt = (PGD_STRETCHBLT)DED->pdrvfn[i].pfn;
|
||||||
if(DED->pdrvfn[i].iFunc == INDEX_DrvSetPalette) DF->SetPalette = (PGD_SETPALETTE)DED->pdrvfn[i].pfn;
|
if(DED->pdrvfn[i].iFunc == INDEX_DrvSetPalette) DF->SetPalette = (PGD_SETPALETTE)DED->pdrvfn[i].pfn;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: brush.c,v 1.11 2001/03/31 15:35:08 jfilby Exp $
|
/* $Id: brush.c,v 1.12 2001/05/02 12:33:42 jfilby Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@
|
||||||
#include <win32k/brush.h>
|
#include <win32k/brush.h>
|
||||||
//#include <win32k/debug.h>
|
//#include <win32k/debug.h>
|
||||||
|
|
||||||
// #define NDEBUG
|
#define NDEBUG
|
||||||
#include <win32k/debug1.h>
|
#include <win32k/debug1.h>
|
||||||
|
|
||||||
HBRUSH STDCALL W32kCreateBrushIndirect(CONST LOGBRUSH *lb)
|
HBRUSH STDCALL W32kCreateBrushIndirect(CONST LOGBRUSH *lb)
|
||||||
|
@ -19,17 +19,18 @@ HBRUSH STDCALL W32kCreateBrushIndirect(CONST LOGBRUSH *lb)
|
||||||
|
|
||||||
brushPtr = BRUSHOBJ_AllocBrush();
|
brushPtr = BRUSHOBJ_AllocBrush();
|
||||||
hBrush = BRUSHOBJ_PtrToHandle (brushPtr);
|
hBrush = BRUSHOBJ_PtrToHandle (brushPtr);
|
||||||
|
|
||||||
if (hBrush == NULL)
|
if (hBrush == NULL)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
brushPtr->iSolidColor = lb->lbColor;
|
||||||
brushPtr->logbrush.lbStyle = lb->lbStyle;
|
brushPtr->logbrush.lbStyle = lb->lbStyle;
|
||||||
brushPtr->logbrush.lbColor = lb->lbColor;
|
brushPtr->logbrush.lbColor = lb->lbColor;
|
||||||
brushPtr->logbrush.lbHatch = lb->lbHatch;
|
brushPtr->logbrush.lbHatch = lb->lbHatch;
|
||||||
|
|
||||||
BRUSHOBJ_UnlockBrush (hBrush);
|
BRUSHOBJ_UnlockBrush (hBrush);
|
||||||
DPRINT("%08x\n", hBrush);
|
|
||||||
|
|
||||||
return hBrush;
|
return hBrush;
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@ HPALETTE STDCALL W32kCreateHalftonePalette(HDC hDC)
|
||||||
HPALETTE STDCALL W32kCreatePalette(CONST PLOGPALETTE palette)
|
HPALETTE STDCALL W32kCreatePalette(CONST PLOGPALETTE palette)
|
||||||
{
|
{
|
||||||
PPALOBJ PalObj;
|
PPALOBJ PalObj;
|
||||||
|
|
||||||
HPALETTE NewPalette = EngCreatePalette(PAL_INDEXED, palette->palNumEntries, palette->palPalEntry, 0, 0, 0);
|
HPALETTE NewPalette = EngCreatePalette(PAL_INDEXED, palette->palNumEntries, palette->palPalEntry, 0, 0, 0);
|
||||||
ULONG size;
|
ULONG size;
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* $Id: dc.c,v 1.19 2001/03/31 15:35:08 jfilby Exp $
|
/* $Id: dc.c,v 1.20 2001/05/02 12:33:42 jfilby Exp $
|
||||||
*
|
*
|
||||||
* DC.C - Device context functions
|
* DC.C - Device context functions
|
||||||
*
|
*
|
||||||
|
@ -16,6 +16,7 @@
|
||||||
#include <win32k/region.h>
|
#include <win32k/region.h>
|
||||||
#include <win32k/gdiobj.h>
|
#include <win32k/gdiobj.h>
|
||||||
#include <win32k/pen.h>
|
#include <win32k/pen.h>
|
||||||
|
#include <win32k/text.h>
|
||||||
#include "../eng/objects.h"
|
#include "../eng/objects.h"
|
||||||
|
|
||||||
// #define NDEBUG
|
// #define NDEBUG
|
||||||
|
@ -166,6 +167,8 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC)
|
||||||
NewDC->w.hBitmap = hBitmap;
|
NewDC->w.hBitmap = hBitmap;
|
||||||
NewDC->w.hFirstBitmap = hBitmap;
|
NewDC->w.hFirstBitmap = hBitmap;
|
||||||
NewDC->w.hPalette = OrigDC->w.hPalette;
|
NewDC->w.hPalette = OrigDC->w.hPalette;
|
||||||
|
NewDC->w.textColor = OrigDC->w.textColor;
|
||||||
|
NewDC->w.textAlign = OrigDC->w.textAlign;
|
||||||
|
|
||||||
DC_UnlockDC(NewDC);
|
DC_UnlockDC(NewDC);
|
||||||
DC_UnlockDC(OrigDC);
|
DC_UnlockDC(OrigDC);
|
||||||
|
@ -173,6 +176,8 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC)
|
||||||
return DC_PtrToHandle(NewDC);
|
return DC_PtrToHandle(NewDC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#include <ddk/ntddvid.h>
|
||||||
|
|
||||||
HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
||||||
LPCWSTR Device,
|
LPCWSTR Device,
|
||||||
LPCWSTR Output,
|
LPCWSTR Output,
|
||||||
|
@ -291,6 +296,9 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
||||||
DC_InitDC(NewDC);
|
DC_InitDC(NewDC);
|
||||||
hNewDC = DC_PtrToHandle(NewDC);
|
hNewDC = DC_PtrToHandle(NewDC);
|
||||||
|
|
||||||
|
W32kSetTextColor(hNewDC, RGB(0xff, 0xff, 0xff));
|
||||||
|
W32kSetTextAlign(hNewDC, TA_BASELINE);
|
||||||
|
|
||||||
// If we've created a DC for the DISPLAY, save the reference for later CreateCompatibleDC(NULL... usage
|
// If we've created a DC for the DISPLAY, save the reference for later CreateCompatibleDC(NULL... usage
|
||||||
if(wcscmp(Driver, "DISPLAY")) // FIXME: this works.. but shouldn't we compare to L"DISPLAY" ? (which doesn't work..)
|
if(wcscmp(Driver, "DISPLAY")) // FIXME: this works.. but shouldn't we compare to L"DISPLAY" ? (which doesn't work..)
|
||||||
{
|
{
|
||||||
|
|
|
@ -6,22 +6,38 @@
|
||||||
#include <win32k/dc.h>
|
#include <win32k/dc.h>
|
||||||
#include <win32k/text.h>
|
#include <win32k/text.h>
|
||||||
#include <win32k/kapi.h>
|
#include <win32k/kapi.h>
|
||||||
// #include <freetype/freetype.h>
|
#include <freetype/freetype.h>
|
||||||
|
|
||||||
|
#include "../eng/objects.h"
|
||||||
|
|
||||||
// #define NDEBUG
|
// #define NDEBUG
|
||||||
#include <win32k/debug1.h>
|
#include <win32k/debug1.h>
|
||||||
|
|
||||||
// FT_Library library;
|
FT_Library library;
|
||||||
|
|
||||||
|
typedef struct _FONTTABLE {
|
||||||
|
HFONT hFont;
|
||||||
|
LPCWSTR FaceName;
|
||||||
|
} FONTTABLE, *PFONTTABLE;
|
||||||
|
|
||||||
|
FONTTABLE FontTable[256];
|
||||||
|
INT FontsLoaded = 0;
|
||||||
|
|
||||||
BOOL InitFontSupport()
|
BOOL InitFontSupport()
|
||||||
{
|
{
|
||||||
/* ULONG error;
|
ULONG error;
|
||||||
|
|
||||||
error = FT_Init_FreeType(&library);
|
error = FT_Init_FreeType(&library);
|
||||||
if(error)
|
if(error)
|
||||||
{
|
{
|
||||||
return FALSE;
|
return FALSE;
|
||||||
} else return TRUE; */
|
}
|
||||||
|
|
||||||
|
W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\helb____.ttf");
|
||||||
|
W32kAddFontResource(L"\\SystemRoot\\media\\fonts\\timr____.ttf");
|
||||||
|
|
||||||
|
DbgPrint("All fonts loaded\n");
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +45,103 @@ int
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kAddFontResource(LPCWSTR Filename)
|
W32kAddFontResource(LPCWSTR Filename)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
HFONT NewFont;
|
||||||
|
PFONTOBJ FontObj;
|
||||||
|
PFONTGDI FontGDI;
|
||||||
|
UNICODE_STRING uFileName;
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE FileHandle;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
FILE_STANDARD_INFORMATION FileStdInfo;
|
||||||
|
PVOID buffer;
|
||||||
|
ULONG size;
|
||||||
|
INT error;
|
||||||
|
FT_Face face;
|
||||||
|
ANSI_STRING StringA;
|
||||||
|
UNICODE_STRING StringU;
|
||||||
|
|
||||||
|
FontObj = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEOBJ), NULL);
|
||||||
|
FontGDI = EngAllocMem(FL_ZERO_MEMORY, sizeof(XLATEGDI), NULL);
|
||||||
|
NewFont = CreateGDIHandle(FontGDI, FontObj);
|
||||||
|
|
||||||
|
RtlCreateUnicodeString(&uFileName, Filename);
|
||||||
|
|
||||||
|
// Open the Module
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, &uFileName, 0, NULL, NULL);
|
||||||
|
|
||||||
|
Status = NtOpenFile(&FileHandle, FILE_ALL_ACCESS, &ObjectAttributes, NULL, 0, 0);
|
||||||
|
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Could not open module file: %wZ\n", Filename);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the size of the file
|
||||||
|
Status = NtQueryInformationFile(FileHandle, NULL, &FileStdInfo, sizeof(FileStdInfo), FileStandardInformation);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("Could not get file size\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allocate nonpageable memory for driver
|
||||||
|
size = FileStdInfo.EndOfFile.u.LowPart;
|
||||||
|
buffer = ExAllocatePool(NonPagedPool, size);
|
||||||
|
|
||||||
|
if (buffer == NULL)
|
||||||
|
{
|
||||||
|
DbgPrint("could not allocate memory for module");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load driver into memory chunk
|
||||||
|
Status = NtReadFile(FileHandle, 0, 0, 0, 0, buffer, FileStdInfo.EndOfFile.u.LowPart, 0, 0);
|
||||||
|
if (!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
DbgPrint("could not read module file into memory");
|
||||||
|
ExFreePool(buffer);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
NtClose(FileHandle);
|
||||||
|
|
||||||
|
error = FT_New_Memory_Face(library, buffer, size, 0, &face);
|
||||||
|
if (error == FT_Err_Unknown_File_Format)
|
||||||
|
{
|
||||||
|
DbgPrint("Unknown font file format\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if (error)
|
||||||
|
{
|
||||||
|
DbgPrint("Error reading font file (error code: %u)\n", error); // 48
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// FontGDI->Filename = Filename; perform strcpy
|
||||||
|
FontGDI->face = face;
|
||||||
|
|
||||||
|
// FIXME: Complete text metrics
|
||||||
|
FontGDI->TextMetric.tmAscent = face->size->metrics.ascender; // units above baseline
|
||||||
|
FontGDI->TextMetric.tmDescent = face->size->metrics.descender; // units below baseline
|
||||||
|
FontGDI->TextMetric.tmHeight = FontGDI->TextMetric.tmAscent + FontGDI->TextMetric.tmDescent;
|
||||||
|
|
||||||
|
DbgPrint("Family name: %s\n", face->family_name);
|
||||||
|
DbgPrint("Style name: %s\n", face->style_name);
|
||||||
|
DbgPrint("Num glyphs: %u\n", face->num_glyphs);
|
||||||
|
|
||||||
|
// Add this font resource to the font table
|
||||||
|
FontTable[FontsLoaded].hFont = NewFont;
|
||||||
|
FontTable[FontsLoaded].FaceName = ExAllocatePool(NonPagedPool, (StringU.Length + 1) * 2);
|
||||||
|
|
||||||
|
RtlInitAnsiString(&StringA, (LPSTR)face->family_name);
|
||||||
|
RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
|
||||||
|
wcscpy(FontTable[FontsLoaded].FaceName, StringU.Buffer);
|
||||||
|
RtlFreeUnicodeString(&StringU);
|
||||||
|
|
||||||
|
FontsLoaded++;
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
HFONT
|
HFONT
|
||||||
|
@ -49,14 +161,53 @@ W32kCreateFont(int Height,
|
||||||
DWORD PitchAndFamily,
|
DWORD PitchAndFamily,
|
||||||
LPCWSTR Face)
|
LPCWSTR Face)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
LOGFONT logfont;
|
||||||
|
|
||||||
|
logfont.lfHeight = Height;
|
||||||
|
logfont.lfWidth = Width;
|
||||||
|
logfont.lfEscapement = Escapement;
|
||||||
|
logfont.lfOrientation = Orientation;
|
||||||
|
logfont.lfWeight = Weight;
|
||||||
|
logfont.lfItalic = Italic;
|
||||||
|
logfont.lfUnderline = Underline;
|
||||||
|
logfont.lfStrikeOut = StrikeOut;
|
||||||
|
logfont.lfCharSet = CharSet;
|
||||||
|
logfont.lfOutPrecision = OutputPrecision;
|
||||||
|
logfont.lfClipPrecision = ClipPrecision;
|
||||||
|
logfont.lfQuality = Quality;
|
||||||
|
logfont.lfPitchAndFamily = PitchAndFamily;
|
||||||
|
|
||||||
|
if(Face)
|
||||||
|
memcpy(logfont.lfFaceName, Face, sizeof(logfont.lfFaceName));
|
||||||
|
else
|
||||||
|
logfont.lfFaceName[0] = '\0';
|
||||||
|
|
||||||
|
return W32kCreateFontIndirect(&logfont);
|
||||||
}
|
}
|
||||||
|
|
||||||
HFONT
|
HFONT
|
||||||
STDCALL
|
STDCALL
|
||||||
W32kCreateFontIndirect(CONST LPLOGFONT lf)
|
W32kCreateFontIndirect(CONST LPLOGFONT lf)
|
||||||
{
|
{
|
||||||
DbgPrint("WARNING: W32kCreateFontIndirect is current unimplemented\n");
|
HFONT hFont = 0;
|
||||||
|
PTEXTOBJ fontPtr;
|
||||||
|
|
||||||
|
if (lf)
|
||||||
|
{
|
||||||
|
if(fontPtr = TEXTOBJ_AllocText())
|
||||||
|
{
|
||||||
|
memcpy(&fontPtr->logfont, lf, sizeof(LOGFONT));
|
||||||
|
|
||||||
|
if (lf->lfEscapement != lf->lfOrientation) {
|
||||||
|
/* this should really depend on whether GM_ADVANCED is set */
|
||||||
|
fontPtr->logfont.lfOrientation = fontPtr->logfont.lfEscapement;
|
||||||
|
}
|
||||||
|
hFont = TEXTOBJ_PtrToHandle(fontPtr);
|
||||||
|
TEXTOBJ_UnlockText(hFont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return hFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -268,7 +419,42 @@ W32kGetTextExtentPoint(HDC hDC,
|
||||||
int Count,
|
int Count,
|
||||||
LPSIZE Size)
|
LPSIZE Size)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PDC dc = AccessUserObject(hDC);
|
||||||
|
PFONTGDI FontGDI;
|
||||||
|
FT_Face face;
|
||||||
|
FT_GlyphSlot glyph;
|
||||||
|
INT error, pitch, glyph_index, i;
|
||||||
|
ULONG TotalWidth = 0, MaxHeight = 0, CurrentChar = 0, SpaceBetweenChars = 5;
|
||||||
|
|
||||||
|
FontGDI = AccessInternalObject(dc->w.hFont);
|
||||||
|
|
||||||
|
for(i=0; i<Count; i++)
|
||||||
|
{
|
||||||
|
glyph_index = FT_Get_Char_Index(face, *String);
|
||||||
|
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
|
||||||
|
if(error) DbgPrint("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index);
|
||||||
|
glyph = face->glyph;
|
||||||
|
|
||||||
|
if (glyph->format == ft_glyph_format_outline)
|
||||||
|
{
|
||||||
|
error = FT_Render_Glyph(glyph, ft_render_mode_mono);
|
||||||
|
if(error) DbgPrint("WARNING: Failed to render glyph!\n");
|
||||||
|
pitch = glyph->bitmap.pitch;
|
||||||
|
} else {
|
||||||
|
pitch = glyph->bitmap.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
TotalWidth += pitch-1;
|
||||||
|
if((glyph->bitmap.rows-1) > MaxHeight) MaxHeight = glyph->bitmap.rows-1;
|
||||||
|
|
||||||
|
CurrentChar++;
|
||||||
|
|
||||||
|
if(CurrentChar < Size) TotalWidth += SpaceBetweenChars;
|
||||||
|
String++;
|
||||||
|
}
|
||||||
|
|
||||||
|
Size->cx = TotalWidth;
|
||||||
|
Size->cy = MaxHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -295,7 +481,13 @@ STDCALL
|
||||||
W32kGetTextMetrics(HDC hDC,
|
W32kGetTextMetrics(HDC hDC,
|
||||||
LPTEXTMETRIC tm)
|
LPTEXTMETRIC tm)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
PDC dc = AccessUserObject(hDC);
|
||||||
|
PFONTGDI FontGDI;
|
||||||
|
|
||||||
|
FontGDI = AccessInternalObject(dc->w.hFont);
|
||||||
|
memcpy(tm, &FontGDI->TextMetric, sizeof(TEXTMETRIC));
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
|
@ -357,6 +549,7 @@ W32kSetTextColor(HDC hDC,
|
||||||
|
|
||||||
oldColor = dc->w.textColor;
|
oldColor = dc->w.textColor;
|
||||||
dc->w.textColor = color;
|
dc->w.textColor = color;
|
||||||
|
|
||||||
DC_UnlockDC(hDC);
|
DC_UnlockDC(hDC);
|
||||||
|
|
||||||
return oldColor;
|
return oldColor;
|
||||||
|
@ -379,104 +572,55 @@ W32kTextOut(HDC hDC,
|
||||||
LPCWSTR String,
|
LPCWSTR String,
|
||||||
int Count)
|
int Count)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
|
||||||
// Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
|
// Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
|
||||||
/*
|
|
||||||
DC *dc = DC_HandleToPtr(hDC);
|
DC *dc = DC_HandleToPtr(hDC);
|
||||||
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
||||||
UNICODE_STRING FileName;
|
int error, glyph_index, n, load_flags = FT_LOAD_RENDER, i, j, sx, sy, scc;
|
||||||
int error, glyph_index, n, load_flags = FT_LOAD_RENDER, i, j;
|
|
||||||
FT_Face face;
|
FT_Face face;
|
||||||
FT_GlyphSlot glyph;
|
FT_GlyphSlot glyph;
|
||||||
NTSTATUS Status;
|
ULONG TextLeft = XStart, TextTop = YStart, SpaceBetweenChars = 2, pitch, previous;
|
||||||
HANDLE FileHandle;
|
FT_Bool use_kerning;
|
||||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
RECTL DestRect, MaskRect;
|
||||||
FILE_STANDARD_INFORMATION FileStdInfo;
|
POINTL SourcePoint, BrushOrigin;
|
||||||
PVOID buffer;
|
HBRUSH hBrush;
|
||||||
ULONG size, TextLeft = XStart, TextTop = YStart, SpaceBetweenChars = 5, StringLength;
|
PBRUSHOBJ Brush;
|
||||||
FT_Vector origin;
|
|
||||||
FT_Bitmap bit, bit2, bit3;
|
|
||||||
POINTL SourcePoint;
|
|
||||||
RECTL DestRect;
|
|
||||||
HBITMAP HSourceGlyph;
|
HBITMAP HSourceGlyph;
|
||||||
PSURFOBJ SourceGlyphSurf;
|
PSURFOBJ SourceGlyphSurf;
|
||||||
SIZEL bitSize;
|
SIZEL bitSize;
|
||||||
FT_CharMap found = 0;
|
FT_CharMap found = 0, charmap;
|
||||||
FT_CharMap charmap;
|
INT yoff;
|
||||||
PCHAR bitbuf;
|
HFONT hFont = 0;
|
||||||
|
PFONTOBJ FontObj;
|
||||||
|
PFONTGDI FontGDI;
|
||||||
|
PTEXTOBJ TextObj;
|
||||||
|
PPALGDI PalDestGDI;
|
||||||
|
PXLATEOBJ XlateObj;
|
||||||
|
|
||||||
// For now we're just going to use an internal font
|
TextObj = TEXTOBJ_HandleToPtr(dc->w.hFont);
|
||||||
// grWriteCellString(SurfObj, XStart, YStart, AString->Buffer, 0xffffff);
|
|
||||||
|
|
||||||
// Prepare the Unicode FileName
|
for(i=0; i<FontsLoaded; i++)
|
||||||
RtlCreateUnicodeString(&FileName, L"\\SystemRoot\\fonts\\arial.ttf");
|
|
||||||
|
|
||||||
// Open the Module
|
|
||||||
InitializeObjectAttributes(&ObjectAttributes, &FileName, 0, NULL, NULL);
|
|
||||||
|
|
||||||
Status = NtOpenFile(&FileHandle, FILE_ALL_ACCESS, &ObjectAttributes, NULL, 0, 0);
|
|
||||||
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
DbgPrint("Could not open module file: %wZ\n", L"c:/reactos/fonts/arial.ttf");
|
if(wcscmp(FontTable[i].FaceName, (LPSTR)TextObj->logfont.lfFaceName) == 0)
|
||||||
return 0;
|
hFont = FontTable[i].hFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the size of the file
|
if(hFont == 0)
|
||||||
Status = NtQueryInformationFile(FileHandle, NULL, &FileStdInfo, sizeof(FileStdInfo), FileStandardInformation);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
{
|
||||||
DbgPrint("Could not get file size\n");
|
DbgPrint("Specified font %s is not loaded\n", TextObj->logfont.lfFaceName);
|
||||||
return 0;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allocate nonpageable memory for driver
|
FontObj = AccessUserObject(hFont);
|
||||||
size = FileStdInfo.EndOfFile.u.LowPart;
|
FontGDI = AccessInternalObject(hFont);
|
||||||
buffer = ExAllocatePool(NonPagedPool, size);
|
face = FontGDI->face;
|
||||||
|
|
||||||
if (buffer == NULL)
|
|
||||||
{
|
|
||||||
DbgPrint("could not allocate memory for module");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load driver into memory chunk
|
|
||||||
Status = NtReadFile(FileHandle, 0, 0, 0, 0, buffer, FileStdInfo.EndOfFile.u.LowPart, 0, 0);
|
|
||||||
if (!NT_SUCCESS(Status))
|
|
||||||
{
|
|
||||||
DbgPrint("could not read module file into memory");
|
|
||||||
ExFreePool(buffer);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
NtClose(FileHandle);
|
|
||||||
|
|
||||||
error = FT_New_Memory_Face(library,
|
|
||||||
buffer, // first byte in memory
|
|
||||||
size, // size in bytes
|
|
||||||
0, // face_index
|
|
||||||
&face );
|
|
||||||
if ( error == FT_Err_Unknown_File_Format )
|
|
||||||
{
|
|
||||||
DbgPrint("Unknown font file format\n");
|
|
||||||
}
|
|
||||||
else if ( error )
|
|
||||||
{
|
|
||||||
DbgPrint("Error reading font file\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
DbgPrint("Family name: %s\n", face->family_name);
|
|
||||||
DbgPrint("Style name: %s\n", face->style_name);
|
|
||||||
DbgPrint("Num glyphs: %u\n", face->num_glyphs);
|
|
||||||
DbgPrint("Height: %d\n", face->height);
|
|
||||||
|
|
||||||
if (face->charmap == NULL)
|
if (face->charmap == NULL)
|
||||||
{
|
{
|
||||||
DbgPrint("WARNING: No charmap selected!\n");
|
DbgPrint("WARNING: No charmap selected!\n");
|
||||||
DbgPrint("This font face has %d charmaps\n", face->num_charmaps);
|
DbgPrint("This font face has %d charmaps\n", face->num_charmaps);
|
||||||
|
|
||||||
for ( n = 0; n < face->num_charmaps; n++ )
|
for (n = 0; n < face->num_charmaps; n++)
|
||||||
{
|
{
|
||||||
charmap = face->charmaps[n];
|
charmap = face->charmaps[n];
|
||||||
DbgPrint("found charmap encoding: %u\n", charmap->encoding);
|
DbgPrint("found charmap encoding: %u\n", charmap->encoding);
|
||||||
|
@ -486,70 +630,97 @@ W32kTextOut(HDC hDC,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!found) DbgPrint("WARNING: Could not find desired charmap!\n");
|
||||||
|
error = FT_Set_Charmap(face, found);
|
||||||
|
if (error) DbgPrint("WARNING: Could not set the charmap!\n");
|
||||||
}
|
}
|
||||||
if (!found) DbgPrint("WARNING: Could not find desired charmap!\n");
|
|
||||||
|
|
||||||
error = FT_Set_Charmap(face, found);
|
error = FT_Set_Pixel_Sizes(face, TextObj->logfont.lfHeight, TextObj->logfont.lfWidth);
|
||||||
if (error) DbgPrint("WARNING: Could not set the charmap!\n");
|
if(error) {
|
||||||
|
DbgPrint("Error in setting pixel sizes: %u\n", error);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
error = FT_Set_Char_Size(
|
// Create the brush
|
||||||
face, // handle to face object
|
PalDestGDI = AccessInternalObject(dc->w.hPalette);
|
||||||
16*64, // char_width in 1/64th of points
|
XlateObj = EngCreateXlate(PalDestGDI->Mode, PAL_RGB, dc->w.hPalette, NULL);
|
||||||
16*64, // char_height in 1/64th of points
|
hBrush = W32kCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor));
|
||||||
300, // horizontal device resolution
|
Brush = BRUSHOBJ_HandleToPtr(hBrush);
|
||||||
300 ); // vertical device resolution
|
EngDeleteXlate(XlateObj);
|
||||||
|
|
||||||
StringLength = wcslen(String);
|
SourcePoint.x = 0;
|
||||||
DbgPrint("StringLength: %u\n", StringLength);
|
SourcePoint.y = 0;
|
||||||
|
MaskRect.left = 0;
|
||||||
|
MaskRect.top = 0;
|
||||||
|
BrushOrigin.x = 0;
|
||||||
|
BrushOrigin.y = 0;
|
||||||
|
|
||||||
for(i=0; i<StringLength; i++)
|
// Do we use the current TEXTOBJ's logfont.lfOrientation or the DC's textAlign?
|
||||||
|
if (dc->w.textAlign & TA_BASELINE) {
|
||||||
|
yoff = 0;
|
||||||
|
} else if (dc->w.textAlign & TA_BOTTOM) {
|
||||||
|
yoff = -face->size->metrics.descender / 64;
|
||||||
|
} else { // TA_TOP
|
||||||
|
yoff = face->size->metrics.ascender / 64;
|
||||||
|
}
|
||||||
|
|
||||||
|
use_kerning = FT_HAS_KERNING(face);
|
||||||
|
previous = 0;
|
||||||
|
|
||||||
|
for(i=0; i<Count; i++)
|
||||||
{
|
{
|
||||||
glyph_index = FT_Get_Char_Index(face, *String);
|
glyph_index = FT_Get_Char_Index(face, *String);
|
||||||
|
error = FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
|
||||||
error = FT_Load_Glyph(
|
if(error) {
|
||||||
face, // handle to face object
|
DbgPrint("WARNING: Failed to load and render glyph! [index: %u]\n", glyph_index);
|
||||||
glyph_index, // glyph index
|
return FALSE;
|
||||||
FT_LOAD_DEFAULT ); // load flags (erase previous glyph)
|
}
|
||||||
if(error) DbgPrint("WARNING: Failed to load and render glyph!\n");
|
|
||||||
|
|
||||||
glyph = face->glyph;
|
glyph = face->glyph;
|
||||||
|
|
||||||
if ( glyph->format == ft_glyph_format_outline )
|
// retrieve kerning distance and move pen position
|
||||||
|
if (use_kerning && previous && glyph_index)
|
||||||
{
|
{
|
||||||
DbgPrint("Outline Format Font\n");
|
FT_Vector delta;
|
||||||
error = FT_Render_Glyph( glyph, ft_render_mode_normal );
|
FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
|
||||||
if(error) DbgPrint("WARNING: Failed to render glyph!\n");
|
TextLeft += delta.x >> 6;
|
||||||
} else {
|
|
||||||
DbgPrint("Bitmap Format Font\n");
|
|
||||||
bit3.rows = glyph->bitmap.rows;
|
|
||||||
bit3.width = glyph->bitmap.width;
|
|
||||||
bit3.pitch = glyph->bitmap.pitch;
|
|
||||||
bit3.buffer = glyph->bitmap.buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SourcePoint.x = 0;
|
if (glyph->format == ft_glyph_format_outline)
|
||||||
SourcePoint.y = 0;
|
{
|
||||||
DestRect.left = TextLeft;
|
error = FT_Render_Glyph(glyph, ft_render_mode_mono);
|
||||||
DestRect.top = TextTop;
|
if(error) {
|
||||||
DestRect.right = TextLeft + glyph->bitmap.width-1;
|
DbgPrint("WARNING: Failed to render glyph!\n");
|
||||||
DestRect.bottom = TextTop + glyph->bitmap.rows-1;
|
return FALSE;
|
||||||
bitSize.cx = glyph->bitmap.width-1;
|
}
|
||||||
bitSize.cy = glyph->bitmap.rows-1;
|
pitch = glyph->bitmap.pitch;
|
||||||
|
} else {
|
||||||
|
pitch = glyph->bitmap.width;
|
||||||
|
}
|
||||||
|
|
||||||
HSourceGlyph = EngCreateBitmap(bitSize, glyph->bitmap.pitch, BMF_8BPP, 0, glyph->bitmap.buffer);
|
DestRect.left = TextLeft;
|
||||||
|
DestRect.top = TextTop + yoff - glyph->bitmap_top;
|
||||||
|
DestRect.right = TextLeft + glyph->bitmap.width;
|
||||||
|
DestRect.bottom = DestRect.top + glyph->bitmap.rows;
|
||||||
|
bitSize.cx = pitch-1;
|
||||||
|
bitSize.cy = glyph->bitmap.rows-1;
|
||||||
|
MaskRect.right = glyph->bitmap.width;
|
||||||
|
MaskRect.bottom = glyph->bitmap.rows;
|
||||||
|
|
||||||
|
// We should create the bitmap out of the loop at the biggest possible glyph size
|
||||||
|
// Then use memset with 0 to clear it and sourcerect to limit the work of the transbitblt
|
||||||
|
HSourceGlyph = EngCreateBitmap(bitSize, pitch, BMF_1BPP, 0, glyph->bitmap.buffer);
|
||||||
SourceGlyphSurf = AccessUserObject(HSourceGlyph);
|
SourceGlyphSurf = AccessUserObject(HSourceGlyph);
|
||||||
|
|
||||||
EngBitBlt(SurfObj, SourceGlyphSurf,
|
// Use the font data as a mask to paint onto the DCs surface using a brush
|
||||||
NULL, NULL, NULL, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL);
|
EngBitBlt(SurfObj, NULL, SourceGlyphSurf, NULL, NULL, &DestRect, &SourcePoint, &MaskRect, Brush, &BrushOrigin, 0xAACC);
|
||||||
|
|
||||||
|
EngDeleteSurface(HSourceGlyph);
|
||||||
|
|
||||||
|
TextLeft += glyph->advance.x >> 6;
|
||||||
|
previous = glyph_index;
|
||||||
|
|
||||||
TextLeft += glyph->bitmap.width + SpaceBetweenChars;
|
|
||||||
String++;
|
String++;
|
||||||
}
|
}
|
||||||
|
|
||||||
DbgPrint("BREAK\n"); for (;;) ;
|
|
||||||
*/
|
|
||||||
/* RtlFreeAnsiString(AString);
|
|
||||||
RtlFreeUnicodeString(UString); */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
UINT
|
UINT
|
||||||
|
|
Loading…
Reference in a new issue