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)
12 LPK_LPEDITCONTROL_LIST LpkEditControl
= {EditCreate
, EditIchToXY
, EditMouseToIch
, EditCchInWidth
,
13 EditGetLineWidth
, EditDrawText
, EditHScroll
, EditMoveSelection
,
14 EditVerifyText
, EditNextWord
, EditSetMenu
, EditProcessMenu
,
15 EditCreateCaret
, EditAdjustCaret
};
25 return LpkDllInitialize(hDll
,dwReason
,lpReserved
);
37 case DLL_PROCESS_ATTACH
:
38 DisableThreadLibraryCalls(hDll
);
39 /* Tell usp10 it is activated usp10 */
68 LPWSTR reordered_str
= NULL
;
70 DWORD dwSICFlags
= SIC_COMPLEX
;
71 BOOL bResult
, bReorder
;
73 UNREFERENCED_PARAMETER(unknown
);
75 fuOptions
|= ETO_IGNORELANGUAGE
;
77 /* Check text direction */
78 if ((GetLayout(hdc
) & LAYOUT_RTL
) || (GetTextAlign(hdc
) & TA_RTLREADING
))
79 fuOptions
|= ETO_RTLREADING
;
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; */
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
))
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
));
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
);
99 fuOptions
|= ETO_GLYPH_INDEX
;
103 /* Now display the reordered text if any of the arrays is valid and if BIDI_Reorder succeeded */
104 if ((glyphs
|| reordered_str
) && bReorder
)
106 bResult
= ExtTextOutW(hdc
, x
, y
, fuOptions
, lprc
,
107 glyphs
? (LPWSTR
)glyphs
: reordered_str
, uCount
, lpDx
);
111 DPRINT1("BIDI_Reorder failed, falling back to original string.\n");
112 bResult
= ExtTextOutW(hdc
, x
, y
, fuOptions
, lprc
, lpString
, uCount
, lpDx
);
115 HeapFree(GetProcessHeap(), 0, glyphs
);
116 HeapFree(GetProcessHeap(), 0, reordered_str
);
121 return ExtTextOutW(hdc
, x
, y
, fuOptions
, lprc
, lpString
, uCount
, lpDx
);
129 LpkGetCharacterPlacement(
134 LPGCP_RESULTSW lpResults
,
138 LPWORD lpGlyphs
= NULL
;
144 UNREFERENCED_PARAMETER(dwUnused
);
146 /* Sanity check (most likely a direct call) */
147 if (!(dwFlags
& GCP_REORDER
))
148 return GetCharacterPlacementW(hdc
, lpString
, uCount
, nMaxExtent
, lpResults
, dwFlags
);
151 if (nSet
> lpResults
->nGlyphs
)
152 nSet
= lpResults
->nGlyphs
;
154 BIDI_Reorder(hdc
, lpString
, uCount
, dwFlags
, WINE_GCPW_FORCE_LTR
, lpResults
->lpOutString
,
155 nSet
, lpResults
->lpOrder
, &lpGlyphs
, &cGlyphs
);
157 lpResults
->nGlyphs
= (UINT
)cGlyphs
;
159 if (lpResults
->lpGlyphs
)
162 StringCchCopyW(lpResults
->lpGlyphs
, cGlyphs
, lpGlyphs
);
163 else if (lpResults
->lpOutString
)
164 GetGlyphIndicesW(hdc
, lpResults
->lpOutString
, nSet
, lpResults
->lpGlyphs
, 0);
171 /* If glyph shaping was requested */
172 if (dwFlags
& GCP_GLYPHSHAPE
)
174 if (lpResults
->lpGlyphs
)
176 for (i
= 0; i
< lpResults
->nGlyphs
; i
++)
178 if (GetCharWidthI(hdc
, 0, 1, (WORD
*)&lpResults
->lpGlyphs
[i
], &c
))
179 lpResults
->lpDx
[i
] = c
;
186 for (i
= 0; i
< nSet
; i
++)
188 if (GetCharWidth32W(hdc
, lpResults
->lpOutString
[i
], lpResults
->lpOutString
[i
], &c
))
189 lpResults
->lpDx
[i
] = c
;
194 /* FIXME: Currently not bidi compliant! */
195 if (lpResults
->lpCaretPos
)
199 lpResults
->lpCaretPos
[0] = 0;
200 for (i
= 1; i
< nSet
; i
++)
202 if (GetTextExtentPoint32W(hdc
, &(lpString
[i
- 1]), 1, &size
))
203 lpResults
->lpCaretPos
[i
] = (pos
+= size
.cx
);
207 if (GetTextExtentPoint32W(hdc
, lpString
, uCount
, &size
))
208 ret
= MAKELONG(size
.cx
, size
.cy
);
210 HeapFree(GetProcessHeap(), 0, lpGlyphs
);