/****************************************************************************
**
** Implementation of font database class.
**
** Created : 990603
**
** Copyright (C) 1999-2008 Trolltech ASA.  All rights reserved.
**
** This file is part of the kernel module of the TQt GUI Toolkit.
**
** This file may be used under the terms of the GNU General
** Public License versions 2.0 or 3.0 as published by the Free
** Software Foundation and appearing in the files LICENSE.GPL2
** and LICENSE.GPL3 included in the packaging of this file.
** Alternatively you may (at your option) use any later version
** of the GNU General Public License if such license has been
** publicly approved by Trolltech ASA (or its successors, if any)
** and the KDE Free TQt Foundation.
**
** Please review the following information to ensure GNU General
** Public Licensing requirements will be met:
** http://trolltech.com/products/qt/licenses/licensing/opensource/.
** If you are unsure which license is appropriate for your use, please
** review the following information:
** http://trolltech.com/products/qt/licenses/licensing/licensingoverview
** or contact the sales department at sales@trolltech.com.
**
** This file may be used under the terms of the Q Public License as
** defined by Trolltech ASA and appearing in the file LICENSE.TQPL
** included in the packaging of this file.  Licensees holding valid TQt
** Commercial licenses may use this file in accordance with the TQt
** Commercial License Agreement provided with the Software.
**
** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE. Trolltech reserves all rights not granted
** herein.
**
**********************************************************************/

#include "ntqfontdatabase.h"

#ifndef QT_NO_FONTDATABASE

#include <ntqtl.h>
#include <ntqapplication.h>

#include <private/qunicodetables_p.h>
#include "qfontengine_p.h"

#include <ntqcleanuphandler.h>

#ifdef Q_WS_X11
#include <locale.h>
#endif
#include <stdlib.h>

//#define TQFONTDATABASE_DEBUG
#ifdef TQFONTDATABASE_DEBUG
#  define FD_DEBUG tqDebug
#else
#  define FD_DEBUG if (FALSE) tqDebug
#endif

//#define FONT_MATCH_DEBUG
#ifdef FONT_MATCH_DEBUG
#  define FM_DEBUG tqDebug
#else
#  define FM_DEBUG if (FALSE) tqDebug
#endif

#if defined(Q_CC_MSVC) && !defined(Q_CC_MSVC_NET)
#  define for if(0){}else for
#endif

static int ucstricmp( const TQString &as, const TQString &bs )
{
    const TQChar *a = as.unicode();
    const TQChar *b = bs.unicode();
    if ( a == b )
	return 0;
    if ( a == 0 )
	return 1;
    if ( b == 0 )
	return -1;
    int l=TQMIN(as.length(),bs.length());
    while ( l-- && ::lower( *a ) == ::lower( *b ) )
	a++,b++;
    if ( l==-1 )
	return ( as.length()-bs.length() );
    return ::lower( *a ).unicode() - ::lower( *b ).unicode();
}

static int getFontWeight( const TQString &weightString )
{
    TQString s = weightString.lower();

    // Test in decreasing order of commonness
    if (s == "medium" ||
	s == "normal")
	return TQFont::Normal;
    if (s == "bold")
	return TQFont::Bold;
    if (s == "demibold" || s == "demi bold")
	return TQFont::DemiBold;
    if (s == "black")
	return TQFont::Black;
    if (s == "light")
	return TQFont::Light;

    if (s.contains("bold")) {
	if (s.contains("demi"))
	    return (int) TQFont::DemiBold;
	return (int) TQFont::Bold;
    }

    if (s.contains("light"))
	return (int) TQFont::Light;

    if (s.contains("black"))
	return (int) TQFont::Black;

    return (int) TQFont::Normal;
}

#ifdef Q_WS_X11
struct TQtFontEncoding
{
    signed int encoding : 16;

    uint xpoint   : 16;
    uint xres     : 8;
    uint yres     : 8;
    uint avgwidth : 16;
    uchar pitch   : 8;
};
#endif // Q_WS_X11

struct TQtFontSize
{
    unsigned short pixelSize;

#ifdef Q_WS_X11
    int count;
    TQtFontEncoding *encodings;
    TQtFontEncoding *encodingID( int id, uint xpoint = 0, uint xres = 0,
				uint yres = 0, uint avgwidth = 0, bool add = FALSE);
#endif // Q_WS_X11
};


#ifdef Q_WS_X11
TQtFontEncoding *TQtFontSize::encodingID( int id, uint xpoint, uint xres,
					uint yres, uint avgwidth, bool add )
{
    // we don't match using the xpoint, xres and yres parameters, only the id
    for ( int i = 0; i < count; ++i ) {
	if ( encodings[i].encoding == id )
	    return encodings + i;
    }

    if ( !add ) return 0;

    if ( !(count % 4) )
	encodings = ( TQtFontEncoding * )
		    realloc( encodings,
			     (((count+4) >> 2 ) << 2 ) * sizeof( TQtFontEncoding ) );
    encodings[count].encoding = id;
    encodings[count].xpoint = xpoint;
    encodings[count].xres = xres;
    encodings[count].yres = yres;
    encodings[count].avgwidth = avgwidth;
    encodings[count].pitch = '*';
    return encodings + count++;
}
#endif // Q_WS_X11

struct TQtFontStyle
{
    struct Key {
	Key( const TQString &styleString );
	Key() : italic( FALSE ), oblique( FALSE ),
		weight( TQFont::Normal ), stretch( 0 ) { }
	Key( const Key &o ) : italic( o.italic ), oblique( o.oblique ),
			      weight( o.weight ), stretch( o.stretch ) { }
	uint italic : 1;
	uint oblique : 1;
	signed int  weight : 8;
	signed int stretch : 12;

	bool operator==( const Key & other ) {
	    return ( italic == other.italic &&
		     oblique == other.oblique &&
		     weight == other.weight &&
		     (stretch == 0 || other.stretch == 0 || stretch == other.stretch) );
	}
	bool operator!=( const Key &other ) {
	    return !operator==(other);
	}
	bool operator <( const Key &o ) {
	    int x = (italic << 13) + (oblique << 12) + (weight << 14) + stretch;
	    int y = (o.italic << 13) + (o.oblique << 12) + (o.weight << 14) + o.stretch;
	    return ( x < y );
	}
    };

    TQtFontStyle( const Key &k )
	: key( k ), bitmapScalable( FALSE ), smoothScalable( FALSE ),
	  fakeOblique( FALSE ), count( 0 ), pixelSizes( 0 )
    {
#if defined(Q_WS_X11)
	weightName = setwidthName = 0;
#endif // Q_WS_X11
    }

    ~TQtFontStyle() {
#ifdef Q_WS_X11
	delete [] weightName;
	delete [] setwidthName;
	while ( count-- )
	    free(pixelSizes[count].encodings);
#endif
	free( pixelSizes );
    }

    Key key;
    bool bitmapScalable : 1;
    bool smoothScalable : 1;
    bool fakeOblique    : 1;
    int count           : 29;
    TQtFontSize *pixelSizes;

#ifdef Q_WS_X11
    const char *weightName;
    const char *setwidthName;
#endif // Q_WS_X11

    TQtFontSize *pixelSize( unsigned short size, bool = FALSE );
};

TQtFontStyle::Key::Key( const TQString &styleString )
    : italic( FALSE ), oblique( FALSE ), weight( TQFont::Normal ), stretch( 0 )
{
    weight = getFontWeight( styleString );

    if ( styleString.contains( "Italic" ) )
	 italic = TRUE;
    else if ( styleString.contains( "Oblique" ) )
	 oblique = TRUE;
}

TQtFontSize *TQtFontStyle::pixelSize( unsigned short size, bool add )
{
    for ( int i = 0; i < count; i++ ) {
	if ( pixelSizes[i].pixelSize == size )
	    return pixelSizes + i;
    }
    if ( !add )
	return 0;

    if ( !(count % 8) )
	pixelSizes = (TQtFontSize *)
		     realloc( pixelSizes,
			      (((count+8) >> 3 ) << 3) * sizeof(TQtFontSize) );
    pixelSizes[count].pixelSize = size;
#ifdef Q_WS_X11
    pixelSizes[count].count = 0;
    pixelSizes[count].encodings = 0;
#endif
    return pixelSizes + (count++);
}

struct TQtFontFoundry
{
    TQtFontFoundry( const TQString &n ) : name( n ), count( 0 ), styles( 0 ) {}
    ~TQtFontFoundry() {
	while ( count-- )
	    delete styles[count];
	free( styles );
    }

    TQString name;

    int count;
    TQtFontStyle **styles;
    TQtFontStyle *style( const TQtFontStyle::Key &,  bool = FALSE );
};

TQtFontStyle *TQtFontFoundry::style( const TQtFontStyle::Key &key, bool create )
{
    int pos = 0;
    if ( count ) {
	int low = 0;
	int high = count;
	pos = count / 2;
	while ( high > low ) {
	    if ( styles[pos]->key == key )
		return styles[pos];
	    if ( styles[pos]->key < key )
		low = pos + 1;
	    else
		high = pos;
	    pos = (high + low) / 2;
	};
	pos = low;
    }
    if ( !create )
	return 0;

//     tqDebug("adding key (weight=%d, italic=%d, oblique=%d stretch=%d) at %d",  key.weight, key.italic, key.oblique, key.stretch, pos );
    if ( !(count % 8) )
	styles = (TQtFontStyle **)
		 realloc( styles, (((count+8) >> 3 ) << 3) * sizeof( TQtFontStyle * ) );

    memmove( styles + pos + 1, styles + pos, (count-pos)*sizeof(TQtFontStyle *) );
    styles[pos] = new TQtFontStyle( key );
    count++;
    return styles[pos];
}


