[GDI32]
[reactos.git] / reactos / dll / win32 / gdi32 / objects / text.c
index 69833d7..d64e012 100644 (file)
@@ -1,18 +1,17 @@
 #include "precomp.h"
 
 
-
 /*
  * @implemented
  */
-BOOL  
-STDCALL 
+BOOL
+WINAPI
 TextOutA(
        HDC  hdc,
        int  nXStart,
        int  nYStart,
        LPCSTR  lpString,
-       int  cbString)
+       int  cchString)
 {
         ANSI_STRING StringA;
         UNICODE_STRING StringU;
@@ -25,7 +24,7 @@ TextOutA(
        } else
                StringU.Buffer = NULL;
 
-       ret = TextOutW(hdc, nXStart, nYStart, StringU.Buffer, cbString);
+       ret = TextOutW(hdc, nXStart, nYStart, StringU.Buffer, cchString);
        RtlFreeUnicodeString(&StringU);
        return ret;
 }
@@ -35,29 +34,46 @@ TextOutA(
  * @implemented
  */
 BOOL
-STDCALL
+WINAPI
 TextOutW(
        HDC  hdc,
        int  nXStart,
        int  nYStart,
        LPCWSTR  lpString,
-       int  cbString)
+       int  cchString)
 {
-  return NtGdiExtTextOut(hdc, nXStart, nYStart, 0, NULL, lpString, cbString, NULL);
+  return NtGdiExtTextOutW(hdc, nXStart, nYStart, 0, NULL, (LPWSTR)lpString, cchString, NULL, 0);
 }
 
 
 /*
  * @implemented
  */
+DWORD
+WINAPI
+GdiGetCodePage(HDC hdc)
+{
+  PDC_ATTR Dc_Attr;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
+  if (Dc_Attr->ulDirty_ & DIRTY_CHARSET) return LOWORD(NtGdiGetCharSet(hdc));
+  return LOWORD(Dc_Attr->iCS_CP);
+}
+
+
+/*
+ * @unimplemented
+ */
 int
