static BOOL RenderingEnabled = TRUE;
#define MAX_FONT_CACHE 256
-UINT Hits;
-UINT Misses;
typedef struct _FONT_CACHE_ENTRY
{
if (Characteristics & FR_PRIVATE)
{
- PW32PROCESS Win32Process = PsGetCurrentProcessWin32Process();
+ PPROCESSINFO Win32Process = PsGetCurrentProcessWin32Process();
IntLockProcessPrivateFonts(Win32Process);
InsertTailList(&Win32Process->PrivateFontListHead, &Entry->ListEntry);
IntUnLockProcessPrivateFonts(Win32Process);
return;
}
- if (0 == pOS2->usWinAscent + pOS2->usWinDescent)
+ if (pOS2->usWinAscent + pOS2->usWinDescent == 0)
{
Ascent = pHori->Ascender;
Descent = -pHori->Descender;
TM->tmAscent = (Face->size->metrics.ascender + 32) >> 6; /* units above baseline */
TM->tmDescent = (32 - Face->size->metrics.descender) >> 6; /* units below baseline */
#endif
-
TM->tmInternalLeading = (FT_MulFix(Ascent + Descent - Face->units_per_EM, YScale) + 32) >> 6;
- TM->tmHeight = TM->tmAscent + TM->tmDescent; // we need add 1 height more after scale it right
+
+ TM->tmHeight = TM->tmAscent + TM->tmDescent;
/* MSDN says:
* el = MAX(0, LineGap - ((WinAscent + WinDescent) - (Ascender - Descender)))
YScale) + 32) >> 6);
TM->tmAveCharWidth = (FT_MulFix(pOS2->xAvgCharWidth, XScale) + 32) >> 6;
- if (0 == TM->tmAveCharWidth)
+ if (TM->tmAveCharWidth == 0)
{
TM->tmAveCharWidth = 1;
}
TM->tmWeight = pOS2->usWeightClass;
TM->tmOverhang = 0;
- TM->tmDigitizedAspectX = 300;
- TM->tmDigitizedAspectY = 300;
+ TM->tmDigitizedAspectX = 96;
+ TM->tmDigitizedAspectY = 96;
TM->tmFirstChar = pOS2->usFirstCharIndex;
+ TM->tmDefaultChar = pOS2->usDefaultChar ? pOS2->usDefaultChar : 0xffff;
TM->tmLastChar = pOS2->usLastCharIndex;
- TM->tmDefaultChar = pOS2->usDefaultChar;
TM->tmBreakChar = L'\0' != pOS2->usBreakChar ? pOS2->usBreakChar : ' ';
TM->tmItalic = (Face->style_flags & FT_STYLE_FLAG_ITALIC) ? 255 : 0;
TM->tmUnderlined = FontGDI->Underline;
TM->tmPitchAndFamily |= FF_SCRIPT;
break;
case PAN_FAMILY_DECORATIVE:
- case PAN_FAMILY_PICTORIAL:
TM->tmPitchAndFamily |= FF_DECORATIVE;
break;
+
+ case PAN_ANY:
+ case PAN_NO_FIT:
case PAN_FAMILY_TEXT_DISPLAY:
- if (0 == TM->tmPitchAndFamily) /* fixed */
+ case PAN_FAMILY_PICTORIAL: /* symbol fonts get treated as if they were text */
+ /* which is clearly not what the panose spec says. */
+ if (TM->tmPitchAndFamily == 0) /* fixed */
{
TM->tmPitchAndFamily = FF_MODERN;
}
{
switch (pOS2->panose[PAN_SERIFSTYLE_INDEX])
{
+ case PAN_ANY:
+ case PAN_NO_FIT:
+ default:
+ TM->tmPitchAndFamily |= FF_DONTCARE;
+ break;
+
+ case PAN_SERIF_COVE:
+ case PAN_SERIF_OBTUSE_COVE:
+ case PAN_SERIF_SQUARE_COVE:
+ case PAN_SERIF_OBTUSE_SQUARE_COVE:
+ case PAN_SERIF_SQUARE:
+ case PAN_SERIF_THIN:
+ case PAN_SERIF_BONE:
+ case PAN_SERIF_EXAGGERATED:
+ case PAN_SERIF_TRIANGLE:
+ TM->tmPitchAndFamily |= FF_ROMAN;
+ break;
+
case PAN_SERIF_NORMAL_SANS:
case PAN_SERIF_OBTUSE_SANS:
case PAN_SERIF_PERP_SANS:
+ case PAN_SERIF_FLARED:
+ case PAN_SERIF_ROUNDED:
TM->tmPitchAndFamily |= FF_SWISS;
break;
- default:
- TM->tmPitchAndFamily |= FF_ROMAN;
- break;
}
}
break;
Otm->otmrcFontBox.right = (FT_MulFix(FontGDI->face->bbox.xMax, XScale) + 32) >> 6;
Otm->otmrcFontBox.top = (FT_MulFix(FontGDI->face->bbox.yMax, YScale) + 32) >> 6;
Otm->otmrcFontBox.bottom = (FT_MulFix(FontGDI->face->bbox.yMin, YScale) + 32) >> 6;
- Otm->otmMacAscent = 0; /* where do these come from ? */
- Otm->otmMacDescent = 0;
- Otm->otmMacLineGap = 0;
+ Otm->otmMacAscent = FontGDI->TextMetric.tmAscent;
+ Otm->otmMacDescent = -FontGDI->TextMetric.tmDescent;
+ Otm->otmMacLineGap = Otm->otmLineGap;
Otm->otmusMinimumPPEM = 0; /* TT Header */
Otm->otmptSubscriptSize.x = (FT_MulFix(pOS2->ySubscriptXSize, XScale) + 32) >> 6;
Otm->otmptSubscriptSize.y = (FT_MulFix(pOS2->ySubscriptYSize, YScale) + 32) >> 6;
Otm->otmptSuperscriptOffset.y = (FT_MulFix(pOS2->ySuperscriptYOffset, YScale) + 32) >> 6;
Otm->otmsStrikeoutSize = (FT_MulFix(pOS2->yStrikeoutSize, YScale) + 32) >> 6;
Otm->otmsStrikeoutPosition = (FT_MulFix(pOS2->yStrikeoutPosition, YScale) + 32) >> 6;
- if (NULL == pPost)
+ if (!pPost)
{
Otm->otmsUnderscoreSize = 0;
Otm->otmsUnderscorePosition = 0;
static PFONTGDI FASTCALL
FindFaceNameInLists(PUNICODE_STRING FaceName)
{
- PW32PROCESS Win32Process;
+ PPROCESSINFO Win32Process;
PFONTGDI Font;
/* Search the process local list */
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;
}
INT error;
PFONT_CACHE_ENTRY NewEntry;
-// DbgPrint("CacheSet.\n");
-
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;
}
FontCacheNumEntries--;
}
-// DbgPrint("Returning the glyphcopy: %x\n", GlyphCopy);
-
return GlyphCopy;
}
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)
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)
char_previous = char_code = FT_Get_First_Char(face, &glyph_index);
- IntUnLockFreeType;
+ IntLockFreeType;
while (glyph_index)
{
LOGFONTW LogFont;
PFONTFAMILYINFO Info;
DWORD Count;
- PW32PROCESS Win32Process;
+ PPROCESSINFO Win32Process;
/* Make a safe copy */
Status = MmCopyFromCaller(&LogFont, UnsafeLogFont, sizeof(LOGFONTW));
BOOL
APIENTRY
-NtGdiExtTextOutW(
+GreExtTextOutW(
IN HDC hDC,
IN INT XStart,
IN INT YStart,
IN UINT fuOptions,
- IN OPTIONAL LPRECT lprc,
- IN LPWSTR UnsafeString,
+ IN OPTIONAL PRECTL lprc,
+ IN LPWSTR String,
IN INT Count,
- IN OPTIONAL LPINT UnsafeDx,
+ IN OPTIONAL LPINT Dx,
IN DWORD dwCodePage)
{
/*
*/
DC *dc;
- PDC_ATTR Dc_Attr;
+ PDC_ATTR pdcattr;
SURFOBJ *SurfObj;
- BITMAPOBJ *BitmapObj = NULL;
+ SURFACE *psurf = NULL;
int error, glyph_index, n, i;
FT_Face face;
FT_GlyphSlot glyph;
LONGLONG TextLeft, RealXStart;
ULONG TextTop, previous, BackgroundLeft;
FT_Bool use_kerning;
- RECTL DestRect, MaskRect, SpecifiedDestRect;
+ RECTL DestRect, MaskRect;
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;
- NTSTATUS Status;
- INT *Dx = NULL;
POINT Start;
BOOL DoBreak = FALSE;
- LPCWSTR String, SafeString = NULL;
HPALETTE hDestPalette;
- PVOID TmpBuffer = NULL;
- ULONG TmpBufSize, StringSize, DxSize = 0;
+ PPALETTE ppalDst;
+ USHORT DxShift;
// TODO: Write test-cases to exactly match real Windows in different
// bad parameters (e.g. does Windows check the DC or the RECT first?).
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;
- /* Check if String is valid */
- if ((Count > 0xFFFF) || (Count > 0 && UnsafeString == NULL))
- {
- SetLastWin32Error(ERROR_INVALID_PARAMETER);
- goto fail;
- }
+ if (pdcattr->ulDirty_ & DIRTY_TEXT)
+ DC_vUpdateTextBrush(dc);
- Status = STATUS_SUCCESS;
- if (Count > 0)
+ if ((fuOptions & ETO_OPAQUE) || pdcattr->jBkMode == OPAQUE)
{
- TmpBufSize = StringSize = Count * sizeof(WCHAR);
- if (UnsafeDx)
- {
- /* If ETO_PDY is specified, we have pairs of INTs */
- DxSize = Count * sizeof(INT) * (fuOptions & ETO_PDY ? 2 : 1);
- TmpBufSize += DxSize;
- }
-
- /* Allocate a temp buffer for the string and the Dx values */
- TmpBuffer = ExAllocatePoolWithTag(PagedPool, TmpBufSize, TAG_GDITEXT);
- SafeString = TmpBuffer;
- if (!TmpBuffer)
- {
- SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
- goto fail;
- }
-
- /* Probe and copy user mode data to the temp buffer */
- _SEH2_TRY
- {
- if (UnsafeString)
- {
- ProbeForRead(UnsafeString, StringSize, 1);
- memcpy((PVOID)SafeString, UnsafeString, StringSize);
- }
-
- if (UnsafeDx)
- {
- ProbeForRead(UnsafeDx, DxSize, 1);
- Dx = (INT*)((ULONG_PTR)TmpBuffer + StringSize);
- memcpy(Dx, UnsafeString, DxSize);
- }
-
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END
- if (!NT_SUCCESS(Status))
- {
- goto fail;
- }
+ if (pdcattr->ulDirty_ & DIRTY_BACKGROUND)
+ DC_vUpdateBackgroundBrush(dc);
}
- String = SafeString;
- if (lprc)
+ /* Check if String is valid */
+ if ((Count > 0xFFFF) || (Count > 0 && String == NULL))
{
- _SEH2_TRY
- {
- ProbeForRead(lprc, sizeof(RECT), 1);
- memcpy(&SpecifiedDestRect, lprc, sizeof(RECT));
- }
- _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
- {
- Status = _SEH2_GetExceptionCode();
- }
- _SEH2_END
- if (!NT_SUCCESS(Status))
- {
- goto fail;
- }
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ goto fail;
}
- if (PATH_IsPathOpen(dc->DcLevel))
+ DxShift = fuOptions & ETO_PDY ? 1 : 0;
+
+ if (PATH_IsPathOpen(dc->dclevel))
{
if (!PATH_ExtTextOut( dc,
XStart,
YStart,
fuOptions,
- (const RECT *)&SpecifiedDestRect,
- SafeString,
+ (const RECTL *)lprc,
+ String,
Count,
(const INT *)Dx)) goto fail;
goto good;
if (lprc && (fuOptions & (ETO_OPAQUE | ETO_CLIPPED)))
{
- IntLPtoDP(dc, (POINT *) &SpecifiedDestRect, 2);
+ IntLPtoDP(dc, (POINT *)lprc, 2);
}
- BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
- if ( !BitmapObj )
+ psurf = dc->dclevel.pSurface;
+ if (!psurf)
{
goto fail;
}
- SurfObj = &BitmapObj->SurfObj;
- ASSERT(SurfObj);
+ SurfObj = &psurf->SurfObj;
Start.x = XStart;
Start.y = YStart;
RealXStart = (Start.x + dc->ptlDCOrig.x) << 6;
YStart = Start.y + dc->ptlDCOrig.y;
- /* Create the brushes */
- hDestPalette = BitmapObj->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 = SpecifiedDestRect.left + dc->ptlDCOrig.x;
- DestRect.top = SpecifiedDestRect.top + dc->ptlDCOrig.y;
- DestRect.right = SpecifiedDestRect.right + dc->ptlDCOrig.x;
- DestRect.bottom = SpecifiedDestRect.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;
+
IntEngBitBlt(
- &BitmapObj->SurfObj,
+ &psurf->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;
}
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;
if (NULL != Dx)
{
Start = Count < 2 ? 0 : Count - 2;
- TextWidth = Count < 2 ? 0 : (Dx[Count - 2] << 6);
+ TextWidth = Count < 2 ? 0 : (Dx[(Count-2)<<DxShift] << 6);
}
else
{
previous = 0;
- if (Dc_Attr->lTextAlign & TA_RIGHT)
+ if (pdcattr->lTextAlign & TA_RIGHT)
{
RealXStart -= TextWidth;
}
TextTop = YStart;
BackgroundLeft = (RealXStart + 32) >> 6;
+ /* Create the xlateobj */
+ hDestPalette = psurf->hDIBPalette;
+ if (!hDestPalette) hDestPalette = pPrimarySurface->devinfo.hpalDefault;
+ ppalDst = PALETTE_LockPalette(hDestPalette);
+ EXLATEOBJ_vInitialize(&exloRGB2Dst, &gpalRGB, ppalDst, 0, 0, 0);
+ EXLATEOBJ_vInitialize(&exloDst2RGB, ppalDst, &gpalRGB, 0, 0, 0);
+ PALETTE_UnlockPalette(ppalDst);
+
+
/*
* The main rendering loop.
*/
{
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);
+ DPRINT("TextLeft: %d\n", TextLeft);
+ DPRINT("TextTop: %d\n", TextTop);
if (realglyph->format == ft_glyph_format_outline)
{
- DbgPrint("Should already be done\n");
+ DPRINT1("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;
+ goto fail2;
}
}
realglyph2 = (FT_BitmapGlyph)realglyph;
-// DPRINT1("Pitch: %d\n", pitch);
-// DPRINT1("Advance: %d\n", realglyph->advance.x);
+ DPRINT("Advance: %d\n", realglyph->advance.x);
if (fuOptions & ETO_OPAQUE)
{
DestRect.top = TextTop + yoff - ((face->size->metrics.ascender + 32) >> 6);
DestRect.bottom = TextTop + yoff + ((32 - face->size->metrics.descender) >> 6);
IntEngBitBlt(
- &BitmapObj->SurfObj,
+ &psurf->SurfObj,
NULL,
NULL,
- dc->CombinedClip,
+ dc->rosdc.CombinedClip,
NULL,
&DestRect,
&SourcePoint,
&SourcePoint,
- &BrushBgInst.BrushObject,
+ &dc->eboBackground.BrushObject,
&BrushOrigin,
ROP3_TO_ROP4(PATCOPY));
BackgroundLeft = DestRect.right;
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;
}
/*
if (lprc &&
(fuOptions & ETO_CLIPPED) &&
- DestRect.right >= SpecifiedDestRect.right + dc->ptlDCOrig.x)
+ DestRect.right >= lprc->right + dc->ptlDCOrig.x)
{
// We do the check '>=' instead of '>' to possibly save an iteration
// through this loop, since it's breaking after the drawing is done,
// and x is always incremented.
- DestRect.right = SpecifiedDestRect.right + dc->ptlDCOrig.x;
+ DestRect.right = lprc->right + dc->ptlDCOrig.x;
DoBreak = TRUE;
}
IntEngMaskBlt(
SurfObj,
SourceGlyphSurf,
- dc->CombinedClip,
- XlateObj,
- XlateObj2,
+ dc->rosdc.CombinedClip,
+ &exloRGB2Dst.xlo,
+ &exloDst2RGB.xlo,
&DestRect,
- &SourcePoint,
(PPOINTL)&MaskRect,
- &BrushFgInst.BrushObject,
+ &dc->eboText.BrushObject,
&BrushOrigin);
EngUnlockSurface(SourceGlyphSurf);
if (NULL == Dx)
{
TextLeft += realglyph->advance.x >> 10;
-// DbgPrint("new TextLeft: %d\n", TextLeft);
+ DPRINT("new TextLeft: %d\n", TextLeft);
}
else
{
- if (fuOptions & ETO_PDY)
- {
- TextLeft += Dx[i*2] << 6;
- }
- else
- {
- TextLeft += Dx[i] << 6;
- }
-// DbgPrint("new TextLeft2: %d\n", TextLeft);
+ TextLeft += Dx[i<<DxShift] << 6;
+ DPRINT("new TextLeft2: %d\n", TextLeft);
+ }
+
+ if (DxShift)
+ {
+ TextTop -= Dx[2 * i + 1] << 6;
}
+
previous = glyph_index;
String++;
IntUnLockFreeType;
- EngDeleteXlate(XlateObj);
- EngDeleteXlate(XlateObj2);
- BITMAPOBJ_UnlockBitmap(BitmapObj);
+ 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:
- if (NULL != SafeString)
- {
- ExFreePoolWithTag((void*)SafeString, TAG_GDITEXT);
- }
- if (NULL != Dx)
- {
- ExFreePoolWithTag(Dx, TAG_GDITEXT);
- }
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 (BitmapObj != NULL)
- BITMAPOBJ_UnlockBitmap(BitmapObj);
- if (hBrushBg != NULL)
+ DC_UnlockDc(dc);
+
+ return FALSE;
+}
+
+#define STACK_TEXT_BUFFER_SIZE 100
+BOOL
+APIENTRY
+NtGdiExtTextOutW(
+ IN HDC hDC,
+ IN INT XStart,
+ IN INT YStart,
+ IN UINT fuOptions,
+ IN OPTIONAL LPRECT UnsafeRect,
+ IN LPWSTR UnsafeString,
+ IN INT Count,
+ IN OPTIONAL LPINT UnsafeDx,
+ IN DWORD dwCodePage)
+{
+ BOOL Result = FALSE;
+ NTSTATUS Status = STATUS_SUCCESS;
+ RECTL SafeRect;
+ BYTE LocalBuffer[STACK_TEXT_BUFFER_SIZE];
+ PVOID Buffer = LocalBuffer;
+ LPWSTR SafeString = NULL;
+ LPINT SafeDx = NULL;
+ ULONG BufSize, StringSize, DxSize = 0;
+
+ /* Check if String is valid */
+ if ((Count > 0xFFFF) || (Count > 0 && UnsafeString == NULL))
{
- BRUSHOBJ_UnlockBrush(BrushBg);
- NtGdiDeleteObject(hBrushBg);
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
}
- if (hBrushFg != NULL)
+
+ if (Count > 0)
{
- BRUSHOBJ_UnlockBrush(BrushFg);
- NtGdiDeleteObject(hBrushFg);
+ /* Calculate buffer size for string and Dx values */
+ BufSize = StringSize = Count * sizeof(WCHAR);
+ if (UnsafeDx)
+ {
+ /* If ETO_PDY is specified, we have pairs of INTs */
+ DxSize = (Count * sizeof(INT)) * (fuOptions & ETO_PDY ? 2 : 1);
+ BufSize += DxSize;
+ }
+
+ /* Check if our local buffer is large enough */
+ if (BufSize > STACK_TEXT_BUFFER_SIZE)
+ {
+ /* It's not, allocate a temp buffer */
+ Buffer = ExAllocatePoolWithTag(PagedPool, BufSize, TAG_GDITEXT);
+ if (!Buffer)
+ {
+ return FALSE;
+ }
+ }
+
+ /* Probe and copy user mode data to the buffer */
+ _SEH2_TRY
+ {
+ /* Put the Dx before the String to assure alignment of 4 */
+ SafeString = (LPWSTR)(((ULONG_PTR)Buffer) + DxSize);
+
+ /* Probe and copy the string */
+ ProbeForRead(UnsafeString, StringSize, 1);
+ memcpy((PVOID)SafeString, UnsafeString, StringSize);
+
+ /* If we have Dx values... */
+ if (UnsafeDx)
+ {
+ /* ... probe and copy them */
+ SafeDx = Buffer;
+ ProbeForRead(UnsafeDx, DxSize, 1);
+ memcpy(SafeDx, UnsafeDx, DxSize);
+ }
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+ if (!NT_SUCCESS(Status))
+ {
+ goto cleanup;
+ }
+ }
+
+ /* If we have a rect, copy it */
+ if (UnsafeRect)
+ {
+ _SEH2_TRY
+ {
+ ProbeForRead(UnsafeRect, sizeof(RECT), 1);
+ SafeRect = *UnsafeRect;
+ }
+ _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+ {
+ Status = _SEH2_GetExceptionCode();
+ }
+ _SEH2_END
+ if (!NT_SUCCESS(Status))
+ {
+ goto cleanup;
+ }
}
- if (TmpBuffer)
+
+ /* Finally call the internal routine */
+ Result = GreExtTextOutW(hDC,
+ XStart,
+ YStart,
+ fuOptions,
+ &SafeRect,
+ SafeString,
+ Count,
+ SafeDx,
+ dwCodePage);
+
+cleanup:
+ /* If we allocated a buffer, free it */
+ if (Buffer != LocalBuffer)
{
- ExFreePoolWithTag(TmpBuffer, TAG_GDITEXT);
+ ExFreePoolWithTag(Buffer, TAG_GDITEXT);
}
- DC_UnlockDc(dc);
- return FALSE;
+ return Result;
}
+
/*
* @implemented
*/
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);
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)