struct TQtFontFamily
{
    enum ScriptStatus { Unknown = 0, Supported = 1,
			UnSupported_Xft= 2, UnSupported_Xlfd = 4, UnSupported = 6 };

    TQtFontFamily(const TQString &n )
	:
#ifdef Q_WS_X11
        fixedPitch( TRUE ), hasXft( FALSE ), xftScriptCheck( FALSE ), xlfdLoaded( FALSE ), synthetic(FALSE),
#else
        fixedPitch( FALSE ),
#endif
#ifdef Q_WS_WIN
	scriptCheck( FALSE ),
#endif
#if defined(Q_OS_MAC) && !defined(TQWS)
	fixedPitchComputed(FALSE),
#endif
	fullyLoaded( FALSE ),
	  name( n ), count( 0 ), foundries( 0 ) {
	memset( scripts, 0, sizeof( scripts ) );
    }
    ~TQtFontFamily() {
	while ( count-- )
	    delete foundries[count];
	free( foundries );
    }

    bool fixedPitch : 1;
#ifdef Q_WS_X11
    bool hasXft : 1;
    bool xftScriptCheck : 1;
    bool xlfdLoaded : 1;
    bool synthetic : 1;
#endif
#ifdef Q_WS_WIN
    bool scriptCheck : 1;
#endif
#if defined(Q_OS_MAC) && !defined(TQWS)
    bool fixedPitchComputed : 1;
#endif
    bool fullyLoaded : 1;
    TQString name;
    TQString rawName;
#ifdef Q_WS_X11
    TQCString fontFilename;
    int fontFileIndex;
#endif
#ifdef Q_WS_MAC
    FMFontFamily macFamily;
#endif
#ifdef Q_WS_WIN
    TQString english_name;
#endif
    int count;
    TQtFontFoundry **foundries;

    unsigned char scripts[TQFont::LastPrivateScript];

    TQtFontFoundry *foundry( const TQString &f, bool = FALSE );
};

TQtFontFoundry *TQtFontFamily::foundry( const TQString &f, bool create )
{
    if ( f.isNull() && count == 1 )
	return foundries[0];

    for ( int i = 0; i < count; i++ ) {
	if ( ucstricmp( foundries[i]->name, f ) == 0 )
	    return foundries[i];
    }
    if ( !create )
	return 0;

    if ( !(count % 8) )
	foundries = (TQtFontFoundry **)
		    realloc( foundries,
			     (((count+8) >> 3 ) << 3) * sizeof( TQtFontFoundry * ) );

    foundries[count] = new TQtFontFoundry( f );
    return foundries[count++];
}

class TQFontDatabasePrivate {
public:
    TQFontDatabasePrivate() : count( 0 ), families( 0 ) { }
    ~TQFontDatabasePrivate() {
	while ( count-- )
	    delete families[count];
	free( families );
    }
    TQtFontFamily *family( const TQString &f, bool = FALSE );

    int count;
    TQtFontFamily **families;
};

TQtFontFamily *TQFontDatabasePrivate::family( const TQString &f, bool create )
{
    int low = 0;
    int high = count;
    int pos = count / 2;
    int res = 1;
    if ( count ) {
	while ( (res = ucstricmp( families[pos]->name, f )) && pos != low ) {
	    if ( res > 0 )
		high = pos;
	    else
		low = pos;
	    pos = (high + low) / 2;
	};
	if ( !res )
	    return families[pos];
    }
    if ( !create )
	return 0;

    if ( res < 0 )
	pos++;

    // tqDebug("adding family %s at %d total=%d",  f.latin1(), pos, count);
    if ( !(count % 8) )
	families = (TQtFontFamily **)
		   realloc( families,
			    (((count+8) >> 3 ) << 3) * sizeof( TQtFontFamily * ) );

    memmove( families + pos + 1, families + pos, (count-pos)*sizeof(TQtFontFamily *) );
    families[pos] = new TQtFontFamily( f );
    count++;
    return families[pos];
}




#if defined(Q_WS_X11) || defined(Q_WS_WIN)
static const unsigned short sample_chars[TQFont::LastPrivateScript][14] =
{
    // European Alphabetic Scripts
    // Latin,
    { 0x0041, 0x0 },
    // Greek,
    { 0x0391, 0x0 },
    // Cyrillic,
    { 0x0410, 0x0 },
    // Armenian,
    { 0x0540, 0x0 },
    // Georgian,
    { 0x10d0, 0x0 },
    // Runic,
    { 0x16a0, 0x0 },
    // Ogham,
    { 0x1680, 0x0 },
    // SpacingModifiers,
    { 0x02c6, 0x0 },
    // CombiningMarks,
    { 0x0300, 0x0 },

    // Middle Eastern Scripts
    // Hebrew,
    { 0x05d0, 0x0 },
    // Arabic,
    { 0x0630, 0x0 },
    // Syriac,
    { 0x0710, 0x0 },
    // Thaana,
    { 0x0780, 0x0 },

    // South and Southeast Asian Scripts
    // Devanagari,
    { 0x0910, 0x0 },
    // Bengali,
    { 0x0990, 0x0 },
    // Gurmukhi,
    { 0x0a10, 0x0 },
    // Gujarati,
    { 0x0a90, 0x0 },
    // Oriya,
    { 0x0b10, 0x0 },
    // Tamil,
    { 0x0b90, 0x0 },
    // Telugu,
    { 0x0c10, 0x0 },
    // Kannada,
    { 0x0c90, 0x0 },
    // Malayalam,
    { 0x0d10, 0x0 },
    // Sinhala,
    { 0x0d90, 0x0 },
    // Thai,
    { 0x0e10, 0x0 },
    // Lao,
    { 0x0e81, 0x0 },
    // Tibetan,
    { 0x0f00, 0x0 },
    // Myanmar,
    { 0x1000, 0x0 },
    // Khmer,
    { 0x1780, 0x0 },

    // East Asian Scripts
    // Han,
    { 0x4e00, 0x0 },
    // Hiragana,
    {  0x3050, 0x4e00, 0x25EF, 0x3012, 0x3013, 0x30FB, 0x30FC, 0x5CE0, 0 },
    // Katakana,
    { 0x30b0, 0x4e00, 0x25EF, 0x3012, 0x3013, 0x30FB, 0x30FC, 0x5CE0, 0 },
    // Hangul,
    { 0xac00, 0x0 },
    // Bopomofo,
    { 0x3110, 0x0 },
    // Yi,
    { 0xa000, 0x0 },

    // Additional Scripts
    // Ethiopic,
    { 0x1200, 0x0 },
    // Cherokee,
    { 0x13a0, 0x0 },
    // CanadianAboriginal,
    { 0x1410, 0x0 },
    // Mongolian,
    { 0x1800, 0x0 },

    // Symbols
    // CurrencySymbols,
    { 0x20aa, 0x0 },
    // LetterlikeSymbols,
    { 0x2103, 0x0 },
    // NumberForms,
    { 0x2160, 0x0 },
    // MathematicalOperators,
    { 0x222b, 0x0 },
    // TechnicalSymbols,
    { 0x2312, 0x0 },
    // GeometricSymbols,
    { 0x2500, 0x0 },
    // MiscellaneousSymbols,
    { 0x2640, 0x2714, 0x0 },
    // EnclosedAndSquare,
    { 0x2460, 0x0 },
    // Braille,
    { 0x2800, 0x0 },

    // Unicode,
    { 0xfffd, 0x0 },

    // some scripts added in Unicode 3.2
    // Tagalog,
    { 0x1700, 0x0 },
    // Hanunoo,
    { 0x1720, 0x0 },
    // Buhid,
    { 0x1740, 0x0 },
    // Tagbanwa,
    { 0x1770, 0x0 },

    // KatakanaHalfWidth
    { 0xff65, 0x0 },

    // Limbu
    { 0x1901, 0x0 },
    // TaiLe
    { 0x1950, 0x0 },

    // NScripts
    { 0x0000, 0x0 },
    // NoScript
    { 0x0000, 0x0 },

    // Han_Japanese
    { 0x4e00, 0x25EF, 0x3012, 0x3013, 0x30FB, 0x5CE0, 0 },
    // Han_SimplifiedChinese, 0x3400 is optional
    { 0x4e00, 0x201C, 0x3002, 0x6237, 0x9555, 0xFFE5, 0 },
    // Han_TraditionalChinese, 0xF6B1 is optional
    // OR Han_HongkongChinese, 0x3435, 0xE000, 0xF6B1 are optional
    { 0x4e00, 0x201C, 0x3002, 0x6236, 0x9F98, 0xFFE5, 0 },
    // Han_Korean
    { 0x4e00, 0 }
    // Taiwan would be 0x201C, 0x3002, 0x4E00, 0x9F98, 0xFFE5
};

#if defined(Q_WS_X11) && !defined(QT_NO_XFTFREETYPE)
static inline bool requiresOpenType(TQFont::Script s)
{
    return (s >= TQFont::Syriac && s <= TQFont::Sinhala)
		 || (s >= TQFont::Myanmar && s <= TQFont::Khmer);
}
#endif

static inline bool canRender( TQFontEngine *fe, TQFont::Script script )
{
    if ( !fe ) return FALSE;

    bool hasChar = true;

    if (!sample_chars[script][0])
        hasChar = false;

    int i = 0;
    while (hasChar && sample_chars[script][i]){
        TQChar sample(sample_chars[script][i]);
        if ( !fe->canRender( &sample, 1  ) ) {
             hasChar = false;
#ifdef FONT_MATCH_DEBUG
	FM_DEBUG("    font has NOT char 0x%04x", sample.unicode() );
        } else {
	FM_DEBUG("    font has char 0x%04x", sample.unicode() );
#endif
        }
        ++i;
    }
#if defined(Q_WS_X11) && !defined(QT_NO_XFTFREETYPE)
    if (hasChar && requiresOpenType(script)) {
	TQOpenType *ot = fe->openType();
	if (!ot || !ot->supportsScript(script))
	    return FALSE;
    }
#endif

    return hasChar;
}
#endif // Q_WS_X11 || Q_WS_WIN


