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

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

GetTextExtentPointA fix; call WGSS

File size: 28.7 KB
Line 
1/* $Id: text.cpp,v 1.21 2001-05-24 19:26:31 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
29typedef struct _POLYTEXTA
30{
31 int x;
32 int y;
33 UINT n;
34 LPCSTR lpstr;
35 UINT uiFlags;
36 RECT rcl;
37 int *pdx;
38} POLYTEXTA;
39
40typedef struct _POLYTEXTW
41{
42 int x;
43 int y;
44 UINT n;
45 LPCWSTR lpstr;
46 UINT uiFlags;
47 RECT rcl;
48 int *pdx;
49} POLYTEXTW;
50
51//******************************************************************************
52//******************************************************************************
53UINT WINAPI GetTextCharsetInfo(
54 HDC hdc, /* [in] Handle to device context */
55 LPFONTSIGNATURE fs, /* [out] Pointer to struct to receive data */
56 DWORD flags) /* [in] Reserved - must be 0 */
57{
58 HGDIOBJ hFont;
59 UINT charSet = DEFAULT_CHARSET;
60 LOGFONTW lf;
61 CHARSETINFO csinfo;
62
63 dprintf(("GetTextCharsetInfo %x %x %x", hdc, fs, flags));
64
65 hFont = GetCurrentObject(hdc, OBJ_FONT);
66 if (hFont == 0)
67 return(DEFAULT_CHARSET);
68 if ( GetObjectW(hFont, sizeof(LOGFONTW), &lf) != 0 )
69 charSet = lf.lfCharSet;
70
71 if (fs != NULL) {
72 if (!TranslateCharsetInfo((LPDWORD)charSet, &csinfo, TCI_SRCCHARSET))
73 return (DEFAULT_CHARSET);
74 memcpy(fs, &csinfo.fs, sizeof(FONTSIGNATURE));
75 }
76 return charSet;
77}
78/***********************************************************************
79 * GetTextCharset32 [GDI32.226] Gets character set for font in DC
80 *
81 * NOTES
82 * Should it return a UINT32 instead of an INT32?
83 * => YES, as GetTextCharsetInfo returns UINT32
84 *
85 * RETURNS
86 * Success: Character set identifier
87 * Failure: DEFAULT_CHARSET
88 */
89UINT WINAPI GetTextCharset(HDC hdc) /* [in] Handle to device context */
90{
91 /* MSDN docs say this is equivalent */
92 return GetTextCharsetInfo(hdc, NULL, 0);
93}
94//******************************************************************************
95// CB: USER32 function, but here is the better place
96//******************************************************************************
97INT SYSTEM EXPORT InternalDrawTextExA(HDC hdc,LPCSTR lpchText,INT cchText,LPRECT lprc,UINT dwDTFormat,LPDRAWTEXTPARAMS lpDTParams,BOOL isDrawTextEx)
98{
99 INT rc;
100 ULONG flCmd;
101 RECT localRectangle;
102 PRECT rectPtr;
103 LONG lTabs,xLeft,yTop;
104 UINT fpuctrlword;
105
106 //SvL: Open32's DrawText messes up the fpu control word! (@#$@#$@#$)
107 //CB: don't know if this is still the case with WinDrawTabbedText (-> testcase)
108 fpuctrlword = _control87(0, 0);
109
110 if ((!lpchText) || (cchText == 0) || (cchText < -1) || (lprc == NULL))
111 {
112 SetLastError(ERROR_INVALID_PARAMETER);
113 return 0;
114 }
115
116 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
117
118 if (!pHps)
119 {
120 SetLastError(ERROR_INVALID_HANDLE);
121 return 0;
122 }
123
124 if (cchText == -1)
125 {
126 cchText = strlen(lpchText);
127 if (cchText == 0)
128 return 0; //CB: does Win32 return textheight in this case?
129 }
130
131 if (lpDTParams)
132 {
133 // set margins
134 lprc->left += lpDTParams->iLeftMargin;
135 lprc->right -= lpDTParams->iRightMargin;
136
137 // just assume all the text has been drawn
138 lpDTParams->uiLengthDrawn = cchText;
139 }
140
141 if (!(dwDTFormat & DT_CALCRECT))
142 {
143 BOOL bTopBottomIsOkay;
144
145 if ((getIsTopTop(pHps) && lprc->top > lprc->bottom) ||
146 (!getIsTopTop(pHps) && lprc->top < lprc->bottom))
147 bTopBottomIsOkay = FALSE;
148 else
149 bTopBottomIsOkay = TRUE;
150
151 if ((lprc->left >= lprc->right) || !bTopBottomIsOkay)
152 {
153 TEXTMETRICA txtMetrics;
154 BOOL result;
155
156 result = GetTextMetricsA(hdc,&txtMetrics);
157 if (result)
158 rc = (int)txtMetrics.tmHeight;
159 else
160 rc = 0;
161
162 if (lpDTParams)
163 {
164 lprc->left -= lpDTParams->iLeftMargin;
165 lprc->right += lpDTParams->iRightMargin;
166 }
167
168 return rc;
169 }
170 }
171#ifdef INVERT
172 flCmd = DTOS_INVERT | DTOS_WORLDRECT | DTOS_TEXTATTRS | DTOS_AMPERSAND | DTOS_VERTICALEXTENT;
173#else
174 flCmd = DTOS_WORLDRECT | DTOS_TEXTATTRS | DTOS_AMPERSAND | DTOS_VERTICALEXTENT;
175#endif
176
177 LONG lMixMode = OSLibGpiQueryBackMix(pHps);
178 if (lMixMode == BMOS_OVERPAINT) flCmd |= DTOS_OPAQUE;
179
180 if (dwDTFormat & DT_CALCRECT)
181 {
182 rectPtr = lprc;
183 flCmd |= DTOS_QUERYEXTENT;
184
185 xLeft = rectPtr->left;
186 yTop = rectPtr->top;
187
188 if (dwDTFormat & DT_RIGHT)
189 {
190 if (rectPtr->left >= rectPtr->right)
191 rectPtr->left = rectPtr->right-1;
192 } else
193 {
194 if (rectPtr->right <= rectPtr->left)
195 rectPtr->right = rectPtr->left+1;
196 }
197
198 if (dwDTFormat & DT_BOTTOM)
199 {
200 if (rectPtr->top >= rectPtr->bottom)
201 rectPtr->top = rectPtr->bottom-1;
202 } else
203 {
204 if (rectPtr->bottom <= rectPtr->top)
205 rectPtr->bottom = rectPtr->top+1;
206 }
207 } else
208 {
209 rectPtr = &localRectangle;
210
211 if ((getMapMode(pHps) == MMOS_ANISOTROPIC) || (getMapMode(pHps) == MMOS_ISOTROPIC))
212 {
213 if (doesYAxisGrowNorth(pHps))
214 {
215 flCmd &= ~DTOS_INVERT;
216 flCmd |= DTOS_INVERTCHAR;
217 }
218 }
219
220 if (lprc->left > lprc->right)
221 {
222 rectPtr->left = lprc->right;
223 rectPtr->right = lprc->left;
224 } else
225 {
226 rectPtr->left = lprc->left;
227 rectPtr->right = lprc->right;
228 }
229 if (lprc->top > lprc->bottom)
230 {
231 rectPtr->top = lprc->bottom;
232 rectPtr->bottom = lprc->top;
233 } else
234 {
235 rectPtr->top = lprc->top;
236 rectPtr->bottom = lprc->bottom;
237 }
238
239#ifndef INVERT
240 if (pHps->yInvert > 0) {
241 int temp = pHps->yInvert - rectPtr->bottom;
242 rectPtr->bottom = pHps->yInvert - rectPtr->top;
243 rectPtr->top = temp;
244 }
245#endif
246 }
247
248#ifndef INVERT
249//// dwDTFormat &= ~DT_INVERT;
250//// dwDTFormat |= DT_INVERTCHAR;
251 int top = rectPtr->top;
252#endif
253
254 if (dwDTFormat & DT_EXPANDTABS)
255 {
256 if (isDrawTextEx)
257 {
258 lTabs = (lpDTParams && (dwDTFormat & DT_TABSTOP)) ? lpDTParams->iTabLength:8;
259 } else
260 {
261 lTabs = 8;
262
263 if (dwDTFormat & DT_TABSTOP)
264 {
265 lTabs = (dwDTFormat >> 8) & 0x000000FF;
266 dwDTFormat &= 0xFFFF00FF;
267 }
268 }
269 } else lTabs = -1;
270
271 if (dwDTFormat & DT_RIGHT)
272 flCmd |= DTOS_RIGHT;
273 else
274 if (dwDTFormat & DT_CENTER) flCmd |= DTOS_CENTER;
275 if (dwDTFormat & DT_BOTTOM) flCmd |= DTOS_BOTTOM;
276 if (dwDTFormat & DT_VCENTER) flCmd |= DTOS_VCENTER;
277 if (dwDTFormat & DT_WORDBREAK) flCmd |= DTOS_WORDBREAK;
278 if (dwDTFormat & DT_EXTERNALLEADING) flCmd |= DTOS_EXTERNALLEADING;
279 if (!(dwDTFormat & DT_NOPREFIX)) flCmd |= DTOS_MNEMONIC;
280 if (dwDTFormat & DT_SINGLELINE)
281 flCmd |= DTOS_SINGLELINE;
282 else
283 flCmd |= DTOS_MULTILINE;
284 if (dwDTFormat & DT_NOCLIP) flCmd |= DTOS_NOCLIP;
285
286 //CB: DT_EDITCONTROL, DT_RTLREADING ignored
287
288 BOOL done = FALSE;
289
290 if ((dwDTFormat & DT_END_ELLIPSIS) && (cchText > 1))
291 {
292 int textWidth,width;
293 RECT rect;
294
295 SetRectEmpty(&rect);
296 OSLibWinDrawTabbedText(pHps,cchText,lTabs,lpchText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
297 width = rectPtr->right-rectPtr->left;
298 textWidth = rect.right-rect.left;
299 if ((textWidth > width) && (width > 0))
300 {
301 char* newText;
302 int newTextLen = cchText-1+ELLIPSISLEN;
303 int preLen = cchText-1;
304
305 newText = (char*)malloc(newTextLen+1);
306 strncpy(newText,lpchText,cchText-1);
307 do
308 {
309 strcpy(&newText[preLen],ELLIPSIS);
310 OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
311 textWidth = rect.right-rect.left;
312 if (textWidth <= width || preLen == 1) break;
313 newTextLen--;
314 preLen--;
315 } while (TRUE);
316 rc = OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,rectPtr,0,0,flCmd);
317 if (dwDTFormat & DT_MODIFYSTRING) strcpy((LPSTR)lpchText,newText); //check length?
318 free(newText);
319
320 done = TRUE;
321 }
322 } else if ((dwDTFormat & DT_PATH_ELLIPSIS) && (cchText > 1))
323 {
324 int textWidth,width;
325 RECT rect;
326
327//CB: code not yet checked (-> testcase)
328
329 SetRectEmpty(&rect);
330 OSLibWinDrawTabbedText(pHps,cchText,lTabs,lpchText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
331 width = rectPtr->right-rectPtr->left;
332 textWidth = rect.right-rect.left;
333 if ((textWidth > width) && (width > 0))
334 {
335 char *newText,*slashPos;
336 int newTextLen = cchText+ELLIPSISLEN;
337
338 newText = (char*)malloc(newTextLen+1);
339 strncpy(newText,lpchText,cchText);
340
341 // PH 2000/10/01 "//" appeared wrong ...
342 slashPos = strrchr(newText,(int)'\\');
343 if (slashPos != NULL)
344 {
345 int preLen = slashPos-newText;
346 char* endPtr = (char*)lpchText+preLen;
347 int endLen = cchText-preLen;
348 BOOL ok = FALSE;
349
350 //delete start
351 do
352 {
353 strcpy(&newText[preLen],ELLIPSIS);
354 strncpy(&newText[preLen+ELLIPSISLEN],endPtr,endLen);
355 OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
356 textWidth = rect.right-rect.left;
357 if (textWidth <= width)
358 {
359 ok = TRUE;
360 break;
361 }
362 if (preLen == 0) break;
363 newTextLen--;
364 preLen--;
365 } while (TRUE);
366
367 if (!ok)
368 {
369 //delete end
370 do
371 {
372 endPtr++;
373 endLen--;
374 newTextLen--;
375 strncpy(&newText[ELLIPSISLEN],endPtr,endLen);
376 OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
377 textWidth = rect.right-rect.left;
378 if ((textWidth <= width) || (endLen == 0)) break;
379 } while (TRUE);
380 }
381 } else
382 {
383 int preLen,endLen;
384
385 preLen = cchText/2;
386 endLen = cchText-preLen; //endLen >= preLen
387 char* endPtr = (char*)lpchText+preLen;
388
389 do
390 {
391 strcpy(&newText[preLen],ELLIPSIS);
392 strncpy(&newText[preLen+ELLIPSISLEN],endPtr,endLen);
393 OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
394 textWidth = rect.right-rect.left;
395 if ((textWidth <= width) || (preLen+endLen == 0)) break;
396 if (endLen > preLen)
397 {
398 endLen--;
399 endPtr++;
400 } else preLen--;
401 newTextLen--;
402 } while (TRUE);
403 }
404 rc = OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,rectPtr,0,0,flCmd);
405 if (dwDTFormat & DT_MODIFYSTRING) strcpy((LPSTR)lpchText,newText); //check length?
406 free(newText);
407
408 done = TRUE;
409 }
410 }
411
412 if (!done)
413 {
414 rc = OSLibWinDrawTabbedText(pHps,cchText,lTabs,lpchText,rectPtr,0,0,flCmd);
415 }
416
417 if (dwDTFormat & DT_CALCRECT)
418 {
419#ifndef INVERT
420 if (pHps->yInvert > 0) {
421 top = top - rectPtr->top;
422 rectPtr->top += top;
423 rectPtr->bottom += top;
424 } /* endif */
425#endif
426 if (!(dwDTFormat & DT_RIGHT) && (rectPtr->left < xLeft))
427 {
428 rectPtr->right = xLeft+(rectPtr->right-rectPtr->left);
429 rectPtr->left = xLeft;
430 }
431 if (!(dwDTFormat & DT_BOTTOM) && (rectPtr->top < yTop))
432 {
433 rectPtr->bottom = yTop+(rectPtr->bottom-rectPtr->top);
434 rectPtr->top = yTop;
435 }
436 }
437
438 if (lpDTParams)
439 {
440 // don't forget to restore the margins
441 lprc->left -= lpDTParams->iLeftMargin;
442 lprc->right += lpDTParams->iRightMargin;
443 }
444
445 _control87(fpuctrlword, 0xFFFF);
446
447 return rc;
448}
449//******************************************************************************
450//******************************************************************************
451INT SYSTEM EXPORT InternalDrawTextExW(HDC hdc,LPCWSTR lpchText,INT cchText,LPRECT lprc,UINT dwDTFormat,LPDRAWTEXTPARAMS lpDTParams,BOOL isDrawTextEx)
452{
453 char *astring;
454 INT rc;
455
456 if(cchText == -1) {
457 astring = UnicodeToAsciiString((LPWSTR)lpchText);
458 }
459 else {
460 astring = (char *)HEAP_malloc(cchText+1);
461 UnicodeToAsciiN((LPWSTR)lpchText, astring, cchText+1);
462 astring[cchText] = 0;
463 }
464
465 dprintf(("InternalDrawTextExW %x %s %d %x", hdc, astring, cchText, dwDTFormat));
466 rc = InternalDrawTextExA(hdc,astring,cchText,lprc,dwDTFormat,lpDTParams,isDrawTextEx);
467 if (dwDTFormat & DT_MODIFYSTRING && (dwDTFormat & (DT_END_ELLIPSIS | DT_PATH_ELLIPSIS))) AsciiToUnicode(astring,(LPWSTR)lpchText);
468 FreeAsciiString(astring);
469
470 return(rc);
471}
472//******************************************************************************
473// CB: USER32 function, but here is the better place
474//******************************************************************************
475DWORD SYSTEM EXPORT InternalGetTabbedTextExtentA(HDC hDC,LPCSTR lpString,INT nCount,INT nTabPositions,LPINT lpnTabStopPositions)
476{
477 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hDC);
478 BOOL result;
479 POINTLOS2 pts[TXTBOXOS_COUNT];
480 POINTLOS2 widthHeight = {0,0};
481
482 if (!pHps || (nCount == 0) || (nTabPositions < 0))
483 return 0;
484
485 if (nCount < 0)
486 {
487 SetLastError(ERROR_STACK_OVERFLOW);
488 return 0;
489 }
490 if ((lpString == NULL) || (nCount > 512) || ((nTabPositions > 0) && (lpnTabStopPositions == NULL)))
491 {
492 SetLastError(ERROR_INVALID_PARAMETER);
493 return 0;
494 }
495 //CB: Win95 supports negative values for right aligned text
496 for (INT i = 0;i < nTabPositions;i++)
497 {
498 if (lpnTabStopPositions[i] < 0)
499 {
500 SetLastError(ERROR_INVALID_PARAMETER);
501 return 0;
502 }
503 }
504
505 result = OSLibGpiQueryTextBox(pHps,(nCount > 1) ? 1:nCount,lpString,TXTBOXOS_COUNT,pts);
506 if (result == FALSE)
507 return 0;
508 calcDimensions(pts,&widthHeight);
509
510 LONG rv1 = OSLibGpiQueryTabbedTextExtent(pHps,nCount,lpString,nTabPositions,lpnTabStopPositions);
511 if (rv1 == GPIOS_ERROR)
512 return 0;
513
514 return (widthHeight.y <<16)+labs(rv1);
515}
516//******************************************************************************
517//******************************************************************************
518DWORD SYSTEM EXPORT InternalGetTabbedTextExtentW(HDC hDC,LPCWSTR lpString,INT nCount,INT nTabPositions,LPINT lpnTabStopPositions)
519{
520 char *astring;
521 DWORD rc;
522
523 if(nCount == -1) {
524 astring = UnicodeToAsciiString((LPWSTR)lpString);
525 }
526 else {
527 astring = (char *)HEAP_malloc(nCount+1);
528 UnicodeToAsciiN((LPWSTR)lpString, astring, nCount+1);
529 astring[nCount] = 0;
530 }
531
532 rc = InternalGetTabbedTextExtentA(hDC,astring,nCount,nTabPositions,lpnTabStopPositions);
533 FreeAsciiString(astring);
534
535 return(rc);
536}
537//******************************************************************************
538// CB: USER32 function, but here is the better place
539//******************************************************************************
540LONG SYSTEM EXPORT InternalTabbedTextOutA(HDC hdc,INT x,INT y,LPCSTR lpString,INT nCount,INT nTabPositions,LPINT lpnTabStopPositions,INT nTabOrigin)
541{
542 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
543 POINTLOS2 ptl;
544 DWORD dimensions;
545
546 if ((pHps == NULL) || (lpString == NULL))
547 {
548 SetLastError(ERROR_INVALID_HANDLE);
549 return 0;
550 }
551 if (nCount == -1)
552 nCount = strlen(lpString);
553 if (nCount < 1)
554 {
555 SetLastError(ERROR_INVALID_HANDLE);
556 return 0;
557 }
558 if (lpnTabStopPositions == NULL)
559 nTabPositions = 0;
560 if (nTabPositions == 0)
561 lpnTabStopPositions = NULL;
562 if (nTabPositions < 0)
563 {
564 SetLastError(ERROR_INVALID_HANDLE);
565 return 0;
566 }
567 if (getAlignUpdateCP(pHps) == TRUE) {
568 OSLibGpiQueryCurrentPosition(pHps,&ptl);
569 }
570 else
571 {
572 ptl.x = x;
573 ptl.y = y;
574#ifndef INVERT
575 if (pHps->yInvert > 0) {
576 ptl.y = pHps->yInvert - ptl.y;
577 }
578#endif
579 }
580
581 //CB: nTabOrigin is ignored! -> wrong size (width)!
582 // todo: change low word (width), height is ok
583 dimensions = InternalGetTabbedTextExtentA(hdc,lpString,nCount,nTabPositions,lpnTabStopPositions);
584 if (dimensions != 0)
585 {
586 LONG rcGPI;
587
588 ptl.y += getWorldYDeltaFor1Pixel(pHps);
589
590 rcGPI = OSLibGpiTabbedCharStringAt(pHps,&ptl,NULL,0,nCount,lpString,nTabPositions,lpnTabStopPositions,nTabOrigin);
591 if (rcGPI == GPIOS_ALTERROR)
592 return 0;
593 if (getAlignUpdateCP(pHps))
594 {
595 OSLibGpiQueryCurrentPosition (pHps,&ptl);
596 ptl.y -= getWorldYDeltaFor1Pixel(pHps);
597 OSLibGpiSetCurrentPosition (pHps,&ptl);
598 }
599
600 return dimensions;
601 }
602 return 0;
603}
604//******************************************************************************
605//******************************************************************************
606LONG SYSTEM EXPORT InternalTabbedTextOutW(HDC hdc,INT x,INT y,LPCWSTR lpString,INT nCount,INT nTabPositions,LPINT lpnTabStopPositions,INT nTabOrigin)
607{
608 char *astring;
609 LONG rc;
610
611 if(nCount == -1) {
612 astring = UnicodeToAsciiString((LPWSTR)lpString);
613 }
614 else {
615 astring = (char *)HEAP_malloc(nCount+1);
616 UnicodeToAsciiN((LPWSTR)lpString, astring, nCount+1);
617 astring[nCount] = 0;
618 }
619
620 rc = InternalTabbedTextOutA(hdc,x,y,astring,nCount,nTabPositions,lpnTabStopPositions,nTabOrigin);
621 FreeAsciiString(astring);
622
623 return(rc);
624}
625//******************************************************************************
626// todo: metafile support
627//******************************************************************************
628BOOL InternalTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,INT cbCount,CONST INT *lpDx,BOOL IsExtTextOut)
629{
630 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
631 ULONG flOptions = 0;
632 RECTLOS2 pmRect;
633 POINTLOS2 ptl;
634 LONG hits;
635
636 if (!pHps || (cbCount < 0) || ((lpszString == NULL) && (cbCount != 0)))
637 {
638 dprintf(("InternalTextOutA: invalid parameter"));
639 SetLastError(ERROR_INVALID_HANDLE);
640 return FALSE;
641 }
642
643 if (cbCount > 512)
644 {
645 dprintf(("InternalTextOutA: invalid parameter cbCount"));
646 SetLastError(ERROR_INVALID_PARAMETER);
647 return FALSE;
648 }
649 if (fuOptions & ~((UINT)(ETO_CLIPPED | ETO_OPAQUE)))
650 {
651 dprintf(("InternalTextOutA: invalid fuOptions"));
652 //ETO_GLYPH_INDEX, ETO_RTLLEADING, ETO_NUMERICSLOCAL, ETO_NUMERICSLATIN, ETO_IGNORELANGUAGE, ETO_PDY are ignored
653 return TRUE;
654 }
655
656 //CB: add metafile info
657
658 if (lprc)
659 {
660 if (fuOptions)
661 {
662 MapWin32ToOS2Rect(*lprc,pmRect);
663 if (excludeBottomRightPoint(pHps,(PPOINTLOS2)&pmRect) == 0)
664 {
665 dprintf(("InternalTextOutA: excludeBottomRightPoint returned 0"));
666 return TRUE;
667 }
668#ifndef INVERT
669 if (pHps->yInvert > 0) {
670 int temp = pHps->yInvert - pmRect.yTop;
671 pmRect.yTop = pHps->yInvert - pmRect.yBottom;
672 pmRect.yBottom = temp;
673 }
674#endif
675
676 if (fuOptions & ETO_CLIPPED) flOptions |= CHSOS_CLIP;
677 if (fuOptions & ETO_OPAQUE) flOptions |= CHSOS_OPAQUE;
678 }
679 }
680 else
681 {
682 if (fuOptions)
683 {
684 dprintf(("InternalTextOutA: ERROR_INVALID_HANDLE"));
685 SetLastError(ERROR_INVALID_HANDLE);
686 return FALSE;
687 }
688 }
689
690 if (cbCount == 0)
691 {
692 if (fuOptions & ETO_OPAQUE)
693 {
694 lpszString = " ";
695 cbCount = 1;
696 flOptions |= CHSOS_CLIP;
697 }
698 else {
699 dprintf(("InternalTextOutA: cbCount == 0"));
700 return TRUE;
701 }
702 }
703 if (lpDx)
704 flOptions |= CHSOS_VECTOR;
705
706 if (!getAlignUpdateCP(pHps))
707 {
708 ptl.x = X;
709 ptl.y = Y;
710
711#ifndef INVERT
712 if (pHps->yInvert > 0) {
713 ptl.y = pHps->yInvert - Y;
714 }
715#endif
716
717 flOptions |= CHSOS_LEAVEPOS;
718 }
719 else OSLibGpiQueryCurrentPosition(pHps,&ptl);
720
721 UINT align = GetTextAlign(hdc);
722 LONG pmHAlign,pmVAlign;
723
724 //CB: TA_RIGHT not supported by PM, only TA_CENTER and TA_LEFT
725 if ((align & 0x6) == TA_RIGHT)
726 {
727 PPOINTLOS2 pts = (PPOINTLOS2)malloc((cbCount+1)*sizeof(POINTLOS2));
728
729 OSLibGpiQueryCharStringPosAt(pHps,&ptl,flOptions,cbCount,lpszString,lpDx,pts);
730 ptl.x -= pts[cbCount].x-pts[0].x;
731 free(pts);
732 }
733
734 if (lprc && ((align & 0x18) == TA_BASELINE))
735 {
736 //CB: if TA_BASELINE is set, GPI doesn't fill rect
737 // TA_BOTTOM fills rect
738 OSLibGpiQueryTextAlignment(pHps,&pmHAlign,&pmVAlign);
739 OSLibGpiSetTextAlignment(pHps,pmHAlign,(pmVAlign & ~TAOS_BASE) | TAOS_BOTTOM);
740 }
741
742 ptl.y += getWorldYDeltaFor1Pixel(pHps);
743
744#ifndef INVERT
745 int vertAdjust = 0;
746 if ((pHps->taMode & 0x18) == TA_TOP)
747 {
748 vertAdjust = OSLibGpiQueryFontMaxHeight(pHps->hps);
749 }
750 ptl.y -= vertAdjust;
751#endif
752
753 hits = OSLibGpiCharStringPosAt(pHps,&ptl,&pmRect,flOptions,cbCount,lpszString,lpDx);
754
755 if (lprc && ((align & 0x18) == TA_BASELINE))
756 OSLibGpiSetTextAlignment(pHps,pmHAlign,pmVAlign);
757
758 if(hits == GPIOS_ERROR) {
759 dprintf(("InternalTextOutA: OSLibGpiCharStringPosAt returned GPIOS_ERROR"));
760 return FALSE;
761 }
762
763 if (getAlignUpdateCP(pHps))
764 {
765 OSLibGpiQueryCurrentPosition(pHps,&ptl);
766 ptl.y -= getWorldYDeltaFor1Pixel(pHps);
767#ifndef INVERT
768 ptl.y += vertAdjust;
769#endif
770 OSLibGpiSetCurrentPosition(pHps,&ptl);
771 }
772
773 return TRUE;
774}
775//******************************************************************************
776//******************************************************************************
777BOOL InternalTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCWSTR lpszString,INT cbCount,CONST INT *lpDx,BOOL IsExtTextOut)
778{
779 char *astring = NULL;
780 BOOL rc;
781
782 if(cbCount == -1) {
783 astring = UnicodeToAsciiString((LPWSTR)lpszString);
784 }
785 else
786 if(cbCount) {
787 astring = (char *)HEAP_malloc(cbCount+1);
788 UnicodeToAsciiN((LPWSTR)lpszString, astring, cbCount+1);
789 astring[cbCount] = 0;
790 }
791 rc = InternalTextOutA(hdc,X,Y,fuOptions,lprc,(LPCSTR)astring,cbCount,lpDx,IsExtTextOut);
792 if(astring) {
793 FreeAsciiString(astring);
794 }
795
796 return(rc);
797}
798//******************************************************************************
799//******************************************************************************
800BOOL WIN32API ExtTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,UINT cbCount,CONST INT *lpDx)
801{
802 if(lprc) {
803 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));
804 }
805 else dprintf(("GDI32: ExtTextOutA %x %s (%d,%d) %x %d %x", hdc, lpszString, X, Y, fuOptions, cbCount, lpDx));
806
807 return InternalTextOutA(hdc, X, Y, fuOptions, lprc, lpszString, cbCount, lpDx, TRUE);
808}
809//******************************************************************************
810//******************************************************************************
811BOOL WIN32API ExtTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCWSTR lpszString,UINT cbCount,CONST int *lpDx)
812{
813 if(lprc) {
814 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));
815 }
816 else dprintf(("GDI32: ExtTextOutW %x %ls (%d,%d) %x %d %x", hdc, lpszString, X, Y, fuOptions, cbCount, lpDx));
817 return InternalTextOutW(hdc, X, Y, fuOptions, lprc, lpszString, cbCount, lpDx, TRUE);
818}
819//******************************************************************************
820//******************************************************************************
821BOOL WIN32API TextOutA(HDC hdc,int nXStart,int nYStart,LPCSTR lpszString,int cbString)
822{
823 dprintf(("GDI32: TextOutA %x (%d,%d) %s", hdc, nXStart, nYStart, lpszString));
824
825 return InternalTextOutA(hdc,nXStart,nYStart,0,NULL,lpszString,cbString,NULL,FALSE);
826}
827//******************************************************************************
828//******************************************************************************
829BOOL WIN32API TextOutW(HDC hdc,int nXStart,int nYStart,LPCWSTR lpszString,int cbString)
830{
831 dprintf(("GDI32: TextOutW"));
832
833 return InternalTextOutW(hdc,nXStart,nYStart,0,NULL,lpszString,cbString,NULL,FALSE);
834}
835//******************************************************************************
836//******************************************************************************
837BOOL WIN32API PolyTextOutA(HDC hdc,POLYTEXTA *pptxt,int cStrings)
838{
839 dprintf(("GDI32: PolyTextOutA"));
840
841 for (INT x = 0;x < cStrings;x++)
842 {
843 BOOL rc;
844
845 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);
846 if (!rc) return FALSE;
847 }
848
849 return TRUE;
850}
851//******************************************************************************
852//******************************************************************************
853BOOL WIN32API PolyTextOutW(HDC hdc,POLYTEXTW *pptxt,int cStrings)
854{
855 dprintf(("GDI32: PolyTextOutW"));
856
857 for (INT x = 0;x < cStrings;x++)
858 {
859 BOOL rc;
860
861 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);
862 if (!rc) return FALSE;
863 }
864
865 return TRUE;
866}
867//******************************************************************************
868//******************************************************************************
869BOOL WIN32API GetTextExtentPointA(HDC hdc, LPCTSTR lpsz, int cbString,
870 LPSIZE lpsSize)
871{
872#if 1
873 //SvL: This works better than the code below. Can been seen clearly
874 // in the Settings dialog box of VirtualPC. Strings are clipped.
875 // (e.g.: Hard Disk 1 -> Hard Disk)
876 return O32_GetTextExtentPoint(hdc, lpsz, cbString, lpsSize);
877#else
878 BOOL rc;
879 POINTLOS2 pts[TXTBOXOS_COUNT];
880 POINTLOS2 widthHeight = { 0, 0};
881 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
882
883 dprintf(("GDI32: GetTextExtentPointA %s\n", lpsz));
884 if(pHps == NULL)
885 {
886 SetLastError(ERROR_INVALID_HANDLE);
887 return FALSE;
888 }
889
890 if(lpsz == NULL || cbString < 0 || lpsSize == NULL)
891 {
892 SetLastError(ERROR_INVALID_PARAMETER);
893 return FALSE;
894 }
895
896 lpsSize->cx = 0;
897 lpsSize->cy = 0;
898
899 // Verified with NT4, SP6
900 if(cbString == 0)
901 {
902 SetLastError(ERROR_SUCCESS);
903 return TRUE;
904 }
905 if(cbString > 512)
906 {
907 DWORD cbStringNew;
908 SIZE newSize;
909
910 dprintf(("WARNING: string longer than 512 chars; splitting up"));
911 lpsSize->cx = 0;
912 lpsSize->cy = 0;
913 while(cbString) {
914 cbStringNew = min(500, cbString);
915 rc = GetTextExtentPointA(hdc, lpsz, cbStringNew, &newSize);
916 if(rc == FALSE) {
917 return FALSE;
918 }
919 lpsSize->cx += newSize.cx;
920 lpsSize->cy = max(newSize.cy, lpsSize->cy);
921 lpsz += cbStringNew;
922 cbString -= cbStringNew;
923 }
924 return TRUE;
925 }
926
927 rc = OSLibGpiQueryTextBox(pHps, cbString, lpsz, TXTBOXOS_COUNT, pts);
928 if(rc == FALSE)
929 {
930 SetLastError(ERROR_INVALID_PARAMETER); //todo wrong error
931 return FALSE;
932 }
933 calcDimensions(pts, &widthHeight);
934 lpsSize->cx = widthHeight.x;
935 lpsSize->cy = widthHeight.y;
936
937 if(pHps && pHps->isPrinter && pHps->hdc)
938 {//scale for printer dcs
939 LONG alArray[2];
940
941 if (OSLibDevQueryCaps(pHps, OSLIB_CAPS_HORIZONTAL_RESOLUTION, 2, &alArray[0]))
942 lpsSize->cx = lpsSize->cx * alArray[0] / alArray[1];
943 }
944
945 dprintf(("GDI32: GetTextExtentPointA %x %s %d returned %d (%d,%d)", hdc, lpsz, cbString, rc, lpsSize->cx, lpsSize->cy));
946 SetLastError(ERROR_SUCCESS);
947 return TRUE;
948#endif
949}
950//******************************************************************************
951//******************************************************************************
952BOOL WIN32API GetTextExtentPointW(HDC hdc,
953 LPCWSTR lpString,
954 int cbString,
955 PSIZE lpSize)
956{
957 char *astring = UnicodeToAsciiString((LPWSTR)lpString);
958 BOOL rc;
959
960 dprintf(("GDI32: GetTextExtentPointW %s\n", astring));
961 lpSize->cx = lpSize->cy = 0;
962 rc = GetTextExtentPointA(hdc,
963 astring,
964 cbString,
965 lpSize);
966 FreeAsciiString(astring);
967 return(rc);
968}
969//******************************************************************************
970//******************************************************************************
971BOOL WIN32API GetTextExtentPoint32A( HDC hdc, LPCSTR lpsz, int cbString, PSIZE lpSize)
972{
973 BOOL rc;
974
975 dprintf(("GDI32: GetTextExtentPoint32A %s\n", lpsz));
976 lpSize->cx = lpSize->cy = 0;
977 rc = GetTextExtentPointA(hdc, lpsz, cbString, lpSize);
978 return rc;
979}
980//******************************************************************************
981//******************************************************************************
982BOOL WIN32API GetTextExtentPoint32W(HDC arg1, LPCWSTR arg2, int arg3, PSIZE lpSize)
983{
984 char *astring = UnicodeToAsciiString((LPWSTR)arg2);
985 BOOL rc;
986
987 dprintf(("GDI32: GetTextExtentPoint32W %s\n", astring));
988 rc = GetTextExtentPointA(arg1, astring, arg3, lpSize);
989 FreeAsciiString(astring);
990 return(rc);
991}
992//******************************************************************************
993//******************************************************************************
Note: See TracBrowser for help on using the repository browser.