Logo Search packages:      
Sourcecode: rosegarden version File versions

notefontviewer.cpp

// -*- c-basic-offset: 4 -*-
/*
    Rosegarden-4
    A sequencer and musical notation editor.

    This program is Copyright 2000-2006
        Guillaume Laurent   <glaurent@telegraph-road.org>,
        Chris Cannam        <cannam@all-day-breakfast.com>,
        Richard Bown        <bownie@bownie.com>

    The moral right of the authors to claim authorship of this work
    has been asserted.

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License as
    published by the Free Software Foundation; either version 2 of the
    License, or (at your option) any later version.  See the file
    COPYING included with this distribution for more information.
*/

/*
    This file was originally based on fontdisplayer.cpp from the Qt
    example program "qfd", copyright 1992-2000 TrollTech AS.  The
    original file said:

** This file is part of an example program for Qt.  This example
** program may be used, distributed and modified without limitation.

*/

#include <qframe.h>
#include <qpainter.h>
#include <qlabel.h>
#include <qvbox.h>
#include <kcombobox.h>
#include <ktoolbar.h>
#include <klocale.h>
#include <kapplication.h>
#include <kmessagebox.h>

#include "notefontviewer.h"

#ifdef HAVE_XFT
#include <ft2build.h>
#include <X11/Xft/Xft.h>
#endif

FontViewFrame::FontViewFrame( int pixelSize, QWidget* parent, const char* name ) :
    QFrame(parent,name),
    m_fontSize(pixelSize),
    m_tableFont(0)
{
    setBackgroundMode(PaletteBase);
    setFrameStyle(Panel|Sunken);
    setMargin(8);
    setRow(0);
}

FontViewFrame::~FontViewFrame()
{
    // empty
}

void
FontViewFrame::setFont(QString font)
{
    m_fontName = font;
    loadFont();
    update();
}

void
FontViewFrame::loadFont()
{
#ifdef HAVE_XFT
    if (m_tableFont) {
      XftFontClose(x11AppDisplay(), (XftFont *)m_tableFont);
    }
    m_tableFont = 0;

    static bool haveDir = false;
    if (!haveDir) {
      FcConfigAppFontAddDir(FcConfigGetCurrent(),
                        (const FcChar8 *)"/opt/kde3/share/apps/rosegarden/fonts");
      haveDir = true;
    }

    FcPattern *pattern = FcPatternCreate();
    FcPatternAddString(pattern, FC_FAMILY, (FcChar8 *)m_fontName.latin1());
    FcPatternAddInteger(pattern, FC_PIXEL_SIZE, m_fontSize);
    
    FcConfigSubstitute(FcConfigGetCurrent(), pattern, FcMatchPattern);

    FcResult result = FcResultMatch;
    FcPattern *match = FcFontMatch(FcConfigGetCurrent(), pattern, &result);
    FcPatternDestroy(pattern);

    if (!match || result != FcResultMatch) {
      KMessageBox::error(this, i18n("Error: Unable to match font name %1").arg(m_fontName));
      return;
    }

    FcChar8 *matchFamily;
    FcPatternGetString(match, FC_FAMILY, 0, &matchFamily);

    if (QString((const char *)matchFamily).lower() != m_fontName.lower()) {
      KMessageBox::sorry(this, i18n("Warning: No good match for font name %1 (best is %2)").
                       arg(m_fontName).arg(QString((const char *)matchFamily)));
      m_fontName = (const char *)matchFamily;
    }

    m_tableFont = XftFontOpenPattern(x11AppDisplay(), match);

    if (!m_tableFont) {
      KMessageBox::error(this, i18n("Error: Unable to open best-match font %1").
                     arg(QString((const char *)matchFamily)));
    }
#endif
}

void FontViewFrame::setGlyphs(bool glyphs)
{
    m_glyphs = glyphs;
    update();
}

QSize FontViewFrame::sizeHint() const
{
    return QSize(16 * m_fontSize * 3 / 2 + margin() + 2 * frameWidth(),
             16 * m_fontSize * 3 / 2 + margin() + 2 * frameWidth());
}

QSize FontViewFrame::cellSize() const
{
    QFontMetrics fm = fontMetrics();
    return QSize( fm.maxWidth(), fm.lineSpacing()+1 );
}