static TQSingleCleanupHandler<TQFontDatabasePrivate> qfontdatabase_cleanup;
static TQFontDatabasePrivate *db=0;
#define SMOOTH_SCALABLE 0xffff

#if defined( Q_WS_X11 )
#  include "qfontdatabase_x11.cpp"
#elif defined( Q_WS_MAC )
#  include "qfontdatabase_mac.cpp"
#elif defined( Q_WS_WIN )
#  include "qfontdatabase_win.cpp"
#elif defined( Q_WS_QWS )
#  include "qfontdatabase_qws.cpp"
#endif

static TQtFontStyle *bestStyle(TQtFontFoundry *foundry, const TQtFontStyle::Key &styleKey)
{
    int best = 0;
    int dist = 0xffff;

    for ( int i = 0; i < foundry->count; i++ ) {
	TQtFontStyle *style = foundry->styles[i];

	int d = TQABS( styleKey.weight - style->key.weight );

	if ( styleKey.stretch != 0 && style->key.stretch != 0 ) {
	    d += TQABS( styleKey.stretch - style->key.stretch );
	}

	if ( styleKey.italic ) {
	    if ( !style->key.italic )
		d += style->key.oblique ? 0x0001 : 0x1000;
	} else if ( styleKey.oblique ) {
	    if (!style->key.oblique )
		d += style->key.italic ? 0x0001 : 0x1000;
	} else if ( style->key.italic || style->key.oblique ) {
	    d += 0x1000;
	}

	if ( d < dist ) {
	    best = i;
	    dist = d;
	}
    }

    FM_DEBUG( "          best style has distance 0x%x", dist );
    if (!foundry->count) {
        TQtFontStyle *temp = NULL;
        return temp;
    }
    return foundry->styles[best];
}

#if defined(Q_WS_X11)
static TQtFontEncoding *findEncoding(TQFont::Script script, int styleStrategy,
                                    TQtFontSize *size, int force_encoding_id)
{
    TQtFontEncoding *encoding = 0;

    if (force_encoding_id >= 0) {
        encoding = size->encodingID(force_encoding_id);
        if (!encoding)
            FM_DEBUG("            required encoding_id not available");
        return encoding;
    }

    if (styleStrategy & (TQFont::OpenGLCompatible | TQFont::PreferBitmap)) {
        FM_DEBUG("            PreferBitmap and/or OpenGL set, skipping Xft");
    } else {
        encoding = size->encodingID(-1); // -1 == prefer Xft
        if (encoding) return encoding;
    }

    // Xft not available, find an XLFD font, trying the default encoding first
    encoding = size->encodingID(TQFontPrivate::defaultEncodingID);

    if (!encoding || !scripts_for_xlfd_encoding[encoding->encoding][script]) {
        // find the first encoding that supports the requested script
        encoding = 0;
        for (int x = 0; !encoding && x < size->count; ++x) {
            const int enc = size->encodings[x].encoding;
            if (scripts_for_xlfd_encoding[enc][script]) {
                encoding = size->encodings + x;
                break;
            }
        }
    }

    return encoding;
}
#endif // Q_WS_X11


#if defined(Q_WS_X11) || defined(Q_WS_WIN)
static
unsigned int bestFoundry( TQFont::Script script, unsigned int score, int styleStrategy,
			  const TQtFontFamily *family, const TQString &foundry_name,
			  TQtFontStyle::Key styleKey, int pixelSize, char pitch,
			  TQtFontFoundry **best_foundry, TQtFontStyle **best_style,
			  TQtFontSize **best_size
#ifdef Q_WS_X11
			  , TQtFontEncoding **best_encoding, int force_encoding_id
#endif
			  )
{
    Q_UNUSED( script );
    Q_UNUSED( pitch );

    FM_DEBUG( "  REMARK: looking for best foundry for family '%s'", family->name.latin1() );

    for ( int x = 0; x < family->count; ++x ) {
	TQtFontFoundry *foundry = family->foundries[x];
	if ( ! foundry_name.isEmpty() &&
	     ucstricmp( foundry->name, foundry_name ) != 0 )
	    continue;

	FM_DEBUG( "          looking for matching style in foundry '%s'",
		  foundry->name.isEmpty() ? "-- none --" : foundry->name.latin1() );

	TQtFontStyle *style = bestStyle(foundry, styleKey);

	if ( ! style->smoothScalable && ( styleStrategy & TQFont::ForceOutline ) ) {
	    FM_DEBUG( "            ForceOutline set, but not smoothly scalable" );
	    continue;
	}

	int px = -1;
	TQtFontSize *size = 0;

	// 1. see if we have an exact matching size
	if (! (styleStrategy & TQFont::ForceOutline)) {
	    size = style->pixelSize(pixelSize);
	    if (size) {
                FM_DEBUG("          found exact size match (%d pixels)", size->pixelSize);
                px = size->pixelSize;
            }
	}

	// 2. see if we have a smoothly scalable font
	if (! size && style->smoothScalable && ! (styleStrategy & TQFont::PreferBitmap)) {
	    size = style->pixelSize(SMOOTH_SCALABLE);
	    if (size) {
                FM_DEBUG("          found smoothly scalable font (%d pixels)", pixelSize);
                px = pixelSize;
            }
	}

	// 3. see if we have a bitmap scalable font
	if (! size && style->bitmapScalable && (styleStrategy & TQFont::PreferMatch)) {
	    size = style->pixelSize(0);
	    if (size) {
                FM_DEBUG("          found bitmap scalable font (%d pixels)", pixelSize);
                px = pixelSize;
            }
	}

#ifdef Q_WS_X11
        TQtFontEncoding *encoding = 0;
#endif

	// 4. find closest size match
	if (! size) {
	    unsigned int distance = ~0u;
	    for (int x = 0; x < style->count; ++x) {
#ifdef Q_WS_X11
                encoding =
                    findEncoding(script, styleStrategy, style->pixelSizes + x, force_encoding_id);
                if (!encoding) {
                    FM_DEBUG("          size %3d does not support the script we want",
                             style->pixelSizes[x].pixelSize);
                    continue;
                }
#endif

		unsigned int d = TQABS(style->pixelSizes[x].pixelSize - pixelSize);
		if (d < distance) {
		    distance = d;
		    size = style->pixelSizes + x;
		    FM_DEBUG("          best size so far: %3d (%d)", size->pixelSize, pixelSize);
		}
	    }

            if (!size) {
                FM_DEBUG("          no size supports the script we want");
                continue;
            }

	    if (style->bitmapScalable && ! (styleStrategy & TQFont::PreferQuality) &&
		(distance * 10 / pixelSize) >= 2) {
		// the closest size is not close enough, go ahead and
		// use a bitmap scaled font
		size = style->pixelSize(0);
		px = pixelSize;
	    } else {
		px = size->pixelSize;
	    }
	}

#ifdef Q_WS_X11
        if (size) {
            encoding = findEncoding(script, styleStrategy, size, force_encoding_id);
            if (!encoding) size = 0;
        }
	if ( ! encoding ) {
	    FM_DEBUG( "          foundry doesn't support the script we want" );
	    continue;
	}
#endif // Q_WS_X11

	unsigned int this_score = 0x0000;
        enum {
            PitchMismatch       = 0x4000,
            StyleMismatch       = 0x2000,
            BitmapScaledPenalty = 0x1000,
            EncodingMismatch    = 0x0002,
            XLFDPenalty         = 0x0001
        };

#ifdef Q_WS_X11
	if ( encoding->encoding != -1 ) {
	    this_score += XLFDPenalty;
	    if ( encoding->encoding != TQFontPrivate::defaultEncodingID )
		this_score += EncodingMismatch;
	}
 	if (pitch != '*') {
 	    if ( !( pitch == 'm' && encoding->pitch == 'c' ) && pitch != encoding->pitch )
 		this_score += PitchMismatch;
 	}
#else
        // ignore pitch for asian fonts, some of them misreport it, and they are all
        // fixed pitch anyway.
        if (pitch != '*' && (script <= TQFont::NScripts && script != TQFont::KatakanaHalfWidth
                             && (script < TQFont::Han || script > TQFont::Yi))) {
	    if ((pitch == 'm' && !family->fixedPitch)
		|| (pitch == 'p' && family->fixedPitch))
		this_score += PitchMismatch;
	}
#endif
	if ( styleKey != style->key )
	    this_score += StyleMismatch;
	if ( !style->smoothScalable && px != size->pixelSize ) // bitmap scaled
	    this_score += BitmapScaledPenalty;
        if (px != pixelSize) // close, but not exact, size match
            this_score += TQABS(px - pixelSize);

	if ( this_score < score ) {
	    FM_DEBUG( "          found a match: score %x best score so far %x",
		      this_score, score );

	    score = this_score;
	    *best_foundry = foundry;
	    *best_style = style;
	    *best_size = size;
#ifdef Q_WS_X11
	    *best_encoding = encoding;
#endif // Q_WS_X11
	} else {
	    FM_DEBUG( "          score %x no better than best %x", this_score, score);
	}
    }

    return score;
}

