/** Includes ******************************************************************/
-#include <w32k.h>
+#include <win32k.h>
#include <ft2build.h>
#include FT_FREETYPE_H
#include <freetype/tttables.h>
#include <freetype/fttrigon.h>
#include <freetype/ftglyph.h>
+#include <freetype/ftbitmap.h>
#include <freetype/ftoutln.h>
#include <freetype/ftwinfnt.h>
static BOOL RenderingEnabled = TRUE;
#define MAX_FONT_CACHE 256
-UINT Hits;
-UINT Misses;
typedef struct _FONT_CACHE_ENTRY
{
LIST_ENTRY ListEntry;
int GlyphIndex;
FT_Face Face;
- FT_Glyph Glyph;
+ FT_BitmapGlyph BitmapGlyph;
int Height;
} FONT_CACHE_ENTRY, *PFONT_CACHE_ENTRY;
static LIST_ENTRY FontCacheListHead;
if (NT_SUCCESS(Status))
{
- DirInfoBuffer = ExAllocatePool(PagedPool, 0x4000);
+ DirInfoBuffer = ExAllocatePoolWithTag(PagedPool, 0x4000, TAG_FONT);
if (DirInfoBuffer == NULL)
{
ZwClose(hDirectory);
return;
}
- FileName.Buffer = ExAllocatePool(PagedPool, MAX_PATH * sizeof(WCHAR));
+ FileName.Buffer = ExAllocatePoolWithTag(PagedPool, MAX_PATH * sizeof(WCHAR), TAG_FONT);
if (FileName.Buffer == NULL)
{
- ExFreePool(DirInfoBuffer);
+ ExFreePoolWithTag(DirInfoBuffer, TAG_FONT);
ZwClose(hDirectory);
return;
}
bRestartScan = FALSE;
}
- ExFreePool(FileName.Buffer);
- ExFreePool(DirInfoBuffer);
+ ExFreePoolWithTag(FileName.Buffer, TAG_FONT);
+ ExFreePoolWithTag(DirInfoBuffer, TAG_FONT);
ZwClose(hDirectory);
}
}
PSECTION_OBJECT SectionObject;
ULONG ViewSize = 0;
LARGE_INTEGER SectionSize;
+#if 0 // Wine code
FT_Fixed XScale, YScale;
+#endif
UNICODE_STRING FontRegPath = RTL_CONSTANT_STRING(L"\\REGISTRY\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Fonts");
/* Open the font file */
FontGDI->face = Face;
/* FIXME: Complete text metrics */
+#if 0 /* This (Wine) code doesn't seem to work correctly for us */
XScale = Face->size->metrics.x_scale;
YScale = Face->size->metrics.y_scale;
-#if 0 /* This (Wine) code doesn't seem to work correctly for us */
FontGDI->TextMetric.tmAscent = (FT_MulFix(Face->ascender, YScale) + 32) >> 6;
FontGDI->TextMetric.tmDescent = (FT_MulFix(Face->descender, YScale) + 32) >> 6;
FontGDI->TextMetric.tmHeight = (FT_MulFix(Face->ascender, YScale) -
if (Characteristics & FR_PRIVATE)
{
- PW32PROCESS Win32Process = PsGetCurrentProcessWin32Process();
+ PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process();
IntLockProcessPrivateFonts(Win32Process);
InsertTailList(&Win32Process->PrivateFontListHead, &Entry->ListEntry);
IntUnLockProcessPrivateFonts(Win32Process);
}
+static BOOL face_has_symbol_charmap(FT_Face ft_face)
+{
+ int i;
+
+ for(i = 0; i < ft_face->num_charmaps; i++)
+ {
+ if(ft_face->charmaps[i]->encoding == FT_ENCODING_MS_SYMBOL)
+ return TRUE;
+ }
+ return FALSE;
+}
+
static void FASTCALL
FillTM(TEXTMETRICW *TM, PFONTGDI FontGDI, TT_OS2 *pOS2, TT_HoriHeader *pHori, FT_WinFNT_HeaderRec *pWin)
{
TM->tmOverhang = 0;
TM->tmDigitizedAspectX = 96;
TM->tmDigitizedAspectY = 96;
- TM->tmFirstChar = pOS2->usFirstCharIndex;
- TM->tmDefaultChar = pOS2->usDefaultChar ? pOS2->usDefaultChar : 0xffff;
- TM->tmLastChar = pOS2->usLastCharIndex;
- TM->tmBreakChar = L'\0' != pOS2->usBreakChar ? pOS2->usBreakChar : ' ';
+ if (face_has_symbol_charmap(Face) || (pOS2->usFirstCharIndex >= 0xf000 && pOS2->usFirstCharIndex < 0xf100))
+ {
+ USHORT cpOEM, cpAnsi;
+
+ EngGetCurrentCodePage(&cpOEM, &cpAnsi);
+ TM->tmFirstChar = 0;
+ switch(cpAnsi)
+ {
+ case 1257: /* Baltic */
+ TM->tmLastChar = 0xf8fd;
+ break;
+ default:
+ TM->tmLastChar = 0xf0ff;
+ }
+ TM->tmBreakChar = 0x20;
+ TM->tmDefaultChar = 0x1f;
+ }
+ else
+ {
+ TM->tmFirstChar = pOS2->usFirstCharIndex; /* Should be the first char in the cmap */
+ TM->tmLastChar = pOS2->usLastCharIndex; /* Should be min(cmap_last, os2_last) */
+
+ if(pOS2->usFirstCharIndex <= 1)
+ TM->tmBreakChar = pOS2->usFirstCharIndex + 2;
+ else if (pOS2->usFirstCharIndex > 0xff)
+ TM->tmBreakChar = 0x20;
+ else
+ TM->tmBreakChar = pOS2->usFirstCharIndex;
+ TM->tmDefaultChar = TM->tmBreakChar - 1;
+ }
TM->tmItalic = (Face->style_flags & FT_STYLE_FLAG_ITALIC) ? 255 : 0;
TM->tmUnderlined = FontGDI->Underline;
TM->tmStruckOut = FontGDI->StrikeOut;
static PFONTGDI FASTCALL
FindFaceNameInLists(PUNICODE_STRING FaceName)
{
- PW32PROCESS Win32Process;
+ PPROCESSINFO Win32Process;
PFONTGDI Font;
/* Search the process local list */
}
-FT_Glyph APIENTRY
+FT_BitmapGlyph APIENTRY
ftGdiGlyphCacheGet(
FT_Face Face,
INT GlyphIndex,
PLIST_ENTRY CurrentEntry;
PFONT_CACHE_ENTRY FontEntry;
-// DbgPrint("CacheGet\n");
-
CurrentEntry = FontCacheListHead.Flink;
while (CurrentEntry != &FontCacheListHead)
{
if (CurrentEntry == &FontCacheListHead)
{
-// DbgPrint("Miss! %x\n", FontEntry->Glyph);
- /*
- Misses++;
- if (Misses>100) {
- DbgPrint ("Hits: %d Misses: %d\n", Hits, Misses);
- Hits = Misses = 0;
- }
- */
return NULL;
}
RemoveEntryList(CurrentEntry);
InsertHeadList(&FontCacheListHead, CurrentEntry);
-
-// DbgPrint("Hit! %x\n", FontEntry->Glyph);
- /*
- Hits++;
-
- if (Hits>100) {
- DbgPrint ("Hits: %d Misses: %d\n", Hits, Misses);
- Hits = Misses = 0;
- }
- */
- return FontEntry->Glyph;
+ return FontEntry->BitmapGlyph;
}
-FT_Glyph APIENTRY
+FT_BitmapGlyph APIENTRY
ftGdiGlyphCacheSet(
FT_Face Face,
INT GlyphIndex,
FT_Glyph GlyphCopy;
INT error;
PFONT_CACHE_ENTRY NewEntry;
-
-// DbgPrint("CacheSet.\n");
+ FT_Bitmap AlignedBitmap;
+ FT_BitmapGlyph BitmapGlyph;
error = FT_Get_Glyph(GlyphSlot, &GlyphCopy);
if (error)
{
- DbgPrint("Failure caching glyph.\n");
+ DPRINT1("Failure caching glyph.\n");
return NULL;
};
+
error = FT_Glyph_To_Bitmap(&GlyphCopy, RenderMode, 0, 1);
if (error)
{
- DbgPrint("Failure rendering glyph.\n");
+ DPRINT1("Failure rendering glyph.\n");
return NULL;
};
NewEntry = ExAllocatePoolWithTag(PagedPool, sizeof(FONT_CACHE_ENTRY), TAG_FONT);
if (!NewEntry)
{
- DbgPrint("Alloc failure caching glyph.\n");
+ DPRINT1("Alloc failure caching glyph.\n");
FT_Done_Glyph(GlyphCopy);
return NULL;
}
+ BitmapGlyph = (FT_BitmapGlyph)GlyphCopy;
+ FT_Bitmap_New(&AlignedBitmap);
+ if(FT_Bitmap_Convert(GlyphSlot->library, &BitmapGlyph->bitmap, &AlignedBitmap, 4))
+ {
+ DPRINT1("Conversion failed\n");
+ FT_Done_Glyph((FT_Glyph)BitmapGlyph);
+ return NULL;
+ }
+
+ FT_Bitmap_Done(GlyphSlot->library, &BitmapGlyph->bitmap);
+ BitmapGlyph->bitmap = AlignedBitmap;
+
NewEntry->GlyphIndex = GlyphIndex;
NewEntry->Face = Face;
- NewEntry->Glyph = GlyphCopy;
+ NewEntry->BitmapGlyph = BitmapGlyph;
NewEntry->Height = Height;
InsertHeadList(&FontCacheListHead, &NewEntry->ListEntry);
if (FontCacheNumEntries++ > MAX_FONT_CACHE)
{
NewEntry = (PFONT_CACHE_ENTRY)FontCacheListHead.Blink;
- FT_Done_Glyph(NewEntry->Glyph);
+ FT_Done_Glyph((FT_Glyph)NewEntry->BitmapGlyph);
RemoveTailList(&FontCacheListHead);
ExFreePool(NewEntry);
FontCacheNumEntries--;
}
-// DbgPrint("Returning the glyphcopy: %x\n", GlyphCopy);
-
- return GlyphCopy;
+ return BitmapGlyph;
}
BOOL bIgnoreRotation)
{
static const FT_Matrix identityMat = {(1 << 16), 0, 0, (1 << 16)};
- PDC_ATTR Dc_Attr;
+ PDC_ATTR pdcattr;
PTEXTOBJ TextObj;
PFONTGDI FontGDI;
HFONT hFont = 0;
DPRINT("%d, %08x, %p, %08lx, %p, %p\n", wch, iFormat, pgm,
cjBuf, pvBuf, pmat2);
- Dc_Attr = dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+ pdcattr = dc->pdcattr;
- MatrixS2XForm(&xForm, &dc->DcLevel.mxWorldToDevice);
+ MatrixS2XForm(&xForm, &dc->dclevel.mxWorldToDevice);
eM11 = xForm.eM11;
- hFont = Dc_Attr->hlfntNew;
+ hFont = pdcattr->hlfntNew;
TextObj = RealizeFontInit(hFont);
if (!TextObj)
TextIntGetTextExtentPoint(PDC dc,
PTEXTOBJ TextObj,
LPCWSTR String,
- int Count,
- int MaxExtent,
+ INT Count,
+ ULONG MaxExtent,
LPINT Fit,
LPINT Dx,
- LPSIZE Size)
+ LPSIZE Size,
+ FLONG fl)
{
PFONTGDI FontGDI;
FT_Face face;
FT_GlyphSlot glyph;
- FT_Glyph realglyph;
+ FT_BitmapGlyph realglyph;
INT error, n, glyph_index, i, previous;
ULONGLONG TotalWidth = 0;
FT_CharMap charmap, found = NULL;
for (i = 0; i < Count; i++)
{
- glyph_index = FT_Get_Char_Index(face, *String);
+ if (fl & GTEF_INDICES)
+ glyph_index = *String;
+ else
+ glyph_index = FT_Get_Char_Index(face, *String);
+
if (!(realglyph = ftGdiGlyphCacheGet(face, glyph_index,
TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight)))
{
TotalWidth += delta.x;
}
- TotalWidth += realglyph->advance.x >> 10;
+ TotalWidth += realglyph->root.advance.x >> 10;
if (((TotalWidth + 32) >> 6) <= MaxExtent && NULL != Fit)
{
Size->cx = (TotalWidth + 32) >> 6;
Size->cy = (TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight < 0 ? - TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight : TextObj->logfont.elfEnumLogfontEx.elfLogFont.lfHeight);
- Size->cy = EngMulDiv(Size->cy, IntGdiGetDeviceCaps(dc, LOGPIXELSY), 72);
+ Size->cy = EngMulDiv(Size->cy, dc->ppdev->gdiinfo.ulLogPixelsY, 72);
return TRUE;
}
LPFONTSIGNATURE lpSig,
DWORD dwFlags)
{
- PDC_ATTR Dc_Attr;
+ PDC_ATTR pdcattr;
UINT Ret = DEFAULT_CHARSET, i;
HFONT hFont;
PTEXTOBJ TextObj;
DWORD cp, fs0;
USHORT usACP, usOEM;
- Dc_Attr = Dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &Dc->Dc_Attr;
- hFont = Dc_Attr->hlfntNew;
+ pdcattr = Dc->pdcattr;
+ hFont = pdcattr->hlfntNew;
TextObj = RealizeFontInit(hFont);
if (!TextObj)
PTMW_INTERNAL ptmwi)
{
PDC dc;
- PDC_ATTR Dc_Attr;
+ PDC_ATTR pdcattr;
PTEXTOBJ TextObj;
PFONTGDI FontGDI;
FT_Face Face;
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
- Dc_Attr = dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
- TextObj = RealizeFontInit(Dc_Attr->hlfntNew);
+ pdcattr = dc->pdcattr;
+ TextObj = RealizeFontInit(pdcattr->hlfntNew);
if (NULL != TextObj)
{
FontGDI = ObjToGDI(TextObj->Font, FONT);
NTSTATUS Status = STATUS_SUCCESS;
PTEXTOBJ TextObj;
UNICODE_STRING FaceName;
- PW32PROCESS Win32Process;
+ PPROCESSINFO Win32Process;
UINT MatchScore;
if (!pTextObj)
LOGFONTW LogFont;
PFONTFAMILYINFO Info;
DWORD Count;
- PW32PROCESS Win32Process;
+ PPROCESSINFO Win32Process;
/* Make a safe copy */
Status = MmCopyFromCaller(&LogFont, UnsafeLogFont, sizeof(LOGFONTW));
*/
DC *dc;
- PDC_ATTR Dc_Attr;
+ PDC_ATTR pdcattr;
SURFOBJ *SurfObj;
SURFACE *psurf = NULL;
int error, glyph_index, n, i;
FT_Face face;
FT_GlyphSlot glyph;
- FT_Glyph realglyph;
- FT_BitmapGlyph realglyph2;
+ FT_BitmapGlyph realglyph;
LONGLONG TextLeft, RealXStart;
ULONG TextTop, previous, BackgroundLeft;
FT_Bool use_kerning;
- RECTL DestRect, MaskRect;
+ RECTL DestRect, MaskRect, DummyRect = {0, 0, 0, 0};
POINTL SourcePoint, BrushOrigin;
- HBRUSH hBrushFg = NULL;
- PGDIBRUSHOBJ BrushFg = NULL;
- GDIBRUSHINST BrushFgInst;
- HBRUSH hBrushBg = NULL;
- PGDIBRUSHOBJ BrushBg = NULL;
- GDIBRUSHINST BrushBgInst;
HBITMAP HSourceGlyph;
SURFOBJ *SourceGlyphSurf;
SIZEL bitSize;
FONTOBJ *FontObj;
PFONTGDI FontGDI;
PTEXTOBJ TextObj = NULL;
- PPALGDI PalDestGDI;
- XLATEOBJ *XlateObj=NULL, *XlateObj2=NULL;
- ULONG Mode;
+ EXLATEOBJ exloRGB2Dst, exloDst2RGB;
FT_Render_Mode RenderMode;
BOOLEAN Render;
POINT Start;
BOOL DoBreak = FALSE;
- HPALETTE hDestPalette;
USHORT DxShift;
// TODO: Write test-cases to exactly match real Windows in different
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
- if (dc->DC_Type == DC_TYPE_INFO)
+ if (dc->dctype == DC_TYPE_INFO)
{
DC_UnlockDc(dc);
/* Yes, Windows really returns TRUE in this case */
return TRUE;
}
- Dc_Attr = dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+ pdcattr = dc->pdcattr;
+
+ if ((fuOptions & ETO_OPAQUE) || pdcattr->jBkMode == OPAQUE)
+ {
+ if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
+ DC_vUpdateBackgroundBrush(dc);
+ }
/* Check if String is valid */
if ((Count > 0xFFFF) || (Count > 0 && String == NULL))
DxShift = fuOptions & ETO_PDY ? 1 : 0;
- if (PATH_IsPathOpen(dc->DcLevel))
+ if (PATH_IsPathOpen(dc->dclevel))
{
if (!PATH_ExtTextOut( dc,
XStart,
IntLPtoDP(dc, (POINT *)lprc, 2);
}
- psurf = SURFACE_LockSurface(dc->w.hBitmap);
- if (!psurf)
- {
- goto fail;
- }
- SurfObj = &psurf->SurfObj;
- ASSERT(SurfObj);
-
Start.x = XStart;
Start.y = YStart;
IntLPtoDP(dc, &Start, 1);
RealXStart = (Start.x + dc->ptlDCOrig.x) << 6;
YStart = Start.y + dc->ptlDCOrig.y;
- /* Create the brushes */
- hDestPalette = psurf->hDIBPalette;
- if (!hDestPalette) hDestPalette = pPrimarySurface->DevInfo.hpalDefault;
- PalDestGDI = PALETTE_LockPalette(hDestPalette);
- if ( !PalDestGDI )
- Mode = PAL_RGB;
- else
- {
- Mode = PalDestGDI->Mode;
- PALETTE_UnlockPalette(PalDestGDI);
- }
- XlateObj = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, hDestPalette, NULL);
- if ( !XlateObj )
- {
- goto fail;
- }
- hBrushFg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, Dc_Attr->crForegroundClr), 0);
- if ( !hBrushFg )
- {
- goto fail;
- }
- BrushFg = BRUSHOBJ_LockBrush(hBrushFg);
- if ( !BrushFg )
- {
- goto fail;
- }
- IntGdiInitBrushInstance(&BrushFgInst, BrushFg, NULL);
- if ((fuOptions & ETO_OPAQUE) || Dc_Attr->jBkMode == OPAQUE)
- {
- hBrushBg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, Dc_Attr->crBackgroundClr), 0);
- if ( !hBrushBg )
- {
- goto fail;
- }
- BrushBg = BRUSHOBJ_LockBrush(hBrushBg);
- if ( !BrushBg )
- {
- goto fail;
- }
- IntGdiInitBrushInstance(&BrushBgInst, BrushBg, NULL);
- }
- XlateObj2 = (XLATEOBJ*)IntEngCreateXlate(PAL_RGB, Mode, NULL, hDestPalette);
- if ( !XlateObj2 )
- {
- goto fail;
- }
-
SourcePoint.x = 0;
SourcePoint.y = 0;
MaskRect.left = 0;
if ((fuOptions & ETO_OPAQUE) && lprc)
{
- DestRect.left = lprc->left + dc->ptlDCOrig.x;
- DestRect.top = lprc->top + dc->ptlDCOrig.y;
- DestRect.right = lprc->right + dc->ptlDCOrig.x;
- DestRect.bottom = lprc->bottom + dc->ptlDCOrig.y;
+ DestRect.left = lprc->left;
+ DestRect.top = lprc->top;
+ DestRect.right = lprc->right;
+ DestRect.bottom = lprc->bottom;
+
IntLPtoDP(dc, (LPPOINT)&DestRect, 2);
+
+ DestRect.left += dc->ptlDCOrig.x;
+ DestRect.top += dc->ptlDCOrig.y;
+ DestRect.right += dc->ptlDCOrig.x;
+ DestRect.bottom += dc->ptlDCOrig.y;
+
+ DC_vPrepareDCsForBlit(dc, DestRect, NULL, DestRect);
+
+ if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
+ DC_vUpdateBackgroundBrush(dc);
+
IntEngBitBlt(
- &psurf->SurfObj,
+ &dc->dclevel.pSurface->SurfObj,
NULL,
NULL,
- dc->CombinedClip,
+ dc->rosdc.CombinedClip,
NULL,
&DestRect,
&SourcePoint,
&SourcePoint,
- &BrushBgInst.BrushObject,
+ &dc->eboBackground.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
fuOptions &= ~ETO_OPAQUE;
+ DC_vFinishBlit(dc, NULL);
}
else
{
- if (Dc_Attr->jBkMode == OPAQUE)
+ if (pdcattr->jBkMode == OPAQUE)
{
fuOptions |= ETO_OPAQUE;
}
}
- TextObj = RealizeFontInit(Dc_Attr->hlfntNew);
+ TextObj = RealizeFontInit(pdcattr->hlfntNew);
if (TextObj == NULL)
{
goto fail;
* Process the vertical alignment and determine the yoff.
*/
- if (Dc_Attr->lTextAlign & TA_BASELINE)
+ if (pdcattr->lTextAlign & TA_BASELINE)
yoff = 0;
- else if (Dc_Attr->lTextAlign & TA_BOTTOM)
+ else if (pdcattr->lTextAlign & TA_BOTTOM)
yoff = -face->size->metrics.descender >> 6;
else /* TA_TOP */
yoff = face->size->metrics.ascender >> 6;
* Process the horizontal alignment and modify XStart accordingly.
*/
- if (Dc_Attr->lTextAlign & (TA_RIGHT | TA_CENTER))
+ if (pdcattr->lTextAlign & (TA_RIGHT | TA_CENTER))
{
ULONGLONG TextWidth = 0;
LPCWSTR TempText = String;
TextWidth += delta.x;
}
- TextWidth += realglyph->advance.x >> 10;
+ TextWidth += realglyph->root.advance.x >> 10;
previous = glyph_index;
TempText++;
previous = 0;
- if (Dc_Attr->lTextAlign & TA_RIGHT)
+ if (pdcattr->lTextAlign & TA_RIGHT)
{
RealXStart -= TextWidth;
}
TextTop = YStart;
BackgroundLeft = (RealXStart + 32) >> 6;
+ /* Lock blit with a dummy rect */
+ DC_vPrepareDCsForBlit(dc, DummyRect, NULL, DummyRect);
+
+ psurf = dc->dclevel.pSurface ;
+ SurfObj = &psurf->SurfObj ;
+
+ EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, psurf->ppal, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exloDst2RGB, psurf->ppal, &gpalRGB, 0, 0, 0);
+
+ if ((fuOptions & ETO_OPAQUE) && (dc->pdcattr->ulDirty_ & DIRTY_BACKGROUND))
+ DC_vUpdateBackgroundBrush(dc) ;
+
+ if(dc->pdcattr->ulDirty_ & DIRTY_TEXT)
+ DC_vUpdateTextBrush(dc) ;
+
/*
* The main rendering loop.
*/
-
for (i = 0; i < Count; i++)
{
if (fuOptions & ETO_GLYPH_INDEX)
{
DPRINT1("Failed to load and render glyph! [index: %u]\n", glyph_index);
IntUnLockFreeType;
- goto fail;
+ goto fail2;
}
glyph = face->glyph;
realglyph = ftGdiGlyphCacheSet(face,
{
DPRINT1("Failed to render glyph! [index: %u]\n", glyph_index);
IntUnLockFreeType;
- goto fail;
+ goto fail2;
}
}
-// DbgPrint("realglyph: %x\n", realglyph);
-// DbgPrint("TextLeft: %d\n", TextLeft);
/* retrieve kerning distance and move pen position */
if (use_kerning && previous && glyph_index && NULL == Dx)
FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
TextLeft += delta.x;
}
-// DPRINT1("TextLeft: %d\n", TextLeft);
-// DPRINT1("TextTop: %d\n", TextTop);
-
- if (realglyph->format == ft_glyph_format_outline)
- {
- DbgPrint("Should already be done\n");
-// error = FT_Render_Glyph(glyph, RenderMode);
- error = FT_Glyph_To_Bitmap(&realglyph, RenderMode, 0, 0);
- if (error)
- {
- DPRINT1("WARNING: Failed to render glyph!\n");
- goto fail;
- }
- }
- realglyph2 = (FT_BitmapGlyph)realglyph;
-
-// DPRINT1("Pitch: %d\n", pitch);
-// DPRINT1("Advance: %d\n", realglyph->advance.x);
+ DPRINT("TextLeft: %d\n", TextLeft);
+ DPRINT("TextTop: %d\n", TextTop);
+ DPRINT("Advance: %d\n", realglyph->root.advance.x);
if (fuOptions & ETO_OPAQUE)
{
DestRect.left = BackgroundLeft;
- DestRect.right = (TextLeft + (realglyph->advance.x >> 10) + 32) >> 6;
+ DestRect.right = (TextLeft + (realglyph->root.advance.x >> 10) + 32) >> 6;
DestRect.top = TextTop + yoff - ((face->size->metrics.ascender + 32) >> 6);
DestRect.bottom = TextTop + yoff + ((32 - face->size->metrics.descender) >> 6);
+ MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
IntEngBitBlt(
&psurf->SurfObj,
NULL,
NULL,
- dc->CombinedClip,
+ dc->rosdc.CombinedClip,
NULL,
&DestRect,
&SourcePoint,
&SourcePoint,
- &BrushBgInst.BrushObject,
+ &dc->eboBackground.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
+ MouseSafetyOnDrawEnd(dc->ppdev);
BackgroundLeft = DestRect.right;
+
}
- DestRect.left = ((TextLeft + 32) >> 6) + realglyph2->left;
- DestRect.right = DestRect.left + realglyph2->bitmap.width;
- DestRect.top = TextTop + yoff - realglyph2->top;
- DestRect.bottom = DestRect.top + realglyph2->bitmap.rows;
+ DestRect.left = ((TextLeft + 32) >> 6) + realglyph->left;
+ DestRect.right = DestRect.left + realglyph->bitmap.width;
+ DestRect.top = TextTop + yoff - realglyph->top;
+ DestRect.bottom = DestRect.top + realglyph->bitmap.rows;
- bitSize.cx = realglyph2->bitmap.width;
- bitSize.cy = realglyph2->bitmap.rows;
- MaskRect.right = realglyph2->bitmap.width;
- MaskRect.bottom = realglyph2->bitmap.rows;
+ bitSize.cx = realglyph->bitmap.width;
+ bitSize.cy = realglyph->bitmap.rows;
+ MaskRect.right = realglyph->bitmap.width;
+ MaskRect.bottom = realglyph->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.
- *
- * FIXME: DIB bitmaps should have an lDelta which is a multiple of 4.
- * Here we pass in the pitch from the FreeType bitmap, which is not
- * guaranteed to be a multiple of 4. If it's not, we should expand
- * the FreeType bitmap to a temporary bitmap.
*/
- HSourceGlyph = EngCreateBitmap(bitSize, realglyph2->bitmap.pitch,
- (realglyph2->bitmap.pixel_mode == ft_pixel_mode_grays) ?
- BMF_8BPP : BMF_1BPP, BMF_TOPDOWN,
- realglyph2->bitmap.buffer);
+ HSourceGlyph = EngCreateBitmap(bitSize, realglyph->bitmap.pitch,
+ BMF_8BPP, BMF_TOPDOWN,
+ realglyph->bitmap.buffer);
if ( !HSourceGlyph )
{
DPRINT1("WARNING: EngLockSurface() failed!\n");
// FT_Done_Glyph(realglyph);
IntUnLockFreeType;
- goto fail;
+ goto fail2;
}
SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph);
if ( !SourceGlyphSurf )
EngDeleteSurface((HSURF)HSourceGlyph);
DPRINT1("WARNING: EngLockSurface() failed!\n");
IntUnLockFreeType;
- goto fail;
+ goto fail2;
}
/*
DestRect.right = lprc->right + dc->ptlDCOrig.x;
DoBreak = TRUE;
}
-
+ MouseSafetyOnDrawStart(dc->ppdev, DestRect.left, DestRect.top, DestRect.right, DestRect.bottom);
IntEngMaskBlt(
SurfObj,
SourceGlyphSurf,
- dc->CombinedClip,
- XlateObj,
- XlateObj2,
+ dc->rosdc.CombinedClip,
+ &exloRGB2Dst.xlo,
+ &exloDst2RGB.xlo,
&DestRect,
- &SourcePoint,
(PPOINTL)&MaskRect,
- &BrushFgInst.BrushObject,
+ &dc->eboText.BrushObject,
&BrushOrigin);
+ MouseSafetyOnDrawEnd(dc->ppdev) ;
EngUnlockSurface(SourceGlyphSurf);
EngDeleteSurface((HSURF)HSourceGlyph);
if (NULL == Dx)
{
- TextLeft += realglyph->advance.x >> 10;
-// DbgPrint("new TextLeft: %d\n", TextLeft);
+ TextLeft += realglyph->root.advance.x >> 10;
+ DPRINT("new TextLeft: %d\n", TextLeft);
}
else
{
TextLeft += Dx[i<<DxShift] << 6;
-// DbgPrint("new TextLeft2: %d\n", TextLeft);
+ DPRINT("new TextLeft2: %d\n", TextLeft);
}
if (DxShift)
String++;
}
-
IntUnLockFreeType;
- EngDeleteXlate(XlateObj);
- EngDeleteXlate(XlateObj2);
- SURFACE_UnlockSurface(psurf);
+ DC_vFinishBlit(dc, NULL) ;
+ EXLATEOBJ_vCleanup(&exloRGB2Dst);
+ EXLATEOBJ_vCleanup(&exloDst2RGB);
if (TextObj != NULL)
TEXTOBJ_UnlockText(TextObj);
- if (hBrushBg != NULL)
- {
- BRUSHOBJ_UnlockBrush(BrushBg);
- NtGdiDeleteObject(hBrushBg);
- }
- BRUSHOBJ_UnlockBrush(BrushFg);
- NtGdiDeleteObject(hBrushFg);
good:
DC_UnlockDc( dc );
return TRUE;
+fail2:
+ EXLATEOBJ_vCleanup(&exloRGB2Dst);
+ EXLATEOBJ_vCleanup(&exloDst2RGB);
fail:
- if ( XlateObj2 != NULL )
- EngDeleteXlate(XlateObj2);
- if ( XlateObj != NULL )
- EngDeleteXlate(XlateObj);
if (TextObj != NULL)
TEXTOBJ_UnlockText(TextObj);
- if (psurf != NULL)
- SURFACE_UnlockSurface(psurf);
- if (hBrushBg != NULL)
- {
- BRUSHOBJ_UnlockBrush(BrushBg);
- NtGdiDeleteObject(hBrushBg);
- }
- if (hBrushFg != NULL)
- {
- BRUSHOBJ_UnlockBrush(BrushFg);
- NtGdiDeleteObject(hBrushFg);
- }
+
DC_UnlockDc(dc);
return FALSE;
LPABC SafeBuff;
LPABCFLOAT SafeBuffF = NULL;
PDC dc;
- PDC_ATTR Dc_Attr;
+ PDC_ATTR pdcattr;
PTEXTOBJ TextObj;
PFONTGDI FontGDI;
FT_Face face;
return FALSE;
}
+ if (!Buffer)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
BufferSize = Count * sizeof(ABC); // Same size!
SafeBuff = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_GDITEXT);
if (!fl) SafeBuffF = (LPABCFLOAT) SafeBuff;
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
- Dc_Attr = dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
- hFont = Dc_Attr->hlfntNew;
+ pdcattr = dc->pdcattr;
+ hFont = pdcattr->hlfntNew;
TextObj = RealizeFontInit(hFont);
DC_UnlockDc(dc);
LPINT SafeBuff;
PFLOAT SafeBuffF = NULL;
PDC dc;
- PDC_ATTR Dc_Attr;
+ PDC_ATTR pdcattr;
PTEXTOBJ TextObj;
PFONTGDI FontGDI;
FT_Face face;
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
- Dc_Attr = dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
- hFont = Dc_Attr->hlfntNew;
+ pdcattr = dc->pdcattr;
+ hFont = pdcattr->hlfntNew;
TextObj = RealizeFontInit(hFont);
DC_UnlockDc(dc);
return TRUE;
}
+DWORD
+FASTCALL
+GreGetGlyphIndicesW(
+ HDC hdc,
+ LPWSTR pwc,
+ INT cwc,
+ LPWORD pgi,
+ DWORD iMode,
+ DWORD Unknown)
+{
+ PDC dc;
+ PDC_ATTR pdcattr;
+ PTEXTOBJ TextObj;
+ PFONTGDI FontGDI;
+ HFONT hFont = 0;
+ OUTLINETEXTMETRICW *potm;
+ INT i;
+ FT_Face face;
+ WCHAR DefChar = 0xffff;
+ PWSTR Buffer = NULL;
+ ULONG Size;
+
+ if ((!pwc) && (!pgi)) return cwc;
+
+ dc = DC_LockDc(hdc);
+ if (!dc)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return GDI_ERROR;
+ }
+ pdcattr = dc->pdcattr;
+ hFont = pdcattr->hlfntNew;
+ TextObj = RealizeFontInit(hFont);
+ DC_UnlockDc(dc);
+ if (!TextObj)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return GDI_ERROR;
+ }
+
+ FontGDI = ObjToGDI(TextObj->Font, FONT);
+ TEXTOBJ_UnlockText(TextObj);
+
+ Buffer = ExAllocatePoolWithTag(PagedPool, cwc*sizeof(WORD), TAG_GDITEXT);
+ if (!Buffer)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return GDI_ERROR;
+ }
+
+ if (iMode & GGI_MARK_NONEXISTING_GLYPHS) DefChar = 0x001f; /* Indicate non existence */
+ else
+ {
+ Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
+ potm = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT);
+ if (!potm)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ cwc = GDI_ERROR;
+ goto ErrorRet;
+ }
+ IntGetOutlineTextMetrics(FontGDI, Size, potm);
+ DefChar = potm->otmTextMetrics.tmDefaultChar; // May need this.
+ ExFreePool(potm);
+ }
+
+ IntLockFreeType;
+ face = FontGDI->face;
+
+ for (i = 0; i < cwc; i++)
+ {
+ Buffer[i] = FT_Get_Char_Index(face, pwc[i]);
+ if (Buffer[i] == 0)
+ {
+ if (DefChar == 0xffff && FT_IS_SFNT(face))
+ {
+ TT_OS2 *pOS2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+ DefChar = (pOS2->usDefaultChar ? FT_Get_Char_Index(face, pOS2->usDefaultChar) : 0);
+ }
+ Buffer[i] = DefChar;
+ }
+ }
+
+ IntUnLockFreeType;
+
+ RtlCopyMemory( pgi, Buffer, cwc*sizeof(WORD));
+
+ErrorRet:
+ if (Buffer) ExFreePoolWithTag(Buffer, TAG_GDITEXT);
+ return cwc;
+}
+
/*
* @implemented
IN DWORD iMode)
{
PDC dc;
- PDC_ATTR Dc_Attr;
+ PDC_ATTR pdcattr;
PTEXTOBJ TextObj;
PFONTGDI FontGDI;
HFONT hFont = 0;
SetLastWin32Error(ERROR_INVALID_HANDLE);
return GDI_ERROR;
}
- Dc_Attr = dc->pDc_Attr;
- if (!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
- hFont = Dc_Attr->hlfntNew;
+ pdcattr = dc->pdcattr;
+ hFont = pdcattr->hlfntNew;
TextObj = RealizeFontInit(hFont);
DC_UnlockDc(dc);
if (!TextObj)
IntLockFreeType;
face = FontGDI->face;
+ if (DefChar == 0xffff && FT_IS_SFNT(face))
+ {
+ TT_OS2 *pOS2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
+ DefChar = (pOS2->usDefaultChar ? FT_Get_Char_Index(face, pOS2->usDefaultChar) : 0);
+ }
+
for (i = 0; i < cwc; i++)
{
- Buffer[i] = FT_Get_Char_Index(face, UnSafepwc[i]);
+ Buffer[i] = FT_Get_Char_Index(face, UnSafepwc[i]); // FIXME: unsafe!
if (Buffer[i] == 0)
{
- if (DefChar == 0xffff && FT_IS_SFNT(face))
- {
- TT_OS2 *pOS2 = FT_Get_Sfnt_Table(face, ft_sfnt_os2);
- DefChar = (pOS2->usDefaultChar ? FT_Get_Char_Index(face, pOS2->usDefaultChar) : 0);
- }
Buffer[i] = DefChar;
}
}