You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
443 lines
16 KiB
443 lines
16 KiB
/* This file is part of the KDE project
|
|
Copyright (C) 2001, 2002 Montel Laurent <lmontel@mandrakesoft.com>
|
|
|
|
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 "KoFontDiaPreview.h"
|
|
#include "KoGlobal.h"
|
|
#include "KoTextFormat.h"
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <tqfontmetrics.h>
|
|
#include <tqrect.h>
|
|
#include <tqpainter.h>
|
|
#include <tqfont.h>
|
|
#include <tqstringlist.h>
|
|
#include <tqstring.h>
|
|
#include <tqregexp.h>
|
|
|
|
#include <math.h>
|
|
|
|
#include "KoFontDiaPreview.moc"
|
|
|
|
KoFontDiaPreview::KoFontDiaPreview( TQWidget* parent, const char* name , WFlags fl )
|
|
: TQFrame( parent, name, fl )
|
|
,m_text( i18n( "The quick brown dog jumps over the lazy cat." ) )
|
|
,displayText( i18n( "The quick brown dog jumps over the lazy cat." ) )
|
|
,m_font( KoGlobal::defaultFont() )
|
|
,m_textColor( TQt::black )
|
|
,m_backgroundColor( TQt::white )
|
|
,m_shadowDistanceX( 0 )
|
|
,m_shadowDistanceY( 0 )
|
|
,m_shadowColor( TQt::black )
|
|
,m_underlining( 0 )
|
|
,m_underliningStyle( 0 )
|
|
,m_underliningColor( TQt::black )
|
|
,m_wordByWord( false )
|
|
,m_strikethrough( 0 )
|
|
,m_strikethroughStyle( 0 )
|
|
,m_capitalisation( 0 )
|
|
,m_subSuper( 0 )
|
|
,m_offset( 0 )
|
|
,m_relativeSize( 1 )
|
|
|
|
{
|
|
setFrameStyle( TQFrame::WinPanel | TQFrame::Plain );
|
|
setBackgroundMode( PaletteBase );
|
|
setBackgroundColor( TQt::white );
|
|
setMinimumSize( 400, 100 );
|
|
}
|
|
|
|
KoFontDiaPreview::~KoFontDiaPreview()
|
|
{
|
|
}
|
|
|
|
void KoFontDiaPreview::setText( const TQString &text )
|
|
{
|
|
m_text = text;
|
|
update();
|
|
}
|
|
|
|
void KoFontDiaPreview::setFont( const TQFont &font )
|
|
{
|
|
m_font = font;
|
|
m_fontSize = m_font.pointSize();
|
|
update();
|
|
}
|
|
|
|
void KoFontDiaPreview::setFontColor( const TQColor &textColor )
|
|
{
|
|
m_textColor = textColor;
|
|
update();
|
|
}
|
|
|
|
void KoFontDiaPreview::setBackgroundColor( const TQColor &backgroundColor )
|
|
{
|
|
m_backgroundColor = backgroundColor;
|
|
update();
|
|
}
|
|
|
|
void KoFontDiaPreview::setShadow( double sdx, double sdy, TQColor shadowColor )
|
|
{
|
|
m_shadowDistanceX = sdx;
|
|
m_shadowDistanceY = sdy;
|
|
m_shadowColor = shadowColor;
|
|
update();
|
|
}
|
|
|
|
void KoFontDiaPreview::setUnderlining( int underlining, int underliningStyle, const TQColor underliningColor, bool wordByWord )
|
|
{
|
|
m_underlining = underlining;
|
|
m_underliningStyle = underliningStyle;
|
|
m_underliningColor = underliningColor;
|
|
m_wordByWord = wordByWord;
|
|
update();
|
|
}
|
|
|
|
void KoFontDiaPreview::setWordByWord( bool wordByWord )
|
|
{
|
|
m_wordByWord = wordByWord;
|
|
update();
|
|
}
|
|
|
|
void KoFontDiaPreview::setStrikethrough( int strikethrough, int strikethroughStyle, bool wordByWord )
|
|
{
|
|
m_strikethrough = strikethrough;
|
|
m_strikethroughStyle = strikethroughStyle;
|
|
m_wordByWord = wordByWord;
|
|
update();
|
|
}
|
|
|
|
void KoFontDiaPreview::setCapitalisation( int capitalisation )
|
|
{
|
|
m_capitalisation = capitalisation;
|
|
update();
|
|
}
|
|
|
|
void KoFontDiaPreview::setSubSuperscript( int subSuper, int offset, double relativeSize )
|
|
{
|
|
m_subSuper = subSuper;
|
|
m_offset = offset;
|
|
m_relativeSize = relativeSize;
|
|
update();
|
|
}
|
|
|
|
TQString KoFontDiaPreview::formatCapitalisation( const TQString &string )
|
|
{
|
|
switch ( m_capitalisation )
|
|
{
|
|
case KoTextFormat::ATT_NONE :
|
|
return string;
|
|
case KoTextFormat::ATT_UPPER :
|
|
return string.upper();
|
|
case KoTextFormat::ATT_LOWER :
|
|
return string.lower();
|
|
case KoTextFormat::ATT_SMALL_CAPS :
|
|
return string.upper();
|
|
default:
|
|
return string;
|
|
}
|
|
}
|
|
|
|
void KoFontDiaPreview::drawContents( TQPainter* p )
|
|
{
|
|
p->save();
|
|
|
|
// sort out the font to use
|
|
|
|
//Capitalisation
|
|
double capitalisationCoeff;
|
|
TQFontMetrics fmCapitalisation( m_font );
|
|
|
|
switch ( m_capitalisation )
|
|
{
|
|
case KoTextFormat::ATT_NONE :
|
|
capitalisationCoeff = 1.0;
|
|
break;
|
|
case KoTextFormat::ATT_UPPER :
|
|
capitalisationCoeff = 1.0;
|
|
break;
|
|
case KoTextFormat::ATT_LOWER :
|
|
capitalisationCoeff = 1.0;
|
|
break;
|
|
case KoTextFormat::ATT_SMALL_CAPS :
|
|
capitalisationCoeff = ((double)fmCapitalisation.boundingRect("x").height()/(double)fmCapitalisation.boundingRect("X").height());
|
|
break;
|
|
default:
|
|
capitalisationCoeff = 1.0;
|
|
break;
|
|
}
|
|
//Set the display font. m_font is untouched by the modifications of capitalisation
|
|
displayFont = m_font;
|
|
displayFont.setPointSizeFloat( m_font.pointSize() * capitalisationCoeff );
|
|
|
|
// format the string in case Small Caps
|
|
displayText = formatCapitalisation( m_text );
|
|
|
|
// draw the stuff
|
|
TQFontMetrics fm( displayFont );
|
|
TQRect br = fm.boundingRect( contentsRect().x(), contentsRect().y(), contentsRect().width(), contentsRect().height(), TQt::AlignCenter | TQt::WordBreak, displayText );
|
|
|
|
if ( br.width() > contentsRect().width() || br.height() > contentsRect().height() ) {
|
|
displayText = formatCapitalisation( i18n( "Font too large for the preview pane" ) );
|
|
displayFont.setPointSizeFloat( 14 * capitalisationCoeff );
|
|
}
|
|
|
|
TQFontMetrics fm1( displayFont );
|
|
br = fm1.boundingRect( contentsRect().x(), contentsRect().y(), contentsRect().width(), contentsRect().height(), TQt::AlignCenter | TQt::WordBreak, displayText );
|
|
|
|
int xorg = tqRound( ( contentsRect().width() - br.width() ) / 2 ) + contentsRect().x() - fm1.leftBearing( displayText.at( 0 ) );
|
|
|
|
// sub / superscript modifications
|
|
int subSuperOffset = 0;
|
|
switch ( m_subSuper ) {
|
|
case 0: //normal
|
|
displayFont.setPointSizeFloat( displayFont.pointSize() * m_relativeSize );
|
|
subSuperOffset = -( m_offset );
|
|
break;
|
|
case 1: //subscript
|
|
displayFont.setPointSizeFloat( displayFont.pointSize() * m_relativeSize );
|
|
subSuperOffset = fm1.height() / 6;
|
|
break;
|
|
case 2: //superscript
|
|
displayFont.setPointSizeFloat( displayFont.pointSize() * m_relativeSize );
|
|
subSuperOffset = 0 - ( fm1.height() / 2 );
|
|
break;
|
|
default:
|
|
displayFont.setPointSizeFloat( displayFont.pointSize() * m_relativeSize );
|
|
subSuperOffset = 0 - m_offset;
|
|
break;
|
|
}
|
|
|
|
TQFontMetrics fm2( displayFont );
|
|
br = fm2.boundingRect( contentsRect().x(), contentsRect().y(), contentsRect().width(), contentsRect().height(), TQt::AlignCenter | TQt::WordBreak, displayText );
|
|
int yorg = tqRound( ( contentsRect().height() - br.height() ) / 2 ) + fm1.ascent() + subSuperOffset;
|
|
int sxorg = xorg + int( m_shadowDistanceX );
|
|
int syorg = yorg + int( m_shadowDistanceY );
|
|
TQStringList textWords = TQStringList::split( " ", displayText );
|
|
int x = xorg;
|
|
int y = yorg;
|
|
int sx = sxorg;
|
|
int sy = syorg;
|
|
int bx= TQMIN( x, sx );
|
|
int xend = bx;
|
|
int yUnderline;
|
|
int widthUnderline;
|
|
int thicknessUnderline;
|
|
int yStrikethrough;
|
|
int widthStrikethrough;
|
|
int thicknessStrikethrough;
|
|
|
|
p->setFont(displayFont );
|
|
p->setPen( m_textColor );
|
|
int count = 1;
|
|
|
|
for ( TQStringList::iterator it = textWords.begin(); it != textWords.end(); ++it ) {
|
|
int boffset = 0;
|
|
if ( x + fm2.width( (*it) ) > contentsRect().width() ) {
|
|
y += fm1.lineSpacing();
|
|
sy += fm1.lineSpacing();
|
|
xend = x;
|
|
x = xorg;
|
|
sx = sxorg;
|
|
bx= TQMIN( x, sx );
|
|
count = 1;
|
|
}
|
|
TQString textDraw;
|
|
if ( (*it) == textWords.last() ) {
|
|
textDraw = (*it);
|
|
}
|
|
else {
|
|
textDraw = (*it) + " ";
|
|
}
|
|
/*background*/
|
|
if ( count == 1 ) boffset = TQABS( int( m_shadowDistanceX ) );
|
|
else boffset = 0;
|
|
|
|
if ( bx < xend && (bx + fm2.width( textDraw ) + boffset ) < xend && ( TQMIN( y, sy ) - fm2.ascent() ) < ( TQMIN( yorg, syorg ) - fm2.ascent() + fm2.height() + TQABS( m_shadowDistanceY ) ) ) {
|
|
p->fillRect( bx, TQMIN( yorg, syorg ) - fm2.ascent() + fm2.height() + TQABS( int( m_shadowDistanceY ) ), fm2.width( textDraw ) + boffset , fm2.height() + TQABS( int( m_shadowDistanceY ) ) - ( TQMIN( yorg, syorg ) - TQMIN( y, sy ) + fm2.height() + TQABS( int( m_shadowDistanceY ) ) ), m_backgroundColor );
|
|
}
|
|
else if ( bx < xend && (bx + fm2.width( textDraw ) + boffset ) >= xend && ( TQMIN( y, sy ) - fm2.ascent() ) < ( TQMIN( yorg, syorg ) - fm2.ascent() + fm2.height() + TQABS( m_shadowDistanceY ) ) ) {
|
|
p->fillRect( bx, TQMIN( yorg, syorg ) - fm2.ascent() + fm2.height() + TQABS( int( m_shadowDistanceY ) ), xend - bx , fm2.height() + TQABS( int( m_shadowDistanceY ) ) - ( TQMIN( yorg, syorg ) - TQMIN( y, sy ) + fm2.height() + TQABS( int( m_shadowDistanceY ) ) ), m_backgroundColor );
|
|
p->fillRect( xend, TQMIN( y, sy ) - fm2.ascent(), fm2.width( textDraw ) + boffset - xend + bx, fm2.height() + TQABS( int( m_shadowDistanceY ) ), m_backgroundColor );
|
|
}
|
|
else {
|
|
p->fillRect( bx, TQMIN( y, sy ) - fm2.ascent(), fm2.width( textDraw ) + boffset , fm2.height() + TQABS( int( m_shadowDistanceY ) ), m_backgroundColor );
|
|
}
|
|
|
|
if ( count == 1 ) boffset = TQABS( int( m_shadowDistanceX ) );
|
|
else boffset = 0;
|
|
bx += fm2.width( textDraw ) + boffset;//( count == 1 )?0:0;//TQABS( m_shadowDistanceX ):0;
|
|
/*shadow*/
|
|
if ( m_shadowDistanceX || m_shadowDistanceY )
|
|
{
|
|
p->save();
|
|
p->setPen( m_shadowColor );
|
|
p->drawText( sx, sy, textDraw );
|
|
p->restore();
|
|
}
|
|
/*text*/
|
|
p->drawText( x, y, textDraw );
|
|
/*underline*/
|
|
switch ( m_underlining ) {
|
|
case KoTextFormat::U_NONE:
|
|
break;
|
|
case KoTextFormat::U_SIMPLE:
|
|
yUnderline = y + fm2.descent();
|
|
( m_wordByWord )? widthUnderline = fm2.width( (*it) ): widthUnderline = fm2.width( textDraw );
|
|
thicknessUnderline = 1;
|
|
drawUnderline( x, yUnderline, widthUnderline, thicknessUnderline, m_underliningColor, p );
|
|
break;
|
|
case KoTextFormat::U_DOUBLE:
|
|
yUnderline = y + fm2.descent();
|
|
( m_wordByWord )? widthUnderline = fm2.width( (*it) ): widthUnderline = fm2.width( textDraw );
|
|
thicknessUnderline = 1;
|
|
drawUnderline( x, yUnderline, widthUnderline, thicknessUnderline, m_underliningColor, p );
|
|
yUnderline = y + tqRound( fm2.descent() / 2 );
|
|
drawUnderline( x, yUnderline, widthUnderline, thicknessUnderline, m_underliningColor, p );
|
|
break;
|
|
case KoTextFormat::U_SIMPLE_BOLD:
|
|
yUnderline = y + fm2.descent();
|
|
( m_wordByWord )? widthUnderline = fm2.width( (*it) ): widthUnderline = fm2.width( textDraw );
|
|
thicknessUnderline = tqRound( displayFont.pointSize() / 10 ) + 1;
|
|
drawUnderline( x, yUnderline, widthUnderline, thicknessUnderline, m_underliningColor, p );
|
|
break;
|
|
case KoTextFormat::U_WAVE:
|
|
yUnderline = y + fm2.descent();
|
|
( m_wordByWord )? widthUnderline = fm2.width( (*it) ): widthUnderline = fm2.width( textDraw );
|
|
thicknessUnderline = 1;
|
|
drawUnderlineWave( x, yUnderline, widthUnderline, thicknessUnderline, m_underliningColor, p );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
/*Strikethrough*/
|
|
switch ( m_strikethrough ) {
|
|
case KoTextFormat::S_NONE:
|
|
break;
|
|
case KoTextFormat::S_SIMPLE:
|
|
yStrikethrough = y - tqRound( fm2.ascent() / 3 );
|
|
( m_wordByWord )? widthStrikethrough = fm2.width( (*it) ): widthStrikethrough = fm2.width( textDraw );
|
|
thicknessStrikethrough = 1;
|
|
drawStrikethrough( x, yStrikethrough, widthStrikethrough, thicknessStrikethrough, p );
|
|
break;
|
|
case KoTextFormat::S_DOUBLE:
|
|
yStrikethrough = y - tqRound( fm2.ascent() / 4 );
|
|
( m_wordByWord )? widthStrikethrough = fm2.width( (*it) ): widthStrikethrough = fm2.width( textDraw );
|
|
thicknessStrikethrough = 1;
|
|
drawStrikethrough( x, yStrikethrough, widthStrikethrough, thicknessStrikethrough, p );
|
|
yStrikethrough = y - 2 * tqRound( fm2.ascent() / 4 );
|
|
drawStrikethrough( x, yStrikethrough, widthStrikethrough, thicknessStrikethrough, p );
|
|
break;
|
|
case KoTextFormat::S_SIMPLE_BOLD:
|
|
yStrikethrough = y - tqRound( fm2.ascent() / 3 );
|
|
( m_wordByWord )? widthStrikethrough = fm2.width( (*it) ): widthStrikethrough = fm2.width( textDraw );
|
|
thicknessStrikethrough = tqRound( displayFont.pointSize() / 10 ) + 1;
|
|
drawStrikethrough( x, yStrikethrough, widthStrikethrough, thicknessStrikethrough, p );
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
x += fm2.width( textDraw );
|
|
sx += fm2.width( textDraw );
|
|
count++;
|
|
}
|
|
|
|
p->restore();
|
|
}
|
|
|
|
void KoFontDiaPreview::drawUnderline( int x, int y, int width, int thickness, TQColor & color, TQPainter *p )
|
|
{
|
|
p->save();
|
|
switch ( m_underliningStyle ) {
|
|
case KoTextFormat::U_SOLID:
|
|
p->setPen( TQPen( color, thickness, TQt::SolidLine ) );
|
|
break;
|
|
case KoTextFormat::U_DASH:
|
|
p->setPen( TQPen( color, thickness, TQt::DashLine ) );
|
|
break;
|
|
case KoTextFormat::U_DOT:
|
|
p->setPen( TQPen( color, thickness, TQt::DotLine ) );
|
|
break;
|
|
case KoTextFormat::U_DASH_DOT:
|
|
p->setPen( TQPen( color, thickness, TQt::DashDotLine ) );
|
|
break;
|
|
case KoTextFormat::U_DASH_DOT_DOT:
|
|
p->setPen( TQPen( color, thickness, TQt::DashDotDotLine ) );
|
|
break;
|
|
default:
|
|
p->setPen( TQPen( color, thickness, TQt::SolidLine ) );
|
|
}
|
|
p->drawLine( x, y, x+ width, y );
|
|
p->restore();
|
|
}
|
|
|
|
void KoFontDiaPreview::drawUnderlineWave( int x, int y, int width, int thickness, TQColor & color, TQPainter *p )
|
|
{
|
|
p->save();
|
|
int offset = 2 * thickness;
|
|
TQPen pen(color, thickness, TQt::SolidLine);
|
|
pen.setCapStyle(Qt::RoundCap);
|
|
p->setPen(pen);
|
|
double anc=acos(1.0-2*(static_cast<double>(offset-(x)%offset)/static_cast<double>(offset)))/3.1415*180;
|
|
int pos=1;
|
|
//set starting position
|
|
if(2*((x/offset)/2)==x/offset)
|
|
pos*=-1;
|
|
//draw first part of wave
|
|
p->drawArc( (x/offset)*offset, y, offset, offset, 0, -tqRound(pos*anc*16) );
|
|
//now the main part
|
|
int zigzag_x = (x/offset+1)*offset;
|
|
for ( ; zigzag_x + offset <= width+x; zigzag_x += offset)
|
|
{
|
|
p->drawArc( zigzag_x, y, offset, offset, 0, pos*180*16 );
|
|
pos*=-1;
|
|
}
|
|
//and here we finish
|
|
anc=acos(1.0-2*(static_cast<double>((x+width)%offset)/static_cast<double>(offset)))/3.1415*180;
|
|
p->drawArc( zigzag_x, y, offset, offset, 180*16, -tqRound(pos*anc*16) );
|
|
p->restore();
|
|
}
|
|
|
|
void KoFontDiaPreview::drawStrikethrough( int x, int y, int width, int thickness, TQPainter *p )
|
|
{
|
|
p->save();
|
|
switch ( m_strikethroughStyle ) {
|
|
case KoTextFormat::S_SOLID:
|
|
p->setPen( TQPen( TQt::black, thickness, TQt::SolidLine ) );
|
|
break;
|
|
case KoTextFormat::S_DASH:
|
|
p->setPen( TQPen( TQt::black, thickness, TQt::DashLine ) );
|
|
break;
|
|
case KoTextFormat::S_DOT:
|
|
p->setPen( TQPen( TQt::black, thickness, TQt::DotLine ) );
|
|
break;
|
|
case KoTextFormat::S_DASH_DOT:
|
|
p->setPen( TQPen( TQt::black, thickness, TQt::DashDotLine ) );
|
|
break;
|
|
case KoTextFormat::S_DASH_DOT_DOT:
|
|
p->setPen( TQPen( TQt::black, thickness, TQt::DashDotDotLine ) );
|
|
break;
|
|
default:
|
|
p->setPen( TQPen( TQt::black, thickness, TQt::SolidLine ) );
|
|
}
|
|
p->drawLine( x, y, x+ width, y );
|
|
p->restore();
|
|
}
|
|
|