/*!
    \internal
*/
TQFontEngine *
TQFontDatabase::findFont( TQFont::Script script, const TQFontPrivate *fp,
			 const TQFontDef &request, int force_encoding_id )
{
#ifndef Q_WS_X11
    Q_UNUSED( force_encoding_id );
#endif

    if ( !db )
	initializeDb();

    TQFontEngine *fe = 0;
    if ( fp ) {
	if ( fp->rawMode ) {
	    fe = loadEngine( script, fp, request, 0, 0, 0
#ifdef Q_WS_X11
			     , 0, 0, FALSE
#endif
		);

	    // if we fail to load the rawmode font, use a 12pixel box engine instead
	    if (! fe) fe = new TQFontEngineBox( 12 );
	    return fe;
	}

	TQFontCache::Key key( request, script,
#ifdef Q_WS_WIN
			     (int)fp->paintdevice, 
#else
			     fp->screen, 
#endif
                             fp->paintdevice
	    );
	fe = TQFontCache::instance->findEngine( key );
	if ( fe ) return fe;
    }

#ifdef Q_WS_WIN
    if (request.styleStrategy & TQFont::PreferDevice) {
        TQFontEngine *fe = loadEngine(script, fp, request, 0, 0, 0);
        if(fe)
            return fe;
    }
#endif

    TQString family_name, foundry_name;
    TQtFontStyle::Key styleKey;
    styleKey.italic = request.italic;
    styleKey.weight = request.weight;
    styleKey.stretch = request.stretch;
    char pitch = request.ignorePitch ? '*' : request.fixedPitch ? 'm' : 'p';

    parseFontName( request.family, foundry_name, family_name );

#ifdef Q_WS_X11
    if (script == TQFont::Han) {
        // modify script according to locale
        static TQFont::Script defaultHan;
        TQCString locale = setlocale(LC_ALL, NULL);

        if (locale.contains("ko"))
            defaultHan = TQFont::Han_Korean;
        else if (locale.contains("zh_TW") || locale.contains("zh_HK"))
            defaultHan = TQFont::Han_TraditionalChinese;
        else if (locale.contains("zh"))
            defaultHan = TQFont::Han_SimplifiedChinese;
        else if (locale.contains("ja"))
            defaultHan = TQFont::Han_Japanese;
        else
            defaultHan = TQFont::Han; // don't change

        script = defaultHan;
    }
#endif

    FM_DEBUG( "TQFontDatabase::findFont\n"
	      "  request:\n"
	      "    family: %s [%s], script: %d (%s)\n"
	      "    weight: %d, italic: %d\n"
	      "    stretch: %d\n"
	      "    pixelSize: %d\n"
	      "    pitch: %c",
	      family_name.isEmpty() ? "-- first in script --" : family_name.latin1(),
	      foundry_name.isEmpty() ? "-- any --" : foundry_name.latin1(),
	      script, scriptName( script ).latin1(),
	      request.weight, request.italic, request.stretch, request.pixelSize, pitch );

    bool usesFontConfig = FALSE;
#ifdef QT_XFT2
    if (family_name.isEmpty()
	|| family_name == "Sans Serif"
	|| family_name == "Serif"
	|| family_name == "Monospace") {
	fe = loadFontConfigFont(fp, request, script);
        usesFontConfig = (fe != 0);
    }
    if (!fe)
#endif
    {
	TQtFontFamily *best_family = 0;
	TQtFontFoundry *best_foundry = 0;
	TQtFontStyle *best_style = 0;
	TQtFontSize *best_size = 0;
#ifdef Q_WS_X11
	TQtFontEncoding *best_encoding = 0;
#endif // Q_WS_X11

	unsigned int score = ~0;

	load( family_name, script );

	for ( int x = 0; x < db->count; ++x ) {
	    TQtFontFamily *try_family = db->families[x];
#ifdef Q_WS_X11
            if (try_family->synthetic) // skip generated fontconfig fonts
                continue;
#endif

            if ( !family_name.isEmpty() &&
		 ucstricmp( try_family->name, family_name ) != 0
#ifdef Q_WS_WIN
		 && ucstricmp( try_family->english_name, family_name ) != 0
#endif
                )
		continue;

	    if ( family_name.isEmpty() )
		load( try_family->name, script );

	    uint score_adjust = 0;
	    TQFont::Script override_script = script;
	    if ( ! ( try_family->scripts[script] & TQtFontFamily::Supported )
		 && script != TQFont::Unicode) {
		// family not supported in the script we want
#ifdef Q_WS_X11
		if (script >= TQFont::Han_Japanese && script <= TQFont::Han_Korean
		    && try_family->scripts[TQFont::Han] == TQtFontFamily::Supported) {
		    // try with the han script instead, give it a penalty
		    if (override_script == TQFont::Han_TraditionalChinese
			&& (try_family->scripts[TQFont::Han_SimplifiedChinese] & TQtFontFamily::Supported)) {
			override_script = TQFont::Han_SimplifiedChinese;
			score_adjust = 200;
		    } else if (override_script == TQFont::Han_SimplifiedChinese
                               && (try_family->scripts[TQFont::Han_TraditionalChinese] & TQtFontFamily::Supported)) {
			override_script = TQFont::Han_TraditionalChinese;
			score_adjust = 200;
		    } else {
			override_script = TQFont::Han;
			score_adjust = 400;
		    }
		} else
#endif
                    if (family_name.isEmpty()) {
                        continue;
                    } else if (try_family->scripts[TQFont::UnknownScript] & TQtFontFamily::Supported) {
                        // try with the unknown script (for a symbol font)
                        override_script = TQFont::UnknownScript;
#ifndef QT_XFT2
                    } else if (try_family->scripts[TQFont::Unicode] & TQtFontFamily::Supported) {
                        // try with the unicode script instead
                        override_script = TQFont::Unicode;
#endif
                    } else {
                        // family not supported by unicode/unknown scripts
                        continue;
                    }
	    }

	    TQtFontFoundry *try_foundry = 0;
	    TQtFontStyle *try_style = 0;
	    TQtFontSize *try_size = 0;
#ifdef Q_WS_X11
	    TQtFontEncoding *try_encoding = 0;
#endif // Q_WS_X11

	    // as we know the script is supported, we can be sure
	    // to find a matching font here.
	    unsigned int newscore =
		bestFoundry( override_script, score, request.styleStrategy,
			     try_family, foundry_name, styleKey, request.pixelSize, pitch,
			     &try_foundry, &try_style, &try_size
#ifdef Q_WS_X11
			     , &try_encoding, force_encoding_id
#endif
		    );
	    if ( try_foundry == 0 ) {
		// the specific foundry was not found, so look for
		// any foundry matching our requirements
		newscore = bestFoundry( override_script, score, request.styleStrategy, try_family,
					TQString::null, styleKey, request.pixelSize,
					pitch, &try_foundry, &try_style, &try_size
#ifdef Q_WS_X11
					, &try_encoding, force_encoding_id
#endif
		    );
	    }
	    newscore += score_adjust;

	    if ( newscore < score ) {
		score = newscore;
		best_family = try_family;
		best_foundry = try_foundry;
		best_style = try_style;
		best_size = try_size;
#ifdef Q_WS_X11
		best_encoding = try_encoding;
#endif // Q_WS_X11
	    }
	    if ( newscore < 10 ) // xlfd instead of xft... just accept it
		break;
	}

	if ( best_family != 0 && best_foundry != 0 && best_style != 0
#ifdef Q_WS_X11
	     && best_size != 0 && best_encoding != 0
#endif
	    ) {
	    FM_DEBUG( "  BEST:\n"
		      "    family: %s [%s]\n"
		      "    weight: %d, italic: %d, oblique: %d\n"
		      "    stretch: %d\n"
		      "    pixelSize: %d\n"
		      "    pitch: %c\n"
		      "    encoding: %d\n",
		      best_family->name.latin1(),
		      best_foundry->name.isEmpty() ? "-- none --" : best_foundry->name.latin1(),
		      best_style->key.weight, best_style->key.italic, best_style->key.oblique,
		      best_style->key.stretch, best_size ? best_size->pixelSize : 0xffff,
#ifdef Q_WS_X11
		      best_encoding->pitch, best_encoding->encoding
#else
		      'p', 0
#endif
		);

	    fe = loadEngine( script, fp, request, best_family, best_foundry, best_style
#ifdef Q_WS_X11
			     , best_size, best_encoding, ( force_encoding_id >= 0 )
#endif
		);
	}
	if (fe) {
	    fe->fontDef.family = best_family->name;
	    if ( ! best_foundry->name.isEmpty() ) {
		fe->fontDef.family += TQString::fromLatin1( " [" );
		fe->fontDef.family += best_foundry->name;
		fe->fontDef.family += TQString::fromLatin1( "]" );
	    }

	    if ( best_style->smoothScalable )
		fe->fontDef.pixelSize = request.pixelSize;
	    else if ( best_style->bitmapScalable &&
		      ( request.styleStrategy & TQFont::PreferMatch ) )
		fe->fontDef.pixelSize = request.pixelSize;
	    else
		fe->fontDef.pixelSize = best_size->pixelSize;

	    fe->fontDef.styleHint     = request.styleHint;
	    fe->fontDef.styleStrategy = request.styleStrategy;

	    fe->fontDef.weight        = best_style->key.weight;
	    fe->fontDef.italic        = best_style->key.italic || best_style->key.oblique;
	    fe->fontDef.fixedPitch    = best_family->fixedPitch;
	    fe->fontDef.stretch       = best_style->key.stretch;
	    fe->fontDef.ignorePitch   = FALSE;
	}
    }

    if ( fe ) {
	if ( script != TQFont::Unicode && !canRender( fe, script ) ) {
	    FM_DEBUG( "  WARN: font loaded cannot render a sample char" );

	    delete fe;
            fe = 0;
	} else if ( fp ) {
            TQFontDef def = request;
            if (def.family.isEmpty()) {
                def.family = fp->request.family;
                def.family = def.family.left(def.family.find(','));
            }
	    TQFontCache::Key key( def, script,
#ifdef Q_WS_WIN
				 (int)fp->paintdevice, 
#else
				 fp->screen, 
#endif
                                 fp->paintdevice
		);
	    TQFontCache::instance->insertEngine( key, fe );
            if (!usesFontConfig) {
                for ( int i = 0; i < TQFont::NScripts; ++i ) {
                    if ( i == script ) continue;

                    if (!canRender(fe, (TQFont::Script) i))
                        continue;

                    key.script = i;
                    TQFontCache::instance->insertEngine( key, fe );
                }
            }
	}
    }

    if (!fe) {
	if ( !request.family.isEmpty() )
            return 0;

        FM_DEBUG( "returning box engine" );

        fe = new TQFontEngineBox( request.pixelSize );
        fe->fontDef = request;

        if ( fp ) {
            TQFontCache::Key key( request, script,
#ifdef Q_WS_WIN
                                 (int)fp->paintdevice, 
#else
                                 fp->screen, 
#endif
                                 fp->paintdevice
                );
            TQFontCache::instance->insertEngine( key, fe );
        }
    }

    if ( fp ) {
#if defined(Q_WS_X11)
        fe->fontDef.pointSize =
            tqRound(10. * qt_pointSize(fe->fontDef.pixelSize, fp->paintdevice, fp->screen));
#elif defined(Q_WS_WIN)
        fe->fontDef.pointSize     = int( double( fe->fontDef.pixelSize ) * 720.0 /
                                         GetDeviceCaps(shared_dc,LOGPIXELSY) );
#else
        fe->fontDef.pointSize     = int( double( fe->fontDef.pixelSize ) * 720.0 /
                                         96.0 );
#endif
    } else {
        fe->fontDef.pointSize = request.pointSize;
    }

    return fe;
}
#endif // Q_WS_X11 || Q_WS_WIN




