1*c2c66affSColin Finck /* 2*c2c66affSColin Finck * DrawText tests 3*c2c66affSColin Finck * 4*c2c66affSColin Finck * Copyright (c) 2004 Zach Gorman 5*c2c66affSColin Finck * Copyright 2007,2016 Dmitry Timoshkov 6*c2c66affSColin Finck * 7*c2c66affSColin Finck * This library is free software; you can redistribute it and/or 8*c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public 9*c2c66affSColin Finck * License as published by the Free Software Foundation; either 10*c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version. 11*c2c66affSColin Finck * 12*c2c66affSColin Finck * This library is distributed in the hope that it will be useful, 13*c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 14*c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15*c2c66affSColin Finck * Lesser General Public License for more details. 16*c2c66affSColin Finck * 17*c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public 18*c2c66affSColin Finck * License along with this library; if not, write to the Free Software 19*c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20*c2c66affSColin Finck */ 21*c2c66affSColin Finck 22*c2c66affSColin Finck #include <assert.h> 23*c2c66affSColin Finck 24*c2c66affSColin Finck #include "wine/test.h" 25*c2c66affSColin Finck #include "winbase.h" 26*c2c66affSColin Finck #include "wingdi.h" 27*c2c66affSColin Finck #include "winuser.h" 28*c2c66affSColin Finck #include "winerror.h" 29*c2c66affSColin Finck #include "winnls.h" 30*c2c66affSColin Finck 31*c2c66affSColin Finck #define MODIFIED(rect) (rect.left == 10 && rect.right != 100 && rect.top == 10 && rect.bottom != 100) 32*c2c66affSColin Finck #define EMPTY(rect) (rect.left == rect.right && rect.bottom == rect.top) 33*c2c66affSColin Finck 34*c2c66affSColin Finck static void test_DrawTextCalcRect(void) 35*c2c66affSColin Finck { 36*c2c66affSColin Finck HWND hwnd; 37*c2c66affSColin Finck HDC hdc; 38*c2c66affSColin Finck HFONT hFont, hOldFont; 39*c2c66affSColin Finck LOGFONTA lf; 40*c2c66affSColin Finck static CHAR text[] = "Example text for testing DrawText in " 41*c2c66affSColin Finck "MM_HIENGLISH mode"; 42*c2c66affSColin Finck static WCHAR textW[] = {'W','i','d','e',' ','c','h','a','r',' ', 43*c2c66affSColin Finck 's','t','r','i','n','g','\0'}; 44*c2c66affSColin Finck static CHAR emptystring[] = ""; 45*c2c66affSColin Finck static WCHAR emptystringW[] = { 0 }; 46*c2c66affSColin Finck static CHAR wordbreak_text[] = "line1 line2"; 47*c2c66affSColin Finck static WCHAR wordbreak_textW[] = {'l','i','n','e','1',' ','l','i','n','e','2',0}; 48*c2c66affSColin Finck static char tabstring[] = "one\ttwo"; 49*c2c66affSColin Finck INT textlen, textheight, heightcheck; 50*c2c66affSColin Finck RECT rect = { 0, 0, 100, 0 }, rect2; 51*c2c66affSColin Finck BOOL ret; 52*c2c66affSColin Finck DRAWTEXTPARAMS dtp; 53*c2c66affSColin Finck BOOL conform_xp = TRUE; 54*c2c66affSColin Finck 55*c2c66affSColin Finck /* Initialization */ 56*c2c66affSColin Finck hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 57*c2c66affSColin Finck 0, 0, 200, 200, 0, 0, 0, NULL); 58*c2c66affSColin Finck ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError()); 59*c2c66affSColin Finck hdc = GetDC(hwnd); 60*c2c66affSColin Finck ok(hdc != 0, "GetDC error %u\n", GetLastError()); 61*c2c66affSColin Finck trace("hdc %p\n", hdc); 62*c2c66affSColin Finck textlen = lstrlenA(text); 63*c2c66affSColin Finck 64*c2c66affSColin Finck /* LOGFONT initialization */ 65*c2c66affSColin Finck memset(&lf, 0, sizeof(lf)); 66*c2c66affSColin Finck lf.lfCharSet = ANSI_CHARSET; 67*c2c66affSColin Finck lf.lfClipPrecision = CLIP_DEFAULT_PRECIS; 68*c2c66affSColin Finck lf.lfWeight = FW_DONTCARE; 69*c2c66affSColin Finck lf.lfHeight = 0; /* mapping mode dependent */ 70*c2c66affSColin Finck lf.lfQuality = DEFAULT_QUALITY; 71*c2c66affSColin Finck lstrcpyA(lf.lfFaceName, "Arial"); 72*c2c66affSColin Finck 73*c2c66affSColin Finck /* DrawText in MM_HIENGLISH with DT_CALCRECT */ 74*c2c66affSColin Finck SetMapMode(hdc, MM_HIENGLISH); 75*c2c66affSColin Finck lf.lfHeight = 100 * 9 / 72; /* 9 point */ 76*c2c66affSColin Finck hFont = CreateFontIndirectA(&lf); 77*c2c66affSColin Finck ok(hFont != 0, "CreateFontIndirectA error %u\n", 78*c2c66affSColin Finck GetLastError()); 79*c2c66affSColin Finck hOldFont = SelectObject(hdc, hFont); 80*c2c66affSColin Finck 81*c2c66affSColin Finck textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT | 82*c2c66affSColin Finck DT_EXTERNALLEADING | DT_WORDBREAK | DT_NOCLIP | DT_LEFT | 83*c2c66affSColin Finck DT_NOPREFIX); 84*c2c66affSColin Finck ok( textheight, "DrawTextA error %u\n", GetLastError()); 85*c2c66affSColin Finck 86*c2c66affSColin Finck trace("MM_HIENGLISH rect.bottom %d\n", rect.bottom); 87*c2c66affSColin Finck ok(rect.bottom < 0, "In MM_HIENGLISH, DrawText with " 88*c2c66affSColin Finck "DT_CALCRECT should return a negative rectangle bottom. " 89*c2c66affSColin Finck "(bot=%d)\n", rect.bottom); 90*c2c66affSColin Finck 91*c2c66affSColin Finck SelectObject(hdc, hOldFont); 92*c2c66affSColin Finck ret = DeleteObject(hFont); 93*c2c66affSColin Finck ok( ret, "DeleteObject error %u\n", GetLastError()); 94*c2c66affSColin Finck 95*c2c66affSColin Finck 96*c2c66affSColin Finck /* DrawText in MM_TEXT with DT_CALCRECT */ 97*c2c66affSColin Finck SetMapMode(hdc, MM_TEXT); 98*c2c66affSColin Finck lf.lfHeight = -MulDiv(9, GetDeviceCaps(hdc, 99*c2c66affSColin Finck LOGPIXELSY), 72); /* 9 point */ 100*c2c66affSColin Finck hFont = CreateFontIndirectA(&lf); 101*c2c66affSColin Finck ok(hFont != 0, "CreateFontIndirectA error %u\n", 102*c2c66affSColin Finck GetLastError()); 103*c2c66affSColin Finck hOldFont = SelectObject(hdc, hFont); 104*c2c66affSColin Finck 105*c2c66affSColin Finck textheight = DrawTextA(hdc, text, textlen, &rect, DT_CALCRECT | 106*c2c66affSColin Finck DT_EXTERNALLEADING | DT_WORDBREAK | DT_NOCLIP | DT_LEFT | 107*c2c66affSColin Finck DT_NOPREFIX); 108*c2c66affSColin Finck ok( textheight, "DrawTextA error %u\n", GetLastError()); 109*c2c66affSColin Finck 110*c2c66affSColin Finck trace("MM_TEXT rect.bottom %d\n", rect.bottom); 111*c2c66affSColin Finck ok(rect.bottom > 0, "In MM_TEXT, DrawText with DT_CALCRECT " 112*c2c66affSColin Finck "should return a positive rectangle bottom. (bot=%d)\n", 113*c2c66affSColin Finck rect.bottom); 114*c2c66affSColin Finck 115*c2c66affSColin Finck /* empty or null text should in some cases calc an empty rectangle */ 116*c2c66affSColin Finck 117*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 118*c2c66affSColin Finck heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT, NULL ); 119*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 120*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 121*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 122*c2c66affSColin Finck 123*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 124*c2c66affSColin Finck textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT); 125*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 126*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 127*c2c66affSColin Finck if (conform_xp) 128*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextA\n"); 129*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 130*c2c66affSColin Finck 131*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 132*c2c66affSColin Finck SetLastError( 0); 133*c2c66affSColin Finck heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT, NULL ); 134*c2c66affSColin Finck ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect)); 135*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExA\n"); 136*c2c66affSColin Finck 137*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 138*c2c66affSColin Finck textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT); 139*c2c66affSColin Finck ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect)); 140*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextA\n"); 141*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 142*c2c66affSColin Finck 143*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 144*c2c66affSColin Finck SetLastError( 0); 145*c2c66affSColin Finck heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT, NULL ); 146*c2c66affSColin Finck ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect)); 147*c2c66affSColin Finck if (!textheight) /* Windows NT 4 */ 148*c2c66affSColin Finck { 149*c2c66affSColin Finck if (conform_xp) 150*c2c66affSColin Finck win_skip("XP conformity failed, skipping XP tests. Probably winNT\n"); 151*c2c66affSColin Finck conform_xp = FALSE; 152*c2c66affSColin Finck } 153*c2c66affSColin Finck else 154*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExA\n"); 155*c2c66affSColin Finck 156*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 157*c2c66affSColin Finck textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT); 158*c2c66affSColin Finck ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect)); 159*c2c66affSColin Finck if (conform_xp) 160*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextA\n"); 161*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 162*c2c66affSColin Finck 163*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 164*c2c66affSColin Finck heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT, NULL ); 165*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 166*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 167*c2c66affSColin Finck if (conform_xp) 168*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 169*c2c66affSColin Finck 170*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 171*c2c66affSColin Finck textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT); 172*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 173*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 174*c2c66affSColin Finck if (conform_xp) 175*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextA\n"); 176*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 177*c2c66affSColin Finck 178*c2c66affSColin Finck /* DT_SINGLELINE tests */ 179*c2c66affSColin Finck 180*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 181*c2c66affSColin Finck heightcheck = textheight = DrawTextExA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL ); 182*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 183*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 184*c2c66affSColin Finck if (conform_xp) 185*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 186*c2c66affSColin Finck 187*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 188*c2c66affSColin Finck textheight = DrawTextA(hdc, text, 0, &rect, DT_CALCRECT|DT_SINGLELINE); 189*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 190*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 191*c2c66affSColin Finck if (conform_xp) 192*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextA\n"); 193*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 194*c2c66affSColin Finck 195*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 196*c2c66affSColin Finck SetLastError( 0); 197*c2c66affSColin Finck heightcheck = textheight = DrawTextExA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL ); 198*c2c66affSColin Finck ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n", 199*c2c66affSColin Finck wine_dbgstr_rect(&rect)); 200*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExA\n"); 201*c2c66affSColin Finck 202*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 203*c2c66affSColin Finck textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT|DT_SINGLELINE); 204*c2c66affSColin Finck ok(!EMPTY(rect) && MODIFIED (rect), "rectangle should be modified got %s\n", 205*c2c66affSColin Finck wine_dbgstr_rect(&rect)); 206*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextA\n"); 207*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 208*c2c66affSColin Finck 209*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 210*c2c66affSColin Finck SetLastError( 0); 211*c2c66affSColin Finck heightcheck = textheight = DrawTextExA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL ); 212*c2c66affSColin Finck ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n", 213*c2c66affSColin Finck wine_dbgstr_rect(&rect)); 214*c2c66affSColin Finck if (conform_xp) 215*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExA\n"); 216*c2c66affSColin Finck 217*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 218*c2c66affSColin Finck textheight = DrawTextA(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE); 219*c2c66affSColin Finck ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n", 220*c2c66affSColin Finck wine_dbgstr_rect(&rect)); 221*c2c66affSColin Finck if (conform_xp) 222*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextA\n"); 223*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 224*c2c66affSColin Finck 225*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 226*c2c66affSColin Finck heightcheck = textheight = DrawTextExA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL ); 227*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 228*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 229*c2c66affSColin Finck if (conform_xp) 230*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 231*c2c66affSColin Finck 232*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 233*c2c66affSColin Finck textheight = DrawTextA(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE); 234*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 235*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 236*c2c66affSColin Finck if (conform_xp) 237*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextA\n"); 238*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 239*c2c66affSColin Finck 240*c2c66affSColin Finck /* further tests with 0 count, NULL and empty strings */ 241*c2c66affSColin Finck heightcheck = textheight = DrawTextA(hdc, text, 0, &rect, 0); 242*c2c66affSColin Finck if (conform_xp) 243*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextA\n"); 244*c2c66affSColin Finck textheight = DrawTextExA(hdc, text, 0, &rect, 0, NULL ); 245*c2c66affSColin Finck if (conform_xp) 246*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 247*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 248*c2c66affSColin Finck heightcheck = textheight = DrawTextA(hdc, emptystring, 0, &rect, 0); 249*c2c66affSColin Finck if (conform_xp) 250*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextA\n"); 251*c2c66affSColin Finck textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, NULL ); 252*c2c66affSColin Finck if (conform_xp) 253*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 254*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 255*c2c66affSColin Finck heightcheck = textheight = DrawTextA(hdc, NULL, 0, &rect, 0); 256*c2c66affSColin Finck if (conform_xp) 257*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextA\n"); 258*c2c66affSColin Finck textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, NULL ); 259*c2c66affSColin Finck if (conform_xp) 260*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 261*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 262*c2c66affSColin Finck heightcheck = textheight = DrawTextA(hdc, emptystring, -1, &rect, 0); 263*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextA\n"); 264*c2c66affSColin Finck textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, NULL ); 265*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExA\n"); 266*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 267*c2c66affSColin Finck heightcheck = textheight = DrawTextA(hdc, NULL, -1, &rect, 0); 268*c2c66affSColin Finck if (conform_xp) 269*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextA\n"); 270*c2c66affSColin Finck textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, NULL ); 271*c2c66affSColin Finck if (conform_xp) 272*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExA\n"); 273*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 274*c2c66affSColin Finck heightcheck = textheight = DrawTextA(hdc, NULL, 10, &rect, 0); 275*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextA\n"); 276*c2c66affSColin Finck textheight = DrawTextExA(hdc, NULL, 10, &rect, 0, NULL ); 277*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextA\n"); 278*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 279*c2c66affSColin Finck 280*c2c66affSColin Finck 281*c2c66affSColin Finck /* invalid dtp size test */ 282*c2c66affSColin Finck dtp.cbSize = -1; /* Invalid */ 283*c2c66affSColin Finck dtp.uiLengthDrawn = 1337; 284*c2c66affSColin Finck textheight = DrawTextExA(hdc, text, 0, &rect, 0, &dtp); 285*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 286*c2c66affSColin Finck ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn); 287*c2c66affSColin Finck dtp.uiLengthDrawn = 1337; 288*c2c66affSColin Finck textheight = DrawTextExA(hdc, emptystring, 0, &rect, 0, &dtp); 289*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 290*c2c66affSColin Finck ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn); 291*c2c66affSColin Finck dtp.uiLengthDrawn = 1337; 292*c2c66affSColin Finck textheight = DrawTextExA(hdc, NULL, 0, &rect, 0, &dtp); 293*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 294*c2c66affSColin Finck ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn); 295*c2c66affSColin Finck dtp.uiLengthDrawn = 1337; 296*c2c66affSColin Finck textheight = DrawTextExA(hdc, emptystring, -1, &rect, 0, &dtp); 297*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 298*c2c66affSColin Finck ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn); 299*c2c66affSColin Finck dtp.uiLengthDrawn = 1337; 300*c2c66affSColin Finck textheight = DrawTextExA(hdc, NULL, -1, &rect, 0, &dtp); 301*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExA\n"); 302*c2c66affSColin Finck ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn); 303*c2c66affSColin Finck 304*c2c66affSColin Finck /* Margin calculations */ 305*c2c66affSColin Finck dtp.cbSize = sizeof(dtp); 306*c2c66affSColin Finck dtp.iLeftMargin = 0; 307*c2c66affSColin Finck dtp.iRightMargin = 0; 308*c2c66affSColin Finck SetRectEmpty(&rect); 309*c2c66affSColin Finck DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp); 310*c2c66affSColin Finck textlen = rect.right; /* Width without margin */ 311*c2c66affSColin Finck dtp.iLeftMargin = 8; 312*c2c66affSColin Finck SetRectEmpty(&rect); 313*c2c66affSColin Finck DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp); 314*c2c66affSColin Finck ok(rect.right==dtp.iLeftMargin+textlen ,"Incorrect left margin calculated rc(%d,%d)\n", rect.left, rect.right); 315*c2c66affSColin Finck dtp.iLeftMargin = 0; 316*c2c66affSColin Finck dtp.iRightMargin = 8; 317*c2c66affSColin Finck SetRectEmpty(&rect); 318*c2c66affSColin Finck DrawTextExA(hdc, text, -1, &rect, DT_CALCRECT, &dtp); 319*c2c66affSColin Finck ok(rect.right==dtp.iRightMargin+textlen ,"Incorrect right margin calculated rc(%d,%d)\n", rect.left, rect.right); 320*c2c66affSColin Finck 321*c2c66affSColin Finck /* Wide char versions */ 322*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 323*c2c66affSColin Finck SetLastError( 0); 324*c2c66affSColin Finck heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT, NULL ); 325*c2c66affSColin Finck if( GetLastError() != ERROR_CALL_NOT_IMPLEMENTED) { 326*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 327*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 328*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExW\n"); 329*c2c66affSColin Finck 330*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 331*c2c66affSColin Finck textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT); 332*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 333*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 334*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextW\n"); 335*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 336*c2c66affSColin Finck 337*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 338*c2c66affSColin Finck heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT, NULL ); 339*c2c66affSColin Finck ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect)); 340*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExW\n"); 341*c2c66affSColin Finck 342*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 343*c2c66affSColin Finck textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT); 344*c2c66affSColin Finck ok(EMPTY(rect), "rectangle should be empty got %s\n", wine_dbgstr_rect(&rect)); 345*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextW\n"); 346*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 347*c2c66affSColin Finck 348*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 349*c2c66affSColin Finck heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT, NULL ); 350*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 351*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 352*c2c66affSColin Finck if (textheight) /* windows 2000 */ 353*c2c66affSColin Finck { 354*c2c66affSColin Finck if (conform_xp) 355*c2c66affSColin Finck win_skip("XP conformity failed, skipping XP tests. Probably win 2000\n"); 356*c2c66affSColin Finck conform_xp = FALSE; 357*c2c66affSColin Finck } 358*c2c66affSColin Finck else 359*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExW\n"); 360*c2c66affSColin Finck 361*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 362*c2c66affSColin Finck textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT); 363*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 364*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 365*c2c66affSColin Finck if (conform_xp) 366*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextW\n"); 367*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 368*c2c66affSColin Finck 369*c2c66affSColin Finck if (conform_xp) { 370*c2c66affSColin Finck /* Crashes on NT4 */ 371*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 372*c2c66affSColin Finck heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT, NULL ); 373*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 374*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 375*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExW\n"); 376*c2c66affSColin Finck 377*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 378*c2c66affSColin Finck textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT); 379*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 380*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 381*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextW\n"); 382*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 383*c2c66affSColin Finck } 384*c2c66affSColin Finck 385*c2c66affSColin Finck 386*c2c66affSColin Finck /* DT_SINGLELINE tests */ 387*c2c66affSColin Finck 388*c2c66affSColin Finck heightcheck = textheight = DrawTextExW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL ); 389*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 390*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 391*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExW\n"); 392*c2c66affSColin Finck 393*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 394*c2c66affSColin Finck textheight = DrawTextW(hdc, textW, 0, &rect, DT_CALCRECT|DT_SINGLELINE); 395*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 396*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 397*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextW\n"); 398*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 399*c2c66affSColin Finck 400*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 401*c2c66affSColin Finck heightcheck = textheight = DrawTextExW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL ); 402*c2c66affSColin Finck ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n", 403*c2c66affSColin Finck wine_dbgstr_rect(&rect)); 404*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExW\n"); 405*c2c66affSColin Finck 406*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 407*c2c66affSColin Finck textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT|DT_SINGLELINE); 408*c2c66affSColin Finck ok(!EMPTY(rect) && MODIFIED(rect), "rectangle should be modified got %s\n", 409*c2c66affSColin Finck wine_dbgstr_rect(&rect)); 410*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextW\n"); 411*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 412*c2c66affSColin Finck 413*c2c66affSColin Finck if (conform_xp) { 414*c2c66affSColin Finck /* Crashes on NT4 */ 415*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 416*c2c66affSColin Finck heightcheck = textheight = DrawTextExW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE, NULL ); 417*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 418*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 419*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExW\n"); 420*c2c66affSColin Finck 421*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 422*c2c66affSColin Finck textheight = DrawTextW(hdc, NULL, -1, &rect, DT_CALCRECT|DT_SINGLELINE); 423*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 424*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 425*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextW\n"); 426*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 427*c2c66affSColin Finck } 428*c2c66affSColin Finck 429*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 430*c2c66affSColin Finck heightcheck = textheight = DrawTextExW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE, NULL ); 431*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 432*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 433*c2c66affSColin Finck if (conform_xp) 434*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExW\n"); 435*c2c66affSColin Finck 436*c2c66affSColin Finck SetRect( &rect, 10,10, 100, 100); 437*c2c66affSColin Finck textheight = DrawTextW(hdc, NULL, 0, &rect, DT_CALCRECT|DT_SINGLELINE); 438*c2c66affSColin Finck ok(!IsRectEmpty(&rect) && !MODIFIED(rect), 439*c2c66affSColin Finck "rectangle should NOT be empty and NOT modified got %s\n", wine_dbgstr_rect(&rect)); 440*c2c66affSColin Finck if (conform_xp) 441*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextW\n"); 442*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 443*c2c66affSColin Finck 444*c2c66affSColin Finck /* further tests with NULL and empty strings */ 445*c2c66affSColin Finck heightcheck = textheight = DrawTextW(hdc, textW, 0, &rect, 0); 446*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextW\n"); 447*c2c66affSColin Finck textheight = DrawTextExW(hdc, textW, 0, &rect, 0, NULL ); 448*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExW\n"); 449*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 450*c2c66affSColin Finck heightcheck = textheight = DrawTextW(hdc, emptystringW, 0, &rect, 0); 451*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextW\n"); 452*c2c66affSColin Finck textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, NULL ); 453*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExW\n"); 454*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 455*c2c66affSColin Finck heightcheck = textheight = DrawTextW(hdc, NULL, 0, &rect, 0); 456*c2c66affSColin Finck if (conform_xp) 457*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextW\n"); 458*c2c66affSColin Finck textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, NULL ); 459*c2c66affSColin Finck if (conform_xp) 460*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExW\n"); 461*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 462*c2c66affSColin Finck heightcheck = textheight = DrawTextW(hdc, emptystringW, -1, &rect, 0); 463*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextW\n"); 464*c2c66affSColin Finck textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, NULL ); 465*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExW\n"); 466*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 467*c2c66affSColin Finck if (conform_xp) { 468*c2c66affSColin Finck /* Crashes on NT4 */ 469*c2c66affSColin Finck heightcheck = textheight = DrawTextW(hdc, NULL, -1, &rect, 0); 470*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextW\n"); 471*c2c66affSColin Finck textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, NULL ); 472*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExW\n"); 473*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 474*c2c66affSColin Finck heightcheck = textheight = DrawTextW(hdc, NULL, 10, &rect, 0); 475*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextW\n"); 476*c2c66affSColin Finck textheight = DrawTextExW(hdc, NULL, 10, &rect, 0, NULL ); 477*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextW\n"); 478*c2c66affSColin Finck ok(textheight == heightcheck,"DrawTextEx and DrawText differ in return\n"); 479*c2c66affSColin Finck } 480*c2c66affSColin Finck 481*c2c66affSColin Finck dtp.cbSize = -1; /* Invalid */ 482*c2c66affSColin Finck dtp.uiLengthDrawn = 1337; 483*c2c66affSColin Finck textheight = DrawTextExW(hdc, textW, 0, &rect, 0, &dtp); 484*c2c66affSColin Finck ok(textheight!=0,"Failed to get textheight from DrawTextExW\n"); 485*c2c66affSColin Finck ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn); 486*c2c66affSColin Finck dtp.uiLengthDrawn = 1337; 487*c2c66affSColin Finck textheight = DrawTextExW(hdc, emptystringW, 0, &rect, 0, &dtp); 488*c2c66affSColin Finck if (conform_xp) 489*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExW\n"); 490*c2c66affSColin Finck ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn); 491*c2c66affSColin Finck dtp.uiLengthDrawn = 1337; 492*c2c66affSColin Finck textheight = DrawTextExW(hdc, NULL, 0, &rect, 0, &dtp); 493*c2c66affSColin Finck if (conform_xp) 494*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExW\n"); 495*c2c66affSColin Finck ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn); 496*c2c66affSColin Finck dtp.uiLengthDrawn = 1337; 497*c2c66affSColin Finck textheight = DrawTextExW(hdc, emptystringW, -1, &rect, 0, &dtp); 498*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExW\n"); 499*c2c66affSColin Finck ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn); 500*c2c66affSColin Finck if (conform_xp) { 501*c2c66affSColin Finck /* Crashes on NT4 */ 502*c2c66affSColin Finck dtp.uiLengthDrawn = 1337; 503*c2c66affSColin Finck textheight = DrawTextExW(hdc, NULL, -1, &rect, 0, &dtp); 504*c2c66affSColin Finck ok(textheight==0,"Got textheight from DrawTextExW\n"); 505*c2c66affSColin Finck ok(dtp.uiLengthDrawn==1337, "invalid dtp.uiLengthDrawn = %i\n",dtp.uiLengthDrawn); 506*c2c66affSColin Finck } 507*c2c66affSColin Finck } 508*c2c66affSColin Finck 509*c2c66affSColin Finck /* More test cases from bug 12226 */ 510*c2c66affSColin Finck SetRectEmpty(&rect); 511*c2c66affSColin Finck textheight = DrawTextA(hdc, emptystring, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE); 512*c2c66affSColin Finck ok(textheight, "DrawTextA error %u\n", GetLastError()); 513*c2c66affSColin Finck ok(0 == rect.left, "expected 0, got %d\n", rect.left); 514*c2c66affSColin Finck ok(0 == rect.right, "expected 0, got %d\n", rect.right); 515*c2c66affSColin Finck ok(0 == rect.top, "expected 0, got %d\n", rect.top); 516*c2c66affSColin Finck ok(rect.bottom, "rect.bottom should not be 0\n"); 517*c2c66affSColin Finck 518*c2c66affSColin Finck SetRectEmpty(&rect); 519*c2c66affSColin Finck textheight = DrawTextW(hdc, emptystringW, -1, &rect, DT_CALCRECT | DT_LEFT | DT_SINGLELINE); 520*c2c66affSColin Finck if (!textheight && GetLastError() == ERROR_CALL_NOT_IMPLEMENTED) 521*c2c66affSColin Finck { 522*c2c66affSColin Finck win_skip( "DrawTextW not implemented\n" ); 523*c2c66affSColin Finck } 524*c2c66affSColin Finck else 525*c2c66affSColin Finck { 526*c2c66affSColin Finck ok(textheight, "DrawTextW error %u\n", GetLastError()); 527*c2c66affSColin Finck ok(0 == rect.left, "expected 0, got %d\n", rect.left); 528*c2c66affSColin Finck ok(0 == rect.right, "expected 0, got %d\n", rect.right); 529*c2c66affSColin Finck ok(0 == rect.top, "expected 0, got %d\n", rect.top); 530*c2c66affSColin Finck ok(rect.bottom, "rect.bottom should not be 0\n"); 531*c2c66affSColin Finck } 532*c2c66affSColin Finck 533*c2c66affSColin Finck SetRect(&rect, 0, 0, 1, 1); 534*c2c66affSColin Finck heightcheck = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT); 535*c2c66affSColin Finck SetRect(&rect, 0, 0, 1, 1); 536*c2c66affSColin Finck textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK); 537*c2c66affSColin Finck ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n", 538*c2c66affSColin Finck textheight, heightcheck * 2); 539*c2c66affSColin Finck SetRect(&rect, 0, 0, 1, 1); 540*c2c66affSColin Finck textheight = DrawTextA(hdc, wordbreak_text, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL); 541*c2c66affSColin Finck ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n", 542*c2c66affSColin Finck textheight, heightcheck * 6); 543*c2c66affSColin Finck 544*c2c66affSColin Finck SetRect(&rect, 0, 0, 1, 1); 545*c2c66affSColin Finck heightcheck = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT); 546*c2c66affSColin Finck SetRect(&rect, 0, 0, 1, 1); 547*c2c66affSColin Finck textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK); 548*c2c66affSColin Finck ok(textheight == heightcheck * 2, "Got unexpected textheight %d, expected %d.\n", 549*c2c66affSColin Finck textheight, heightcheck * 2); 550*c2c66affSColin Finck SetRect(&rect, 0, 0, 1, 1); 551*c2c66affSColin Finck textheight = DrawTextW(hdc, wordbreak_textW, -1, &rect, DT_CALCRECT | DT_WORDBREAK | DT_EDITCONTROL); 552*c2c66affSColin Finck ok(textheight >= heightcheck * 6, "Got unexpected textheight %d, expected at least %d.\n", 553*c2c66affSColin Finck textheight, heightcheck * 6); 554*c2c66affSColin Finck 555*c2c66affSColin Finck /* DT_TABSTOP | DT_EXPANDTABS tests */ 556*c2c66affSColin Finck SetRect( &rect, 0,0, 10, 10); 557*c2c66affSColin Finck textheight = DrawTextA(hdc, tabstring, -1, &rect, DT_TABSTOP | DT_EXPANDTABS ); 558*c2c66affSColin Finck ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight); 559*c2c66affSColin Finck 560*c2c66affSColin Finck SetRect( &rect, 0,0, 10, 10); 561*c2c66affSColin Finck memset(&dtp, 0, sizeof(dtp)); 562*c2c66affSColin Finck dtp.cbSize = sizeof(dtp); 563*c2c66affSColin Finck textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT, &dtp); 564*c2c66affSColin Finck ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight); 565*c2c66affSColin Finck ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength); 566*c2c66affSColin Finck 567*c2c66affSColin Finck SetRect( &rect2, 0,0, 10, 10); 568*c2c66affSColin Finck memset(&dtp, 0, sizeof(dtp)); 569*c2c66affSColin Finck dtp.cbSize = sizeof(dtp); 570*c2c66affSColin Finck textheight = DrawTextExA(hdc, tabstring, -1, &rect2, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp); 571*c2c66affSColin Finck ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight); 572*c2c66affSColin Finck ok(dtp.iTabLength == 0, "invalid dtp.iTabLength = %i\n",dtp.iTabLength); 573*c2c66affSColin Finck ok(rect.left == rect2.left && rect.right != rect2.right && rect.top == rect2.top && rect.bottom == rect2.bottom, 574*c2c66affSColin Finck "incorrect rect %s rect2 %s\n", wine_dbgstr_rect(&rect), wine_dbgstr_rect(&rect2)); 575*c2c66affSColin Finck 576*c2c66affSColin Finck SetRect( &rect, 0,0, 10, 10); 577*c2c66affSColin Finck memset(&dtp, 0, sizeof(dtp)); 578*c2c66affSColin Finck dtp.cbSize = sizeof(dtp); 579*c2c66affSColin Finck dtp.iTabLength = 8; 580*c2c66affSColin Finck textheight = DrawTextExA(hdc, tabstring, -1, &rect, DT_CALCRECT | DT_TABSTOP | DT_EXPANDTABS, &dtp); 581*c2c66affSColin Finck ok(textheight >= heightcheck, "Got unexpected textheight %d\n", textheight); 582*c2c66affSColin Finck ok(dtp.iTabLength == 8, "invalid dtp.iTabLength = %i\n",dtp.iTabLength); 583*c2c66affSColin Finck ok(rect.left == rect2.left, "unexpected value %d, got %d\n", rect.left, rect2.left); 584*c2c66affSColin Finck /* XP, 2003 appear to not give the same values. */ 585*c2c66affSColin Finck ok(rect.right == rect2.right || broken(rect.right > rect2.right), "unexpected value %d, got %d\n",rect.right, rect2.right); 586*c2c66affSColin Finck ok(rect.top == rect2.top, "unexpected value %d, got %d\n", rect.top, rect2.top); 587*c2c66affSColin Finck ok(rect.bottom == rect2.bottom , "unexpected value %d, got %d\n", rect.bottom, rect2.bottom); 588*c2c66affSColin Finck 589*c2c66affSColin Finck 590*c2c66affSColin Finck SelectObject(hdc, hOldFont); 591*c2c66affSColin Finck ret = DeleteObject(hFont); 592*c2c66affSColin Finck ok( ret, "DeleteObject error %u\n", GetLastError()); 593*c2c66affSColin Finck 594*c2c66affSColin Finck /* Clean up */ 595*c2c66affSColin Finck ret = ReleaseDC(hwnd, hdc); 596*c2c66affSColin Finck ok( ret, "ReleaseDC error %u\n", GetLastError()); 597*c2c66affSColin Finck ret = DestroyWindow(hwnd); 598*c2c66affSColin Finck ok( ret, "DestroyWindow error %u\n", GetLastError()); 599*c2c66affSColin Finck } 600*c2c66affSColin Finck 601*c2c66affSColin Finck /* replace tabs by \t */ 602*c2c66affSColin Finck static void strfmt( const char *str, char *strout) 603*c2c66affSColin Finck { 604*c2c66affSColin Finck unsigned int i,j ; 605*c2c66affSColin Finck for(i=0,j=0;i<=strlen(str);i++,j++) 606*c2c66affSColin Finck if((strout[j]=str[i])=='\t') { 607*c2c66affSColin Finck strout[j++]='\\'; 608*c2c66affSColin Finck strout[j]='t'; 609*c2c66affSColin Finck } 610*c2c66affSColin Finck } 611*c2c66affSColin Finck 612*c2c66affSColin Finck 613*c2c66affSColin Finck #define TABTEST( tabval, tabcount, string, _exp) \ 614*c2c66affSColin Finck { int i; char strdisp[64];\ 615*c2c66affSColin Finck for(i=0;i<8;i++) tabs[i]=(i+1)*(tabval); \ 616*c2c66affSColin Finck extent = GetTabbedTextExtentA( hdc, string, strlen( string), (tabcount), tabs); \ 617*c2c66affSColin Finck strfmt( string, strdisp); \ 618*c2c66affSColin Finck /* trace( "Extent is %08lx\n", extent); */\ 619*c2c66affSColin Finck ok( extent == _exp, "Test case \"%s\". Text extent is 0x%x, expected 0x%x tab %d tabcount %d\n", \ 620*c2c66affSColin Finck strdisp, extent, _exp, tabval, tabcount); \ 621*c2c66affSColin Finck } \ 622*c2c66affSColin Finck 623*c2c66affSColin Finck 624*c2c66affSColin Finck static void test_TabbedText(void) 625*c2c66affSColin Finck { 626*c2c66affSColin Finck HWND hwnd; 627*c2c66affSColin Finck HDC hdc; 628*c2c66affSColin Finck BOOL ret; 629*c2c66affSColin Finck TEXTMETRICA tm; 630*c2c66affSColin Finck DWORD extent; 631*c2c66affSColin Finck INT tabs[8], cx, cy, tab, tabcount,t,align; 632*c2c66affSColin Finck 633*c2c66affSColin Finck /* Initialization */ 634*c2c66affSColin Finck hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 635*c2c66affSColin Finck 0, 0, 200, 200, 0, 0, 0, NULL); 636*c2c66affSColin Finck ok(hwnd != 0, "CreateWindowExA error %u\n", GetLastError()); 637*c2c66affSColin Finck hdc = GetDC(hwnd); 638*c2c66affSColin Finck ok(hdc != 0, "GetDC error %u\n", GetLastError()); 639*c2c66affSColin Finck 640*c2c66affSColin Finck ret = GetTextMetricsA( hdc, &tm); 641*c2c66affSColin Finck ok( ret, "GetTextMetrics error %u\n", GetLastError()); 642*c2c66affSColin Finck 643*c2c66affSColin Finck extent = GetTabbedTextExtentA( hdc, "x", 0, 1, tabs); 644*c2c66affSColin Finck ok( extent == 0, "GetTabbedTextExtentA returned non-zero on nCount == 0\n"); 645*c2c66affSColin Finck 646*c2c66affSColin Finck extent = GetTabbedTextExtentA( hdc, "x", 1, 1, tabs); 647*c2c66affSColin Finck cx = LOWORD( extent); 648*c2c66affSColin Finck cy = HIWORD( extent); 649*c2c66affSColin Finck trace( "cx is %d cy is %d\n", cx, cy); 650*c2c66affSColin Finck 651*c2c66affSColin Finck align=1; 652*c2c66affSColin Finck for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to 653*c2c66affSColin Finck catch the one off errors */ 654*c2c66affSColin Finck tab = (cx *4 + t); 655*c2c66affSColin Finck /* test the special case tabcount =1 and the general array (80 of tabs */ 656*c2c66affSColin Finck for( tabcount = 1; tabcount <= 8; tabcount +=7) { 657*c2c66affSColin Finck TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy)) 658*c2c66affSColin Finck TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy)) 659*c2c66affSColin Finck TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab+cx, cy)) 660*c2c66affSColin Finck TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy)) 661*c2c66affSColin Finck TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy)) 662*c2c66affSColin Finck TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab+cx, cy)) 663*c2c66affSColin Finck TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab+cx, cy)) 664*c2c66affSColin Finck TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(tab+cx, cy)) 665*c2c66affSColin Finck TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(t>0 ? tab + cx : 2*tab+cx, cy)) 666*c2c66affSColin Finck TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab+cx, cy)) 667*c2c66affSColin Finck } 668*c2c66affSColin Finck } 669*c2c66affSColin Finck align=-1; 670*c2c66affSColin Finck for( t=-1; t<=1; t++) { /* slightly adjust the 4 char tabstop, to 671*c2c66affSColin Finck catch the one off errors */ 672*c2c66affSColin Finck tab = (cx *4 + t); 673*c2c66affSColin Finck /* test the special case tabcount =1 and the general array (8) of tabs */ 674*c2c66affSColin Finck for( tabcount = 1; tabcount <= 8; tabcount +=7) { 675*c2c66affSColin Finck TABTEST( align * tab, tabcount, "\t", MAKELONG(tab, cy)) 676*c2c66affSColin Finck TABTEST( align * tab, tabcount, "xxx\t", MAKELONG(tab, cy)) 677*c2c66affSColin Finck TABTEST( align * tab, tabcount, "\tx", MAKELONG(tab, cy)) 678*c2c66affSColin Finck TABTEST( align * tab, tabcount, "\t\t", MAKELONG(tab*2, cy)) 679*c2c66affSColin Finck TABTEST( align * tab, tabcount, "\tx\t", MAKELONG(tab*2, cy)) 680*c2c66affSColin Finck TABTEST( align * tab, tabcount, "x\tx", MAKELONG(tab, cy)) 681*c2c66affSColin Finck TABTEST( align * tab, tabcount, "xx\tx", MAKELONG(tab, cy)) 682*c2c66affSColin Finck TABTEST( align * tab, tabcount, "xxx\tx", MAKELONG(4 * cx >= tab ? 2*tab :tab, cy)) 683*c2c66affSColin Finck TABTEST( align * tab, tabcount, "xxxx\tx", MAKELONG(2*tab, cy)) 684*c2c66affSColin Finck TABTEST( align * tab, tabcount, "xxxxx\tx", MAKELONG(2*tab, cy)) 685*c2c66affSColin Finck } 686*c2c66affSColin Finck } 687*c2c66affSColin Finck 688*c2c66affSColin Finck ReleaseDC( hwnd, hdc ); 689*c2c66affSColin Finck DestroyWindow( hwnd ); 690*c2c66affSColin Finck } 691*c2c66affSColin Finck 692*c2c66affSColin Finck static void test_DrawState(void) 693*c2c66affSColin Finck { 694*c2c66affSColin Finck static const char text[] = "Sample text string"; 695*c2c66affSColin Finck HWND hwnd; 696*c2c66affSColin Finck HDC hdc; 697*c2c66affSColin Finck BOOL ret; 698*c2c66affSColin Finck 699*c2c66affSColin Finck hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP, 700*c2c66affSColin Finck 0, 0, 200, 200, 0, 0, 0, NULL); 701*c2c66affSColin Finck assert(hwnd); 702*c2c66affSColin Finck 703*c2c66affSColin Finck hdc = GetDC(hwnd); 704*c2c66affSColin Finck assert(hdc); 705*c2c66affSColin Finck 706*c2c66affSColin Finck SetLastError(0xdeadbeef); 707*c2c66affSColin Finck ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, (LPARAM)text, strlen(text), 708*c2c66affSColin Finck 0, 0, 10, 10, DST_TEXT); 709*c2c66affSColin Finck ok(ret, "DrawState error %u\n", GetLastError()); 710*c2c66affSColin Finck 711*c2c66affSColin Finck SetLastError(0xdeadbeef); 712*c2c66affSColin Finck ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, (LPARAM)text, 0, 713*c2c66affSColin Finck 0, 0, 10, 10, DST_TEXT); 714*c2c66affSColin Finck ok(ret, "DrawState error %u\n", GetLastError()); 715*c2c66affSColin Finck 716*c2c66affSColin Finck SetLastError(0xdeadbeef); 717*c2c66affSColin Finck ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, strlen(text), 718*c2c66affSColin Finck 0, 0, 10, 10, DST_TEXT); 719*c2c66affSColin Finck ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n"); 720*c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError()); 721*c2c66affSColin Finck 722*c2c66affSColin Finck SetLastError(0xdeadbeef); 723*c2c66affSColin Finck ret = DrawStateA(hdc, GetStockObject(DKGRAY_BRUSH), NULL, 0, 0, 724*c2c66affSColin Finck 0, 0, 10, 10, DST_TEXT); 725*c2c66affSColin Finck ok(!ret || broken(ret) /* win98 */, "DrawState succeeded\n"); 726*c2c66affSColin Finck ok(GetLastError() == 0xdeadbeef, "not expected error %u\n", GetLastError()); 727*c2c66affSColin Finck 728*c2c66affSColin Finck ReleaseDC(hwnd, hdc); 729*c2c66affSColin Finck DestroyWindow(hwnd); 730*c2c66affSColin Finck } 731*c2c66affSColin Finck 732*c2c66affSColin Finck static void test_CharToOem_OemToChar(void) 733*c2c66affSColin Finck { 734*c2c66affSColin Finck static const WCHAR helloWorldW[] = {'H','e','l','l','o',' ','W','o','r','l','d',0}; 735*c2c66affSColin Finck static const WCHAR emptyW[] = {0}; 736*c2c66affSColin Finck static const char helloWorld[] = "Hello World"; 737*c2c66affSColin Finck static const struct 738*c2c66affSColin Finck { 739*c2c66affSColin Finck BOOL src, dst, ret; 740*c2c66affSColin Finck } 741*c2c66affSColin Finck tests[] = 742*c2c66affSColin Finck { 743*c2c66affSColin Finck { FALSE, FALSE, FALSE }, 744*c2c66affSColin Finck { TRUE, FALSE, FALSE }, 745*c2c66affSColin Finck { FALSE, TRUE, FALSE }, 746*c2c66affSColin Finck { TRUE, TRUE, TRUE }, 747*c2c66affSColin Finck }; 748*c2c66affSColin Finck BOOL ret; 749*c2c66affSColin Finck int i; 750*c2c66affSColin Finck char oem; 751*c2c66affSColin Finck WCHAR uni, expect; 752*c2c66affSColin Finck 753*c2c66affSColin Finck for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) 754*c2c66affSColin Finck { 755*c2c66affSColin Finck const char *expected = tests[i].ret ? helloWorld : ""; 756*c2c66affSColin Finck const char *src = tests[i].src ? helloWorld : NULL; 757*c2c66affSColin Finck char buf[64], *dst = tests[i].dst ? buf : NULL; 758*c2c66affSColin Finck 759*c2c66affSColin Finck memset(buf, 0, sizeof(buf)); 760*c2c66affSColin Finck ret = CharToOemA(src, dst); 761*c2c66affSColin Finck ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret); 762*c2c66affSColin Finck ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf); 763*c2c66affSColin Finck 764*c2c66affSColin Finck memset(buf, 0, sizeof(buf)); 765*c2c66affSColin Finck ret = CharToOemBuffA(src, dst, sizeof(helloWorld)); 766*c2c66affSColin Finck ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret); 767*c2c66affSColin Finck ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf); 768*c2c66affSColin Finck 769*c2c66affSColin Finck memset(buf, 0, sizeof(buf)); 770*c2c66affSColin Finck ret = OemToCharA(src, dst); 771*c2c66affSColin Finck ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret); 772*c2c66affSColin Finck ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf); 773*c2c66affSColin Finck 774*c2c66affSColin Finck memset(buf, 0, sizeof(buf)); 775*c2c66affSColin Finck ret = OemToCharBuffA(src, dst, sizeof(helloWorld)); 776*c2c66affSColin Finck ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret); 777*c2c66affSColin Finck ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf); 778*c2c66affSColin Finck } 779*c2c66affSColin Finck 780*c2c66affSColin Finck for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) 781*c2c66affSColin Finck { 782*c2c66affSColin Finck const char *expected = tests[i].ret ? helloWorld : ""; 783*c2c66affSColin Finck const WCHAR *src = tests[i].src ? helloWorldW : NULL; 784*c2c66affSColin Finck char buf[64], *dst = tests[i].dst ? buf : NULL; 785*c2c66affSColin Finck 786*c2c66affSColin Finck memset(buf, 0, sizeof(buf)); 787*c2c66affSColin Finck ret = CharToOemW(src, dst); 788*c2c66affSColin Finck ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret); 789*c2c66affSColin Finck ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf); 790*c2c66affSColin Finck 791*c2c66affSColin Finck memset(buf, 0, sizeof(buf)); 792*c2c66affSColin Finck ret = CharToOemBuffW(src, dst, sizeof(helloWorldW)/sizeof(WCHAR)); 793*c2c66affSColin Finck ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret); 794*c2c66affSColin Finck ok(!strcmp(buf, expected), "test %d: got '%s'\n", i, buf); 795*c2c66affSColin Finck } 796*c2c66affSColin Finck 797*c2c66affSColin Finck for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) 798*c2c66affSColin Finck { 799*c2c66affSColin Finck const WCHAR *expected = tests[i].ret ? helloWorldW : emptyW; 800*c2c66affSColin Finck const char *src = tests[i].src ? helloWorld : NULL; 801*c2c66affSColin Finck WCHAR buf[64], *dst = tests[i].dst ? buf : NULL; 802*c2c66affSColin Finck 803*c2c66affSColin Finck memset(buf, 0, sizeof(buf)); 804*c2c66affSColin Finck ret = OemToCharW(src, dst); 805*c2c66affSColin Finck ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret); 806*c2c66affSColin Finck ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf)); 807*c2c66affSColin Finck 808*c2c66affSColin Finck memset(buf, 0, sizeof(buf)); 809*c2c66affSColin Finck ret = OemToCharBuffW(src, dst, sizeof(helloWorld)); 810*c2c66affSColin Finck ok(ret == tests[i].ret, "test %d: expected %d, got %d\n", i, tests[i].ret, ret); 811*c2c66affSColin Finck ok(!lstrcmpW(buf, expected), "test %d: got '%s'\n", i, wine_dbgstr_w(buf)); 812*c2c66affSColin Finck } 813*c2c66affSColin Finck 814*c2c66affSColin Finck for (i = 0; i < 0x100; i++) 815*c2c66affSColin Finck { 816*c2c66affSColin Finck oem = i; 817*c2c66affSColin Finck ret = OemToCharBuffW( &oem, &uni, 1 ); 818*c2c66affSColin Finck ok( ret, "%02x: returns FALSE\n", i ); 819*c2c66affSColin Finck MultiByteToWideChar( CP_OEMCP, MB_PRECOMPOSED | MB_USEGLYPHCHARS, &oem, 1, &expect, 1 ); 820*c2c66affSColin Finck ok( uni == expect, "%02x: got %04x expected %04x\n", i, uni, expect ); 821*c2c66affSColin Finck } 822*c2c66affSColin Finck } 823*c2c66affSColin Finck 824*c2c66affSColin Finck START_TEST(text) 825*c2c66affSColin Finck { 826*c2c66affSColin Finck test_TabbedText(); 827*c2c66affSColin Finck test_DrawTextCalcRect(); 828*c2c66affSColin Finck test_DrawState(); 829*c2c66affSColin Finck test_CharToOem_OemToChar(); 830*c2c66affSColin Finck } 831