Fix spurious warning/error reported by GCC 4.4.0.
[reactos.git] / reactos / subsystems / win32 / win32k / objects / font.c
index fd9c5f6..1f49571 100644 (file)
@@ -23,7 +23,6 @@ FontGetObject(PTEXTOBJ TFont, INT Count, PVOID Buffer)
 
   switch (Count)
   {
-
      case sizeof(ENUMLOGFONTEXDVW):
         RtlCopyMemory( (LPENUMLOGFONTEXDVW) Buffer,
                                             &TFont->logfont,
@@ -55,6 +54,58 @@ FontGetObject(PTEXTOBJ TFont, INT Count, PVOID Buffer)
   return Count;
 }
 
+DWORD
+FASTCALL
+IntGetFontLanguageInfo(PDC Dc)
+{
+  PDC_ATTR Dc_Attr;
+  FONTSIGNATURE fontsig;
+  static const DWORD GCP_DBCS_MASK=0x003F0000,
+               GCP_DIACRITIC_MASK=0x00000000,
+               FLI_GLYPHS_MASK=0x00000000,
+               GCP_GLYPHSHAPE_MASK=0x00000040,
+               GCP_KASHIDA_MASK=0x00000000,
+               GCP_LIGATE_MASK=0x00000000,
+               GCP_USEKERNING_MASK=0x00000000,
+               GCP_REORDER_MASK=0x00000060;
+
+  DWORD result=0;
+
+  ftGdiGetTextCharsetInfo( Dc, &fontsig, 0 );
+
+ /* We detect each flag we return using a bitmask on the Codepage Bitfields */
+  if( (fontsig.fsCsb[0]&GCP_DBCS_MASK)!=0 )
+               result|=GCP_DBCS;
+
+  if( (fontsig.fsCsb[0]&GCP_DIACRITIC_MASK)!=0 )
+               result|=GCP_DIACRITIC;
+
+  if( (fontsig.fsCsb[0]&FLI_GLYPHS_MASK)!=0 )
+               result|=FLI_GLYPHS;
+
+  if( (fontsig.fsCsb[0]&GCP_GLYPHSHAPE_MASK)!=0 )
+               result|=GCP_GLYPHSHAPE;
+
+  if( (fontsig.fsCsb[0]&GCP_KASHIDA_MASK)!=0 )
+               result|=GCP_KASHIDA;
+
+  if( (fontsig.fsCsb[0]&GCP_LIGATE_MASK)!=0 )
+               result|=GCP_LIGATE;
+
+  if( (fontsig.fsCsb[0]&GCP_USEKERNING_MASK)!=0 )
+               result|=GCP_USEKERNING;
+
+  Dc_Attr = Dc->pDc_Attr;
+  if(!Dc_Attr) Dc_Attr = &Dc->Dc_Attr;
+
+  /* this might need a test for a HEBREW- or ARABIC_CHARSET as well */
+  if ( Dc_Attr->lTextAlign & TA_RTLREADING )
+     if( (fontsig.fsCsb[0]&GCP_REORDER_MASK)!=0 )
+                    result|=GCP_REORDER;
+
+  return result;
+}
+
 PTEXTOBJ
 FASTCALL
 RealizeFontInit(HFONT hFont)
@@ -64,7 +115,7 @@ RealizeFontInit(HFONT hFont)
 
   pTextObj = TEXTOBJ_LockText(hFont);
 
-  if ( pTextObj && !pTextObj->fl & TEXTOBJECT_INIT)
+  if ( pTextObj && !(pTextObj->fl & TEXTOBJECT_INIT))
   {
      Status = TextIntRealizeFont(hFont, pTextObj);
      if (!NT_SUCCESS(Status))
@@ -114,19 +165,19 @@ NtGdiAddFontResourceW(
   Status = MmCopyFromCaller(SafeFileName.Buffer + 4, src, SafeFileName.MaximumLength - (4 * sizeof(WCHAR)));
   if(!NT_SUCCESS(Status))
   {
-    ExFreePool(SafeFileName.Buffer);
+    ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
     SetLastNtError(Status);
     return 0;
   }
 
   Ret = IntGdiAddFontResource(&SafeFileName, (DWORD)fl);
 
-  ExFreePool(SafeFileName.Buffer);
+  ExFreePoolWithTag(SafeFileName.Buffer, TAG_STRING);
   return Ret;
 }
 
 DWORD
-STDCALL
+APIENTRY
 NtGdiGetFontData(
    HDC hDC,
    DWORD Table,
@@ -144,15 +195,15 @@ NtGdiGetFontData(
 
   if (Buffer && Size)
   {
-     _SEH_TRY
+     _SEH2_TRY
      {
          ProbeForRead(Buffer, Size, 1);
      }
-     _SEH_HANDLE
+     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
      {
-         Status = _SEH_GetExceptionCode();
+         Status = _SEH2_GetExceptionCode();
      }
-     _SEH_END
+     _SEH2_END
   }
 
   if (!NT_SUCCESS(Status)) return Result;
@@ -223,8 +274,8 @@ NtGdiGetFontUnicodeRanges(
   }
   FontGdi = ObjToGDI(TextObj->Font, FONT);
 
-
   Size = ftGetFontUnicodeRanges( FontGdi, NULL);
+
   if (Size && pgs)
   {
      pgsSafe = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT);
@@ -239,16 +290,16 @@ NtGdiGetFontUnicodeRanges(
 
      if (Size)
      {     
-        _SEH_TRY
+        _SEH2_TRY
         {
-            ProbeForWrite(pgsSafe, Size, 1);
+            ProbeForWrite(pgs, Size, 1);
             RtlCopyMemory(pgs, pgsSafe, Size);
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-           Status = _SEH_GetExceptionCode();
+           Status = _SEH2_GetExceptionCode();
         }
-        _SEH_END
+        _SEH2_END
 
         if (!NT_SUCCESS(Status)) Size = 0;
      }
@@ -306,32 +357,32 @@ NtGdiGetGlyphOutline(
 
   if (pvBuf)
   {
-     _SEH_TRY
+     _SEH2_TRY
      {
          ProbeForWrite(UnsafeBuf, cjBuf, 1);
          RtlCopyMemory(UnsafeBuf, pvBuf, cjBuf);
      }
-     _SEH_HANDLE
+     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
      {
-         Status = _SEH_GetExceptionCode();
+         Status = _SEH2_GetExceptionCode();
      }
-     _SEH_END
+     _SEH2_END
 
      ExFreePoolWithTag(pvBuf, TAG_GDITEXT);
   }
 
   if (pgm)
   {
-     _SEH_TRY
+     _SEH2_TRY
      {
          ProbeForWrite(pgm, sizeof(GLYPHMETRICS), 1);
          RtlCopyMemory(pgm, &gm, sizeof(GLYPHMETRICS));
      }
-     _SEH_HANDLE
+     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
      {
-         Status = _SEH_GetExceptionCode();
+         Status = _SEH2_GetExceptionCode();
      }
-     _SEH_END
+     _SEH2_END
   }
 
   if (! NT_SUCCESS(Status))
@@ -346,13 +397,74 @@ Exit:
 }
 
 DWORD
-STDCALL
+APIENTRY
 NtGdiGetKerningPairs(HDC  hDC,
                      ULONG  NumPairs,
                      LPKERNINGPAIR  krnpair)
 {
-  UNIMPLEMENTED;
-  return 0;
+  PDC dc;
+  PDC_ATTR Dc_Attr;
+  PTEXTOBJ TextObj;
+  PFONTGDI FontGDI;
+  DWORD Count;
+  KERNINGPAIR *pKP;
+  NTSTATUS Status = STATUS_SUCCESS;
+
+  dc = DC_LockDc(hDC);
+  if (!dc)
+  {
+     SetLastWin32Error(ERROR_INVALID_HANDLE);
+     return 0;
+  }
+
+  Dc_Attr = dc->pDc_Attr;
+  if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
+  TextObj = RealizeFontInit(Dc_Attr->hlfntNew);
+  DC_UnlockDc(dc);
+
+  if (!TextObj)
+  {
+     SetLastWin32Error(ERROR_INVALID_HANDLE);
+     return 0;
+  }
+
+  FontGDI = ObjToGDI(TextObj->Font, FONT);
+  TEXTOBJ_UnlockText(TextObj);
+
+  Count = ftGdiGetKerningPairs(FontGDI,0,NULL);
+
+  if ( Count && krnpair )
+  {
+     if (Count > NumPairs)
+     {
+        SetLastWin32Error(ERROR_INSUFFICIENT_BUFFER);
+        return 0;
+     }
+     pKP = ExAllocatePoolWithTag(PagedPool, Count * sizeof(KERNINGPAIR), TAG_GDITEXT);
+     if (!pKP)
+     {
+        SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
+        return 0;
+     }
+     ftGdiGetKerningPairs(FontGDI,Count,pKP);
+     _SEH2_TRY
+     {
+        ProbeForWrite(krnpair, Count * sizeof(KERNINGPAIR), 1);
+        RtlCopyMemory(krnpair, pKP, Count * sizeof(KERNINGPAIR));
+     }
+     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+     {
+        Status = _SEH2_GetExceptionCode();
+     }
+     _SEH2_END
+     if (!NT_SUCCESS(Status))
+     {
+        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        Count = 0;
+     }     
+     ExFreePoolWithTag(pKP,TAG_GDITEXT);
+  }
+  return Count;
 }
 
 /*
@@ -360,7 +472,7 @@ NtGdiGetKerningPairs(HDC  hDC,
  472, this is NtGdiGetOutlineTextMetricsInternalW.
  */
 ULONG
-STDCALL
+APIENTRY
 NtGdiGetOutlineTextMetricsInternalW (HDC  hDC,
                                    ULONG  Data,
                       OUTLINETEXTMETRICW  *otm,
@@ -373,51 +485,60 @@ NtGdiGetOutlineTextMetricsInternalW (HDC  hDC,
   HFONT hFont = 0;
   ULONG Size;
   OUTLINETEXTMETRICW *potm;
-  NTSTATUS Status;
+  NTSTATUS Status = STATUS_SUCCESS;
 
   dc = DC_LockDc(hDC);
-  if (dc == NULL)
-    {
-      SetLastWin32Error(ERROR_INVALID_HANDLE);
-      return 0;
-    }
+  if (!dc)
+  {
+     SetLastWin32Error(ERROR_INVALID_HANDLE);
+     return 0;
+  }
   Dc_Attr = dc->pDc_Attr;
   if(!Dc_Attr) Dc_Attr = &dc->Dc_Attr;
   hFont = Dc_Attr->hlfntNew;
   TextObj = RealizeFontInit(hFont);
   DC_UnlockDc(dc);
-  if (TextObj == NULL)
-    {
-      SetLastWin32Error(ERROR_INVALID_HANDLE);
-      return 0;
-    }
+  if (!TextObj)
+  {
+     SetLastWin32Error(ERROR_INVALID_HANDLE);
+     return 0;
+  }
   FontGDI = ObjToGDI(TextObj->Font, FONT);
   TEXTOBJ_UnlockText(TextObj);
   Size = IntGetOutlineTextMetrics(FontGDI, 0, NULL);
   if (!otm) return Size;
   if (Size > Data)
-    {
+  {
       SetLastWin32Error(ERROR_INSUFFICIENT_BUFFER);
       return 0;
-    }
+  }
   potm = ExAllocatePoolWithTag(PagedPool, Size, TAG_GDITEXT);
-  if (NULL == potm)
-    {
+  if (!potm)
+  {
       SetLastWin32Error(ERROR_NOT_ENOUGH_MEMORY);
       return 0;
-    }
+  }
   IntGetOutlineTextMetrics(FontGDI, Size, potm);
   if (otm)
-    {
-      Status = MmCopyToCaller(otm, potm, Size);
-      if (! NT_SUCCESS(Status))
-        {
-          SetLastWin32Error(ERROR_INVALID_PARAMETER);
-          ExFreePool(potm);
-          return 0;
-        }
-    }
-  ExFreePool(potm);
+  {
+     _SEH2_TRY
+     {
+         ProbeForWrite(otm, Size, 1);
+         RtlCopyMemory(otm, potm, Size);
+     }
+     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+     {
+         Status = _SEH2_GetExceptionCode();
+     }
+     _SEH2_END
+
+     if (!NT_SUCCESS(Status))
+     {
+        SetLastWin32Error(ERROR_INVALID_PARAMETER);
+        Size = 0;
+     }
+  }
+  ExFreePoolWithTag(potm,TAG_GDITEXT);
   return Size;
 }
 
@@ -468,7 +589,7 @@ NtGdiGetFontResourceInfoInternalW(
     }
 
     /* Check buffers and copy pwszFiles to safe unicode string */
-    _SEH_TRY
+    _SEH2_TRY
     {
         ProbeForRead(pwszFiles, cbStringSize, 1);
         ProbeForWrite(pdwBytes, sizeof(DWORD), 1);
@@ -476,17 +597,17 @@ NtGdiGetFontResourceInfoInternalW(
 
         RtlCopyMemory(SafeFileNames.Buffer, pwszFiles, cbStringSize);
     }
-    _SEH_HANDLE
+    _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
     {
-        Status = _SEH_GetExceptionCode();
+        Status = _SEH2_GetExceptionCode();
     }
-    _SEH_END
+    _SEH2_END
 
     if(!NT_SUCCESS(Status))
     {
         SetLastNtError(Status);
         /* Free the string buffer for the safe filename */
-        ExFreePool(SafeFileNames.Buffer);
+        ExFreePoolWithTag(SafeFileNames.Buffer,TAG('R','T','S','U'));
         return FALSE;
     }
 
@@ -497,17 +618,17 @@ NtGdiGetFontResourceInfoInternalW(
     if (bRet && cjIn >= dwBytes)
     {
         /* Copy the data back to caller */
-        _SEH_TRY
+        _SEH2_TRY
         {
             /* Buffers are already probed */
             RtlCopyMemory(pvBuf, &Buffer, dwBytes);
             *pdwBytes = dwBytes;
         }
-        _SEH_HANDLE
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
         {
-            Status = _SEH_GetExceptionCode();
+            Status = _SEH2_GetExceptionCode();
         }
-        _SEH_END
+        _SEH2_END
 
         if(!NT_SUCCESS(Status))
         {
@@ -517,13 +638,84 @@ NtGdiGetFontResourceInfoInternalW(
     }
 
     /* Free the string for the safe filenames */
-    ExFreePool(SafeFileNames.Buffer);
+    ExFreePoolWithTag(SafeFileNames.Buffer,TAG('R','T','S','U'));
 
     return bRet;
 }
 
+ /*
+ * @unimplemented
+ */
+BOOL
+APIENTRY
+NtGdiGetRealizationInfo(
+    IN HDC hdc,
+    OUT PREALIZATION_INFO pri,
+    IN HFONT hf)
+{
+  PDC pDc;
+  PTEXTOBJ pTextObj;
+  PFONTGDI pFontGdi;
+  PDC_ATTR Dc_Attr;
+  BOOL Ret = FALSE;
+  INT i = 0;
+  REALIZATION_INFO ri;
+
+  pDc = DC_LockDc(hdc);
+  if (!pDc)
+  {
+     SetLastWin32Error(ERROR_INVALID_HANDLE);
+     return 0;
+  }
+  Dc_Attr = pDc->pDc_Attr;
+  if(!Dc_Attr) Dc_Attr = &pDc->Dc_Attr;
+  pTextObj = RealizeFontInit(Dc_Attr->hlfntNew);
+  pFontGdi = ObjToGDI(pTextObj->Font, FONT);
+  TEXTOBJ_UnlockText(pTextObj);
+  DC_UnlockDc(pDc);
+
+  Ret = ftGdiRealizationInfo(pFontGdi, &ri);
+  if (Ret)
+  {
+     if (pri)
+     {
+        NTSTATUS Status = STATUS_SUCCESS;
+        _SEH2_TRY
+        {
+            ProbeForWrite(pri, sizeof(REALIZATION_INFO), 1);
+            RtlCopyMemory(pri, &ri, sizeof(REALIZATION_INFO));
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            Status = _SEH2_GetExceptionCode();
+        }
+        _SEH2_END
+
+        if(!NT_SUCCESS(Status))
+        {
+            SetLastNtError(Status);
+            return FALSE;
+        }
+     }
+     do
+     {
+        if (GdiHandleTable->cfPublic[i].hf == hf)
+        {
+           GdiHandleTable->cfPublic[i].iTechnology = ri.iTechnology;
+           GdiHandleTable->cfPublic[i].iUniq = ri.iUniq;
+           GdiHandleTable->cfPublic[i].dwUnknown = ri.dwUnknown;
+           GdiHandleTable->cfPublic[i].dwCFCount = GdiHandleTable->dwCFCount;
+           GdiHandleTable->cfPublic[i].fl |= CFONT_REALIZATION;
+        }
+        i++;
+     }
+     while ( i < GDI_CFONT_MAX );
+  }
+  return Ret;
+}
+
 HFONT
-STDCALL
+APIENTRY
 NtGdiHfontCreate(
   IN PENUMLOGFONTEXDVW pelfw,
   IN ULONG cjElfw,
@@ -536,21 +728,25 @@ NtGdiHfontCreate(
   PTEXTOBJ TextObj;
   NTSTATUS Status = STATUS_SUCCESS;
 
+  /* Silence GCC warnings */
+  SafeLogfont.elfEnumLogfontEx.elfLogFont.lfEscapement = 0;
+  SafeLogfont.elfEnumLogfontEx.elfLogFont.lfOrientation = 0;
+
   if (!pelfw)
   {
       return NULL;
   }
 
-  _SEH_TRY
+  _SEH2_TRY
   {
       ProbeForRead(pelfw, sizeof(ENUMLOGFONTEXDVW), 1);
       RtlCopyMemory(&SafeLogfont, pelfw, sizeof(ENUMLOGFONTEXDVW));
   }
-  _SEH_HANDLE
+  _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
   {
-      Status = _SEH_GetExceptionCode();
+      Status = _SEH2_GetExceptionCode();
   }
-  _SEH_END
+  _SEH2_END
 
   if (!NT_SUCCESS(Status))
   {
@@ -580,5 +776,41 @@ NtGdiHfontCreate(
   return hNewFont;
 }
 
+/*
+ * @implemented
+ */
+HFONT
+APIENTRY
+NtGdiSelectFont(
+    IN HDC hDC,
+    IN HFONT hFont)
+{
+    PDC pDC;
+    PDC_ATTR pDc_Attr;
+    HFONT hOrgFont = NULL;
+
+    if (hDC == NULL || hFont == NULL) return NULL;
+
+    pDC = DC_LockDc(hDC);
+    if (!pDC)
+    {
+        return NULL;
+    }
+
+    pDc_Attr = pDC->pDc_Attr;
+    if(!pDc_Attr) pDc_Attr = &pDC->Dc_Attr;
+
+    /* FIXME: what if not successful? */
+    if(NT_SUCCESS(TextIntRealizeFont((HFONT)hFont,NULL)))
+    {
+        hOrgFont = pDc_Attr->hlfntNew;
+        pDc_Attr->hlfntNew = hFont;
+    }
+
+    DC_UnlockDc(pDC);
+
+    return hOrgFont;
+}
+
 
 /* EOF */