[ros-diffs] [jimtabor] 22115: Implement NtGdiGetCharABCWidths. Not
sure if the math is
right. Tested with Lazarus IDE. It is completely based on Filip Navara work
on NtGdiGetCharWidth32.
jimtabor at svn.reactos.org
jimtabor at svn.reactos.org
Tue May 30 08:50:04 CEST 2006
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/objects/text.c?rev=22115&r1=22114&r2=22115&view=diff
==============================================================================
--- 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
More information about the Ros-diffs
mailing list