diff options
Diffstat (limited to 'kcontrol/fonts')
-rw-r--r-- | kcontrol/fonts/CMakeLists.txt | 65 | ||||
-rw-r--r-- | kcontrol/fonts/Makefile.am | 21 | ||||
-rw-r--r-- | kcontrol/fonts/configure.in.in | 57 | ||||
-rw-r--r-- | kcontrol/fonts/fonts.cpp | 802 | ||||
-rw-r--r-- | kcontrol/fonts/fonts.desktop | 239 | ||||
-rw-r--r-- | kcontrol/fonts/fonts.h | 124 | ||||
-rw-r--r-- | kcontrol/fonts/kxftconfig.cpp | 1544 | ||||
-rw-r--r-- | kcontrol/fonts/kxftconfig.h | 277 |
8 files changed, 3129 insertions, 0 deletions
diff --git a/kcontrol/fonts/CMakeLists.txt b/kcontrol/fonts/CMakeLists.txt new file mode 100644 index 000000000..46787bcd6 --- /dev/null +++ b/kcontrol/fonts/CMakeLists.txt @@ -0,0 +1,65 @@ +################################################# +# +# (C) 2010-2011 Serghei Amelian +# serghei (DOT) amelian (AT) gmail.com +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +##### check for fontconfig ###################### + +pkg_search_module( FONTCONFIG fontconfig ) +if( NOT FONTCONFIG_FOUND ) + message(FATAL_ERROR "\nfontconfig are required, but not found on your system" ) +endif( NOT FONTCONFIG_FOUND ) +set( HAVE_FONTCONFIG 1 CACHE INTERNAL "" FORCE ) + + +##### check for freetype2 ####################### + +pkg_search_module( FREETYPE freetype2 ) +if( NOT FREETYPE_FOUND ) + message(FATAL_ERROR "\nfreetype2 are required, but not found on your system" ) +endif( NOT FREETYPE_FOUND ) +set( HAVE_FREETYPE2 1 CACHE INTERNAL "" FORCE ) + + +##### compiler/linker settings ################## + +add_definitions( -D_LARGEFILE64_SOURCE ) + +include_directories( + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_BINARY_DIR} + ${TDE_INCLUDE_DIR} + ${TQT_INCLUDE_DIRS} + ${FREETYPE_INCLUDE_DIRS} +) + +link_directories( + ${TQT_LIBRARY_DIRS} +) + + +##### other data ################################ + +install( FILES fonts.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} ) + + +##### kcm_fonts (module) ######################## + +tde_add_kpart( kcm_fonts AUTOMOC + SOURCES fonts.cpp + LINK kxftconfig-static krdb-static tdeui-shared + DESTINATION ${PLUGIN_INSTALL_DIR} +) + + +##### kxftconfig (static) ####################### + +tde_add_library( kxftconfig STATIC_PIC + SOURCES kxftconfig.cpp +) diff --git a/kcontrol/fonts/Makefile.am b/kcontrol/fonts/Makefile.am new file mode 100644 index 000000000..de96e0721 --- /dev/null +++ b/kcontrol/fonts/Makefile.am @@ -0,0 +1,21 @@ +noinst_LTLIBRARIES = libkxftconfig.la + +libkxftconfig_la_SOURCES = kxftconfig.cpp +libkxftconfig_la_LIBADD = $(LIBFONTCONFIG_LIBS) +libkxftconfig_la_LDFLAGS = $(LIBFONTCONFIG_RPATH) + +AM_CPPFLAGS = $(all_includes) $(LIBFONTCONFIG_CFLAGS) $(FREETYPE2_CFLAGS) -D_LARGEFILE64_SOURCE + +kde_module_LTLIBRARIES = kcm_fonts.la + +kcm_fonts_la_SOURCES = fonts.cpp +kcm_fonts_la_LDFLAGS = $(KDE_RPATH) $(LIBFONTCONFIG_RPATH) $(FREETYPE2_LDFLAGS) -module -avoid-version $(all_libraries) -no-undefined +kcm_fonts_la_LIBADD = libkxftconfig.la $(top_builddir)/kcontrol/krdb/libkrdb.la $(LIB_TDEUI) $(LIBFONTCONFIG_LIBS) +METASOURCES = AUTO + +noinst_HEADERS = fonts.h kxftconfig.h + +messages: rc.cpp + $(XGETTEXT) *.cpp -o $(podir)/kcmfonts.pot + +xdg_apps_DATA = fonts.desktop diff --git a/kcontrol/fonts/configure.in.in b/kcontrol/fonts/configure.in.in new file mode 100644 index 000000000..0ecc46d91 --- /dev/null +++ b/kcontrol/fonts/configure.in.in @@ -0,0 +1,57 @@ +KDE_FIND_PATH(fontconfig-config, FONTCONFIG_CONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [ + KDE_FIND_PATH(pkg-config, PKGCONFIG, [${prefix}/bin ${exec_prefix}/bin /usr/bin /usr/local/bin /opt/local/bin], [ + AC_MSG_WARN([Could not find neither pkg-config nor fontconfig-config, check http://www.fontconfig.org/ ]) + ]) +]) + +if test -n "$PKGCONFIG"; then + vers=`$PKGCONFIG fontconfig --modversion 2>/dev/null | sed -e 's/libfontconfig //' | awk 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 1000000 + then + LIBFONTCONFIG_LIBS="`$PKGCONFIG fontconfig --libs`" + LIBFONTCONFIG_RPATH= + for args in $LIBFONTCONFIG_LIBS; do + case $args in + -L*) + LIBFONTCONFIG_RPATH="$LIBFONTCONFIG_RPATH $args" + ;; + esac + done + LIBFONTCONFIG_RPATH=`echo $LIBFONTCONFIG_RPATH | sed -e "s/-L/-R/g"` + LIBFONTCONFIG_CFLAGS="`$PKGCONFIG fontconfig --cflags`" + + AC_DEFINE_UNQUOTED(HAVE_FONTCONFIG, 1, [Defines if your system has the libfontconfig library]) + fi +fi + +if test -n "$FONTCONFIG_CONFIG"; then + vers=`$FONTCONFIG_CONFIG --version 2>/dev/null | sed -e 's/libfontconfig //' | awk 'BEGIN { FS = "."; } { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'` + if test -n "$vers" && test "$vers" -ge 1000000 + then + LIBFONTCONFIG_LIBS="`$FONTCONFIG_CONFIG --libs`" + LIBFONTCONFIG_RPATH= + for args in $LIBFONTCONFIG_LIBS; do + case $args in + -L*) + LIBFONTCONFIG_RPATH="$LIBFONTCONFIG_RPATH $args" + ;; + esac + done + LIBFONTCONFIG_RPATH=`echo $LIBFONTCONFIG_RPATH | sed -e "s/-L/-R/g"` + LIBFONTCONFIG_CFLAGS="`$FONTCONFIG_CONFIG --cflags`" + + AC_DEFINE_UNQUOTED(HAVE_FONTCONFIG, 1, [Defines if your system has the libfontconfig library]) + fi +fi + +AC_SUBST(LIBFONTCONFIG_LIBS) +AC_SUBST(LIBFONTCONFIG_CFLAGS) +AC_SUBST(LIBFONTCONFIG_RPATH) + +if pkg-config --exists freetype2 2>/dev/null; then + FREETYPE2_CFLAGS=`pkg-config --cflags freetype2` + FREETYPE2_LDFLAGS=`pkg-config --libs freetype2` + AC_DEFINE(HAVE_FREETYPE2, 1, [Define if you have FreeType2 library]) +fi +AC_SUBST(FREETYPE2_CFLAGS) +AC_SUBST(FREETYPE2_LDFLAGS) diff --git a/kcontrol/fonts/fonts.cpp b/kcontrol/fonts/fonts.cpp new file mode 100644 index 000000000..c5b4c3353 --- /dev/null +++ b/kcontrol/fonts/fonts.cpp @@ -0,0 +1,802 @@ +// KDE Display fonts setup tab +// +// Copyright (c) Mark Donohoe 1997 +// lars Knoll 1999 +// Rik Hemsley 2000 +// +// Ported to kcontrol2 by Geert Jansen. + +#include <config.h> + +#include <tqcheckbox.h> +#include <tqcombobox.h> +#include <tqdir.h> +#include <tqgroupbox.h> +#include <tqhbox.h> +#include <tqlabel.h> +#include <tqlayout.h> +#include <tqpushbutton.h> +#include <tqsettings.h> +#include <tqtooltip.h> +#include <tqwhatsthis.h> + +#include <dcopclient.h> + +#include <tdeaccelmanager.h> +#include <tdeapplication.h> +#include <kgenericfactory.h> +#include <kipc.h> +#include <tdemessagebox.h> +#include <knuminput.h> +#include <kprocio.h> +#include <ksimpleconfig.h> +#include <kstandarddirs.h> +#include <stdlib.h> + +#ifdef HAVE_FREETYPE2 +#include <ft2build.h> +#ifdef FT_LCD_FILTER_H +#include FT_FREETYPE_H +#include FT_LCD_FILTER_H +#endif +#endif + +#include "../krdb/krdb.h" +#include "fonts.h" +#include "fonts.moc" + +#include <kdebug.h> + +#include <X11/Xlib.h> + +// X11 headers +#undef Bool +#undef Unsorted +#undef None + +static const char *aa_rgb_xpm[]={ +"12 12 3 1", +"a c #0000ff", +"# c #00ff00", +". c #ff0000", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa"}; +static const char *aa_bgr_xpm[]={ +"12 12 3 1", +". c #0000ff", +"# c #00ff00", +"a c #ff0000", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa", +"....####aaaa"}; +static const char *aa_vrgb_xpm[]={ +"12 12 3 1", +"a c #0000ff", +"# c #00ff00", +". c #ff0000", +"............", +"............", +"............", +"............", +"############", +"############", +"############", +"############", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa"}; +static const char *aa_vbgr_xpm[]={ +"12 12 3 1", +". c #0000ff", +"# c #00ff00", +"a c #ff0000", +"............", +"............", +"............", +"............", +"############", +"############", +"############", +"############", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa", +"aaaaaaaaaaaa"}; + +static const char** aaPixmaps[]={ aa_rgb_xpm, aa_bgr_xpm, aa_vrgb_xpm, aa_vbgr_xpm }; + +/**** DLL Interface ****/ +typedef KGenericFactory<TDEFonts, TQWidget> FontFactory; +K_EXPORT_COMPONENT_FACTORY( kcm_fonts, FontFactory("kcmfonts") ) + +/**** FontUseItem ****/ + +FontUseItem::FontUseItem( + TQWidget * parent, + const TQString &name, + const TQString &grp, + const TQString &key, + const TQString &rc, + const TQFont &default_fnt, + bool f +) + : TDEFontRequester(parent, 0L, f), + _rcfile(rc), + _rcgroup(grp), + _rckey(key), + _default(default_fnt) +{ + TDEAcceleratorManager::setNoAccel( this ); + setTitle( name ); + readFont( false ); +} + +void FontUseItem::setDefault() +{ + setFont( _default, isFixedOnly() ); +} + +void FontUseItem::readFont( bool useDefaults ) +{ + TDEConfigBase *config; + + bool deleteme = false; + if (_rcfile.isEmpty()) + config = TDEGlobal::config(); + else + { + config = new TDEConfig(_rcfile, true); + deleteme = true; + } + + config->setReadDefaults( useDefaults ); + + config->setGroup(_rcgroup); + TQFont tmpFnt(_default); + setFont( config->readFontEntry(_rckey, &tmpFnt), isFixedOnly() ); + if (deleteme) delete config; +} + +void FontUseItem::writeFont() +{ + TDEConfigBase *config; + + if (_rcfile.isEmpty()) { + config = TDEGlobal::config(); + config->setGroup(_rcgroup); + config->writeEntry(_rckey, font(), true, true); + } else { + config = new KSimpleConfig(locateLocal("config", _rcfile)); + config->setGroup(_rcgroup); + config->writeEntry(_rckey, font()); + config->sync(); + delete config; + } +} + +void FontUseItem::applyFontDiff( const TQFont &fnt, int fontDiffFlags ) +{ + TQFont _font( font() ); + + if (fontDiffFlags & TDEFontChooser::FontDiffSize) { + _font.setPointSize( fnt.pointSize() ); + } + if (fontDiffFlags & TDEFontChooser::FontDiffFamily) { + if (!isFixedOnly()) _font.setFamily( fnt.family() ); + } + if (fontDiffFlags & TDEFontChooser::FontDiffStyle) { + _font.setBold( fnt.bold() ); + _font.setItalic( fnt.italic() ); + _font.setUnderline( fnt.underline() ); + } + + setFont( _font, isFixedOnly() ); +} + +/**** FontAASettings ****/ + +FontAASettings::FontAASettings(TQWidget *parent) + : KDialogBase(parent, "FontAASettings", true, i18n("Configure Anti-Alias Settings"), Ok|Cancel, Ok, true), + changesMade(false) +{ + TQWidget *mw=new TQWidget(this); + TQGridLayout *layout=new TQGridLayout(mw, 1, 1, 0, KDialog::spacingHint()); + + excludeRange=new TQCheckBox(i18n("E&xclude range:"), mw), + layout->addWidget(excludeRange, 0, 0); + excludeFrom=new KDoubleNumInput(0, 72, 8.0, 1, 1, mw), + excludeFrom->setSuffix(i18n(" pt")); + layout->addWidget(excludeFrom, 0, 1); + excludeToLabel=new TQLabel(i18n(" to "), mw); + layout->addWidget(excludeToLabel, 0, 2); + excludeTo=new KDoubleNumInput(0, 72, 15.0, 1, 1, mw); + excludeTo->setSuffix(i18n(" pt")); + layout->addWidget(excludeTo, 0, 3); + + useSubPixel=new TQCheckBox(i18n("&Use sub-pixel hinting:"), mw); + layout->addWidget(useSubPixel, 1, 0); + + TQWhatsThis::add(useSubPixel, i18n("If you have a TFT or LCD screen you" + " can further improve the quality of displayed fonts by selecting" + " this option.<br>Sub-pixel hinting is also known as ClearType(tm).<br>" + "<br><b>This will not work with CRT monitors.</b>")); + + subPixelType=new TQComboBox(false, mw); + layout->addMultiCellWidget(subPixelType, 1, 1, 1, 3); + + TQWhatsThis::add(subPixelType, i18n("In order for sub-pixel hinting to" + " work correctly you need to know how the sub-pixels of your display" + " are aligned.<br>" + " On TFT or LCD displays a single pixel is actually composed of" + " three sub-pixels, red, green and blue. Most displays" + " have a linear ordering of RGB sub-pixel, some have BGR.")); + + for(int t=KXftConfig::SubPixel::None+1; t<=KXftConfig::SubPixel::Vbgr; ++t) + subPixelType->insertItem(TQPixmap(aaPixmaps[t-1]), KXftConfig::description((KXftConfig::SubPixel::Type)t)); + +#ifdef HAVE_FONTCONFIG + TQLabel *hintingLabel=new TQLabel(i18n("Hinting style: "), mw); + layout->addWidget(hintingLabel, 2, 0); + hintingStyle=new TQComboBox(false, mw); + layout->addMultiCellWidget(hintingStyle, 2, 2, 1, 3); + for(int s=KXftConfig::Hint::NotSet+1; s<=KXftConfig::Hint::Full; ++s) + hintingStyle->insertItem(KXftConfig::description((KXftConfig::Hint::Style)s)); + + TQString hintingText(i18n("Hinting is a process used to enhance the quality of fonts at small sizes.")); + TQWhatsThis::add(hintingStyle, hintingText); + TQWhatsThis::add(hintingLabel, hintingText); +#endif + load(); + enableWidgets(); + setMainWidget(mw); + + connect(excludeRange, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed())); + connect(useSubPixel, TQT_SIGNAL(toggled(bool)), TQT_SLOT(changed())); + connect(excludeFrom, TQT_SIGNAL(valueChanged(double)), TQT_SLOT(changed())); + connect(excludeTo, TQT_SIGNAL(valueChanged(double)), TQT_SLOT(changed())); + connect(subPixelType, TQT_SIGNAL(activated(const TQString &)), TQT_SLOT(changed())); +#ifdef HAVE_FONTCONFIG + connect(hintingStyle, TQT_SIGNAL(activated(const TQString &)), TQT_SLOT(changed())); +#endif +} + +bool FontAASettings::load() +{ + return load( false ); +} + + +bool FontAASettings::load( bool useDefaults ) +{ + double from, to; + KXftConfig xft(KXftConfig::constStyleSettings); + + + if(xft.getExcludeRange(from, to)) + excludeRange->setChecked(true); + else + { + excludeRange->setChecked(false); + from=8.0; + to=15.0; + } + + excludeFrom->setValue(from); + excludeTo->setValue(to); + + KXftConfig::SubPixel::Type spType; + + if(!xft.getSubPixelType(spType) || KXftConfig::SubPixel::None==spType) + useSubPixel->setChecked(false); + else + { + int idx=getIndex(spType); + + if(idx>-1) + { + useSubPixel->setChecked(true); + subPixelType->setCurrentItem(idx); + } + else + useSubPixel->setChecked(false); + } + +#ifdef HAVE_FONTCONFIG + KXftConfig::Hint::Style hStyle; + + if(!xft.getHintStyle(hStyle) || KXftConfig::Hint::NotSet==hStyle) + { + TDEConfig kglobals("kdeglobals", false, false); + + kglobals.setReadDefaults( useDefaults ); + + kglobals.setGroup("General"); + hStyle=KXftConfig::Hint::Full; + xft.setHintStyle(hStyle); + xft.apply(); // Save this setting + kglobals.writeEntry("XftHintStyle", KXftConfig::toStr(hStyle)); + kglobals.sync(); + runRdb(KRdbExportXftSettings); + } + + hintingStyle->setCurrentItem(getIndex(hStyle)); +#endif + + enableWidgets(); + + return xft.getAntiAliasing(); +} + +bool FontAASettings::save( bool useAA ) +{ + KXftConfig xft(KXftConfig::constStyleSettings); + TDEConfig kglobals("kdeglobals", false, false); + + kglobals.setGroup("General"); + + xft.setAntiAliasing( useAA ); + + if(excludeRange->isChecked()) + xft.setExcludeRange(excludeFrom->value(), excludeTo->value()); + else + xft.setExcludeRange(0, 0); + + KXftConfig::SubPixel::Type spType(useSubPixel->isChecked() + ? getSubPixelType() + : KXftConfig::SubPixel::None); + + xft.setSubPixelType(spType); + kglobals.writeEntry("XftSubPixel", KXftConfig::toStr(spType)); + kglobals.writeEntry("XftAntialias", useAA); + + bool mod=false; +#ifdef HAVE_FONTCONFIG + KXftConfig::Hint::Style hStyle(getHintStyle()); + + xft.setHintStyle(hStyle); + + TQString hs(KXftConfig::toStr(hStyle)); + + if(!hs.isEmpty() && hs!=kglobals.readEntry("XftHintStyle")) + { + kglobals.writeEntry("XftHintStyle", hs); + mod=true; + } +#endif + kglobals.sync(); + + if(!mod) + mod=xft.changed(); + + xft.apply(); + + return mod; +} + +void FontAASettings::defaults() +{ + load( true ); +} + +int FontAASettings::getIndex(KXftConfig::SubPixel::Type spType) +{ + int pos=-1; + int index; + + for(index=0; index<subPixelType->count(); ++index) + if(subPixelType->text(index)==KXftConfig::description(spType)) + { + pos=index; + break; + } + + return pos; +} + +KXftConfig::SubPixel::Type FontAASettings::getSubPixelType() +{ + int t; + + for(t=KXftConfig::SubPixel::None; t<=KXftConfig::SubPixel::Vbgr; ++t) + if(subPixelType->currentText()==KXftConfig::description((KXftConfig::SubPixel::Type)t)) + return (KXftConfig::SubPixel::Type)t; + + return KXftConfig::SubPixel::None; +} + +#ifdef HAVE_FONTCONFIG +int FontAASettings::getIndex(KXftConfig::Hint::Style hStyle) +{ + int pos=-1; + int index; + + for(index=0; index<hintingStyle->count(); ++index) + if(hintingStyle->text(index)==KXftConfig::description(hStyle)) + { + pos=index; + break; + } + + return pos; +} + + +KXftConfig::Hint::Style FontAASettings::getHintStyle() +{ + int s; + + for(s=KXftConfig::Hint::NotSet; s<=KXftConfig::Hint::Full; ++s) + if(hintingStyle->currentText()==KXftConfig::description((KXftConfig::Hint::Style)s)) + return (KXftConfig::Hint::Style)s; + + return KXftConfig::Hint::Full; +} +#endif + +void FontAASettings::enableWidgets() +{ + excludeFrom->setEnabled(excludeRange->isChecked()); + excludeTo->setEnabled(excludeRange->isChecked()); + excludeToLabel->setEnabled(excludeRange->isChecked()); + subPixelType->setEnabled(useSubPixel->isChecked()); +#ifdef FT_LCD_FILTER_H + static int ft_has_subpixel = -1; + if( ft_has_subpixel == -1 ) { + FT_Library ftLibrary; + if(FT_Init_FreeType(&ftLibrary) == 0) { + ft_has_subpixel = ( FT_Library_SetLcdFilter(ftLibrary, FT_LCD_FILTER_DEFAULT ) + == FT_Err_Unimplemented_Feature ) ? 0 : 1; + FT_Done_FreeType(ftLibrary); + } + } + useSubPixel->setEnabled(ft_has_subpixel); + subPixelType->setEnabled(ft_has_subpixel); +#endif +} + +void FontAASettings::changed() +{ + changesMade=true; + enableWidgets(); +} + +int FontAASettings::exec() +{ + int i=KDialogBase::exec(); + + if(!i) + load(); // Reset settings... + + return i && changesMade; +} + +/**** TDEFonts ****/ + +static TQCString desktopConfigName() +{ + int desktop=0; + if (tqt_xdisplay()) + desktop = DefaultScreen(tqt_xdisplay()); + TQCString name; + if (desktop == 0) + name = "kdesktoprc"; + else + name.sprintf("kdesktop-screen-%drc", desktop); + + return name; +} + +TDEFonts::TDEFonts(TQWidget *parent, const char *name, const TQStringList &) + : TDECModule(FontFactory::instance(), parent, name) +{ + TQStringList nameGroupKeyRc; + + nameGroupKeyRc + << i18n("General") << "General" << "font" << "" + << i18n("Fixed width") << "General" << "fixed" << "" + << i18n("Toolbar") << "General" << "toolBarFont" << "" + << i18n("Menu") << "General" << "menuFont" << "" + << i18n("Window title") << "WM" << "activeFont" << "" + << i18n("Taskbar") << "General" << "taskbarFont" << "" + << i18n("Desktop") << "FMSettings" << "StandardFont" << desktopConfigName(); + + TQValueList<TQFont> defaultFontList; + + // Keep in sync with tdelibs/tdecore/tdeglobalsettings.cpp + + TQFont f0("Sans Serif", 10); + TQFont f1("Monospace", 10); + TQFont f2("Sans Serif", 10); + TQFont f3("Sans Serif", 10, TQFont::Bold); + TQFont f4("Sans Serif", 10); + + f0.setPointSize(10); + f1.setPointSize(10); + f2.setPointSize(10); + f3.setPointSize(10); + f4.setPointSize(10); + + defaultFontList << f0 << f1 << f2 << f0 << f3 << f4 << f0; + + TQValueList<bool> fixedList; + + fixedList + << false + << true + << false + << false + << false + << false + << false; + + TQStringList quickHelpList; + + quickHelpList + << i18n("Used for normal text (e.g. button labels, list items).") + << i18n("A non-proportional font (i.e. typewriter font).") + << i18n("Used to display text beside toolbar icons.") + << i18n("Used by menu bars and popup menus.") + << i18n("Used by the window titlebar.") + << i18n("Used by the taskbar.") + << i18n("Used for desktop icons."); + + TQVBoxLayout * layout = + new TQVBoxLayout(this, 0, KDialog::spacingHint()); + + TQGridLayout * fontUseLayout = + new TQGridLayout(layout, nameGroupKeyRc.count() / 4, 3); + + fontUseLayout->setColStretch(0, 0); + fontUseLayout->setColStretch(1, 1); + fontUseLayout->setColStretch(2, 0); + + TQValueList<TQFont>::ConstIterator defaultFontIt(defaultFontList.begin()); + TQValueList<bool>::ConstIterator fixedListIt(fixedList.begin()); + TQStringList::ConstIterator quickHelpIt(quickHelpList.begin()); + TQStringList::ConstIterator it(nameGroupKeyRc.begin()); + + unsigned int count = 0; + + while (it != nameGroupKeyRc.end()) { + + TQString name = *it; it++; + TQString group = *it; it++; + TQString key = *it; it++; + TQString file = *it; it++; + + FontUseItem * i = + new FontUseItem( + this, + name, + group, + key, + file, + *defaultFontIt++, + *fixedListIt++ + ); + + fontUseList.append(i); + connect(i, TQT_SIGNAL(fontSelected(const TQFont &)), TQT_SLOT(fontSelected())); + + TQLabel * fontUse = new TQLabel(name+":", this); + TQWhatsThis::add(fontUse, *quickHelpIt++); + + fontUseLayout->addWidget(fontUse, count, 0); + fontUseLayout->addWidget(i, count, 1); + + ++count; + } + + TQHBoxLayout *hblay = new TQHBoxLayout(layout, KDialog::spacingHint()); + hblay->addStretch(); + TQPushButton * fontAdjustButton = new TQPushButton(i18n("Ad&just All Fonts..."), this); + TQWhatsThis::add(fontAdjustButton, i18n("Click to change all fonts")); + hblay->addWidget( fontAdjustButton ); + connect(fontAdjustButton, TQT_SIGNAL(clicked()), TQT_SLOT(slotApplyFontDiff())); + + layout->addSpacing(KDialog::spacingHint()); + + TQGridLayout* lay = new TQGridLayout(layout, 2, 4, KDialog::spacingHint()); + lay->setColStretch( 3, 10 ); + TQLabel* label = new TQLabel( i18n( "Use a&nti-aliasing:" ), this ); + lay->addWidget( label, 0, 0 ); + cbAA = new TQComboBox( this ); + cbAA->insertItem( i18n( "Enabled" )); // change AASetting type if order changes + cbAA->insertItem( i18n( "System settings" )); + cbAA->insertItem( i18n( "Disabled" )); + TQWhatsThis::add(cbAA, i18n("If this option is selected, TDE will smooth the edges of curves in " + "fonts.")); + aaSettingsButton = new TQPushButton( i18n( "Configure..." ), this); + connect(aaSettingsButton, TQT_SIGNAL(clicked()), TQT_SLOT(slotCfgAa())); + label->setBuddy( cbAA ); + lay->addWidget( cbAA, 0, 1 ); + lay->addWidget( aaSettingsButton, 0, 2 ); + connect(cbAA, TQT_SIGNAL(activated(int)), TQT_SLOT(slotUseAntiAliasing())); + + label = new TQLabel( i18n( "Force fonts DPI:" ), this ); + lay->addWidget( label, 1, 0 ); + comboForceDpi = new TQComboBox( this ); + label->setBuddy( comboForceDpi ); + comboForceDpi->insertItem( i18n( "Disabled" )); // change DPISetti ng type if order changes + comboForceDpi->insertItem( i18n( "96 DPI" )); + comboForceDpi->insertItem( i18n( "120 DPI" )); + TQString whatsthis = i18n( + "<p>This option forces a specific DPI value for fonts. It may be useful" + " when the real DPI of the hardware is not detected properly and it" + " is also often misused when poor quality fonts are used that do not" + " look well with DPI values other than 96 or 120 DPI.</p>" + "<p>The use of this option is generally discouraged. For selecting proper DPI" + " value a better option is explicitly configuring it for the whole X server if" + " possible (e.g. DisplaySize in xorg.conf or adding <i>-dpi value</i> to" + " ServerLocalArgs= in $TDEDIR/share/config/tdm/tdmrc). When fonts do not render" + " properly with real DPI value better fonts should be used or configuration" + " of font hinting should be checked.</p>" ); + TQWhatsThis::add(comboForceDpi, whatsthis); + connect( comboForceDpi, TQT_SIGNAL( activated( int )), TQT_SLOT( changed())); + lay->addWidget( comboForceDpi, 1, 1 ); + + layout->addStretch(1); + + aaSettings=new FontAASettings(this); + + load(); +} + +TDEFonts::~TDEFonts() +{ + fontUseList.setAutoDelete(true); + fontUseList.clear(); +} + +void TDEFonts::fontSelected() +{ + emit changed(true); +} + +void TDEFonts::defaults() +{ + load( true ); + aaSettings->defaults(); +} + +void TDEFonts::load() +{ + load( false ); +} + + +void TDEFonts::load( bool useDefaults ) +{ + for ( uint i = 0; i < fontUseList.count(); i++ ) + fontUseList.at( i )->readFont( useDefaults ); + + useAA_original = useAA = aaSettings->load( useDefaults ) ? AAEnabled : AADisabled; + cbAA->setCurrentItem( useAA ); + + TDEConfig cfgfonts("kcmfonts", true); + cfgfonts.setGroup("General"); + int dpicfg = cfgfonts.readNumEntry( "forceFontDPI", 0 ); + DPISetting dpi = dpicfg == 120 ? DPI120 : dpicfg == 96 ? DPI96 : DPINone; + comboForceDpi->setCurrentItem( dpi ); + dpi_original = dpi; + if( cfgfonts.readBoolEntry( "dontChangeAASettings", true )) { + useAA_original = useAA = AASystem; + cbAA->setCurrentItem( useAA ); + } + aaSettingsButton->setEnabled( cbAA->currentItem() == AAEnabled ); + + emit changed( useDefaults ); +} + +void TDEFonts::save() +{ + + for ( FontUseItem* i = fontUseList.first(); i; i = fontUseList.next() ) + i->writeFont(); + TDEGlobal::config()->sync(); + + TDEConfig cfgfonts("kcmfonts"); + cfgfonts.setGroup("General"); + DPISetting dpi = static_cast< DPISetting >( comboForceDpi->currentItem()); + const int dpi2value[] = { 0, 96, 120 }; + cfgfonts.writeEntry( "forceFontDPI", dpi2value[ dpi ] ); + cfgfonts.writeEntry( "dontChangeAASettings", cbAA->currentItem() == AASystem ); + cfgfonts.sync(); + // if the setting is reset in the module, remove the dpi value, + // otherwise don't explicitly remove it and leave any possible system-wide value + if( dpi == DPINone && dpi_original != DPINone ) { + KProcIO proc; + proc << "xrdb" << "-quiet" << "-remove" << "-nocpp"; + proc.writeStdin( TQCString( "Xft.dpi" ), true ); + proc.closeWhenDone(); + proc.start( TDEProcess::Block ); + } + + // KDE-1.x support + KSimpleConfig* config = new KSimpleConfig( TQDir::homeDirPath() + "/.tderc" ); + config->setGroup( "General" ); + for ( FontUseItem* i = fontUseList.first(); i; i = fontUseList.next() ) { + if("font"==i->rcKey()) + TQSettings().writeEntry("/qt/font", i->font().toString()); + kdDebug(1208) << "write entry " << i->rcKey() << endl; + config->writeEntry( i->rcKey(), i->font() ); + } + config->sync(); + delete config; + + KIPC::sendMessageAll(KIPC::FontChanged); + + kapp->processEvents(); // Process font change ourselves + + bool aaSave = false; + // Don't overwrite global settings unless explicitly asked for - e.g. the system + // fontconfig setup may be much more complex than this module can provide. + // TODO: With NoChange the changes already made by this module should be reverted somehow. + if( cbAA->currentItem() != AASystem ) + aaSave = aaSettings->save( useAA == AAEnabled ); + + if( aaSave || (useAA != useAA_original) || dpi != dpi_original) { + KMessageBox::information(this, + i18n( + "<p>Some changes such as anti-aliasing will only affect newly started applications.</p>" + ), i18n("Font Settings Changed"), "FontSettingsChanged", false); + useAA_original = useAA; + dpi_original = dpi; + } + + runRdb(KRdbExportXftSettings); + + emit changed(false); +} + + +void TDEFonts::slotApplyFontDiff() +{ + TQFont font = TQFont(fontUseList.first()->font()); + int fontDiffFlags = 0; + int ret = TDEFontDialog::getFontDiff(font,fontDiffFlags); + + if (ret == KDialog::Accepted && fontDiffFlags) + { + for ( int i = 0; i < (int) fontUseList.count(); i++ ) + fontUseList.at( i )->applyFontDiff( font,fontDiffFlags ); + emit changed(true); + } +} + +void TDEFonts::slotUseAntiAliasing() +{ + useAA = static_cast< AASetting >( cbAA->currentItem()); + aaSettingsButton->setEnabled( cbAA->currentItem() == AAEnabled ); + emit changed(true); +} + +void TDEFonts::slotCfgAa() +{ + if(aaSettings->exec()) + { + emit changed(true); + } +} + +// vim:ts=2:sw=2:tw=78 diff --git a/kcontrol/fonts/fonts.desktop b/kcontrol/fonts/fonts.desktop new file mode 100644 index 000000000..d798e2652 --- /dev/null +++ b/kcontrol/fonts/fonts.desktop @@ -0,0 +1,239 @@ +[Desktop Entry] +Exec=tdecmshell fonts +Icon=font-x-generic +Type=Application +X-DocPath=kcontrol/fonts/index.html + + +X-TDE-Library=fonts +X-TDE-FactoryName=fonts +X-TDE-ParentApp=kcontrol + +Name=Fonts +Name[af]=Skriftipes +Name[ar]=المحارف +Name[az]=Yazı növləri +Name[be]=Шрыфты +Name[bg]=Шрифтове +Name[bn]=ফন্ট +Name[br]=Fontoù +Name[bs]=Fontovi +Name[ca]=Lletres +Name[cs]=Písma +Name[csb]=Fòntë +Name[cy]=Ffontiau +Name[da]=Skrifttyper +Name[de]=Schriftarten +Name[el]=Γραμματοσειρές +Name[eo]=Tiparoj +Name[es]=Tipos de letra +Name[et]=Fondid +Name[eu]=Letra-tipoak +Name[fa]=قلمها +Name[fi]=Kirjasimet +Name[fr]=Polices +Name[fy]=Lettertypen +Name[ga]=Clónna +Name[gl]=Fontes +Name[he]=גופנים +Name[hi]=फ़ॉन्ट्स +Name[hr]=Fontovi +Name[hu]=Betűtípusok +Name[is]=Letur +Name[it]=Tipi di carattere +Name[ja]=フォント +Name[ka]=ფონტები +Name[kk]=Қаріптер +Name[km]=ពុម្ពអក្សរ +Name[ko]=글꼴 +Name[lo]=ຮູບແບບຕົວອັກສອນ +Name[lt]=Šriftai +Name[lv]=Fonti +Name[mk]=Фонтови +Name[mn]=Бичгүүд +Name[ms]=Fon +Name[nb]=Skrifttype +Name[nds]=Schriftoorden +Name[ne]=फन्ट +Name[nl]=Lettertypen +Name[nn]=Skrifttypar +Name[nso]=Difonto +Name[pa]=ਫੋਂਟ +Name[pl]=Czcionki +Name[pt]=Tipos de Letra +Name[pt_BR]=Fontes +Name[ro]=Fonturi +Name[ru]=Шрифты +Name[rw]=Imyandikire +Name[se]=Fonttat +Name[sk]=Písma +Name[sl]=Pisave +Name[sr]=Фонтови +Name[sr@Latn]=Fontovi +Name[ss]=Timo tetinhlamvu temagama +Name[sv]=Teckensnitt +Name[ta]=எழுத்துருக்கள் +Name[tg]=Ҳарфҳо +Name[th]=แบบอักษร +Name[tr]=Yazıtipleri +Name[tt]=Yazu +Name[uk]=Шрифти +Name[uz]=Shriftlar +Name[uz@cyrillic]=Шрифтлар +Name[ven]=Fontu +Name[vi]=Phông chữ +Name[wa]=Fontes +Name[xh]=Uhlobo lwamagama +Name[zh_CN]=字体 +Name[zh_TW]=字型 +Name[zu]=Izinhlobo zamagama + +Comment=Font settings +Comment[af]=Skrif tipe instellings +Comment[ar]=تعيينات المحرف +Comment[az]=Yazı növü qurğuları +Comment[be]=Настаўленні шрыфтоў +Comment[bg]=Настройване шрифтовете на системата +Comment[bn]=ফন্ট সেটিংস +Comment[br]=Kefluniañ ar fontoù +Comment[bs]=Postavke fontova +Comment[ca]=Arranjament de les lletres +Comment[cs]=Nastavení písem +Comment[csb]=Nastôw fòntów +Comment[cy]=Gosodiadau Ffontiau +Comment[da]=Skrifttypeindstillinger +Comment[de]=Schriftarten-Einstellungen +Comment[el]=Ρυθμίσεις γραμματοσειρών +Comment[eo]=Tiparagordo +Comment[es]=Opciones de los tipos de letra +Comment[et]=Fontide seadistused +Comment[eu]=Letra-tipoen konfigurazioa +Comment[fa]=تنظیمات قلم +Comment[fi]=Kirjasinten asetukset +Comment[fr]=Configuration des police de caractères +Comment[fy]=Lettertypen ynstellings +Comment[ga]=Socruithe na gclónna +Comment[gl]=Configuración das fontes +Comment[he]=שינוי הגדרות הגופנים +Comment[hi]=फ़ॉन्ट्स विन्यास +Comment[hr]=Postavke fontova +Comment[hu]=Betűtípus-beállítások +Comment[id]=Seting font +Comment[is]=Stillingar leturs +Comment[it]=Impostazioni tipi di carattere +Comment[ja]=フォントの設定 +Comment[ka]=ფონტების კონფიგურაცია +Comment[kk]=Қаріптерді орнату +Comment[km]=ការកំណត់ពុម្ពអក្សរ +Comment[ko]=글꼴 설정 +Comment[lo]=ຕັ້ງຄ່າຮູບແບບຕົວອັກສອນ +Comment[lt]=Šriftų nustatymai +Comment[lv]=Fontu parametri +Comment[mk]=Поставувања на фонтовите +Comment[mn]=Бичиг тохируулах +Comment[ms]=Seting Fon +Comment[mt]=Konfigurazzjoni tal-fonts +Comment[nb]=Skriftinnstillinger +Comment[nds]=Schriftoorden instellen +Comment[ne]=फन्ट सेटिङ +Comment[nl]=Lettertypeninstellingen +Comment[nn]=Skriftinnstillingar +Comment[nso]=Dipeakanyo tsa difonto +Comment[oc]=Arranjament de les fonts +Comment[pa]=ਫੋਂਟ ਸੈਟਿੰਗ +Comment[pl]=Ustawienia czcionek +Comment[pt]=Configuração dos tipos de letra +Comment[pt_BR]=Configuraçõess de Fontes +Comment[ro]=Configurează fonturile de sistem +Comment[ru]=Настройка шрифтов +Comment[rw]=Amagenamiterere y'imyandikire +Comment[se]=Fontaheivehusat +Comment[sk]=Nastavenie písiem +Comment[sl]=Nastavitve pisav +Comment[sr]=Поставке фонта +Comment[sr@Latn]=Postavke fonta +Comment[sv]=Anpassa teckensnitt +Comment[ta]=எழுத்துரு அமைப்புகள் +Comment[tg]=Танзимоти ҳарфҳо +Comment[th]=ตั้งค่าแบบอักษร +Comment[tr]=Yazıtipi ayarları +Comment[tt]=Yazu şäkellären caylaw +Comment[uk]=Налаштування шрифтів +Comment[uz]=Shriftlarni moslash +Comment[uz@cyrillic]=Шрифтларни мослаш +Comment[ven]=Mavhekanyele a fontu +Comment[vi]=Thiết lập phông chữ +Comment[wa]=Apontiaedje des fontes +Comment[xh]=Izicwangciso zohlobo lwamagama +Comment[zh_CN]=字体设置 +Comment[zh_TW]=字型設定 +Comment[zu]=Izilungiselelo Zohlobo lwamagama + +Keywords=fonts;font size;styles;charsets;character sets;panel;kicker;control panel;desktops;FileManager;Toolbars;Menu;Window Title;Title; +Keywords[ar]=fonts;font size;styles;charsets;character sets;panel;kicker;control panel;desktops;FileManager;Toolbars;Menu;Window Title;Title;خطوط;حجم الخط;لوحة التحكم;محارف;المحارف;أسطح المكتب;مدير الملفات;أشرطة الأدوات;قائمة;عنوان النافذة;عنوان; +Keywords[az]=yazı növləri;yazı böyüklüyü;tərz;hərf köməsi;panel;kicker;idarə masası;masa üstü;masa üstləri;Vasitə Çubuğu;Menyu;Pəncərə Başlığı;Başlıq; +Keywords[be]=шрыфты;памер шрыфту;стылі;знаказборы;знакавыя зборы;панэль;панэль кіравання;працоўныя сталы;працоўны стол;кіраўнік файлаў;панэлі начынняў;панэль начыння;меню;загаловак акна;загаловак;назва;fonts;font size;styles;charsets;character sets;panel;kicker;control panel;desktops;FileManager;Toolbars;Menu;Window Title;Title; +Keywords[bg]=шрифт; шрифтове; размер; символи; знаци; системен панел; fonts; font size; styles; charsets; character sets; panel; kicker; control panel; desktops; FileManager; Toolbars; Menu; Window Title; Title; +Keywords[ca]=lletres;mida de lletra;estils;jocs de caràcters;plafó;kicker;plafó de control;escriptoris;Gestor de fitxers;Barres d'eines;Menú;Títol de finestra;Títol; +Keywords[cs]=Písma;Velikost písem;Styly;Znaková sada;Panel;Kicker;Ovládací centrum;Plocha;Správce souborů;Nástrojová lišta;Nabídka;Titulek okna;Titulek; +Keywords[csb]=fòntë;miara fòntu;sztél;zestôw znaków;panel;kicker;panel sterowaniô;pùltë;biurka;menedżera lopków;lëstwë nôrzãdzów;menu;titel òkna;titel; +Keywords[cy]=ffontiau;maint ffontiau;arddulliau;setiau nodau;panel;ciciwr;rheolydd panel;penbyrddau;Rheolwr Ffeiliau;Barrau Offer;Dewislen;Teitl Ffenestr;Teitl; +Keywords[da]=skrifttyper;skriftstørrelse;stil;tegnsæt;panel;kicker;kontrolpanel;desktoppe;Filhåndtering;Værktøjslinje;Menu;Vinduestitel;Titel; +Keywords[de]=Schriftarten;Schriftgrößen;Zeichensätze;Kontrollleiste;Panel;Kicker;Stile;Dateimanager;Arbeitsflächen;Werkzeugleisten;Menüs;Fenstertitel;Titel; +Keywords[el]=γραμματοσειρές;μέγεθος γραμματοσειράς;στυλ;σύνολα χαρακτήρων;σύνολα χαρακτήρων;πίνακας;kicker;πίνακας ελέγχου;επιφάνειες εργασίας;Διαχειριστής αρχείων;Γραμμές εργαλείων;Μενού;Τίτλος παραθύρου;Τίτλος; +Keywords[eo]=tiparo;grandeco;stilo;signaro;panelo;lanĉilo;stirpanelo;tabuloj;dosieradministrilo;ilobretoj;menuo;fenestrotitolo;titolo; +Keywords[es]=tipos de letra;tamaño del tipo de letra;estilos;mapas de caracteres;panel;kicker;panel de control;escritorios;Gestor de archivos;Barras de herramientas;Menú;Título de la ventana;Título; +Keywords[et]=fondid;font;fondi suurus;stiil;kooditabel;paneel;kicker;juhtimiskeskus;töölauad;failihaldur;tööriistaribad;menüü;akna pealdis;pealdis; +Keywords[eu]=letra-tipoak;letra-tipoa;neurria;estiloak;karaktere-multzoak;karactere ezarpenak ;panela;kicker;kontrol panela;mahaigainak;Fitxategi kudeatzailea;Tresna-barrak; Menua;Leihoaren titulua;Titulua ; +Keywords[fa]=قلمها، اندازۀ قلم، سبکها، نویسهگان، نویسهگان، تابلو، kicker، تابلوی کنترل، رومیزیها، مدیر پرونده، میله ابزارها، گزینگان، عنوان پنجره، عنوان; +Keywords[fi]=kirjasimet;kirjasin;kirjasimen koko;tyyli;merkistö;paneeli;kicker;ohjauspaneeli;työpöydät;Tiedostonhallinta;Työkalurivit;Valikko;Ikkunan otsikko;Otsikko; +Keywords[fr]=polices;police;taille de police;jeu de caractères;tableau de bord;kicker;bureau;bureaux;gestionnaire de fichiers;gestion de fichiers;barre d'outils;menu;titre de fenêtre;titre;fenêtre;barre de menus;barres de menus;barres d'outils; +Keywords[fy]=fonts;font;letters;lettertypen;lettertypes;tekenset;karakterferzamling;paniel;kicker;Konfiguraasjesintrum;styl;triembehearder;wurkbalke;menu;Finster;titel;finstertitel;desktops;buroblêden; +Keywords[ga]=clónna;clófhoirne;clómhéid;stíleanna;tacair charachtair;painéal;kicker;painéal rialaithe;deasca;Bainisteoir Comhad;Barraí Uirlisí;Roghchlár;Teideal Fuinneoige;Teideal; +Keywords[gl]=fontes;tamaño da fonte;estilos;codificación;conxunto de carácteres;painel;kicker;painel de control;escritórios;Xestor de Ficheiros;Barras de ferramentas;Menu;Título da Fiestra;Título; +Keywords[he]=לוח הבקרה;שולחנות עבודה;מנהל קבצים;סרגלי כלים;תפריט;כותרת; חלון;כותרת;גופנים;גודל גופן;סגנונות;מערכי תווים;לוח; fonts;font size;styles;charsets;character sets;panel;kicker;control panel;desktops;FileManager;Toolbars;Menu;Window Title;Title; +Keywords[hi]=फ़ॉन्ट्स; फ़ॉन्ट्स आकार;शैली;कैरसेट;कैरेक्टर सेट्स;फलक;किकर; नियंत्रण फलक;डेस्कटॉप;फ़ाइल प्रबंधक;औज़ार पट्टी;मेन्यू;विंडो शीर्षक;शीर्षक; +Keywords[hr]=fonts;font size;styles;charsets;character sets;panel;kicker;control panel;desktops;FileManager;Toolbars;Menu;Window Title;Title;fontovi;veličina fonta;stilovi;znakovi;ploča;radna površina;alatne trake;izbornik;naslov prozora;naslov;upravljanje datotekama; +Keywords[hu]=betűtípusok;betűméret;stílusok;karakterkészletek;panel;Kicker;vezérlőközpont;asztalok;fájlkezelő;eszköztár;menü;ablakcím;címsor; +Keywords[id]=fonts;font;ukuran font;gaya;charset;panel;kicker;panel kontroldesktops;FileManager;Toolbars;Menu;Window Title;Title; +Keywords[is]=letur;leturstærð;leturgerð;stafatafla;spjald;stillingar;spjald;kicker;gluggar;titill;titilrönd; +Keywords[it]=tipi di carattere;caratteri;dimensione carattere;stile;insieme di caratteri;pannello;kicker;pannello di controllo;desktop;file manager;barre degli strumenti;menu;finestre;titolo finestra;titolo; +Keywords[ja]=フォント;フォントサイズ;スタイル;文字セットパネル;kicker;コントロールパネル;デスクトップ;ファイルマネージャ;ツールバー;メニュー;ウィンドウタイトル;タイトル; +Keywords[ka]=ფონტები;ფონტების ზომა;სტილები;სიმბოლოების რუქა;სიმბოლოების რუქა;პანელი;kicker;კონტროლის პანელი;სამუშაო მაგიდები;ფაილის მენეჯერი;ინსტრუმენტთა პანელი;მენიუ;ფანჯრის სათაური;სათაური; +Keywords[km]=ពុម្ពអក្សរ;ទំហំពុម្ពអក្សរ;រចនាប័ទ្ម;តួអក្សរ;សំណុំតួអក្សរ;បន្ទះ;kicker;ស្លាបព្រិលបញ្ជា;ផ្ទៃតុ;កម្មវិធីគ្រប់គ្រងឯកសារ;របារឧបករណ៍;ម៉ឺនុយ;ចំណងជើងបង្អួច;ចំណងជើង; +Keywords[lt]=fonts;šriftai;font size;šrifto dydis;styles;stiliai;charsets;kodavimas;koduotė;simbolių rinkinys;panel;pultas;kicker;control panel;Valdymo Centras;desktops;darbastaliai;FileManager;failų tvarkyklė;Toolbars;įrankinės;įrankių juostos;Menu;meniu;Window Title;Title;antraštė; +Keywords[lv]=fonti;fonta izmērs;stili;čārseti;simbolu komplekti;panelis;kikers;vadības panelis;darbvirsmas;FailuMenedžeris;Rīkjoslas;Izvēlne;Loga Titli;Titli; +Keywords[mk]=fonts;font size;styles;charsets;character sets;panel;kicker;control panel;desktops;FileManager;Toolbars;Menu;Window Title;Title;фонтови;големина на фонтови;стилови;знаковно множество;знаковни множества;панел;контролен панел;површини;лентасо алатки;алатки;Мени;Наслов на прозорец;Наслов; +Keywords[mn]=Бичгүүд;Бичгийн хэмжээ;Тэмдэгтүүд;Удирдах самбар;Самбар;Дамжуулагч;Хэлбэр;Файл удирдагч;Ажлын тавцан;Багаж самбар;Цэс;Цонхны толгой;Гарчиг; +Keywords[nb]=skrift;skrifttyper;skriftstørrelse;stil;tegnsett;panel;kicker;kontrollpanel;skrivebord;filbehandler;verktøylinjer;meny;vindustittel;tittel; +Keywords[nds]=Schriftoorden;Schriftgrött;Stilen;Tekensetten;Paneel;kicker;Kuntrullbalken;Schriefdischen;Dateimanager;Dateipleger;Warktüüchbalken;Menü;Finstertitel;Titel; +Keywords[nl]=fonts;font;letters;lettertypen;lettertypes;tekenset;tekenverzamelingen;paneel;kicker;configuratiecentrum;stijl;bestandsbeheerder;werkbalk;menu;venster;titel;venstertitel;desktops;bureaubladen; +Keywords[nn]=skrift;skrift;skriftstorleik;stil;teiknsett;panel;kicker;kontrollpanel;skrivebord;filhandsamar;verktøylinjer;meny;vindaugstittel;tittel; +Keywords[nso]=difonto;bogolo bja difonto;mokgwa;charsets;dipeakanyo tsa dihlaka; panel;seragi;panel ya taolo;di-desktop;Molaodi wa Faele;Di-bar tsa Dibereka;Menu; Sehlogo sa Window;Sehlogo; +Keywords[pa]=fonts;font size;styles;charsets;character sets;panel;kicker;control panel;desktops;FileManager;Toolbars;Menu;Window Title;Title;ਫੋਂਟ;ਫੋਂਟ ਅਕਾਰ;ਕੰਟਰੋਲ ਪੈਨਲ;ਵੇਹੜਾ;ਫਾਇਲ ਮੈਨੇਜਰ;ਮੇਨੂ;ਟਾਇਟਲ; +Keywords[pl]=czcionki;rozmiar czcionki;styl;zestaw znaków;panel;kicker;panel sterowania;pulpity;biurka;menedżer plików;paski narzędzi;menu;tytuł okna;tytuł; +Keywords[pt]=tipo de letra;tipos de letra;fontes;fonte;tamanho de fonte;estilo;mapa de caracteres;painel;kicker;painel de controlo;ecrãs;gestor de ficheiros;barras de ferramentas;menu;título da janela;título; +Keywords[pt_BR]=fontes;letras;tipos de letra;tamanho de fonte;tamanho de letra;estilo;conjunto de caracteres;painel;gerenciador de janelas;painel de controle;áreas de trabalho;Gerenciador de arquivos;barras de ferramentas;título da janela;título; +Keywords[ro]=fonturi;font;mărime;stil;set de caractere;panou;kicker;panou de control;ecrane;manager de fișiere;bară de unelte;meniu;titlu fereastră;titlu; +Keywords[rw]=Imyandikire;ingano y'imyandikire;imisusire;itsinda-nyuguti;amatsinday'inyuguti;umwanya;igitera;umwanya w'igenzura;ibiro;Mucungadosiye; Imyanyabikoresho;ibikubiyemo;Umutwe w'idirishya;Umutwe; +Keywords[se]=fonttat;fontasturrodat;stiila;charsets;character sets;panela;kicker;stivrenpanela; čállinbeavddit;fiilagieđahalli;neavvoholggat;fálut;lásenamahusat;namahus; +Keywords[sk]=písma;písmo;veľkosť písma;panel;ovládací panel;znakové sady;kódovanie;štýly;kicker;plochy;Správca súborov;Panely nástrojov;Ponuka;menu;titulok;titulok okna; +Keywords[sl]=pisava;pisave;velikost pisave;slog;stil;znakovni nabor;pult;kicker;nadzorna plošča;upravitelj datotek;upravitelj;orodna vrstica;naslov okna;naslov; +Keywords[sr]=fonts;фонт size;styles;charsets;character sets;панел;kicker;control панел;desktops;FileManager;Toolbars;Menu;Window Title;Title;стилови;мени;прозор;трака са алатима;менаџер фајлова;радна површина;скуп знакова; +Keywords[sr@Latn]=fonts;font size;styles;charsets;character sets;panel;kicker;control panel;desktops;FileManager;Toolbars;Menu;Window Title;Title;stilovi;meni;prozor;traka sa alatima;menadžer fajlova;radna površina;skup znakova; +Keywords[sv]=typsnitt;teckensnitt;typsnittstorlek;teckensnittstorlek;stil;teckenkodning;panel;kicker;kontrollpanel;inställningscentral;Filhanterare;Verktygsrader;Meny;Fönstertitel;Titel; +Keywords[ta]=எழுத்துருக்கள்;எழுத்துரு அளவு;பாணிகள்;எழுத்து அமைப்பு;எழுத்து அமைப்புகள்;பலகம்;கிக்கர்;கட்டுப்பாட்டு பலகம்;மேல்மேசைகள்;கோப்பு மேலாளர்;கருவிப்பட்டிகள்;பட்டியல்;சாளர தலைப்பு;தலைப்பு; +Keywords[th]=แบบอักษร;ขนาดแบบอักษร;ลักษณะ;ชุดรหัสอักขระ;ชุดอักขระ;พาเนล;คิกเกอร์;ถาดควบคุม;พื้นที่ทำงาน;จัดการแฟ้ม;แถบเครื่องมือ;เมนู;แถบหัวเรื่องหน้าต่าง;แถบหัวเรื่อง; +Keywords[tr]=yazıtipleri;yazı boyutu;stil;karakter kümesi;panel;kicker;denetim masası;masaüstü;masaüstleri;Araç Çubuğu;Menü;Pencere Başlığı;Başlık; +Keywords[uk]=шрифти;шрифт;розмір шрифту;стиль;набір символів;панель;kicker;панель керування;стільниці;панель інструментів;меню;заголовок вікна;заголовок; +Keywords[uz]=shriftlar;shriftning oʻlchami;uslublar;belgi toʻplami;kodlash usuli;panel;boshqaruv paneli;ish stollari;Fayl boshqaruvchisi;Asboblar paneli;Menyu;Oynaning sarlavhasi;Sarlavha; +Keywords[uz@cyrillic]=шрифтлар;шрифтнинг ўлчами;услублар;белги тўплами;кодлаш усули;панел;бошқарув панели;иш столлари;Файл бошқарувчиси;Асбоблар панели;Меню;Ойнанинг сарлавҳаси;Сарлавҳа; +Keywords[ven]=Dzifontu;saizi ya Fontu;Zwitaela;Tshasete;Mubvumbedzhwa;Phanele;Murahi;Phanele yau langula;desikithopo;Mulanguli wa faela;bara ya tshishumiswa;Menu;thoho ya windo;Thoho; +Keywords[vi]=Phông chữ;cỡ;kiểu;bảng mã;bộ ký tự;bảng;thanh đẩy;bảng điều khiển;màn hình nền;Trình quản lý Tập tin;Thanh công cụ;Thực đơn;Tên Cửa sổ;Tên; +Keywords[wa]=fonte;fontes;grandeu del fonte;stîle;miernowes;cråsses;clintcheyes;ecôdaedjes;djeu di caracteres;scriftôr;kicker;cinte di contrôle;scribannes;Manaedjeu di fitchîs;Bår d' usteyes;Menu;Dressêye;Tite do purnea;Bår di tite;Tite; +Keywords[xh]=ubungakanani bamagama;ubungakanani begama;iintlobo;iicharset;amaqela abasebenzi;iqela labantu benjongo ethile;umkhabi;iqela labantu abalawulayo benjongo ethile;desktops;Umphathi wefayile iibar zesixhobo;Menu;Umxholo we Window;Umxholo; +Keywords[zh_CN]=fonts;font size;styles;charsets;character sets;panel;kicker;control panel;desktops;FileManager;Toolbars;Menu;Window Title;Title;字体;字体大小;风格;字符集;面板;控制面板;桌面;文件管理器;工具条;菜单;窗口标题;标题; +Keywords[zh_TW]=fonts;font size;styles;charsets;character sets;panel;kicker;control panel;desktops;FileManager;Toolbars;Menu;Window Title;Title;字型;字型大小;風格;字元;字元集;面板;控制面板;桌面;檔案管理程式;工具列;選單;視窗標題;標題; +Keywords[zu]=Izinhlobo zamagama;uhlobo lwamagama;izitayela;charsets; amaqoqo ezaimpawu;kicker;lawula;iwindi lemininingwane;ama-desktop;Imenenja yefayela;amabha amathuluzi;Imenu;Isihloko se-Window;Isihloko; + +Categories=Qt;TDE;X-TDE-settings-looknfeel; diff --git a/kcontrol/fonts/fonts.h b/kcontrol/fonts/fonts.h new file mode 100644 index 000000000..65a1266cb --- /dev/null +++ b/kcontrol/fonts/fonts.h @@ -0,0 +1,124 @@ +//----------------------------------------------------------------------------- +// +// tdedisplay, fonts tab +// +// Copyright (c) Mark Donohoe 1997 +// Lars Knoll 1999 + +#ifndef FONTS_H +#define FONTS_H + +#include <tqobject.h> + +#include <tdecmodule.h> +#include <kdialogbase.h> +#include <tdefontdialog.h> +#include <tdefontrequester.h> + +#include "kxftconfig.h" + +class TQCheckBox; +class TQComboBox; +class KDoubleNumInput; +class FontAASettings; + +class FontUseItem : public TDEFontRequester +{ + Q_OBJECT + +public: + FontUseItem(TQWidget * parent, const TQString &name, const TQString &grp, + const TQString &key, const TQString &rc, const TQFont &default_fnt, + bool fixed = false); + + void readFont( bool useDefaults ); + void writeFont(); + void setDefault(); + void applyFontDiff(const TQFont &fnt, int fontDiffFlags); + + const TQString& rcFile() { return _rcfile; } + const TQString& rcGroup() { return _rcgroup; } + const TQString& rcKey() { return _rckey; } + +private: + TQString _rcfile; + TQString _rcgroup; + TQString _rckey; + TQFont _default; +}; + +class FontAASettings : public KDialogBase +{ + Q_OBJECT + +public: + + FontAASettings(TQWidget *parent); + + bool save( bool useAA ); + bool load(); + bool load( bool useDefaults ); + void defaults(); + int getIndex(KXftConfig::SubPixel::Type spType); + KXftConfig::SubPixel::Type getSubPixelType(); +#ifdef HAVE_FONTCONFIG + int getIndex(KXftConfig::Hint::Style hStyle); + KXftConfig::Hint::Style getHintStyle(); +#endif + void enableWidgets(); + int exec(); + +protected slots: + + void changed(); + +private: + + TQCheckBox *excludeRange; + TQCheckBox *useSubPixel; + KDoubleNumInput *excludeFrom; + KDoubleNumInput *excludeTo; + TQComboBox *subPixelType; +#ifdef HAVE_FONTCONFIG + TQComboBox *hintingStyle; +#endif + TQLabel *excludeToLabel; + bool changesMade; +}; + +/** + * The Desktop/fonts tab in kcontrol. + */ +class TDEFonts : public TDECModule +{ + Q_OBJECT + +public: + TDEFonts(TQWidget *parent, const char *name, const TQStringList &); + ~TDEFonts(); + + virtual void load(); + virtual void load( bool useDefaults ); + virtual void save(); + virtual void defaults(); + +protected slots: + void fontSelected(); + void slotApplyFontDiff(); + void slotUseAntiAliasing(); + void slotCfgAa(); + +private: + enum AASetting { AAEnabled, AASystem, AADisabled }; + enum DPISetting { DPINone, DPI96, DPI120 }; + AASetting useAA, useAA_original; + DPISetting dpi_original; + TQComboBox *cbAA; + TQComboBox* comboForceDpi; + TQPushButton *aaSettingsButton; + TQPtrList <FontUseItem> fontUseList; + FontAASettings *aaSettings; +}; + +#endif + diff --git a/kcontrol/fonts/kxftconfig.cpp b/kcontrol/fonts/kxftconfig.cpp new file mode 100644 index 000000000..459c7b88a --- /dev/null +++ b/kcontrol/fonts/kxftconfig.cpp @@ -0,0 +1,1544 @@ +/* + Copyright (c) 2002 Craig Drummond <[email protected]> + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "kxftconfig.h" +#include <math.h> +#include <string.h> +#include <ctype.h> +#include <stdlib.h> +#include <sys/stat.h> +#include <tqregexp.h> +#include <tqfile.h> +#include <tqpaintdevice.h> +#include <tdelocale.h> +#include <klargefile.h> +#include <tqdir.h> +#include <tqsettings.h> +#include <tqfont.h> + +#ifdef HAVE_FONTCONFIG +#include <stdarg.h> +#include <stdio.h> +#include <fontconfig/fontconfig.h> +#include <kdebug.h> +#endif + +using namespace std; + +TQString KXftConfig::contractHome(TQString path) +{ + if (!path.isEmpty() && '/'==path[0]) + { + TQString home(TQDir::homeDirPath()); + + if(path.startsWith(home)) + { + unsigned int len = home.length(); + + if(path.length() == len || path[len] == '/') + return path.replace(0, len, TQString::fromLatin1("~")); + } + } + + return path; +} + +TQString KXftConfig::expandHome(TQString path) +{ + if(!path.isEmpty() && '~'==path[0]) + return 1==path.length() ? TQDir::homeDirPath() : path.replace(0, 1, TQDir::homeDirPath()); + + return path; +} + +static int point2Pixel(double point) +{ + return (int)(((point*TQPaintDevice::x11AppDpiY())/72.0)+0.5); +} + +static int pixel2Point(double pixel) +{ + return (int)(((pixel*72.0)/(double)TQPaintDevice::x11AppDpiY())+0.5); +} + +static bool equal(double d1, double d2) +{ + return (fabs(d1 - d2) < 0.0001); +} + +static TQString dirSyntax(const TQString &d) +{ + if(!d.isNull()) + { + TQString ds(d); + + ds.replace("//", "/"); + + int slashPos=ds.findRev('/'); + + if(slashPos!=(((int)ds.length())-1)) + ds.append('/'); + + return ds; + } + + return d; +} + +static TQString xDirSyntax(const TQString &d) +{ + if(!d.isNull()) + { + TQString ds(d); + int slashPos=ds.findRev('/'); + + if(slashPos==(((int)ds.length())-1)) + ds.remove(slashPos, 1); + return ds; + } + + return d; +} + +static bool check(const TQString &path, unsigned int fmt, bool checkW=false) +{ + KDE_struct_stat info; + TQCString pathC(TQFile::encodeName(path)); + + return 0==KDE_lstat(pathC, &info) && (info.st_mode&S_IFMT)==fmt && (!checkW || 0==::access(pathC, W_OK)); +} + +inline bool fExists(const TQString &p) +{ + return check(p, S_IFREG, false); +} + +inline bool dWritable(const TQString &p) +{ + return check(p, S_IFDIR, true); +} + +inline bool dExists(const TQString &p) +{ + return check(p, S_IFDIR, false); +} + +static TQString getDir(const TQString &f) +{ + TQString d(f); + + int slashPos=d.findRev('/'); + + if(-1!=slashPos) + d.remove(slashPos+1, d.length()); + + return dirSyntax(d); +} + +static time_t getTimeStamp(const TQString &item) +{ + KDE_struct_stat info; + + return !item.isNull() && 0==KDE_lstat(TQFile::encodeName(item), &info) ? info.st_mtime : 0; +} + +#ifdef HAVE_FONTCONFIG + +inline TQString fileSyntax(const TQString &f) { return xDirSyntax(f); } +// +// Obtain location of config file to use. +// +// For system, prefer the following: +// +// <...>/config.d/00kde.conf = preferred method from FontConfig >= 2.3 +// <...>/local.conf +// +// Non-system, prefer: +// +// $HOME/<...>/.fonts.conf +// $HOME/<...>/fonts.conf +// +TQString getConfigFile(bool system) +{ +#if (FC_VERSION>=20300) + static const char * constKdeRootFcFile="00kde.conf"; +#endif + + FcStrList *list=FcConfigGetConfigFiles(FcConfigGetCurrent()); + TQStringList files; + FcChar8 *file; + TQString home(dirSyntax(TQDir::homeDirPath())); + + while((file=FcStrListNext(list))) + { + TQString f((const char *)file); + + if(fExists(f)) + { + if(system || 0==fileSyntax(f).find(home)) // For nonsystem, only consider file within $HOME + files.append(f); + } +#if (FC_VERSION>=20300) + if(system && dExists(f) && (-1!=f.find(TQRegExp("/conf\\.d/?$")) || -1!=f.find(TQRegExp("/conf\\.d?$"))) ) + return dirSyntax(f)+constKdeRootFcFile; // This ones good enough for me! +#endif + } + + // + // Go through list of files, looking for the preferred one... + if(files.count()) + { + TQStringList::Iterator it(files.begin()), + end(files.end()); + + for(; it!=end; ++it) + if(-1!=(*it).find(TQRegExp(system ? "/local\\.conf$" : "/\\.?fonts\\.conf$"))) + return *it; + return files.front(); // Just return the 1st one... + } + else + return system ? "/etc/fonts/local.conf" : fileSyntax(home+"/.fonts.conf"); // Hmmm... no known files? +} + +static TQString getEntry(TQDomElement element, const char *type, unsigned int numAttributes, ...) +{ + if(numAttributes==element.attributes().length()) + { + va_list args; + unsigned int arg; + bool ok=true; + + va_start(args, numAttributes); + + for(arg=0; arg<numAttributes && ok; ++arg) + { + const char *attr=va_arg(args, const char *); + const char *val =va_arg(args, const char *); + + if(!attr || !val || val!=element.attribute(attr)) + ok=false; + } + + va_end(args); + + if(ok) + { + TQDomNode n=element.firstChild(); + + if(!n.isNull()) + { + TQDomElement e = n.toElement(); + + if(!e.isNull() && type==e.tagName()) + return e.text(); + } + } + } + + return TQString::null; +} + +static KXftConfig::SubPixel::Type strToType(const char *str) +{ + if(0==strcmp(str, "rgb")) + return KXftConfig::SubPixel::Rgb; + else if(0==strcmp(str, "bgr")) + return KXftConfig::SubPixel::Bgr; + else if(0==strcmp(str, "vrgb")) + return KXftConfig::SubPixel::Vrgb; + else if(0==strcmp(str, "vbgr")) + return KXftConfig::SubPixel::Vbgr; + else + return KXftConfig::SubPixel::None; +} + +static KXftConfig::Hint::Style strToStyle(const char *str) +{ + if(0==strcmp(str, "hintslight")) + return KXftConfig::Hint::Slight; + else if(0==strcmp(str, "hintmedium")) + return KXftConfig::Hint::Medium; + else if(0==strcmp(str, "hintfull")) + return KXftConfig::Hint::Full; + else + return KXftConfig::Hint::None; +} + +#else +static bool strToType(const char *str, KXftConfig::SubPixel::Type &type) +{ + if(0==memcmp(str, "rgb", 3)) + type=KXftConfig::SubPixel::Rgb; + else if(0==memcmp(str, "bgr", 3)) + type=KXftConfig::SubPixel::Bgr; + else if(0==memcmp(str, "vrgb", 4)) + type=KXftConfig::SubPixel::Vrgb; + else if(0==memcmp(str, "vbgr", 4)) + type=KXftConfig::SubPixel::Vbgr; + else if(0==memcmp(str, "none", 4)) + type=KXftConfig::SubPixel::None; + else + return false; + return true; +} + +static inline bool isWhiteSpace(char c) +{ + return c==' ' || c=='\n' || c== '\t'; +} + +static bool ok(char *data, char *entry) +{ + char *e=entry; + + for(;;) + { + e--; + if(e==data || *e=='\n') + return true; + else + if(!isWhiteSpace(*e)) + return false; + } + return false; +} + +static char * getKey(char *data, const char *key) +{ + char *entry, + *start=data; + + while(start &&start && (entry=strstr(start, key))) + if(entry==data || ok(data, entry) && isWhiteSpace(entry[strlen(key)])) + return entry; + else + start=entry+strlen(key); + + return NULL; +} + +static bool skipToken(char **ptr, const char *token) +{ + while(isWhiteSpace(**ptr)) + (*ptr)++; + if(0!=memcmp(*ptr, token, strlen(token))) + return false; + (*ptr)+=strlen(token); + return true; +} + +static bool readNum(char **ptr, double *num) +{ + static const int constMaxNumLen=64; + + char n[constMaxNumLen+1]; + bool foundNum=false, + foundPoint=false, + foundE=false; + int numChars=0; + + while(isWhiteSpace(**ptr)) + (*ptr)++; + + while(numChars<constMaxNumLen && (isdigit(**ptr) || + ('.'==**ptr && foundNum && !foundPoint && !foundE) || ('e'==**ptr && foundNum && !foundE))) + { + n[numChars++]=**ptr; + if('.'==**ptr) + foundPoint=true; + else if('e'==**ptr) + foundE=true; + else + foundNum=true; + (*ptr)++; + } + + if(numChars) + { + n[numChars]='\0'; + *num=atof(n); + return true; + } + + return false; +} + +static KXftConfig::ListItem * getFirstItem(TQPtrList<KXftConfig::ListItem> &list) +{ + KXftConfig::ListItem *cur; + + for(cur=list.first(); cur; cur=list.next()) + if(!cur->added()) + return cur; + return NULL; +} +#endif + +static KXftConfig::ListItem * getLastItem(TQPtrList<KXftConfig::ListItem> &list) +{ + KXftConfig::ListItem *cur; + + for(cur=list.last(); cur; cur=list.prev()) + if(!cur->added()) + return cur; + return NULL; +} + +#ifndef HAVE_FONTCONFIG +static const TQString defaultPath("/usr/X11R6/lib/X11/XftConfig"); +static const TQString defaultUserFile(".xftconfig"); +static const char * constSymEnc="\"glyphs-fontspecific\""; + +static const TQString constConfigFiles[]= +{ + defaultPath, + + "/etc/X11/XftConfig", + TQString::null +}; +#endif + +KXftConfig::KXftConfig(int required, bool system) + : m_required(required), +#ifdef HAVE_FONTCONFIG + m_doc("fontconfig"), +#else + m_size(0), + m_data(NULL), +#endif + m_system(system) +{ +#ifdef HAVE_FONTCONFIG + m_file=getConfigFile(system); + kdDebug(1208) << "Using fontconfig file:" << m_file << endl; + m_antiAliasing = aliasingEnabled(); +#else + if(system) + { + int f; + + for(f=0; !constConfigFiles[f].isNull(); ++f) + if(fExists(constConfigFiles[f])) + m_file=constConfigFiles[f]; + + if(m_file.isNull()) + m_file=defaultPath; + } + else + m_file= TQString(TQDir::homeDirPath()+"/"+defaultUserFile); +#endif +#ifndef HAVE_FONTCONFIG + m_symbolFamilies.setAutoDelete(true); +#endif + m_dirs.setAutoDelete(true); + reset(); +} + +KXftConfig::~KXftConfig() +{ +#ifndef HAVE_FONTCONFIG + delete [] m_data; + m_data=NULL; +#endif +} + +bool KXftConfig::reset() +{ + bool ok=false; + + m_madeChanges=false; +#ifdef HAVE_FONTCONFIG + m_hint.reset(); + m_hinting.reset(); +#else + m_symbolFamilies.clear(); +#endif + m_dirs.clear(); + m_excludeRange.reset(); + m_excludePixelRange.reset(); + m_subPixel.reset(); + +#ifdef HAVE_FONTCONFIG + TQFile f(m_file); + + if(f.open(IO_ReadOnly)) + { + m_time=getTimeStamp(m_file); + ok=true; + m_doc.clear(); + + if(m_doc.setContent(&f)) + readContents(); + f.close(); + } + else + ok=!fExists(m_file) && dWritable(getDir(m_file)); + + if(m_doc.documentElement().isNull()) + m_doc.appendChild(m_doc.createElement("fontconfig")); +#else + TQFile f(m_file); + + m_size=0; + delete [] m_data; + m_data=NULL; + + if(f.open(IO_Raw|IO_ReadOnly)) + { + m_time=getTimeStamp(m_file); + m_size=f.size(); + ok=true; + + if(m_size>0) + { + m_data=new char [m_size+1]; + + if(m_data) + { + f.readBlock(m_data, m_size); + m_data[m_size]='\0'; + readContents(); + } + } + f.close(); + } + else + ok=!fExists(m_file) && dWritable(getDir(m_file)); +#endif + + if(ok && m_required&ExcludeRange) + { + // + // Check exclude range values - i.e. size and pixel size... + if(!equal(0, m_excludeRange.from) || !equal(0, m_excludeRange.to)) // If "size" range is set, ensure "pixelsize" matches... + { + double pFrom=(double)point2Pixel(m_excludeRange.from), + pTo=(double)point2Pixel(m_excludeRange.to); + + if(!equal(pFrom, m_excludePixelRange.from) || !equal(pTo, m_excludePixelRange.to)) + { + m_excludePixelRange.from=pFrom; + m_excludePixelRange.to=pTo; + m_madeChanges=true; + apply(); + } + } + else if(!equal(0, m_excludePixelRange.from) || !equal(0, m_excludePixelRange.to)) // "pixelsize" set, but not "size" !!! + { + m_excludeRange.from=(int)pixel2Point(m_excludePixelRange.from); + m_excludeRange.to=(int)pixel2Point(m_excludePixelRange.to); + m_madeChanges=true; + apply(); + } + } + + return ok; +} + +bool KXftConfig::apply() +{ + bool ok=true; + + if(m_madeChanges) + { + // + // Check if file has been written since we last read it. If it has, then re-read and add any + // of our changes... + if(fExists(m_file) && getTimeStamp(m_file)!=m_time) + { + KXftConfig newConfig(m_required, m_system); + TQStringList list; + TQStringList::Iterator it; + + if(m_required&Dirs) + { + list=getDirs(); + for(it=list.begin(); it!=list.end(); ++it) + newConfig.addDir(*it); + } + + if(m_required&ExcludeRange) + newConfig.setExcludeRange(m_excludeRange.from, m_excludeRange.to); + if(m_required&SubPixelType) + newConfig.setSubPixelType(m_subPixel.type); +#ifdef HAVE_FONTCONFIG + if(m_required&HintStyle) + newConfig.setHintStyle(m_hint.style); + if(m_required&AntiAlias) + newConfig.setAntiAliasing(m_antiAliasing.set); +#else + if(m_required&SymbolFamilies) + { + list=getSymbolFamilies(); + for(it=list.begin(); it!=list.end(); ++it) + newConfig.addSymbolFamily(*it); + } +#endif + + ok=newConfig.changed() ? newConfig.apply() : true; + if(ok) + reset(); + else + m_time=getTimeStamp(m_file); + } + else + { + if(m_required&ExcludeRange) + { + // Ensure these are always equal... + m_excludePixelRange.from=(int)point2Pixel(m_excludeRange.from); + m_excludePixelRange.to=(int)point2Pixel(m_excludeRange.to); + } + +#ifdef HAVE_FONTCONFIG + FcAtomic *atomic=FcAtomicCreate((const unsigned char *)((const char *)(TQFile::encodeName(m_file)))); + + ok=false; + if(atomic) + { + if(FcAtomicLock(atomic)) + { + FILE *f=fopen((char *)FcAtomicNewFile(atomic), "w"); + + if(f) + { + if(m_required&Dirs) + { + applyDirs(); + removeItems(m_dirs); + } + if(m_required&SubPixelType) + applySubPixelType(); + if(m_required&HintStyle) + applyHintStyle(); + if(m_required&AntiAlias) + applyAntiAliasing(); + if(m_required&ExcludeRange) + { + applyExcludeRange(false); + applyExcludeRange(true); + } + + // + // Check document syntax... + const char qtXmlHeader[] = "<?xml version = '1.0'?>"; + const char xmlHeader[] = "<?xml version=\"1.0\"?>"; + const char qtDocTypeLine[] = "<!DOCTYPE fontconfig>"; + const char docTypeLine[] = "<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">"; + + TQString str(m_doc.toString()); + int idx; + + if(0!=str.find("<?xml")) + str.insert(0, xmlHeader); + else if(0==str.find(qtXmlHeader)) + str.replace(0, strlen(qtXmlHeader), xmlHeader); + + if(-1!=(idx=str.find(qtDocTypeLine))) + str.replace(idx, strlen(qtDocTypeLine), docTypeLine); + + // + // Write to file... + fputs(str.utf8(), f); + fclose(f); + + if(FcAtomicReplaceOrig(atomic)) + { + ok=true; + reset(); // Re-read contents.. + } + else + FcAtomicDeleteNew(atomic); + } + FcAtomicUnlock(atomic); + } + FcAtomicDestroy(atomic); + } +#else + std::ofstream f(TQFile::encodeName(m_file)); + + if(f) + { + ListItem *ldi=m_required&Dirs ? getLastItem(m_dirs) : NULL, + *lfi=m_required&SymbolFamilies ? getLastItem(m_symbolFamilies) : NULL; + char *pos=m_data; + bool finished=false, + pixel=false; + + while(!finished) + { + int type=0; + ListItem *fdi=NULL, + *ffi=NULL; + Item *first=NULL; + + if(m_required&Dirs && NULL!=(fdi=getFirstItem(m_dirs)) && (NULL==first || fdi->start < first->start)) + { + first=fdi; + type=Dirs; + } + if(m_required&SymbolFamilies && NULL!=(ffi=getFirstItem(m_symbolFamilies)) && (NULL==first || ffi->start < first->start)) + { + first=ffi; + type=SymbolFamilies; + } + if(m_required&SubPixelType && NULL!=m_subPixel.start && (NULL==first || m_subPixel.start < first->start)) + { + first=&m_subPixel; + type=SubPixelType; + } + if(m_required&ExcludeRange) + if(NULL!=m_excludeRange.start && (NULL==first || m_excludeRange.start < first->start)) + { + first=&m_excludeRange; + type=ExcludeRange; + pixel=false; + } + else if(NULL!=m_excludePixelRange.start && (NULL==first || m_excludePixelRange.start < first->start)) + { + first=&m_excludePixelRange; + type=ExcludeRange; + pixel=true; + } + + if(first && first->start!=pos) + f.write(pos, first->start-pos); + + if(0!=type) + pos=first->end+1; + + switch(type) + { + case Dirs: + if(!first->toBeRemoved) + outputDir(f, fdi->str); + m_dirs.remove(fdi); + if(fdi==ldi) + outputNewDirs(f); + break; + case SymbolFamilies: + if(!first->toBeRemoved) + outputSymbolFamily(f, ffi->str); + m_symbolFamilies.remove(ffi); + if(ffi==lfi) + outputNewSymbolFamilies(f); + break; + case SubPixelType: + if(!first->toBeRemoved) + outputSubPixelType(f, false); + m_subPixel.start=NULL; + break; + case ExcludeRange: + if(!first->toBeRemoved) + outputExcludeRange(f, false, pixel); + m_excludeRange.start=NULL; + break; + case 0: // 0 => All read in entries written... + if(m_size && (pos < m_data+m_size)) + f.write(pos, (m_data+m_size)-pos); + default: + finished=true; + break; + } + }; + + outputNewDirs(f); + outputNewSymbolFamilies(f); + outputSubPixelType(f, true); + outputExcludeRange(f, true, false); + outputExcludeRange(f, true, true); + f.close(); + reset(); // Re-read contents... + } + else + ok=false; +#endif + } + } + + return ok; +} + +bool KXftConfig::getSubPixelType(SubPixel::Type &type) +{ + type=m_subPixel.type; + return SubPixel::None!=m_subPixel.type; +} + +void KXftConfig::setSubPixelType(SubPixel::Type type) +{ + if(type!=m_subPixel.type) + { + m_subPixel.type=type; + m_madeChanges=true; + } +} + +#ifdef HAVE_FONTCONFIG +bool KXftConfig::getHintStyle(Hint::Style &style) +{ + if(Hint::NotSet!=m_hint.style && !m_hint.toBeRemoved) + { + style=m_hint.style; + return true; + } + else + return false; +} + +void KXftConfig::setHintStyle(Hint::Style style) +{ + if((Hint::NotSet==style && Hint::NotSet!=m_hint.style && !m_hint.toBeRemoved) || + (Hint::NotSet!=style && (style!=m_hint.style || m_hint.toBeRemoved)) ) + { + m_hint.toBeRemoved=(Hint::NotSet==style); + m_hint.style=style; + m_madeChanges=true; + } + + if(Hint::NotSet!=style) + setHinting(Hint::None!=m_hint.style); +} + +void KXftConfig::setHinting(bool set) +{ + if(set!=m_hinting.set) + { + m_hinting.set=set; + m_madeChanges=true; + } +} +#endif + +bool KXftConfig::getExcludeRange(double &from, double &to) +{ + if(!equal(0, m_excludeRange.from) || !equal(0,m_excludeRange.to)) + { + from=m_excludeRange.from; + to=m_excludeRange.to; + return true; + } + else + return false; +} + + +void KXftConfig::setExcludeRange(double from, double to) +{ + double f=from<to ? from : to, + t=from<to ? to : from; + + if(!equal(f, m_excludeRange.from) || !equal(t,m_excludeRange.to)) + { + m_excludeRange.from=f; + m_excludeRange.to=t; + m_madeChanges=true; + } +} + +void KXftConfig::addDir(const TQString &d) +{ + TQString dir(dirSyntax(d)); + + if(dExists(dir) && !hasDir(dir)) + addItem(m_dirs, dir); +} + +void KXftConfig::removeDir(const TQString &d) +{ + TQString dir(dirSyntax(d)); + + removeItem(m_dirs, dir); +} + +TQString KXftConfig::description(SubPixel::Type t) +{ + switch(t) + { + default: + case SubPixel::None: + return i18n("None"); + case SubPixel::Rgb: + return i18n("RGB"); + case SubPixel::Bgr: + return i18n("BGR"); + case SubPixel::Vrgb: + return i18n("Vertical RGB"); + case SubPixel::Vbgr: + return i18n("Vertical BGR"); + } +} + +const char * KXftConfig::toStr(SubPixel::Type t) +{ + switch(t) + { + default: + case SubPixel::None: + return "none"; + case SubPixel::Rgb: + return "rgb"; + case SubPixel::Bgr: + return "bgr"; + case SubPixel::Vrgb: + return "vrgb"; + case SubPixel::Vbgr: + return "vbgr"; + } +} + +#ifdef HAVE_FONTCONFIG +TQString KXftConfig::description(Hint::Style s) +{ + switch(s) + { + default: + case Hint::Medium: + return i18n("Medium"); + case Hint::NotSet: + return ""; + case Hint::None: + return i18n("None"); + case Hint::Slight: + return i18n("Slight"); + case Hint::Full: + return i18n("Full"); + } +} + +const char * KXftConfig::toStr(Hint::Style s) +{ + switch(s) + { + default: + case Hint::Medium: + return "hintmedium"; + case Hint::None: + return "hintnone"; + case Hint::Slight: + return "hintslight"; + case Hint::Full: + return "hintfull"; + } +} +#endif + +bool KXftConfig::hasDir(const TQString &d) +{ + TQString dir(dirSyntax(d)); + +#ifdef HAVE_FONTCONFIG + ListItem *item; + + for(item=m_dirs.first(); item; item=m_dirs.next()) + if(0==dir.find(item->str)) + return true; + + return false; +#else + return NULL!=findItem(m_dirs, dir); +#endif +} + +KXftConfig::ListItem * KXftConfig::findItem(TQPtrList<ListItem> &list, const TQString &i) +{ + ListItem *item; + + for(item=list.first(); item; item=list.next()) + if(item->str==i) + break; + + return item; +} + +void KXftConfig::clearList(TQPtrList<ListItem> &list) +{ + ListItem *item; + + for(item=list.first(); item; item=list.next()) + removeItem(list, item); +} + +TQStringList KXftConfig::getList(TQPtrList<ListItem> &list) +{ + TQStringList res; + ListItem *item; + + for(item=list.first(); item; item=list.next()) + if(!item->toBeRemoved) + res.append(item->str); + + return res; +} + +void KXftConfig::addItem(TQPtrList<ListItem> &list, const TQString &i) +{ + ListItem *item=findItem(list, i); + + if(!item) + { + list.append(new ListItem(i +#ifndef HAVE_FONTCONFIG + , NULL, NULL +#endif + )); + m_madeChanges=true; + } + else + item->toBeRemoved=false; +} + +void KXftConfig::removeItem(TQPtrList<ListItem> &list, ListItem *item) +{ + if(item) + { + if(item->added()) + list.remove(item); + else + item->toBeRemoved=true; + m_madeChanges=true; + } +} + +void KXftConfig::readContents() +{ +#ifdef HAVE_FONTCONFIG + TQDomNode n = m_doc.documentElement().firstChild(); + + while(!n.isNull()) + { + TQDomElement e = n.toElement(); + + if(!e.isNull()) + if("dir"==e.tagName()) + { + if(m_required&Dirs) + m_dirs.append(new ListItem(expandHome(dirSyntax(e.text())), n)); + } + else if("match"==e.tagName()) + { + TQString str; + + switch(e.childNodes().count()) + { + case 1: + if(m_required&SubPixelType && "font"==e.attribute("target")) + { + TQDomElement ene=e.firstChild().toElement(); + + if(!ene.isNull() && "edit"==ene.tagName()) + if(!(str=getEntry(ene, "const", 2, "name", "rgba", "mode", "assign")).isNull()) + { + m_subPixel.node=n; + m_subPixel.type=strToType(str.latin1()); + } + else if(!(str=getEntry(ene, "const", 2, "name", "hintstyle", "mode", "assign")).isNull()) + { + m_hint.node=n; + m_hint.style=strToStyle(str.latin1()); + } + else if(!(str=getEntry(ene, "bool", 2, "name", "hinting", "mode", "assign")).isNull()) + { + m_hinting.node=n; + m_hinting.set=str.lower()!="false"; + } + else if(!(str=getEntry(ene, "bool", 2, "name", "antialias", "mode", "assign")).isNull()) + { + m_antiAliasing.node=n; + m_antiAliasing.set=str.lower()!="false"; + } + } + break; + case 3: + if(m_required&ExcludeRange && "font"==e.attribute("target")) // CPD: Is target "font" or "pattern" ???? + { + bool foundFalse=false; + TQDomNode en=e.firstChild(); + TQString family; + double from=-1.0, + to=-1.0, + pixelFrom=-1.0, + pixelTo=-1.0; + + while(!en.isNull()) + { + TQDomElement ene=en.toElement(); + + if(!ene.isNull()) + if("test"==ene.tagName()) + { + // kcmfonts used to write incorrectly more or less instead of more_eq and less_eq, so read both, + // first the old (wrong) one then the right one + if(!(str=getEntry(ene, "double", 3, "qual", "any", "name", "size", "compare", "more")).isNull()) + from=str.toDouble(); + if(!(str=getEntry(ene, "double", 3, "qual", "any", "name", "size", "compare", "more_eq")).isNull()) + from=str.toDouble(); + if(!(str=getEntry(ene, "double", 3, "qual", "any", "name", "size", "compare", "less")).isNull()) + to=str.toDouble(); + if(!(str=getEntry(ene, "double", 3, "qual", "any", "name", "size", "compare", "less_eq")).isNull()) + to=str.toDouble(); + if(!(str=getEntry(ene, "double", 3, "qual", "any", "name", "pixelsize", "compare", "more")).isNull()) + pixelFrom=str.toDouble(); + if(!(str=getEntry(ene, "double", 3, "qual", "any", "name", "pixelsize", "compare", "more_eq")).isNull()) + pixelFrom=str.toDouble(); + if(!(str=getEntry(ene, "double", 3, "qual", "any", "name", "pixelsize", "compare", "less")).isNull()) + pixelTo=str.toDouble(); + if(!(str=getEntry(ene, "double", 3, "qual", "any", "name", "pixelsize", "compare", "less_eq")).isNull()) + pixelTo=str.toDouble(); + } + else if("edit"==ene.tagName() && "false"==getEntry(ene, "bool", 2, "name", "antialias", "mode", "assign")) + foundFalse=true; + + en=en.nextSibling(); + } + + if((from>=0 || to>=0) && foundFalse) + { + m_excludeRange.from=from < to ? from : to; + m_excludeRange.to =from < to ? to : from; + m_excludeRange.node=n; + } + else if((pixelFrom>=0 || pixelTo>=0) && foundFalse) + { + m_excludePixelRange.from=pixelFrom < pixelTo ? pixelFrom : pixelTo; + m_excludePixelRange.to =pixelFrom < pixelTo ? pixelTo : pixelFrom; + m_excludePixelRange.node=n; + } + } + break; + default: + break; + } + } + n=n.nextSibling(); + } +#else + static const int constMaxDataLen=2048; + + char *from=NULL, + *ptr=m_data, + *eostr=NULL, + data[constMaxDataLen]; + + if(m_required&Dirs) + while((ptr=getKey(ptr, "dir"))) + { + from=ptr; + ptr+=4; + while(isWhiteSpace(*ptr)) + ptr++; + + if(*ptr=='\"') + { + ptr++; + if(NULL!=(eostr=strchr(ptr, '\"')) && eostr-ptr<constMaxDataLen) + { + memcpy(data, ptr, eostr-ptr); + data[eostr-ptr]='\0'; + if(NULL==strchr(data, '\n')) + { + ptr=eostr+1; + + while(*ptr!='\n' && *ptr!='\0' && isWhiteSpace(*ptr)) + ptr++; + m_dirs.append(new ListItem(expandHome(dirSyntax(data)), from, ptr)); + } + } + } + } + + if(m_required&SymbolFamilies || m_required&SubPixelType || m_required&ExcludeRange) + { + double efrom, + eto; + + ptr=m_data; + + while((ptr=getKey(ptr, "match"))) + { + from=ptr; + ptr+=6; + if((m_required&SymbolFamilies || m_required&ExcludeRange) && skipToken(&ptr, "any")) + { + if(m_required&SymbolFamilies && skipToken(&ptr, "family") && skipToken(&ptr, "==")) + { + while(isWhiteSpace(*ptr)) + ptr++; + if(*ptr=='\"') + { + ptr++; + if(NULL!=(eostr=strchr(ptr, '\"')) && eostr-ptr<constMaxDataLen) + { + memcpy(data, ptr, eostr-ptr); + data[eostr-ptr]='\0'; + if(NULL==strchr(data, '\n')) + { + ptr=eostr+1; + + if(skipToken(&ptr, "edit") && skipToken(&ptr, "encoding") && skipToken(&ptr, "=") && + skipToken(&ptr, constSymEnc) && skipToken(&ptr, ";")) + { + while(*ptr!='\n' && *ptr!='\0' && isWhiteSpace(*ptr)) + ptr++; + + m_symbolFamilies.append(new ListItem(data, from, ptr)); + } + } + } + } + } + else if(m_required&ExcludeRange && skipToken(&ptr, "size") && (skipToken(&ptr, ">")||skipToken(&ptr, "<")) && + readNum(&ptr, &efrom) && skipToken(&ptr, "any") && skipToken(&ptr, "size") && + (skipToken(&ptr, "<")||skipToken(&ptr, ">")) && readNum(&ptr, &eto) && skipToken(&ptr, "edit") && + skipToken(&ptr, "antialias") && skipToken(&ptr, "=") && skipToken(&ptr, "false") && skipToken(&ptr, ";")) + { + while(*ptr!='\n' && *ptr!='\0' && isWhiteSpace(*ptr)) + ptr++; + m_excludeRange.from=efrom<eto ? efrom : eto; + m_excludeRange.to=efrom<eto ? eto : efrom; + m_excludeRange.start=from; + m_excludeRange.end=ptr; + } + else if(m_required&ExcludeRange && skipToken(&ptr, "pixelsize") && (skipToken(&ptr, ">")||skipToken(&ptr, "<")) && + readNum(&ptr, &efrom) && skipToken(&ptr, "any") && skipToken(&ptr, "pixelsize") && + (skipToken(&ptr, "<")||skipToken(&ptr, ">")) && readNum(&ptr, &eto) && skipToken(&ptr, "edit") && + skipToken(&ptr, "antialias") && skipToken(&ptr, "=") && skipToken(&ptr, "false") && skipToken(&ptr, ";")) + { + while(*ptr!='\n' && *ptr!='\0' && isWhiteSpace(*ptr)) + ptr++; + m_excludePixelRange.from=efrom<eto ? efrom : eto; + m_excludePixelRange.to=efrom<eto ? eto : efrom; + m_excludePixelRange.start=from; + m_excludePixelRange.end=ptr; + } + } + else if(m_required&SubPixelType && skipToken(&ptr, "edit") && skipToken(&ptr, "rgba") && skipToken(&ptr, "=")) + { + SubPixel::Type type=SubPixel::None; + + while(isWhiteSpace(*ptr)) + ptr++; + + if(!strToType(ptr, type)) + continue; + + ptr+=SubPixel::Rgb==type || SubPixel::Bgr==type ? 3 : 4; + + if(skipToken(&ptr, ";")) + { + while(*ptr!='\n' && *ptr!='\0' && isWhiteSpace(*ptr)) + ptr++; + m_subPixel.type=type; + m_subPixel.start=from; + m_subPixel.end=ptr; + } + } + } + } +#endif +} + +#ifdef HAVE_FONTCONFIG +void KXftConfig::applyDirs() +{ + ListItem *item, + *last=getLastItem(m_dirs); + + for(item=m_dirs.first(); item; item=m_dirs.next()) + if(!item->toBeRemoved && item->node.isNull()) + { + TQDomElement newNode = m_doc.createElement("dir"); + TQDomText text = m_doc.createTextNode(contractHome(xDirSyntax(item->str))); + + newNode.appendChild(text); + + if(last) + m_doc.documentElement().insertAfter(newNode, last->node); + else + m_doc.documentElement().appendChild(newNode); + } +} + +void KXftConfig::applySubPixelType() +{ + TQDomElement matchNode = m_doc.createElement("match"), + typeNode = m_doc.createElement("const"), + editNode = m_doc.createElement("edit"); + TQDomText typeText = m_doc.createTextNode(toStr(m_subPixel.type)); + + matchNode.setAttribute("target", "font"); + editNode.setAttribute("mode", "assign"); + editNode.setAttribute("name", "rgba"); + editNode.appendChild(typeNode); + typeNode.appendChild(typeText); + matchNode.appendChild(editNode); + if(m_subPixel.node.isNull()) + m_doc.documentElement().appendChild(matchNode); + else + m_doc.documentElement().replaceChild(matchNode, m_subPixel.node); + m_subPixel.node=matchNode; +} + +void KXftConfig::applyHintStyle() +{ + applyHinting(); + + if(Hint::NotSet==m_hint.style || m_hint.toBeRemoved) + { + if(!m_hint.node.isNull()) + { + m_doc.documentElement().removeChild(m_hint.node); + m_hint.node.clear(); + } + } + else + { + TQDomElement matchNode = m_doc.createElement("match"), + typeNode = m_doc.createElement("const"), + editNode = m_doc.createElement("edit"); + TQDomText typeText = m_doc.createTextNode(toStr(m_hint.style)); + + matchNode.setAttribute("target", "font"); + editNode.setAttribute("mode", "assign"); + editNode.setAttribute("name", "hintstyle"); + editNode.appendChild(typeNode); + typeNode.appendChild(typeText); + matchNode.appendChild(editNode); + if(m_hint.node.isNull()) + m_doc.documentElement().appendChild(matchNode); + else + m_doc.documentElement().replaceChild(matchNode, m_hint.node); + m_hint.node=matchNode; + } +} + +void KXftConfig::applyHinting() +{ + TQDomElement matchNode = m_doc.createElement("match"), + typeNode = m_doc.createElement("bool"), + editNode = m_doc.createElement("edit"); + TQDomText typeText = m_doc.createTextNode(m_hinting.set ? "true" : "false"); + + matchNode.setAttribute("target", "font"); + editNode.setAttribute("mode", "assign"); + editNode.setAttribute("name", "hinting"); + editNode.appendChild(typeNode); + typeNode.appendChild(typeText); + matchNode.appendChild(editNode); + if(m_hinting.node.isNull()) + m_doc.documentElement().appendChild(matchNode); + else + m_doc.documentElement().replaceChild(matchNode, m_hinting.node); + m_hinting.node=matchNode; +} + +void KXftConfig::applyExcludeRange(bool pixel) +{ + Exclude &range=pixel ? m_excludePixelRange : m_excludeRange; + + if(equal(range.from, 0) && equal(range.to, 0)) + { + if(!range.node.isNull()) + { + m_doc.documentElement().removeChild(range.node); + range.node.clear(); + } + } + else + { + TQString fromString, + toString; + + fromString.setNum(range.from); + toString.setNum(range.to); + + TQDomElement matchNode = m_doc.createElement("match"), + fromTestNode = m_doc.createElement("test"), + fromNode = m_doc.createElement("double"), + toTestNode = m_doc.createElement("test"), + toNode = m_doc.createElement("double"), + editNode = m_doc.createElement("edit"), + boolNode = m_doc.createElement("bool"); + TQDomText fromText = m_doc.createTextNode(fromString), + toText = m_doc.createTextNode(toString), + boolText = m_doc.createTextNode("false"); + + matchNode.setAttribute("target", "font"); // CPD: Is target "font" or "pattern" ???? + fromTestNode.setAttribute("qual", "any"); + fromTestNode.setAttribute("name", pixel ? "pixelsize" : "size"); + fromTestNode.setAttribute("compare", "more_eq"); + fromTestNode.appendChild(fromNode); + fromNode.appendChild(fromText); + toTestNode.setAttribute("qual", "any"); + toTestNode.setAttribute("name", pixel ? "pixelsize" : "size"); + toTestNode.setAttribute("compare", "less_eq"); + toTestNode.appendChild(toNode); + toNode.appendChild(toText); + editNode.setAttribute("mode", "assign"); + editNode.setAttribute("name", "antialias"); + editNode.appendChild(boolNode); + boolNode.appendChild(boolText); + matchNode.appendChild(fromTestNode); + matchNode.appendChild(toTestNode); + matchNode.appendChild(editNode); + + if(!m_antiAliasing.node.isNull()) + m_doc.documentElement().removeChild(range.node); + m_doc.documentElement().appendChild(matchNode); + range.node=matchNode; + } +} + +void KXftConfig::removeItems(TQPtrList<ListItem> &list) +{ + ListItem *item; + TQDomElement docElem = m_doc.documentElement(); + + for(item=list.first(); item; item=list.next()) + if(item->toBeRemoved && !item->node.isNull()) + docElem.removeChild(item->node); +} +#else +void KXftConfig::outputDir(std::ofstream &f, const TQString &str) +{ + f << "dir \"" << contractHome(xDirSyntax(str)).local8Bit() << "\"" << endl; +} + +void KXftConfig::outputNewDirs(std::ofstream &f) +{ + ListItem *item; + + for(item=m_dirs.first(); item; item=m_dirs.next()) + if(!item->toBeRemoved && NULL==item->start) + outputDir(f, item->str); + m_dirs.clear(); +} + +void KXftConfig::outputSymbolFamily(std::ofstream &f, const TQString &str) +{ + f << "match any family == \"" << str.local8Bit() << "\" edit encoding = " << constSymEnc << ';' << endl; +} + +void KXftConfig::outputNewSymbolFamilies(std::ofstream &f) +{ + ListItem *item; + + for(item=m_symbolFamilies.first(); item; item=m_symbolFamilies.next()) + if(!item->toBeRemoved && NULL==item->start) + outputSymbolFamily(f, item->str); + m_symbolFamilies.clear(); +} + +void KXftConfig::outputSubPixelType(std::ofstream &f, bool ifNew) +{ + if((ifNew && NULL==m_subPixel.end) || (!ifNew && NULL!=m_subPixel.end)) + f << "match edit rgba = " << toStr(m_subPixel.type) << ';' << endl; +} + +void KXftConfig::outputExcludeRange(std::ofstream &f, bool ifNew, bool pixel) +{ + Exclude &range=pixel ? m_excludePixelRange : m_excludeRange; + + if(((ifNew && NULL==range.end) || (!ifNew && NULL!=range.end)) && + (!equal(range.from,0) || !equal(range.to,0))) + { + if(pixel) + f << "match any pixelsize > "; + else + f << "match any size > "; + + f << range.from; + if(pixel) + f << " any pixelsize < "; + else + f << " any size < "; + f << range.to << " edit antialias = false;" << endl; +} +} + +#endif + +#ifdef HAVE_FONTCONFIG +bool KXftConfig::getAntiAliasing() const +{ + return m_antiAliasing.set; +} + +void KXftConfig::setAntiAliasing( bool set ) +{ + if ((set && !m_antiAliasing.set) || (!set && m_antiAliasing.set)) + { + m_antiAliasing.set = set; + m_madeChanges = true; + } +} + +void KXftConfig::applyAntiAliasing() +{ + TQDomElement matchNode = m_doc.createElement("match"), + typeNode = m_doc.createElement("bool"), + editNode = m_doc.createElement("edit"); + TQDomText typeText = m_doc.createTextNode(m_antiAliasing.set ? "true" : "false"); + + matchNode.setAttribute("target", "font"); + editNode.setAttribute("mode", "assign"); + editNode.setAttribute("name", "antialias"); + editNode.appendChild(typeNode); + typeNode.appendChild(typeText); + matchNode.appendChild(editNode); + if(!m_antiAliasing.node.isNull()) + m_doc.documentElement().removeChild(m_antiAliasing.node); + m_doc.documentElement().appendChild(matchNode); + m_antiAliasing.node=matchNode; +} + +// KXftConfig only parses one config file, user's .fonts.conf usually. +// If that one doesn't exist, then KXftConfig doesn't know if antialiasing +// is enabled or not. So try to find out the default value from the default font. +// Maybe there's a better way *shrug*. +bool KXftConfig::aliasingEnabled() +{ + FcPattern *pattern = FcPatternCreate(); + FcConfigSubstitute(0, pattern, FcMatchPattern); + FcDefaultSubstitute(pattern); + FcResult result; + FcPattern *f = FcFontMatch( 0, pattern, &result ); + FcBool antialiased = FcTrue; + FcPatternGetBool( f, FC_ANTIALIAS, 0, &antialiased ); + FcPatternDestroy( f ); + FcPatternDestroy( pattern ); + return antialiased == FcTrue; +} + +#else + +void KXftConfig::setAntiAliasing( bool set ) +{ + TQSettings().writeEntry("/qt/useXft", set); + if (set) + TQSettings().writeEntry("/qt/enableXft", set); +} + +bool KXftConfig::getAntiAliasing() const +{ + return TQSettings().readBoolEntry("/qt/useXft"); +} + + +#endif diff --git a/kcontrol/fonts/kxftconfig.h b/kcontrol/fonts/kxftconfig.h new file mode 100644 index 000000000..cb5cd71f5 --- /dev/null +++ b/kcontrol/fonts/kxftconfig.h @@ -0,0 +1,277 @@ +#ifndef __KXFTCONFIG_H__ +#define __KXFTCONFIG_H__ + +/* + Copyright (c) 2002 Craig Drummond <[email protected]> + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <tqstringlist.h> +#include <tqstring.h> +#include <tqptrlist.h> +#include <stdio.h> +#include <fstream> +#include <time.h> + +#ifdef HAVE_FONTCONFIG +#include <tqdom.h> +#endif + +class KXftConfig +{ + public: + + enum RequiredData + { + Dirs = 0x01, + SubPixelType = 0x02, + ExcludeRange = 0x04, + AntiAlias = 0x08, +#ifdef HAVE_FONTCONFIG + HintStyle = 0x10 +#else + SymbolFamilies = 0x10 +#endif + }; + +#ifdef HAVE_FONTCONFIG + static const int constStyleSettings=SubPixelType|ExcludeRange|AntiAlias|HintStyle; +#else + static const int constStyleSettings=SubPixelType|ExcludeRange|AntiAlias|SymbolFamilies; +#endif + + struct Item + { +#ifdef HAVE_FONTCONFIG + Item(TQDomNode &n) : node(n), toBeRemoved(false) {} + Item() : toBeRemoved(false) {} + virtual void reset() { node.clear(); toBeRemoved=false; } + bool added() { return node.isNull(); } + + TQDomNode node; +#else + Item(char *s, char *e) : start(s), end(e), toBeRemoved(false) {} + virtual void reset() { start=end=NULL; toBeRemoved=false; } + bool added() { return NULL==start; } + + char *start, + *end; +#endif + virtual ~Item() {}; + bool toBeRemoved; + }; + + struct ListItem : public Item + { +#ifdef HAVE_FONTCONFIG + ListItem(const TQString &st, TQDomNode &n) : Item(n), str(st) {} + ListItem(const TQString &st) : str(st) {} +#else + ListItem(const TQString &st, char *s=NULL, char *e=NULL) : Item(s, e), str(st) {} +#endif + + TQString str; + }; + + struct SubPixel : public Item + { + enum Type + { + None, + Rgb, + Bgr, + Vrgb, + Vbgr + }; + +#ifdef HAVE_FONTCONFIG + SubPixel(Type t, TQDomNode &n) : Item(n), type(t) {} + SubPixel(Type t=None) : type(t) {} +#else + SubPixel(Type t=None, char *s=NULL, char *e=NULL) : Item(s, e), type(t) {} +#endif + void reset() { Item::reset(); type=None; } + + Type type; + }; + + struct Exclude : public Item + { +#ifdef HAVE_FONTCONFIG + Exclude(double f, double t, TQDomNode &n) : Item(n), from(f), to(t) {} + Exclude(double f=0, double t=0) : from(f), to(t) {} +#else + Exclude(double f=0, double t=0, char *s=NULL, char *e=NULL) : Item(s, e), from(f), to(t) {} +#endif + void reset() { Item::reset(); from=to=0; } + + double from, + to; + }; + +#ifdef HAVE_FONTCONFIG + struct Hint : public Item + { + enum Style + { + NotSet, + None, + Slight, + Medium, + Full + }; + + Hint(Style s, TQDomNode &n) : Item(n), style(s) {} + Hint(Style s=NotSet) : style(s) {} + + void reset() { Item::reset(); style=NotSet; } + + Style style; + }; + + struct Hinting : public Item + { + Hinting(bool s, TQDomNode &n) : Item(n), set(s) {} + Hinting(bool s=true) : set(s) {} + + void reset() { Item::reset(); set=true; } + + bool set; + }; + + struct AntiAliasing : public Item + { + AntiAliasing(bool s, TQDomNode &n) : Item(n), set(s) {} + AntiAliasing(bool s=true) : set(s) {} + + void reset() { Item::reset(); set=true; } + + bool set; + }; +#endif + + public: + + static TQString contractHome(TQString path); + static TQString expandHome(TQString path); + + // + // Constructor + // required - This should be a bitmask of 'RequiredData', and indicates the data to be + // read/written to the config file. It is intended that the 'fonts' KControl + // module will use KXftConfig::SubPixelType|KXftConfig::ExcludeRange, and the + // font installer will use KXftConfig::Dirs|KXftConfig::SymbolFamilies. + // + // system - Indicates if the system-wide config file, or the users ~/.xftconfig file + // should be used. Only the font-installer should access the system file (and then + // only if run as root. + KXftConfig(int required, bool system=false); + + virtual ~KXftConfig(); + + bool reset(); + bool apply(); + bool getSubPixelType(SubPixel::Type &type); + void setSubPixelType(SubPixel::Type type); // SubPixel::None => turn off sub-pixel hinting + bool getExcludeRange(double &from, double &to); + void setExcludeRange(double from, double to); // from:0, to:0 => turn off exclude range + void addDir(const TQString &d); + void removeDir(const TQString &d); + void clearDirs() { clearList(m_dirs); } + TQStringList getDirs() { return getList(m_dirs); } +#ifdef HAVE_FONTCONFIG + bool getHintStyle(Hint::Style &style); + void setHintStyle(Hint::Style style); +#else + void addSymbolFamily(const TQString &f) { addItem(m_symbolFamilies, f); } + void removeSymbolFamily(const TQString &f) { removeItem(m_symbolFamilies, f); } + void clearSymbolFamilies() { clearList(m_symbolFamilies); } + TQStringList getSymbolFamilies() { return getList(m_symbolFamilies); } +#endif + void setAntiAliasing(bool set); + bool getAntiAliasing() const; + bool changed() { return m_madeChanges; } + static TQString description(SubPixel::Type t); + static const char * toStr(SubPixel::Type t); +#ifdef HAVE_FONTCONFIG + static TQString description(Hint::Style s); + static const char * toStr(Hint::Style s); +#endif + bool hasDir(const TQString &d); + + private: + + ListItem * findItem(TQPtrList<ListItem> &list, const TQString &i); + void clearList(TQPtrList<ListItem> &list); + static TQStringList getList(TQPtrList<ListItem> &list); + void addItem(TQPtrList<ListItem> &list, const TQString &i); + void removeItem(TQPtrList<ListItem> &list, ListItem *item); + void removeItem(TQPtrList<ListItem> &list, const TQString &i) { removeItem(list, findItem(list, i)); } + void readContents(); +#ifdef HAVE_FONTCONFIG + void applyDirs(); +#if 0 + void applySymbolFamilies(); +#endif + void applySubPixelType(); + void applyHintStyle(); + void applyAntiAliasing(); + void setHinting(bool set); + void applyHinting(); + void applyExcludeRange(bool pixel); + void removeItems(TQPtrList<ListItem> &list); +#else + void outputDir(std::ofstream &f, const TQString &str); + void outputNewDirs(std::ofstream &f); + void outputSymbolFamily(std::ofstream &f, const TQString &str); + void outputNewSymbolFamilies(std::ofstream &f); + void outputSubPixelType(std::ofstream &f, bool ifNew); + void outputExcludeRange(std::ofstream &f, bool ifNew, bool pixel); +#endif + + private: + + SubPixel m_subPixel; + Exclude m_excludeRange, + m_excludePixelRange; +#ifdef HAVE_FONTCONFIG + Hint m_hint; + Hinting m_hinting; + AntiAliasing m_antiAliasing; + bool aliasingEnabled(); +#else + TQPtrList<ListItem> m_symbolFamilies; +#endif + TQPtrList<ListItem> m_dirs; + TQString m_file; + int m_required; +#ifdef HAVE_FONTCONFIG + TQDomDocument m_doc; +#else + int m_size; + char *m_data; +#endif + bool m_madeChanges, + m_system; + time_t m_time; +}; + +#endif |