/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: fontinfo.cpp,v 1.1.2.1 2004/07/09 01:50:20 hubbe Exp $
 * 
 * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved.
 * 
 * The contents of this file, and the files included with this file,
 * are subject to the current version of the RealNetworks Public
 * Source License (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (the "RCSL") available at
 * http://www.helixcommunity.org/content/rcsl, in which case the RCSL
 * will apply. You may also obtain the license terms directly from
 * RealNetworks.  You may not use this file except in compliance with
 * the RPSL or, if you have a valid RCSL with RealNetworks applicable
 * to this file, the RCSL.  Please see the applicable RPSL or RCSL for
 * the rights, obligations and limitations governing use of the
 * contents of the file.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 or later (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * This file is part of the Helix DNA Technology. RealNetworks is the
 * developer of the Original Code and owns the copyrights in the
 * portions it created.
 * 
 * This file, and the files included with this file, is distributed
 * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY
 * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS
 * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET
 * ENJOYMENT OR NON-INFRINGEMENT.
 * 
 * Technology Compatibility Kit Test Suite(s) Location:
 *    http://www.helixcommunity.org/content/tck
 * 
 * Contributor(s):
 * 
 * ***** END LICENSE BLOCK ***** */

/////////////////////////////////////////////////////////////////////////////
//
//  fontinfo.cpp
//
//  INT16 GetCharacterWidth(UINT16 ch, ULONG32 ulFontFaceIndex,
//  	    ULONG32 ulFontPtSize, BOOL isBold, BOOL isItalicized,
//	    ULONG32 ulFontCharsetIndex)
//  This function takes a char (which can be a 2-byte char, thus the val
//  passed in is a UINT16) and calculates its "width" (x-extent) in pixels
//  based on its font face (e.g., "courier"), its point size, whether or not
//  it is bold and/or is italicized.  The parameter ulFontCharsetIndex tells
//  the function whether or not the character is single byte, double byte,
//  or Unicode.
//
//


#include "hxtypes.h"
#include "rt_types.h"
#include "fontdefs.h"
#include "fontinfo.h"
#include "string.h" //for strcpy()

#include "hxassert.h"

#include "textprsr.h" /*for ..._CONTENT_VERSION_... defines */

#include "hxheap.h"
#ifdef _DEBUG
#undef HX_THIS_FILE		
static char HX_THIS_FILE[] = __FILE__;
#endif

//use 256 here to allow upper sbcs chars
#define SBCS_NUM_CHARS			128
#define SBCS_FIRST_NON_CONTROL_CHAR	32

#define UNKNOWN_TIMES_8PT_CHAR_WIDTH	5//== ceiling(avg char width * 1.25).
#define UNKNOWN_TIMES_10PT_CHAR_WIDTH	6//== ceiling(avg char width * 1.25).
#define UNKNOWN_TIMES_12PT_CHAR_WIDTH	7//== ceiling(avg char width * 1.25).
#define UNKNOWN_TIMES_14PT_CHAR_WIDTH	8//== ceiling(avg char width * 1.25).
#define UNKNOWN_TIMES_16PT_CHAR_WIDTH	9//== ceiling(avg char width * 1.25).
#define UNKNOWN_TIMES_20PT_CHAR_WIDTH	11//== ceiling(avg char width* 1.25).
#define UNKNOWN_TIMES_24PT_CHAR_WIDTH	14//== ceiling(avg char width* 1.25).
#define UNKNOWN_TIMES_36PT_CHAR_WIDTH	20//== ceiling(avg char width* 1.25).
#define UNKNOWN_TIMES_48PT_CHAR_WIDTH	27//== ceiling(avg char width* 1.25).

#define UNKNWNWDTH16	8
#define UNKNWNWDTH100	50

const UINT8 timesFontWidths16PointRegular[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 4, 5, 5, 7, 7,12,11, 4, 5, 5, 7, 8, 4, 5, 4, 4,
	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 3, 4, 8, 8, 8, 6,
	13, 9, 8, 9,10, 8, 8,10, 9, 5, 6, 9, 8,12,10,10,
	 8,10, 9, 8, 9, 9, 9,13,10, 9, 8, 5, 4, 5, 6, 7,
	 4, 6, 7, 7, 7, 6, 5, 7, 7, 3, 3, 7, 3,11, 7, 7,
	 7, 7, 5, 6, 4, 7, 7,11, 7, 7, 6, 7, 3, 7, 8, 4
	};
const UINT8 timesFontWidths16PointBold[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 3, 4, 7, 7, 7,15,11, 4, 4, 4, 7, 7, 3, 4, 3, 4,
	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 7, 7, 7, 7,
	12, 9, 9, 9, 9, 7, 7, 9, 9, 4, 7, 9, 8,11, 9,10,
	 8,10, 9, 8, 8, 8, 9,13, 9, 8, 8, 4, 4, 4, 8, 7,
	 4, 6, 6, 6, 6, 6, 4, 7, 7, 4, 4, 8, 4,10, 7, 6,
	 6, 6, 6, 6, 4, 7, 5, 8, 6, 6, 6, 5, 3, 5, 7, 3
	};
const UINT8 timesFontWidths16PointItalics[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 4, 4, 7, 7, 7,11,12, 4, 5, 5, 7, 9, 4, 5, 4, 4,
	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 5, 5, 9, 9, 9, 7,
	13, 9, 9, 9,10, 9, 9,10,10, 5, 6, 9, 8,12, 9,10,
	 9,10, 9, 7, 8,10, 9,11, 9, 8, 8, 6, 4, 6, 6, 7,
	 4, 7, 7, 6, 7, 6, 5, 7, 7, 4, 4, 7, 4,10, 7, 7,
	 7, 7, 5, 5, 4, 7, 7, 9, 6, 6, 5, 6, 4, 6, 8, 4
	};

const UINT8 timesFontWidths16PointBoldItalics[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 3, 5, 7, 6, 7,11,10, 4, 4, 4, 7, 7, 3, 4, 3, 4,
	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 7, 7, 7, 7,
	11, 9, 9, 9, 9, 9, 9, 9,10, 5, 6, 9, 8,12, 9, 9,
	 8, 9, 9, 7, 8, 9, 9,12, 9, 7, 8, 4, 4, 4, 7, 7,
	 4, 7, 7, 6, 7, 6, 4, 7, 7, 4, 4, 7, 4,10, 7, 7,
	 7, 7, 5, 5, 4, 7, 6, 9, 7, 6, 5, 5, 3, 5, 8, 3
	};

const UINT8 timesFontWidths20PointRegular[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 5, 6, 7, 9, 9,15,14, 5, 6, 6, 9,10, 5, 6, 5, 5,
	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 4, 5,10,10,10, 8,
	16,12,12,12,13,11,10,13,13, 6, 7,13,11,16,13,13,
	11,13,12,10,12,13,12,17,13,13,11, 6, 5, 6, 8, 9,
	 6, 8, 9, 8, 9, 8, 6, 8, 9, 4, 5, 9, 4,14, 9, 9,
	 9, 9, 6, 7, 5, 9, 9,13, 8, 9, 8, 9, 3, 9,10, 5
	};
const UINT8 timesFontWidths20PointBold[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 5, 5,10, 9, 9,17,15, 5, 6, 6, 9,10, 5, 6, 5, 5,
	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5,10,10,10, 9,
	17,13,12,13,13,11,10,14,14, 7, 9,14,12,17,13,14,
	11,14,13,10,11,13,13,17,12,12,11, 6, 5, 6,10, 9,
	 6, 9,10, 8,10, 8, 6, 9,10, 5, 6,10, 5,15,10,10,
	10,10, 7, 7, 6,10, 9,12, 9, 9, 8, 7, 3, 7, 9, 5
	};

const UINT8 timesFontWidths24PointRegular[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 5, 6, 8,11,11,18,16, 6, 7, 7,10,12, 5, 7, 5, 6,
	11,11,11,11,11,11,11,11,11,11, 6, 5,12,12,12,10,
	19,14,14,14,15,13,12,15,15, 6, 8,15,12,18,15,15,
	12,15,14,11,12,15,15,19,14,15,12, 7, 6, 7,10,11,
	 6, 9,10, 9,10, 9, 7,10,10, 6, 6,10, 6,16,10,11,
	10,10, 7, 8, 6,11,10,15,10, 9, 9,10, 3,10,11, 5
	};
const UINT8 timesFontWidths24PointBold[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 5, 7,12,11,11,20,18, 7, 7, 7,11,12, 5, 7, 5, 6,
	11,11,11,11,11,11,11,11,11,11, 7, 7,12,12,12,11,
	20,15,15,15,15,14,14,16,16, 7,11,17,14,19,15,16,
	14,16,15,12,13,15,15,20,15,15,13, 7, 6, 7,12,11,
	 7,11,11,10,11,10, 7,11,11, 5, 6,11, 5,17,11,11,
	11,11, 8, 8, 7,11,11,15,10,10, 9, 8, 5, 8,11, 5
	};


const UINT8 timesFontWidths100PointRegular[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	22,29,35,42,42,73,68,22,29,29,42,50,22,28,22,25,
	42,42,42,42,42,42,42,42,42,42,24,24,50,50,50,40,
	81,62,59,59,64,54,47,64,64,28,35,62,52,77,65,64,
	53,64,59,49,59,64,62,83,64,64,53,29,24,29,40,46,
	28,39,44,39,44,39,29,42,44,23,24,44,23,67,44,44,
	44,44,30,34,24,44,43,63,42,42,39,42,16,42,48,22
	};

const UINT8 arialFontWidths16PointRegular[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 4, 3, 5, 7, 7,12, 9, 4, 4, 4, 5, 8, 4, 4, 4, 4,
	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 8, 8, 8, 7,
	13, 9, 9, 9, 9, 9, 8,10, 9, 3, 6, 9, 7,11, 9,10,
	 9,10, 9, 9, 7, 9, 9,13, 7, 9, 7, 4, 4, 4, 5, 7,
	 4, 7, 7, 7, 7, 7, 3, 7, 7, 3, 3, 7, 3,11, 7, 7,
	 7, 7, 4, 7, 4, 7, 5, 9, 7, 7, 7, 4, 3, 4, 8, 4
	};
const UINT8 arialFontWidths16PointBold[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 4, 4, 6, 7, 7,10, 9, 4, 4, 4, 5, 8, 4, 4, 4, 4,
	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 8, 8, 8, 8,
	13, 9, 9, 9, 9, 8, 8,10, 9, 4, 7, 9, 8,11, 9,10,
	 9,10, 9, 9, 8, 9, 9,13, 9, 8, 7, 4, 4, 4, 8, 7,
	 4, 8, 8, 7, 8, 8, 4, 8, 8, 4, 4, 7, 4,12, 8, 8,
	 8, 8, 5, 6, 4, 8, 7,11, 8, 7, 7, 5, 3, 5, 8, 3
	};
const UINT8 arialFontWidths16PointItalics[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 4, 4, 5, 7, 7,12, 9, 4, 4, 4, 5, 8, 4, 4, 4, 4,
	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 8, 8, 8, 7,
	13, 9, 9, 9, 9, 9, 8,10, 9, 4, 7, 9, 7,10, 9,10,
	 9,10, 9, 9, 8, 9, 9,13, 9, 9, 8, 4, 4, 4, 6, 7,
	 4, 7, 8, 7, 7, 7, 4, 7, 7, 3, 3, 8, 3,11, 7, 7,
	 7, 7, 4, 7, 4, 7, 6, 8, 6, 6, 7, 4, 3, 4, 8, 4
	};

const UINT8 arialFontWidths16PointBoldItalics[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 4, 4, 6, 7, 7,11, 9, 4, 4, 4, 5, 8, 4, 4, 4, 4,
	 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 4, 4, 8, 8, 8, 8,
	12,10, 9, 9, 9, 9, 8,10, 9, 3, 7, 9, 8,12, 9,10,
	 8,10, 9, 9, 8, 9, 9,13, 9, 9, 9, 4, 4, 4, 8, 7,
	 4, 7, 8, 7, 8, 7, 4, 8, 8, 4, 4, 8, 4,12, 8, 8,
	 8, 8, 5, 6, 4, 8, 7,10, 7, 7, 7, 5, 3, 5, 8, 4
	};

const UINT8 arialFontWidths20PointRegular[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 5, 5, 6, 9, 9,15,11, 6, 6, 6, 7,10, 5, 6, 5, 5,
	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 5, 5,10,10,10, 9,
	17,11,11,12,12,11,10,12,11, 5, 9,11, 9,13,11,12,
	11,12,11,11, 9,11,11,17,11,11, 9, 5, 5, 5, 7, 9,
	 6, 9, 9, 9, 9, 9, 5, 9, 9, 4, 3, 8, 3,13, 9, 9,
	 9, 9, 6, 8, 4, 9, 7,11, 7, 9, 8, 6, 5, 6,10, 5
	};
const UINT8 arialFontWidths20PointBold[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 5, 6, 8, 9, 9,16,12, 6, 6, 6, 7,10, 5, 6, 5, 5,
	 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 6, 6,10,10,10,10,
	17,11,12,12,12,11,10,13,12, 4, 9,12,10,13,12,13,
	11,13,12,11,10,12,11,17,11,10, 9, 6, 5, 6,10, 9,
	 6, 9,10, 9,10, 9, 5,10,10, 4, 4, 9, 4,14,10,10,
	10,10, 7, 9, 6,10, 9,13, 9, 9, 9, 7, 4, 7,10, 5
	};

const UINT8 arialFontWidths24PointRegular[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 6, 6, 7,12,12,19,14, 7, 7, 7, 8,12, 6, 7, 6, 6,
	12,12,12,12,12,12,12,12,12,12, 6, 6,12,12,12,12,
	21,13,14,15,15,14,13,16,14, 6,11,14,12,17,14,16,
	14,16,15,14,12,14,13,21,14,14,13, 6, 6, 6, 8,12,
	 7,12,11,11,11,12, 6,11,11, 5, 4,10, 4,16,11,12,
	11,11, 7,11, 6,11,11,15,10,11, 9, 7, 6, 7,12, 6
	};
const UINT8 arialFontWidths24PointBold[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 6, 7, 9,11,11,17,14, 7, 7, 7, 8,12, 6, 7, 6, 6,
	11,11,11,11,11,11,11,11,11,11, 7, 7,12,12,12,12,
	20,13,14,14,14,13,12,16,14, 5,11,14,12,17,14,16,
	13,16,14,13,13,14,13,19,13,13,11, 7, 6, 7,12,11,
	 7,11,12,11,12,11, 7,12,12, 5, 5,11, 5,17,12,12,
	12,12, 8,11, 7,12,11,15,11,11,10, 8, 6, 8,12, 6
	};



const UINT8 systemFontWidths16PointAll[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 4, 4, 6, 8, 8,11, 9, 5, 4, 4, 6, 8, 4, 4, 4, 4,
	 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 4, 4, 8, 8, 8, 8,
	14, 8,10, 9,10, 9, 8,10,10, 4, 7, 9, 8,12,10,10,
	 9,10,10, 9, 8,10, 8,14, 9,10, 9, 4, 4, 4, 5, 8,
	 5, 8, 8, 7, 8, 8, 4, 8, 8, 4, 4, 7, 4,12, 8, 8,
	 8, 8, 5, 8, 4, 8, 8,10, 8, 8, 8, 5, 4, 5, 5, 4
	};
const UINT8 systemFontWidths36PointAll[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	 8, 8,12,16,16,22,18,10, 8, 8,12,16, 8, 8, 8, 8,
	16,16,16,16,16,16,16,16,16,16, 8, 8,16,16,16,16,
	27/*?*/,16,20,18,20,18,16,20,20, 8,14,18,16,24/*?*/,20,20,
	18,20,20,18,16,20,16,28,18,20,18, 8, 8, 8,10,16,
	10,16,16,14,16,16, 8,16,16, 8, 8,14, 8,24/**?**/,16,16,
	16,16,10,16, 8,16,16,20,16,16,16,10, 8,10,10, 8
	};
const UINT8 systemFontWidths48PointAll[
	SBCS_NUM_CHARS - SBCS_FIRST_NON_CONTROL_CHAR] = {
	12,12,18,24,24,33,27,14,12,12,18,24,12,12,12,12,
	24,24,24,24,24,24,24,24,24,24,12,12,24,24,24,24,
	42,24,30,27,30,27,24,30,30,12,21,27,24,36,30,30,
	27,30,30,27,24,30,24,42,27,30,27,12,12,12,15,24,
	15,24,24,21,24,24,12,24,24,12,12,21,12,36,24,24,
	24,24,15,24,12,24,24,30,24,24,24,15,12,15,15,12
	};


#define UNKNOWN_CHAR_CONVERSION	    0x20
#define UNDEFINED_CHAR_CONVERSION   0x00
#define FIRST_UPPER_128_CHAR_INDEX  0x80
/* 0x80 up to the defined value are unspecified for all these: */
#define FIRST_UPPER_ISO_8859_1_INDEX	0xA0
#define FIRST_UPPER_ISO_8859_2_INDEX	0xA0
#define FIRST_UPPER_ISO_8859_5_INDEX	0xA0 
#define FIRST_UPPER_ISO_8859_6_INDEX	0xA0
#define FIRST_UPPER_ISO_8859_7_INDEX	0xA0
#define FIRST_UPPER_ISO_8859_8_INDEX	0xA0
#define FIRST_UPPER_ISO_8859_9_INDEX	0xA0
#define FIRST_UPPER_ISO_8859_11_INDEX	0xA0
#define FIRST_UPPER_ISO_8859_13_INDEX	0xA0
/* Each lower-case char is 0x20 higher than the upper case one in the
   conversion to windows-1251 from KOI8-R: */
#define KOI8_R_LOWER_CASE_CHAR_OFFSET 0x20 
#define UPPER_128_CHAR_COUNT	    0x80
//
//mac-roman to iso8859-1:   (http://czyborra.com/charsets/mac-roman.gif)
//_______________________
//
//(starting at 0x80):
//XXXEH- those prefaced by a "/*?*/" mean that the value therein is a
// good (?) substite.  "/*?|x*/ means that x might also be a good subsitute:
const UINT8 macRoman_to_iso88591[UPPER_128_CHAR_COUNT] =
	{
	/*0x80:*/ 0xc4, 0xc5, 0xc7, 0xc9, 0xd1, 0xd6, 0xdc, 0xe1,
	/*0x88:*/0xe0, 0xe2, 0xe4, 0xe3, 0xe5, 0xe7, 0xe9, 0xe8,
	/*0x90:*/0xea, 0xeb, 0xed, 0xec, 0xee, 0xef, 0xf1, 0xf3,
	/*0x98:*/0xf2, 0xf4, 0xf6, 0xf5, 0xfa, 0xf9, 0xFB, 0xFC,
	/*0xA0:*/UNKNOWN_CHAR_CONVERSION, 0xB0, 0xA2, 0xA3, 0xA7, /*?*/0xB7,
		    0xB6, 0xDF,
	/*0xA8:*/0xAE, 0xA9, /*?*/0x99, 0xB4, 0xA8, /*?|0x3D*/0x2F, 0xC6,
		    0xD8,
	/*0xB0:*/UNKNOWN_CHAR_CONVERSION, 0xB1, /*?|0x5F*/0x3C,
		    /*?|0x5F*/0x3E, 0xA5, 0xB5, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION,
	/*0xB8:*/UNKNOWN_CHAR_CONVERSION, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION, 0xAA, 0xBA,
		    UNKNOWN_CHAR_CONVERSION, 0xE6, 0xF8,

	/*0xC0:*/0xBF, 0xA1, 0xAC, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION, 0xAB,
	/*0xC8:*/0xBB, UNKNOWN_CHAR_CONVERSION, 0xA0, 0xC0, 0xC3, 0xD5,
		    UNKNOWN_CHAR_CONVERSION, UNKNOWN_CHAR_CONVERSION,
	/*0xD0:*/UNKNOWN_CHAR_CONVERSION, 0xAD, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION, 0xF7, UNKNOWN_CHAR_CONVERSION,
	/*0xD8:*/0xFF, UNKNOWN_CHAR_CONVERSION, /*?*/0x2F, 0xA4, /*?*/0x3C,
		    /*?*/0x3E, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION,
	/*0xE0:*/UNKNOWN_CHAR_CONVERSION, 0xB7, 0xB8,
		    UNKNOWN_CHAR_CONVERSION, UNKNOWN_CHAR_CONVERSION, 0xC2,
		    0xCA, 0xC1,
	/*0xE8:*/0xCB, 0xC8, 0xCD, 0xCE, 0xCF, 0xCC, 0xD3, 0xD3,
	/*0xF0:*/UNKNOWN_CHAR_CONVERSION, 0xD2, 0xDA, 0xDB, 0xD9,
		    UNKNOWN_CHAR_CONVERSION, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION,
	/*0xF8:*/0xAF, UNKNOWN_CHAR_CONVERSION, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION, 0xB8, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION, UNKNOWN_CHAR_CONVERSION
	};
//
//iso8859-1 to mac-roman:
//	(http://czyborra.com/charsets/iso8859.html#ISO-8859-1)
//_______________________
//
//(starting at 0x80):
const UINT8 iso88591_to_macRoman[UPPER_128_CHAR_COUNT] =
	{
	/*0x80:*/UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
	/*0x88:*/UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
	/*0x90:*/UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
	/*0x98:*/UNDEFINED_CHAR_CONVERSION, 0xAA, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION, UNDEFINED_CHAR_CONVERSION,
		    UNDEFINED_CHAR_CONVERSION,
	/*0xA0:*/0xCA, 0xC1, 0xA2, 0xA3, 0xDB, 0xB4, UNKNOWN_CHAR_CONVERSION,
		    0xA4,
	/*0xA8:*/0xAC, 0xA9, 0xBB, 0xC7, 0xC2, 0xD1, 0xA8, 0xF8,
	/*0xB0:*/0xA1, 0xB1, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION, 0xAB, 0xB5, 0xA6,/*|0xA5?*/0xE1,
	/*0xB8:*/ /*|0xE2?*/0xFC, UNKNOWN_CHAR_CONVERSION, 0xBC, 0xC8,
		    UNKNOWN_CHAR_CONVERSION, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION, 0xC0,

	/*0xC0:*/0xCB, 0xE7, 0xE5, 0xCC, 0x80, 0x81, 0xAE, 0x82,
	/*0xC8:*/0xE9, 0x83, 0xE6, 0xE8, 0xED, 0xEA, 0xEB, 0xEC,
	/*0xD0:*/UNKNOWN_CHAR_CONVERSION, 0x84, 0xF1, 0xEE, 0xEF, 0xCD, 0x85,
		    /*?:use small 'x' for multiply sign:*/0x78,
	/*0xD8:*/0xAF, 0xF4, 0xF2, 0xF3, 0x86, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION, 0xA7,
	/*0xE0:*/0x88, 0x87, 0x89, 0x8B, 0x8A, 0x8C, 0xBE, 0x8D,
	/*0xE8:*/0x8F, 0x8E, 0x90, 0x91, 0x93, 0x92, 0x94, 0x95,
	/*0xF0:*/UNKNOWN_CHAR_CONVERSION, 0x96, 0x98, 0x97, 0x99, 0x9B, 0x9A,
		    0xD6,
	/*0xF8:*/0xBF, 0x9D, 0x9C, 0x9E, 0x9F, UNKNOWN_CHAR_CONVERSION,
		    UNKNOWN_CHAR_CONVERSION, 0xD8
	};


const UINT8 iso88595_to_windows1251_A0_to_AF[16] =
	{
	/*0xA0:*/0xA0, 0xA8, 0x80, 0x81, 0xAA, 0xBD, 0xB2, 0xAF,
		    0xA3, 0x8A, 0x8C, 0x8E, 0x8D, 0xAD, 0xA1, 0x8F
	};

const UINT8 iso88595_to_windows1251_F0_to_FF[16] =
	{
	/*0xF0:*/0xB9, 0xB8, 0x90, 0x83, 0xBA, 0xBE, 0xB3, 0xBF,
		    0xBC, 0x9A, 0x9C, 0x9E, 0x9D, 0xA7, 0xA2, 0x9F
	};

const UINT8 koi8r_to_windows1251_E0_to_FF[32] =
	{
	/*0xE0:*/ 0xDE, 0xC0, 0xC1, 0xD6, 0xC4, 0xC5, 0xD4, 0xC3,
		    0xD5, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE,
	/*0xF0:*/ 0xCF, 0xDF, 0xD0, 0xD1, 0xD2, 0xD3, 0xC6, 0xC2,
		    0xDC, 0xDB, 0xC7, 0xD8, 0xDD, 0xD9, 0xD7, 0xDA
	};



/////////////////////////////////////////////////////////////////////////////
//
//  This function converts text that was authored in the mac-roman charset
//  to iso-8859-1 if we're in a renderer on a non-Mac machine, and vice
//  versa.
//
//  Returns FALSE if there was a problem, e.g., pBuf NULL.
//
BOOL ConvertAcrossCharacterSets(_CHAR* pBuf, ULONG32 ulCharset,
				BOOL bRendererIsCallingThis,
				UINT16 uiMaxSupportedLevel)
{
    if (!pBuf)
    {
	return FALSE;
    }
    else if (!bRendererIsCallingThis)
    {
	return TRUE; //nothing to do!  We only want to convert in renderer.
    }
#if defined(_MACINTOSH)
    if(CHARSET__us_ascii == ulCharset  ||  CHARSET__iso_8859_1 == ulCharset)
    {
	//Charset when authored was not mac-roman so we need to convert all
	// above 128 (0x80) to Mac chars for display on this Mac if authored
	// in the iso-8859-1 or us-ascii charset.  Note that iso-8859-1 doesn't
	// define what characters are in the range from 0x80 to 0x9F:
	while (*pBuf)
	{
	    if ((UINT8)(*pBuf) >= (UINT8)FIRST_UPPER_128_CHAR_INDEX)
	    {
		_CHAR tmpCh = iso88591_to_macRoman[
			(UINT8)(*pBuf) - (UINT8)FIRST_UPPER_128_CHAR_INDEX];
		//Don't translate if there is no matching character:
		if (UNKNOWN_CHAR_CONVERSION != tmpCh  &&
			UNDEFINED_CHAR_CONVERSION != tmpCh)
		{
		    *pBuf = tmpCh;
		}
	    }
	    pBuf++;
	}
	goto cleanup;
    }

    if (uiMaxSupportedLevel < 1) // /RealText 1.0 is level 0 only.
    {
	goto cleanup;
    }

    if (CHARSET__iso_8859_5 == ulCharset  ||
	    CHARSET__koi8_r == ulCharset)
    {
	HX_ASSERT(0  &&  "handle_MacCyrillic(Ukranian?)_charset");
    }
#else
    // /What do you see when an infant eats food for the first time?:
    const UINT8 ucFirstHighChar = FIRST_UPPER_128_CHAR_INDEX;
    if(CHARSET__x_mac_roman == ulCharset)
    {
	//WINDOWS and UNIX need conversion, if mac-roman charset, to the
	// iso-8859-1 charset:
	while (*pBuf)
	{
	    if ((UINT8)(*pBuf) >= ucFirstHighChar)
	    {
		_CHAR tmpCh = macRoman_to_iso88591[
			(UINT8)(*pBuf) - ucFirstHighChar];
		//Translate only if there is a matching character:
		if (UNKNOWN_CHAR_CONVERSION != tmpCh  &&
			UNDEFINED_CHAR_CONVERSION != tmpCh)
		{
		    *pBuf = tmpCh;
		}
	    }
	    pBuf++;
	};
	goto cleanup;
    }

    if (uiMaxSupportedLevel < 1) // /RealText 1.0 is level 0 only.
    {
	goto cleanup;
    }

    if  (CHARSET__us_ascii == ulCharset)
    {
	while (*pBuf)
	{
	    UINT8 uCh = (UINT8)(*pBuf);
	    if ((UINT8)(*pBuf) >= FIRST_UPPER_128_CHAR_INDEX)
	    {
		// /None of these chars are defined, so do what browsers do
		// and ignore the high-order bit:
		*pBuf &= 0x7F;
	    }
	    pBuf++;
	};
	// /Caller should now be sure to handle the change in actual charset!
    }
    else if  (CHARSET__iso_8859_1 == ulCharset) // /Western European
    {
	while (*pBuf)
	{
	    UINT8 uCh = (UINT8)(*pBuf);
	    if (uCh >= FIRST_UPPER_ISO_8859_1_INDEX)
	    {
		; // /They're all OK; WinLatin1 maps to iso-8859-1
	    }
	    else if ((UINT8)(*pBuf) >= FIRST_UPPER_128_CHAR_INDEX)
	    {
		// /Convert 0x80-0x9F chars that are not in iso-8859-9 to nbsp:
		*pBuf = (_CHAR)0xA0;
	    }
	    pBuf++;
	};
	// /Caller should now be sure to handle the change in actual charset!
    }
    else if (CHARSET__iso_8859_2 == ulCharset) // /Eastern European
    {
	while (*pBuf)
	{
	    UINT8 uCh = (UINT8)(*pBuf);
	    if ((UINT8)(*pBuf) >= FIRST_UPPER_ISO_8859_2_INDEX)
	    {
		// /Note: I manually made these translations by comparing the
		// codepages  -eh:
		if (0xA0 == uCh  ||  (uCh >= 0xA2  &&  uCh <= 0xA4)  ||
			0xA7 == uCh  ||  0xA8 == uCh  ||  0xAA == uCh  ||
			0xAD == uCh  ||  (uCh >= 0xAF  &&  uCh <= 0xB0)  ||
			(uCh >= 0xB2  &&  uCh <= 0xB4)  ||  0xB8 == uCh  ||
			0xBA == uCh  ||  (uCh >= 0xC0  &&  uCh <= 0xFF) )
		{
		    ; // /It's OK as is.
		}
		else if (0xA1 == uCh)
		{
		    *pBuf = (_CHAR)0xA5;
		}
		else if (0xA5 == uCh)
		{
		    *pBuf = (_CHAR)0xBC;
		}
		else if (0xA6 == uCh  ||  0xB6 == uCh)
		{
		    *pBuf -= 0x1A; // /A6->8C, B6->9C
		}
		else if (0xA9 == uCh  ||  0xAE == uCh  ||  0xB9 == uCh)
		{
		    *pBuf -= 0x1F; // /A9->8A, AE->8E, B9->9A
		}
		else if (0xAB == uCh  ||  0xBB == uCh)
		{
		    *pBuf -= 0x1E; // /AB->8D, BB->9D
		}
		else if (0xAC == uCh  ||  0xBC == uCh)
		{
		    *pBuf -= 0x1D; // /AC->8F, BC->9F
		}
		else if (0xB1 == uCh)
		{
		    *pBuf = (_CHAR)0xB9;
		}
		else if (0xB5 == uCh)
		{
		    *pBuf = (_CHAR)0xBE;
		}
		else if (0xB7 == uCh)
		{
		    *pBuf = (_CHAR)0xA1;
		}
		else if (0xBD == uCh)
		{
		    *pBuf = (_CHAR)0x94;
		}
		else if (0xBE == uCh  ||  0xBF == uCh)
		{
		    *pBuf -= 0x20; // /BE->9E, BF->9F
		}
	    }
	    else if ((UINT8)(*pBuf) >= FIRST_UPPER_128_CHAR_INDEX)
	    {
		// /Convert 0x80-0x9F chars that are not in iso-8859-5 to nbsp:
		*pBuf = (_CHAR)0xA0;
	    }
	    pBuf++;
	};
	// /Caller should now be sure to handle the change in actual charset!
    }
    else if (CHARSET__iso_8859_5 == ulCharset) // /Cyrillic
    {
	while (*pBuf)
	{
	    if ((UINT8)(*pBuf) >= FIRST_UPPER_ISO_8859_5_INDEX)
	    {
		// /Note: I manually made these translations by comparing the
		// codepages  -eh:
		if ((UINT8)(*pBuf) < 0xB0)
		{
		    *pBuf = (_CHAR)iso88595_to_windows1251_A0_to_AF[
			    (UINT8)(*pBuf) - 0xA0];
		}
		else if ((UINT8)(*pBuf) >= 0xF0)
		{
		    *pBuf = (_CHAR)iso88595_to_windows1251_F0_to_FF[
			    (UINT8)(*pBuf) - 0xF0];
		}
		else // /add 0x10 to convert the middle 4 rows:
		{
		    *pBuf += 0x10;
		}
	    }
	    else if ((UINT8)(*pBuf) >= FIRST_UPPER_128_CHAR_INDEX)
	    {
		// /Convert 0x80-0x9F chars that are not in iso-8859-5 to nbsp:
		*pBuf = (_CHAR)0xA0;
	    }
	    pBuf++;
	};
	// /Caller should now be sure to handle the change in actual charset!
    }
    else if (CHARSET__koi8_r == ulCharset) // /Cyrillic
    {
	while (*pBuf)
	{
	    UINT8 uCh = (UINT8)(*pBuf);
	    if ((UINT8)(*pBuf) >= ucFirstHighChar)
	    {
		// /Note: I manually made these translations by comparing the
		// codepages  -eh:
		if (uCh >= 0xE0)
		{
		    *pBuf = (_CHAR)koi8r_to_windows1251_E0_to_FF[
			    uCh - 0xE0];
		}
		else if (uCh >= 0xC0) // /and we know it is < 0xE0
		{
		    *pBuf = (_CHAR)koi8r_to_windows1251_E0_to_FF[
			    uCh - 0xC0 /*-0xC0==(0x20-0xE0) */] +
			    KOI8_R_LOWER_CASE_CHAR_OFFSET;
		}
		else if (0x9A == uCh)
		{
		    *pBuf = (_CHAR)0xA0;// /XXXEH- should be non-breaking space
		}
		else if (0x9C == uCh)
		{
		    *pBuf = (_CHAR)0xB0;
		}
		else if (0x9E == uCh)
		{
		    *pBuf = (_CHAR)0xB7;
		}
		else if (0xA3 == uCh)
		{
		    *pBuf = (_CHAR)0xB8;
		}
		else if (0xB3 == uCh)
		{
		    *pBuf = (_CHAR)0xA8;
		}
		else if (0xBF == uCh)
		{
		    *pBuf = (_CHAR)0xA9;
		}
		else if (0x95 == uCh)
		{
		    ; // /It's stays the same.
		}
		else // /All the others are from the original IBM Personal
		    // Computer with the code page CP437's box-drawing
		    // characters.  We *could* bother to convert them (and
		    // draw each in US-ASCII charset), but won't go to that
		    // trouble unless we get complaints which I *strongly*
		    // doubt will happen.  Instead, just draw them as blanks:
		{
		    *pBuf = (_CHAR)0x98; // /0x98 in Windows-1251 is a box
		}
	    }
	    pBuf++;
	};
	// /Caller should now be sure to handle the change in actual charset!
    }
    else if (CHARSET__iso_8859_6 == ulCharset) // /Arabic
    {
#if defined(RTL_PERFORM_REVERSAL_OF_RTL_CHARS)
	// /First, this is Arabic, so we need to reverse the text of each line:
	_CHAR* pTmpBuf = pBuf;
	_CHAR* pNewline = pTmpBuf;
	while (*pTmpBuf  &&  *pNewline)
	{
	    while (*pNewline  &&  '\r' != *pNewline  &&  '\n' != *pNewline)
	    {
		pNewline++;
	    };
	    _CHAR* pFromLastChar = pNewline-1;
	    while (*pTmpBuf  &&  pTmpBuf < pFromLastChar)
	    {
		_CHAR chTmp = *pFromLastChar;
		*pFromLastChar = *pTmpBuf;
		*pTmpBuf = chTmp;
		pTmpBuf++;
		pFromLastChar--;
	    }
	    if ('\r' == *pNewline  &&  '\n' == pNewline[1])
	    {
		pNewline++; // /Treat \r\n as single char.
	    }
	    if (*pNewline)
	    {
		pNewline++; // /Go look for the next one.
	    }
	    pTmpBuf = pNewline;
	}
#endif

	while (*pBuf)
	{
	    UINT8 uCh = (UINT8)(*pBuf);
	    if (uCh >= FIRST_UPPER_ISO_8859_6_INDEX)
	    {
		// /Note: I manually made these translations by comparing the
		// codepages  -eh:
		if (0xA0 == uCh  ||  0xA4 == uCh  ||  0xAD == uCh  ||
			0xBF == uCh  ||  (uCh >= 0xC1  &&  uCh <= 0xD6))
		{
		    ; // /It's OK as is.
		}
		else if (0xAC == uCh)  // /[Could also translate to 0x60 (?)]
		{
		    *pBuf = (_CHAR)0x91;
		}
		else if (0xBB == uCh)
		{
		    *pBuf = (_CHAR)0xBA;
		}
		else if (uCh >= 0xD7  &&  uCh <= 0xDA)
		{
		    *pBuf += 1;
		}
		else if (uCh >= 0xE0  &&  uCh <= 0xE3)
		{
		    *pBuf -= 4;
		}
		else if (0xE4 == uCh)
		{
		    *pBuf = (_CHAR)0xE1;
		}
		else if (uCh >= 0xE5  &&  uCh <= 0xE8)
		{
		    *pBuf -= 2;
		}
		else if (uCh >= 0xE9  &&  uCh <= 0xEA)
		{
		    *pBuf += 3;
		}
		else if (0xEC == uCh)  // /[Could also translate to 0xF1 (?)]
		{
		    *pBuf = (_CHAR)0x94;
		}
		else if (0xEB == uCh  ||  0xED == uCh  ||  0xEE == uCh)
		{
		    *pBuf +=5;
		}
		else if (0xEF == uCh)  // /[Could also translate to 0xF5 (?)]
		{
		    *pBuf = (_CHAR)0x92;
		}
		else if (0xF0 == uCh)
		{
		    *pBuf +=6;
		}
		else if (0xF1 == uCh)
		{
		    *pBuf +=7;
		}
		else if (0xF2 == uCh)
		{
		    *pBuf += 8;
		}
		else
		{
		    // /Convert chars that are not in iso-8859-6 to nbsp char:
		    *pBuf = (_CHAR)0xA0;
		}
	    }
	    else if ((UINT8)(*pBuf) >= FIRST_UPPER_128_CHAR_INDEX)
	    {
		// /Convert 0x80-0x9F chars that are not in iso-8859-5 to nbsp:
		*pBuf = (_CHAR)0xA0;
	    }
	    pBuf++;
	};
	// /Caller should now be sure to handle the change in actual charset!
    }
    else if (CHARSET__iso_8859_7 == ulCharset) // /Greek
    {
	while (*pBuf)
	{
	    UINT8 uCh = (UINT8)(*pBuf);
	    if (uCh >= FIRST_UPPER_ISO_8859_7_INDEX)
	    {
		// /Note: I manually made these translations by comparing the
		// codepages  -eh:
		if (0xA0 == uCh  ||  0xA3 == uCh  ||
			(uCh >= 0xA6  &&  uCh <= 0xA9)  ||
			(uCh >= 0xAB  &&  uCh <= 0xAD)  ||
			(uCh >= 0xAF  &&  uCh <= 0xB4)  ||
			(uCh >= 0xB7  &&  uCh <= 0xD1)  ||
			(uCh >= 0xD3  &&  uCh <= 0xFE) )
		{
		    ; // /It's OK as is.
		}
		else if (0xA1 == uCh  ||  0xA2 == uCh)
		{
		    *pBuf -= 0x10; // /A1->91, A2->92
		}
		else if (0xB5 == uCh  ||  0xB6 == uCh)
		{
		    *pBuf -= 0x14;  // /B5->A1, B6->A2.
		}
		else
		{
		    // /Convert chars that are not in iso-8859-7 to nbsp char:
		    *pBuf = (_CHAR)0xA0;
		}
	    }
	    else if ((UINT8)(*pBuf) >= FIRST_UPPER_128_CHAR_INDEX)
	    {
		// /Convert 0x80-0x9F chars that are not in iso-8859-7 to nbsp:
		*pBuf = (_CHAR)0xA0;
	    }
	    pBuf++;
	};
	// /Caller should now be sure to handle the change in actual charset!
    }
    else if  (CHARSET__iso_8859_8 == ulCharset) // /Hebrew
    {
	// /XXXEH- NOTE: iso-8859-8's 0xDF doesn't seem to map to anything on
	// Windows; it appears to be a double underline char (low '=').
	while (*pBuf)
	{
	    UINT8 uCh = (UINT8)(*pBuf);
	    if (uCh >= FIRST_UPPER_ISO_8859_8_INDEX)
	    {
		if (0xA1 == uCh  ||  (uCh >= 0xBF  &&  uCh <= 0xDE)  ||
			(uCh >= 0xFB  &&  uCh <= 0xFF) )
		{
		    // /Convert chars that are not in iso-8859-8 to nbsp char:
		    *pBuf = (_CHAR)0xA0;
		}
	    }
	    else if ((UINT8)(*pBuf) >= FIRST_UPPER_128_CHAR_INDEX)
	    {
		// /Convert 0x80-0x9F chars that are not in iso-8859-8 to nbsp:
		*pBuf = (_CHAR)0xA0;
	    }
	    pBuf++;
	};
	// /Caller should now be sure to handle the change in actual charset!
    }
    else if  (CHARSET__iso_8859_9 == ulCharset) // /Turkish
    {
	while (*pBuf)
	{
	    UINT8 uCh = (UINT8)(*pBuf);
	    if (uCh >= FIRST_UPPER_ISO_8859_9_INDEX)
	    {
		; // /All are OK as-is; WinTurkish maps exactly to iso-8859-9
	    }
	    else if ((UINT8)(*pBuf) >= FIRST_UPPER_128_CHAR_INDEX)
	    {
		// /Convert 0x80-0x9F chars that are not in iso-8859-9 to nbsp:
		*pBuf = (_CHAR)0xA0;
	    }
	    pBuf++;
	};
    }
    else if  (CHARSET__iso_ir_166 == ulCharset  ||  // /Thai
	    CHARSET__iso_8859_11 == ulCharset)
    {
	while (*pBuf)
	{
	    UINT8 uCh = (UINT8)(*pBuf);
	    if (uCh >= FIRST_UPPER_ISO_8859_11_INDEX)
	    {
		if ((uCh >= 0xDB  &&  uCh <= 0xDE)  ||
			(uCh >= 0xFC  &&  uCh <= 0xFF) )
		{
		    // /Convert chars that are not in iso-8859-11 to nbsp char:
		    *pBuf = (_CHAR)0xA0;
		}
	    }
	    else if ((UINT8)(*pBuf) >= FIRST_UPPER_128_CHAR_INDEX)
	    {
		// /Convert 0x80-0x9F chars that are not in iso-8859-5 to nbsp:
		*pBuf = (_CHAR)0xA0;
	    }
	    pBuf++;
	};
	// /Caller should now be sure to handle the change in actual charset!
    }
    else if  (CHARSET__iso_8859_13 == ulCharset) // /Baltic (Latin 7)
    {
	while (*pBuf)
	{
	    UINT8 uCh = (UINT8)(*pBuf);
	    if (uCh >= FIRST_UPPER_ISO_8859_13_INDEX)
	    {
		if (0xA0 == uCh  ||
			(uCh >= 0xA2  &&  uCh <= 0xA4)  ||
			(uCh >= 0xA6  &&  uCh <= 0xB3)  ||
			(uCh >= 0xB5  &&  uCh <= 0xFF) )
		{
		    ; // /It's OK as is.
		}
		else if (0xA1 == uCh)
		{
		    *pBuf = (_CHAR)0x94;
		}
		else if (0xA5 == uCh)
		{
		    *pBuf = (_CHAR)0x84;
		}
		else if (0xB4 == uCh)
		{
		    *pBuf = (_CHAR)0x93;
		}
		else
		{
		    // /Convert chars that are not in iso-8859-7 to nbsp char:
		    *pBuf = (_CHAR)0xA0;
		}
	    }
	    else if ((UINT8)(*pBuf) >= FIRST_UPPER_128_CHAR_INDEX)
	    {
		// /Convert 0x80-0x9F chars that are not in iso-8859-5 to nbsp:
		*pBuf = (_CHAR)0xA0;
	    }
	    pBuf++;
	};
	// /Caller should now be sure to handle the change in actual charset!
    }
#endif  /* end of #else (not Mac) */

cleanup:
    return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
//
//  This function returns the "width" in pixels of the character ch, given
//  the font face, font charset, font point size, and whether or not the
//  character is bold &/or italicized:
//
//  WARNING: the value returned may be an error (which is a negative number)
//  so you must check the return val before using it!
//
INT16 GetCharacterWidth(UINT16 ch, ULONG32 ulFontFaceIndex,
	ULONG32 ulFontPtSize, BOOL isBold, BOOL isItalicized,
	ULONG32 ulFontCharsetIndex)
{
    if(ulFontCharsetIndex & HX_SBCS_CHARSET)
    {
	//CAUTION!: This HAS to be a double due to differences in the way
	// float calculations are done in release Vs. debug builds with the
	// Visual C++ compiler (at least version 5.0):
	double fontDerivativeScaleFactor = 1.0;
	if(ch<SBCS_FIRST_NON_CONTROL_CHAR)
	{
	    return 0;
	}
	if(ch>=SBCS_NUM_CHARS)
	{
	    switch(ulFontPtSize)
	    {
		case 8:
		    return UNKNOWN_TIMES_8PT_CHAR_WIDTH;
		case 10:
		    return UNKNOWN_TIMES_10PT_CHAR_WIDTH;
		case 12:
		    return UNKNOWN_TIMES_12PT_CHAR_WIDTH;
		case 14:
		    return UNKNOWN_TIMES_14PT_CHAR_WIDTH;
		case 16:
		    return UNKNOWN_TIMES_16PT_CHAR_WIDTH;
		case 20:
		    return UNKNOWN_TIMES_20PT_CHAR_WIDTH;
		case 24:
		    return UNKNOWN_TIMES_24PT_CHAR_WIDTH;
		case 36:
		    return UNKNOWN_TIMES_36PT_CHAR_WIDTH;
		case 48:
		    return UNKNOWN_TIMES_48PT_CHAR_WIDTH;
	    }
	    return UNKNOWN_TIMES_16PT_CHAR_WIDTH;
	}
	switch(ulFontFaceIndex)
	{
	    case TIMES_FONT_FACE_INDX:
		fontDerivativeScaleFactor = 1.0;
	    case BRUSH_SCRIPT_FONT_FACE_INDX:
		if(BRUSH_SCRIPT_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  0.8319327731092;
	    case COLONNA_MT_FONT_FACE_INDX:
		if(COLONNA_MT_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  1.1134;
	    case COMIC_SANS_MS_FONT_FACE_INDX:
		if(COMIC_SANS_MS_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  1.0; ///XXXEH- need # here!!
	    case GARAMOND_FONT_FACE_INDX:
		if(GARAMOND_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  1.0462;
	    case KINO_MT_FONT_FACE_INDX:
		if(KINO_MT_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  0.8697;
	    case MATURA_MT_SCRIPT_CAPITALS_FONT_FACE_INDX:
		if(MATURA_MT_SCRIPT_CAPITALS_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  1.1849;
	    case MS_DIALOG_FONT_FACE_INDX:
		if(MS_DIALOG_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = 1.0; //XXXEH- need # here!!
	    case MS_DIALOG_LIGHT_FONT_FACE_INDX:
		if(MS_DIALOG_LIGHT_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = 1.0; //XXXEH- need # here!!
	    case MS_SYSTEMEX_FONT_FACE_INDX:
		if(MS_SYSTEMEX_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  1.0; //XXXEH- need # here!!
	    case PLAYBILL_FONT_FACE_INDX:
		if(PLAYBILL_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  0.6513;
	    case SMALL_FONTS_FONT_FACE_INDX:
		if(SMALL_FONTS_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  1.1471;
	    {
do{ //XXXEH- this is here so break will go do default code.
		if(16 == ulFontPtSize)
		{
		    if(isBold)
		    {
			if(isItalicized)
			{
			    return INT16(float(fontDerivativeScaleFactor *
				    double((INT32)
				    timesFontWidths16PointBoldItalics[
				    ch - SBCS_FIRST_NON_CONTROL_CHAR])));
			}
			else
			{
			    return INT16(float(fontDerivativeScaleFactor *
				    double((INT32)
				    timesFontWidths16PointBold[
				    ch - SBCS_FIRST_NON_CONTROL_CHAR])));
			}
		    }
		    else if(isItalicized)
		    {
			return INT16(float(fontDerivativeScaleFactor *
				double((INT32)
				timesFontWidths16PointItalics[
				ch - SBCS_FIRST_NON_CONTROL_CHAR])));
		    }
		    else
		    {
			return INT16(float(fontDerivativeScaleFactor *
				double((INT32)
				timesFontWidths16PointRegular[
				ch - SBCS_FIRST_NON_CONTROL_CHAR])));
		    }
		}
		else if(20 == ulFontPtSize)
		{
		    if(isBold)
		    {
			if(isItalicized)
			{
			    break; //XXXEH- replace with table look-up.
			}
			else
			{
			    return INT16(float(fontDerivativeScaleFactor *
				    double((INT32)
				    timesFontWidths20PointBold[
				    ch - SBCS_FIRST_NON_CONTROL_CHAR])));
			}
		    }
		    else if(isItalicized)
		    {
			break; //XXXEH- replace with table look-up.
		    }
		    else
		    {
			return INT16(float(fontDerivativeScaleFactor *
				double((INT32)
				timesFontWidths20PointRegular[
				ch - SBCS_FIRST_NON_CONTROL_CHAR])));
		    }
		}
		else if(24 == ulFontPtSize)
		{
		    if(isBold)
		    {
			if(isItalicized)
			{
			    break; //XXXEH- replace with table look-up.
			}
			else
			{
			    return INT16(float(fontDerivativeScaleFactor *
				    double((INT32)
				    timesFontWidths24PointBold[
				    ch - SBCS_FIRST_NON_CONTROL_CHAR])));
			}
		    }
		    else if(isItalicized)
		    {
			break; //XXXEH- replace with table look-up.
		    }
		    else
		    {
			return INT16(float(fontDerivativeScaleFactor *
				double((INT32)
				timesFontWidths24PointRegular[
				ch - SBCS_FIRST_NON_CONTROL_CHAR])));
		    }
		}
}while(0);		
		float foo = 
			float(fontDerivativeScaleFactor *
			double(float(ulFontPtSize *
			UINT32((UINT16)timesFontWidths100PointRegular[
			ch - SBCS_FIRST_NON_CONTROL_CHAR]))) / double(100.0));
		if(foo > INT16(foo))
		{
		    foo++;
		}
		return (INT16(foo));
	    }

	    case COURIERTT_FONT_FACE_INDX:
		fontDerivativeScaleFactor = 1.0;
	    case FIXEDSYS_FONT_FACE_INDX:
		if(FIXEDSYS_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = .8062;
	    case ALGERIAN_FONT_FACE_INDX:
		if(ALGERIAN_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =    0.9213;
	    {
		switch(ulFontPtSize)
		{
		    case FONT_SIZE_MINUS2:
		    {
			return INT16(float(fontDerivativeScaleFactor *
				double(.875 * (ulFontPtSize/2))));
		    }

		    case FONT_SIZE_MINUS1:
		    {
			break;
		    }

		    case FONT_SIZE_0:
		    {
			if(isBold  ||  isItalicized)
			{
			    return INT16(float(fontDerivativeScaleFactor *
				    double(.875 * (ulFontPtSize/2))));
			}
			break;
		    }

		    case FONT_SIZE_PLUS1:
		    {
			break;
		    }

		    case FONT_SIZE_PLUS2:
		    {
			return INT16(float(fontDerivativeScaleFactor *
				    double(1.125 * (ulFontPtSize/2))));
		    }

		    case FONT_SIZE_PLUS3:
		    {
			if(isItalicized  &&  !isBold)
			{
			    return INT16(float(fontDerivativeScaleFactor *
				    double(1.125 * (ulFontPtSize/2))));
			}
			return INT16(float(fontDerivativeScaleFactor *
				    double(1.1 * (ulFontPtSize/2))));
		    }

		    case FONT_SIZE_PLUS4:
		    {
			if(isBold  ||  isItalicized)
			{
			    return INT16(float(fontDerivativeScaleFactor *
				    double(1.05 * (ulFontPtSize/2))));
			}
			return INT16(float(fontDerivativeScaleFactor *
				    double(1.125 * (ulFontPtSize/2))));
		    }
		}
		return INT16(float(fontDerivativeScaleFactor *
			double(ulFontPtSize/2)));
	    }

	    case SYSTEM_FONT_FACE_INDX:
		fontDerivativeScaleFactor =  1.0;
	    case TERMINAL_FONT_FACE_INDX:
		if(TERMINAL_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  1.0717;
	    {
		if(16 == ulFontPtSize)
		{
		    return INT16(float(fontDerivativeScaleFactor *
			    double((INT32)systemFontWidths16PointAll[
			    ch - SBCS_FIRST_NON_CONTROL_CHAR])));
		}
		else if(36 == ulFontPtSize)
		{
		    return INT16(float(fontDerivativeScaleFactor *
			    double((INT32)systemFontWidths36PointAll[
			    ch - SBCS_FIRST_NON_CONTROL_CHAR])));
		}
		else if(48 == ulFontPtSize)
		{
		    return INT16(float(fontDerivativeScaleFactor *
			    double((INT32)systemFontWidths48PointAll[
			    ch - SBCS_FIRST_NON_CONTROL_CHAR])));
		}

		//XXXEH- need lookup table!
		float foo;
		if(ulFontPtSize == 48  &&  1.0 == fontDerivativeScaleFactor)
		{
		    foo = float(UINT32((UINT16)systemFontWidths48PointAll[
			ch - SBCS_FIRST_NON_CONTROL_CHAR]));
		}
		else
		{
		    foo = 
			float(fontDerivativeScaleFactor *
			double(float(ulFontPtSize *
			UINT32((UINT16)systemFontWidths48PointAll[
			ch - SBCS_FIRST_NON_CONTROL_CHAR]))) / double(48.0));
		}
		if(foo > INT16(foo))
		{
		    foo++;
		}
		return (INT16(foo));
	    }

	    case ARIAL_FONT_FACE_INDX:
		fontDerivativeScaleFactor = 1.0;
	    case ARIAL_BLACK_FONT_FACE_INDX:
		if(ARIAL_BLACK_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  1.3;
	    case ARIAL_NARROW_FONT_FACE_INDX:
		if(ARIAL_NARROW_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  0.855;
	    case ARIAL_ROUNDED_MT_BOLD_FONT_FACE_INDX:
		if(ARIAL_ROUNDED_MT_BOLD_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  1.1561;
	    case BOOK_ANTIQUA_FONT_FACE_INDX:
		if(BOOK_ANTIQUA_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =   1.0297;
	    case BOOKMAN_OLD_STYLE_FONT_FACE_INDX:
		if(BOOKMAN_OLD_STYLE_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =   1.1412;
	    case BRAGGADOCIO_FONT_FACE_INDX:
		if(BRAGGADOCIO_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =   1.5204;
	    case BRITANNIC_BOLD_FONT_FACE_INDX:
		if(BRITANNIC_BOLD_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =   1.0335;
	    case CENTURY_GOTHIC_FONT_FACE_INDX:
		if(CENTURY_GOTHIC_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =   1.1487;
	    case CENTURY_SCHOOLBOOK_FONT_FACE_INDX:
		if(CENTURY_SCHOOLBOOK_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =   1.0595;
	    case DESDEMONA_FONT_FACE_INDX:
		if(DESDEMONA_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  1.0;
	    case FOOTLIGHT_MT_LIGHT_FONT_FACE_INDX:
		if(FOOTLIGHT_MT_LIGHT_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor =  1.0;
	    case HAETTENSCHWEILER_FONT_FACE_INDX:
		if(HAETTENSCHWEILER_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = .8; //0.7323;
	    case HELVETICA_FONT_FACE_INDX:
		if(HELVETICA_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = 1.0;
	    case IMPACT_FONT_FACE_INDX:
		if(IMPACT_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = 0.9294;
	    case MODERN_FONT_FACE_INDX:
		if(MODERN_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = 1.0;
	    case MS_LINEDRAW_FONT_FACE_INDX:
		if(MS_LINEDRAW_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = 1.0;
	    case MS_SANS_SERIF_FONT_FACE_INDX:
		if(MS_SANS_SERIF_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = 1.0297;
	    case MS_SERIF_FONT_FACE_INDX:
		if(MS_SERIF_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = 0.9331;
	    case VERDANA_FONT_FACE_INDX:
		if(VERDANA_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = 1.1933;
	    case WIDE_LATIN_FONT_FACE_INDX:
		if(WIDE_LATIN_FONT_FACE_INDX == ulFontFaceIndex)
		    fontDerivativeScaleFactor = 1.9368;
	    {
do{ //XXXEH- this is here so break will go do default code.
		if(16 == ulFontPtSize)
		{
		    if(isBold)
		    {
			if(isItalicized)
			{
			    return INT16(float(fontDerivativeScaleFactor *
				    double((INT32)
				    (INT32)arialFontWidths16PointBoldItalics[
				    ch - SBCS_FIRST_NON_CONTROL_CHAR])));
			}
			else
			{
			    return INT16(float(fontDerivativeScaleFactor *
				    double((INT32)
				    (INT32)arialFontWidths16PointBold[
				    ch - SBCS_FIRST_NON_CONTROL_CHAR])));
			}
		    }
		    else if(isItalicized)
		    {
			return INT16(float(fontDerivativeScaleFactor *
				double((INT32)
				arialFontWidths16PointItalics[
				ch - SBCS_FIRST_NON_CONTROL_CHAR])));
		    }
		    else
		    {
			return INT16(float(fontDerivativeScaleFactor *
				double((INT32)
				arialFontWidths16PointRegular[
				ch - SBCS_FIRST_NON_CONTROL_CHAR])));
		    }
		}
		else if(20 == ulFontPtSize)
		{
		    if(isBold)
		    {
			if(isItalicized)
			{
			    break; //XXXEH- replace with table look-up.
			}
			else
			{
			    return INT16(float(fontDerivativeScaleFactor *
				    double((INT32)
				    arialFontWidths20PointBold[
				    ch - SBCS_FIRST_NON_CONTROL_CHAR])));
			}
		    }
		    else if(isItalicized)
		    {
			break; //XXXEH- replace with table look-up.
		    }
		    else
		    {
			return INT16(float(fontDerivativeScaleFactor *
				double((INT32)
				arialFontWidths20PointRegular[
				ch - SBCS_FIRST_NON_CONTROL_CHAR])));
		    }
		}
		else if(24 == ulFontPtSize)
		{
		    if(isBold)
		    {
			if(isItalicized)
			{
			    break; //XXXEH- replace with table look-up.
			}
			else
			{
			    return INT16(float(fontDerivativeScaleFactor *
				    double((INT32)
				    arialFontWidths24PointBold[
				    ch - SBCS_FIRST_NON_CONTROL_CHAR])));
			}
		    }
		    else if(isItalicized)
		    {
			break; //XXXEH- replace with table look-up.
		    }
		    else
		    {
			return INT16(float(fontDerivativeScaleFactor *
				double((INT32)
				arialFontWidths24PointRegular[
				ch - SBCS_FIRST_NON_CONTROL_CHAR])));
		    }
		}
}while(0);		
		//XXXEH- need lookup table!
		float foo;
		//Floating point error in release build forces the first part
		// of this if to have to be added (release build was
		// calculating:
		// float(24) / (24.0) = 1.000000001
		// (when it should be simply 1.0).
		if(24 == ulFontPtSize  &&  1.0 == fontDerivativeScaleFactor)
		{
		    foo = float(UINT32((UINT16)arialFontWidths24PointRegular[
			ch - SBCS_FIRST_NON_CONTROL_CHAR]));
		}
		else
		{
		    foo = 
			float((fontDerivativeScaleFactor *
			double(float(ulFontPtSize *
			UINT32((UINT16)arialFontWidths24PointRegular[
			ch - SBCS_FIRST_NON_CONTROL_CHAR]))) /
			double(24.0)));
		}
		if(foo > INT16(foo))
		{
		    foo++;
		}
		return (INT16(foo));
	    }
	}
	return INT16(ulFontPtSize/2);
    }
    else if(ulFontCharsetIndex & HX_DBCS_CHARSET)
    {
	if(ch > 0x00FF) //then is two-byte char:
	{
	    return INT16(ulFontPtSize);
	}
	return INT16(ulFontPtSize/2);
    }
    else if(ulFontCharsetIndex & HX_UNICODE_CHARSET)
    {
	return INT16(ulFontPtSize);
    }

    return FONTINFO_ERROR_UNKNOWN_CHARSET;
}



/////////////////////////////////////////////////////////////////////////////
//
//  This function returns the "width" in pixels of the string pStr, given
//  the font face, font charset, font point size, and whether or not the
//  character is bold &/or italicized:
//
//  WARNING: the value returned may be an error (which is a negative number)
//  so you must check the return val before using it!  A negative number is
//  the negative of the width found up to the point of error, so zero return
//  means error occurred before any char widths were calculated.
//
INT16 GetStringWidthInPixels(_CHAR* pStr, ULONG32 len,
	ULONG32 ulFontFaceIndex, ULONG32 ulFontPtSize, BOOL isBold,
	BOOL isItalicized, ULONG32 ulFontCharsetIndex)
{
    INT16 totalWidth = 0L;
    if(!pStr  ||  !len)
    {
	return totalWidth;
    }
    
    ULONG32 ulIndx;
    for(ulIndx=0; ulIndx<len; ulIndx++)
    {
	if(ulFontCharsetIndex & HX_DBCS_CHARSET)
	{
	    if((UCHAR)pStr[ulIndx]>= DBCS_MIN_LEAD_BYTE_VAL)
	    {
		//Is a 2-byte character, so deal with it:
		if(len-1==ulIndx)//shouldn't happen! Lead byte w/o trail byte
		{
		    HX_ASSERT(len-1==ulIndx); //Lead byte w/o trail byte.
		    return -totalWidth;
		}
		totalWidth += GetCharacterWidth(
		    (pStr[ulIndx]<<8 | pStr[ulIndx+1]), //send two byte char.
		    ulFontFaceIndex, ulFontPtSize, isBold, isItalicized,
		    ulFontCharsetIndex);
		ulIndx++;
		continue;
	    }
	    //else drop on through and do the single-byte call below...
	}
	else if(ulFontCharsetIndex & HX_UNICODE_CHARSET)
	{
	    //Is a 2-byte character, so deal with it:
	    if(len-1==ulIndx)//shouldn't happen! Lead byte w/o trail byte
	    {
		HX_ASSERT(len-1==ulIndx); //Lead byte w/o trail byte.
		return -totalWidth;
	    }
	    totalWidth += GetCharacterWidth(
		(pStr[ulIndx]<<8 | pStr[ulIndx+1]), //send two byte char.
		ulFontFaceIndex, ulFontPtSize, isBold, isItalicized,
		ulFontCharsetIndex);
	    ulIndx++;
	    continue;
	}
	totalWidth += GetCharacterWidth(pStr[ulIndx], ulFontFaceIndex,
		ulFontPtSize, isBold, isItalicized, ulFontCharsetIndex);
    }
    return totalWidth;
}



/////////////////////////////////////////////////////////////////////////////
//
//  This function returns the string associated with the point size, e.g.,
//  a point size of 16 (which is FONT_SIZE_0) returns "+0":
//
//  Note: pRetBuf must be capable of holding 3 chars + the NULL-terminator;
//  retBufSize is the number of bytes pRetBuf was allocated.
//
void getFontPointSizeStringFromPtSize(ULONG32 ulPtSize, char* pRetBuf,
	ULONG32 retBufSize)
{
    if(retBufSize>0)
    {
	pRetBuf[0]='\0';
    }
    if(retBufSize < 4)
    {
	return;
    }

    switch(ulPtSize)
    {
	case FONT_SIZE_MINUS2:
	    strcpy(pRetBuf,"-2"); /* Flawfinder: ignore */
	    break;

	case FONT_SIZE_MINUS1:
	    strcpy(pRetBuf,"-1"); /* Flawfinder: ignore */
	    break;

	case FONT_SIZE_0:
	    strcpy(pRetBuf,"+0"); /* Flawfinder: ignore */
	    break;

	case FONT_SIZE_PLUS1:
	    strcpy(pRetBuf,"+1"); /* Flawfinder: ignore */
	    break;

	case FONT_SIZE_PLUS2:
	    strcpy(pRetBuf,"+2"); /* Flawfinder: ignore */
	    break;

	case FONT_SIZE_PLUS3:
	    strcpy(pRetBuf,"+3"); /* Flawfinder: ignore */
	    break;

	case FONT_SIZE_PLUS4:
	    strcpy(pRetBuf,"+4"); /* Flawfinder: ignore */
	    break;

	default:
	    strcpy(pRetBuf,"+0"); /* Flawfinder: ignore */
	    break;
    }
}


//Added this function as this code is now being called in
// more than one place:
/////////////////////////////////////////////////////////////////////////////
//
//  This function returns the string associated with the charset, e.g.,
//  a charset value of CHARSET__us_ascii returns "us-ascii":
//
//  Note: pRetBuf must be capable of holding 31 chars + the NULL-terminator;
//  retBufSize is the number of bytes pRetBuf was allocated.
//
void getFontCharsetStringFromCharsetVal(ULONG32 ulCharsetVal, char* pRetBuf,
	ULONG32 retBufSize)
{
    if(retBufSize>0)
    {
	pRetBuf[0]='\0';
    }
    if(retBufSize < 32)
    {
	return;
    }

    switch(ulCharsetVal)
    {
	case CHARSET__us_ascii:
	    strcpy(pRetBuf,"us-ascii"); /* Flawfinder: ignore */
	    break;

	case CHARSET__iso_8859_1:
	    strcpy(pRetBuf,"iso-8859-1"); /* Flawfinder: ignore */
	    break;

	case CHARSET__x_mac_roman:
	    strcpy(pRetBuf,"mac-roman"); /* Flawfinder: ignore */
	    break;

	case CHARSET__iso_2022_jp:
	    strcpy(pRetBuf,"iso-2022-jp"); /* Flawfinder: ignore */
	    break;

	case CHARSET__x_sjis:
	    strcpy(pRetBuf,"x-sjis"); /* Flawfinder: ignore */
	    break;

	case CHARSET__x_euc_jap:
	    strcpy(pRetBuf,"x-euc-jap"); /* Flawfinder: ignore */
	    break;

	case CHARSET__euc_kr:
	    strcpy(pRetBuf,"euc-kr"); /* Flawfinder: ignore */
	    break;

	case CHARSET__iso_2022_kr:
	    strcpy(pRetBuf,"iso-2022-kr"); /* Flawfinder: ignore */
	    break;

	case CHARSET__gb2312:
	    strcpy(pRetBuf,"gb2312"); /* Flawfinder: ignore */
	    break;

	case CHARSET__big5:
	    strcpy(pRetBuf,"big5"); /* Flawfinder: ignore */
	    break;

	//XXXEH- need to support all the other charsets...
	// (see fontdefs.h).
	default:
	    strcpy(pRetBuf,"us-ascii"); /* Flawfinder: ignore */
	    break;

    }
}

//Added this function as this code is now being called in
// more than one place:
/////////////////////////////////////////////////////////////////////////////
//
//  This function returns the string associated with the font face, e.g.,
//  a font face index of 20 (TIMES_FONT_FACE_STR) returns "times":
//
//  Note: pRetBuf must be capable of holding 31 chars + the NULL-terminator;
//  retBufSize is the number of bytes pRetBuf was allocated.
//
void getFontFaceStringFromFaceIndex(ULONG32 ulFontFaceIndex, char* pRetBuf,
	ULONG32 retBufSize,
	//The following are necessary for backwards-compatibility; we don't
	// want to support fonts that can't play on older players, so, if
	// content version is older than when the font faces were added,
	// we have to ignore those font faces:
	ULONG32 ulMajorContentVersion, ULONG32 ulMinorContentVersion)
{
    if(retBufSize>0)
    {
	pRetBuf[0]='\0';
    }
    if(retBufSize < 32)
    {
	return;
    }

    BOOL bActiveContentVersionIncludesKorean = FALSE;
    //XXXEH: docs need updating: version="1.4" or higher must
    // be set in the <window> tag of the rt file in order for
    // Korean to be rendered:
    if(ulMajorContentVersion >
	    REAL_TEXT_KOREAN_FONT_HANDLING_CONTENT_MAJOR_VERSION
	    ||
	    (ulMajorContentVersion ==
	    REAL_TEXT_KOREAN_FONT_HANDLING_CONTENT_MAJOR_VERSION
	    &&
	    ulMinorContentVersion >=
	    REAL_TEXT_KOREAN_FONT_HANDLING_CONTENT_MINOR_VERSION)
	    )
    {
	bActiveContentVersionIncludesKorean = TRUE;
    }

    switch(ulFontFaceIndex)
    {
	case TIMES_FONT_FACE_INDX:
	    strcpy(pRetBuf, TIMES_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;

	case COURIERTT_FONT_FACE_INDX:
	    strcpy(pRetBuf, COURIERTT_FONT_FACE_STR2); /* Flawfinder: ignore */
	    break;

	case SYSTEM_FONT_FACE_INDX:
	    strcpy(pRetBuf, SYSTEM_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;

	case ARIAL_FONT_FACE_INDX:
	    strcpy(pRetBuf, ARIAL_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
        case ARIAL_BLACK_FONT_FACE_INDX:
	    strcpy(pRetBuf, ARIAL_BLACK_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case ARIAL_NARROW_FONT_FACE_INDX:
	    strcpy(pRetBuf, ARIAL_NARROW_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case ARIAL_ROUNDED_MT_BOLD_FONT_FACE_INDX:
	    strcpy(pRetBuf, ARIAL_ROUNDED_MT_BOLD_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;

	case ALGERIAN_FONT_FACE_INDX:
	    strcpy(pRetBuf, ALGERIAN_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case BOOK_ANTIQUA_FONT_FACE_INDX:
	    strcpy(pRetBuf, BOOK_ANTIQUA_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case BOOKMAN_OLD_STYLE_FONT_FACE_INDX:
	    strcpy(pRetBuf, BOOKMAN_OLD_STYLE_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case BRAGGADOCIO_FONT_FACE_INDX:
	    strcpy(pRetBuf, BRAGGADOCIO_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case BRITANNIC_BOLD_FONT_FACE_INDX:
	    strcpy(pRetBuf, BRITANNIC_BOLD_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case BRUSH_SCRIPT_FONT_FACE_INDX:
	    strcpy(pRetBuf, BRUSH_SCRIPT_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case CENTURY_GOTHIC_FONT_FACE_INDX:
	    strcpy(pRetBuf, CENTURY_GOTHIC_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case CENTURY_SCHOOLBOOK_FONT_FACE_INDX:
	    strcpy(pRetBuf, CENTURY_SCHOOLBOOK_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case COLONNA_MT_FONT_FACE_INDX:
	    strcpy(pRetBuf, COLONNA_MT_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case COMIC_SANS_MS_FONT_FACE_INDX:
	    strcpy(pRetBuf, COMIC_SANS_MS_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case DESDEMONA_FONT_FACE_INDX:
	    strcpy(pRetBuf, DESDEMONA_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case FOOTLIGHT_MT_LIGHT_FONT_FACE_INDX:
	    strcpy(pRetBuf, FOOTLIGHT_MT_LIGHT_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case GARAMOND_FONT_FACE_INDX:
	    strcpy(pRetBuf, GARAMOND_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case HAETTENSCHWEILER_FONT_FACE_INDX:
	    strcpy(pRetBuf, HAETTENSCHWEILER_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case HELVETICA_FONT_FACE_INDX:
	    strcpy(pRetBuf, HELVETICA_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case IMPACT_FONT_FACE_INDX:
	    strcpy(pRetBuf, IMPACT_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case KINO_MT_FONT_FACE_INDX:
	    strcpy(pRetBuf, KINO_MT_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case MATURA_MT_SCRIPT_CAPITALS_FONT_FACE_INDX:
	    strcpy(pRetBuf, MATURA_MT_SCRIPT_CAPITALS_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case MODERN_FONT_FACE_INDX:
	    strcpy(pRetBuf, MODERN_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case MS_DIALOG_FONT_FACE_INDX:
	    strcpy(pRetBuf, MS_DIALOG_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case MS_DIALOG_LIGHT_FONT_FACE_INDX:
	    strcpy(pRetBuf, MS_DIALOG_LIGHT_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case MS_LINEDRAW_FONT_FACE_INDX:
	    strcpy(pRetBuf, MS_LINEDRAW_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case MS_SANS_SERIF_FONT_FACE_INDX:
	    strcpy(pRetBuf, MS_SANS_SERIF_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case MS_SERIF_FONT_FACE_INDX:
	    strcpy(pRetBuf, MS_SERIF_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case MS_SYSTEMEX_FONT_FACE_INDX:
	    strcpy(pRetBuf, MS_SYSTEMEX_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case PLAYBILL_FONT_FACE_INDX:
	    strcpy(pRetBuf, PLAYBILL_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case SMALL_FONTS_FONT_FACE_INDX:
	    strcpy(pRetBuf, SMALL_FONTS_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case VERDANA_FONT_FACE_INDX:
	    strcpy(pRetBuf, VERDANA_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;
	case WIDE_LATIN_FONT_FACE_INDX:
	    strcpy(pRetBuf, WIDE_LATIN_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;

	//DBCS and UNICODE fonts:
	case OSAKA_FONT_FACE_INDX:
	    strcpy(pRetBuf, OSAKA_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;

	case SIMPLECHINESE_FONT_FACE_INDX:
	    strcpy(pRetBuf, SIMPLECHINESE_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;

	case TRADITIONALCHINESE_FONT_FACE_INDX:
	    strcpy(pRetBuf, TRADITIONALCHINESE_FONT_FACE_STR); /* Flawfinder: ignore */
	    break;

	case SEOUL_FONT_FACE_INDX:
	    strcpy(pRetBuf, /* Flawfinder: ignore */
		    bActiveContentVersionIncludesKorean?
		    SEOUL_FONT_FACE_STR : DEFAULT_FONT_STR);
	    break;
	case BATANG_FONT_FACE_INDX:
	    strcpy(pRetBuf, /* Flawfinder: ignore */
		    bActiveContentVersionIncludesKorean?
		    BATANG_FONT_FACE_STR : DEFAULT_FONT_STR);
	    break;
	case BATANGCHE_FONT_FACE_INDX:
	    strcpy(pRetBuf, /* Flawfinder: ignore */
		    bActiveContentVersionIncludesKorean?
		    BATANGCHE_FONT_FACE_STR : DEFAULT_FONT_STR);
	    break;
	case GULIM_FONT_FACE_INDX:
	    strcpy(pRetBuf, /* Flawfinder: ignore */
		    bActiveContentVersionIncludesKorean?
		    GULIM_FONT_FACE_STR : DEFAULT_FONT_STR);
	    break;
	case GULIMCHE_FONT_FACE_INDX:
	    strcpy(pRetBuf, /* Flawfinder: ignore */
		    bActiveContentVersionIncludesKorean?
		    GULIMCHE_FONT_FACE_STR : DEFAULT_FONT_STR);
	    break;
	case GOTHIC_FONT_FACE_INDX:
	    strcpy(pRetBuf, /* Flawfinder: ignore */
		    bActiveContentVersionIncludesKorean?
		    GOTHIC_FONT_FACE_STR : DEFAULT_FONT_STR);
	    break;
	case APPLEGOTHIC_FONT_FACE_INDX:
	    strcpy(pRetBuf, /* Flawfinder: ignore */
		    bActiveContentVersionIncludesKorean?
		    APPLEGOTHIC_FONT_FACE_STR : DEFAULT_FONT_STR);
	    break;

	default:	//XXXEH- handle more fonts here!?!?
	    strcpy(pRetBuf, DEFAULT_FONT_STR); /* Flawfinder: ignore */
	    break;
    }
}