static TQString styleString( int weight, bool italic, bool oblique )
{
    TQString result;
    if ( weight >= TQFont::Black )
	result = "Black";
    else if ( weight >= TQFont::Bold )
	result = "Bold";
    else if ( weight >= TQFont::DemiBold )
	result = "Demi Bold";
    else if ( weight < TQFont::Normal )
	result = "Light";

    if ( italic )
	result += " Italic";
    else if ( oblique )
	result += " Oblique";

    if ( result.isEmpty() )
	result = "Normal";

    return result.simplifyWhiteSpace();
}

/*!
    Returns a string that describes the style of the font \a f. For
    example, "Bold Italic", "Bold", "Italic" or "Normal". An empty
    string may be returned.
*/
TQString TQFontDatabase::styleString( const TQFont &f )
{
    // ### fix oblique here
    return ::styleString( f.weight(), f.italic(), FALSE );
}


/*!
    \class TQFontDatabase ntqfontdatabase.h
    \brief The TQFontDatabase class provides information about the fonts available in the underlying window system.

    \ingroup environment
    \ingroup graphics

    The most common uses of this class are to query the database for
    the list of font families() and for the pointSizes() and styles()
    that are available for each family. An alternative to pointSizes()
    is smoothSizes() which returns the sizes at which a given family
    and style will look attractive.

    If the font family is available from two or more foundries the
    foundry name is included in the family name, e.g. "Helvetica
    [Adobe]" and "Helvetica [Cronyx]". When you specify a family you
    can either use the old hyphenated TQt 2.x "foundry-family" format,
    e.g. "Cronyx-Helvetica", or the new bracketed TQt 3.x "family
    [foundry]" format e.g. "Helvetica [Cronyx]". If the family has a
    foundry it is always returned, e.g. by families(), using the
    bracketed format.

    The font() function returns a TQFont given a family, style and
    point size.

    A family and style combination can be checked to see if it is
    italic() or bold(), and to retrieve its weight(). Similarly we can
    call isBitmapScalable(), isSmoothlyScalable(), isScalable() and
    isFixedPitch().

    A text version of a style is given by styleString().

    The TQFontDatabase class also supports some static functions, for
    example, standardSizes(). You can retrieve the Unicode 3.0
    description of a \link TQFont::Script script\endlink using
    scriptName(), and a sample of characters in a script with
    scriptSample().

    Example:
\code
#include <ntqapplication.h>
#include <ntqfontdatabase.h>
#include <else.h>

int main( int argc, char **argv )
{
    TQApplication app( argc, argv );
    TQFontDatabase fdb;
    TQStringList families = fdb.families();
    for ( TQStringList::Iterator f = families.begin(); f != families.end(); ++f ) {
	TQString family = *f;
	tqDebug( family );
	TQStringList styles = fdb.styles( family );
	for ( TQStringList::Iterator s = styles.begin(); s != styles.end(); ++s ) {
	    TQString style = *s;
	    TQString dstyle = "\t" + style + " (";
	    TQValueList<int> smoothies = fdb.smoothSizes( family, style );
	    for ( TQValueList<int>::Iterator points = smoothies.begin();
		  points != smoothies.end(); ++points ) {
		dstyle += TQString::number( *points ) + " ";
	    }
	    dstyle = dstyle.left( dstyle.length() - 1 ) + ")";
	    tqDebug( dstyle );
	}
    }
    return 0;
}
\endcode
    This example gets the list of font families, then the list of
    styles for each family and the point sizes that are available for
    each family/style combination.
*/
/*!
    \obsolete
    \fn inline TQStringList TQFontDatabase::families( bool ) const
*/
/*!
    \obsolete
    \fn inline TQStringList TQFontDatabase::styles( const TQString &family,
					  const TQString & ) const
*/
/*!
    \obsolete
    \fn inline TQValueList<int> TQFontDatabase::pointSizes( const TQString &family,
						  const TQString &style ,
						  const TQString & )
*/

/*!
    \obsolete
    \fn inline TQValueList<int> TQFontDatabase::smoothSizes( const TQString &family,
						   const TQString &style,
						   const TQString & )
*/
/*!
    \obsolete
    \fn inline TQFont TQFontDatabase::font( const TQString &familyName,
				  const TQString &style,
				  int pointSize,
				  const TQString &)
*/
/*!
    \obsolete
    \fn inline bool TQFontDatabase::isBitmapScalable( const TQString &family,
					     const TQString &style,
					     const TQString & ) const
*/

/*!
    \obsolete
    \fn inline bool TQFontDatabase::isSmoothlyScalable( const TQString &family,
					       const TQString &style,
					       const TQString & ) const
*/

/*!
    \obsolete
    \fn inline bool TQFontDatabase::isScalable( const TQString &family,
				       const TQString &style,
				       const TQString & ) const
*/

/*!
    \obsolete
    \fn inline bool TQFontDatabase::isFixedPitch( const TQString &family,
					 const TQString &style,
					 const TQString & ) const
*/

/*!
    \obsolete
    \fn inline bool TQFontDatabase::italic( const TQString &family,
				   const TQString &style,
				   const TQString & ) const
*/

/*!
    \obsolete
    \fn inline bool TQFontDatabase::bold( const TQString &family,
				 const TQString &style,
				 const TQString & ) const
*/

/*!
    \obsolete
    \fn inline int TQFontDatabase::weight( const TQString &family,
				  const TQString &style,
				  const TQString & ) const
*/


/*!
    Creates a font database object.
*/
TQFontDatabase::TQFontDatabase()
{
    createDatabase();

    d = db;
}


/*! Returns a sorted list of the names of the available font families.

    If a family exists in several foundries, the returned name for
    that font is in the form "family [foundry]". Examples: "Times
    [Adobe]", "Times [Cronyx]", "Palatino".
*/
TQStringList TQFontDatabase::families() const
{
    load();

    TQStringList flist;
    for ( int i = 0; i < d->count; i++ ) {
	TQtFontFamily *f = d->families[i];
	if ( f->count == 0 )
	    continue;
	if ( f->count == 1 ) {
	    flist.append( f->name );
	} else {
	    for ( int j = 0; j < f->count; j++ ) {
		TQString str = f->name;
		TQString foundry = f->foundries[j]->name;
		if ( !foundry.isEmpty() ) {
		    str += " [";
		    str += foundry;
		    str += "]";
		}
		flist.append( str );
	    }
	}
    }
    return flist;
}

/*!
    \overload

    Returns a sorted list of the available font families which support
    the Unicode script \a script.

    If a family exists in several foundries, the returned name for
    that font is in the form "family [foundry]". Examples: "Times
    [Adobe]", "Times [Cronyx]", "Palatino".
*/
TQStringList TQFontDatabase::families( TQFont::Script script ) const
{
    load();

    TQStringList flist;
    for ( int i = 0; i < d->count; i++ ) {
	TQtFontFamily *f = d->families[i];
	if ( f->count == 0 )
	    continue;
	if (!(f->scripts[script] & TQtFontFamily::Supported))
	    continue;
	if ( f->count == 1 ) {
	    flist.append( f->name );
	} else {
	    for ( int j = 0; j < f->count; j++ ) {
		TQString str = f->name;
		TQString foundry = f->foundries[j]->name;
		if ( !foundry.isEmpty() ) {
		    str += " [";
		    str += foundry;
		    str += "]";
		}
		flist.append( str );
	    }
	}
    }
    return flist;
}

/*!
    Returns a list of the styles available for the font family \a
    family. Some example styles: "Light", "Light Italic", "Bold",
    "Oblique", "Demi". The list may be empty.
*/
TQStringList TQFontDatabase::styles( const TQString &family ) const
{
    TQString familyName,  foundryName;
    parseFontName( family, foundryName, familyName );

    load( familyName );

    TQStringList l;
    TQtFontFamily *f = d->family( familyName );
    if ( !f )
	return l;

    TQtFontFoundry allStyles( foundryName );
    for ( int j = 0; j < f->count; j++ ) {
	TQtFontFoundry *foundry = f->foundries[j];
	if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
	    for ( int k = 0; k < foundry->count; k++ ) {
		TQtFontStyle::Key ke( foundry->styles[k]->key );
		ke.stretch = 0;
		allStyles.style( ke,  TRUE );
	    }
	}
    }

    for ( int i = 0; i < allStyles.count; i++ )
	l.append( ::styleString( allStyles.styles[i]->key.weight,
				 allStyles.styles[i]->key.italic,
				 allStyles.styles[i]->key.oblique ) );
    return l;
}

