[LPK] Changes (#622).
[reactos.git] / dll / win32 / lpk / lpk.c
1 /*
2 * PROJECT: ReactOS LPK
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Language Pack DLL.
5 * PROGRAMMERS: Magnus Olsen (greatlrd)
6 * Baruch Rutman (peterooch at gmail dot com)
7 */
8
9 #include "ros_lpk.h"
10 #include <debug.h>
11
12 LPK_LPEDITCONTROL_LIST LpkEditControl = {EditCreate, EditIchToXY, EditMouseToIch, EditCchInWidth,
13 EditGetLineWidth, EditDrawText, EditHScroll, EditMoveSelection,
14 EditVerifyText, EditNextWord, EditSetMenu, EditProcessMenu,
15 EditCreateCaret, EditAdjustCaret};
16
17 BOOL
18 WINAPI
19 DllMain(
20 HANDLE hDll,
21 DWORD dwReason,
22 LPVOID lpReserved)
23 {
24
25 return LpkDllInitialize(hDll,dwReason,lpReserved);
26 }
27
28 BOOL
29 WINAPI
30 LpkDllInitialize(
31 HANDLE hDll,
32 DWORD dwReason,
33 LPVOID lpReserved)
34 {
35 switch(dwReason)
36 {
37 case DLL_PROCESS_ATTACH:
38 DisableThreadLibraryCalls(hDll);
39 /* Tell usp10 it is activated usp10 */
40 //LpkPresent();
41 break;
42
43 default:
44 break;
45 }
46
47 return TRUE;
48 }
49
50
51 /*
52 * @implemented
53 */
54 BOOL
55 WINAPI
56 LpkExtTextOut(
57 HDC hdc,
58 int x,
59 int y,
60 UINT fuOptions,
61 const RECT *lprc,
62 LPCWSTR lpString,
63 UINT uCount,
64 const INT *lpDx,
65 INT unknown)
66 {
67 LPWORD glyphs = NULL;
68 LPWSTR reordered_str = NULL;
69 INT cGlyphs;
70 DWORD dwSICFlags = SIC_COMPLEX;
71 BOOL bResult, bReorder;
72
73 UNREFERENCED_PARAMETER(unknown);
74
75 fuOptions |= ETO_IGNORELANGUAGE;
76
77 /* Check text direction */
78 if ((GetLayout(hdc) & LAYOUT_RTL) || (GetTextAlign(hdc) & TA_RTLREADING))
79 fuOptions |= ETO_RTLREADING;
80
81 /* If text direction is RTL change flag to account neutral characters
82 BUG: disables reordering of propsheet titles */
83 /* if (fuOptions & ETO_RTLREADING)
84 dwSICFlags = SIC_NEUTRAL; */
85
86 /* Check if the string requires complex script processing and not a "glyph indices" array */
87 if (ScriptIsComplex(lpString, uCount, dwSICFlags) == S_OK && !(fuOptions & ETO_GLYPH_INDEX))
88 {
89 /* reordered_str is used as fallback in case the glyphs array fails to generate,
90 BIDI_Reorder doesn't attempt to write into reordered_str if memory allocation fails */
91 reordered_str = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WCHAR));
92
93 bReorder = BIDI_Reorder(hdc, lpString, uCount, GCP_REORDER,
94 (fuOptions & ETO_RTLREADING) ? WINE_GCPW_FORCE_RTL : WINE_GCPW_FORCE_LTR,
95 reordered_str, uCount, NULL, &glyphs, &cGlyphs);
96
97 if (glyphs)
98 {
99 fuOptions |= ETO_GLYPH_INDEX;
100 uCount = cGlyphs;
101 }
102
103 /* Now display the reordered text if any of the arrays is valid and if BIDI_Reorder succeeded */
104 if ((glyphs || reordered_str) && bReorder)
105 {
106 bResult = ExtTextOutW(hdc, x, y, fuOptions, lprc,
107 glyphs ? (LPWSTR)glyphs : reordered_str, uCount, lpDx);
108 }
109 else
110 {
111 DPRINT1("BIDI_Reorder failed, falling back to original string.\n");
112 bResult = ExtTextOutW(hdc, x, y, fuOptions, lprc, lpString, uCount, lpDx);
113 }
114
115 HeapFree(GetProcessHeap(), 0, glyphs);
116 HeapFree(GetProcessHeap(), 0, reordered_str);
117
118 return bResult;
119 }
120
121 return ExtTextOutW(hdc, x, y, fuOptions, lprc, lpString, uCount, lpDx);
122 }
123
124 /*
125 * @implemented
126 */
127 DWORD
128 WINAPI
129 LpkGetCharacterPlacement(
130 HDC hdc,
131 LPCWSTR lpString,
132 INT uCount,
133 INT nMaxExtent,
134 LPGCP_RESULTSW lpResults,
135 DWORD dwFlags,
136 DWORD dwUnused)
137 {
138 LPWORD lpGlyphs = NULL;
139 SIZE size;
140 DWORD ret = 0;
141 UINT nSet, i;
142 INT cGlyphs;
143
144 UNREFERENCED_PARAMETER(dwUnused);
145
146 /* Sanity check (most likely a direct call) */
147 if (!(dwFlags & GCP_REORDER))
148 return GetCharacterPlacementW(hdc, lpString, uCount, nMaxExtent, lpResults, dwFlags);
149
150 nSet = (UINT)uCount;
151 if (nSet > lpResults->nGlyphs)
152 nSet = lpResults->nGlyphs;
153
154 BIDI_Reorder(hdc, lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
155 nSet, lpResults->lpOrder, &lpGlyphs, &cGlyphs);
156
157 lpResults->nGlyphs = (UINT)cGlyphs;
158
159 if (lpResults->lpGlyphs)
160 {
161 if (lpGlyphs)
162 StringCchCopyW(lpResults->lpGlyphs, cGlyphs, lpGlyphs);
163 else if (lpResults->lpOutString)
164 GetGlyphIndicesW(hdc, lpResults->lpOutString, nSet, lpResults->lpGlyphs, 0);
165 }
166
167 if (lpResults->lpDx)
168 {
169 int c;
170
171 /* If glyph shaping was requested */
172 if (dwFlags & GCP_GLYPHSHAPE)
173 {
174 if (lpResults->lpGlyphs)
175 {
176 for (i = 0; i < lpResults->nGlyphs; i++)
177 {
178 if (GetCharWidthI(hdc, 0, 1, (WORD *)&lpResults->lpGlyphs[i], &c))
179 lpResults->lpDx[i] = c;
180 }
181 }
182 }
183
184 else
185 {
186 for (i = 0; i < nSet; i++)
187 {
188 if (GetCharWidth32W(hdc, lpResults->lpOutString[i], lpResults->lpOutString[i], &c))
189 lpResults->lpDx[i] = c;
190 }
191 }
192 }
193
194 /* FIXME: Currently not bidi compliant! */
195 if (lpResults->lpCaretPos)
196 {
197 int pos = 0;
198
199 lpResults->lpCaretPos[0] = 0;
200 for (i = 1; i < nSet; i++)
201 {
202 if (GetTextExtentPoint32W(hdc, &(lpString[i - 1]), 1, &size))
203 lpResults->lpCaretPos[i] = (pos += size.cx);
204 }
205 }
206
207 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
208 ret = MAKELONG(size.cx, size.cy);
209
210 HeapFree(GetProcessHeap(), 0, lpGlyphs);
211
212 return ret;
213 }