-STDCALL
-GetTextCharset(
-       HDC     hdc
+WINAPI
+GetTextCharacterExtra(
+       HDC     hDc
        )
 {
-    /* MSDN docs say this is equivalent */
-        return GetTextCharsetInfo(hdc, NULL, 0);        
+  PDC_ATTR Dc_Attr;
+
+  if (!GdiGetHandleUserData((HGDIOBJ) hDc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
+  return Dc_Attr->lTextExtra;
+// return GetDCDWord( hDc, GdiGetTextCharExtra, 0);
 }
 
 
@@ -65,49 +81,56 @@ GetTextCharset(
  * @implemented
  */
 int
-STDCALL
-GetTextCharsetInfo(
-       HDC             hdc,
-       LPFONTSIGNATURE lpSig,
-       DWORD           dwFlags
-       )
+WINAPI
+GetTextCharset(HDC hdc)
 {
-        return NtGdiGetTextCharsetInfo(hdc, lpSig, dwFlags);
+    /* MSDN docs say this is equivalent */
+    return NtGdiGetTextCharsetInfo(hdc,NULL,0);
 }
 
 
+
 /*
  * @implemented
  */
-BOOL 
-STDCALL 
+BOOL
+WINAPI
 GetTextMetricsA(
-       HDC             hdc, 
+       HDC             hdc,
        LPTEXTMETRICA   lptm
        )
 {
-  TEXTMETRICW tmw;
+  TMW_INTERNAL tmwi;
 
-  if (! NtGdiGetTextMetrics(hdc, &tmw))
-    {
-      return FALSE;
-    }
+  if (! NtGdiGetTextMetricsW(hdc, &tmwi, sizeof(TMW_INTERNAL)))
+  {
+    return FALSE;
+  }
 
-  return TextMetricW2A(lptm, &tmw);
+  FONT_TextMetricWToA(&tmwi.TextMetric, lptm);
+  return TRUE;
 }
 
 
 /*
  * @implemented
  */
-BOOL 
-STDCALL 
+BOOL
+WINAPI
 GetTextMetricsW(
-       HDC             hdc, 
+       HDC             hdc,
        LPTEXTMETRICW   lptm
        )
 {
-  return NtGdiGetTextMetrics(hdc, lptm);
+  TMW_INTERNAL tmwi;
+
+  if (! NtGdiGetTextMetricsW(hdc, &tmwi, sizeof(TMW_INTERNAL)))
+  {
+    return FALSE;
+  }
+
+  *lptm = tmwi.TextMetric;
+  return TRUE;
 }
 
 
@@ -119,7 +142,7 @@ APIENTRY
 GetTextExtentPointA(
        HDC             hdc,
        LPCSTR          lpString,
-       int             cbString,
+       int             cchString,
        LPSIZE          lpSize
        )
 {
@@ -130,7 +153,7 @@ GetTextExtentPointA(
        RtlInitAnsiString(&StringA, (LPSTR)lpString);
        RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
 
-        ret = GetTextExtentPointW(hdc, StringU.Buffer, cbString, lpSize);
+        ret = GetTextExtentPointW(hdc, StringU.Buffer, cchString, lpSize);
 
        RtlFreeUnicodeString(&StringU);
 
@@ -146,11 +169,11 @@ APIENTRY
 GetTextExtentPointW(
        HDC             hdc,
        LPCWSTR         lpString,
-       int             cbString,
+       int             cchString,
        LPSIZE          lpSize
        )
 {
-  return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cbString, lpSize, 0);
+  return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpSize, 1);
 }
 
 
@@ -160,15 +183,22 @@ GetTextExtentPointW(
 BOOL
 APIENTRY
 GetTextExtentExPointW(
-       HDC             hdc,
-       LPCWSTR         lpszStr,
-       int             cchString,
-       int             nMaxExtent,
-       LPINT           lpnFit,
-       LPINT           alpDx,
-       LPSIZE          lpSize
+       HDC     hdc,
+       LPCWSTR lpszStr,
+       int     cchString,
+       int     nMaxExtent,
+       LPINT   lpnFit,
+       LPINT   alpDx,
+       LPSIZE  lpSize
        )
 {
+
+  if(nMaxExtent < -1)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return FALSE;
+  }
+
   return NtGdiGetTextExtentExW (
     hdc, (LPWSTR)lpszStr, cchString, nMaxExtent, (PULONG)lpnFit, (PULONG)alpDx, lpSize, 0 );
 }
@@ -193,6 +223,12 @@ GetTextExtentExPointA(
   LPWSTR lpszStrW;
   BOOL rc = 0;
 
+  if(nMaxExtent < -1)
+  {
+    SetLastError(ERROR_INVALID_PARAMETER);
+    return FALSE;
+  }
+
   Status = HEAP_strdupA2W ( &lpszStrW, lpszStr );
   if (!NT_SUCCESS (Status))
     SetLastError (RtlNtStatusToDosError(Status));
@@ -216,7 +252,7 @@ APIENTRY
 GetTextExtentPoint32A(
        HDC             hdc,
        LPCSTR          lpString,
-       int             cbString,
+       int             cchString,
        LPSIZE          lpSize
        )
 {
@@ -227,7 +263,7 @@ GetTextExtentPoint32A(
   RtlInitAnsiString(&StringA, (LPSTR)lpString);
   RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
 
-  ret = GetTextExtentPoint32W(hdc, StringU.Buffer, cbString, lpSize);
+  ret = GetTextExtentPoint32W(hdc, StringU.Buffer, cchString, lpSize);
 
   RtlFreeUnicodeString(&StringU);
 
@@ -243,27 +279,55 @@ APIENTRY
 GetTextExtentPoint32W(
        HDC             hdc,
        LPCWSTR         lpString,
-       int             cbString,
+       int             cchString,
        LPSIZE          lpSize
        )
 {
-  return NtGdiGetTextExtentPoint32(hdc, lpString, cbString, lpSize);
+       return NtGdiGetTextExtent(hdc, (LPWSTR)lpString, cchString, lpSize, 0);
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+GetTextExtentExPointI(HDC hdc,
+                      LPWORD pgiIn,
+                      int cgi,
+                      int nMaxExtent,
+                      LPINT lpnFit,
+                      LPINT alpDx,
+                      LPSIZE lpSize)
+{
+    return NtGdiGetTextExtentExW(hdc,pgiIn,cgi,nMaxExtent,(ULONG *)lpnFit, (PULONG) alpDx,lpSize,1);
 }
 
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+GetTextExtentPointI(HDC hdc,
+                    LPWORD pgiIn,
+                    int cgi,
+                    LPSIZE lpSize)
+{
+    return NtGdiGetTextExtent(hdc,pgiIn,cgi,lpSize,2);
+}
 
 /*
  * @implemented
  */
-BOOL  
-STDCALL 
+BOOL
+WINAPI
 ExtTextOutA(
-       HDC             hdc, 
-       int             X, 
-       int             Y, 
-       UINT            fuOptions, 
+       HDC             hdc,
+       int             X,
+       int             Y,
+       UINT            fuOptions,
        CONST RECT      *lprc,
-       LPCSTR          lpString, 
-       UINT            cbCount, 
+       LPCSTR          lpString,
+       UINT            cchString,
        CONST INT       *lpDx
        )
 {
@@ -274,7 +338,7 @@ ExtTextOutA(
        RtlInitAnsiString(&StringA, (LPSTR)lpString);
        RtlAnsiStringToUnicodeString(&StringU, &StringA, TRUE);
 
-        ret = ExtTextOutW(hdc, X, Y, fuOptions, lprc, StringU.Buffer, cbCount, lpDx);
+        ret = ExtTextOutW(hdc, X, Y, fuOptions, lprc, StringU.Buffer, cchString, lpDx);
 
        RtlFreeUnicodeString(&StringU);
 
@@ -285,35 +349,42 @@ ExtTextOutA(
 /*
  * @implemented
  */
-BOOL  
-STDCALL 
+BOOL
+WINAPI
 ExtTextOutW(
-       HDC             hdc, 
-       int             X, 
-       int             Y, 
-       UINT            fuOptions,       
+       HDC             hdc,
+       int             X,
+       int             Y,
+       UINT            fuOptions,
        CONST RECT      *lprc,
-       LPCWSTR         lpString, 
-       UINT            cbCount, 
+       LPCWSTR         lpString,
+       UINT            cchString,
        CONST INT       *lpDx
        )
 {
-  return NtGdiExtTextOut(hdc, X, Y, fuOptions, lprc, lpString, cbCount, lpDx);
+  return NtGdiExtTextOutW(hdc, X, Y, fuOptions, (LPRECT)lprc, (LPWSTR)lpString, cchString, (LPINT)lpDx, 0);
 }
 
 
 /*
  * @implemented
  */
-int
-STDCALL
-GetTextFaceW(
-       HDC     hDC,
-       int     nCount,
-       LPWSTR  lpFaceName
-       )
+INT
+WINAPI
+GetTextFaceW(HDC hDC,
+             INT nCount,
+             PWSTR pFaceName)
 {
-       return NtGdiGetTextFaceW(hDC, nCount, lpFaceName, FALSE);
+    /* Validate parameters */
+    if (pFaceName && nCount <= 0)
+    {
+        /* Set last error and return failure */
+        GdiSetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+
+    /* Forward to kernel */
+    return NtGdiGetTextFaceW(hDC, nCount, pFaceName, FALSE);
 }
 
 
@@ -321,11 +392,26 @@ GetTextFaceW(
  * @implemented
  */
 int
-STDCALL
+WINAPI
 GetTextFaceA( HDC hdc, INT count, LPSTR name )
 {
-    INT res = GetTextFaceW(hdc, 0, NULL);
-    LPWSTR nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
+    INT res;
+    LPWSTR nameW;
+
+    /* Validate parameters */
+    if (name && count <= 0)
+    {
+        /* Set last error and return failure */
+        GdiSetLastError(ERROR_INVALID_PARAMETER);
+        return 0;
+    }
+
+    res = GetTextFaceW(hdc, 0, NULL);
+    nameW = HeapAlloc( GetProcessHeap(), 0, res * 2 );
+    if (nameW == NULL)
+    {
+        return 0;
+    }
     GetTextFaceW( hdc, res, nameW );
 
     if (name)
@@ -340,8 +426,27 @@ GetTextFaceA( HDC hdc, INT count, LPSTR name )
     return res;
 }
 
+
+/*
+ * @implemented
+ */
+INT
+WINAPI
+GetTextFaceAliasW(HDC hdc,
+                  int cChar,
+                  LPWSTR pszOut)
+{
+   if ( pszOut && !cChar )
+   {
+      GdiSetLastError(ERROR_INVALID_PARAMETER);
+      return 0;
+   }
+   return NtGdiGetTextFaceW(hdc,cChar,pszOut,TRUE);
+}
+
+
 BOOL
-STDCALL
+WINAPI
 GetFontResourceInfoW(
     LPCWSTR lpFileName,
     DWORD *pdwBufSize,
@@ -369,7 +474,7 @@ GetFontResourceInfoW(
 
     bRet = NtGdiGetFontResourceInfoInternalW(
         NtFileName.Buffer,
-        NtFileName.Length,
+        (NtFileName.Length / sizeof(WCHAR)) + 1,
         1,
         *pdwBufSize,
         pdwBufSize,
@@ -385,3 +490,200 @@ GetFontResourceInfoW(
 
     return TRUE;
 }
+
+
+/*
+ * @unimplemented
+ */
+int
+WINAPI
+SetTextCharacterExtra(
+       HDC     hDC,
+       int     CharExtra
+       )
+{
+  INT cExtra = 0x80000000;
+  PDC_ATTR Dc_Attr;
+
+  if (CharExtra == cExtra)
+  {
+     SetLastError(ERROR_INVALID_PARAMETER);
+     return cExtra;
+  }
+#if 0
+  if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
+  {
+    return MFDRV_SetTextCharacterExtra( hDC, CharExtra ); // Wine port.
+  }
+#endif
+  if (!GdiGetHandleUserData((HGDIOBJ) hDC, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return cExtra;
+
+  if (NtCurrentTeb()->GdiTebBatch.HDC == hDC)
+  {
+     if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
+     {
+       NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
+       Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
+     }
+  }
+  cExtra = Dc_Attr->lTextExtra;
+  Dc_Attr->lTextExtra = CharExtra;
+  return cExtra;
+// return GetAndSetDCDWord( hDC, GdiGetSetTextCharExtra, CharExtra, 0, 0, 0 );
+}
+
+/*
+ * @implemented
+ *
+ */
+UINT
+WINAPI
+GetTextAlign(HDC hdc)
+{
+  PDC_ATTR Dc_Attr;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
+  return Dc_Attr->lTextAlign;
+}
+
+
+/*
+ * @implemented
+ *
+ */
+COLORREF
+WINAPI
+GetTextColor(HDC hdc)
+{
+  PDC_ATTR Dc_Attr;
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return 0;
+  return Dc_Attr->ulForegroundClr;
+}
+
+
+
+/*
+ * @unimplemented
+ */
+UINT
+WINAPI
+SetTextAlign(HDC hdc,
+             UINT fMode)
+{
+  PDC_ATTR Dc_Attr;
+  INT OldMode = 0;
+#if 0
+  if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
+  {
+    if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
+      return MFDRV_SetTextAlign( hdc, fMode )
+    else
+    {
+      PLDC pLDC = Dc_Attr->pvLDC;
+      if ( !pLDC )
+      {
+         SetLastError(ERROR_INVALID_HANDLE);
+         return FALSE;
+      }
+      if (pLDC->iType == LDC_EMFLDC)
+      {
+        if return EMFDRV_SetTextAlign( hdc, fMode )
+      }
+    }
+  }
+#endif
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldMode;
+
+  OldMode = Dc_Attr->lTextAlign;
+  Dc_Attr->lTextAlign = fMode; // Raw
+  if (Dc_Attr->dwLayout & LAYOUT_RTL)
+  {
+     if(!(fMode & TA_CENTER))  fMode |= TA_RIGHT;
+  }
+  Dc_Attr->flTextAlign = fMode & (TA_BASELINE|TA_UPDATECP|TA_CENTER);
+  return OldMode;
+
+}
+
+
+/*
+ * @implemented
+ */
+COLORREF
+WINAPI
+SetTextColor(
+       HDC hdc,
+       COLORREF crColor
+)
+{
+  PDC_ATTR Dc_Attr;
+  COLORREF OldColor = CLR_INVALID;
+#if 0
+  if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
+  {
+    if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
+      return MFDRV_SetTextColor( hDC, crColor );
+    else
+    {
+      PLDC pLDC = Dc_Attr->pvLDC;
+      if ( !pLDC )
+      {
+         SetLastError(ERROR_INVALID_HANDLE);
+         return FALSE;
+      }
+      if (pLDC->iType == LDC_EMFLDC)
+      {
+        if return EMFDRV_SetTextColor( hDC, crColor );
+      }
+    }
+  }
+#endif
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return OldColor;
+
+  OldColor = (COLORREF) Dc_Attr->ulForegroundClr;
+  Dc_Attr->ulForegroundClr = (ULONG) crColor;
+
+  if ( Dc_Attr->crForegroundClr != crColor )
+  {
+     Dc_Attr->ulDirty_ |= (DIRTY_TEXT|DIRTY_LINE|DIRTY_FILL);
+     Dc_Attr->crForegroundClr = crColor;
+  }
+  return OldColor;
+}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+SetTextJustification(
+       HDC     hdc,
+       int     extra,
+       int     breaks
+       )
+{
+  PDC_ATTR Dc_Attr;
+#if 0
+  if (GDI_HANDLE_GET_TYPE(hDC) != GDI_OBJECT_TYPE_DC)
+  {
+    if (GDI_HANDLE_GET_TYPE(hDC) == GDI_OBJECT_TYPE_METADC)
+      return MFDRV_SetTextJustification( hdc, extra, breaks )
+    else
+    {
+      SetLastError(ERROR_INVALID_HANDLE);
+      return FALSE;
+    }
+#endif
+  if (!GdiGetHandleUserData((HGDIOBJ) hdc, GDI_OBJECT_TYPE_DC, (PVOID) &Dc_Attr)) return FALSE;
+
+  if (NtCurrentTeb()->GdiTebBatch.HDC == hdc)
+  {
+     if (Dc_Attr->ulDirty_ & DC_FONTTEXT_DIRTY)
+     {
+       NtGdiFlush(); // Sync up Dc_Attr from Kernel space.
+       Dc_Attr->ulDirty_ &= ~(DC_MODE_DIRTY|DC_FONTTEXT_DIRTY);
+     }
+  }
+  Dc_Attr->cBreak = breaks;
+  Dc_Attr->lBreakExtra = extra;
+  return TRUE;
+}