/*!
    Returns TRUE if the font that has family \a family and style \a
    style is fixed pitch; otherwise returns FALSE.
*/

bool TQFontDatabase::isFixedPitch(const TQString &family,
				 const TQString &style) const
{
    Q_UNUSED(style);

    TQString familyName,  foundryName;
    parseFontName( family, foundryName, familyName );

    load( familyName );

    TQtFontFamily *f = d->family( familyName );
#if defined(Q_OS_MAC) && !defined(TQWS)
    if (f) {
	if (!f->fixedPitchComputed) {
	    TQFontMetrics fm(familyName);
	    f->fixedPitch = fm.width('i') == fm.width('m');
	    f->fixedPitchComputed = TRUE;
	}
    }
#endif

    return ( f && f->fixedPitch );
}

/*!
    Returns TRUE if the font that has family \a family and style \a
    style is a scalable bitmap font; otherwise returns FALSE. Scaling
    a bitmap font usually produces an unattractive hardly readable
    result, because the pixels of the font are scaled. If you need to
    scale a bitmap font it is better to scale it to one of the fixed
    sizes returned by smoothSizes().

    \sa isScalable(), isSmoothlyScalable()
*/
bool TQFontDatabase::isBitmapScalable( const TQString &family,
				      const TQString &style) const
{
    bool bitmapScalable = FALSE;
    TQString familyName,  foundryName;
    parseFontName( family, foundryName, familyName );

    load( familyName );

    TQtFontStyle::Key styleKey( style );

    TQtFontFamily *f = d->family( familyName );
    if ( !f ) return bitmapScalable;

    for ( int j = 0; j < f->count; j++ ) {
	TQtFontFoundry *foundry = f->foundries[j];
	if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
	    for ( int k = 0; k < foundry->count; k++ )
		if ((style.isEmpty() || foundry->styles[k]->key == styleKey) &&
                    foundry->styles[k]->bitmapScalable && !foundry->styles[k]->smoothScalable) {
		    bitmapScalable = TRUE;
		    goto end;
		}
	}
    }
 end:
    return bitmapScalable;
}


/*!
    Returns TRUE if the font that has family \a family and style \a
    style is smoothly scalable; otherwise returns FALSE. If this
    function returns TRUE, it's safe to scale this font to any size,
    and the result will always look attractive.

    \sa isScalable(), isBitmapScalable()
*/
bool  TQFontDatabase::isSmoothlyScalable( const TQString &family,
                                         const TQString &style) const
{
    bool smoothScalable = FALSE;
    TQString familyName,  foundryName;
    parseFontName( family, foundryName, familyName );

    load( familyName );

    TQtFontStyle::Key styleKey( style );

    TQtFontFamily *f = d->family( familyName );
    if ( !f ) return smoothScalable;

    for ( int j = 0; j < f->count; j++ ) {
	TQtFontFoundry *foundry = f->foundries[j];
	if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
	    for ( int k = 0; k < foundry->count; k++ )
		if ((style.isEmpty() || foundry->styles[k]->key == styleKey) && foundry->styles[k]->smoothScalable) {
		    smoothScalable = TRUE;
		    goto end;
		}
	}
    }
 end:
    return smoothScalable;
}

/*!
    Returns TRUE if the font that has family \a family and style \a
    style is scalable; otherwise returns FALSE.

    \sa isBitmapScalable(), isSmoothlyScalable()
*/
bool  TQFontDatabase::isScalable( const TQString &family,
                                 const TQString &style) const
{
    if ( isSmoothlyScalable( family, style) )
        return TRUE;

    return isBitmapScalable( family, style);
}


/*!
    Returns a list of the point sizes available for the font that has
    family \a family and style \a style. The list may be empty.

    \sa smoothSizes(), standardSizes()
*/
TQValueList<int> TQFontDatabase::pointSizes( const TQString &family,
					   const TQString &style)
{
#if defined(Q_WS_MAC)
    // windows and macosx are always smoothly scalable
    Q_UNUSED( family );
    Q_UNUSED( style );
    return standardSizes();
#else
    bool smoothScalable = FALSE;
    TQString familyName,  foundryName;
    parseFontName( family, foundryName, familyName );

    load( familyName );

    TQtFontStyle::Key styleKey( style );

    TQValueList<int> sizes;

    TQtFontFamily *fam = d->family( familyName );
    if ( !fam ) return sizes;

    for ( int j = 0; j < fam->count; j++ ) {
	TQtFontFoundry *foundry = fam->foundries[j];
	if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
	    TQtFontStyle *style = foundry->style( styleKey );
	    if ( !style ) continue;

	    if ( style->smoothScalable ) {
		smoothScalable = TRUE;
		goto end;
	    }
	    for ( int l = 0; l < style->count; l++ ) {
		const TQtFontSize *size = style->pixelSizes + l;

		if (size->pixelSize != 0 && size->pixelSize != USHRT_MAX) {
#ifdef Q_WS_X11
		    const uint pointSize = tqRound(qt_pointSize(size->pixelSize, 0, -1));
#else
		    const uint pointSize = size->pixelSize; // embedded uses 72dpi
#endif
		    if (! sizes.contains(pointSize))
			sizes.append(pointSize);
		}
	    }
	}
    }
 end:
    if ( smoothScalable )
	return standardSizes();

    qHeapSort( sizes );
    return sizes;
#endif
}

/*!
    Returns a TQFont object that has family \a family, style \a style
    and point size \a pointSize. If no matching font could be created,
    a TQFont object that uses the application's default font is
    returned.
*/
TQFont TQFontDatabase::font( const TQString &family, const TQString &style,
                           int pointSize)
{
    TQString familyName,  foundryName;
    parseFontName( family, foundryName, familyName );

    load( familyName );

    TQtFontFoundry allStyles( foundryName );
    TQtFontFamily *f = d->family( familyName );
    if ( !f ) return TQApplication::font();

    for ( int j = 0; j < f->count; j++ ) {
	TQtFontFoundry *foundry = f->foundries[j];
	if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
	    for ( int k = 0; k < foundry->count; k++ )
		allStyles.style( foundry->styles[k]->key,  TRUE );
	}
    }

    TQtFontStyle::Key styleKey( style );
    TQtFontStyle *s = bestStyle(&allStyles, styleKey);

    if ( !s ) // no styles found?
	return TQApplication::font();
    return TQFont( family, pointSize, s->key.weight,
		  s->key.italic ? TRUE : s->key.oblique ? TRUE : FALSE );
}


/*!
    Returns the point sizes of a font that has family \a family and
    style \a style that will look attractive. The list may be empty.
    For non-scalable fonts and bitmap scalable fonts, this function
    is equivalent to pointSizes().

  \sa pointSizes(), standardSizes()
*/
TQValueList<int> TQFontDatabase::smoothSizes( const TQString &family,
					    const TQString &style)
{
#ifdef Q_WS_WIN
    Q_UNUSED( family );
    Q_UNUSED( style );
    return TQFontDatabase::standardSizes();
#else
    bool smoothScalable = FALSE;
    TQString familyName,  foundryName;
    parseFontName( family, foundryName, familyName );

    load( familyName );

    TQtFontStyle::Key styleKey( style );

    TQValueList<int> sizes;

    TQtFontFamily *fam = d->family( familyName );
    if ( !fam )
	return sizes;

    for ( int j = 0; j < fam->count; j++ ) {
	TQtFontFoundry *foundry = fam->foundries[j];
	if ( foundryName.isEmpty() ||
	     ucstricmp( foundry->name, foundryName ) == 0 ) {
	    TQtFontStyle *style = foundry->style( styleKey );
	    if ( !style ) continue;

	    if ( style->smoothScalable ) {
		smoothScalable = TRUE;
		goto end;
	    }
	    for ( int l = 0; l < style->count; l++ ) {
		const TQtFontSize *size = style->pixelSizes + l;

		if ( size->pixelSize != 0 && size->pixelSize != USHRT_MAX ) {
#ifdef Q_WS_X11
		    const uint pointSize = tqRound(qt_pointSize(size->pixelSize, 0, -1));
#else
		    const uint pointSize = size->pixelSize; // embedded uses 72dpi
#endif
		    if (! sizes.contains(pointSize))
			sizes.append( pointSize );
		}
	    }
	}
    }
 end:
    if ( smoothScalable )
	return TQFontDatabase::standardSizes();

    qHeapSort( sizes );
    return sizes;
#endif
}


/*!
    Returns a list of standard font sizes.

    \sa smoothSizes(), pointSizes()
*/
TQValueList<int> TQFontDatabase::standardSizes()
{
    TQValueList<int> ret;
    static const unsigned short standard[] =
	{ 6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 22, 24, 26, 28, 36, 48, 72, 0 };
    const unsigned short *sizes = standard;
    while ( *sizes ) ret << *sizes++;
    return ret;
}


/*!
    Returns TRUE if the font that has family \a family and style \a
    style is italic; otherwise returns FALSE.

    \sa weight(), bold()
*/
bool TQFontDatabase::italic( const TQString &family,
                            const TQString &style) const
{
    TQString familyName,  foundryName;
    parseFontName( family, foundryName, familyName );

    load( familyName );

    TQtFontFoundry allStyles( foundryName );
    TQtFontFamily *f = d->family( familyName );
    if ( !f ) return FALSE;

    for ( int j = 0; j < f->count; j++ ) {
	TQtFontFoundry *foundry = f->foundries[j];
	if ( foundryName.isEmpty() || ucstricmp( foundry->name, foundryName ) == 0 ) {
	    for ( int k = 0; k < foundry->count; k++ )
		allStyles.style( foundry->styles[k]->key,  TRUE );
	}
    }

    TQtFontStyle::Key styleKey( style );
    TQtFontStyle *s = allStyles.style( styleKey );
    return s && s->key.italic;
}


