* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: text.c,v 1.99 2004/06/23 15:30:21 weiden Exp $ */
+/* $Id: text.c,v 1.110 2004/08/24 17:29:00 navaraf Exp $ */
#include <w32k.h>
#include <ft2build.h>
BOOL bRestartScan = TRUE;
NTSTATUS Status;
- RtlInitUnicodeString(&Directory, L"\\SystemRoot\\Media\\Fonts\\");
+ RtlInitUnicodeString(&Directory, L"\\SystemRoot\\media\\fonts\\");
/* FIXME: Add support for other font types */
RtlInitUnicodeString(&SearchPattern, L"*.ttf");
break;
}
- for (DirInfo = (PFILE_DIRECTORY_INFORMATION)DirInfoBuffer;
- DirInfo->NextEntryOffset != 0;
- DirInfo = (PFILE_DIRECTORY_INFORMATION)((ULONG_PTR)DirInfo + DirInfo->NextEntryOffset))
+ DirInfo = (PFILE_DIRECTORY_INFORMATION)DirInfoBuffer;
+ while (1)
{
TempString.Buffer = DirInfo->FileName;
TempString.Length =
RtlCopyUnicodeString(&FileName, &Directory);
RtlAppendUnicodeStringToString(&FileName, &TempString);
IntGdiAddFontResource(&FileName, 0);
+ if (DirInfo->NextEntryOffset == 0)
+ break;
+ DirInfo = (PFILE_DIRECTORY_INFORMATION)((ULONG_PTR)DirInfo + DirInfo->NextEntryOffset);
}
bRestartScan = FALSE;
/* FIXME: Complete text metrics */
FontGDI->TextMetric.tmAscent = (Face->size->metrics.ascender + 32) >> 6; /* units above baseline */
FontGDI->TextMetric.tmDescent = (32 - Face->size->metrics.descender) >> 6; /* units below baseline */
- FontGDI->TextMetric.tmHeight = FontGDI->TextMetric.tmAscent + FontGDI->TextMetric.tmDescent;
+ FontGDI->TextMetric.tmHeight = (Face->size->metrics.ascender -
+ Face->size->metrics.descender) >> 6;
- DPRINT("Font loaded: %s (%s)\n", face->family_name, face->style_name);
- DPRINT("Num glyphs: %u\n", face->num_glyphs);
+ DPRINT("Font loaded: %s (%s)\n", Face->family_name, Face->style_name);
+ DPRINT("Num glyphs: %u\n", Face->num_glyphs);
/* Add this font resource to the font table */
BOOL FASTCALL
IntIsFontRenderingEnabled(VOID)
{
- BOOL Ret;
- HDC hDC;
- PDC dc;
- SURFOBJ *SurfObj;
- Ret = RenderingEnabled;
- hDC = IntGetScreenDC();
- if(hDC)
- {
- dc = DC_LockDc(hDC);
- SurfObj = (SURFOBJ*)AccessUserObject((ULONG) dc->Surface);
- if(SurfObj)
- Ret = (SurfObj->iBitmapFormat >= BMF_8BPP);
- DC_UnlockDc(hDC);
- }
- return Ret;
+ BOOL Ret = RenderingEnabled;
+ HDC hDC;
+
+ hDC = IntGetScreenDC();
+ if (hDC)
+ Ret = (NtGdiGetDeviceCaps(hDC, BITSPIXEL) > 8) && RenderingEnabled;
+
+ return Ret;
}
VOID FASTCALL
LPCWSTR CurrentPath)
{
UNIMPLEMENTED;
+ return FALSE;
}
/*************************************************************************
}
pPost = FT_Get_Sfnt_Table(FontGDI->face, ft_sfnt_post); /* we can live with this failing */
- IntUnLockFreeType;
Otm->otmSize = Needed;
Otm->otmsUnderscorePosition = (FT_MulFix(pPost->underlinePosition, YScale) + 32) >> 6;
}
+ IntUnLockFreeType;
+
/* otmp* members should clearly have type ptrdiff_t, but M$ knows best */
Cp = (char*) Otm + sizeof(OUTLINETEXTMETRICW);
Otm->otmpFamilyName = (LPSTR)(Cp - (char*) Otm);
LPARAM lParam)
{
UNIMPLEMENTED;
+ return 0;
}
BOOL STDCALL
DC *dc;
SURFOBJ *SurfObj;
+ BITMAPOBJ *BitmapObj;
int error, glyph_index, n, i;
FT_Face face;
FT_GlyphSlot glyph;
- ULONG TextLeft, TextTop, pitch, previous, BackgroundLeft;
+ LONGLONG TextLeft, RealXStart;
+ ULONG TextTop, pitch, previous, BackgroundLeft;
FT_Bool use_kerning;
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;
}
}
- SurfObj = (SURFOBJ*)AccessUserObject((ULONG) dc->Surface);
+ BitmapObj = BITMAPOBJ_LockBitmap(dc->w.hBitmap);
+ ASSERT(BitmapObj);
+ SurfObj = &BitmapObj->SurfObj;
Start.x = XStart; Start.y = YStart;
IntLPtoDP(dc, &Start, 1);
- XStart = Start.x + dc->w.DCOrgX;
+ RealXStart = (Start.x + dc->w.DCOrgX) << 6;
YStart = Start.y + dc->w.DCOrgY;
- TextObj = TEXTOBJ_LockText(dc->w.hFont);
-
- if (!NT_SUCCESS(GetFontObjectsFromTextObj(TextObj, NULL, &FontObj, &FontGDI)))
- {
- goto fail;
- }
-
- face = FontGDI->face;
- if (face->charmap == NULL)
- {
- DPRINT("WARNING: No charmap selected!\n");
- DPRINT("This font face has %d charmaps\n", face->num_charmaps);
-
- for (n = 0; n < face->num_charmaps; n++)
- {
- charmap = face->charmaps[n];
- DPRINT("found charmap encoding: %u\n", charmap->encoding);
- if (charmap->encoding != 0)
- {
- found = charmap;
- break;
- }
- }
- if (!found)
- DPRINT1("WARNING: Could not find desired charmap!\n");
- IntLockFreeType;
- error = FT_Set_Charmap(face, found);
- IntUnLockFreeType;
- if (error)
- DPRINT1("WARNING: Could not set the charmap!\n");
- }
-
- Render = IntIsFontRenderingEnabled();
- if (Render)
- RenderMode = IntGetFontRenderMode(&TextObj->logfont);
- else
- RenderMode = FT_RENDER_MODE_MONO;
-
- IntLockFreeType;
- error = FT_Set_Pixel_Sizes(
- face,
- /* FIXME should set character height if neg */
- (TextObj->logfont.lfHeight < 0 ?
- - TextObj->logfont.lfHeight :
- TextObj->logfont.lfHeight),
- TextObj->logfont.lfWidth);
- IntUnLockFreeType;
- if (error)
- {
- DPRINT1("Error in setting pixel sizes: %u\n", error);
- goto fail;
- }
-
/* Create the brushes */
PalDestGDI = PALETTE_LockPalette(dc->w.hPalette);
if ( !PalDestGDI )
XlateObj = (XLATEOBJ*)IntEngCreateXlate(Mode, PAL_RGB, dc->w.hPalette, NULL);
hBrushFg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.textColor));
BrushFg = BRUSHOBJ_LockBrush(hBrushFg);
+ IntGdiInitBrushInstance(&BrushFgInst, BrushFg, NULL);
if ((fuOptions & ETO_OPAQUE) || dc->w.backgroundMode == OPAQUE)
{
hBrushBg = NtGdiCreateSolidBrush(XLATEOBJ_iXlate(XlateObj, dc->w.backgroundColor));
if (hBrushBg)
{
BrushBg = BRUSHOBJ_LockBrush(hBrushBg);
+ IntGdiInitBrushInstance(&BrushBgInst, BrushBg, NULL);
}
else
{
DestRect.right += dc->w.DCOrgX;
DestRect.bottom += dc->w.DCOrgY;
IntEngBitBlt(
- SurfObj,
+ BitmapObj,
NULL,
NULL,
dc->CombinedClip,
&DestRect,
&SourcePoint,
&SourcePoint,
- &BrushBg->BrushObject,
+ &BrushBgInst.BrushObject,
&BrushOrigin,
PATCOPY);
fuOptions &= ~ETO_OPAQUE;
}
}
+ TextObj = TEXTOBJ_LockText(dc->w.hFont);
+
+ if (!NT_SUCCESS(GetFontObjectsFromTextObj(TextObj, NULL, &FontObj, &FontGDI)))
+ {
+ goto fail;
+ }
+
+ face = FontGDI->face;
+ if (face->charmap == NULL)
+ {
+ DPRINT("WARNING: No charmap selected!\n");
+ DPRINT("This font face has %d charmaps\n", face->num_charmaps);
+
+ for (n = 0; n < face->num_charmaps; n++)
+ {
+ charmap = face->charmaps[n];
+ DPRINT("found charmap encoding: %u\n", charmap->encoding);
+ if (charmap->encoding != 0)
+ {
+ found = charmap;
+ break;
+ }
+ }
+ if (!found)
+ DPRINT1("WARNING: Could not find desired charmap!\n");
+ IntLockFreeType;
+ error = FT_Set_Charmap(face, found);
+ IntUnLockFreeType;
+ if (error)
+ DPRINT1("WARNING: Could not set the charmap!\n");
+ }
+
+ Render = IntIsFontRenderingEnabled();
+ if (Render)
+ RenderMode = IntGetFontRenderMode(&TextObj->logfont);
+ else
+ RenderMode = FT_RENDER_MODE_MONO;
+
+ IntLockFreeType;
+ error = FT_Set_Pixel_Sizes(
+ face,
+ /* FIXME should set character height if neg */
+ (TextObj->logfont.lfHeight < 0 ?
+ - TextObj->logfont.lfHeight :
+ TextObj->logfont.lfHeight),
+ TextObj->logfont.lfWidth);
+ IntUnLockFreeType;
+ if (error)
+ {
+ DPRINT1("Error in setting pixel sizes: %u\n", error);
+ goto fail;
+ }
+
/*
* Process the vertical alignment and determine the yoff.
*/
if (dc->w.textAlign & (TA_RIGHT | TA_CENTER))
{
- UINT TextWidth = 0;
+ ULONGLONG TextWidth = 0;
LPCWSTR TempText = String;
int Start;
if (NULL != Dx)
{
Start = Count < 2 ? 0 : Count - 2;
- TextWidth = Count < 2 ? 0 : Dx[Count - 2];
+ TextWidth = Count < 2 ? 0 : (Dx[Count - 2] << 6);
}
else
{
IntLockFreeType;
FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
IntUnLockFreeType;
- TextWidth += delta.x >> 6;
+ TextWidth += delta.x;
}
- TextWidth += glyph->advance.x >> 6;
+ TextWidth += glyph->advance.x;
previous = glyph_index;
TempText++;
if (dc->w.textAlign & TA_RIGHT)
{
- XStart -= TextWidth;
+ RealXStart -= TextWidth;
}
else
{
- XStart -= TextWidth / 2;
+ RealXStart -= TextWidth / 2;
}
}
- TextLeft = XStart;
+ TextLeft = RealXStart;
TextTop = YStart;
- BackgroundLeft = XStart;
+ BackgroundLeft = (RealXStart + 32) >> 6;
/*
* The main rendering loop.
IntLockFreeType;
FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
IntUnLockFreeType;
- TextLeft += delta.x >> 6;
+ TextLeft += delta.x;
}
if (glyph->format == ft_glyph_format_outline)
if (fuOptions & ETO_OPAQUE)
{
DestRect.left = BackgroundLeft;
- DestRect.right = TextLeft + ((glyph->advance.x + 32) >> 6);
+ DestRect.right = (TextLeft + glyph->advance.x + 32) >> 6;
DestRect.top = TextTop + yoff - ((face->size->metrics.ascender + 32) >> 6);
DestRect.bottom = TextTop + yoff + ((32 - face->size->metrics.descender) >> 6);
IntEngBitBlt(
- SurfObj,
+ BitmapObj,
NULL,
NULL,
dc->CombinedClip,
&DestRect,
&SourcePoint,
&SourcePoint,
- &BrushBg->BrushObject,
+ &BrushBgInst.BrushObject,
&BrushOrigin,
PATCOPY);
BackgroundLeft = DestRect.right;
}
- DestRect.left = TextLeft;
- DestRect.right = TextLeft + glyph->bitmap.width;
+ DestRect.left = ((TextLeft + 32) >> 6) + glyph->bitmap_left;
+ DestRect.right = DestRect.left + glyph->bitmap.width;
DestRect.top = TextTop + yoff - glyph->bitmap_top;
DestRect.bottom = DestRect.top + glyph->bitmap.rows;
*/
HSourceGlyph = EngCreateBitmap(bitSize, pitch, (glyph->bitmap.pixel_mode == ft_pixel_mode_grays) ? BMF_8BPP : BMF_1BPP, BMF_TOPDOWN, glyph->bitmap.buffer);
- SourceGlyphSurf = (SURFOBJ*)AccessUserObject((ULONG) HSourceGlyph);
+ SourceGlyphSurf = EngLockSurface((HSURF)HSourceGlyph);
/*
* Use the font data as a mask to paint onto the DCs surface using a
&DestRect,
&SourcePoint,
(PPOINTL)&MaskRect,
- &BrushFg->BrushObject,
+ &BrushFgInst.BrushObject,
&BrushOrigin);
+ EngUnlockSurface(SourceGlyphSurf);
EngDeleteSurface((HSURF)HSourceGlyph);
if (NULL == Dx)
{
- TextLeft += (glyph->advance.x + 32) >> 6;
+ TextLeft += glyph->advance.x;
}
else
{
- TextLeft += Dx[i];
+ TextLeft += Dx[i] << 6;
}
previous = glyph_index;
EngDeleteXlate(XlateObj);
EngDeleteXlate(XlateObj2);
+ BITMAPOBJ_UnlockBitmap(dc->w.hBitmap);
TEXTOBJ_UnlockText(dc->w.hFont);
if (hBrushBg != NULL)
{
fail:
TEXTOBJ_UnlockText(dc->w.hFont);
+ BITMAPOBJ_UnlockBitmap(dc->w.hBitmap);
if (hBrushBg != NULL)
{
BRUSHOBJ_UnlockBrush(hBrushBg);
LPSIZE AspectRatio)
{
UNIMPLEMENTED;
+ return FALSE;
}
BOOL
LPABCFLOAT abcF)
{
UNIMPLEMENTED;
+ return FALSE;
}
DWORD
DWORD Flags)
{
UNIMPLEMENTED;
+ return 0;
}
BOOL
FT_Face face;
FT_CharMap charmap, found = NULL;
UINT i, glyph_index, BufferSize;
+ HFONT hFont = 0;
if (LastChar < FirstChar)
{
SetLastWin32Error(ERROR_INVALID_HANDLE);
return FALSE;
}
- TextObj = TEXTOBJ_LockText(dc->w.hFont);
+ hFont = dc->w.hFont;
+ TextObj = TEXTOBJ_LockText(hFont);
DC_UnlockDc(hDC);
- GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGDI);
+ if (TextObj == NULL)
+ {
+ ExFreePool(SafeBuffer);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ if (!NT_SUCCESS(GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGDI)))
+ {
+ ExFreePool(SafeBuffer);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ TEXTOBJ_UnlockText(hFont);
+ return FALSE;
+ }
face = FontGDI->face;
if (face->charmap == NULL)
{
glyph_index = FT_Get_Char_Index(face, i);
FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
- SafeBuffer[i - FirstChar] = face->glyph->advance.x >> 6;
+ SafeBuffer[i - FirstChar] = (face->glyph->advance.x + 32) >> 6;
}
IntUnLockFreeType;
- TEXTOBJ_UnlockText(dc->w.hFont);
+ TEXTOBJ_UnlockText(hFont);
MmCopyToCaller(Buffer, SafeBuffer, BufferSize);
ExFreePool(SafeBuffer);
return TRUE;
PFLOAT Buffer)
{
UNIMPLEMENTED;
+ return FALSE;
}
DWORD
NtGdiGetFontLanguageInfo(HDC hDC)
{
UNIMPLEMENTED;
+ return 0;
}
DWORD
CONST LPMAT2 mat2)
{
UNIMPLEMENTED;
-
-
+ return 0;
}
DWORD
LPKERNINGPAIR krnpair)
{
UNIMPLEMENTED;
+ return 0;
}
UINT
LPOUTLINETEXTMETRICW otm)
{
UNIMPLEMENTED;
+ return 0;
}
BOOL
UINT Size)
{
UNIMPLEMENTED;
+ return FALSE;
}
UINT
NtGdiGetTextCharset(HDC hDC)
{
UNIMPLEMENTED;
+ return 0;
}
UINT
DWORD Flags)
{
UNIMPLEMENTED;
+ return 0;
}
static BOOL
FT_Face face;
FT_GlyphSlot glyph;
INT error, n, glyph_index, i, previous;
- LONG TotalWidth = 0;
+ ULONGLONG TotalWidth = 0;
FT_CharMap charmap, found = NULL;
BOOL use_kerning;
- GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGDI);
+ if (!NT_SUCCESS(GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGDI)))
+ {
+ return FALSE;
+ }
+
face = FontGDI->face;
if (NULL != Fit)
{
IntLockFreeType;
FT_Get_Kerning(face, previous, glyph_index, 0, &delta);
IntUnLockFreeType;
- TotalWidth += delta.x >> 6;
+ TotalWidth += delta.x;
}
- TotalWidth += glyph->advance.x >> 6;
+ TotalWidth += glyph->advance.x;
- if (TotalWidth <= MaxExtent && NULL != Fit)
+ if (((TotalWidth + 32) >> 6) <= MaxExtent && NULL != Fit)
{
*Fit = i + 1;
}
if (NULL != Dx)
{
- Dx[i] = TotalWidth;
+ Dx[i] = (TotalWidth + 32) >> 6;
}
previous = glyph_index;
String++;
}
- Size->cx = TotalWidth;
+ Size->cx = (TotalWidth + 32) >> 6;
Size->cy = (TextObj->logfont.lfHeight < 0 ? - TextObj->logfont.lfHeight : TextObj->logfont.lfHeight);
Size->cy = EngMulDiv(Size->cy, NtGdiGetDeviceCaps(hDC, LOGPIXELSY), 72);
return TRUE;
}
-int
-STDCALL
-NtGdiGetTextFace(HDC hDC,
- int Count,
- LPWSTR FaceName)
+INT STDCALL
+NtGdiGetTextFace(HDC hDC, INT Count, LPWSTR FaceName)
{
- UNIMPLEMENTED;
+ PDC Dc;
+ PTEXTOBJ TextObj;
+ NTSTATUS Status;
+
+ Dc = DC_LockDc(hDC);
+ if (Dc == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ TextObj = TEXTOBJ_LockText(Dc->w.hFont);
+ DC_UnlockDc(hDC);
+
+ Count = min(Count, wcslen(TextObj->logfont.lfFaceName));
+ Status = MmCopyToCaller(FaceName, TextObj->logfont.lfFaceName, Count * sizeof(WCHAR));
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ return 0;
+ }
+
+ return Count;
}
BOOL
SafeTm.tmAscent = (Face->size->metrics.ascender + 32) >> 6; // units above baseline
SafeTm.tmDescent = (32 - Face->size->metrics.descender) >> 6; // units below baseline
SafeTm.tmHeight = SafeTm.tmAscent + SafeTm.tmDescent;
- SafeTm.tmMaxCharWidth = (Face->size->metrics.max_advance + 32) >> 6;
+ SafeTm.tmMaxCharWidth = (Face->size->metrics.max_advance + 32) >> 6;
+ if (FT_IS_SFNT(FontGDI->face))
+ {
+ SafeTm.tmPitchAndFamily |= TMPF_TRUETYPE;
+ }
Status = MmCopyToCaller(tm, &SafeTm, sizeof(TEXTMETRICW));
}
}
int Count)
{
UNIMPLEMENTED;
+ return FALSE;
}
BOOL
NtGdiRemoveFontResource(LPCWSTR FileName)
{
UNIMPLEMENTED;
+ return FALSE;
}
DWORD
DWORD Flag)
{
UNIMPLEMENTED;
+ return 0;
}
UINT
int BreakCount)
{
UNIMPLEMENTED;
+ return FALSE;
}
BOOL STDCALL
return NtGdiExtTextOut(hDC, XStart, YStart, 0, NULL, String, Count, NULL);
}
+DWORD STDCALL
+NtGdiGetFontData(
+ HDC hDC,
+ DWORD Table,
+ DWORD Offset,
+ LPVOID Buffer,
+ DWORD Size)
+{
+ PDC Dc;
+ HFONT hFont;
+ PTEXTOBJ TextObj;
+ PFONTGDI FontGdi;
+ DWORD Result = GDI_ERROR;
+ NTSTATUS Status;
+
+ Dc = DC_LockDc(hDC);
+ if (Dc == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return GDI_ERROR;
+ }
+ hFont = Dc->w.hFont;
+ TextObj = TEXTOBJ_LockText(hFont);
+ DC_UnlockDc(hDC);
+
+ if (TextObj == NULL)
+ {
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return GDI_ERROR;
+ }
+
+ Status = GetFontObjectsFromTextObj(TextObj, NULL, NULL, &FontGdi);
+ if (NT_SUCCESS(Status))
+ {
+ IntLockFreeType;
+
+ if (FT_IS_SFNT(FontGdi->face))
+ {
+ if (Table)
+ Table = Table >> 24 | Table << 24 | (Table >> 8 & 0xFF00) |
+ (Table << 8 & 0xFF0000);
+
+ if (Buffer == NULL)
+ Size = 0;
+
+ if (!FT_Load_Sfnt_Table(FontGdi->face, Table, Offset, Buffer, &Size))
+ Result = Size;
+ }
+
+ IntUnLockFreeType;
+ }
+
+ TEXTOBJ_UnlockText(hFont);
+
+ return Result;
+}
+
static UINT FASTCALL
GetFontScore(LOGFONTW *LogFont, PUNICODE_STRING FaceName, PFONTGDI FontGDI)
{
continue;
}
Score = GetFontScore(LogFont, FaceName, FontGDI);
- if (*MatchScore < Score)
+ if (*MatchScore == 0 || *MatchScore < Score)
{
*Font = CurrentEntry->hFont;
*MatchScore = Score;
RtlFreeUnicodeString(&FaceName);
TEXTOBJ_UnlockText(FontHandle);
- ASSERT(! NT_SUCCESS(Status) || NULL != TextObj->GDIFontHandle);
+
+ ASSERT((NT_SUCCESS(Status) ^ (NULL == TextObj->GDIFontHandle)) != 0);
return Status;
}