kcharsets.cpp

来自「将konqueror浏览器移植到ARM9 2410中」· C++ 代码 · 共 920 行 · 第 1/2 页

CPP
920
字号
/* This file is part of the KDE libraries    Copyright (C) 1999 Lars Knoll (knoll@kde.org)    $Id: kcharsets.cpp,v 1.111.2.2 2002/08/21 16:11:48 pchitescu Exp $    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    Library General Public License for more details.    You should have received a copy of the GNU Library General Public License    along with this library; see the file COPYING.LIB.  If not, write to    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,    Boston, MA 02111-1307, USA.*/#include "kcharsets.h"#include "kentities.c"#include <kapp.h>#include <kglobal.h>#include <klocale.h>#include <kconfig.h>#include <qfontinfo.h>#include <qstrlist.h>#include <qfontdatabase.h>#include <kdebug.h>#include <qtextcodec.h>#include <qmap.h>#include <qcstring.h>template class QList<QFont::CharSet>;#if QT_VERSION >= 224#define CHARSETS_COUNT 32#else#define CHARSETS_COUNT 30#endifstatic const char * const charsetsStr[CHARSETS_COUNT] = {    "unicode",    "iso-8859-1",    "iso-8859-2",    "iso-8859-3",    "iso-8859-4",    "iso-8859-5",    "iso-8859-6",    "iso-8859-7",    "iso-8859-8",    "iso-8859-9",    "iso-8859-10",    "iso-8859-11",    "iso-8859-12",    "iso-8859-13",    "iso-8859-14",    "iso-8859-15",    "koi8r",    "koi8u",#if QT_VERSION >= 224    "cp 1251",    "pt 154",#endif    "eucjp",    "euckr",    "set-th-th",    "set-gbk",    "set-zh",    "set-zh-tw",    "big5",    "tscii",    "utf-8",    "utf-16",    "iso-8859-11",    "Any"};// these can contain wildcard characters. Needed for fontset matching (CJK fonts)// sort them by length if they have the same prefix!static const char * const xNames[CHARSETS_COUNT] = {    "iso10646-1",    "iso8859-1",    "iso8859-2",    "iso8859-3",    "iso8859-4",    "iso8859-5",    "iso8859-6",    "iso8859-7",    "iso8859-8",    "iso8859-9",    "iso8859-10",    "iso8859-11",    "iso8859-12",    "iso8859-13",    "iso8859-14",    "iso8859-15",    "koi8-r",    "koi8-u",#if QT_VERSION >= 224    "microsoft-cp1251",    "paratype-cp154",#endif    "jisx0208.1983-0",    "ksc5601.1987-0",    "tis620.2533-1",    "gb2312.1980-0",    "gb2312.1980-0",    "cns11643.1986-",    "big5-0",    "tscii-0",    "utf8",    "utf16",    "tis620-0",    ""  // this will always return true...        // adjust xNameToId if you remove this};static const QFont::CharSet charsetsIds[CHARSETS_COUNT] = {    QFont::Unicode,    QFont::ISO_8859_1,    QFont::ISO_8859_2,    QFont::ISO_8859_3,    QFont::ISO_8859_4,    QFont::ISO_8859_5,    QFont::ISO_8859_6,    QFont::ISO_8859_7,    QFont::ISO_8859_8,    QFont::ISO_8859_9,    QFont::ISO_8859_10,    QFont::ISO_8859_11,    QFont::ISO_8859_12,    QFont::ISO_8859_13,    QFont::ISO_8859_14,    QFont::ISO_8859_15,    QFont::KOI8R,    QFont::KOI8U,#if QT_VERSION >= 224    QFont::CP1251,    QFont::PT154,#endif    QFont::Set_Ja,    QFont::Set_Ko,    QFont::Set_Th_TH,    QFont::Set_GBK,    QFont::Set_Zh,    QFont::Set_Zh_TW,    QFont::Set_Big5,    QFont::TSCII,    QFont::Unicode,    QFont::Unicode,    QFont::ISO_8859_11,    QFont::AnyCharSet};static const char * const languages[] = {    I18N_NOOP( "other" ),	I18N_NOOP( "Arabic" ),	I18N_NOOP( "Baltic" ),	I18N_NOOP( "Central European" ),	I18N_NOOP( "Chinese Simplified" ),	I18N_NOOP( "Chinese Traditional" ),	I18N_NOOP( "Cyrillic" ),	I18N_NOOP( "Greek" ),	I18N_NOOP( "Hebrew" ),	I18N_NOOP( "Japanese" ),	I18N_NOOP( "Korean" ),	I18N_NOOP( "Thai" ),	I18N_NOOP( "Turkish" ),	I18N_NOOP( "Western European" ),	I18N_NOOP( "Tamil" ),	I18N_NOOP( "Unicode" )};class KCharsetsPrivate{public:    KCharsetsPrivate(KCharsets* _kc)        : codecForNameDict(43, false) // case insensitive    {        db = 0;        availableCharsets = 0;        kc = _kc;	_conf = 0;    }    ~KCharsetsPrivate()    {        delete db;        delete availableCharsets;        delete _conf;    }    KConfig* conf()	{	if( _conf == NULL )            _conf = new KConfig( "charsets", true, false );	return _conf;	}    QFontDatabase *db;    QMap<QFont::CharSet, QStrList> *availableCharsets;    QMap<QCString, QFont::CharSet> charsetForEncodingMap;    QMap<QString, QFont::CharSet> nameToIDMap;    QAsciiDict<QTextCodec> codecForNameDict;    KCharsets* kc;    KConfig* _conf;    void getAvailableCharsets();};void KCharsetsPrivate::getAvailableCharsets(){    if(availableCharsets)        return;    if(!db)        db = new QFontDatabase;    availableCharsets = new QMap<QFont::CharSet, QStrList >;    QStringList f = db->families( false );    for ( QStringList::ConstIterator it = f.begin(); it != f.end(); ++it ) {	QStringList chSets = db->charSets(*it, false);	QCString family = (*it).latin1(); // can only be latin1        QCString shortFamily; // family without foundry, if "family" contains the foundry        int dashPos = family.find( '-' );	if ( dashPos != -1 )	    shortFamily = family.right( family.length() - dashPos - 1);	//kdDebug() << "KCharsetsPrivate full-family='" << *it << "' family='" << family << "'  charsets: " << chSets.join(",") << endl;	for ( QStringList::ConstIterator ch = chSets.begin(); ch != chSets.end(); ++ch ) {	    //kdDebug() << "    " << *ch << " " << KGlobal::charsets()->xNameToID( *ch ) << endl;	    QCString cs = (*ch).latin1();	    QFont::CharSet qcs = kc->xNameToID( cs );	redo:	    if ( qcs != QFont::AnyCharSet )		if( !availableCharsets->contains( qcs ) ) {		    QStrList strList;		    strList.append( family );		    if ( !shortFamily.isEmpty() )			strList.append( shortFamily );		    availableCharsets->insert( qcs, strList );		} else		{		    ((*availableCharsets)[qcs]).append(family);		    if ( !shortFamily.isEmpty() )			((*availableCharsets)[qcs]).append(shortFamily);		}	    // hack to get the duplicated entry for gb2312 right.	    if ( qcs == QFont::Set_Zh ) {		qcs = QFont::Set_GBK;		goto redo;	    }	}    }    // sort lists to avoid "Arial Black" being found before "Arial"    for( QMap<QFont::CharSet, QStrList >::Iterator it = availableCharsets->begin();         it != availableCharsets->end(); ++it )        it.data().sort();#if 0    for( QMap<QFont::CharSet, QValueList<QCString> >::Iterator it = availableCharsets->begin();         it != availableCharsets->end(); ++it ) {        kdDebug() << "KCharsetsPrivate::getAvailableCharsets " << it.key() << " " << endl;    }#endif}// --------------------------------------------------------------------------KCharsets::KCharsets(){    d = new KCharsetsPrivate(this);}KCharsets::~KCharsets(){    delete d;}QChar KCharsets::fromEntity(const QString &str) const{    QChar res = QChar::null;    int pos = 0;    if(str[pos] == '&') pos++;    // Check for '&#000' or '&#x0000' sequence    if (str[pos] == '#' && str.length()-pos > 1) {        bool ok;        pos++;        if (str[pos] == 'x' || str[pos] == 'X') {            pos++;            // '&#x0000', hexadeciaml character reference            QString tmp(str.unicode()+pos, str.length()-pos);            res = tmp.toInt(&ok, 16);        } else {            //  '&#0000', deciaml character reference            QString tmp(str.unicode()+pos, str.length()-pos);            res = tmp.toInt(&ok, 10);        }        return res;    }    const entity *e = findEntity(str.ascii(), str.length());    if(!e)    {        //kdDebug( 0 ) << "unknown entity " << str <<", len = " << str.length() << endl;        return QChar::null;    }    //kdDebug() << "got entity " << str << " = " << e->code << endl;    return QChar(e->code);}QChar KCharsets::fromEntity(const QString &str, int &len) const{    // entities are never longer than 8 chars... we start from    // that length and work backwards...    len = 8;    while(len > 0)    {        QString tmp = str.left(len);        QChar res = fromEntity(tmp);        if( res != QChar::null ) return res;        len--;    }    return QChar::null;}QString KCharsets::toEntity(const QChar &ch) const{    QString ent;    ent.sprintf("&#0x%x;", ch.unicode());    return ent;}QList<QFont::CharSet> KCharsets::availableCharsets(QString family){    if(!d->db)        d->db = new QFontDatabase;    d->getAvailableCharsets();    QList<QFont::CharSet> chSets;    //chSets.setAutoDelete(true);    QCString f = family.latin1();    for( QMap<QFont::CharSet, QStrList >::Iterator it = d->availableCharsets->begin();         it != d->availableCharsets->end(); ++it ) {	if ( f.isEmpty() || it.data().contains( f.data() ) ) {	    QFont::CharSet *i = new QFont::CharSet;	    *i = it.key();	    chSets.append( i );	}    }    return chSets;}QStringList KCharsets::availableCharsetNames(QString family){    QList<QFont::CharSet> list = availableCharsets( family );    list.setAutoDelete( true );    QStringList chsetNames;    QFont::CharSet *chset;    for ( chset = list.first(); chset != 0; chset = list.next() ) {	chsetNames.append( xCharsetName( *chset ) );    }    return chsetNames;}QStringList KCharsets::availableEncodingNames(){    QStringList available;    QMap<QString, QString> map = d->conf()->entryMap("charsetsForEncoding");    d->conf()->setGroup("charsetsForEncoding");    QMap<QString, QString>::ConstIterator it;    for( it = map.begin(); it != map.end(); ++it ) {        //kdDebug(0) << "key = " << it.key() << " string =" << it.data() << endl;        //kdDebug(0) << "list is: " << d->conf->readEntry(it.key()) << endl;        QStringList charsets = d->conf()->readListEntry(it.key());        // iterate thorugh the list and find the first charset that is available        for ( QStringList::ConstIterator sit = charsets.begin(); sit != charsets.end(); ++sit ) {            //kdDebug(0) << "checking for " << *sit << endl;            if( const_cast<KCharsets *>(this)->isAvailable(*sit) ) {                //kdDebug(0) << *sit << " available" << endl;                available.append(it.key());                break;            }        }    }    return available;}QString KCharsets::languageForEncoding( const QString &encoding ){    d->conf()->setGroup("LanguageForEncoding");    int lang = d->conf()->readNumEntry(encoding, 0 );    return i18n( languages[lang] );}QString KCharsets::encodingForName( const QString &descriptiveName ){    int left = descriptiveName.find( "( " );    return descriptiveName.mid( left + 2, descriptiveName.find( " )" )      - left - 2 );}QStringList KCharsets::descriptiveEncodingNames(){  QStringList encodings = availableEncodingNames();  QStringList::Iterator it;  for( it = encodings.begin(); it != encodings.end(); ++it ) {      QString lang = KGlobal::charsets()->languageForEncoding( *it );      *it = lang + " ( " + *it + " )";  }  encodings.sort();  return encodings;}QFont KCharsets::fontForChar( const QChar &c, const QFont &_f ) const{    QFontInfo fi(_f);    // unicode can display any char...    if (fi.charSet() == QFont::Unicode) return _f;    // here comes the work...    // we look at the range the char is in, and try charsets which can    // map the char...    QFont f = _f;    int uc = c.unicode();    if( uc < 0xff ) // 8859-1        setQFont( f, QFont::Latin1 );    else if ( uc > 0x0400 && uc < 0x0460 )        setQFont( f, QFont::Latin5 );    else if ( uc > 0x0600 && uc < 0x0660 )        setQFont( f, QFont::Latin6 );    else if ( uc > 0x0380 && uc < 0x03e0 )        setQFont( f, QFont::Latin7 );    else if ( uc >= 0x05d0 && uc < 0x05f0 )        setQFont( f, QFont::Latin8 );    else if ( hasUnicode( f ) ) // don't know, let's try Unicode        setQFont( f, QFont::Unicode );    return f;

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?