/*
* Copyright (c) 2005 X.Org Foundation L.L.C.
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* this software and associated documentation files (the "Software"), to deal in
* the Software without restriction, including without limitation the rights to
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
* of the Software, and to permit persons to whom the Software is furnished to do
* so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
* 
* Copyright (c) Applied Testing and Technology, Inc. 1995
* All Rights Reserved.
* 
* 
* 
* Copyright (c) 1993  X Consortium
* 
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* 
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
* X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
* AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
* 
* Except as contained in this notice, the name of the X Consortium shall not be
* used in advertising or otherwise to promote the sale, use or other dealings
* in this Software without prior written authorization from the X Consortium.
* Copyright 1993 by Sun Microsystems, Inc. Mountain View, CA.
* 
* All Rights Reserved
* 
* Permission  to  use,  copy,  modify,  and  distribute   this
* software  and  its documentation for any purpose and without
* fee is hereby granted, provided that the above copyright no-
* tice  appear  in all copies and that both that copyright no-
* tice and this permission notice appear in  supporting  docu-
* mentation,  and  that the names of Sun or MIT not be used in
* advertising or publicity pertaining to distribution  of  the
* software  without specific prior written permission. Sun and
* M.I.T. make no representations about the suitability of this
* software for any purpose. It is provided "as is" without any
* express or implied warranty.
* 
* SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
* NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
* ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
* ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
* PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
* THE USE OR PERFORMANCE OF THIS SOFTWARE.
* 
*/
/*
 * SYNOPSIS:
 *   Status
 *   XwcTextPerCharExtents(font_set, pwctest, nwchars, ink_return, logical_return, array_size, pnchars, overall_ink_return, overall_logical_return)
 *   XFontSet font_set;
 *   wchar_t *pwctest;
 *   int nwchars;
 *   XRectangle *ink_return;
 *   XRectangle *logical_return;
 *   int array_size;
 *   int *pnchars;
 *   XRectangle *overall_ink_return;
 *   XRectangle *overall_logical_return;
 */


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include	<stdlib.h>
#include	<stdio.h>
#include	<string.h>
#include	"xtest.h"
#include	"X11/Xlib.h"
#include	"X11/Xutil.h"
#include	"X11/Xresource.h"
#include	"X11/keysym.h"
#include	"tet_api.h"
#include	"xtestlib.h"
#include	"pixval.h"
#ifdef INPUTEXTENSION
#include        "X11/extensions/XInput.h"
#include        "XItest.h"
#endif

extern	Display	*Dsp;
extern	Window	Win;

extern	Window	ErrdefWindow;
extern	Drawable ErrdefDrawable;
extern	GC		ErrdefGC;
extern	Colormap ErrdefColormap;
extern	Pixmap	ErrdefPixmap;
extern	Atom	ErrdefAtom;
extern	Cursor	ErrdefCursor;
extern	Font	ErrdefFont;

#include <locale.h>
#include <ximtest.h>

#define MAX_CHARS	32
#define MAX_TEST_STR	5
static char *test_str_list[MAX_TEST_STR] = {
	"T",
	"Te",
	"Tes",
	"Test",
	"Te\nst",
};



#define T_XwcTextPerCharExtents	1
char    *TestName = "XwcTextPerCharExtents";

/*
 * Defines for different argument types
 */


/*
 * Arguments to the XwcTextPerCharExtents function
 */
static XFontSet font_set;
static wchar_t *pwctest;
static int nwchars;
static XRectangle *ink_return;
static XRectangle *logical_return;
static int array_size;
static int *pnchars;
static XRectangle *overall_ink_return;
static XRectangle *overall_logical_return;


static int 	StatusReturn;

int 	tet_thistest;

/*
 * Called at the beginning of each test purpose to reset the
 * arguments to their initial values
 */
static void
setargs()
{
	font_set = 0;
	pwctest = 0;
	nwchars = 0;
	ink_return = 0;
	logical_return = 0;
	array_size = 0;
	pnchars = 0;
	overall_ink_return = 0;
	overall_logical_return = 0;
}

/*
 * Set the arguments to default values for error tests
 */
static void
seterrdef()
{
}

