Author: jimtabor
Date: Tue May 30 10:50:03 2006
New Revision: 22115
URL:
http://svn.reactos.ru/svn/reactos?rev=22115&view=rev
Log:
Implement NtGdiGetCharABCWidths. Not sure if the math is right. Tested with Lazarus IDE.
It is completely based on Filip Navara work on NtGdiGetCharWidth32.
Modified:
trunk/reactos/subsystems/win32/win32k/objects/text.c
Modified: trunk/reactos/subsystems/win32/win32k/objects/text.c
URL:
http://svn.reactos.ru/svn/reactos/trunk/reactos/subsystems/win32/win32k/obj…
==============================================================================
--- trunk/reactos/subsystems/win32/win32k/objects/text.c (original)
+++ trunk/reactos/subsystems/win32/win32k/objects/text.c Tue May 30 10:50:03 2006
@@ -1973,8 +1973,118 @@
UINT LastChar,
LPABC abc)
{
- DPRINT1("NtGdiGetCharABCWidths Is unimplemented, keep going anyway\n");
- return 1;
+ LPABC SafeBuffer;
+ PDC dc;
+ PTEXTOBJ TextObj;
+ PFONTGDI FontGDI;
+ FT_Face face;
+ FT_CharMap charmap, found = NULL;
+ UINT i, glyph_index, BufferSize;
+ HFONT hFont = 0;
+ NTSTATUS Status;
+
+ if (LastChar < FirstChar)
+ {
+ SetLastWin32Error(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ BufferSize = (LastChar - FirstChar + 1) * sizeof(ABC);
+ SafeBuffer = ExAllocatePoolWithTag(PagedPool, BufferSize, TAG_GDITEXT);
+ if (SafeBuffer == NULL)
+ {
+ SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+
+ dc = DC_LockDc(hDC);
+ if (dc == NULL)
+ {
+ ExFreePool(SafeBuffer);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+ hFont = dc->w.hFont;
+ TextObj = TEXTOBJ_LockText(hFont);
+ DC_UnlockDc(dc);
+
+ if (TextObj == NULL)
+ {
+ ExFreePool(SafeBuffer);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ FontGDI = ObjToGDI(TextObj->Font, FONT);
+
+ face = FontGDI->face;
+ if (face->charmap == NULL)
+ {
+ for (i = 0; i < face->num_charmaps; i++)
+ {
+ charmap = face->charmaps[i];
+ if (charmap->encoding != 0)
+ {
+ found = charmap;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ DPRINT1("WARNING: Could not find desired charmap!\n");
+ ExFreePool(SafeBuffer);
+ SetLastWin32Error(ERROR_INVALID_HANDLE);
+ return FALSE;
+ }
+
+ IntLockFreeType;
+ FT_Set_Charmap(face, found);
+ IntUnLockFreeType;
+ }
+
+ IntLockFreeType;
+ FT_Set_Pixel_Sizes(face,
+ TextObj->logfont.lfWidth,
+ /* FIXME should set character height if neg */
+ (TextObj->logfont.lfHeight < 0 ? -
TextObj->logfont.lfHeight :
+ TextObj->logfont.lfHeight == 0 ? 11 :
TextObj->logfont.lfHeight));
+
+ for (i = FirstChar; i <= LastChar; i++)
+ {
+ int adv, lsb, bbx, left, right;
+
+ glyph_index = FT_Get_Char_Index(face, i);
+ FT_Load_Glyph(face, glyph_index, FT_LOAD_DEFAULT);
+
+ left = (INT)face->glyph->metrics.horiBearingX & -64;
+ right = (INT)((face->glyph->metrics.horiBearingX +
face->glyph->metrics.width) + 63) & -64;
+ adv = (face->glyph->advance.x + 32) >> 6;
+
+// int test = (INT)(face->glyph->metrics.horiAdvance + 63) >> 6;
+// DPRINT1("Advance Wine %d and Advance Ros %d\n",test, adv ); /* It's
the same!*/
+
+ lsb = left >> 6;
+ bbx = (right - left) >> 6;
+/*
+ DPRINT1("lsb %d and bbx %d\n", lsb, bbx );
+ */
+ SafeBuffer[i - FirstChar].abcA = lsb;
+ SafeBuffer[i - FirstChar].abcB = bbx;
+ SafeBuffer[i - FirstChar].abcC = adv - lsb - bbx;
+ }
+ IntUnLockFreeType;
+ TEXTOBJ_UnlockText(TextObj);
+ Status = MmCopyToCaller(abc, SafeBuffer, BufferSize);
+ if (! NT_SUCCESS(Status))
+ {
+ SetLastNtError(Status);
+ ExFreePool(SafeBuffer);
+ return FALSE;
+ }
+ ExFreePool(SafeBuffer);
+ DPRINT("NtGdiGetCharABCWidths Worked!\n");
+ return TRUE;
}
BOOL