/*!
    Returns TRUE if the font that has family \a family and style \a
    style is bold; otherwise returns FALSE.

    \sa italic(), weight()
*/
bool TQFontDatabase::bold( const TQString &family,
			  const TQString &style) const
{
    TQString familyName,  foundryName;
    parseFontName( family, foundryName, familyName );

    load( familyName );

    TQtFontFoundry allStyles( foundryName );
    TQtFontFamily *f = d->family( familyName );
    if ( !f ) return FALSE;

    for ( int j = 0; j < f->count; j++ ) {
	TQtFontFoundry *foundry = f->foundries[j];
	if ( foundryName.isEmpty() ||
	     ucstricmp( foundry->name, foundryName ) == 0 ) {
	    for ( int k = 0; k < foundry->count; k++ )
		allStyles.style( foundry->styles[k]->key,  TRUE );
	}
    }

    TQtFontStyle::Key styleKey( style );
    TQtFontStyle *s = allStyles.style( styleKey );
    return s && s->key.weight >= TQFont::Bold;
}


/*!
    Returns the weight of the font that has family \a family and style
    \a style. If there is no such family and style combination,
    returns -1.

    \sa italic(), bold()
*/
int TQFontDatabase::weight( const TQString &family,
                           const TQString &style) const
{
    TQString familyName,  foundryName;
    parseFontName( family, foundryName, familyName );

    load( familyName );

    TQtFontFoundry allStyles( foundryName );
    TQtFontFamily *f = d->family( familyName );
    if ( !f ) return -1;

    for ( int j = 0; j < f->count; j++ ) {
	TQtFontFoundry *foundry = f->foundries[j];
	if ( foundryName.isEmpty() ||
	     ucstricmp( foundry->name, foundryName ) == 0 ) {
	    for ( int k = 0; k < foundry->count; k++ )
		allStyles.style( foundry->styles[k]->key,  TRUE );
	}
    }

    TQtFontStyle::Key styleKey( style );
    TQtFontStyle *s = allStyles.style( styleKey );
    return s ? s->key.weight : -1;
}


/*!
    Returns a string that gives a default description of the \a script
    (e.g. for displaying to the user in a dialog).  The name matches
    the name of the script as defined by the Unicode 3.0 standard.

    \sa TQFont::Script
*/
TQString TQFontDatabase::scriptName(TQFont::Script script)
{
    const char *name = 0;

    switch (script) {
    case TQFont::Latin:
	name = QT_TRANSLATE_NOOP("TQFont",  "Latin");
	break;
    case TQFont::Greek:
	name = QT_TRANSLATE_NOOP("TQFont",  "Greek" );
	break;
    case TQFont::Cyrillic:
	name = QT_TRANSLATE_NOOP("TQFont",  "Cyrillic" );
	break;
    case TQFont::Armenian:
	name = QT_TRANSLATE_NOOP("TQFont",  "Armenian" );
	break;
    case TQFont::Georgian:
	name = QT_TRANSLATE_NOOP("TQFont",  "Georgian" );
	break;
    case TQFont::Runic:
	name = QT_TRANSLATE_NOOP("TQFont",  "Runic" );
	break;
    case TQFont::Ogham:
	name = QT_TRANSLATE_NOOP("TQFont",  "Ogham" );
	break;
    case TQFont::SpacingModifiers:
	name = QT_TRANSLATE_NOOP("TQFont",  "SpacingModifiers" );
	break;
    case TQFont::CombiningMarks:
	name = QT_TRANSLATE_NOOP("TQFont",  "CombiningMarks" );
	break;
    case TQFont::Hebrew:
	name = QT_TRANSLATE_NOOP("TQFont",  "Hebrew" );
	break;
    case TQFont::Arabic:
	name = QT_TRANSLATE_NOOP("TQFont",  "Arabic" );
	break;
    case TQFont::Syriac:
	name = QT_TRANSLATE_NOOP("TQFont",  "Syriac" );
	break;
    case TQFont::Thaana:
	name = QT_TRANSLATE_NOOP("TQFont",  "Thaana" );
	break;
    case TQFont::Devanagari:
	name = QT_TRANSLATE_NOOP("TQFont",  "Devanagari" );
	break;
    case TQFont::Bengali:
	name = QT_TRANSLATE_NOOP("TQFont",  "Bengali" );
	break;
    case TQFont::Gurmukhi:
	name = QT_TRANSLATE_NOOP("TQFont",  "Gurmukhi" );
	break;
    case TQFont::Gujarati:
	name = QT_TRANSLATE_NOOP("TQFont",  "Gujarati" );
	break;
    case TQFont::Oriya:
	name = QT_TRANSLATE_NOOP("TQFont",  "Oriya" );
	break;
    case TQFont::Tamil:
	name = QT_TRANSLATE_NOOP("TQFont",  "Tamil" );
	break;
    case TQFont::Telugu:
	name = QT_TRANSLATE_NOOP("TQFont",  "Telugu" );
	break;
    case TQFont::Kannada:
	name = QT_TRANSLATE_NOOP("TQFont",  "Kannada" );
	break;
    case TQFont::Malayalam:
	name = QT_TRANSLATE_NOOP("TQFont",  "Malayalam" );
	break;
    case TQFont::Sinhala:
	name = QT_TRANSLATE_NOOP("TQFont",  "Sinhala" );
	break;
    case TQFont::Thai:
	name = QT_TRANSLATE_NOOP("TQFont",  "Thai" );
	break;
    case TQFont::Lao:
	name = QT_TRANSLATE_NOOP("TQFont",  "Lao" );
	break;
    case TQFont::Tibetan:
	name = QT_TRANSLATE_NOOP("TQFont",  "Tibetan" );
	break;
    case TQFont::Myanmar:
	name = QT_TRANSLATE_NOOP("TQFont",  "Myanmar" );
	break;
    case TQFont::Khmer:
	name = QT_TRANSLATE_NOOP("TQFont",  "Khmer" );
	break;
    case TQFont::Han:
	name = QT_TRANSLATE_NOOP("TQFont",  "Han" );
	break;
    case TQFont::Hiragana:
	name = QT_TRANSLATE_NOOP("TQFont",  "Hiragana" );
	break;
    case TQFont::Katakana:
	name = QT_TRANSLATE_NOOP("TQFont",  "Katakana" );
	break;
    case TQFont::Hangul:
	name = QT_TRANSLATE_NOOP("TQFont",  "Hangul" );
	break;
    case TQFont::Bopomofo:
	name = QT_TRANSLATE_NOOP("TQFont",  "Bopomofo" );
	break;
    case TQFont::Yi:
	name = QT_TRANSLATE_NOOP("TQFont",  "Yi" );
	break;
    case TQFont::Ethiopic:
	name = QT_TRANSLATE_NOOP("TQFont",  "Ethiopic" );
	break;
    case TQFont::Cherokee:
	name = QT_TRANSLATE_NOOP("TQFont",  "Cherokee" );
	break;
    case TQFont::CanadianAboriginal:
	name = QT_TRANSLATE_NOOP("TQFont",  "Canadian Aboriginal" );
	break;
    case TQFont::Mongolian:
	name = QT_TRANSLATE_NOOP("TQFont",  "Mongolian" );
	break;

    case TQFont::CurrencySymbols:
	name = QT_TRANSLATE_NOOP("TQFont",  "Currency Symbols" );
	break;

    case TQFont::LetterlikeSymbols:
	name = QT_TRANSLATE_NOOP("TQFont",  "Letterlike Symbols" );
	break;

    case TQFont::NumberForms:
	name = QT_TRANSLATE_NOOP("TQFont",  "Number Forms" );
	break;

    case TQFont::MathematicalOperators:
	name = QT_TRANSLATE_NOOP("TQFont",  "Mathematical Operators" );
	break;

    case TQFont::TechnicalSymbols:
	name = QT_TRANSLATE_NOOP("TQFont",  "Technical Symbols" );
	break;

    case TQFont::GeometricSymbols:
	name = QT_TRANSLATE_NOOP("TQFont",  "Geometric Symbols" );
	break;

    case TQFont::MiscellaneousSymbols:
	name = QT_TRANSLATE_NOOP("TQFont",  "Miscellaneous Symbols" );
	break;

    case TQFont::EnclosedAndSquare:
	name = QT_TRANSLATE_NOOP("TQFont",  "Enclosed and Square" );
	break;

    case TQFont::Braille:
	name = QT_TRANSLATE_NOOP("TQFont",  "Braille" );
	break;

    case TQFont::Unicode:
	name = QT_TRANSLATE_NOOP("TQFont",  "Unicode" );
	break;

    case TQFont::Tagalog:
	name = QT_TRANSLATE_NOOP( "TQFont", "Tagalog" );
	break;

    case TQFont::Hanunoo:
	name = QT_TRANSLATE_NOOP( "TQFont", "Hanunoo" );
	break;

    case TQFont::Buhid:
	name = QT_TRANSLATE_NOOP( "TQFont", "Buhid" );
    	break;

    case TQFont::Tagbanwa:
	name = QT_TRANSLATE_NOOP( "TQFont", "Tagbanwa" );
	break;

    case TQFont::KatakanaHalfWidth:
	name = QT_TRANSLATE_NOOP( "TQFont", "Katakana Half-Width Forms" );
	break;

    case TQFont::Han_Japanese:
	name = QT_TRANSLATE_NOOP( "TQFont", "Han (Japanese)" );
	break;

    case TQFont::Han_SimplifiedChinese:
	name = QT_TRANSLATE_NOOP( "TQFont", "Han (Simplified Chinese)" );
	break;

    case TQFont::Han_TraditionalChinese:
	name = QT_TRANSLATE_NOOP( "TQFont", "Han (Traditional Chinese)" );
	break;

    case TQFont::Han_Korean:
	name = QT_TRANSLATE_NOOP( "TQFont", "Han (Korean)" );
	break;

    default:
	name = QT_TRANSLATE_NOOP( "TQFont", "Unknown Script" );
	break;
    }

    return tqApp ? tqApp->translate("TQFont", name) : TQString::fromLatin1(name);
}


