qwt_text_engine.cpp
Go to the documentation of this file.
00001 /* -*- mode: C++ ; c-file-style: "stroustrup" -*- *****************************
00002  * Qwt Widget Library
00003  * Copyright (C) 1997   Josef Wilgen
00004  * Copyright (C) 2002   Uwe Rathmann
00005  *
00006  * This library is free software; you can redistribute it and/or
00007  * modify it under the terms of the Qwt License, Version 1.0
00008  *****************************************************************************/
00009 
00010 #include "qwt_text_engine.h"
00011 #include "qwt_math.h"
00012 #include "qwt_painter.h"
00013 #include <qpainter.h>
00014 #include <qpixmap.h>
00015 #include <qimage.h>
00016 #include <qmap.h>
00017 #include <qwidget.h>
00018 #include <qtextobject.h>
00019 #include <qtextdocument.h>
00020 #include <qabstracttextdocumentlayout.h>
00021 
00022 static QString taggedRichText( const QString &text, int flags )
00023 {
00024     QString richText = text;
00025 
00026     // By default QSimpleRichText is Qt::AlignLeft
00027     if ( flags & Qt::AlignJustify )
00028     {
00029         richText.prepend( QString::fromLatin1( "<div align=\"justify\">" ) );
00030         richText.append( QString::fromLatin1( "</div>" ) );
00031     }
00032     else if ( flags & Qt::AlignRight )
00033     {
00034         richText.prepend( QString::fromLatin1( "<div align=\"right\">" ) );
00035         richText.append( QString::fromLatin1( "</div>" ) );
00036     }
00037     else if ( flags & Qt::AlignHCenter )
00038     {
00039         richText.prepend( QString::fromLatin1( "<div align=\"center\">" ) );
00040         richText.append( QString::fromLatin1( "</div>" ) );
00041     }
00042 
00043     return richText;
00044 }
00045 
00046 class QwtRichTextDocument: public QTextDocument
00047 {
00048 public:
00049     QwtRichTextDocument( const QString &text, int flags, const QFont &font )
00050     {
00051         setUndoRedoEnabled( false );
00052         setDefaultFont( font );
00053         setHtml( text );
00054 
00055         // make sure we have a document layout
00056         ( void )documentLayout();
00057 
00058         QTextOption option = defaultTextOption();
00059         if ( flags & Qt::TextWordWrap )
00060             option.setWrapMode( QTextOption::WordWrap );
00061         else
00062             option.setWrapMode( QTextOption::NoWrap );
00063 
00064         option.setAlignment( static_cast<Qt::Alignment>( flags ) );
00065         setDefaultTextOption( option );
00066 
00067         QTextFrame *root = rootFrame();
00068         QTextFrameFormat fm = root->frameFormat();
00069         fm.setBorder( 0 );
00070         fm.setMargin( 0 );
00071         fm.setPadding( 0 );
00072         fm.setBottomMargin( 0 );
00073         fm.setLeftMargin( 0 );
00074         root->setFrameFormat( fm );
00075 
00076         adjustSize();
00077     }
00078 };
00079 
00080 class QwtPlainTextEngine::PrivateData
00081 {
00082 public:
00083     int effectiveAscent( const QFont &font ) const
00084     {
00085         const QString fontKey = font.key();
00086 
00087         QMap<QString, int>::const_iterator it =
00088             d_ascentCache.find( fontKey );
00089         if ( it == d_ascentCache.end() )
00090         {
00091             int ascent = findAscent( font );
00092             it = d_ascentCache.insert( fontKey, ascent );
00093         }
00094 
00095         return ( *it );
00096     }
00097 
00098 private:
00099     static int findAscent( const QFont &font )
00100     {
00101         static const QString dummy( "E" );
00102         static const QColor white( Qt::white );
00103 
00104         const QFontMetrics fm( font );
00105         QPixmap pm( fm.width( dummy ), fm.height() );
00106         pm.fill( white );
00107 
00108         QPainter p( &pm );
00109         p.setFont( font );
00110         p.drawText( 0, 0,  pm.width(), pm.height(), 0, dummy );
00111         p.end();
00112 
00113         const QImage img = pm.toImage();
00114 
00115         int row = 0;
00116         for ( row = 0; row < img.height(); row++ )
00117         {
00118             const QRgb *line = reinterpret_cast<const QRgb *>( 
00119                 img.scanLine( row ) );
00120 
00121             const int w = pm.width();
00122             for ( int col = 0; col < w; col++ )
00123             {
00124                 if ( line[col] != white.rgb() )
00125                     return fm.ascent() - row + 1;
00126             }
00127         }
00128 
00129         return fm.ascent();
00130     }
00131 
00132     mutable QMap<QString, int> d_ascentCache;
00133 };
00134 
00136 QwtTextEngine::QwtTextEngine()
00137 {
00138 }
00139 
00141 QwtTextEngine::~QwtTextEngine()
00142 {
00143 }
00144 
00146 QwtPlainTextEngine::QwtPlainTextEngine()
00147 {
00148     d_data = new PrivateData;
00149 }
00150 
00152 QwtPlainTextEngine::~QwtPlainTextEngine()
00153 {
00154     delete d_data;
00155 }
00156 
00167 double QwtPlainTextEngine::heightForWidth( const QFont& font, int flags,
00168         const QString& text, double width ) const
00169 {
00170     const QFontMetricsF fm( font );
00171     const QRectF rect = fm.boundingRect(
00172         QRectF( 0, 0, width, QWIDGETSIZE_MAX ), flags, text );
00173 
00174     return rect.height();
00175 }
00176 
00186 QSizeF QwtPlainTextEngine::textSize( const QFont &font,
00187     int flags, const QString& text ) const
00188 {
00189     const QFontMetricsF fm( font );
00190     const QRectF rect = fm.boundingRect(
00191         QRectF( 0, 0, QWIDGETSIZE_MAX, QWIDGETSIZE_MAX ), flags, text );
00192 
00193     return rect.size();
00194 }
00195 
00205 void QwtPlainTextEngine::textMargins( const QFont &font, const QString &,
00206     double &left, double &right, double &top, double &bottom ) const
00207 {
00208     left = right = top = 0;
00209 
00210     const QFontMetricsF fm( font );
00211     top = fm.ascent() - d_data->effectiveAscent( font );
00212     bottom = fm.descent();
00213 }
00214 
00225 void QwtPlainTextEngine::draw( QPainter *painter, const QRectF &rect,
00226     int flags, const QString& text ) const
00227 {
00228     QwtPainter::drawText( painter, rect, flags, text );
00229 }
00230 
00235 bool QwtPlainTextEngine::mightRender( const QString & ) const
00236 {
00237     return true;
00238 }
00239 
00240 #ifndef QT_NO_RICHTEXT
00241 
00243 QwtRichTextEngine::QwtRichTextEngine()
00244 {
00245 }
00246 
00257 double QwtRichTextEngine::heightForWidth( const QFont& font, int flags,
00258         const QString& text, double width ) const
00259 {
00260     QwtRichTextDocument doc( text, flags, font );
00261 
00262     doc.setPageSize( QSizeF( width, QWIDGETSIZE_MAX ) );
00263     return doc.documentLayout()->documentSize().height();
00264 }
00265 
00276 QSizeF QwtRichTextEngine::textSize( const QFont &font,
00277     int flags, const QString& text ) const
00278 {
00279     QwtRichTextDocument doc( text, flags, font );
00280 
00281     QTextOption option = doc.defaultTextOption();
00282     if ( option.wrapMode() != QTextOption::NoWrap )
00283     {
00284         option.setWrapMode( QTextOption::NoWrap );
00285         doc.setDefaultTextOption( option );
00286         doc.adjustSize();
00287     }
00288 
00289     return doc.size();
00290 }
00291 
00300 void QwtRichTextEngine::draw( QPainter *painter, const QRectF &rect,
00301     int flags, const QString& text ) const
00302 {
00303     QwtRichTextDocument doc( text, flags, painter->font() );
00304     QwtPainter::drawSimpleRichText( painter, rect, flags, doc );
00305 }
00306 
00315 QString QwtRichTextEngine::taggedText( const QString &text, int flags ) const
00316 {
00317     return taggedRichText( text, flags );
00318 }
00319 
00326 bool QwtRichTextEngine::mightRender( const QString &text ) const
00327 {
00328     return Qt::mightBeRichText( text );
00329 }
00330 
00339 void QwtRichTextEngine::textMargins( const QFont &, const QString &,
00340     double &left, double &right, double &top, double &bottom ) const
00341 {
00342     left = right = top = bottom = 0;
00343 }
00344 
00345 #endif // !QT_NO_RICHTEXT


plotjuggler
Author(s): Davide Faconti
autogenerated on Fri Sep 1 2017 02:41:57