|
Lines 52-57
Link Here
|
| 52 |
|
52 |
|
| 53 |
#ifndef QT_NO_XFTFREETYPE |
53 |
#ifndef QT_NO_XFTFREETYPE |
| 54 |
#include <freetype/freetype.h> |
54 |
#include <freetype/freetype.h> |
|
|
55 |
#include <qfile.h> |
| 56 |
#include <qdict.h> |
| 57 |
#include <qtextcodec.h> |
| 55 |
#endif |
58 |
#endif |
| 56 |
|
59 |
|
| 57 |
#ifdef QFONTDATABASE_DEBUG |
60 |
#ifdef QFONTDATABASE_DEBUG |
|
Lines 783-793
Link Here
|
| 783 |
return qtweight; |
786 |
return qtweight; |
| 784 |
} |
787 |
} |
| 785 |
|
788 |
|
|
|
789 |
|
| 790 |
static void getInfoFromSfntTables( const char *file, uint index, |
| 791 |
QByteArray &tmp_buffer, |
| 792 |
QTextCodec *locale, QTextCodec *utf16, |
| 793 |
QString &familyName, int &spacing ) |
| 794 |
{ |
| 795 |
#define Q_GET_ULONG( p ) ( ( (Q_UINT32)(((Q_UINT8*)(p))[0]) << 24 ) | \ |
| 796 |
( (Q_UINT32)(((Q_UINT8*)(p))[1]) << 16 ) | \ |
| 797 |
( (Q_UINT32)(((Q_UINT8*)(p))[2]) << 8 ) | \ |
| 798 |
( (Q_UINT32)(((Q_UINT8*)(p))[3]) << 0 ) ) |
| 799 |
#define Q_GET_USHORT( p ) ( ( (Q_UINT16)(((Q_UINT8*)(p))[0]) << 8 ) | \ |
| 800 |
( (Q_UINT16)(((Q_UINT8*)(p))[1]) << 0 ) ) |
| 801 |
|
| 802 |
QFile f( QFile::decodeName( QCString( file ) ) ); |
| 803 |
if ( !f.open( IO_ReadOnly ) ) |
| 804 |
return; |
| 805 |
|
| 806 |
char* buf = tmp_buffer.data(); |
| 807 |
char* b = buf; |
| 808 |
Q_UINT16 i; |
| 809 |
|
| 810 |
if ( f.readBlock( buf, 12 ) < 12 ) |
| 811 |
return; |
| 812 |
|
| 813 |
if ( b[0] == 't' && b[1] == 't' && b[2] == 'c' && b[3] == 'f' ) { |
| 814 |
Q_ULONG numFonts = Q_GET_ULONG( b+8 ); |
| 815 |
if ( index + 1 > numFonts ) |
| 816 |
return; |
| 817 |
if ( !f.at( 12 + 4*index ) || f.readBlock( buf, 4 ) < 4 ) |
| 818 |
return; |
| 819 |
Q_ULONG OffsetTable = Q_GET_ULONG( b ); |
| 820 |
if ( !f.at( OffsetTable ) || f.readBlock( buf, 12 ) < 12 ) |
| 821 |
return; |
| 822 |
} |
| 823 |
else if ( index > 0 ) |
| 824 |
return; |
| 825 |
|
| 826 |
// TrueType or CFF ? |
| 827 |
if ( !( b[0] == 0 && b[1] == 1 && b[2] == 0 && b[3] == 0 ) && |
| 828 |
!( b[0] == 'O' && b[1] == 'T' && b[2] == 'T' && b[3] == 'O' ) ) |
| 829 |
return; |
| 830 |
|
| 831 |
Q_ULONG numTables = Q_GET_USHORT( b+4 ); |
| 832 |
if ( numTables == 0 || numTables > 64 || |
| 833 |
(Q_ULONG)f.readBlock( buf, 16 * numTables ) < 16 * numTables ) |
| 834 |
return; |
| 835 |
|
| 836 |
if ( spacing == XFT_PROPORTIONAL ) { |
| 837 |
for ( i = 0, b = buf; i < numTables; i++, b += 16 ) { |
| 838 |
if ( b[0] == 'O' && b[1] == 'S' && b[2] == '/' && b[3] == '2' ) { |
| 839 |
Q_ULONG offset = Q_GET_ULONG( b+8 ); |
| 840 |
Q_UINT8 panose[10]; |
| 841 |
|
| 842 |
if ( !f.at( offset + 16*2 ) || |
| 843 |
f.readBlock( (char *)panose, 10 ) < 10 ) |
| 844 |
break; |
| 845 |
|
| 846 |
if ( panose[3] == 9 ) |
| 847 |
spacing = XFT_MONO; |
| 848 |
break; |
| 849 |
} |
| 850 |
} |
| 851 |
} |
| 852 |
|
| 853 |
|
| 854 |
Q_ULONG table_length = 0; |
| 855 |
for ( i = 0, b = buf; i < numTables; i++, b += 16 ) { |
| 856 |
if ( b[0] == 'n' && b[1] == 'a' && b[2] == 'm' && b[3] == 'e' ) { |
| 857 |
Q_ULONG offset = Q_GET_ULONG( b+8 ); |
| 858 |
Q_ULONG length = Q_GET_ULONG( b+12 ); |
| 859 |
|
| 860 |
if ( length < 12 ) |
| 861 |
return; |
| 862 |
if ( length > tmp_buffer.size() && |
| 863 |
!tmp_buffer.resize( length, QGArray::SpeedOptim ) ) |
| 864 |
return; |
| 865 |
|
| 866 |
buf = tmp_buffer.data(); |
| 867 |
if ( !f.at( offset ) || (Q_ULONG)f.readBlock( buf, length ) < length ) |
| 868 |
return; |
| 869 |
|
| 870 |
table_length = length; |
| 871 |
break; |
| 872 |
} |
| 873 |
} |
| 874 |
|
| 875 |
if ( i == numTables ) |
| 876 |
return; |
| 877 |
|
| 878 |
b = buf; |
| 879 |
Q_UINT16 count = Q_GET_USHORT( b+2 ); |
| 880 |
Q_UINT16 stringOffset = Q_GET_USHORT( b+4 ); |
| 881 |
if ( (Q_ULONG)( 12 + 12 * count ) > table_length ) |
| 882 |
return; |
| 883 |
|
| 884 |
QStringList nameList( familyName ); |
| 885 |
char* strings = buf + stringOffset; |
| 886 |
char* limit = buf + table_length; |
| 887 |
int n_locNames = 0; |
| 888 |
for ( i = 0, b = buf + 6; i < count; i++, b += 12 ) { |
| 889 |
Q_UINT16 platformID = Q_GET_USHORT( b+0 ); |
| 890 |
Q_UINT16 encodingID = Q_GET_USHORT( b+2 ); |
| 891 |
// Q_UINT16 languageID = Q_GET_ULONG( b+4 ); |
| 892 |
Q_UINT16 nameID = Q_GET_USHORT( b+6 ); |
| 893 |
Q_UINT16 length = Q_GET_USHORT( b+8 ); |
| 894 |
Q_UINT16 offset = Q_GET_USHORT( b+10 ); |
| 895 |
|
| 896 |
if ( platformID != 3 || // ! Microsoft |
| 897 |
encodingID != 1 || // ! UTF16 |
| 898 |
nameID != 1 || // ! family name |
| 899 |
strings + offset + length > limit ) // oversize |
| 900 |
continue; |
| 901 |
|
| 902 |
QString family = utf16->toUnicode( strings + offset, length ); |
| 903 |
|
| 904 |
family.replace('-', ' '); |
| 905 |
family.replace("/", ""); |
| 906 |
|
| 907 |
if ( !nameList.contains( family ) ) { |
| 908 |
if ( locale && locale->canEncode( family ) ) { |
| 909 |
nameList.prepend( family ); |
| 910 |
n_locNames += 1; |
| 911 |
|
| 912 |
} else { |
| 913 |
nameList.append( family ); |
| 914 |
} |
| 915 |
} |
| 916 |
} |
| 917 |
|
| 918 |
if ( n_locNames > 0 ) { |
| 919 |
familyName = ""; |
| 920 |
|
| 921 |
QStringList::iterator it = nameList.begin(); |
| 922 |
for ( ; n_locNames > 0; --n_locNames, ++it ) { |
| 923 |
const unsigned short* ucs2 = (*it).ucs2(); |
| 924 |
uint len = (*it).length(); |
| 925 |
|
| 926 |
for ( ; len > 0; len-- ) { |
| 927 |
if ( *ucs2++ >= 128 ) { |
| 928 |
familyName = *it; |
| 929 |
nameList.remove( it ); |
| 930 |
break; |
| 931 |
} |
| 932 |
} |
| 933 |
|
| 934 |
if ( len > 0 ) |
| 935 |
break; |
| 936 |
} |
| 937 |
|
| 938 |
if ( familyName.isEmpty() ) { |
| 939 |
familyName = *nameList.begin(); |
| 940 |
nameList.remove( nameList.begin() ); |
| 941 |
} |
| 942 |
|
| 943 |
} else { |
| 944 |
nameList.remove( nameList.begin() ); |
| 945 |
} |
| 946 |
|
| 947 |
if ( nameList.count() > 0 ) { |
| 948 |
QStringList::iterator it = nameList.begin(); |
| 949 |
QStringList::iterator end = nameList.end(); |
| 950 |
|
| 951 |
for ( ; it != end; ++it ) { |
| 952 |
qt_FamilyDictXft->insert( *it, new QString( familyName ) ); |
| 953 |
} |
| 954 |
} |
| 955 |
} |
| 956 |
|
| 957 |
|
| 786 |
static void loadXft() |
958 |
static void loadXft() |
| 787 |
{ |
959 |
{ |
| 788 |
if (!qt_has_xft) |
960 |
if (!qt_has_xft) |
| 789 |
return; |
961 |
return; |
| 790 |
|
962 |
|
|
|
963 |
if ( !qt_FamilyDictXft ) { |
| 964 |
qt_FamilyDictXft = new QDict<QString>( 17, FALSE ); |
| 965 |
qt_FamilyDictXft->setAutoDelete( TRUE ); |
| 966 |
} |
| 967 |
|
| 791 |
XftFontSet *fonts; |
968 |
XftFontSet *fonts; |
| 792 |
|
969 |
|
| 793 |
QString familyName; |
970 |
QString familyName; |
|
Lines 798-810
Link Here
|
| 798 |
int spacing_value; |
975 |
int spacing_value; |
| 799 |
char *file_value; |
976 |
char *file_value; |
| 800 |
int index_value; |
977 |
int index_value; |
|
|
978 |
char *style_value; |
| 979 |
|
| 980 |
QByteArray tmp_buffer( 4096 ); |
| 981 |
QTextCodec *utf16 = QTextCodec::codecForName( "ISO-10646-UCS-2" ); |
| 982 |
QTextCodec *locale = QTextCodec::codecForLocale(); |
| 983 |
|
| 984 |
int mib = locale ? locale->mibEnum() : 4; |
| 985 |
switch ( mib ) { |
| 986 |
#if 1 |
| 987 |
case 4: // Latin1 |
| 988 |
case 111: // Latin15 |
| 989 |
locale = 0; |
| 990 |
break; |
| 991 |
#else |
| 992 |
case 38: // eucKR |
| 993 |
case 2025: // GB2312 |
| 994 |
case 113: // GBK |
| 995 |
case 114: // GB18030 |
| 996 |
case 2026: // Big5 |
| 997 |
case 2101: // Big5-HKSCS |
| 998 |
case 16: // JIS7 |
| 999 |
case 17: // SJIS |
| 1000 |
case 18: // eucJP |
| 1001 |
break; |
| 1002 |
|
| 1003 |
default: |
| 1004 |
locale = 0; |
| 1005 |
break; |
| 1006 |
#endif |
| 1007 |
} |
| 801 |
|
1008 |
|
| 802 |
fonts = |
1009 |
fonts = |
| 803 |
XftListFonts(QPaintDevice::x11AppDisplay(), |
1010 |
XftListFonts(QPaintDevice::x11AppDisplay(), |
| 804 |
QPaintDevice::x11AppScreen(), |
1011 |
QPaintDevice::x11AppScreen(), |
| 805 |
(const char *)0, |
1012 |
(const char *)0, |
| 806 |
XFT_FAMILY, XFT_WEIGHT, XFT_SLANT, |
1013 |
XFT_FAMILY, XFT_WEIGHT, XFT_SLANT, |
| 807 |
XFT_SPACING, XFT_FILE, XFT_INDEX, |
1014 |
XFT_SPACING, XFT_FILE, XFT_INDEX, XFT_STYLE, |
| 808 |
#ifdef QT_XFT2 |
1015 |
#ifdef QT_XFT2 |
| 809 |
FC_CHARSET, |
1016 |
FC_CHARSET, |
| 810 |
#endif // QT_XFT2 |
1017 |
#endif // QT_XFT2 |
|
Lines 828-833
Link Here
|
| 828 |
XftPatternGetString (fonts->fonts[i], XFT_FILE, 0, &file_value); |
1035 |
XftPatternGetString (fonts->fonts[i], XFT_FILE, 0, &file_value); |
| 829 |
XftPatternGetInteger (fonts->fonts[i], XFT_INDEX, 0, &index_value); |
1036 |
XftPatternGetInteger (fonts->fonts[i], XFT_INDEX, 0, &index_value); |
| 830 |
|
1037 |
|
|
|
1038 |
getInfoFromSfntTables( file_value, index_value, |
| 1039 |
tmp_buffer, locale, utf16, |
| 1040 |
familyName, spacing_value ); |
| 1041 |
|
| 831 |
QtFontFamily *family = db->family( familyName, TRUE ); |
1042 |
QtFontFamily *family = db->family( familyName, TRUE ); |
| 832 |
family->rawName = rawName; |
1043 |
family->rawName = rawName; |
| 833 |
family->hasXft = TRUE; |
1044 |
family->hasXft = TRUE; |
|
Lines 867-872
Link Here
|
| 867 |
style->smoothScalable = TRUE; |
1078 |
style->smoothScalable = TRUE; |
| 868 |
family->fixedPitch = ( spacing_value >= XFT_MONO ); |
1079 |
family->fixedPitch = ( spacing_value >= XFT_MONO ); |
| 869 |
|
1080 |
|
|
|
1081 |
if ( XftPatternGetString (fonts->fonts[i], |
| 1082 |
XFT_STYLE, 0, &style_value) == XftResultMatch ) |
| 1083 |
style->rawName = QString::fromUtf8( style_value ); |
| 1084 |
|
| 870 |
QtFontSize *size = style->pixelSize( SMOOTH_SCALABLE, TRUE ); |
1085 |
QtFontSize *size = style->pixelSize( SMOOTH_SCALABLE, TRUE ); |
| 871 |
QtFontEncoding *enc = size->encodingID( -1, 0, 0, 0, 0, TRUE ); |
1086 |
QtFontEncoding *enc = size->encodingID( -1, 0, 0, 0, 0, TRUE ); |
| 872 |
enc->pitch = ( spacing_value >= XFT_CHARCELL ? 'c' : |
1087 |
enc->pitch = ( spacing_value >= XFT_CHARCELL ? 'c' : |
|
Lines 874-879
Link Here
|
| 874 |
} |
1089 |
} |
| 875 |
|
1090 |
|
| 876 |
XftFontSetDestroy (fonts); |
1091 |
XftFontSetDestroy (fonts); |
|
|
1092 |
|
| 1093 |
if ( qt_FamilyDictXft->count() == 0 ) { |
| 1094 |
delete qt_FamilyDictXft; |
| 1095 |
qt_FamilyDictXft = 0; |
| 1096 |
} |
| 877 |
} |
1097 |
} |
| 878 |
|
1098 |
|
| 879 |
#ifndef QT_XFT2 |
1099 |
#ifndef QT_XFT2 |
|
Lines 1192-1197
Link Here
|
| 1192 |
equiv->fakeOblique = TRUE; |
1412 |
equiv->fakeOblique = TRUE; |
| 1193 |
#endif // !QT_XFT2 |
1413 |
#endif // !QT_XFT2 |
| 1194 |
equiv->smoothScalable = TRUE; |
1414 |
equiv->smoothScalable = TRUE; |
|
|
1415 |
equiv->rawName = style->rawName; |
| 1195 |
|
1416 |
|
| 1196 |
QtFontSize *equiv_size = equiv->pixelSize( SMOOTH_SCALABLE, TRUE ); |
1417 |
QtFontSize *equiv_size = equiv->pixelSize( SMOOTH_SCALABLE, TRUE ); |
| 1197 |
QtFontEncoding *equiv_enc = equiv_size->encodingID( -1, 0, 0, 0, 0, TRUE ); |
1418 |
QtFontEncoding *equiv_enc = equiv_size->encodingID( -1, 0, 0, 0, 0, TRUE ); |
|
Lines 1309-1314
Link Here
|
| 1309 |
XftPatternAddString( pattern, XFT_FAMILY, |
1530 |
XftPatternAddString( pattern, XFT_FAMILY, |
| 1310 |
family->rawName.utf8().data() ); |
1531 |
family->rawName.utf8().data() ); |
| 1311 |
|
1532 |
|
|
|
1533 |
if ( !style->rawName.isEmpty() ) |
| 1534 |
XftPatternAddString( pattern, XFT_STYLE, |
| 1535 |
style->rawName.utf8().data() ); |
| 1536 |
|
| 1537 |
|
| 1312 |
const char *stylehint_value = 0; |
1538 |
const char *stylehint_value = 0; |
| 1313 |
switch ( request.styleHint ) { |
1539 |
switch ( request.styleHint ) { |
| 1314 |
case QFont::SansSerif: |
1540 |
case QFont::SansSerif: |
|
Lines 1396-1401
Link Here
|
| 1396 |
XftPattern *result = |
1622 |
XftPattern *result = |
| 1397 |
XftFontMatch( QPaintDevice::x11AppDisplay(), fp->screen, pattern, &res ); |
1623 |
XftFontMatch( QPaintDevice::x11AppDisplay(), fp->screen, pattern, &res ); |
| 1398 |
XftPatternDestroy(pattern); |
1624 |
XftPatternDestroy(pattern); |
|
|
1625 |
|
| 1626 |
for ( int s = QFont::Han; s <= QFont::Yi; s++ ) { |
| 1627 |
if ( !( family->scripts[s] & QtFontFamily::UnSupported_Xft ) ) { |
| 1628 |
XftPatternDel( result, XFT_SPACING ); |
| 1629 |
# ifdef QT_XFT2 |
| 1630 |
FcPatternDel( result, FC_GLOBAL_ADVANCE ); |
| 1631 |
FcPatternAddBool( result, FC_GLOBAL_ADVANCE, FcFalse ); |
| 1632 |
break; |
| 1633 |
# endif |
| 1634 |
} |
| 1635 |
} |
| 1399 |
|
1636 |
|
| 1400 |
// We pass a duplicate to XftFontOpenPattern because either xft font |
1637 |
// We pass a duplicate to XftFontOpenPattern because either xft font |
| 1401 |
// will own the pattern after the call or the pattern will be |
1638 |
// will own the pattern after the call or the pattern will be |