source: trunk/src/gdi32/text.cpp@ 7682

Last change on this file since 7682 was 7682, checked in by sandervl, 24 years ago

removed internaldrawtext

File size: 14.5 KB
Line 
1/* $Id: text.cpp,v 1.28 2001-12-26 11:33:10 sandervl Exp $ */
2
3/*
4 * GDI32 text apis
5 *
6 * Based on Wine code (991031) (objects\text.c)
7 *
8 * Copyright 1993, 1994 Alexandre Julliard
9 * Copyright 1999-2000 Christoph Bratschi
10 *
11 * Project Odin Software License can be found in LICENSE.TXT
12 *
13 */
14#include <os2win.h>
15#include <stdlib.h>
16#include <misc.h>
17#include <string.h>
18#include <float.h>
19#include "oslibgpi.h"
20#include <dcdata.h>
21#include <unicode.h>
22
23#define DBG_LOCALLOG DBG_text
24#include "dbglocal.h"
25
26#define ELLIPSIS "..."
27#define ELLIPSISLEN 3
28
29//******************************************************************************
30//******************************************************************************
31UINT WINAPI GetTextCharsetInfo(
32 HDC hdc, /* [in] Handle to device context */
33 LPFONTSIGNATURE fs, /* [out] Pointer to struct to receive data */
34 DWORD flags) /* [in] Reserved - must be 0 */
35{
36 HGDIOBJ hFont;
37 UINT charSet = DEFAULT_CHARSET;
38 LOGFONTW lf;
39 CHARSETINFO csinfo;
40
41 dprintf(("GetTextCharsetInfo %x %x %x", hdc, fs, flags));
42
43 hFont = GetCurrentObject(hdc, OBJ_FONT);
44 if (hFont == 0)
45 return(DEFAULT_CHARSET);
46 if ( GetObjectW(hFont, sizeof(LOGFONTW), &lf) != 0 )
47 charSet = lf.lfCharSet;
48
49 if (fs != NULL) {
50 if (!TranslateCharsetInfo((LPDWORD)charSet, &csinfo, TCI_SRCCHARSET))
51 return (DEFAULT_CHARSET);
52 memcpy(fs, &csinfo.fs, sizeof(FONTSIGNATURE));
53 }
54 return charSet;
55}
56/***********************************************************************
57 * GetTextCharset32 [GDI32.226] Gets character set for font in DC
58 *
59 * NOTES
60 * Should it return a UINT32 instead of an INT32?
61 * => YES, as GetTextCharsetInfo returns UINT32
62 *
63 * RETURNS
64 * Success: Character set identifier
65 * Failure: DEFAULT_CHARSET
66 */
67UINT WINAPI GetTextCharset(HDC hdc) /* [in] Handle to device context */
68{
69 /* MSDN docs say this is equivalent */
70 return GetTextCharsetInfo(hdc, NULL, 0);
71}
72//******************************************************************************
73// todo: metafile support
74//******************************************************************************
75BOOL InternalTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,INT cbCount,CONST INT *lpDx,BOOL IsExtTextOut)
76{
77 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
78 ULONG flOptions = 0;
79 RECTLOS2 pmRect;
80 POINTLOS2 ptl;
81 LONG hits;
82
83 if (!pHps || (cbCount < 0) || ((lpszString == NULL) && (cbCount != 0)))
84 {
85 dprintf(("InternalTextOutA: invalid parameter"));
86 SetLastError(ERROR_INVALID_HANDLE);
87 return FALSE;
88 }
89
90 if (cbCount > 512)
91 {
92 dprintf(("InternalTextOutA: invalid parameter cbCount"));
93 SetLastError(ERROR_INVALID_PARAMETER);
94 return FALSE;
95 }
96 if (fuOptions & ~((UINT)(ETO_CLIPPED | ETO_OPAQUE)))
97 {
98 dprintf(("InternalTextOutA: invalid fuOptions"));
99 //ETO_GLYPH_INDEX, ETO_RTLLEADING, ETO_NUMERICSLOCAL, ETO_NUMERICSLATIN, ETO_IGNORELANGUAGE, ETO_PDY are ignored
100 return TRUE;
101 }
102
103 //CB: add metafile info
104
105 if (lprc)
106 {
107 if (fuOptions)
108 {
109 MapWin32ToOS2Rect(*lprc,pmRect);
110 if (excludeBottomRightPoint(pHps,(PPOINTLOS2)&pmRect) == 0)
111 {
112 dprintf(("InternalTextOutA: excludeBottomRightPoint returned 0"));
113 return TRUE;
114 }
115#ifndef INVERT
116 if (pHps->yInvert > 0) {
117 int temp = pHps->yInvert - pmRect.yTop;
118 pmRect.yTop = pHps->yInvert - pmRect.yBottom;
119 pmRect.yBottom = temp;
120 }
121#endif
122
123 if (fuOptions & ETO_CLIPPED) flOptions |= CHSOS_CLIP;
124 if (fuOptions & ETO_OPAQUE) flOptions |= CHSOS_OPAQUE;
125 }
126 }
127 else
128 {
129 if (fuOptions)
130 {
131 dprintf(("InternalTextOutA: ERROR_INVALID_HANDLE"));
132 SetLastError(ERROR_INVALID_HANDLE);
133 return FALSE;
134 }
135 }
136
137 if (cbCount == 0)
138 {
139 if (fuOptions & ETO_OPAQUE)
140 {
141//SvL: This doesn't seem to work (anymore). Look at MFC apps for the missing border
142// between menu & button bar (all white). (e.g. odin app & acrobat reader 4.05)
143#if 0
144 lpszString = " ";
145 cbCount = 1;
146 flOptions |= CHSOS_CLIP;
147#else
148 HBRUSH hbrush = CreateSolidBrush(GetBkColor(hdc));
149 HBRUSH oldbrush;
150
151 oldbrush = SelectObject(hdc, hbrush);
152 FillRect(hdc, lprc, hbrush);
153 SelectObject(hdc, oldbrush);
154 DeleteObject(hbrush);
155 return TRUE;
156#endif
157 }
158 else {
159 dprintf(("InternalTextOutA: cbCount == 0"));
160 return TRUE;
161 }
162 }
163 if (lpDx)
164 flOptions |= CHSOS_VECTOR;
165
166 if (!getAlignUpdateCP(pHps))
167 {
168 ptl.x = X;
169 ptl.y = Y;
170
171#ifndef INVERT
172 if (pHps->yInvert > 0) {
173 ptl.y = pHps->yInvert - Y;
174 }
175#endif
176
177 flOptions |= CHSOS_LEAVEPOS;
178 }
179 else OSLibGpiQueryCurrentPosition(pHps,&ptl);
180
181 UINT align = GetTextAlign(hdc);
182 LONG pmHAlign,pmVAlign;
183
184 //CB: TA_RIGHT not supported by PM, only TA_CENTER and TA_LEFT
185 if ((align & 0x6) == TA_RIGHT)
186 {
187 PPOINTLOS2 pts = (PPOINTLOS2)malloc((cbCount+1)*sizeof(POINTLOS2));
188
189 OSLibGpiQueryCharStringPosAt(pHps,&ptl,flOptions,cbCount,lpszString,lpDx,pts);
190 ptl.x -= pts[cbCount].x-pts[0].x;
191 free(pts);
192 }
193
194 if (lprc && ((align & 0x18) == TA_BASELINE))
195 {
196 //CB: if TA_BASELINE is set, GPI doesn't fill rect
197 // TA_BOTTOM fills rect
198 OSLibGpiQueryTextAlignment(pHps,&pmHAlign,&pmVAlign);
199 OSLibGpiSetTextAlignment(pHps,pmHAlign,(pmVAlign & ~TAOS_BASE) | TAOS_BOTTOM);
200 }
201
202 ptl.y += getWorldYDeltaFor1Pixel(pHps);
203
204#ifndef INVERT
205 int vertAdjust = 0;
206 if ((pHps->taMode & 0x18) == TA_TOP)
207 {
208 vertAdjust = OSLibGpiQueryFontMaxHeight(pHps->hps);
209 }
210 ptl.y -= vertAdjust;
211#endif
212
213 hits = OSLibGpiCharStringPosAt(pHps,&ptl,&pmRect,flOptions,cbCount,lpszString,lpDx);
214
215 if (lprc && ((align & 0x18) == TA_BASELINE))
216 OSLibGpiSetTextAlignment(pHps,pmHAlign,pmVAlign);
217
218 if(hits == GPIOS_ERROR) {
219 dprintf(("InternalTextOutA: OSLibGpiCharStringPosAt returned GPIOS_ERROR"));
220 return FALSE;
221 }
222
223 if (getAlignUpdateCP(pHps))
224 {
225 OSLibGpiQueryCurrentPosition(pHps,&ptl);
226 ptl.y -= getWorldYDeltaFor1Pixel(pHps);
227#ifndef INVERT
228 ptl.y += vertAdjust;
229#endif
230 OSLibGpiSetCurrentPosition(pHps,&ptl);
231 }
232
233 return TRUE;
234}
235//******************************************************************************
236//******************************************************************************
237BOOL InternalTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCWSTR lpszString,INT cbCount,CONST INT *lpDx,BOOL IsExtTextOut)
238{
239 char *astring = NULL;
240 BOOL rc;
241
242 if(cbCount == -1) {
243 astring = UnicodeToAsciiString((LPWSTR)lpszString);
244 }
245 else
246 if(cbCount) {
247 astring = (char *)HEAP_malloc(cbCount+1);
248 UnicodeToAsciiN((LPWSTR)lpszString, astring, cbCount+1);
249 astring[cbCount] = 0;
250 }
251 rc = InternalTextOutA(hdc,X,Y,fuOptions,lprc,(LPCSTR)astring,cbCount,lpDx,IsExtTextOut);
252 if(astring) {
253 FreeAsciiString(astring);
254 }
255
256 return(rc);
257}
258//******************************************************************************
259//******************************************************************************
260BOOL WIN32API ExtTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,UINT cbCount,CONST INT *lpDx)
261{
262 if(lprc) {
263 dprintf(("GDI32: ExtTextOutA %x %s (%d,%d) %x %d %x rect (%d,%d)(%d,%d)", hdc, lpszString, X, Y, fuOptions, cbCount, lpDx, lprc->left, lprc->top, lprc->right, lprc->bottom));
264 }
265 else dprintf(("GDI32: ExtTextOutA %x %s (%d,%d) %x %d %x", hdc, lpszString, X, Y, fuOptions, cbCount, lpDx));
266
267 return InternalTextOutA(hdc, X, Y, fuOptions, lprc, lpszString, cbCount, lpDx, TRUE);
268}
269//******************************************************************************
270//******************************************************************************
271BOOL WIN32API ExtTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCWSTR lpszString,UINT cbCount,CONST int *lpDx)
272{
273 if(lprc) {
274 dprintf(("GDI32: ExtTextOutW %x %ls (%d,%d) %x %d %x rect (%d,%d)(%d,%d)", hdc, lpszString, X, Y, fuOptions, cbCount, lpDx, lprc->left, lprc->top, lprc->right, lprc->bottom));
275 }
276 else dprintf(("GDI32: ExtTextOutW %x %ls (%d,%d) %x %d %x", hdc, lpszString, X, Y, fuOptions, cbCount, lpDx));
277 return InternalTextOutW(hdc, X, Y, fuOptions, lprc, lpszString, cbCount, lpDx, TRUE);
278}
279//******************************************************************************
280//******************************************************************************
281BOOL WIN32API TextOutA(HDC hdc,int nXStart,int nYStart,LPCSTR lpszString,int cbString)
282{
283 dprintf(("GDI32: TextOutA %x (%d,%d) %s", hdc, nXStart, nYStart, lpszString));
284
285 return InternalTextOutA(hdc,nXStart,nYStart,0,NULL,lpszString,cbString,NULL,FALSE);
286}
287//******************************************************************************
288//******************************************************************************
289BOOL WIN32API TextOutW(HDC hdc,int nXStart,int nYStart,LPCWSTR lpszString,int cbString)
290{
291 dprintf(("GDI32: TextOutW %x (%d,%d) %ls", hdc, nXStart, nYStart, lpszString));
292
293 return InternalTextOutW(hdc,nXStart,nYStart,0,NULL,lpszString,cbString,NULL,FALSE);
294}
295//******************************************************************************
296//******************************************************************************
297BOOL WIN32API PolyTextOutA(HDC hdc,POLYTEXTA *pptxt,int cStrings)
298{
299 dprintf(("GDI32: PolyTextOutA %x %x %d", hdc, pptxt, cStrings));
300
301 for (INT x = 0;x < cStrings;x++)
302 {
303 BOOL rc;
304
305 rc = InternalTextOutA(hdc,pptxt[x].x,pptxt[x].y,pptxt[x].uiFlags,&pptxt[x].rcl,pptxt[x].lpstr,pptxt[x].n,pptxt[x].pdx,TRUE);
306 if (!rc) return FALSE;
307 }
308
309 return TRUE;
310}
311//******************************************************************************
312//******************************************************************************
313BOOL WIN32API PolyTextOutW(HDC hdc,POLYTEXTW *pptxt,int cStrings)
314{
315 dprintf(("GDI32: PolyTextOutW %x %x %d", hdc, pptxt, cStrings));
316
317 for (INT x = 0;x < cStrings;x++)
318 {
319 BOOL rc;
320
321 rc = InternalTextOutW(hdc,pptxt[x].x,pptxt[x].y,pptxt[x].uiFlags,&pptxt[x].rcl,pptxt[x].lpstr,pptxt[x].n,pptxt[x].pdx,TRUE);
322 if (!rc) return FALSE;
323 }
324
325 return TRUE;
326}
327//******************************************************************************
328//******************************************************************************
329BOOL WIN32API GetTextExtentPointA(HDC hdc, LPCTSTR lpsz, int cbString,
330 LPSIZE lpsSize)
331{
332#if 1
333 //SvL: This works better than the code below. Can been seen clearly
334 // in the Settings dialog box of VirtualPC. Strings are clipped.
335 // (e.g.: Hard Disk 1 -> Hard Disk)
336 dprintf(("GDI32: GetTextExtentPointA %s\n", lpsz));
337 BOOL rc = O32_GetTextExtentPoint(hdc, lpsz, cbString, lpsSize);
338 if(rc) {
339 dprintf(("GDI32: GetTextExtentPointA %x %s %d returned %d (%d,%d)", hdc, lpsz, cbString, rc, lpsSize->cx, lpsSize->cy));
340 SetLastError(ERROR_SUCCESS);
341 return TRUE;
342 }
343 return FALSE;
344#else
345 BOOL rc;
346 POINTLOS2 pts[TXTBOXOS_COUNT];
347 POINTLOS2 widthHeight = { 0, 0};
348 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
349
350 dprintf(("GDI32: GetTextExtentPointA %s\n", lpsz));
351 if(pHps == NULL)
352 {
353 SetLastError(ERROR_INVALID_HANDLE);
354 return FALSE;
355 }
356
357 if(lpsz == NULL || cbString < 0 || lpsSize == NULL)
358 {
359 SetLastError(ERROR_INVALID_PARAMETER);
360 return FALSE;
361 }
362
363 lpsSize->cx = 0;
364 lpsSize->cy = 0;
365
366 // Verified with NT4, SP6
367 if(cbString == 0)
368 {
369 SetLastError(ERROR_SUCCESS);
370 return TRUE;
371 }
372 if(cbString > 512)
373 {
374 DWORD cbStringNew;
375 SIZE newSize;
376
377 dprintf(("WARNING: string longer than 512 chars; splitting up"));
378 lpsSize->cx = 0;
379 lpsSize->cy = 0;
380 while(cbString) {
381 cbStringNew = min(500, cbString);
382 rc = GetTextExtentPointA(hdc, lpsz, cbStringNew, &newSize);
383 if(rc == FALSE) {
384 return FALSE;
385 }
386 lpsSize->cx += newSize.cx;
387 lpsSize->cy = max(newSize.cy, lpsSize->cy);
388 lpsz += cbStringNew;
389 cbString -= cbStringNew;
390 }
391 return TRUE;
392 }
393
394 rc = OSLibGpiQueryTextBox(pHps, cbString, lpsz, TXTBOXOS_COUNT, pts);
395 if(rc == FALSE)
396 {
397 SetLastError(ERROR_INVALID_PARAMETER); //todo wrong error
398 return FALSE;
399 }
400 calcDimensions(pts, &widthHeight);
401 lpsSize->cx = widthHeight.x;
402 lpsSize->cy = widthHeight.y;
403
404 if(pHps && pHps->isPrinter && pHps->hdc)
405 {//scale for printer dcs
406 LONG alArray[2];
407
408 if (OSLibDevQueryCaps(pHps, OSLIB_CAPS_HORIZONTAL_RESOLUTION, 2, &alArray[0]))
409 lpsSize->cx = lpsSize->cx * alArray[0] / alArray[1];
410 }
411
412 dprintf(("GDI32: GetTextExtentPointA %x %s %d returned %d (%d,%d)", hdc, lpsz, cbString, rc, lpsSize->cx, lpsSize->cy));
413 SetLastError(ERROR_SUCCESS);
414 return TRUE;
415#endif
416}
417//******************************************************************************
418//******************************************************************************
419BOOL WIN32API GetTextExtentPointW(HDC hdc,
420 LPCWSTR lpString,
421 int cbString,
422 PSIZE lpSize)
423{
424 char *astring = UnicodeToAsciiString((LPWSTR)lpString);
425 BOOL rc;
426
427 dprintf(("GDI32: GetTextExtentPointW %s\n", astring));
428 lpSize->cx = lpSize->cy = 0;
429 rc = GetTextExtentPointA(hdc,
430 astring,
431 cbString,
432 lpSize);
433 FreeAsciiString(astring);
434 return(rc);
435}
436//******************************************************************************
437//******************************************************************************
438BOOL WIN32API GetTextExtentPoint32A( HDC hdc, LPCSTR lpsz, int cbString, PSIZE lpSize)
439{
440 BOOL rc;
441
442 dprintf(("GDI32: GetTextExtentPoint32A %s\n", lpsz));
443 lpSize->cx = lpSize->cy = 0;
444 rc = GetTextExtentPointA(hdc, lpsz, cbString, lpSize);
445 return rc;
446}
447//******************************************************************************
448//******************************************************************************
449BOOL WIN32API GetTextExtentPoint32W(HDC arg1, LPCWSTR arg2, int arg3, PSIZE lpSize)
450{
451 char *astring = UnicodeToAsciiString((LPWSTR)arg2);
452 BOOL rc;
453
454 dprintf(("GDI32: GetTextExtentPoint32W %s\n", astring));
455 rc = GetTextExtentPointA(arg1, astring, arg3, lpSize);
456 FreeAsciiString(astring);
457 return(rc);
458}
459//******************************************************************************
460//******************************************************************************
Note: See TracBrowser for help on using the repository browser.