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

Last change on this file since 10374 was 10374, checked in by sandervl, 22 years ago

Update

File size: 24.0 KB
Line 
1/* $Id: text.cpp,v 1.40 2004-01-11 11:42:22 sandervl Exp $ */
2
3/*
4 * GDI32 text apis
5 *
6 * Based on Wine/ReWind code (objects\text.c, objects\font.c)
7 *
8 * Copyright 1993, 1994 Alexandre Julliard
9 * 1997 Alex Korobka
10 *
11 * Copyright 1999-2000 Christoph Bratschi
12 * Copyright 2002-2003 Innotek Systemberatung GmbH (sandervl@innotek.de)
13 *
14 * Project Odin Software License can be found in LICENSE.TXT
15 *
16 */
17#include <os2win.h>
18#include <stdlib.h>
19#include <stdio.h>
20#include <misc.h>
21#include <string.h>
22#include <float.h>
23#include "oslibgpi.h"
24#include <dcdata.h>
25#include <unicode.h>
26#include "dibsect.h"
27#include "ft2supp.h"
28#include "font.h"
29
30#define DBG_LOCALLOG DBG_text
31#include "dbglocal.h"
32
33#define ELLIPSIS "..."
34#define ELLIPSISLEN 3
35
36//******************************************************************************
37//******************************************************************************
38UINT WINAPI GetTextCharsetInfo(
39 HDC hdc, /* [in] Handle to device context */
40 LPFONTSIGNATURE fs, /* [out] Pointer to struct to receive data */
41 DWORD flags) /* [in] Reserved - must be 0 */
42{
43 HGDIOBJ hFont;
44 UINT charSet = DEFAULT_CHARSET;
45 LOGFONTW lf;
46 CHARSETINFO csinfo;
47
48 dprintf(("GetTextCharsetInfo %x %x %x", hdc, fs, flags));
49
50 hFont = GetCurrentObject(hdc, OBJ_FONT);
51 if (hFont == 0)
52 return(DEFAULT_CHARSET);
53 if ( GetObjectW(hFont, sizeof(LOGFONTW), &lf) != 0 )
54 charSet = lf.lfCharSet;
55
56 if (fs != NULL) {
57 if (!TranslateCharsetInfo((LPDWORD)charSet, &csinfo, TCI_SRCCHARSET))
58 return (DEFAULT_CHARSET);
59 memcpy(fs, &csinfo.fs, sizeof(FONTSIGNATURE));
60 }
61 return charSet;
62}
63/***********************************************************************
64 * GetTextCharset32 [GDI32.226] Gets character set for font in DC
65 *
66 * NOTES
67 * Should it return a UINT32 instead of an INT32?
68 * => YES, as GetTextCharsetInfo returns UINT32
69 *
70 * RETURNS
71 * Success: Character set identifier
72 * Failure: DEFAULT_CHARSET
73 */
74UINT WINAPI GetTextCharset(HDC hdc) /* [in] Handle to device context */
75{
76 /* MSDN docs say this is equivalent */
77 return GetTextCharsetInfo(hdc, NULL, 0);
78}
79//******************************************************************************
80// todo: metafile support
81//#undef INVERT
82//#define INVERT_SETYINVERSION
83//******************************************************************************
84BOOL InternalTextOutAW(HDC hdc,int X,int Y,UINT fuOptions,
85 CONST RECT *lprc, LPCSTR lpszStringA, LPCWSTR lpszStringW,
86 INT cbCount,CONST INT *lpDx,BOOL IsExtTextOut, BOOL fUnicode)
87{
88 pDCData pHps = (pDCData)OSLibGpiQueryDCData(hdc);
89 ULONG flOptions = 0;
90 RECTLOS2 pmRect;
91 POINTLOS2 ptl;
92 LONG hits;
93
94 if (!pHps || (cbCount < 0) || (((lpszStringA == NULL && !fUnicode) || (lpszStringW == NULL && fUnicode)) && (cbCount != 0)))
95 {
96 dprintf(("InternalTextOutA: invalid parameter"));
97 SetLastError(ERROR_INVALID_HANDLE);
98 return FALSE;
99 }
100
101 if(cbCount == -1) {
102 if(fUnicode)
103 cbCount = lstrlenW(lpszStringW);
104 else cbCount = lstrlenA(lpszStringA);
105 }
106
107 if (cbCount > 512)
108 {
109 dprintf(("InternalTextOutA: invalid parameter cbCount"));
110 SetLastError(ERROR_INVALID_PARAMETER);
111 return FALSE;
112 }
113 if (fuOptions & ~((UINT)(ETO_CLIPPED | ETO_OPAQUE | ETO_GLYPH_INDEX)))
114 {
115 dprintf(("InternalTextOutA: invalid fuOptions"));
116 //ETO_GLYPH_INDEX, ETO_RTLLEADING, ETO_NUMERICSLOCAL, ETO_NUMERICSLATIN, ETO_IGNORELANGUAGE, ETO_PDY are ignored
117 return TRUE;
118 }
119
120#if defined(INVERT) && !defined(INVERT_SETYINVERSION)
121 if(pHps->yInvert > 0) {
122 Y = pHps->yInvert - Y;
123 }
124#endif
125
126#ifdef INVERT_SETYINVERSION
127 int oldyinv = GpiQueryYInversion(pHps->hps);
128 Y = oldyinv - Y;
129#endif
130
131 //CB: add metafile info
132
133 if (lprc)
134 {
135 if (fuOptions)
136 {
137 MapWin32ToOS2Rect(*lprc,pmRect);
138 if (excludeBottomRightPoint(pHps,(PPOINTLOS2)&pmRect) == 0)
139 {
140 dprintf(("InternalTextOutA: excludeBottomRightPoint returned 0"));
141 return TRUE;
142 }
143#ifndef INVERT
144#ifdef INVERT_SETYINVERSION
145 if (oldyinv) {
146 int temp = oldyinv - pmRect.yTop;
147 pmRect.yTop = oldyinv - pmRect.yBottom;
148 pmRect.yBottom = temp;
149 }
150#else
151 if (pHps->yInvert > 0) {
152 int temp = pHps->yInvert - pmRect.yTop;
153 pmRect.yTop = pHps->yInvert - pmRect.yBottom;
154 pmRect.yBottom = temp;
155 }
156#endif
157#endif
158
159 if (fuOptions & ETO_CLIPPED) flOptions |= CHSOS_CLIP;
160 if (fuOptions & ETO_OPAQUE) flOptions |= CHSOS_OPAQUE;
161 }
162 }
163 else
164 {
165 if (fuOptions & ~ETO_GLYPH_INDEX)
166 {
167 dprintf(("InternalTextOutA: ERROR_INVALID_PARAMETER"));
168 SetLastError(ERROR_INVALID_PARAMETER);
169 return FALSE;
170 }
171 }
172
173 if((lpszStringA || lpszStringW) && cbCount) {
174 DIBSECTION_CHECK_IF_DIRTY(hdc);
175 }
176
177 if (cbCount == 0)
178 {
179 if (fuOptions & ETO_OPAQUE)
180 {
181//SvL: This doesn't seem to work (anymore). Look at MFC apps for the missing border
182// between menu & button bar (all white). (e.g. odin app & acrobat reader 4.05)
183#if 0
184 lpszString = " ";
185 cbCount = 1;
186 flOptions |= CHSOS_CLIP;
187#else
188 HBRUSH hbrush = CreateSolidBrush(GetBkColor(hdc));
189 HBRUSH oldbrush;
190
191 oldbrush = SelectObject(hdc, hbrush);
192 FillRect(hdc, lprc, hbrush);
193 SelectObject(hdc, oldbrush);
194 DeleteObject(hbrush);
195
196 DIBSECTION_MARK_INVALID(hdc);
197
198 return TRUE;
199#endif
200 }
201 else {
202 dprintf(("InternalTextOutA: cbCount == 0"));
203 return TRUE;
204 }
205 }
206
207#ifdef INVERT_SETYINVERSION
208 GpiEnableYInversion(pHps->hps, 0);
209#endif
210
211 if (lpDx)
212 flOptions |= CHSOS_VECTOR;
213
214 if (!getAlignUpdateCP(pHps))
215 {
216 ptl.x = X;
217 ptl.y = Y;
218
219 flOptions |= CHSOS_LEAVEPOS;
220 }
221 else OSLibGpiQueryCurrentPosition(pHps,&ptl);
222
223 UINT align = GetTextAlign(hdc);
224 LONG pmHAlign,pmVAlign;
225
226#if 0
227 //SvL: This code is broken. TODO: Investigate
228 //CB: TA_RIGHT not supported by PM, only TA_CENTER and TA_LEFT
229 if ((align & 0x6) == TA_RIGHT)
230 {
231 BOOL rc;
232 PPOINTLOS2 pts = (PPOINTLOS2)malloc((cbCount+1)*sizeof(POINTLOS2));
233
234 rc = OSLibGpiQueryCharStringPosAt(pHps,&ptl,flOptions & CHSOS_VECTOR,cbCount,lpszString,lpDx,pts);
235 if(rc) {
236 for(int i=0;i<cbCount+1;i++) {
237 dprintf(("OSLibGpiQueryCharStringPosAt %d (%d,%d)", pts[i].x, pts[i].y));
238 }
239 ptl.x -= pts[cbCount].x-pts[0].x;
240 }
241 free(pts);
242 }
243#endif
244
245 if (lprc && ((align & 0x18) == TA_BASELINE))
246 {
247 //CB: if TA_BASELINE is set, GPI doesn't fill rect
248 // TA_BOTTOM fills rect
249 OSLibGpiQueryTextAlignment(pHps,&pmHAlign,&pmVAlign);
250 OSLibGpiSetTextAlignment(pHps,pmHAlign,(pmVAlign & ~TAOS_BASE) | TAOS_BOTTOM);
251 }
252
253#ifdef INVERT
254 ptl.y += getWorldYDeltaFor1Pixel(pHps);
255#else
256 ptl.y -= getWorldYDeltaFor1Pixel(pHps);
257
258 int vertAdjust = 0;
259 if ((pHps->taMode & 0x18) != TA_TOP)
260 {
261 vertAdjust = OSLibGpiQueryFontMaxHeight(pHps->hps);
262 }
263 ptl.y -= vertAdjust;
264#endif
265
266 if(fUnicode)
267 hits = FT2Module.Ft2CharStringPosAtW(pHps->hps,&ptl,&pmRect,flOptions,cbCount,lpszStringW,lpDx, fuOptions & ETO_GLYPH_INDEX);
268 else hits = FT2Module.Ft2CharStringPosAtA(pHps->hps,&ptl,&pmRect,flOptions,cbCount,lpszStringA,lpDx, fuOptions & ETO_GLYPH_INDEX);
269
270 if (lprc && ((align & 0x18) == TA_BASELINE))
271 OSLibGpiSetTextAlignment(pHps,pmHAlign,pmVAlign);
272
273 if(hits == GPIOS_ERROR) {
274 dprintf(("InternalTextOutA: OSLibGpiCharStringPosAt returned GPIOS_ERROR"));
275#ifdef INVERT_SETYINVERSION
276 GpiEnableYInversion(pHps->hps, oldyinv);
277#endif
278 return FALSE;
279 }
280
281 if (getAlignUpdateCP(pHps))
282 {
283 OSLibGpiQueryCurrentPosition(pHps,&ptl);
284 ptl.y -= getWorldYDeltaFor1Pixel(pHps);
285#ifndef INVERT
286 ptl.y += vertAdjust;
287#endif
288 OSLibGpiSetCurrentPosition(pHps,&ptl);
289 }
290
291#ifdef INVERT_SETYINVERSION
292 GpiEnableYInversion(pHps->hps, oldyinv);
293#endif
294
295 DIBSECTION_MARK_INVALID(hdc);
296
297 return TRUE;
298}
299//******************************************************************************
300//******************************************************************************
301BOOL WIN32API ExtTextOutA(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCSTR lpszString,UINT cbCount,CONST INT *lpDx)
302{
303 BOOL rc;
304 SIZE size;
305 int newy;
306
307 if(lprc)
308 {
309 dprintf(("GDI32: ExtTextOutA %x %.*s (%d,%d) %x %d %x rect (%d,%d)(%d,%d)", hdc, cbCount, lpszString, X, Y, fuOptions, cbCount, lpDx, lprc->left, lprc->top, lprc->right, lprc->bottom));
310 }
311 else dprintf(("GDI32: ExtTextOutA %x %.*s (%d,%d) %x %d %x", hdc, cbCount, lpszString, X, Y, fuOptions, cbCount, lpDx));
312
313 rc = InternalTextOutAW(hdc, X, Y, fuOptions, lprc, lpszString, NULL, cbCount, lpDx, TRUE, FALSE);
314
315 return(rc);
316}
317//******************************************************************************
318//******************************************************************************
319BOOL WIN32API ExtTextOutW(HDC hdc,int X,int Y,UINT fuOptions,CONST RECT *lprc,LPCWSTR lpszString,UINT cbCount,CONST int *lpDx)
320{
321 if(lprc) {
322 dprintf(("GDI32: ExtTextOutW %x %.*ls (%d,%d) %x %d %x rect (%d,%d)(%d,%d)", hdc, cbCount, lpszString, X, Y, fuOptions, cbCount, lpDx, lprc->left, lprc->top, lprc->right, lprc->bottom));
323 }
324 else dprintf(("GDI32: ExtTextOutW %x %.*ls (%d,%d) %x %d %x", hdc, cbCount, lpszString, X, Y, fuOptions, cbCount, lpDx));
325
326 return InternalTextOutAW(hdc, X, Y, fuOptions, lprc, NULL, lpszString, cbCount, lpDx, TRUE, TRUE);
327}
328//******************************************************************************
329//******************************************************************************
330BOOL WIN32API TextOutA(HDC hdc,int nXStart,int nYStart,LPCSTR lpszString,int cbString)
331{
332 dprintf(("GDI32: TextOutA %x (%d,%d) %d %.*s", hdc, nXStart, nYStart, cbString, cbString, lpszString));
333 return InternalTextOutAW(hdc,nXStart,nYStart,0,NULL,lpszString,NULL,cbString,NULL,FALSE, FALSE);
334}
335//******************************************************************************
336//******************************************************************************
337BOOL WIN32API TextOutW(HDC hdc,int nXStart,int nYStart,LPCWSTR lpszString,int cbString)
338{
339 dprintf(("GDI32: TextOutW %x (%d,%d) %d %.*ls", hdc, nXStart, nYStart, cbString, cbString, lpszString));
340 return InternalTextOutAW(hdc,nXStart,nYStart,0,NULL, NULL, lpszString,cbString,NULL,FALSE, TRUE);
341}
342//******************************************************************************
343//******************************************************************************
344BOOL WIN32API PolyTextOutA(HDC hdc,POLYTEXTA *pptxt,int cStrings)
345{
346 dprintf(("GDI32: PolyTextOutA %x %x %d", hdc, pptxt, cStrings));
347
348 for (INT x = 0;x < cStrings;x++)
349 {
350 BOOL rc;
351
352 rc = ExtTextOutA(hdc,pptxt[x].x,pptxt[x].y,pptxt[x].uiFlags,&pptxt[x].rcl,pptxt[x].lpstr, pptxt[x].n,pptxt[x].pdx);
353 if (!rc) return FALSE;
354 }
355
356 return TRUE;
357}
358//******************************************************************************
359//******************************************************************************
360BOOL WIN32API PolyTextOutW(HDC hdc,POLYTEXTW *pptxt,int cStrings)
361{
362 dprintf(("GDI32: PolyTextOutW %x %x %d", hdc, pptxt, cStrings));
363
364 for (INT x = 0;x < cStrings;x++)
365 {
366 BOOL rc;
367
368 rc = ExtTextOutW(hdc,pptxt[x].x,pptxt[x].y,pptxt[x].uiFlags,&pptxt[x].rcl, pptxt[x].lpstr,pptxt[x].n,pptxt[x].pdx);
369 if (!rc) return FALSE;
370 }
371
372 return TRUE;
373}
374//******************************************************************************
375// Note: GetTextExtentPoint behaves differently under certain circumstances
376// compared to GetTextExtentPoint32 (due to bugs).
377// We are treating both as the same thing which is not entirely correct.
378//
379//******************************************************************************
380BOOL WIN32API GetTextExtentPointA(HDC hdc, LPCTSTR lpsz, int cbString,
381 LPSIZE lpsSize)
382{
383 BOOL ret = FALSE;
384 INT wlen;
385 LPWSTR p = FONT_mbtowc(hdc, lpsz, cbString, &wlen, NULL);
386 if (p) {
387 ret = GetTextExtentPointW( hdc, p, wlen, lpsSize );
388 HeapFree( GetProcessHeap(), 0, p );
389 }
390 else DebugInt3();
391 return ret;
392}
393//******************************************************************************
394//******************************************************************************
395BOOL WIN32API GetTextExtentPointW(HDC hdc,
396 LPCWSTR lpString,
397 int cbString,
398 PSIZE lpSize)
399{
400 BOOL rc;
401 POINTLOS2 pts[TXTBOXOS_COUNT];
402 POINTLOS2 widthHeight = { 0, 0};
403 pDCData pHps = (pDCData)OSLibGpiQueryDCData((HPS)hdc);
404
405 dprintf(("GDI32: GetTextExtentPointW %ls", lpString));
406 if(pHps == NULL)
407 {
408 SetLastError(ERROR_INVALID_HANDLE);
409 return FALSE;
410 }
411
412 if(lpString == NULL || cbString < 0 || lpSize == NULL)
413 {
414 SetLastError(ERROR_INVALID_PARAMETER);
415 return FALSE;
416 }
417
418 lpSize->cx = 0;
419 lpSize->cy = 0;
420
421 // Verified with NT4, SP6
422 if(cbString == 0)
423 {
424 dprintf(("!WARNING!: GDI32: GetTextExtentPointW invalid parameter!"));
425 SetLastError(ERROR_SUCCESS);
426 return TRUE;
427 }
428
429 if(pHps->isPrinter)
430 ReallySetCharAttrs(pHps);
431
432 if(cbString > 512)
433 {
434 DWORD cbStringNew;
435 SIZE newSize;
436
437 dprintf(("WARNING: string longer than 512 chars; splitting up"));
438 lpSize->cx = 0;
439 lpSize->cy = 0;
440 while(cbString) {
441 cbStringNew = min(500, cbString);
442 rc = GetTextExtentPointW(hdc, lpString, cbStringNew, &newSize);
443 if(rc == FALSE) {
444 return FALSE;
445 }
446 lpSize->cx += newSize.cx;
447 lpSize->cy = max(newSize.cy, lpSize->cy);
448 lpString += cbStringNew;
449 cbString -= cbStringNew;
450 }
451 return TRUE;
452 }
453
454 rc = FT2Module.Ft2GetTextExtentW(pHps->hps, cbString, lpString, TXTBOXOS_COUNT, pts);
455 if(rc == FALSE)
456 {
457 SetLastError(ERROR_INVALID_PARAMETER); //todo wrong error
458 return FALSE;
459 }
460 calcDimensions(pts, &widthHeight);
461 lpSize->cx = widthHeight.x;
462 lpSize->cy = widthHeight.y;
463
464 if(pHps && pHps->isPrinter && pHps->hdc)
465 {//scale for printer dcs
466 LONG alArray[2];
467
468 if(OSLibDevQueryCaps(pHps, OSLIB_CAPS_HORIZONTAL_RESOLUTION, 2, &alArray[0]))
469 lpSize->cx = lpSize->cx * alArray[0] / alArray[1];
470 }
471
472 dprintf(("GDI32: GetTextExtentPointW %x %ls %d returned %d (%d,%d)", hdc, lpString, cbString, rc, lpSize->cx, lpSize->cy));
473 SetLastError(ERROR_SUCCESS);
474 return TRUE;
475}
476//******************************************************************************
477//******************************************************************************
478BOOL WIN32API GetTextExtentPoint32A( HDC hdc, LPCSTR lpsz, int cbString, PSIZE lpSize)
479{
480 return GetTextExtentPointA(hdc, lpsz, cbString, lpSize);
481}
482//******************************************************************************
483//******************************************************************************
484BOOL WIN32API GetTextExtentPoint32W(HDC hdc, LPCWSTR lpsz, int cbString, PSIZE lpSize)
485{
486 return GetTextExtentPointW(hdc, lpsz, cbString, lpSize);
487}
488//******************************************************************************
489//******************************************************************************
490BOOL WIN32API GetTextExtentExPointA(HDC hdc,
491 LPCSTR str,
492 int count,
493 int maxExt,
494 LPINT lpnFit,
495 LPINT alpDx,
496 LPSIZE size)
497{
498 BOOL ret;
499 INT wlen;
500 LPWSTR p = FONT_mbtowc( hdc, str, count, &wlen, NULL);
501 ret = GetTextExtentExPointW( hdc, p, wlen, maxExt, lpnFit, alpDx, size);
502 if (lpnFit) *lpnFit = WideCharToMultiByte(CP_ACP,0,p,*lpnFit,NULL,0,NULL,NULL);
503 if( IsDBCSEnv() && alpDx ) /* index of alpDx between ansi and wide may not match in DBCS !!! */
504 {
505 LPINT alpDxNew = ( LPINT )HeapAlloc( GetProcessHeap(), 0, sizeof( alpDx[ 0 ] ) * *lpnFit );
506 int i, j;
507
508 for( i = j = 0; i < *lpnFit; i++, j++ )
509 {
510 if( IsDBCSLeadByte( str[ i ]))
511 {
512 alpDxNew[ i++ ] = alpDx[ j ] >> 1;
513 if( i < *lpnFit )
514 alpDxNew[ i ] = alpDx[ j ] >> 1;
515 }
516 else
517 alpDxNew[ i ] = alpDx[ j ];
518
519 }
520
521 memcpy( alpDx, alpDxNew, sizeof( alpDx[ 0 ] ) * *lpnFit );
522
523 HeapFree( GetProcessHeap(), 0, alpDxNew );
524 }
525 HeapFree( GetProcessHeap(), 0, p );
526 return ret;
527}
528//******************************************************************************
529//******************************************************************************
530BOOL WIN32API GetTextExtentExPointW(HDC hdc,
531 LPCWSTR str,
532 int count,
533 int maxExt,
534 LPINT lpnFit,
535 LPINT alpDx,
536 LPSIZE size)
537{
538 int index, nFit, extent;
539 SIZE tSize;
540 BOOL ret = FALSE;
541
542 size->cx = size->cy = nFit = extent = 0;
543 for(index = 0; index < count; index++)
544 {
545 if(!GetTextExtentPoint32W( hdc, str, 1, &tSize )) goto done;
546 /* GetTextExtentPoint includes intercharacter spacing. */
547 /* FIXME - justification needs doing yet. Remember that the base
548 * data will not be in logical coordinates.
549 */
550 extent += tSize.cx;
551 if( !lpnFit || extent <= maxExt )
552 /* It is allowed to be equal. */
553 {
554 nFit++;
555 if( alpDx ) alpDx[index] = extent;
556 }
557 if( tSize.cy > size->cy ) size->cy = tSize.cy;
558 str++;
559 }
560 size->cx = extent;
561 if(lpnFit) *lpnFit = nFit;
562 ret = TRUE;
563
564 dprintf(("returning %d %ld x %ld\n",nFit,size->cx,size->cy));
565
566done:
567 return ret;
568}
569//******************************************************************************
570//******************************************************************************
571BOOL WIN32API GetCharWidth32A( HDC hdc, UINT iFirstChar, UINT iLastChar, PINT pWidthArray)
572{
573 BOOL ret = FALSE;
574
575 for (int i = iFirstChar; i <= iLastChar; i++)
576 {
577 SIZE size;
578 CHAR c = i;
579
580 if (GetTextExtentPointA(hdc, &c, 1, &size))
581 {
582 pWidthArray[i-iFirstChar] = size.cx;
583 // at least one character was processed
584 ret = TRUE;
585 }
586 else
587 {
588 // default value for unprocessed characters
589 pWidthArray[i-iFirstChar] = 0;
590 }
591
592 dprintf2(("Char 0x%x('%c') -> width %d", i, i<256? i: '.', pWidthArray[i-iFirstChar]));
593 }
594
595 return ret;
596}
597//******************************************************************************
598//******************************************************************************
599BOOL WIN32API GetCharWidth32W(HDC hdc, UINT iFirstChar, UINT iLastChar, PINT pWidthArray)
600{
601 BOOL ret = FALSE;
602
603 for (int i = iFirstChar; i <= iLastChar; i++)
604 {
605 SIZE size;
606 WCHAR wc = i;
607
608 if (GetTextExtentPointW(hdc, &wc, 1, &size))
609 {
610 pWidthArray[i-iFirstChar] = size.cx;
611 // at least one character was processed
612 ret = TRUE;
613 }
614 else
615 {
616 // default value for unprocessed characters
617 pWidthArray[i-iFirstChar] = 0;
618 }
619
620 dprintf2(("Char 0x%x('%c') -> width %d", i, i<256? i: '.', pWidthArray[i-iFirstChar]));
621 }
622
623 return ret;
624}
625//******************************************************************************
626// GetStringWidthW
627//
628// Return the width of each character in the string
629//
630// Parameters:
631// HDC hdc - device context handle
632// LPWSTR lpszString - unicod string pointer
633// UINT cbString - number of valid characters in string
634// PINT pWidthArray - array that receives the character width (must be
635// large enough to contain cbString elements
636//
637// Returns:
638// FALSE - failure
639// TRUE - success
640//
641//******************************************************************************
642BOOL WIN32API GetStringWidthW(HDC hdc, LPWSTR lpszString, UINT cbString, PINT pWidthArray)
643{
644 return FT2Module.Ft2GetStringWidthW(hdc, lpszString, cbString, pWidthArray);
645}
646//******************************************************************************
647//******************************************************************************
648BOOL WIN32API GetCharWidthFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar, PFLOAT pxBUffer)
649{
650 dprintf(("ERROR: GDI32: GetCharWidthFloatA, not implemented\n"));
651 DebugInt3();
652 return(FALSE);
653}
654//******************************************************************************
655//******************************************************************************
656BOOL WIN32API GetCharWidthFloatW(HDC hdc, UINT iFirstChar, UINT iLastChar, PFLOAT pxBUffer)
657{
658 dprintf(("ERROR: GDI32: GetCharWidthFloatW, not implemented\n"));
659 DebugInt3();
660 return(FALSE);
661}
662//******************************************************************************
663//******************************************************************************
664BOOL WIN32API GetCharABCWidthsA(HDC hdc, UINT firstChar, UINT lastChar, LPABC abc)
665{
666 if(FT2Module.isEnabled() == FALSE)
667 {//fallback method
668 return O32_GetCharABCWidths(hdc, firstChar, lastChar, abc);
669 }
670
671 INT i, wlen, count = (INT)(lastChar - firstChar + 1);
672 LPSTR str;
673 LPWSTR wstr;
674 BOOL ret = TRUE;
675
676 if(count <= 0) {
677 dprintf(("ERROR: Invalid parameter!!"));
678 SetLastError(ERROR_INVALID_PARAMETER);
679 return FALSE;
680 }
681
682 str = (LPSTR)HeapAlloc(GetProcessHeap(), 0, count);
683 for(i = 0; i < count; i++)
684 str[i] = (BYTE)(firstChar + i);
685
686 wstr = FONT_mbtowc(hdc, str, count, &wlen, NULL);
687
688 for(i = 0; i < wlen; i++)
689 {
690 if(!GetCharABCWidthsW(hdc, wstr[i], wstr[i], abc))
691 {
692 ret = FALSE;
693 break;
694 }
695 abc++;
696 }
697
698 HeapFree(GetProcessHeap(), 0, str);
699 HeapFree(GetProcessHeap(), 0, wstr);
700
701 return ret;
702}
703//******************************************************************************
704//******************************************************************************
705BOOL WIN32API GetCharABCWidthsW( HDC hdc, UINT firstChar, UINT lastChar, LPABC abc)
706{
707 if(FT2Module.isEnabled() == FALSE)
708 {//no fallback method (yet)
709 DebugInt3();
710 return FALSE;
711 }
712
713 int i;
714 GLYPHMETRICS gm;
715
716 for (i=firstChar;i<=lastChar;i++)
717 {
718 if(GetGlyphOutlineW(hdc, i, GGO_METRICS, &gm, 0, NULL, NULL) == GDI_ERROR)
719 {
720 dprintf(("ERROR: GetGlyphOutlineW failed!!"));
721 return FALSE;
722 }
723 abc[i-firstChar].abcA = gm.gmptGlyphOrigin.x;
724 abc[i-firstChar].abcB = gm.gmBlackBoxX;
725 abc[i-firstChar].abcC = gm.gmCellIncX - gm.gmptGlyphOrigin.x - gm.gmBlackBoxX;
726 dprintf2(("GetCharABCWidthsW %d (%d,%d,%d)", i, abc[i-firstChar].abcA, abc[i-firstChar].abcB, abc[i-firstChar].abcC));
727 }
728 return TRUE;
729}
730//******************************************************************************
731//******************************************************************************
732BOOL WIN32API GetCharABCWidthsFloatA(HDC hdc, UINT iFirstChar, UINT iLastChar, LPABCFLOAT pxBUffer)
733{
734 dprintf(("ERROR: GDI32: GetCharABCWidthsFloatA, not implemented\n"));
735 DebugInt3();
736 return(FALSE);
737}
738//******************************************************************************
739//******************************************************************************
740BOOL WIN32API GetCharABCWidthsFloatW(HDC hdc,
741 UINT iFirstChar,
742 UINT iLastChar,
743 LPABCFLOAT pxBUffer)
744{
745 dprintf(("ERROR: GDI32: GetCharABCWidthsFloatA, not implemented\n"));
746 DebugInt3();
747 return(FALSE);
748}
749//******************************************************************************
750//******************************************************************************
Note: See TracBrowser for help on using the repository browser.