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

Last change on this file since 2558 was 2558, checked in by sandervl, 26 years ago

Save and restore FPU control word when calling Open32's DrawText

File size: 21.5 KB
Line 
1/* $Id: text.cpp,v 1.7 2000-01-29 14:22:13 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 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
21#define ELLIPSIS "..."
22#define ELLIPSISLEN 3
23
24typedef struct _POLYTEXTA
25{
26 int x;
27 int y;
28 UINT n;
29 LPCSTR lpstr;
30 UINT uiFlags;
31 RECT rcl;
32 int *pdx;
33} POLYTEXTA;
34
35typedef struct _POLYTEXTW
36{
37 int x;
38 int y;
39 UINT n;
40 LPCWSTR lpstr;
41 UINT uiFlags;
42 RECT rcl;
43 int *pdx;
44} POLYTEXTW;
45
46//******************************************************************************
47//******************************************************************************
48UINT WINAPI GetTextCharsetInfo(
49 HDC hdc, /* [in] Handle to device context */
50 LPFONTSIGNATURE fs, /* [out] Pointer to struct to receive data */
51 DWORD flags) /* [in] Reserved - must be 0 */
52{
53 HGDIOBJ hFont;
54 UINT charSet = DEFAULT_CHARSET;
55 LOGFONTW lf;
56 CHARSETINFO csinfo;
57
58 dprintf(("GetTextCharsetInfo %x %x %x", hdc, fs, flags));
59
60 hFont = GetCurrentObject(hdc, OBJ_FONT);
61 if (hFont == 0)
62 return(DEFAULT_CHARSET);
63 if ( GetObjectW(hFont, sizeof(LOGFONTW), &lf) != 0 )
64 charSet = lf.lfCharSet;
65
66 if (fs != NULL) {
67 if (!TranslateCharsetInfo((LPDWORD)charSet, &csinfo, TCI_SRCCHARSET))
68 return (DEFAULT_CHARSET);
69 memcpy(fs, &csinfo.fs, sizeof(FONTSIGNATURE));
70 }
71 return charSet;
72}
73/***********************************************************************
74 * GetTextCharset32 [GDI32.226] Gets character set for font in DC
75 *
76 * NOTES
77 * Should it return a UINT32 instead of an INT32?
78 * => YES, as GetTextCharsetInfo returns UINT32
79 *
80 * RETURNS
81 * Success: Character set identifier
82 * Failure: DEFAULT_CHARSET
83 */
84UINT WINAPI GetTextCharset(HDC hdc) /* [in] Handle to device context */
85{
86 /* MSDN docs say this is equivalent */
87 return GetTextCharsetInfo(hdc, NULL, 0);
88}
89//******************************************************************************
90// CB: USER32 function, but here is the better place
91//******************************************************************************
92INT SYSTEM EXPORT InternalDrawTextExA(HDC hdc,LPCSTR lpchText,INT cchText,LPRECT lprc,UINT dwDTFormat,LPDRAWTEXTPARAMS lpDTParams,BOOL isDrawTextEx)
93{
94/*
95 PVOID pHps = OSLibGpiQueryDCData(hdc);
96 INT rc;
97 ULONG flCmd;
98 RECT localRectangle;
99 PRECT rectPtr;
100 LONG lTabs,xLeft,yTop;
101
102 if ((!lpchText) || (cchText == 0) || (cchText < -1) || (!lprc == NULL))
103 {
104 SetLastError(ERROR_INVALID_PARAMETER);
105 return 0;
106 }
107
108 if (!pHps)
109 {
110 SetLastError(ERROR_INVALID_HANDLE);
111 return 0;
112 }
113
114 if (cchText == -1)
115 {
116 cchText = strlen(lpchText);
117 if (cchText == 0)
118 return 0; //CB: does Win32 return textheight in this case?
119 }
120
121 if (lpDTParams)
122 {
123 // set margins
124 lprc->left += lpDTParams->iLeftMargin;
125 lprc->right -= lpDTParams->iRightMargin;
126
127 // just assume all the text has been drawn
128 lpDTParams->uiLengthDrawn = cchText;
129 }
130
131 if (!(dwDTFormat & DT_CALCRECT))
132 {
133 BOOL bTopBottomIsOkay;
134
135 if ((getIsTopTop(pHps) && lprc->top > lprc->bottom) ||
136 (!getIsTopTop(pHps) && lprc->top < lprc->bottom))
137 bTopBottomIsOkay = FALSE;
138 else
139 bTopBottomIsOkay = TRUE;
140
141 if ((lprc->left >= lprc->right) || !bTopBottomIsOkay)
142 {
143 TEXTMETRICA txtMetrics;
144 BOOL result;
145
146 result = GetTextMetricsA(hdc,&txtMetrics);
147 if (result)
148 rc = (int)txtMetrics.tmHeight;
149 else
150 rc = 0;
151
152 if (lpDTParams)
153 {
154 lprc->left -= lpDTParams->iLeftMargin;
155 lprc->right += lpDTParams->iRightMargin;
156 }
157
158 return rc;
159 }
160 }
161
162 flCmd = DTOS_INVERT | DTOS_WORLDRECT | DTOS_TEXTATTRS | DTOS_AMPERSAND | DTOS_VERTICALEXTENT;
163
164 LONG lMixMode = OSLibGpiQueryBackMix(pHps);
165 if (lMixMode == BMOS_OVERPAINT) flCmd |= DTOS_OPAQUE;
166
167 if (dwDTFormat & DT_CALCRECT)
168 {
169 rectPtr = lprc;
170 flCmd |= DTOS_QUERYEXTENT;
171
172 xLeft = rectPtr->left;
173 yTop = rectPtr->top;
174
175 if (dwDTFormat & DT_RIGHT)
176 {
177 if (rectPtr->left >= rectPtr->right)
178 rectPtr->left = rectPtr->right-1;
179 } else
180 {
181 if (rectPtr->right <= rectPtr->left)
182 rectPtr->right = rectPtr->left+1;
183 }
184
185 if (dwDTFormat & DT_BOTTOM)
186 {
187 if (rectPtr->top >= rectPtr->bottom)
188 rectPtr->top = rectPtr->bottom-1;
189 } else
190 {
191 if (rectPtr->bottom <= rectPtr->top)
192 rectPtr->bottom = rectPtr->top+1;
193 }
194 } else
195 {
196 rectPtr = &localRectangle;
197
198 if (getMapMode(pHps) == MMOS_ANISOTROPIC || getMapMode(pHps) == MMOS_ISOTROPIC)
199 {
200 if (doesYAxisGrowNorth(pHps))
201 {
202 flCmd &= ~DTOS_INVERT;
203 flCmd |= DTOS_INVERTCHAR;
204 }
205 }
206
207 if (lprc->left > lprc->right)
208 {
209 rectPtr->left = lprc->right;
210 rectPtr->right = lprc->left;
211 } else
212 {
213 rectPtr->left = lprc->left;
214 rectPtr->right = lprc->right;
215 }
216 if (lprc->top > lprc->bottom)
217 {
218 rectPtr->top = lprc->bottom;
219 rectPtr->bottom = lprc->top;
220 } else
221 {
222 rectPtr->top = lprc->top;
223 rectPtr->bottom = lprc->bottom;
224 }
225 }
226
227 if (dwDTFormat & DT_EXPANDTABS)
228 {
229 if (isDrawTextEx)
230 {
231 lTabs = (lpDTParams && dwDTFormat & DT_TABSTOP) ? lpDTParams->iTabLength:8;
232 } else
233 {
234 lTabs = 8;
235
236 if (dwDTFormat & DT_TABSTOP)
237 {
238 lTabs = (dwDTFormat >> 8) & 0x000000FF;
239 dwDTFormat &= 0xFFFF00FF;
240 }
241 }
242 } else lTabs = -1;
243
244 if (dwDTFormat & DT_RIGHT)
245 flCmd |= DTOS_RIGHT;
246 else
247 if (dwDTFormat & DT_CENTER) flCmd |= DTOS_CENTER;
248 if (dwDTFormat & DT_BOTTOM) flCmd |= DTOS_BOTTOM;
249 if (dwDTFormat & DT_VCENTER) flCmd |= DTOS_VCENTER;
250 if (dwDTFormat & DT_WORDBREAK) flCmd |= DTOS_WORDBREAK;
251 if (dwDTFormat & DT_EXTERNALLEADING) flCmd |= DTOS_EXTERNALLEADING;
252 if (!(dwDTFormat & DT_NOPREFIX)) flCmd |= DTOS_MNEMONIC;
253 if (dwDTFormat & DT_SINGLELINE)
254 flCmd |= DTOS_SINGLELINE;
255 else
256 flCmd |= DTOS_MULTILINE;
257 if (dwDTFormat & DT_NOCLIP) flCmd |= DTOS_NOCLIP;
258
259 //CB: DT_EDITCONTROL, DT_RTLREADING ignored
260
261 BOOL done = FALSE;
262
263 if ((dwDTFormat & DT_END_ELLIPSIS) && (cchText > 1))
264 {
265 int textWidth,width;
266 RECT rect;
267
268 SetRectEmpty(&rect);
269 OSLibWinDrawTabbedText(pHps,cchText,lTabs,lpchText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
270 width = rectPtr->right-rectPtr->left;
271 textWidth = rect.right-rect.left;
272 if ((textWidth > width) && (width > 0))
273 {
274 char* newText;
275 int newTextLen = cchText-1+ELLIPSISLEN;
276 int preLen = cchText-1;
277
278 newText = (char*)malloc(newTextLen+1);
279 strncpy(newText,lpchText,cchText-1);
280 do
281 {
282 strcpy(&newText[preLen],ELLIPSIS);
283 OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
284 textWidth = rect.right-rect.left;
285 if (textWidth <= width || preLen == 1) break;
286 newTextLen--;
287 preLen--;
288 } while (TRUE);
289 rc = OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,rectPtr,0,0,flCmd);
290 if (dwDTFormat & DT_MODIFYSTRING) strcpy((LPSTR)lpchText,newText); //check length?
291 free(newText);
292
293 done = TRUE;
294 }
295 } else if ((dwDTFormat & DT_PATH_ELLIPSIS) && (cchText > 1))
296 {
297 int textWidth,width;
298 RECT rect;
299
300//CB: code not yet checked (-> testcase)
301
302 SetRectEmpty(&rect);
303 OSLibWinDrawTabbedText(pHps,cchText,lTabs,lpchText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
304 width = rectPtr->right-rectPtr->left;
305 textWidth = rect.right-rect.left;
306 if ((textWidth > width) && (width > 0))
307 {
308 char *newText,*slashPos;
309 int newTextLen = cchText+ELLIPSISLEN;
310
311 newText = (char*)malloc(newTextLen+1);
312 strncpy(newText,lpchText,cchText);
313 slashPos = strrchr(newText,(int)"\\");
314 if (slashPos != NULL)
315 {
316 int preLen = slashPos-newText;
317 char* endPtr = (char*)lpchText+preLen;
318 int endLen = cchText-preLen;
319 BOOL ok = FALSE;
320
321 //delete start
322 do
323 {
324 strcpy(&newText[preLen],ELLIPSIS);
325 strncpy(&newText[preLen+ELLIPSISLEN],endPtr,endLen);
326 OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
327 textWidth = rect.right-rect.left;
328 if (textWidth <= width)
329 {
330 ok = TRUE;
331 break;
332 }
333 if (preLen == 0) break;
334 newTextLen--;
335 preLen--;
336 } while (TRUE);
337
338 if (!ok)
339 {
340 //delete end
341 do
342 {
343 endPtr++;
344 endLen--;
345 newTextLen--;
346 strncpy(&newText[ELLIPSISLEN],endPtr,endLen);
347 OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
348 textWidth = rect.right-rect.left;
349 if ((textWidth <= width) || (endLen == 0)) break;
350 } while (TRUE);
351 }
352 } else
353 {
354 int preLen,endLen;
355
356 preLen = cchText/2;
357 endLen = cchText-preLen; //endLen >= preLen
358 char* endPtr = (char*)lpchText+preLen;
359
360 do
361 {
362 strcpy(&newText[preLen],ELLIPSIS);
363 strncpy(&newText[preLen+ELLIPSISLEN],endPtr,endLen);
364 OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,&rect,0,0,flCmd | DTOS_QUERYEXTENT);
365 textWidth = rect.right-rect.left;
366 if ((textWidth <= width) || (preLen+endLen == 0)) break;
367 if (endLen > preLen)
368 {
369 endLen--;
370 endPtr++;
371 } else preLen--;
372 newTextLen--;
373 } while (TRUE);
374 }
375 rc = OSLibWinDrawTabbedText(pHps,newTextLen,lTabs,newText,rectPtr,0,0,flCmd);
376 if (dwDTFormat & DT_MODIFYSTRING) strcpy((LPSTR)lpchText,newText); //check length?
377 free(newText);
378
379 done = TRUE;
380 }
381 }
382
383 if (!done)
384 rc = OSLibWinDrawTabbedText(pHps,cchText,lTabs,lpchText,rectPtr,0,0,flCmd);
385
386 if (dwDTFormat & DT_CALCRECT)
387 {
388 if (!(dwDTFormat & DT_RIGHT) && (rectPtr->left < xLeft))
389 {
390 rectPtr->right = xLeft+(rectPtr->right-rectPtr->left);
391 rectPtr->left = xLeft;
392 }
393 if (!(dwDTFormat & DT_BOTTOM) && (rectPtr->top < yTop))
394 {
395 rectPtr->bottom = yTop+(rectPtr->bottom-rectPtr->top);
396 rectPtr->top = yTop;
397 }
398 }
399
400 if (lpDTParams)
401 {
402 // don't forget to restore the margins
403 lprc->left -= lpDTParams->iLeftMargin;
404 lprc->right += lpDTParams->iRightMargin;
405 }
406
407 return rc;
408*/
409 UINT fpuctrlword;
410 INT rc;
411
412 //SvL: Open32's DrawText messes up the fpu control word! (@#$@#$@#$)
413 fpuctrlword = _control87(0, 0);
414 dwDTFormat &= ~(DT_END_ELLIPSIS | DT_PATH_ELLIPSIS);
415
416 rc = O32_DrawText(hdc,lpchText,cchText,lprc,dwDTFormat);
417 _control87(fpuctrlword, 0xFFFF);
418 return rc;
419}
420//******************************************************************************
421//******************************************************************************
422INT SYSTEM EXPORT InternalDrawTextExW(HDC hdc,LPCWSTR lpchText,INT cchText,LPRECT lprc,UINT dwDTFormat,LPDRAWTEXTPARAMS lpDTParams,BOOL isDrawTextEx)
423{
424 char *astring = (cchText == -1) ? UnicodeToAsciiString((LPWSTR)lpchText):UnicodeToAsciiStringN((LPWSTR)lpchText,cchText);
425 INT rc;
426
427 rc = InternalDrawTextExA(hdc,astring,cchText,lprc,dwDTFormat,lpDTParams,isDrawTextEx);
428 if (dwDTFormat & DT_MODIFYSTRING && (dwDTFormat & (DT_END_ELLIPSIS | DT_PATH_ELLIPSIS))) AsciiToUnicode(astring,(LPWSTR)lpchText);
429 FreeAsciiString(astring);
430
431 return(rc);
432}
433//******************************************************************************
434// CB: USER32 function, but here is the better place
435//******************************************************************************
436DWORD SYSTEM EXPORT InternalGetTabbedTextExtentA(HDC hDC,LPCSTR lpString,INT nCount,INT nTabPositions,LPINT lpnTabStopPositions)
437{
438 PVOID pHps = OSLibGpiQueryDCData(hDC);
439 BOOL result;
440 POINTLOS2 pts[TXTBOXOS_COUNT];
441 POINTLOS2 widthHeight = {0,0};
442
443 if (!pHps || (nCount == 0) || (nTabPositions < 0))
444 return 0;
445
446 if (nCount < 0)
447 {
448 SetLastError(ERROR_STACK_OVERFLOW);
449 return 0;
450 }
451 if ((lpString == NULL) || (nCount > 512) || ((nTabPositions > 0) && (lpnTabStopPositions == NULL)))
452 {
453 SetLastError(ERROR_INVALID_PARAMETER);
454 return 0;
455 }
456 //CB: Win95 supports negative values for right aligned text
457 for (INT i = 0;i < nTabPositions;i++)
458 {
459 if (lpnTabStopPositions[i] < 0)
460 {
461 SetLastError(ERROR_INVALID_PARAMETER);
462 return 0;
463 }
464 }
465
466 result = OSLibGpiQueryTextBox(pHps,(nCount > 1) ? 1:nCount,lpString,TXTBOXOS_COUNT,pts);
467 if (result == FALSE)
468 return 0;
469 calcDimensions(pts,&widthHeight);
470
471 LONG rv1 = OSLibGpiQueryTabbedTextExtent(pHps,nCount,lpString,nTabPositions,lpnTabStopPositions);
472 if (rv1 == GPIOS_ERROR)
473 return 0;
474
475 return (widthHeight.y <<16)+labs(rv1);
476}
477//******************************************************************************
478//******************************************************************************
479DWORD SYSTEM EXPORT InternalGetTabbedTextExtentW(HDC hDC,LPCWSTR lpString,INT nCount,INT nTabPositions,LPINT lpnTabStopPositions)
480{
481 char *astring = (nCount == -1) ? UnicodeToAsciiString((LPWSTR)lpString):UnicodeToAsciiStringN((LPWSTR)lpString,nCount);
482 DWORD rc;
483
484 rc = InternalGetTabbedTextExtentA(hDC,astring,nCount,nTabPositions,lpnTabStopPositions);
485 FreeAsciiString(astring);
486
487 return(rc);
488}
489//******************************************************************************
490// CB: USER32 function, but here is the better place
491//******************************************************************************
492LONG SYSTEM EXPORT InternalTabbedTextOutA(HDC hdc,INT x,INT y,LPCSTR lpString,INT nCount,INT nTabPositions,LPINT lpnTabStopPositions,INT nTabOrigin)
493{
494 PVOID pHps = OSLibGpiQueryDCData(hdc);
495 POINTLOS2 ptl;
496 DWORD dimensions;
497
498 if ((pHps == NULL) || (lpString == NULL))
499 {
500 SetLastError(ERROR_INVALID_HANDLE);
501 return 0;
502 }
503 if (nCount == -1)
504 nCount = strlen(lpString);
505 if (nCount < 1)
506 {
507 SetLastError(ERROR_INVALID_HANDLE);
508 return 0;
509 }
510 if (lpnTabStopPositions == NULL)
511 nTabPositions = 0;
512 if (nTabPositions == 0)
513 lpnTabStopPositions = NULL;
514 if (nTabPositions < 0)
515 {
516 SetLastError(ERROR_INVALID_HANDLE);
517 return 0;
518 }
519 if (getAlignUpdateCP(pHps) == TRUE)
520 OSLibGpiQueryCurrentPosition(pHps,&ptl);
521 else
522 {
523 ptl.x = x;
524 ptl.y = y;
525 }
526
527 //CB: nTabOrigin is ignored! -> wrong size (width)!
528 // todo: change low word (width), height is ok
529 dimensions = InternalGetTabbedTextExtentA(hdc,lpString,nCount,nTabPositions,lpnTabStopPositions);
530 if (dimensions != 0)
531 {
532 LONG rcGPI;
533
534 ptl.y += getWorldYDeltaFor1Pixel(pHps);
535
536 rcGPI = OSLibGpiTabbedCharStringAt(pHps,&ptl,NULL,0,nCount,lpString,nTabPositions,lpnTabStopPositions,nTabOrigin);
537 if (rcGPI == GPIOS_ALTERROR)
538 return 0;
539 if (getAlignUpdateCP(pHps))
540 {
541 OSLibGpiQueryCurrentPosition (pHps,&ptl);
542 ptl.y -= getWorldYDeltaFor1Pixel(pHps);
543 OSLibGpiSetCurrentPosition (pHps,&ptl);
544 }
545
546 return dimensions;
547 }
548 return 0;
549}
550//******************************************************************************
551//******************************************************************************
552LONG SYSTEM EXPORT InternalTabbedTextOutW(HDC hdc,INT x,INT y,LPCWSTR lpString,INT nCount,INT nTabPositions,LPINT lpnTabStopPositions,INT nTabOrigin)
553{
554 char *astring = (nCount == -1) ? UnicodeToAsciiString((LPWSTR)lpString):UnicodeToAsciiStringN((LPWSTR)lpString,nCount);
555 LONG rc;
556
557 rc = InternalTabbedTextOutA(hdc,x,y,astring,nCount,nTabPositions,lpnTabStopPositions,nTabOrigin);
558 FreeAsciiString(astring);
559
560 return(rc);
561}
562//******************************************************************************
563// todo: metafile support
564//******************************************************************************
565BOOL InternalTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,INT cbCount,CONST INT *lpDx,BOOL IsExtTextOut)
566{
567 PVOID pHps = OSLibGpiQueryDCData(hdc);
568 ULONG flOptions = 0;
569 RECTLOS2 pmRect;
570 POINTLOS2 ptl;
571 LONG hits;
572
573 if (!pHps || (cbCount < 0) || ((lpszString == NULL) && (cbCount != 0)))
574 {
575 SetLastError(ERROR_INVALID_HANDLE);
576 return FALSE;
577 }
578
579 if (cbCount > 512)
580 {
581 SetLastError(ERROR_INVALID_PARAMETER);
582 return FALSE;
583 }
584 if (fuOptions & ~((UINT)(ETO_CLIPPED | ETO_OPAQUE)))
585 {
586 //ETO_GLYPH_INDEX, ETO_RTLLEADING, ETO_NUMERICSLOCAL, ETO_NUMERICSLATIN, ETO_IGNORELANGUAGE, ETO_PDY are ignored
587 return TRUE;
588 }
589
590 //CB: add metafile info
591
592 if (lprc)
593 {
594 if (fuOptions)
595 {
596 MapWin32ToOS2Rect(*lprc,pmRect);
597 if (excludeBottomRightPoint(pHps,(PPOINTLOS2)&pmRect) == 0)
598 {
599 return TRUE;
600 }
601
602 if (fuOptions & ETO_CLIPPED) flOptions |= CHSOS_CLIP;
603 if (fuOptions & ETO_OPAQUE) flOptions |= CHSOS_OPAQUE;
604 }
605 } else
606 {
607 if (fuOptions)
608 {
609 SetLastError(ERROR_INVALID_HANDLE);
610 return FALSE;
611 }
612 }
613
614 if (cbCount == 0)
615 {
616 if (fuOptions & ETO_OPAQUE)
617 {
618 lpszString = " ";
619 cbCount = 1;
620 flOptions |= CHSOS_CLIP;
621 } else return TRUE;
622 }
623 if (lpDx)
624 flOptions |= CHSOS_VECTOR;
625
626 if (!getAlignUpdateCP(pHps))
627 {
628 ptl.x = X;
629 ptl.y = Y;
630
631 flOptions |= CHSOS_LEAVEPOS;
632 } else OSLibGpiQueryCurrentPosition(pHps,&ptl);
633
634 UINT align = GetTextAlign(hdc);
635 LONG pmHAlign,pmVAlign;
636
637 //CB: TA_RIGHT not supported by PM, only TA_CENTER and TA_LEFT
638 if ((align & 0x6) == TA_RIGHT)
639 {
640 PPOINTLOS2 pts = (PPOINTLOS2)malloc((cbCount+1)*sizeof(POINTLOS2));
641
642 OSLibGpiQueryCharStringPosAt(pHps,&ptl,flOptions,cbCount,lpszString,lpDx,pts);
643 ptl.x -= pts[cbCount].x-pts[0].x;
644 free(pts);
645 }
646
647 if (lprc && ((align & 0x18) == TA_BASELINE))
648 {
649 //CB: if TA_BASELINE is set, GPI doesn't fill rect
650 // TA_BOTTOM fills rect
651 OSLibGpiQueryTextAlignment(pHps,&pmHAlign,&pmVAlign);
652 OSLibGpiSetTextAlignment(pHps,pmHAlign,(pmVAlign & ~TAOS_BASE) | TAOS_BOTTOM);
653 }
654
655 ptl.y += getWorldYDeltaFor1Pixel(pHps);
656
657 hits = OSLibGpiCharStringPosAt(pHps,&ptl,&pmRect,flOptions,cbCount,lpszString,lpDx);
658
659 if (lprc && ((align & 0x18) == TA_BASELINE))
660 OSLibGpiSetTextAlignment(pHps,pmHAlign,pmVAlign);
661
662 if (hits == GPIOS_ERROR)
663 return FALSE;
664
665 if (getAlignUpdateCP(pHps))
666 {
667 OSLibGpiQueryCurrentPosition(pHps,&ptl);
668 ptl.y -= getWorldYDeltaFor1Pixel(pHps);
669 OSLibGpiSetCurrentPosition(pHps,&ptl);
670 }
671
672 return TRUE;
673}
674//******************************************************************************
675//******************************************************************************
676BOOL InternalTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCWSTR lpszString,INT cbCount,CONST INT *lpDx,BOOL IsExtTextOut)
677{
678 char *astring = (cbCount == -1) ? UnicodeToAsciiString((LPWSTR)lpszString):UnicodeToAsciiStringN((LPWSTR)lpszString,cbCount);
679 BOOL rc;
680
681 rc = InternalTextOutA(hdc,X,Y,fuOptions,lprc,(LPCSTR)astring,cbCount,lpDx,IsExtTextOut);
682 FreeAsciiString(astring);
683
684 return(rc);
685}
686//******************************************************************************
687//******************************************************************************
688BOOL WIN32API ExtTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,UINT cbCount,CONST INT *lpDx)
689{
690 dprintf(("GDI32: ExtTextOutA\n"));
691
692 return InternalTextOutA(hdc,X,Y,fuOptions,lprc,lpszString,cbCount,lpDx,TRUE);
693}
694//******************************************************************************
695//******************************************************************************
696BOOL WIN32API ExtTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCWSTR lpszString,UINT cbCount,CONST int *lpDx)
697{
698 dprintf(("GDI32: ExtTextOutW\n"));
699
700 return InternalTextOutW(hdc,X,Y,fuOptions,lprc,lpszString,cbCount,lpDx,TRUE);
701}
702//******************************************************************************
703//******************************************************************************
704BOOL WIN32API TextOutA(HDC hdc,int nXStart,int nYStart,LPCSTR lpszString,int cbString)
705{
706 dprintf(("GDI32: TextOutA"));
707
708 return InternalTextOutA(hdc,nXStart,nYStart,0,NULL,lpszString,cbString,NULL,FALSE);
709}
710//******************************************************************************
711//******************************************************************************
712BOOL WIN32API TextOutW(HDC hdc,int nXStart,int nYStart,LPCWSTR lpszString,int cbString)
713{
714 dprintf(("GDI32: TextOutW"));
715
716 return InternalTextOutW(hdc,nXStart,nYStart,0,NULL,lpszString,cbString,NULL,FALSE);
717}
718//******************************************************************************
719//******************************************************************************
720BOOL WIN32API PolyTextOutA(HDC hdc,POLYTEXTA *pptxt,int cStrings)
721{
722 dprintf(("GDI32: PolyTextOutA"));
723
724 for (INT x = 0;x < cStrings;x++)
725 {
726 BOOL rc;
727
728 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);
729 if (!rc) return FALSE;
730 }
731
732 return TRUE;
733}
734//******************************************************************************
735//******************************************************************************
736BOOL WIN32API PolyTextOutW(HDC hdc,POLYTEXTW *pptxt,int cStrings)
737{
738 dprintf(("GDI32: PolyTextOutW"));
739
740 for (INT x = 0;x < cStrings;x++)
741 {
742 BOOL rc;
743
744 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);
745 if (!rc) return FALSE;
746 }
747
748 return TRUE;
749}
Note: See TracBrowser for help on using the repository browser.