F:/KPlato/koffice/libs/kotext/KoFontDiaPreview.cpp

Aller à la documentation de ce fichier.
00001 /* This file is part of the KDE project
00002    Copyright (C)  2001, 2002 Montel Laurent <lmontel@mandrakesoft.com>
00003 
00004    This library is free software; you can redistribute it and/or
00005    modify it under the terms of the GNU Library General Public
00006    License as published by the Free Software Foundation; either
00007    version 2 of the License, or (at your option) any later version.
00008 
00009    This library is distributed in the hope that it will be useful,
00010    but WITHOUT ANY WARRANTY; without even the implied warranty of
00011    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012    Library General Public License for more details.
00013 
00014    You should have received a copy of the GNU Library General Public License
00015    along with this library; see the file COPYING.LIB.  If not, write to
00016    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018 */
00019 
00020 #include "KoFontDiaPreview.h"
00021 #include "KoGlobal.h"
00022 #include "KoTextFormat.h"
00023 
00024 #include <klocale.h>
00025 
00026 #include <QFontMetrics>
00027 #include <QRect>
00028 #include <QPainter>
00029 #include <QFont>
00030 #include <QStringList>
00031 #include <QString>
00032 #include <QRegExp>
00033 //Added by qt3to4:
00034 #include <Q3Frame>
00035 
00036 #include <math.h>
00037 
00038 #include "KoFontDiaPreview.moc"
00039 
00040 KoFontDiaPreview::KoFontDiaPreview( QWidget* parent, const char* name , Qt::WFlags fl )
00041         : Q3Frame( parent, name, fl )
00042         ,m_text( i18n( "The quick brown fox jumps over the lazy dog." ) )
00043         ,displayText( i18n( "The quick brown fox jumps over the lazy dog." ) )
00044         ,m_font( KoGlobal::defaultFont() )
00045         ,m_textColor( Qt::black )
00046         ,m_backgroundColor( Qt::white )
00047         ,m_shadowDistanceX( 0 )
00048         ,m_shadowDistanceY( 0 )
00049         ,m_shadowColor( Qt::black )
00050         ,m_underlining( 0 )
00051         ,m_underliningStyle( 0 )
00052         ,m_underliningColor( Qt::black )
00053         ,m_wordByWord( false )
00054         ,m_strikethrough( 0 )
00055         ,m_strikethroughStyle( 0 )
00056         ,m_capitalisation( 0 )
00057         ,m_subSuper( 0 )
00058         ,m_offset( 0 )
00059         ,m_relativeSize( 1 )
00060 
00061 {
00062     setFrameStyle( Q3Frame::WinPanel | Q3Frame::Plain );
00063     setBackgroundMode( Qt::PaletteBase );
00064     setBackgroundColor( Qt::white );
00065     setMinimumSize( 400, 100 );
00066 }
00067 
00068 KoFontDiaPreview::~KoFontDiaPreview()
00069 {
00070 }
00071 
00072 void KoFontDiaPreview::setText( const QString &text )
00073 {
00074     m_text = text;
00075     update();
00076 }
00077 
00078 void KoFontDiaPreview::setFont( const QFont &font )
00079 {
00080     m_font = font;
00081     m_fontSize = m_font.pointSize();
00082     update();
00083 }
00084 
00085 void KoFontDiaPreview::setFontColor( const QColor &textColor )
00086 {
00087     m_textColor = textColor;
00088     update();
00089 }
00090 
00091 void KoFontDiaPreview::setBackgroundColor( const QColor &backgroundColor )
00092 {
00093     m_backgroundColor = backgroundColor;
00094     update();
00095 }
00096 
00097 void KoFontDiaPreview::setShadow( double sdx, double sdy, QColor shadowColor )
00098 {
00099     m_shadowDistanceX = sdx;
00100     m_shadowDistanceY = sdy;
00101     m_shadowColor = shadowColor;
00102     update();
00103 }
00104 
00105 void KoFontDiaPreview::setUnderlining( int underlining, int underliningStyle, const QColor underliningColor, bool wordByWord )
00106 {
00107     m_underlining = underlining;
00108     m_underliningStyle = underliningStyle;
00109     m_underliningColor = underliningColor;
00110     m_wordByWord = wordByWord;
00111     update();
00112 }
00113 
00114 void KoFontDiaPreview::setWordByWord( bool wordByWord )
00115 {
00116     m_wordByWord = wordByWord;
00117     update();
00118 }
00119 
00120 void KoFontDiaPreview::setStrikethrough( int strikethrough, int strikethroughStyle, bool wordByWord )
00121 {
00122     m_strikethrough = strikethrough;
00123     m_strikethroughStyle = strikethroughStyle;
00124     m_wordByWord = wordByWord;
00125     update();
00126 }
00127 
00128 void KoFontDiaPreview::setCapitalisation( int capitalisation )
00129 {
00130     m_capitalisation = capitalisation;
00131     update();
00132 }
00133 
00134 void KoFontDiaPreview::setSubSuperscript( int subSuper, int offset, double relativeSize )
00135 {
00136     m_subSuper = subSuper;
00137     m_offset = offset;
00138     m_relativeSize = relativeSize;
00139     update();
00140 }
00141 
00142 QString KoFontDiaPreview::formatCapitalisation( const QString &string )
00143 {
00144     switch ( m_capitalisation )
00145     {
00146     case KoTextFormat::ATT_NONE :
00147         return string;
00148     case KoTextFormat::ATT_UPPER :
00149         return string.toUpper();
00150     case KoTextFormat::ATT_LOWER :
00151         return string.toLower();
00152     case KoTextFormat::ATT_SMALL_CAPS :
00153         return string.toUpper();
00154     default:
00155         return string;
00156     }
00157 }
00158 
00159 void KoFontDiaPreview::drawContents( QPainter* p )
00160 {
00161     p->save();
00162 
00163     // sort out the font to use
00164 
00165     //Capitalisation
00166     double capitalisationCoeff;
00167     QFontMetrics fmCapitalisation( m_font );
00168 
00169     switch ( m_capitalisation )
00170     {
00171     case KoTextFormat::ATT_NONE :
00172         capitalisationCoeff = 1.0;
00173         break;
00174     case KoTextFormat::ATT_UPPER :
00175         capitalisationCoeff = 1.0;
00176         break;
00177     case KoTextFormat::ATT_LOWER :
00178         capitalisationCoeff = 1.0;
00179         break;
00180     case KoTextFormat::ATT_SMALL_CAPS :
00181         capitalisationCoeff = ((double)fmCapitalisation.boundingRect("x").height()/(double)fmCapitalisation.boundingRect("X").height());
00182         break;
00183     default:
00184         capitalisationCoeff = 1.0;
00185         break;
00186     }
00187     //Set the display font. m_font is untouched by the modifications of capitalisation
00188     displayFont = m_font;
00189     displayFont.setPointSizeF( m_font.pointSize() * capitalisationCoeff );
00190 
00191 // format the string in case Small Caps
00192     displayText = formatCapitalisation( m_text );
00193 
00194 // draw the stuff
00195     QFontMetrics fm( displayFont );
00196     QRect br = fm.boundingRect( contentsRect().x(), contentsRect().y(), contentsRect().width(), contentsRect().height(), Qt::AlignCenter | Qt::TextWordWrap, displayText );
00197 
00198     if ( br.width() > contentsRect().width() || br.height() > contentsRect().height() ) {
00199         displayText = formatCapitalisation( i18n( "Font too large for the preview pane" ) );
00200         displayFont.setPointSizeF( 14 * capitalisationCoeff );
00201     }
00202 
00203     QFontMetrics fm1( displayFont );
00204     br = fm1.boundingRect( contentsRect().x(), contentsRect().y(), contentsRect().width(), contentsRect().height(), Qt::AlignCenter | Qt::TextWordWrap, displayText );
00205 
00206     int xorg = qRound( ( contentsRect().width() - br.width() ) / 2 ) + contentsRect().x() - fm1.leftBearing( displayText.at( 0 ) );
00207 
00208     // sub / superscript modifications
00209     int subSuperOffset = 0;
00210     switch ( m_subSuper ) {
00211         case 0: //normal
00212             displayFont.setPointSizeF( displayFont.pointSize() * m_relativeSize );
00213             subSuperOffset = -( m_offset );
00214             break;
00215         case 1: //subscript
00216             displayFont.setPointSizeF( displayFont.pointSize() * m_relativeSize );
00217             subSuperOffset = fm1.height() / 6;
00218             break;
00219         case 2: //superscript
00220             displayFont.setPointSizeF( displayFont.pointSize() * m_relativeSize );
00221             subSuperOffset = 0 - ( fm1.height() / 2 );
00222             break;
00223         default:
00224             displayFont.setPointSizeF( displayFont.pointSize() * m_relativeSize );
00225             subSuperOffset = 0 - m_offset;
00226             break;
00227     }
00228 
00229     QFontMetrics fm2( displayFont );
00230     br = fm2.boundingRect( contentsRect().x(), contentsRect().y(), contentsRect().width(), contentsRect().height(), Qt::AlignCenter | Qt::TextWordWrap, displayText );
00231     int yorg = qRound( ( contentsRect().height() - br.height() ) / 2 ) + fm1.ascent() + subSuperOffset;
00232     int sxorg = xorg + int( m_shadowDistanceX );
00233     int syorg = yorg + int( m_shadowDistanceY );
00234     QStringList textWords = QStringList::split( " ", displayText );
00235     int x = xorg;
00236     int y = yorg;
00237     int sx = sxorg;
00238     int sy = syorg;
00239     int bx= qMin( x, sx );
00240     int xend = bx;
00241     int yUnderline;
00242     int widthUnderline;
00243     int thicknessUnderline;
00244     int yStrikethrough;
00245     int widthStrikethrough;
00246     int thicknessStrikethrough;
00247 
00248     p->setFont(displayFont );
00249     p->setPen( m_textColor );
00250     int count = 1;
00251 
00252     for ( QStringList::iterator it = textWords.begin(); it != textWords.end(); ++it ) {
00253         int boffset = 0;
00254         if ( x + fm2.width( (*it) ) >  contentsRect().width() ) {
00255             y += fm1.lineSpacing();
00256             sy += fm1.lineSpacing();
00257             xend = x;
00258             x = xorg;
00259             sx = sxorg;
00260             bx= qMin( x, sx );
00261             count = 1;
00262         }
00263         QString textDraw;
00264         if ( (*it) == textWords.last() ) {
00265             textDraw = (*it);
00266         }
00267         else {
00268             textDraw = (*it) + ' ';
00269         }
00270 /*background*/
00271         if ( count == 1 ) boffset = QABS( int( m_shadowDistanceX ) );
00272         else boffset = 0;
00273 
00274         if ( bx < xend && (bx + fm2.width( textDraw ) + boffset ) < xend && ( qMin( y, sy ) - fm2.ascent() ) < ( qMin( yorg, syorg ) - fm2.ascent() + fm2.height() + QABS( m_shadowDistanceY ) ) ) {
00275             p->fillRect( bx, qMin( yorg, syorg ) - fm2.ascent() + fm2.height() + QABS( int( m_shadowDistanceY ) ), fm2.width( textDraw ) + boffset , fm2.height() + QABS( int( m_shadowDistanceY ) ) - ( qMin( yorg, syorg ) - qMin( y, sy ) + fm2.height() + QABS( int( m_shadowDistanceY ) ) ), m_backgroundColor );
00276         }
00277         else if ( bx < xend && (bx + fm2.width( textDraw ) + boffset ) >= xend && ( qMin( y, sy ) - fm2.ascent() ) < ( qMin( yorg, syorg ) - fm2.ascent() + fm2.height() + QABS( m_shadowDistanceY ) ) ) {
00278             p->fillRect( bx, qMin( yorg, syorg ) - fm2.ascent() + fm2.height() + QABS( int( m_shadowDistanceY ) ), xend - bx , fm2.height() + QABS( int( m_shadowDistanceY ) ) - ( qMin( yorg, syorg ) - qMin( y, sy ) + fm2.height() + QABS( int( m_shadowDistanceY ) ) ), m_backgroundColor );
00279             p->fillRect( xend, qMin( y, sy ) - fm2.ascent(), fm2.width( textDraw ) + boffset - xend + bx, fm2.height() + QABS( int( m_shadowDistanceY ) ), m_backgroundColor );
00280         }
00281         else {
00282             p->fillRect( bx, qMin( y, sy ) - fm2.ascent(), fm2.width( textDraw ) + boffset , fm2.height() + QABS( int( m_shadowDistanceY ) ), m_backgroundColor );
00283         }
00284 
00285         if ( count == 1 ) boffset = QABS( int( m_shadowDistanceX ) );
00286         else boffset = 0;
00287         bx += fm2.width( textDraw ) + boffset;//( count == 1 )?0:0;//QABS( m_shadowDistanceX ):0;
00288 /*shadow*/
00289         if ( m_shadowDistanceX || m_shadowDistanceY )
00290         {
00291             p->save();
00292             p->setPen( m_shadowColor );
00293             p->drawText( sx, sy, textDraw );
00294             p->restore();
00295         }
00296 /*text*/        
00297         p->drawText( x, y, textDraw );
00298 /*underline*/   
00299         switch ( m_underlining ) {
00300             case KoTextFormat::U_NONE:
00301                 break;
00302             case KoTextFormat::U_SIMPLE:
00303                 yUnderline = y + fm2.descent();
00304                 ( m_wordByWord )? widthUnderline = fm2.width( (*it) ): widthUnderline = fm2.width( textDraw );
00305                 thicknessUnderline = 1;
00306                 drawUnderline( x, yUnderline, widthUnderline, thicknessUnderline, m_underliningColor, p );
00307                 break;
00308             case KoTextFormat::U_DOUBLE:
00309                 yUnderline = y + fm2.descent();
00310                 ( m_wordByWord )? widthUnderline = fm2.width( (*it) ): widthUnderline = fm2.width( textDraw );
00311                 thicknessUnderline = 1;
00312                 drawUnderline( x, yUnderline, widthUnderline, thicknessUnderline, m_underliningColor, p  );
00313                 yUnderline = y + qRound( fm2.descent() / 2 );
00314                 drawUnderline( x, yUnderline, widthUnderline, thicknessUnderline, m_underliningColor, p  );
00315                 break;
00316             case KoTextFormat::U_SIMPLE_BOLD:
00317                 yUnderline = y + fm2.descent();
00318                 ( m_wordByWord )? widthUnderline = fm2.width( (*it) ): widthUnderline = fm2.width( textDraw );
00319                 thicknessUnderline = qRound( displayFont.pointSize() / 10 ) + 1;
00320                 drawUnderline( x, yUnderline, widthUnderline, thicknessUnderline, m_underliningColor, p );
00321                 break;
00322             case KoTextFormat::U_WAVE:
00323                 yUnderline = y + fm2.descent();
00324                 ( m_wordByWord )? widthUnderline = fm2.width( (*it) ): widthUnderline = fm2.width( textDraw );
00325                 thicknessUnderline = 1;
00326                 drawUnderlineWave( x, yUnderline, widthUnderline, thicknessUnderline, m_underliningColor, p );
00327                 break;
00328             default:
00329                 break;
00330         }
00331 /*Strikethrough*/
00332         switch ( m_strikethrough ) {
00333             case KoTextFormat::S_NONE:
00334                 break;
00335             case KoTextFormat::S_SIMPLE:
00336                 yStrikethrough = y - qRound( fm2.ascent() / 3 );
00337                 ( m_wordByWord )? widthStrikethrough = fm2.width( (*it) ): widthStrikethrough = fm2.width( textDraw );
00338                 thicknessStrikethrough = 1;
00339                 drawStrikethrough( x, yStrikethrough, widthStrikethrough, thicknessStrikethrough, p );
00340                 break;
00341             case KoTextFormat::S_DOUBLE:
00342                 yStrikethrough = y - qRound( fm2.ascent() / 4 );
00343                 ( m_wordByWord )? widthStrikethrough = fm2.width( (*it) ): widthStrikethrough = fm2.width( textDraw );
00344                 thicknessStrikethrough = 1;
00345                 drawStrikethrough( x, yStrikethrough, widthStrikethrough, thicknessStrikethrough, p  );
00346                 yStrikethrough = y - 2 * qRound( fm2.ascent() / 4 );
00347                 drawStrikethrough( x, yStrikethrough, widthStrikethrough, thicknessStrikethrough, p  );
00348                 break;
00349             case KoTextFormat::S_SIMPLE_BOLD:
00350                 yStrikethrough = y - qRound( fm2.ascent() / 3 );
00351                 ( m_wordByWord )? widthStrikethrough = fm2.width( (*it) ): widthStrikethrough = fm2.width( textDraw );
00352                 thicknessStrikethrough = qRound( displayFont.pointSize() / 10 ) + 1;
00353                 drawStrikethrough( x, yStrikethrough, widthStrikethrough, thicknessStrikethrough, p );
00354                 break;
00355             default:
00356                 break;
00357         }
00358         x += fm2.width( textDraw );
00359         sx += fm2.width( textDraw );
00360         count++;
00361     }
00362 
00363     p->restore();
00364 }
00365 
00366 void KoFontDiaPreview::drawUnderline( int x, int y, int width, int thickness, QColor & color, QPainter *p )
00367 {
00368     p->save();
00369     switch ( m_underliningStyle ) {
00370         case KoTextFormat::U_SOLID:
00371             p->setPen( QPen( color, thickness, Qt::SolidLine ) );
00372             break;
00373         case KoTextFormat::U_DASH:
00374             p->setPen( QPen( color, thickness, Qt::DashLine ) );
00375             break;
00376         case KoTextFormat::U_DOT:
00377             p->setPen( QPen( color, thickness, Qt::DotLine ) );
00378             break;
00379         case KoTextFormat::U_DASH_DOT:
00380             p->setPen( QPen( color, thickness, Qt::DashDotLine ) );
00381             break;
00382         case KoTextFormat::U_DASH_DOT_DOT:
00383             p->setPen( QPen( color, thickness, Qt::DashDotDotLine ) );
00384             break;
00385         default:
00386             p->setPen( QPen( color, thickness, Qt::SolidLine ) );
00387     }
00388     p->drawLine( x, y, x+ width, y );
00389     p->restore();
00390 }
00391 
00392 void KoFontDiaPreview::drawUnderlineWave( int x, int y, int width, int thickness, QColor & color, QPainter *p )
00393 {
00394     p->save();
00395     int offset = 2 * thickness;
00396     QPen pen(color, thickness, Qt::SolidLine);
00397     pen.setCapStyle(Qt::RoundCap);
00398     p->setPen(pen);
00399     double anc=acos(1.0-2*(static_cast<double>(offset-(x)%offset)/static_cast<double>(offset)))/3.1415*180;
00400     int pos=1;
00401     //set starting position
00402     if(2*((x/offset)/2)==x/offset)
00403         pos*=-1;
00404     //draw first part of wave
00405     p->drawArc( (x/offset)*offset, y, offset, offset, 0, -qRound(pos*anc*16) );
00406     //now the main part
00407     int zigzag_x = (x/offset+1)*offset;
00408     for ( ; zigzag_x + offset <= width+x; zigzag_x += offset)
00409     {
00410         p->drawArc( zigzag_x, y, offset, offset, 0, pos*180*16 );
00411         pos*=-1;
00412     }
00413     //and here we finish
00414     anc=acos(1.0-2*(static_cast<double>((x+width)%offset)/static_cast<double>(offset)))/3.1415*180;
00415     p->drawArc( zigzag_x, y, offset, offset, 180*16, -qRound(pos*anc*16) );
00416     p->restore();
00417 }
00418 
00419 void KoFontDiaPreview::drawStrikethrough( int x, int y, int width, int thickness, QPainter *p )
00420 {
00421     p->save();
00422     switch ( m_strikethroughStyle ) {
00423         case KoTextFormat::S_SOLID:
00424             p->setPen( QPen( Qt::black, thickness, Qt::SolidLine ) );
00425             break;
00426         case KoTextFormat::S_DASH:
00427             p->setPen( QPen( Qt::black, thickness, Qt::DashLine ) );
00428             break;
00429         case KoTextFormat::S_DOT:
00430             p->setPen( QPen( Qt::black, thickness, Qt::DotLine ) );
00431             break;
00432         case KoTextFormat::S_DASH_DOT:
00433             p->setPen( QPen( Qt::black, thickness, Qt::DashDotLine ) );
00434             break;
00435         case KoTextFormat::S_DASH_DOT_DOT:
00436             p->setPen( QPen( Qt::black, thickness, Qt::DashDotDotLine ) );
00437             break;
00438         default:
00439             p->setPen( QPen( Qt::black, thickness, Qt::SolidLine ) );
00440     }
00441      p->drawLine( x, y, x+ width, y );
00442     p->restore();
00443 }
00444 

Généré le Wed Nov 22 23:41:08 2006 pour KPlato par  doxygen 1.5.1-p1