03ed3268ef4af5bba70b9de02f98d71836433ff7
[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 LPWORD glyphs = NULL;
67 LPWSTR reordered_str = NULL;
68 INT cGlyphs;
69 BOOL bResult;
70
71 UNREFERENCED_PARAMETER(unknown);
72
73 if (!(fuOptions & ETO_IGNORELANGUAGE))
74 fuOptions |= ETO_IGNORELANGUAGE;
75
76 /* Check text direction */
77 if ((GetLayout(hdc) & LAYOUT_RTL) || (GetTextAlign(hdc) & TA_RTLREADING))
78 {
79 if (!(fuOptions & ETO_RTLREADING))
80 fuOptions |= ETO_RTLREADING;
81 }
82
83 /* Check if the string requires complex script processing and not a "glyph indices" array */
84 if (ScriptIsComplex(lpString, uCount, SIC_COMPLEX) == S_OK && !(fuOptions & ETO_GLYPH_INDEX))
85 {
86 reordered_str = HeapAlloc(GetProcessHeap(), 0, uCount * sizeof(WCHAR));
87
88 BIDI_Reorder(hdc, lpString, uCount, GCP_REORDER,
89 (fuOptions & ETO_RTLREADING) ? WINE_GCPW_FORCE_RTL : WINE_GCPW_FORCE_LTR,
90 reordered_str, uCount, NULL, &glyphs, &cGlyphs);
91
92 if (glyphs)
93 {
94 fuOptions |= ETO_GLYPH_INDEX;
95 uCount = cGlyphs;
96 }
97
98 if (glyphs || reordered_str)
99 {
100 bResult = ExtTextOutW(hdc, x, y, fuOptions, lprc,
101 glyphs ? (LPWSTR)glyphs : reordered_str, uCount, lpDx);
102 }
103
104 else
105 bResult = ExtTextOutW(hdc, x, y, fuOptions, lprc, lpString, uCount, lpDx);
106
107 HeapFree(GetProcessHeap(), 0, glyphs);
108 HeapFree(GetProcessHeap(), 0, reordered_str);
109
110 return bResult;
111 }
112
113 return ExtTextOutW(hdc, x, y, fuOptions, lprc, lpString, uCount, lpDx);
114 }
115
116 /*
117 * @implemented
118 */
119 DWORD
120 WINAPI
121 LpkGetCharacterPlacement(
122 HDC hdc,
123 LPCWSTR lpString,
124 INT uCount,
125 INT nMaxExtent,
126 LPGCP_RESULTSW lpResults,
127 DWORD dwFlags,
128 DWORD dwUnused)
129 {
130 LPWORD lpGlyphs = NULL;
131 SIZE size;
132 DWORD ret = 0;
133 UINT nSet, i;
134 INT cGlyphs;
135
136 UNREFERENCED_PARAMETER(dwUnused);
137
138 /* Sanity check (most likely a direct call) */
139 if (!(dwFlags & GCP_REORDER))
140 return GetCharacterPlacementW(hdc, lpString, uCount, nMaxExtent, lpResults, dwFlags);
141
142 nSet = (UINT)uCount;
143 if (nSet > lpResults->nGlyphs)
144 nSet = lpResults->nGlyphs;
145
146 BIDI_Reorder(hdc, lpString, uCount, dwFlags, WINE_GCPW_FORCE_LTR, lpResults->lpOutString,
147 nSet, lpResults->lpOrder, &lpGlyphs, &cGlyphs);
148
149 lpResults->nGlyphs = (UINT)cGlyphs;
150
151 if (lpResults->lpGlyphs)
152 {
153 if (lpGlyphs)
154 StringCchCopyW(lpResults->lpGlyphs, cGlyphs, lpGlyphs);
155
156 else if (lpResults->lpOutString)
157 GetGlyphIndicesW(hdc, lpResults->lpOutString, nSet, lpResults->lpGlyphs, 0);
158 }
159
160 if (lpResults->lpDx)
161 {
162 /* If glyph shaping was requested */
163 if (dwFlags & GCP_GLYPHSHAPE)
164 {
165 int c;
166
167 if (lpResults->lpGlyphs)
168 {
169 for (i = 0; i < lpResults->nGlyphs; i++)
170 {
171 if (GetCharWidthI(hdc, 0, 1, (WORD *)&lpResults->lpGlyphs[i], &c))
172 lpResults->lpDx[i] = c;
173 }
174 }
175 }
176
177 else
178 {
179 int c;
180
181 for (i = 0; i < nSet; i++)
182 {
183 if (GetCharWidth32W(hdc, lpResults->lpOutString[i], lpResults->lpOutString[i], &c))
184 lpResults->lpDx[i] = c;
185 }
186 }
187 }
188
189 /* FIXME: Currently not bidi compliant! */
190 if (lpResults->lpCaretPos)
191 {
192 int pos = 0;
193
194 lpResults->lpCaretPos[0] = 0;
195 for (i = 1; i < nSet; i++)
196 {
197 if (GetTextExtentPoint32W(hdc, &(lpString[i - 1]), 1, &size))
198 lpResults->lpCaretPos[i] = (pos += size.cx);
199 }
200 }
201
202 if (GetTextExtentPoint32W(hdc, lpString, uCount, &size))
203 ret = MAKELONG(size.cx, size.cy);
204
205 HeapFree(GetProcessHeap(), 0, lpGlyphs);
206
207 return ret;
208 }