/*!
    Returns a string with sample characters from \a script.

    \sa TQFont::Script
*/
TQString TQFontDatabase::scriptSample(TQFont::Script script)
{
    TQString sample = "AaBb";

    switch (script) {
    case TQFont::Latin:
	// This is cheating... we only show latin-1 characters so that we don't
	// end up loading lots of fonts - at least on X11...
	sample += TQChar(0x00C3);
	sample += TQChar(0x00E1);
	sample += "Zz";
	break;
    case TQFont::Greek:
	sample += TQChar(0x0393);
	sample += TQChar(0x03B1);
	sample += TQChar(0x03A9);
	sample += TQChar(0x03C9);
	break;
    case TQFont::Cyrillic:
	sample += TQChar(0x0414);
	sample += TQChar(0x0434);
	sample += TQChar(0x0436);
	sample += TQChar(0x0402);
	break;
    case TQFont::Armenian:
	sample += TQChar(0x053f);
	sample += TQChar(0x054f);
	sample += TQChar(0x056f);
	sample += TQChar(0x057f);
	break;
    case TQFont::Georgian:
	sample += TQChar(0x10a0);
	sample += TQChar(0x10b0);
	sample += TQChar(0x10c0);
	sample += TQChar(0x10d0);
	break;
    case TQFont::Runic:
	sample += TQChar(0x16a0);
	sample += TQChar(0x16b0);
	sample += TQChar(0x16c0);
	sample += TQChar(0x16d0);
	break;
    case TQFont::Ogham:
	sample += TQChar(0x1681);
	sample += TQChar(0x1687);
	sample += TQChar(0x1693);
	sample += TQChar(0x168d);
	break;



    case TQFont::Hebrew:
        sample += TQChar(0x05D0);
        sample += TQChar(0x05D1);
        sample += TQChar(0x05D2);
        sample += TQChar(0x05D3);
	break;
    case TQFont::Arabic:
	sample += TQChar(0x0628);
	sample += TQChar(0x0629);
        sample += TQChar(0x062A);
        sample += TQChar(0x063A);
	break;
    case TQFont::Syriac:
	sample += TQChar(0x0715);
	sample += TQChar(0x0725);
	sample += TQChar(0x0716);
	sample += TQChar(0x0726);
	break;
    case TQFont::Thaana:
	sample += TQChar(0x0784);
	sample += TQChar(0x0794);
	sample += TQChar(0x078c);
	sample += TQChar(0x078d);
	break;



    case TQFont::Devanagari:
	sample += TQChar(0x0905);
	sample += TQChar(0x0915);
	sample += TQChar(0x0925);
	sample += TQChar(0x0935);
	break;
    case TQFont::Bengali:
	sample += TQChar(0x0986);
	sample += TQChar(0x0996);
	sample += TQChar(0x09a6);
	sample += TQChar(0x09b6);
	break;
    case TQFont::Gurmukhi:
	sample += TQChar(0x0a05);
	sample += TQChar(0x0a15);
	sample += TQChar(0x0a25);
	sample += TQChar(0x0a35);
	break;
    case TQFont::Gujarati:
	sample += TQChar(0x0a85);
	sample += TQChar(0x0a95);
	sample += TQChar(0x0aa5);
	sample += TQChar(0x0ab5);
	break;
    case TQFont::Oriya:
	sample += TQChar(0x0b06);
	sample += TQChar(0x0b16);
	sample += TQChar(0x0b2b);
	sample += TQChar(0x0b36);
	break;
    case TQFont::Tamil:
	sample += TQChar(0x0b89);
	sample += TQChar(0x0b99);
	sample += TQChar(0x0ba9);
	sample += TQChar(0x0bb9);
	break;
    case TQFont::Telugu:
	sample += TQChar(0x0c05);
	sample += TQChar(0x0c15);
	sample += TQChar(0x0c25);
	sample += TQChar(0x0c35);
	break;
    case TQFont::Kannada:
	sample += TQChar(0x0c85);
	sample += TQChar(0x0c95);
	sample += TQChar(0x0ca5);
	sample += TQChar(0x0cb5);
	break;
    case TQFont::Malayalam:
	sample += TQChar(0x0d05);
	sample += TQChar(0x0d15);
	sample += TQChar(0x0d25);
	sample += TQChar(0x0d35);
	break;
    case TQFont::Sinhala:
	sample += TQChar(0x0d90);
	sample += TQChar(0x0da0);
	sample += TQChar(0x0db0);
	sample += TQChar(0x0dc0);
	break;
    case TQFont::Thai:
	sample += TQChar(0x0e02);
	sample += TQChar(0x0e12);
	sample += TQChar(0x0e22);
	sample += TQChar(0x0e32);
	break;
    case TQFont::Lao:
	sample += TQChar(0x0e8d);
	sample += TQChar(0x0e9d);
	sample += TQChar(0x0ead);
	sample += TQChar(0x0ebd);
	break;
    case TQFont::Tibetan:
	sample += TQChar(0x0f00);
	sample += TQChar(0x0f01);
	sample += TQChar(0x0f02);
	sample += TQChar(0x0f03);
	break;
    case TQFont::Myanmar:
	sample += TQChar(0x1000);
	sample += TQChar(0x1001);
	sample += TQChar(0x1002);
	sample += TQChar(0x1003);
	break;
    case TQFont::Khmer:
	sample += TQChar(0x1780);
	sample += TQChar(0x1790);
	sample += TQChar(0x17b0);
	sample += TQChar(0x17c0);
	break;



    case TQFont::Han:
	sample += TQChar(0x6f84);
	sample += TQChar(0x820a);
	sample += TQChar(0x61a9);
	sample += TQChar(0x9781);
	break;
    case TQFont::Hiragana:
	sample += TQChar(0x3050);
	sample += TQChar(0x3060);
	sample += TQChar(0x3070);
	sample += TQChar(0x3080);
	break;
    case TQFont::Katakana:
	sample += TQChar(0x30b0);
	sample += TQChar(0x30c0);
	sample += TQChar(0x30d0);
	sample += TQChar(0x30e0);
	break;
    case TQFont::Hangul:
	sample += TQChar(0xac00);
	sample += TQChar(0xac11);
	sample += TQChar(0xac1a);
	sample += TQChar(0xac2f);
	break;
    case TQFont::Bopomofo:
	sample += TQChar(0x3105);
	sample += TQChar(0x3115);
	sample += TQChar(0x3125);
	sample += TQChar(0x3129);
	break;
    case TQFont::Yi:
	sample += TQChar(0xa1a8);
	sample += TQChar(0xa1a6);
	sample += TQChar(0xa200);
	sample += TQChar(0xa280);
	break;



    case TQFont::Ethiopic:
	sample += TQChar(0x1200);
	sample += TQChar(0x1240);
	sample += TQChar(0x1280);
	sample += TQChar(0x12c0);
	break;
    case TQFont::Cherokee:
	sample += TQChar(0x13a0);
	sample += TQChar(0x13b0);
	sample += TQChar(0x13c0);
	sample += TQChar(0x13d0);
	break;
    case TQFont::CanadianAboriginal:
	sample += TQChar(0x1410);
	sample += TQChar(0x1500);
	sample += TQChar(0x15f0);
	sample += TQChar(0x1650);
	break;
    case TQFont::Mongolian:
	sample += TQChar(0x1820);
	sample += TQChar(0x1840);
	sample += TQChar(0x1860);
	sample += TQChar(0x1880);
	break;


    case TQFont::CurrencySymbols:
    case TQFont::LetterlikeSymbols:
    case TQFont::NumberForms:
    case TQFont::MathematicalOperators:
    case TQFont::TechnicalSymbols:
    case TQFont::GeometricSymbols:
    case TQFont::MiscellaneousSymbols:
    case TQFont::EnclosedAndSquare:
    case TQFont::Braille:
	break;


    case TQFont::Unicode:
	sample += TQChar(0x0174);
	sample += TQChar(0x0628);
	sample += TQChar(0x0e02);
	sample += TQChar(0x263A);
	sample += TQChar(0x3129);
	sample += TQChar(0x61a9);
	sample += TQChar(0xac2f);
	break;



    default:
	sample += TQChar(0xfffd);
	sample += TQChar(0xfffd);
	sample += TQChar(0xfffd);
	sample += TQChar(0xfffd);
	break;
    }

    return sample;
}




/*!
  \internal

  This makes sense of the font family name:

  1) if the family name contains a '-' (ie. "Adobe-Courier"), then we
  split at the '-', and use the string as the foundry, and the string to
  the right as the family

  2) if the family name contains a '[' and a ']', then we take the text
  between the square brackets as the foundry, and the text before the
  square brackets as the family (ie. "Arial [Monotype]")
*/
void TQFontDatabase::parseFontName(const TQString &name, TQString &foundry, TQString &family)
{
    if ( name.contains('-') ) {
	int i = name.find('-');
	foundry = name.left( i );
	family = name.right( name.length() - i - 1 );
    } else if ( name.contains('[') && name.contains(']')) {
	int i = name.find('[');
	int li = name.findRev(']');

	if (i < li) {
	    foundry = name.mid(i + 1, li - i - 1);
	    if (name[i - 1] == ' ')
		i--;
	    family = name.left(i);
	}
    } else {
	foundry = TQString::null;
	family = name;
    }
}

#endif // QT_NO_FONTDATABASE
