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

Last change on this file since 2092 was 2092, checked in by cbratschi, 26 years ago

text output API changes, line speed improvements

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