https://git.reactos.org/?p=reactos.git;a=commitdiff;h=107847935850743aed27c…
commit 107847935850743aed27c2e5358e5ab1c0c7023b
Author: Baruch Rutman <peterooch(a)gmail.com>
AuthorDate: Fri Feb 15 03:54:10 2019 +0200
Commit: Hermès Bélusca-Maïto <hermes.belusca-maito(a)reactos.org>
CommitDate: Sat Mar 23 23:31:02 2019 +0100
[LPK] Implement LpkGetTextExtentExPoint(). (#1362)
- Add argument checking.
- Use logic from NtGdiGetTextExtentExW().
---
dll/win32/lpk/lpk.c | 99 +++++++++++++++++++++++++++++++++++++++++++++----
dll/win32/lpk/lpk.spec | 2 +-
dll/win32/lpk/ros_lpk.h | 6 ++-
dll/win32/lpk/stub.c | 9 -----
4 files changed, 98 insertions(+), 18 deletions(-)
diff --git a/dll/win32/lpk/lpk.c b/dll/win32/lpk/lpk.c
index f78015447d..f3ecaf9499 100644
--- a/dll/win32/lpk/lpk.c
+++ b/dll/win32/lpk/lpk.c
@@ -46,7 +46,7 @@ static void PSM_PrepareToDraw(LPCWSTR str, INT count, LPWSTR new_str,
LPINT new_
{
if (str[i] == PREFIX || (iswspace(str[i]) && str[i] != L' '))
{
- if(i < count - 1 && str[i + 1] == PREFIX)
+ if (i < count - 1 && str[i + 1] == PREFIX)
new_str[j++] = str[i++];
else
i++;
@@ -239,15 +239,15 @@ LpkExtTextOut(
(fuOptions & ETO_RTLREADING) ? WINE_GCPW_FORCE_RTL :
WINE_GCPW_FORCE_LTR,
reordered_str, uCount, NULL, &glyphs, &cGlyphs);
- if (glyphs)
- {
- fuOptions |= ETO_GLYPH_INDEX;
- uCount = cGlyphs;
- }
-
/* Now display the reordered text if any of the arrays is valid and if
BIDI_Reorder succeeded */
if ((glyphs || reordered_str) && bReorder)
{
+ if (glyphs)
+ {
+ fuOptions |= ETO_GLYPH_INDEX;
+ uCount = cGlyphs;
+ }
+
bResult = ExtTextOutW(hdc, x, y, fuOptions, lprc,
glyphs ? (LPWSTR)glyphs : reordered_str, uCount,
lpDx);
}
@@ -425,3 +425,88 @@ INT WINAPI LpkPSMTextOut(HDC hdc, int x, int y, LPCWSTR lpString, int
cString, D
return size.cx;
}
+
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+LpkGetTextExtentExPoint(
+ HDC hdc,
+ LPCWSTR lpString,
+ INT cString,
+ INT nMaxExtent,
+ LPINT lpnFit,
+ LPINT lpnDx,
+ LPSIZE lpSize,
+ DWORD dwUnused,
+ int unknown)
+{
+ SCRIPT_STRING_ANALYSIS ssa;
+ HRESULT hr;
+ const SIZE *pSize;
+ INT i, extent, *Dx;
+
+ UNREFERENCED_PARAMETER(dwUnused);
+ UNREFERENCED_PARAMETER(unknown);
+
+ if (cString < 0 || !lpSize)
+ return FALSE;
+
+ if (cString == 0)
+ {
+ lpSize->cx = 0;
+ lpSize->cy = 0;
+ return TRUE;
+ }
+
+ /* Check if any processing is required */
+ if (ScriptIsComplex(lpString, cString, SIC_COMPLEX) != S_OK)
+ return GetTextExtentExPointWPri(hdc, lpString, cString, nMaxExtent, lpnFit,
lpnDx, lpSize);
+
+ hr = ScriptStringAnalyse(hdc, lpString, cString, 3 * cString / 2 + 16, -1,
+ SSA_GLYPHS, 0, NULL, NULL, NULL, NULL, NULL, &ssa);
+
+ if (hr != S_OK)
+ return FALSE;
+
+ pSize = ScriptString_pSize(ssa);
+
+ if (pSize)
+ *lpSize = *pSize;
+ else
+ GetTextExtentExPointWPri(hdc, lpString, cString, 0, NULL, NULL, lpSize);
+
+ /* Use logic from TextIntGetTextExtentPoint */
+ if (lpnDx || lpnFit)
+ {
+ Dx = HeapAlloc(GetProcessHeap(), 0, cString * sizeof(INT));
+
+ if (!Dx)
+ {
+ ScriptStringFree(&ssa);
+ return FALSE;
+ }
+
+ if (lpnFit)
+ *lpnFit = 0;
+
+ ScriptStringGetLogicalWidths(ssa, Dx);
+
+ for (i = 0, extent = 0; i < cString; i++)
+ {
+ extent += Dx[i];
+
+ if (extent <= nMaxExtent && lpnFit)
+ *lpnFit = i + 1;
+
+ if (lpnDx)
+ lpnDx[i] = extent;
+ }
+
+ HeapFree(GetProcessHeap(), 0, Dx);
+ }
+
+ ScriptStringFree(&ssa);
+ return TRUE;
+}
diff --git a/dll/win32/lpk/lpk.spec b/dll/win32/lpk/lpk.spec
index 1ef05e1a74..15a913f643 100644
--- a/dll/win32/lpk/lpk.spec
+++ b/dll/win32/lpk/lpk.spec
@@ -5,7 +5,7 @@
@ extern LpkEditControl
@ stdcall LpkExtTextOut(long long long long ptr wstr long ptr long)
@ stdcall LpkGetCharacterPlacement(long wstr long long ptr long long)
-@ stdcall LpkGetTextExtentExPoint(long long long long long long long long long)
+@ stdcall LpkGetTextExtentExPoint(long wstr long long ptr ptr ptr long long)
@ stdcall LpkPSMTextOut(long long long wstr long long)
@ stdcall LpkUseGDIWidthCache(long long long long long)
@ stdcall ftsWordBreak(long long long long long)
diff --git a/dll/win32/lpk/ros_lpk.h b/dll/win32/lpk/ros_lpk.h
index 2d2d338080..8ad993f197 100644
--- a/dll/win32/lpk/ros_lpk.h
+++ b/dll/win32/lpk/ros_lpk.h
@@ -18,6 +18,7 @@
#include <winnls.h>
#include <usp10.h>
#include <strsafe.h>
+#include "undocgdi.h"
#include "wine/unicode.h"
#include "wine/debug.h"
@@ -67,7 +68,6 @@ DWORD WINAPI LpkInitialize(DWORD x1);
DWORD WINAPI LpkTabbedTextOut(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD
x7,DWORD x8,DWORD x9,DWORD x10,DWORD x11,DWORD x12);
BOOL WINAPI LpkDllInitialize (HANDLE hDll, DWORD dwReason, LPVOID lpReserved);
DWORD WINAPI LpkDrawTextEx(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD
x7,DWORD x8,DWORD x9, DWORD x10);
-DWORD WINAPI LpkGetTextExtentExPoint(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD
x6,DWORD x7,DWORD x8,DWORD x9);
DWORD WINAPI LpkUseGDIWidthCache(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5);
DWORD WINAPI ftsWordBreak(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5);
@@ -80,6 +80,10 @@ DWORD WINAPI LpkGetCharacterPlacement(HDC hdc, LPCWSTR lpString, INT
uCount, INT
GCP_RESULTSW *lpResults, DWORD dwFlags, DWORD
dwUnused);
INT WINAPI LpkPSMTextOut(HDC hdc, int x, int y, LPCWSTR lpString, int cString, DWORD
dwFlags);
+
+BOOL WINAPI LpkGetTextExtentExPoint(HDC hdc, LPCWSTR lpString, INT cString, INT
nMaxExtent,
+ LPINT lpnFit, LPINT lpnDx, LPSIZE lpSize, DWORD
dwUnused,
+ int unknown);
/* bidi.c */
#define WINE_GCPW_FORCE_LTR 0
diff --git a/dll/win32/lpk/stub.c b/dll/win32/lpk/stub.c
index 310c4caf94..d0c11d1e1d 100644
--- a/dll/win32/lpk/stub.c
+++ b/dll/win32/lpk/stub.c
@@ -40,15 +40,6 @@ DWORD WINAPI LpkDrawTextEx(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD
x5,DWORD x6
return 0;
}
-/*
- * @unimplemented
- */
-DWORD WINAPI LpkGetTextExtentExPoint(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD
x6,DWORD x7,DWORD x8,DWORD x9)
-{
- UNIMPLEMENTED
- return 0;
-}
-
/*
* @unimplemented
*/