static void t001(){

#if XT_X_RELEASE > 4
Display *dpy;
char *plocale;
char *font_list;
XFontSet pfs;
char *defstr;
int missing_cnt;
char **missing_chars;
XFontSetExtents *ext;
int escapement;
int nchars, maxescape;
Status status;
XRectangle ink[MAX_CHARS];
XRectangle logical[MAX_CHARS];
XRectangle overall_ink;
XRectangle overall_logical;
wchar_t wcharstr[512];
#endif
int 	pass = 0, fail = 0;

 	report_purpose(1);

	report_assertion("Assertion XwcTextPerCharExtents-1.(C)");
	report_assertion("If the implementation is X11R5 or later:");
	report_assertion("XwcTextPerCharExtents shall return the ink and logical");
	report_assertion("extents of each character in addition to the overall extents");
	report_assertion("of a string.");

	report_strategy("For every Locale specified by the user in the configuration file, create");
	report_strategy("each of the base font sets specified by the user, by calling");
	report_strategy("XCreateFontSet, then call XwcTextPerCharExtents to get the extents per");
	report_strategy("character and the overall extents.  Check to make sure the extents are");
	report_strategy("valid. Also make sure the overall extents are equal to the combined");
	report_strategy("extents of the characters.  Make sure the returned status is good.");

	tpstartup();
	setargs();
#if XT_X_RELEASE > 4

	resetlocale();
	dpy = Dsp;
	while(nextlocale(&plocale))
	{

		if (locale_set(plocale))
			CHECK;
		else
		{
			report("Couldn't set locale.");
			FAIL;
			continue;
		}

		/* cycle through the fontsets */
		resetfontset();
		while(nextfontset(&font_list))
		{
			pfs = XCreateFontSet(dpy,font_list,&missing_chars,
				&missing_cnt,&defstr);
			if(pfs == NULL)
			{
				report("XCreateFontSet unable to create fontset, %s",
					font_list);
				FAIL;
			}
			else
			{
				trace("Created Font Set %s", font_list);
				font_set = pfs;

				ext = XExtentsOfFontSet(pfs);
				if(ext == NULL)
				{
					report("Extents of fontset %s returns null record for locale, %s",
						font_list,plocale);
					FAIL;
				}
				else
				{
				int j;
					trace("Extents for fontset, %s, in locale %s:",
						font_list,plocale);
					trace("    Max Ink     Extents - (%d,%d) w=%d, h=%d",
						ext->max_ink_extent.x,
						ext->max_ink_extent.y,
						ext->max_ink_extent.width,
						ext->max_ink_extent.height);
					trace("    Max Logical Extents - (%d,%d) w=%d, h=%d",
						ext->max_logical_extent.x,
						ext->max_logical_extent.y,
						ext->max_logical_extent.width,
						ext->max_logical_extent.height);

					maxescape = 0;
					for(j=0;j<MAX_TEST_STR;j++)
					{
						nwchars = mbstowcs(wcharstr,test_str_list[j],128);
						pwctest = wcharstr;
						nchars = 0;
		
						ink_return = ink;
						logical_return = logical;
						array_size = MAX_CHARS;
						pnchars = (int *)&nchars;
						overall_ink_return = (XRectangle *)&overall_ink;
						overall_logical_return = (XRectangle *)&overall_logical;
						startcall(Dsp);
						if (isdeleted())
							return;
						status = XwcTextPerCharExtents(font_set, pwctest, nwchars, ink_return, logical_return, array_size, pnchars, overall_ink_return, overall_logical_return);
						endcall(Dsp);
						if (geterr() != Success) {
							report("Got %s, Expecting Success", errorname(geterr()));
							FAIL;
						}
						if(status == 0)
						{
							report("Illegal escapement, %d, for string %s",
								escapement,test_str_list[j]);
							FAIL;
						}
						else
						{
							trace("Extents for string %s, fontset %s, in locale %s",
								test_str_list[j],font_list,plocale);

							if(nchars <= 0)
							{
								report("No characters returned");
								FAIL;
							}
							else
							{
							int k;
							int wcnt, hcnt;
								wcnt = 0;
								hcnt = ink[0].height;
								trace("---Ink     [overall] wid=%d, ht=%d",
									overall_ink.width, overall_ink.height);
								for(k=0;k<nchars;k++)
									wcnt += ink[k].width;
								trace("---Ink     [char   ] wid=%d, ht=%d",
									wcnt,hcnt);
								if((wcnt > (int)overall_ink.width) || 
								   (hcnt > (int)overall_ink.height))
								{
									report("Ink extents of chars (%d,%d) is greater than overall extents (%d,%d) for string %s",
										wcnt,hcnt,
										overall_ink.width,
										overall_ink.height,
										test_str_list[j]);
									FAIL;
								}
								else
									CHECK;
							
								wcnt = 0;
								hcnt = logical[0].height;
								trace("---Logical [overall] wid=%d, ht=%d",
									overall_ink.width, overall_ink.height);
								for(k=0;k<nchars;k++)
									wcnt += logical[k].width;
								trace("---Logical [char   ] wid=%d, ht=%d",
									wcnt,hcnt);
								if((wcnt > (int)overall_logical.width) || 
								   (hcnt > (int)overall_logical.height))
								{
									report("Logical extents of chars (%d,%d) is greater than overall extents (%d,%d) for string %s",
										wcnt,hcnt,
										overall_logical.width,
										overall_logical.height,
										test_str_list[j]);
									FAIL;
								}
								else
									CHECK;
							}
							if((overall_ink.width > overall_logical.width) ||
							   (overall_ink.height > overall_logical.height))
							{
								report("Ink extents are greater than logical extents of fontset, %s in locale %s",
									font_list,plocale);
								FAIL;
							}
							else
								CHECK;
						}
					}
				}
				XFreeFontSet(dpy,pfs);
				XFreeStringList(missing_chars);
			}
		}
	}
	
	CHECKPASS(nlocales()+3*MAX_TEST_STR*nlocales()*nfontset());
#else

	tet_infoline("INFO: Implementation not X11R5 or greater");
	tet_result(TET_UNSUPPORTED);
#endif
	tpcleanup();
	pfcount(pass, fail);
}

/* End of Test Cases */


struct tet_testlist tet_testlist[] = {
	{ t001, 1 },
	{ NULL, 0 }
};

int 	ntests = sizeof(tet_testlist)/sizeof(struct tet_testlist)-1;

void	(*tet_startup)() = localestartup;
void	(*tet_cleanup)() = localecleanup;
