mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 20:25:39 +00:00
[LPK] Implement LpkPSMTextOut(). (#890)
- The function is almost fully implemented, but some return values change wildly. The results are mostly compatible to the Windows results. - Remove #ifdef (this is primary ReactOS code).
This commit is contained in:
parent
b3179a0771
commit
a494d0583f
4 changed files with 147 additions and 19 deletions
|
@ -14,6 +14,97 @@ LPK_LPEDITCONTROL_LIST LpkEditControl = {EditCreate, EditIchToXY, EditMou
|
||||||
EditVerifyText, EditNextWord, EditSetMenu, EditProcessMenu,
|
EditVerifyText, EditNextWord, EditSetMenu, EditProcessMenu,
|
||||||
EditCreateCaret, EditAdjustCaret};
|
EditCreateCaret, EditAdjustCaret};
|
||||||
|
|
||||||
|
#define PREFIX 38
|
||||||
|
#define ALPHA_PREFIX 30 /* Win16: Alphabet prefix */
|
||||||
|
#define KANA_PREFIX 31 /* Win16: Katakana prefix */
|
||||||
|
|
||||||
|
static int PSM_FindLastPrefix(LPCWSTR str, int count)
|
||||||
|
{
|
||||||
|
int i, prefix_count = 0, index = -1;
|
||||||
|
|
||||||
|
for (i = 0; i < count - 1; i++)
|
||||||
|
{
|
||||||
|
if (str[i] == PREFIX && str[i + 1] != PREFIX)
|
||||||
|
{
|
||||||
|
index = i - prefix_count;
|
||||||
|
prefix_count++;
|
||||||
|
}
|
||||||
|
else if (str[i] == PREFIX && str[i + 1] == PREFIX)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PSM_PrepareToDraw(LPCWSTR str, INT count, LPWSTR new_str, LPINT new_count)
|
||||||
|
{
|
||||||
|
int len, i = 0, j = 0;
|
||||||
|
|
||||||
|
while (i < count)
|
||||||
|
{
|
||||||
|
if (str[i] == PREFIX || (iswspace(str[i]) && str[i] != L' '))
|
||||||
|
{
|
||||||
|
if(i < count - 1 && str[i + 1] == PREFIX)
|
||||||
|
new_str[j++] = str[i++];
|
||||||
|
else
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_str[j++] = str[i++];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
new_str[j] = L'\0';
|
||||||
|
len = wcslen(new_str);
|
||||||
|
*new_count = len;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Can be used with also LpkDrawTextEx if it will be implemented */
|
||||||
|
static void LPK_DrawUnderscore(HDC hdc, int x, int y, LPCWSTR str, int count, int offset)
|
||||||
|
{
|
||||||
|
SCRIPT_STRING_ANALYSIS ssa;
|
||||||
|
int prefix_x;
|
||||||
|
int prefix_end;
|
||||||
|
int pos;
|
||||||
|
SIZE size;
|
||||||
|
HPEN hpen;
|
||||||
|
HPEN oldPen;
|
||||||
|
HRESULT hr = S_FALSE;
|
||||||
|
|
||||||
|
if (offset == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (ScriptIsComplex(str, count, SIC_COMPLEX) == S_OK)
|
||||||
|
{
|
||||||
|
hr = ScriptStringAnalyse(hdc, str, count, (3 * count / 2 + 16),
|
||||||
|
-1, SSA_GLYPHS, -1, NULL, NULL, NULL, NULL, NULL, &ssa);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hr == S_OK)
|
||||||
|
{
|
||||||
|
ScriptStringCPtoX(ssa, offset, FALSE, &pos);
|
||||||
|
prefix_x = x + pos;
|
||||||
|
ScriptStringCPtoX(ssa, offset, TRUE, &pos);
|
||||||
|
prefix_end = x + pos;
|
||||||
|
ScriptStringFree(&ssa);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetTextExtentPointW(hdc, str, offset, &size);
|
||||||
|
prefix_x = x + size.cx;
|
||||||
|
GetTextExtentPointW(hdc, str, offset + 1, &size);
|
||||||
|
prefix_end = x + size.cx - 1;
|
||||||
|
}
|
||||||
|
hpen = CreatePen(PS_SOLID, 1, GetTextColor(hdc));
|
||||||
|
oldPen = SelectObject(hdc, hpen);
|
||||||
|
MoveToEx(hdc, prefix_x, y, NULL);
|
||||||
|
LineTo(hdc, prefix_end, y);
|
||||||
|
SelectObject(hdc, oldPen);
|
||||||
|
DeleteObject(hpen);
|
||||||
|
}
|
||||||
|
|
||||||
BOOL
|
BOOL
|
||||||
WINAPI
|
WINAPI
|
||||||
DllMain(
|
DllMain(
|
||||||
|
@ -196,14 +287,7 @@ LpkGetCharacterPlacement(
|
||||||
{
|
{
|
||||||
int pos = 0;
|
int pos = 0;
|
||||||
|
|
||||||
hr = ScriptStringAnalyse(hdc, lpString, nSet,
|
hr = ScriptStringAnalyse(hdc, lpString, nSet, (3 * nSet / 2 + 16), -1, SSA_GLYPHS, -1,
|
||||||
#ifdef __REACTOS__
|
|
||||||
/* ReactOS r57677 and r57679 */
|
|
||||||
(3 * nSet / 2 + 16),
|
|
||||||
#else
|
|
||||||
(1.5 * nSet + 16),
|
|
||||||
#endif
|
|
||||||
-1, SSA_GLYPHS, -1,
|
|
||||||
NULL, NULL, NULL, NULL, NULL, &ssa);
|
NULL, NULL, NULL, NULL, NULL, &ssa);
|
||||||
if (hr == S_OK)
|
if (hr == S_OK)
|
||||||
{
|
{
|
||||||
|
@ -232,3 +316,55 @@ LpkGetCharacterPlacement(
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Stripped down version of DrawText, can only draw single line text and Prefix underscore
|
||||||
|
* (only on the last found amperstand)
|
||||||
|
* only flags to be found to be of use in testing:
|
||||||
|
*
|
||||||
|
* DT_NOPREFIX - Draw the string as is without removal of the amperstands and without underscore
|
||||||
|
* DT_HIDEPREFIX - Draw the string without underscore
|
||||||
|
* DT_PREFIXONLY - Draw only the underscore
|
||||||
|
*
|
||||||
|
* without any of these flags the behavior is the string being drawn without the amperstands and
|
||||||
|
* with the underscore.
|
||||||
|
* user32 has an equivalent function - UserLpkPSMTextOut
|
||||||
|
*/
|
||||||
|
INT WINAPI LpkPSMTextOut(HDC hdc, int x, int y, LPCWSTR lpString, int cString, DWORD dwFlags)
|
||||||
|
{
|
||||||
|
SIZE size;
|
||||||
|
TEXTMETRICW tm;
|
||||||
|
int prefix_offset, len;
|
||||||
|
LPWSTR display_str = NULL;
|
||||||
|
|
||||||
|
if (!lpString || cString <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (dwFlags & DT_NOPREFIX)
|
||||||
|
{
|
||||||
|
LpkExtTextOut(hdc, x, y, (dwFlags & DT_RTLREADING) ? ETO_RTLREADING : 0, NULL, lpString, cString - 1, NULL, 0);
|
||||||
|
GetTextExtentPointW(hdc, lpString, cString, &size);
|
||||||
|
return size.cx;
|
||||||
|
}
|
||||||
|
|
||||||
|
display_str = HeapAlloc(GetProcessHeap(), 0, (cString + 1) * sizeof(WCHAR));
|
||||||
|
|
||||||
|
if (!display_str)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
PSM_PrepareToDraw(lpString, cString, display_str, &len);
|
||||||
|
|
||||||
|
if (!(dwFlags & DT_PREFIXONLY))
|
||||||
|
LpkExtTextOut(hdc, x, y, (dwFlags & DT_RTLREADING) ? ETO_RTLREADING : 0, NULL, display_str, len, NULL, 0);
|
||||||
|
|
||||||
|
if (!(dwFlags & DT_HIDEPREFIX))
|
||||||
|
{
|
||||||
|
prefix_offset = PSM_FindLastPrefix(lpString, cString);
|
||||||
|
GetTextMetricsW(hdc, &tm);
|
||||||
|
LPK_DrawUnderscore(hdc, x, y + tm.tmAscent + 1, display_str, len, prefix_offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetTextExtentPointW(hdc, display_str, len + 1, &size);
|
||||||
|
HeapFree(GetProcessHeap(), 0, display_str);
|
||||||
|
|
||||||
|
return size.cx;
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,6 @@
|
||||||
@ stdcall LpkExtTextOut(long long long long ptr wstr long ptr long)
|
@ stdcall LpkExtTextOut(long long long long ptr wstr long ptr long)
|
||||||
@ stdcall LpkGetCharacterPlacement(long wstr long long ptr long long)
|
@ stdcall LpkGetCharacterPlacement(long wstr long long ptr long long)
|
||||||
@ stdcall LpkGetTextExtentExPoint(long long long long long long long long long)
|
@ stdcall LpkGetTextExtentExPoint(long long long long long long long long long)
|
||||||
@ stdcall LpkPSMTextOut(long long long long long long)
|
@ stdcall LpkPSMTextOut(long long long wstr long long)
|
||||||
@ stdcall LpkUseGDIWidthCache(long long long long long)
|
@ stdcall LpkUseGDIWidthCache(long long long long long)
|
||||||
@ stdcall ftsWordBreak(long long long long long)
|
@ stdcall ftsWordBreak(long long long long long)
|
||||||
|
|
|
@ -66,7 +66,6 @@ DWORD WINAPI LpkTabbedTextOut(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD
|
||||||
BOOL WINAPI LpkDllInitialize (HANDLE hDll, DWORD dwReason, LPVOID lpReserved);
|
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 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 LpkGetTextExtentExPoint(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6,DWORD x7,DWORD x8,DWORD x9);
|
||||||
DWORD WINAPI LpkPSMTextOut(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6);
|
|
||||||
DWORD WINAPI LpkUseGDIWidthCache(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5);
|
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);
|
DWORD WINAPI ftsWordBreak(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5);
|
||||||
|
|
||||||
|
@ -77,6 +76,8 @@ BOOL WINAPI LpkExtTextOut(HDC hdc, int x, int y, UINT fuOptions, const RECT *lpr
|
||||||
|
|
||||||
DWORD WINAPI LpkGetCharacterPlacement(HDC hdc, LPCWSTR lpString, INT uCount, INT nMaxExtent,
|
DWORD WINAPI LpkGetCharacterPlacement(HDC hdc, LPCWSTR lpString, INT uCount, INT nMaxExtent,
|
||||||
GCP_RESULTSW *lpResults, DWORD dwFlags, DWORD dwUnused);
|
GCP_RESULTSW *lpResults, DWORD dwFlags, DWORD dwUnused);
|
||||||
|
|
||||||
|
INT WINAPI LpkPSMTextOut(HDC hdc, int x, int y, LPCWSTR lpString, int cString, DWORD dwFlags);
|
||||||
/* bidi.c */
|
/* bidi.c */
|
||||||
|
|
||||||
#define WINE_GCPW_FORCE_LTR 0
|
#define WINE_GCPW_FORCE_LTR 0
|
||||||
|
|
|
@ -48,15 +48,6 @@ DWORD WINAPI LpkGetTextExtentExPoint(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* @unimplemented
|
|
||||||
*/
|
|
||||||
DWORD WINAPI LpkPSMTextOut(DWORD x1,DWORD x2,DWORD x3,DWORD x4,DWORD x5,DWORD x6)
|
|
||||||
{
|
|
||||||
UNIMPLEMENTED
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @unimplemented
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue