[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