[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-devel
Subject:    kwrite: CachedFontMetrics - big speedup
From:       Martin Schenk <martin () schenk ! com>
Date:       2001-02-28 13:46:15
[Download RAW message or body]

The last big performance problem in kwrite is the use of
QFontMetrics::width to calculate the width of characters.

I implemented a class CachedFontMetrics, inheriting from
QFontMetrics, that caches the width of characters.

For memory efficiency, this class allocates memory by
Unicode-Row (256 characters) - ASCII text only needs
row 0, so only that is allocated. When using other character
sets, the needed rows are dynamically allocated.

Using this class, changing the font from "courier new"
to "arial" on 800K text takes less than 1 second, compared
to about 10 seconds the old way. As this example shows,
this speedup also works with proportional fonts, in contrast
to the (currently unused) Attribute::width speedup.


["kwattribute.h" (text/x-c)]

/*
  $Id: kwattribute.h,v 1.1 2000/10/30 23:17:58 waba Exp $

   Copyright (C) 1998, 1999 Jochen Wilhelmy
                            digisnap@cs.tu-berlin.de

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#ifndef _KWATTRIBUTE_H_
#define _KWATTRIBUTE_H_

#include <qstring.h>
#include <qcolor.h>
#include <qfont.h>
#include <qfontmetrics.h>

/**
        CachedFontMetrics: Cache font metrics for faster lookup

        uses a 2-dimensional *array[256] to limit memory requirements
 */

#define CACHED_FONT_METRICS
#ifdef CACHED_FONT_METRICS
class CachedFontMetrics : public QFontMetrics {
private:
    short *warray[256];
public:
    CachedFontMetrics(const QFont& f) : QFontMetrics(f) {
        for (int i=0; i<256; i++) warray[i]=0;
    }
    ~CachedFontMetrics() {
        for (int i=0; i<256; i++)
                if (warray[i]) delete[] warray[i];
    }
    int width(QChar c) {
        uchar cell=c.cell();
        uchar row=c.row();
        short *wa=warray[row];
        if (!wa) {
                // qDebug("create row: %d",row);
                wa=warray[row]=new short[256];
                for (int i=0; i<256; i++) wa[i]=-1;
        }
        if (wa[cell]<0) wa[cell]=(short) QFontMetrics::width(c);
        return (int)wa[cell];
    }
    int width(QString s) { return QFontMetrics::width(s); }
};
typedef CachedFontMetrics FontMetrics;
#else
typedef QFontMetrics FontMetrics;
#endif

class Attribute {
  public:
    Attribute();
//    Attribute(const char *aName, const QColor &, const QColor &, const QFont &);
//    QString name;
    QColor col;
    QColor selCol;
    void setFont(const QFont &);
    QFont font;
    // QFontMetrics fm;
    FontMetrics fm;
    //workaround for slow QFontMetrics::width()
    int width(QChar c) {return (fontWidth < 0) ? fm.width(c) : fontWidth;}
    int width(QString s) {return (fontWidth < 0) ? fm.width(s) : s.length()*fontWidth;}
  protected:
    int fontWidth;
};

#endif //_KWATTRIBUTE_H_

["kwattribute.cpp" (text/x-c)]

/*
  $Id: kwattribute.cpp,v 1.1 2000/10/30 23:17:58 waba Exp $

   Copyright (C) 1998, 1999 Jochen Wilhelmy
                            digisnap@cs.tu-berlin.de

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public License
    along with this library; see the file COPYING.LIB.  If not, write to
    the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.
*/

#include "kwattribute.h"

Attribute::Attribute() : font(), fm(font) {
}

void Attribute::setFont(const QFont &f) {
  font = f;
  fm = FontMetrics(f);
//workaround for slow QFontMetrics::width(), QFont::fixedPitch() doesn't seem to work
  if ((fontWidth = fm.width('W')) != fm.width('i')) fontWidth = -1;
}


>> Visit http://master.kde.org/mailman/listinfo/kde-devel#unsub to unsubscribe <<


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic