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

Last change on this file since 3648 was 3648, checked in by sandervl, 25 years ago

added more logging

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