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

Last change on this file since 4365 was 4365, checked in by phaller, 25 years ago

Fixed possible bug in strrchr() call

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