void FontViewFrame::paintEvent( QPaintEvent* e )
{
#ifdef HAVE_XFT
    if (!m_tableFont) return;

    QFrame::paintEvent(e);
    QPainter p(this);

    int ll = 25;
    int ml = frameWidth()+margin() + ll + 1;
    int mt = frameWidth()+margin();
    QSize cell((width()-16-ml)/17,(height()-16-mt)/17);

    if ( !cell.width() || !cell.height() )
        return;

    QColor body(255,255,192);
    QColor negative(255,192,192);
    QColor positive(192,192,255);
    QColor rnegative(255,128,128);
    QColor rpositive(128,128,255);

    Drawable drawable = (Drawable)handle();
    XftDraw *draw = XftDrawCreate(x11AppDisplay(), drawable,
                          (Visual *)x11Visual(), x11Colormap());

    QColor pen(Qt::black);
    XftColor col;
    col.color.red = pen.red () | pen.red() << 8;
    col.color.green = pen.green () | pen.green() << 8;
    col.color.blue = pen.blue () | pen.blue() << 8;
    col.color.alpha = 0xffff;
    col.pixel = pen.pixel();

    for (int j = 0; j <= 16; j++) {
        for (int i = 0; i <= 16; i++) {

          int x = i*cell.width();
          int y = j*cell.height();
          
          x += ml;
          y += mt; // plus ascent
          
          if (i == 0) {
            if (j == 0) continue;
            p.setFont(kapp->font());
            QFontMetrics afm(kapp->font());
            QString s = QString("%1").arg(m_row * 256 + (j-1) * 16);
            p.drawText(x - afm.width(s), y, s);
            p.setPen(QColor(190, 190, 255));
            p.drawLine(0, y, width(), y);
            p.setPen(Qt::black);
            continue;
          } else if (j == 0) {
            p.setFont(kapp->font());
            QString s = QString("%1").arg(i - 1);
            p.drawText(x, y, s);
            p.setPen(QColor(190, 190, 255));
            p.drawLine(x, 0, x, height());
            p.setPen(Qt::black);
            continue;
          }
          
          p.save();
          
          if (m_glyphs) {
            FT_UInt  ui = m_row * 256 + (j-1) * 16 + i - 1;
            XftDrawGlyphs(draw, &col, (XftFont *)m_tableFont, x, y, &ui, 1);
          } else {
            FcChar32 ch = m_row * 256 + (j-1) * 16 + i - 1;
            if (XftCharExists(x11AppDisplay(), (XftFont *)m_tableFont, ch)) {
                XftDrawString32(draw, &col, (XftFont *)m_tableFont, x, y, &ch, 1);
            }
          }
            
          p.restore();
        }
    }
#endif
}

bool
FontViewFrame::hasRow(int r) const
{
#ifdef HAVE_XFT
    if (m_glyphs) {

      if (r < 256) return true;

    } else {

      for (int c = 0; c < 256; ++c) {
          FcChar32 ch = r * 256 + c;
          if (XftCharExists(x11AppDisplay(), (XftFont *)m_tableFont, ch)) {
            return true;
          }
      }
    }
#endif
    return false;
}

void FontViewFrame::setRow(int row)
{
    m_row = row;
    update();
}

void
NoteFontViewer::slotViewChanged(int i)
{
    m_frame->setGlyphs(i == 0);

    m_rows->clear();
    int firstRow = -1;

    for (int r = 0; r < 256; ++r) {
      if (m_frame->hasRow(r)) {
          m_rows->insertItem(QString("%1").arg(r));
          if (firstRow < 0) firstRow = r;
      }
    }

    if (firstRow < 0) {
      m_rows->setEnabled(false);
      m_frame->setRow(0);
    } else {
      m_rows->setEnabled(true);
      m_frame->setRow(firstRow);
    }
}

void
NoteFontViewer::slotRowChanged(const QString &s)
{
    bool ok;
    int i = s.toInt(&ok);
    if (ok) m_frame->setRow(i);
}

void
NoteFontViewer::slotFontChanged(const QString &s)
{
    m_frame->setFont(s);
    slotViewChanged(m_view->currentItem());
}

NoteFontViewer::NoteFontViewer(QWidget *parent, QString noteFontName,
                         QStringList fontNames, int pixelSize) :
    KDialogBase(parent, 0, true,
            i18n("Note Font Viewer: %1").arg(noteFontName), Close)
{
    QVBox *box = makeVBoxMainWidget();
    KToolBar* controls = new KToolBar(box);
    controls->setMargin(3);

    (void) new QLabel(i18n("  Component: "), controls);
    m_font = new KComboBox(controls);

    for (QStringList::iterator i = fontNames.begin(); i != fontNames.end();
       ++i) {
      m_font->insertItem(*i);
    }

    (void) new QLabel(i18n("  View: "), controls);
    m_view = new KComboBox(controls);

    m_view->insertItem(i18n("Glyphs"));
    m_view->insertItem(i18n("Codes"));

    (void) new QLabel(i18n("  Page: "), controls);
    m_rows = new KComboBox(controls);

    m_frame = new FontViewFrame(pixelSize, box);

    connect(m_font, SIGNAL(activated(const QString &)),
          this, SLOT(slotFontChanged(const QString &)));

    connect(m_view, SIGNAL(activated(int)),
          this, SLOT(slotViewChanged(int)));

    connect(m_rows,SIGNAL(activated(const QString &)),
          this, SLOT(slotRowChanged(const QString &)));

    slotFontChanged(m_font->currentText());
}

#include "notefontviewer.moc"

Generated by  Doxygen 1.6.0   Back to index