mirror of
https://github.com/reactos/reactos.git
synced 2025-05-28 21:48:19 +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;
|
||||
|
||||
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:
|
||||
SourceBits_24BPP = SourceSurf->pvBits + (SourcePoint->y * SourceSurf->lDelta) + SourcePoint->x * 3;
|
||||
|
||||
|
|
|
@ -49,13 +49,13 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
|
|||
BOOL EnumMore;
|
||||
PSURFGDI DestGDI, SourceGDI;
|
||||
HSURF hTemp;
|
||||
PSURFOBJ TempSurf;
|
||||
PSURFOBJ TempSurf = NULL;
|
||||
BOOLEAN canCopyBits;
|
||||
POINTL TempPoint;
|
||||
RECTL TempRect;
|
||||
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 it exists
|
||||
|
@ -75,23 +75,26 @@ BOOL EngBitBlt(SURFOBJ *Dest, SURFOBJ *Source,
|
|||
|
||||
if (DestGDI->BitBlt!=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 = DestRect->bottom - DestRect->top;
|
||||
TempRect.right = DestRect->right - DestRect->left;
|
||||
TempSize.cx = TempRect.right;
|
||||
TempSize.cy = TempRect.bottom;
|
||||
if (Source!=NULL)
|
||||
{
|
||||
// Get the source into a format compatible surface
|
||||
TempPoint.x = 0;
|
||||
TempPoint.y = 0;
|
||||
TempRect.top = 0;
|
||||
TempRect.left = 0;
|
||||
TempRect.bottom = DestRect->bottom - DestRect->top;
|
||||
TempRect.right = DestRect->right - DestRect->left;
|
||||
TempSize.cx = TempRect.right;
|
||||
TempSize.cy = TempRect.bottom;
|
||||
|
||||
hTemp = EngCreateBitmap(TempSize,
|
||||
DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)),
|
||||
Dest->iBitmapFormat, 0, NULL);
|
||||
TempSurf = AccessUserObject(hTemp);
|
||||
hTemp = EngCreateBitmap(TempSize,
|
||||
DIB_GetDIBWidthBytes(DestRect->right - DestRect->left, BitsPerFormat(Dest->iBitmapFormat)),
|
||||
Dest->iBitmapFormat, 0, NULL);
|
||||
TempSurf = AccessUserObject(hTemp);
|
||||
|
||||
// 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);
|
||||
// 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->BitBlt(Dest, TempSurf, Mask, ClipRegion,
|
||||
NULL, DestRect, &TempPoint,
|
||||
|
|
|
@ -22,6 +22,7 @@ BOOL EngLineTo(SURFOBJ *Surface, CLIPOBJ *Clip, BRUSHOBJ *Brush,
|
|||
if(Surface->iType!=STYPE_BITMAP)
|
||||
{
|
||||
// Call the driver's DrvLineTo
|
||||
DbgPrint("calling surfgdi's lineto\n");
|
||||
return SurfGDI->LineTo(Surface, Clip, Brush, x1, y1, x2, y2, RectBounds, mix);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
* 21/8/1999: Created
|
||||
*/
|
||||
|
||||
#include <freetype/freetype.h>
|
||||
|
||||
typedef struct _BRUSHGDI {
|
||||
|
||||
} BRUSHGDI;
|
||||
|
@ -32,8 +34,10 @@ typedef struct _FLOATGDI {
|
|||
} FLOATGDI;
|
||||
|
||||
typedef struct _FONTGDI {
|
||||
|
||||
} FONTGDI;
|
||||
LPCWSTR Filename;
|
||||
FT_Face face;
|
||||
TEXTMETRIC TextMetric;
|
||||
} FONTGDI, *PFONTGDI;
|
||||
|
||||
typedef struct _PALGDI {
|
||||
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,
|
||||
PBRUSHOBJ, PPOINTL, ROP4);
|
||||
|
||||
typedef BOOL (*PFN_TransparentBlt)(PSURFOBJ, PSURFOBJ, PCLIPOBJ, PXLATEOBJ, PRECTL, PRECTL, ULONG, ULONG);
|
||||
|
||||
typedef BOOL (*PFN_StretchBlt)(PSURFOBJ, PSURFOBJ, PSURFOBJ, PCLIPOBJ,
|
||||
PXLATEOBJ, PCOLORADJUSTMENT, PPOINTL,
|
||||
PRECTL, PRECTL, PPOINT, ULONG);
|
||||
|
@ -94,6 +100,7 @@ typedef struct _SURFGDI {
|
|||
INT BitsPerPixel;
|
||||
|
||||
PFN_BitBlt BitBlt;
|
||||
PFN_TransparentBlt TransparentBlt;
|
||||
PFN_StretchBlt StretchBlt;
|
||||
PFN_TextOut TextOut;
|
||||
PFN_Paint Paint;
|
||||
|
|
|
@ -56,7 +56,7 @@ BOOL EngDeletePalette(IN HPALETTE Palette)
|
|||
PALGDI *PalGDI;
|
||||
|
||||
PalGDI = AccessInternalObject(Palette);
|
||||
PalObj = AccessInternalObject(Palette);
|
||||
PalObj = AccessUserObject(Palette);
|
||||
|
||||
EngFreeMem(PalGDI);
|
||||
EngFreeMem(PalObj);
|
||||
|
|
|
@ -60,6 +60,7 @@ VOID InitializeHooks(SURFGDI *SurfGDI)
|
|||
SurfGDI->CopyBits = NULL;
|
||||
SurfGDI->CreateDeviceBitmap = NULL;
|
||||
SurfGDI->SetPalette = NULL;
|
||||
SurfGDI->TransparentBlt = NULL;
|
||||
}
|
||||
|
||||
HBITMAP EngCreateDeviceBitmap(DHSURF dhsurf, SIZEL Size, ULONG Format)
|
||||
|
@ -90,6 +91,7 @@ HBITMAP EngCreateBitmap(IN SIZEL Size,
|
|||
NewBitmap = (PVOID)CreateGDIHandle(SurfGDI, SurfObj);
|
||||
|
||||
InitializeHooks(SurfGDI);
|
||||
|
||||
SurfGDI->BitsPerPixel = BitsPerFormat(Format);
|
||||
SurfObj->lDelta = Width;
|
||||
SurfObj->cjBits = SurfObj->lDelta * Size.cy;
|
||||
|
@ -174,6 +176,7 @@ BOOL EngAssociateSurface(HSURF Surface, HDEV Dev, ULONG Hooks)
|
|||
|
||||
// Hook up specified functions
|
||||
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_TEXTOUT) SurfGDI->TextOut = Dc->DriverFunctions.TextOut;
|
||||
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
|
||||
*/
|
||||
|
||||
// TODO: Cache XLATEOBJs that are created by EngCreateXlate by checking if the given palettes match a cached list
|
||||
|
||||
#include <ddk/ntddk.h>
|
||||
#include <ddk/winddi.h>
|
||||
#include <ddk/ntddvid.h>
|
||||
|
@ -46,8 +48,8 @@ ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors,
|
|||
{
|
||||
PVIDEO_CLUTDATA cSourceColor;
|
||||
PVIDEO_CLUTDATA cDestColors;
|
||||
ULONG bestMatch = 256, idx = 0, i;
|
||||
ULONG rt;
|
||||
LONG idx = 0, i, rt;
|
||||
ULONG cxRed, cxGreen, cxBlue, BestMatch = 65535;
|
||||
|
||||
// Simple cache -- only one value because we don't want to waste time
|
||||
// if the colors aren't very sequential
|
||||
|
@ -58,19 +60,20 @@ ULONG ClosestColorMatch(ULONG SourceColor, ULONG *DestColors,
|
|||
}
|
||||
|
||||
cSourceColor = &SourceColor;
|
||||
|
||||
for (i=0; i<NumColors; i++)
|
||||
{
|
||||
cDestColors = &DestColors[i];
|
||||
|
||||
rt = ( abs(cSourceColor->Red - cDestColors->Red) +
|
||||
abs(cSourceColor->Green - cDestColors->Green) +
|
||||
abs(cSourceColor->Blue - cDestColors->Blue) ) / 3;
|
||||
cxRed = abs(cSourceColor->Red - cDestColors->Red) ^ 2;
|
||||
cxGreen = abs(cSourceColor->Green - cDestColors->Green) ^ 2;
|
||||
cxBlue = abs(cSourceColor->Blue - cDestColors->Blue) ^ 2;
|
||||
|
||||
if(rt<=bestMatch)
|
||||
rt = /* sqrt */ (cxRed + cxGreen + cxBlue);
|
||||
|
||||
if(rt<=BestMatch)
|
||||
{
|
||||
idx = i;
|
||||
bestMatch = rt;
|
||||
BestMatch = rt;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -132,8 +135,17 @@ XLATEOBJ *EngCreateXlate(USHORT DestPalType, USHORT SourcePalType,
|
|||
if( (SourcePalType == PAL_INDEXED) || (SourcePalType == PAL_RGB) )
|
||||
{
|
||||
XlateObj->flXlate |= XO_TABLE;
|
||||
if (SourcePalType == PAL_INDEXED) IndexedColors = SourcePalGDI->NumColors;
|
||||
if (DestPalType == PAL_INDEXED) IndexedColors = DestPalGDI->NumColors;
|
||||
if ((SourcePalType == PAL_INDEXED) && (DestPalType == PAL_INDEXED))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
@ -52,6 +52,8 @@ BOOLEAN
|
|||
STDCALL
|
||||
W32kInitialize (VOID)
|
||||
{
|
||||
DbgPrint("W32kInitialize\n");
|
||||
|
||||
// FIXME: Retrieve name from registry
|
||||
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
|
||||
#
|
||||
|
@ -7,7 +7,7 @@ PATH_TO_TOP = ../..
|
|||
TARGET=win32k
|
||||
|
||||
# from atheos appserver makefile
|
||||
COPTS = -pipe -O3 -I./freetype2-beta8/include -c -Wall
|
||||
COPTS = -pipe -O3 -I./freetype/include -c -Wall
|
||||
|
||||
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/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
|
||||
MISC_OBJECTS = misc/driver.o misc/math.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/bezier.o objects/objconv.o objects/dib.o objects/palette.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
|
||||
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
|
||||
* (mostly swiped from Wine)
|
||||
|
@ -107,6 +107,7 @@ BOOL DRIVER_BuildDDIFunctions(PDRVENABLEDATA DED,
|
|||
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_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_DrvStretchBlt) DF->StretchBlt = (PGD_STRETCHBLT)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,28 +9,29 @@
|
|||
#include <win32k/brush.h>
|
||||
//#include <win32k/debug.h>
|
||||
|
||||
// #define NDEBUG
|
||||
#define NDEBUG
|
||||
#include <win32k/debug1.h>
|
||||
|
||||
HBRUSH STDCALL W32kCreateBrushIndirect(CONST LOGBRUSH *lb)
|
||||
{
|
||||
PBRUSHOBJ brushPtr;
|
||||
HBRUSH hBrush;
|
||||
|
||||
|
||||
brushPtr = BRUSHOBJ_AllocBrush();
|
||||
hBrush = BRUSHOBJ_PtrToHandle (brushPtr);
|
||||
|
||||
if (hBrush == NULL)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
brushPtr->iSolidColor = lb->lbColor;
|
||||
brushPtr->logbrush.lbStyle = lb->lbStyle;
|
||||
brushPtr->logbrush.lbColor = lb->lbColor;
|
||||
brushPtr->logbrush.lbHatch = lb->lbHatch;
|
||||
|
||||
BRUSHOBJ_UnlockBrush (hBrush);
|
||||
DPRINT("%08x\n", hBrush);
|
||||
|
||||
|
||||
return hBrush;
|
||||
}
|
||||
|
||||
|
|
|
@ -119,6 +119,7 @@ HPALETTE STDCALL W32kCreateHalftonePalette(HDC hDC)
|
|||
HPALETTE STDCALL W32kCreatePalette(CONST PLOGPALETTE palette)
|
||||
{
|
||||
PPALOBJ PalObj;
|
||||
|
||||
HPALETTE NewPalette = EngCreatePalette(PAL_INDEXED, palette->palNumEntries, palette->palPalEntry, 0, 0, 0);
|
||||
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
|
||||
*
|
||||
|
@ -16,6 +16,7 @@
|
|||
#include <win32k/region.h>
|
||||
#include <win32k/gdiobj.h>
|
||||
#include <win32k/pen.h>
|
||||
#include <win32k/text.h>
|
||||
#include "../eng/objects.h"
|
||||
|
||||
// #define NDEBUG
|
||||
|
@ -166,6 +167,8 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC)
|
|||
NewDC->w.hBitmap = hBitmap;
|
||||
NewDC->w.hFirstBitmap = hBitmap;
|
||||
NewDC->w.hPalette = OrigDC->w.hPalette;
|
||||
NewDC->w.textColor = OrigDC->w.textColor;
|
||||
NewDC->w.textAlign = OrigDC->w.textAlign;
|
||||
|
||||
DC_UnlockDC(NewDC);
|
||||
DC_UnlockDC(OrigDC);
|
||||
|
@ -173,6 +176,8 @@ HDC STDCALL W32kCreateCompatableDC(HDC hDC)
|
|||
return DC_PtrToHandle(NewDC);
|
||||
}
|
||||
|
||||
#include <ddk/ntddvid.h>
|
||||
|
||||
HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
||||
LPCWSTR Device,
|
||||
LPCWSTR Output,
|
||||
|
@ -192,7 +197,7 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
|||
}
|
||||
|
||||
DPRINT("NAME: %S\n", Driver); // FIXME: Should not crash if NULL
|
||||
|
||||
|
||||
/* Allocate a DC object */
|
||||
if ((NewDC = DC_AllocDC(Driver)) == NULL)
|
||||
{
|
||||
|
@ -291,6 +296,9 @@ HDC STDCALL W32kCreateDC(LPCWSTR Driver,
|
|||
DC_InitDC(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(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/text.h>
|
||||
#include <win32k/kapi.h>
|
||||
// #include <freetype/freetype.h>
|
||||
#include <freetype/freetype.h>
|
||||
|
||||
#include "../eng/objects.h"
|
||||
|
||||
// #define NDEBUG
|
||||
#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()
|
||||
{
|
||||
/* ULONG error;
|
||||
ULONG error;
|
||||
|
||||
error = FT_Init_FreeType(&library);
|
||||
if(error)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -29,7 +45,103 @@ int
|
|||
STDCALL
|
||||
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
|
||||
|
@ -49,14 +161,53 @@ W32kCreateFont(int Height,
|
|||
DWORD PitchAndFamily,
|
||||
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
|
||||
STDCALL
|
||||
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
|
||||
|
@ -268,7 +419,42 @@ W32kGetTextExtentPoint(HDC hDC,
|
|||
int Count,
|
||||
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
|
||||
|
@ -295,7 +481,13 @@ STDCALL
|
|||
W32kGetTextMetrics(HDC hDC,
|
||||
LPTEXTMETRIC tm)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
PDC dc = AccessUserObject(hDC);
|
||||
PFONTGDI FontGDI;
|
||||
|
||||
FontGDI = AccessInternalObject(dc->w.hFont);
|
||||
memcpy(tm, &FontGDI->TextMetric, sizeof(TEXTMETRIC));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
|
@ -357,6 +549,7 @@ W32kSetTextColor(HDC hDC,
|
|||
|
||||
oldColor = dc->w.textColor;
|
||||
dc->w.textColor = color;
|
||||
|
||||
DC_UnlockDC(hDC);
|
||||
|
||||
return oldColor;
|
||||
|
@ -379,104 +572,55 @@ W32kTextOut(HDC hDC,
|
|||
LPCWSTR String,
|
||||
int Count)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
// Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
|
||||
/*
|
||||
|
||||
DC *dc = DC_HandleToPtr(hDC);
|
||||
SURFOBJ *SurfObj = AccessUserObject(dc->Surface);
|
||||
UNICODE_STRING FileName;
|
||||
int error, glyph_index, n, load_flags = FT_LOAD_RENDER, i, j;
|
||||
int error, glyph_index, n, load_flags = FT_LOAD_RENDER, i, j, sx, sy, scc;
|
||||
FT_Face face;
|
||||
FT_GlyphSlot glyph;
|
||||
NTSTATUS Status;
|
||||
HANDLE FileHandle;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
FILE_STANDARD_INFORMATION FileStdInfo;
|
||||
PVOID buffer;
|
||||
ULONG size, TextLeft = XStart, TextTop = YStart, SpaceBetweenChars = 5, StringLength;
|
||||
FT_Vector origin;
|
||||
FT_Bitmap bit, bit2, bit3;
|
||||
POINTL SourcePoint;
|
||||
RECTL DestRect;
|
||||
ULONG TextLeft = XStart, TextTop = YStart, SpaceBetweenChars = 2, pitch, previous;
|
||||
FT_Bool use_kerning;
|
||||
RECTL DestRect, MaskRect;
|
||||
POINTL SourcePoint, BrushOrigin;
|
||||
HBRUSH hBrush;
|
||||
PBRUSHOBJ Brush;
|
||||
HBITMAP HSourceGlyph;
|
||||
PSURFOBJ SourceGlyphSurf;
|
||||
SIZEL bitSize;
|
||||
FT_CharMap found = 0;
|
||||
FT_CharMap charmap;
|
||||
PCHAR bitbuf;
|
||||
FT_CharMap found = 0, charmap;
|
||||
INT yoff;
|
||||
HFONT hFont = 0;
|
||||
PFONTOBJ FontObj;
|
||||
PFONTGDI FontGDI;
|
||||
PTEXTOBJ TextObj;
|
||||
PPALGDI PalDestGDI;
|
||||
PXLATEOBJ XlateObj;
|
||||
|
||||
// For now we're just going to use an internal font
|
||||
// grWriteCellString(SurfObj, XStart, YStart, AString->Buffer, 0xffffff);
|
||||
TextObj = TEXTOBJ_HandleToPtr(dc->w.hFont);
|
||||
|
||||
// Prepare the Unicode FileName
|
||||
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))
|
||||
for(i=0; i<FontsLoaded; i++)
|
||||
{
|
||||
DbgPrint("Could not open module file: %wZ\n", L"c:/reactos/fonts/arial.ttf");
|
||||
return 0;
|
||||
if(wcscmp(FontTable[i].FaceName, (LPSTR)TextObj->logfont.lfFaceName) == 0)
|
||||
hFont = FontTable[i].hFont;
|
||||
}
|
||||
|
||||
// Get the size of the file
|
||||
Status = NtQueryInformationFile(FileHandle, NULL, &FileStdInfo, sizeof(FileStdInfo), FileStandardInformation);
|
||||
if (!NT_SUCCESS(Status))
|
||||
if(hFont == 0)
|
||||
{
|
||||
DbgPrint("Could not get file size\n");
|
||||
return 0;
|
||||
DbgPrint("Specified font %s is not loaded\n", TextObj->logfont.lfFaceName);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// 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, // 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);
|
||||
FontObj = AccessUserObject(hFont);
|
||||
FontGDI = AccessInternalObject(hFont);
|
||||
face = FontGDI->face;
|
||||
|
||||
if (face->charmap == NULL)
|
||||
{
|
||||
DbgPrint("WARNING: No charmap selected!\n");
|
||||
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];
|
||||
DbgPrint("found charmap encoding: %u\n", charmap->encoding);
|
||||
|
@ -486,70 +630,97 @@ W32kTextOut(HDC hDC,
|
|||
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);
|
||||
if (error) DbgPrint("WARNING: Could not set the charmap!\n");
|
||||
|
||||
error = FT_Set_Char_Size(
|
||||
face, // handle to face object
|
||||
16*64, // char_width in 1/64th of points
|
||||
16*64, // char_height in 1/64th of points
|
||||
300, // horizontal device resolution
|
||||
300 ); // vertical device resolution
|
||||
error = FT_Set_Pixel_Sizes(face, TextObj->logfont.lfHeight, TextObj->logfont.lfWidth);
|
||||
if(error) {
|
||||
DbgPrint("Error in setting pixel sizes: %u\n", error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
StringLength = wcslen(String);
|
||||
DbgPrint("StringLength: %u\n", StringLength);
|
||||
// Create the brush
|
||||
PalDestGDI = AccessInternalObject(dc->w.hPalette);
|
||||
XlateObj = EngCreateXlate(PalDestGDI->Mode, PAL_RGB, dc->w.hPalette, NULL);
|
||||
hBrush = W32kCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor));
|
||||
Brush = BRUSHOBJ_HandleToPtr(hBrush);
|
||||
EngDeleteXlate(XlateObj);
|
||||
|
||||
for(i=0; i<StringLength; i++)
|
||||
SourcePoint.x = 0;
|
||||
SourcePoint.y = 0;
|
||||
MaskRect.left = 0;
|
||||
MaskRect.top = 0;
|
||||
BrushOrigin.x = 0;
|
||||
BrushOrigin.y = 0;
|
||||
|
||||
// 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);
|
||||
|
||||
error = FT_Load_Glyph(
|
||||
face, // handle to face object
|
||||
glyph_index, // glyph index
|
||||
FT_LOAD_DEFAULT ); // load flags (erase previous glyph)
|
||||
if(error) DbgPrint("WARNING: Failed to load and render glyph!\n");
|
||||
|
||||
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);
|
||||
return FALSE;
|
||||
}
|
||||
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");
|
||||
error = FT_Render_Glyph( glyph, ft_render_mode_normal );
|
||||
if(error) DbgPrint("WARNING: Failed to render glyph!\n");
|
||||
} 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;
|
||||
FT_Vector delta;
|
||||
FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
|
||||
TextLeft += delta.x >> 6;
|
||||
}
|
||||
|
||||
SourcePoint.x = 0;
|
||||
SourcePoint.y = 0;
|
||||
DestRect.left = TextLeft;
|
||||
DestRect.top = TextTop;
|
||||
DestRect.right = TextLeft + glyph->bitmap.width-1;
|
||||
DestRect.bottom = TextTop + glyph->bitmap.rows-1;
|
||||
bitSize.cx = glyph->bitmap.width-1;
|
||||
bitSize.cy = glyph->bitmap.rows-1;
|
||||
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");
|
||||
return FALSE;
|
||||
}
|
||||
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);
|
||||
|
||||
EngBitBlt(SurfObj, SourceGlyphSurf,
|
||||
NULL, NULL, NULL, &DestRect, &SourcePoint, NULL, NULL, NULL, NULL);
|
||||
// Use the font data as a mask to paint onto the DCs surface using a brush
|
||||
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++;
|
||||
}
|
||||
|
||||
DbgPrint("BREAK\n"); for (;;) ;
|
||||
*/
|
||||
/* RtlFreeAnsiString(AString);
|
||||
RtlFreeUnicodeString(UString); */
|
||||
}
|
||||
|
||||
UINT
|
||||
|
|
Loading…
Reference in a new issue