[LPK] Refactoring (#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
11 LPK_LPEDITCONTROL_LIST LpkEditControl = {EditCreate, EditIchToXY, EditMouseToIch, EditCchInWidth,
12 EditGetLineWidth, EditDrawText, EditHScroll, EditMoveSelection,
13 EditVerifyText, EditNextWord, EditSetMenu, EditProcessMenu,
14 EditCreateCaret, EditAdjustCaret};
15
16 BOOL
17 WINAPI
18 DllMain(
19 HANDLE hDll,
20 DWORD dwReason,
21 LPVOID lpReserved)
22 {
23
24 return LpkDllInitialize(hDll,dwReason,lpReserved);
25 }
26
27 BOOL
28 WINAPI
29 LpkDllInitialize(
30 HANDLE hDll,
31 DWORD dwReason,
32 LPVOID lpReserved)
33 {
34 switch(dwReason)
35 {
36 case DLL_PROCESS_ATTACH:
37 DisableThreadLibraryCalls(hDll);
38 /* Tell usp10 it is activated usp10 */
39 //LpkPresent();
40 break;
41
42 default:
43 break;
44 }
45
46 return TRUE;
47 }
48
49
50 /*
51 * @implemented
52 */
53 BOOL
54 WINAPI
55 LpkExtTextOut(
56 HDC hdc,
57 int x,
58 int y,
59 UINT fuOptions,
60 const RECT *lprc,
61 LPCWSTR lpString,
62 UINT uCount,
63 const INT *lpDx,
64 INT unknown)
65 {
66 UNREFERENCED_PARAMETER(unknown);
67
68 if (!(fuOptions & ETO_IGNORELANGUAGE))
69 fuOptions |= ETO_IGNORELANGUAGE;
70
71 /* Check text direction */
72 if ((GetLayout(hdc) & LAYOUT_RTL) || (GetTextAlign(hdc) & TA_RTLREADING))
73 {
74 if (!(fuOptions & ETO_RTLREADING))
75 fuOptions |= ETO_RTLREADING;
76 }
77
78 /* Check if the string requires complex script processing and not a "glyph indices" array */
79 if (ScriptIsComplex(lpString, uCount, SIC_COMPLEX) == S_OK && !(fuOptions & ETO_GLYPH_INDEX))
80 {
81 LPWORD glyphs = NULL;
82 LPWSTR reordered_str = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WCHAR));
83 INT cGlyphs;
84 BOOL bResult;
85
86 BIDI_Reorder(hdc, lpString, uCount, GCP_REORDER,
87 (fuOptions & ETO_RTLREADING) ? WINE_GCPW_FORCE_RTL : WINE_GCPW_FORCE_LTR,
88 reordered_str, uCount, NULL, &glyphs, &cGlyphs);
89
90 if (glyphs)
91 {
92 fuOptions |= ETO_GLYPH_INDEX;
93
94 if (uCount != cGlyphs)
95 uCount = cGlyphs;
96 }
97
98 bResult = ExtTextOutW(hdc, x, y, fuOptions, lprc,
99 glyphs ? (LPWSTR)glyphs : reordered_str, uCount, lpDx);
100
101 HeapFree(GetProcessHeap(), 0, glyphs);
102 HeapFree(GetProcessHeap(), 0, reordered_str);
103
104 return bResult;
105 }
106
107 return ExtTextOutW(hdc, x, y, fuOptions, lprc, lpString, uCount, lpDx);
108 }
109
110 /*
111 * @implemented
112 */
113 DWORD
114 WINAPI
115 LpkGetCharacterPlacement(
116 HDC hdc,
117 LPCWSTR lpString,
118 INT uCount,
119 INT nMaxExtent,
120 LPGCP_RESULTSW lpResults,
121 DWORD dwFlags,
122 DWORD dwUnused)
123 {
124 LPWORD lpGlyphs = NULL;
125 SIZE size;
126 DWORD ret = 0;
127 UINT nSet, i;
128 INT cGlyphs;
129
130 UNREFERENCED_PARAMETER(dwUnused);
131
132 /* Sanity check (most likely a direct call) */
133 if (!(dwFlags & GCP_REORDER))
134 return GetCharacterPlacementW(hdc, lpString, uCount, nMaxExtent, lpResults, dwFlags);
135
136 nSet = (UINT)uCount;
137 if (nSet > lpResults->nGlyphs)
138 nSet = lpResults->nGlyphs;
139
140 BIDI_Reorder(hdc, lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
141 nSet, lpResults->lpOrder, &lpGlyphs, &cGlyphs);
142
143 lpResults->nGlyphs = (UINT)cGlyphs;
144
145 if (lpResults->lpGlyphs)
146 {
147 if (lpGlyphs)
148 wcscpy(lpResults->lpGlyphs, lpGlyphs);
149
150 else if (lpResults->lpOutString)
151 GetGlyphIndicesW(hdc, lpResults->lpOutString, nSet, lpResults->lpGlyphs, 0);
152 }
153
154 if (lpResults->lpDx)
155 {
156 /* If glyph shaping was requested */
157 if(dwFlags & GCP_GLYPHSHAPE)
158 {
159 int c;
160
161 if (lpResults->lpGlyphs)
162 {
163 for (i = 0; i < lpResults->nGlyphs; i++)
164 {
165 if (GetCharWidth32W(hdc, lpResults->lpGlyphs[i], lpResults->lpGlyphs[i], &c))
166 lpResults->lpDx[i] = c;
167 }
168 }
169 }
170
171 else
172 {
173 int c;
174
175 for (i = 0; i < nSet; i++)
176 {
177 if (GetCharWidth32W(hdc, lpResults->lpOutString[i], lpResults->lpOutString[i], &c))
178 lpResults->lpDx[i] = c;
179 }
180 }
181 }
182
183 /* FIXME: Currently not bidi compliant! */
184 if (lpResults->lpCaretPos)
185 {
186 int pos = 0;
187
188 lpResults->lpCaretPos[0] = 0;
189 for (i = 1; i < nSet; i++)
190 {
191 if (GetTextExtentPoint32W(hdc, &(lpString[i - 1]), 1, &size))
192 lpResults->lpCaretPos[i] = (pos += size.cx);
193 }
194 }
195
196 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
197 ret = MAKELONG(size.cx, size.cy);
198
199 HeapFree(GetProcessHeap(), 0, lpGlyphs);
200
201 return ret;
202 }