00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <qglobal.h>
00021 #if QT_VERSION >= 0x030200
00022 #define INDIC
00023 #endif
00024
00025 #include "kotextformat.h"
00026 #include "korichtext.h"
00027 #include "kozoomhandler.h"
00028 #include <kglobal.h>
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031 #include <assert.h>
00032 #include "kostyle.h"
00033
00034 void KoTextFormat::KoTextFormatPrivate::clearCache()
00035 {
00036 delete m_screenFontMetrics; m_screenFontMetrics = 0L;
00037 delete m_screenFont; m_screenFont = 0L;
00038 delete m_refFontMetrics; m_refFontMetrics = 0L;
00039 delete m_refFont; m_refFont = 0L;
00040 m_refAscent = -1;
00041 m_refDescent = -1;
00042 m_refHeight = -1;
00043 memset( m_screenWidths, 0, 256 * sizeof( ushort ) );
00044 }
00045
00046 KoTextFormat::KoTextFormat()
00047 {
00048
00049 ref = 0;
00050 missp = FALSE;
00051 va = AlignNormal;
00052 collection = 0;
00054 fn.setStyleStrategy( QFont::ForceOutline );
00055 d = new KoTextFormatPrivate;
00056 m_textUnderlineColor=QColor();
00057 m_underlineType = U_NONE;
00058 m_strikeOutType = S_NONE;
00059 m_underlineStyle = U_SOLID;
00060 m_strikeOutStyle = S_SOLID;
00061 m_language = KGlobal::locale()->language();
00062 d->m_bHyphenation = false;
00063 d->m_underLineWidth = 1.0;
00064 d->m_shadowDistanceX = 0;
00065 d->m_shadowDistanceY = 0;
00066 d->m_relativeTextSize = 0.66;
00067 d->m_offsetFromBaseLine= 0;
00068 d->m_bWordByWord = false;
00069 m_attributeFont = ATT_NONE;
00071
00072
00073
00074 }
00075
00076 KoTextFormat::KoTextFormat( const QFont &f, const QColor &c, const QString &_language, bool hyphenation, double ulw, KoTextFormatCollection *parent )
00077 : fn( f ), col( c )
00078 {
00079 #ifdef DEBUG_COLLECTION
00080 kdDebug(32500) << "KoTextFormat with font & color & parent (" << parent << "), addRef. " << this << endl;
00081 #endif
00082 int pointSize;
00083 if ( f.pointSize() == -1 )
00084 pointSize = (int)( ( (double)fn.pixelSize() * 72.0 ) / (double)QPaintDevice::x11AppDpiY() );
00085 else
00086 pointSize = f.pointSize();
00087 fn.setPointSize( pointSize );
00088
00089 fn.setStyleStrategy( QFont::ForceOutline );
00090 ref = 0;
00091 collection = parent;
00092
00093
00094
00095
00096
00097 missp = FALSE;
00098 va = AlignNormal;
00100 d = new KoTextFormatPrivate;
00101 m_textUnderlineColor = QColor();
00102 m_underlineType = U_NONE;
00103 m_strikeOutType = S_NONE;
00104 m_underlineStyle = U_SOLID;
00105 m_strikeOutStyle = S_SOLID;
00106 m_language = _language;
00107 d->m_shadowDistanceX = 0;
00108 d->m_shadowDistanceY = 0;
00109 d->m_relativeTextSize= 0.66;
00110 d->m_offsetFromBaseLine = 0;
00111 d->m_bWordByWord = false;
00112 d->m_charStyle = 0L;
00113 d->m_bHyphenation = hyphenation;
00114 d->m_underLineWidth = ulw;
00115 m_attributeFont = ATT_NONE;
00117 generateKey();
00118 addRef();
00119 }
00120
00121 KoTextFormat::KoTextFormat( const QFont &_font,
00122 VerticalAlignment _valign,
00123 const QColor & _color,
00124 const QColor & _backGroundColor,
00125 const QColor & _underlineColor,
00126 KoTextFormat::UnderlineType _underlineType,
00127 KoTextFormat::UnderlineStyle _underlineStyle,
00128 KoTextFormat::StrikeOutType _strikeOutType,
00129 KoTextFormat::StrikeOutStyle _strikeOutStyle,
00130 KoTextFormat::AttributeStyle _fontAttribute,
00131 const QString &_language,
00132 double _relativeTextSize,
00133 int _offsetFromBaseLine,
00134 bool _wordByWord,
00135 bool _hyphenation,
00136 double _shadowDistanceX,
00137 double _shadowDistanceY,
00138 const QColor& _shadowColor )
00139 {
00140 ref = 0;
00141 collection = 0;
00142 fn = _font;
00143 col = _color;
00144 missp = false;
00145 va = _valign;
00146 d = new KoTextFormatPrivate;
00147 m_textBackColor = _backGroundColor;
00148 m_textUnderlineColor = _underlineColor;
00149 m_underlineType = _underlineType;
00150 m_strikeOutType = _strikeOutType;
00151 m_underlineStyle = _underlineStyle;
00152 m_strikeOutStyle = _strikeOutStyle;
00153 m_language = _language;
00154 d->m_bHyphenation = _hyphenation;
00155 d->m_underLineWidth = 1.0;
00156 d->m_shadowDistanceX = _shadowDistanceX;
00157 d->m_shadowDistanceY = _shadowDistanceY;
00158 d->m_shadowColor = _shadowColor;
00159 d->m_relativeTextSize = _relativeTextSize;
00160 d->m_offsetFromBaseLine = _offsetFromBaseLine;
00161 d->m_bWordByWord = _wordByWord;
00162 m_attributeFont = _fontAttribute;
00163 d->m_charStyle = 0L;
00165 generateKey();
00166 addRef();
00167 }
00168
00169 KoTextFormat::KoTextFormat( const KoTextFormat &f )
00170 {
00171 d = 0L;
00172 operator=( f );
00173 }
00174
00175 KoTextFormat::~KoTextFormat()
00176 {
00178
00179
00180 #ifndef NDEBUG
00181 if ( parent() && parent()->defaultFormat() )
00182 assert( ! ( parent()->dict().find( key() ) == this ) );
00183
00184 #endif
00185 delete d;
00187 }
00188
00189 KoTextFormat& KoTextFormat::operator=( const KoTextFormat &f )
00190 {
00191 #ifdef DEBUG_COLLECTION
00192 kdDebug(32500) << "KoTextFormat::operator= " << this << " (copying " << &f << "). Will addRef" << endl;
00193 #endif
00194 ref = 0;
00195 collection = 0;
00196 fn = f.fn;
00197 col = f.col;
00198
00199
00200
00201
00202
00203
00204 missp = f.missp;
00205 va = f.va;
00206 k = f.k;
00207
00209 delete d;
00210 d = new KoTextFormatPrivate;
00211 m_textBackColor=f.m_textBackColor;
00212 m_textUnderlineColor=f.m_textUnderlineColor;
00213 m_underlineType = f.m_underlineType;
00214 m_strikeOutType = f.m_strikeOutType;
00215 m_underlineStyle = f.m_underlineStyle;
00216 m_strikeOutStyle = f.m_strikeOutStyle;
00217 m_language = f.m_language;
00218 d->m_bHyphenation=f.d->m_bHyphenation;
00219 d->m_underLineWidth=f.d->m_underLineWidth;
00220 d->m_shadowDistanceX = f.d->m_shadowDistanceX;
00221 d->m_shadowDistanceY = f.d->m_shadowDistanceY;
00222 d->m_shadowColor = f.d->m_shadowColor;
00223 d->m_relativeTextSize = f.d->m_relativeTextSize;
00224 d->m_offsetFromBaseLine = f.d->m_offsetFromBaseLine;
00225 d->m_bWordByWord = f.d->m_bWordByWord;
00226 m_attributeFont = f.m_attributeFont;
00227 d->m_charStyle = 0L;
00229 addRef();
00230 return *this;
00231 }
00232
00233 void KoTextFormat::update()
00234 {
00235
00236 fn.setStyleStrategy( QFont::ForceOutline );
00237
00238
00239
00240
00241
00242
00243 generateKey();
00244
00246 assert( d );
00247 d->clearCache();
00249 }
00250
00251 void KoTextFormat::copyFormat( const KoTextFormat & nf, int flags )
00252 {
00253 if ( flags & KoTextFormat::Bold )
00254 fn.setBold( nf.fn.bold() );
00255 if ( flags & KoTextFormat::Italic )
00256 fn.setItalic( nf.fn.italic() );
00257 if ( flags & KoTextFormat::Underline )
00258 fn.setUnderline( nf.fn.underline() );
00259 if ( flags & KoTextFormat::Family )
00260 fn.setFamily( nf.fn.family() );
00261 if ( flags & KoTextFormat::Size )
00262 fn.setPointSize( nf.fn.pointSize() );
00263 if ( flags & KoTextFormat::Color )
00264 col = nf.col;
00265 if ( flags & KoTextFormat::Misspelled )
00266 missp = nf.missp;
00267 if ( flags & KoTextFormat::VAlign )
00268 {
00269 va = nf.va;
00270 setRelativeTextSize( nf.relativeTextSize());
00271 }
00273 if ( flags & KoTextFormat::StrikeOut )
00274 {
00275 setStrikeOutStyle( nf.strikeOutStyle() );
00276 setStrikeOutType (nf.strikeOutType());
00277 }
00278 if( flags & KoTextFormat::TextBackgroundColor)
00279 setTextBackgroundColor(nf.textBackgroundColor());
00280 if( flags & KoTextFormat::ExtendUnderLine)
00281 {
00282 setTextUnderlineColor(nf.textUnderlineColor());
00283 setUnderlineType (nf.underlineType());
00284 setUnderlineStyle (nf.underlineStyle());
00285 }
00286 if( flags & KoTextFormat::Language)
00287 setLanguage(nf.language());
00288 if( flags & KoTextFormat::ShadowText)
00289 setShadow(nf.shadowDistanceX(), nf.shadowDistanceY(), nf.shadowColor());
00290 if( flags & KoTextFormat::OffsetFromBaseLine)
00291 setOffsetFromBaseLine(nf.offsetFromBaseLine());
00292 if( flags & KoTextFormat::WordByWord)
00293 setWordByWord(nf.wordByWord());
00294 if( flags & KoTextFormat::Attribute)
00295 setAttributeFont(nf.attributeFont());
00296 if( flags & KoTextFormat::Hyphenation )
00297 setHyphenation( nf.hyphenation());
00298 if( flags & KoTextFormat::UnderLineWidth )
00299 setUnderLineWidth( nf.underLineWidth());
00301 update();
00302
00303
00304 }
00305
00306 void KoTextFormat::setBold( bool b )
00307 {
00308 if ( b == fn.bold() )
00309 return;
00310 fn.setBold( b );
00311 update();
00312 }
00313
00314 void KoTextFormat::setMisspelled( bool b )
00315 {
00316 if ( b == (bool)missp )
00317 return;
00318 missp = b;
00319 update();
00320 }
00321
00322 void KoTextFormat::setVAlign( VerticalAlignment a )
00323 {
00324 if ( a == va )
00325 return;
00326 va = a;
00327 update();
00328 }
00329
00330 void KoTextFormat::setItalic( bool b )
00331 {
00332 if ( b == fn.italic() )
00333 return;
00334 fn.setItalic( b );
00335 update();
00336 }
00337
00338 void KoTextFormat::setUnderline( bool b )
00339 {
00340 if ( b == fn.underline() )
00341 return;
00342 fn.setUnderline( b );
00343 update();
00344 }
00345
00346 void KoTextFormat::setFamily( const QString &f )
00347 {
00348 if ( f == fn.family() )
00349 return;
00350 fn.setFamily( f );
00351 update();
00352 }
00353
00354 void KoTextFormat::setPointSize( int s )
00355 {
00356 if ( s == fn.pointSize() )
00357 return;
00358 fn.setPointSize( s );
00359 update();
00360 }
00361
00362 void KoTextFormat::setFont( const QFont &f )
00363 {
00364 if ( f == fn && !k.isEmpty() )
00365 return;
00366 fn = f;
00367 update();
00368 }
00369
00370 void KoTextFormat::setColor( const QColor &c )
00371 {
00372 if ( c == col )
00373 return;
00374 col = c;
00375 update();
00376 }
00377
00378 #if 0
00379 int KoTextFormat::minLeftBearing() const
00380 {
00381 if ( !painter || !painter->isActive() )
00382 return leftBearing;
00383 painter->setFont( fn );
00384 return painter->fontMetrics().minLeftBearing();
00385 }
00386
00387 int KoTextFormat::minRightBearing() const
00388 {
00389 if ( !painter || !painter->isActive() )
00390 return rightBearing;
00391 painter->setFont( fn );
00392 return painter->fontMetrics().minRightBearing();
00393 }
00394 #endif
00395
00396
00397
00398 void KoTextFormat::generateKey()
00399 {
00400 k = fn.key();
00401 k += '/';
00402 if ( col.isValid() )
00403 k += QString::number( (uint)col.rgb() );
00404 k += '/';
00405 k += QString::number( (int)isMisspelled() );
00406 k += QString::number( (int)vAlign() );
00408 k += '/';
00409 if (m_textBackColor.isValid())
00410 k += QString::number( (uint)m_textBackColor.rgb() );
00411 k += '/';
00412 if ( m_textUnderlineColor.isValid())
00413 k += QString::number( (uint)m_textUnderlineColor.rgb() );
00414 k += '/';
00415 k += QString::number( (int)m_underlineType );
00416 k += QString::number( (int)m_strikeOutType );
00417 k += QString::number( (int)m_underlineStyle );
00418 k += QString::number( (int)m_strikeOutStyle );
00419 k += '/';
00420 k += m_language;
00421 k += '/';
00422 if ( d->m_shadowDistanceX != 0 || d->m_shadowDistanceY != 0 )
00423 {
00424 k += QString::number( d->m_shadowDistanceX );
00425 k += '/';
00426 k += QString::number( d->m_shadowDistanceY );
00427 k += '/';
00428 k += QString::number( (uint)d->m_shadowColor.rgb() );
00429 }
00430 k += '/';
00431 k += QString::number( d->m_relativeTextSize);
00432 k += '/';
00433 k += QString::number( d->m_offsetFromBaseLine);
00434 k += '/';
00435 k += QString::number( (int)d->m_bWordByWord);
00436 k += QString::number( (int)m_attributeFont);
00437 k += '/';
00438 k += QString::number( (int)d->m_bHyphenation);
00439 k += QString::number( (double)d->m_underLineWidth);
00441
00442 }
00443
00444
00445
00446 QString KoTextFormat::getKey( const QFont &fn, const QColor &col, bool misspelled, VerticalAlignment a )
00447 {
00448 QString k = fn.key();
00449 k += '/';
00450 if ( col.isValid() )
00451 k += QString::number( (uint)col.rgb() );
00452 k += '/';
00453 k += QString::number( (int)misspelled );
00454 k += QString::number( (int)a );
00456 k += '/';
00457
00458 k += '/';
00459
00460 k += '/';
00461 k += QString::number( (int)U_NONE );
00462 k += QString::number( (int)S_NONE );
00463 k += QString::number( (int)U_SOLID );
00464 k += QString::number( (int)S_SOLID );
00465 k += '/';
00466
00467 k += '/';
00468
00469 k += '/';
00470 k += "0.66";
00471 k += '/';
00472 k += "0";
00473 k += '/';
00474 k += "0";
00475 k += "0";
00476 k += '/';
00477 k += "0";
00478 k += "0";
00479
00481 return k;
00482 }
00483
00484 void KoTextFormat::addRef()
00485 {
00486 ref++;
00487 #ifdef DEBUG_COLLECTION
00488 if ( collection )
00489 kdDebug(32500) << " add ref of '" << k << "' to " << ref << " (" << this << ") (coll " << collection << ")" << endl;
00490 #endif
00491 }
00492
00493 void KoTextFormat::removeRef()
00494 {
00495 ref--;
00496 if ( !collection )
00497 return;
00498 #ifdef DEBUG_COLLECTION
00499 kdDebug(32500) << " remove ref of '" << k << "' to " << ref << " (" << this << ") (coll " << collection << ")" << endl;
00500 #endif
00501 if ( ref == 0 )
00502 collection->remove( this );
00503 }
00504
00505 void KoTextFormat::setStrikeOutType (StrikeOutType _type)
00506 {
00507 if ( m_strikeOutType == _type )
00508 return;
00509 m_strikeOutType = _type;
00510 update();
00511 }
00512
00513 void KoTextFormat::setUnderlineType (UnderlineType _type)
00514 {
00515 if ( m_underlineType == _type )
00516 return;
00517 m_underlineType = _type;
00518 update();
00519 }
00520
00521 void KoTextFormat::setUnderlineStyle (UnderlineStyle _type)
00522 {
00523 if ( m_underlineStyle == _type )
00524 return;
00525 m_underlineStyle = _type;
00526 update();
00527 }
00528
00529 void KoTextFormat::setStrikeOutStyle( StrikeOutStyle _type )
00530 {
00531 if ( m_strikeOutStyle == _type )
00532 return;
00533 m_strikeOutStyle = _type;
00534 update();
00535 }
00536
00537 void KoTextFormat::setTextBackgroundColor(const QColor &_col)
00538 {
00539 if(m_textBackColor==_col)
00540 return;
00541 m_textBackColor=_col;
00542 update();
00543 }
00544 void KoTextFormat::setTextUnderlineColor(const QColor &_col)
00545 {
00546 if ( m_textUnderlineColor == _col )
00547 return;
00548 m_textUnderlineColor=_col;
00549 update();
00550 }
00551
00552 void KoTextFormat::setShadow( double shadowDistanceX, double shadowDistanceY, const QColor& shadowColor )
00553 {
00554 if ( d->m_shadowDistanceX == shadowDistanceX &&
00555 d->m_shadowDistanceY == shadowDistanceY &&
00556 d->m_shadowColor == shadowColor )
00557 return;
00558 d->m_shadowDistanceX = shadowDistanceX;
00559 d->m_shadowDistanceY = shadowDistanceY;
00560 d->m_shadowColor = shadowColor;
00561 update();
00562 }
00563
00564 void KoTextFormat::setRelativeTextSize( double _size )
00565 {
00566 if ( d->m_relativeTextSize == _size)
00567 return;
00568 d->m_relativeTextSize = _size;
00569 update();
00570 }
00571
00572 void KoTextFormat::setOffsetFromBaseLine( int _offset )
00573 {
00574 if ( d->m_offsetFromBaseLine == _offset)
00575 return;
00576 d->m_offsetFromBaseLine = _offset;
00577 update();
00578 }
00579
00580 void KoTextFormat::setWordByWord( bool _b )
00581 {
00582 if ( d->m_bWordByWord == _b)
00583 return;
00584 d->m_bWordByWord = _b;
00585 update();
00586 }
00587
00588
00589 void KoTextFormat::setAttributeFont(KoTextFormat::AttributeStyle _att )
00590 {
00591 if ( m_attributeFont == _att)
00592 return;
00593 m_attributeFont = _att;
00594 update();
00595
00596 }
00597
00598 int KoTextFormat::compare( const KoTextFormat & format ) const
00599 {
00600 int flags = 0;
00601 if ( fn.weight() != format.fn.weight() )
00602 flags |= KoTextFormat::Bold;
00603 if ( fn.italic() != format.fn.italic() )
00604 flags |= KoTextFormat::Italic;
00605 if ( textUnderlineColor()!=format.textUnderlineColor() ||
00606 underlineType()!= format.underlineType() ||
00607 underlineStyle() != format.underlineStyle())
00608 flags |= KoTextFormat::ExtendUnderLine;
00609 if ( fn.family() != format.fn.family() )
00610 flags |= KoTextFormat::Family;
00611 if ( pointSize() != format.pointSize() )
00612 flags |= KoTextFormat::Size;
00613 if ( color() != format.color() )
00614 flags |= KoTextFormat::Color;
00615 if ( vAlign() != format.vAlign() ||
00616 relativeTextSize() != format.relativeTextSize())
00617 flags |= KoTextFormat::VAlign;
00618 if ( strikeOutType() != format.strikeOutType()
00619 || underlineStyle() != format.underlineStyle())
00620 flags |= KoTextFormat::StrikeOut;
00621 if ( textBackgroundColor() != format.textBackgroundColor() )
00622 flags |= KoTextFormat::TextBackgroundColor;
00623 if ( language() != format.language() )
00624 flags |= KoTextFormat::Language;
00625 if ( d->m_shadowDistanceX != format.shadowDistanceX()
00626 || d->m_shadowDistanceY != format.shadowDistanceY()
00627 || d->m_shadowColor != format.shadowColor() )
00628 flags |= KoTextFormat::ShadowText;
00629 if ( offsetFromBaseLine() != format.offsetFromBaseLine() )
00630 flags |= KoTextFormat::OffsetFromBaseLine;
00631 if ( wordByWord() != format.wordByWord() )
00632 flags |= KoTextFormat::WordByWord;
00633 if ( attributeFont() != format.attributeFont() )
00634 flags |= KoTextFormat::Attribute;
00635 if( hyphenation() != format.hyphenation() )
00636 flags |= KoTextFormat::Hyphenation;
00637 if( underLineWidth() != format.underLineWidth() )
00638 flags |= KoTextFormat::UnderLineWidth;
00639 return flags;
00640 }
00641
00642 QColor KoTextFormat::defaultTextColor( QPainter * painter )
00643 {
00644 if ( painter->device()->devType() == QInternal::Printer )
00645 return Qt::black;
00646 return QApplication::palette().color( QPalette::Active, QColorGroup::Text );
00647 }
00648
00649 float KoTextFormat::screenPointSize( const KoZoomHandler* zh ) const
00650 {
00651
00652 int pointSizeLU = KoTextZoomHandler::ptToLayoutUnitPt( pointSize() );
00653 if ( vAlign() != KoTextFormat::AlignNormal )
00654 pointSizeLU = (int)( pointSizeLU *relativeTextSize() );
00655 return zh->layoutUnitToFontSize( pointSizeLU, false );
00656 }
00657
00658 float KoTextFormat::refPointSize() const
00659 {
00660 if ( vAlign() != KoTextFormat::AlignNormal )
00661 return (float)pointSize() * relativeTextSize();
00662 else
00663 return pointSize();
00664 }
00665
00666 QFont KoTextFormat::refFont() const
00667 {
00668 float pointSize = refPointSize();
00669 if ( !d->m_refFont || pointSize != d->m_refFont->pointSizeFloat() )
00670 {
00671 delete d->m_refFont;
00672 d->m_refFont = new QFont( font() );
00673 d->m_refFont->setPointSizeFloat( pointSize );
00674 delete d->m_refFontMetrics;
00675 d->m_refFontMetrics = 0;
00676
00677 }
00678 return *d->m_refFont;
00679 }
00680
00681 QFont KoTextFormat::screenFont( const KoZoomHandler* zh ) const
00682 {
00683 float pointSize = screenPointSize( zh );
00684
00685
00686
00687
00688
00689
00690 if ( !d->m_screenFont || kAbs( pointSize - d->m_screenFont->pointSizeFloat() ) > 1E-4 )
00691 {
00692 delete d->m_screenFont;
00693 d->m_screenFont = new QFont( font() );
00694 d->m_screenFont->setPointSizeFloat( pointSize );
00695 delete d->m_screenFontMetrics;
00696 d->m_screenFontMetrics = 0;
00697
00698 }
00699 return *d->m_screenFont;
00700 }
00701
00702 const QFontMetrics& KoTextFormat::screenFontMetrics( const KoZoomHandler* zh ) const
00703 {
00704 QFont f = screenFont(zh);
00705
00706 if ( !d->m_screenFontMetrics )
00707 {
00708
00709 d->m_screenFontMetrics = new QFontMetrics( f );
00710
00711 }
00712 return *d->m_screenFontMetrics;
00713 }
00714
00715 const QFontMetrics& KoTextFormat::refFontMetrics() const
00716 {
00717 QFont f = refFont();
00718
00719 if ( !d->m_refFontMetrics )
00720 {
00721
00722 d->m_refFontMetrics = new QFontMetrics( f );
00723
00724 }
00725 return *d->m_refFontMetrics;
00726 }
00727
00728 QFont KoTextFormat::smallCapsFont( const KoZoomHandler* zh, bool applyZoom ) const
00729 {
00730 QFont font = applyZoom ? screenFont( zh ) : refFont();
00731 QFontMetrics fm = refFontMetrics();
00732 double pointSize = font.pointSize() * ((double)fm.boundingRect("x").height()/(double)fm.boundingRect("X").height());
00733 font.setPointSizeFloat( pointSize );
00734 return font;
00735 }
00736
00737 int KoTextFormat::charWidth( const KoZoomHandler* zh, bool applyZoom, const KoTextStringChar* c,
00738 const KoTextParag* parag, int i ) const
00739 {
00740 ushort unicode = c->c.unicode();
00741 #ifndef INDIC
00742 if ( unicode == 0xad )
00743 return 0;
00744 #else
00745 if ( !c->charStop || unicode == 0xad || unicode == 0x2028 )
00746 return 0;
00747 #endif
00748 Q_ASSERT( !c->isCustom() );
00749 if( c->isCustom() ) {
00750 if( c->customItem()->placement() == KoTextCustomItem::PlaceInline ) {
00751
00752 int w = qRound( KoTextZoomHandler::layoutUnitPtToPt( c->customItem()->width ) );
00753 return applyZoom ? ( w * zh->zoom() / 100 ) : w;
00754 }
00755 else
00756 return 0;
00757 }
00758 int pixelww;
00759 int r = c->c.row();
00760 #ifndef INDIC
00761 if( r < 0x06 || r > 0x1f )
00762 #else
00763 if( r < 0x06 || (r > 0x1f && !(r > 0xd7 && r < 0xe0)) )
00764 #endif
00765 {
00766
00767 if ( attributeFont() == KoTextFormat::ATT_SMALL_CAPS && c->c.upper() != c->c )
00768 {
00769 pixelww = QFontMetrics( smallCapsFont( zh, applyZoom ) ).width( displayedChar( c->c ) );
00770 }
00771 else
00772
00773 if ( applyZoom )
00774 {
00775 if ( r ) {
00776 pixelww = this->screenFontMetrics( zh ).width( displayedChar( c->c ) );
00777 } else {
00778
00779 Q_ASSERT( unicode < 256 );
00780 pixelww = d->m_screenWidths[ unicode ];
00781
00782 if ( pixelww == 0 ) {
00783 pixelww = this->screenFontMetrics( zh ).width( displayedChar( c->c ) );
00784 Q_ASSERT( pixelww < 65535 );
00785 d->m_screenWidths[ unicode ] = pixelww;
00786 }
00787 }
00788 }
00789 else {
00790 pixelww = this->refFontMetrics().width( displayedChar( c->c ) );
00791 }
00792 }
00793 else {
00794
00795 bool smallCaps = ( attributeFont() == KoTextFormat::ATT_SMALL_CAPS && c->c.upper() != c->c );
00796 const QFontMetrics& fontMetrics = smallCaps ? smallCapsFont( zh, applyZoom ) : applyZoom ? screenFontMetrics( zh ) : refFontMetrics();
00797 QString str;
00798 int pos = 0;
00799 #ifndef INDIC
00800 if( i > 4 )
00801 pos = i - 4;
00802 #else
00803 if( i > 8 )
00804 pos = i - 8;
00805 #endif
00806 int off = i - pos;
00807 #ifndef INDIC
00808 int end = QMIN( parag->length(), i + 4 );
00809 #else
00810 int end = QMIN( parag->length(), i + 8 );
00811 #endif
00812 while ( pos < end ) {
00813 str += displayedChar( parag->at(pos)->c );
00814 pos++;
00815 }
00816 pixelww = fontMetrics.charWidth( str, off );
00817 }
00818
00819 #if 0
00820
00821
00822
00823 if ( d->m_shadowDistanceX != 0 )
00824 {
00825
00826 int shadowpix = (int)(POINT_TO_INCH( static_cast<double>( QPaintDevice::x11AppDpiX() ) ) * QABS( d->m_shadowDistanceX ) );
00827
00828
00829
00830 pixelww += applyZoom ? ( shadowpix * zh->zoom() / 100 ) : shadowpix;
00831 }
00832 #endif
00833
00834 #if 0
00835 kdDebug(32500) << "KoTextFormat::charWidth: char=" << QString(c->c) << " format=" << key()
00836 << ", applyZoom=" << applyZoom << " pixel-width=" << pixelww << endl;
00837 #endif
00838 return pixelww;
00839 }
00840
00841 int KoTextFormat::height() const
00842 {
00843 if ( d->m_refHeight < 0 )
00844 {
00845
00846 int h = refFontMetrics().height()+QABS(offsetFromBaseLine());
00847 if ( vAlign() == KoTextFormat::AlignSuperScript )
00848 h += refFontMetrics().height()/2;
00849 else if ( vAlign() == KoTextFormat::AlignSubScript )
00850 h += refFontMetrics().height()/6;
00851
00852
00853 if ( d->m_shadowDistanceY != 0 ) {
00854
00855 h += (int)(POINT_TO_INCH( static_cast<double>( QPaintDevice::x11AppDpiY() ) ) * QABS( d->m_shadowDistanceY ) );
00856 }
00857
00858
00859
00860 d->m_refHeight = qRound( KoTextZoomHandler::ptToLayoutUnitPt( h ) );
00861 }
00862 return d->m_refHeight;
00863 }
00864
00865 int KoTextFormat::offsetX() const
00866 {
00867 int off = 0;
00868 #if 0
00869
00870
00871
00872 if ( d->m_shadowDistanceX < 0 )
00873 {
00874 double lupt = KoTextZoomHandler::ptToLayoutUnitPt( QABS( d->m_shadowDistanceX ) );
00875 off += (int)(POINT_TO_INCH( static_cast<double>( QPaintDevice::x11AppDpiX() ) ) * lupt );
00876 }
00877 #endif
00878 return off;
00879 }
00880
00881 int KoTextFormat::offsetY() const
00882 {
00883 int off = 0;
00884 #if 0
00885
00886 if ( d->m_shadowDistanceY < 0 )
00887 {
00888 double lupt = KoTextZoomHandler::ptToLayoutUnitPt( QABS( d->m_shadowDistanceY ) );
00889 off += (int)(POINT_TO_INCH( static_cast<double>( QPaintDevice::x11AppDpiY() ) ) * lupt );
00890 }
00891 #endif
00892 return off;
00893 }
00894
00895 QString KoTextFormat::displayedString( const QString& str )const
00896 {
00897 switch ( m_attributeFont ) {
00898 case ATT_NONE:
00899 return str;
00900 case ATT_UPPER:
00901 case ATT_SMALL_CAPS:
00902 return str.upper();
00903 case ATT_LOWER:
00904 return str.lower();
00905 default:
00906 kdDebug(32500)<<" Error in AttributeStyle \n";
00907 return str;
00908 }
00909 }
00910
00911 QChar KoTextFormat::displayedChar( QChar c )const
00912 {
00913 if ( c.unicode() == 0xa0 )
00914 return ' ';
00915 switch ( m_attributeFont ) {
00916 case ATT_NONE:
00917 return c;
00918 case ATT_SMALL_CAPS:
00919 case ATT_UPPER:
00920 return c.upper();
00921 case ATT_LOWER:
00922 return c.lower();
00923 default:
00924 kdDebug(32500)<<" Error in AttributeStyle \n";
00925 return c;
00926 }
00927 }
00928
00929 int KoTextFormat::ascent() const
00930 {
00931 if ( d->m_refAscent < 0 )
00932 {
00933
00934 int h = refFontMetrics().ascent();
00935 if ( offsetFromBaseLine()>0 )
00936 h += offsetFromBaseLine();
00937 if ( vAlign() == KoTextFormat::AlignSuperScript )
00938 h += refFontMetrics().height()/2;
00939
00940 d->m_refAscent = qRound( KoTextZoomHandler::ptToLayoutUnitPt( h ) );
00941
00942 }
00943 return d->m_refAscent;
00944 }
00945
00946 int KoTextFormat::descent() const
00947 {
00948 if ( d->m_refDescent < 0 )
00949 {
00950
00951 int h = refFontMetrics().descent();
00952 if ( offsetFromBaseLine()<0 )
00953 h -= offsetFromBaseLine();
00954
00955 d->m_refDescent = qRound( KoTextZoomHandler::ptToLayoutUnitPt( h ) );
00956
00957 }
00958 return d->m_refDescent;
00959 }
00960
00961 int KoTextFormat::charWidthLU( const KoTextStringChar* c, const KoTextParag* parag, int i ) const
00962 {
00963
00964
00965 return KoTextZoomHandler::ptToLayoutUnitPt( charWidth( 0L, false, c, parag, i ) );
00966 }
00967
00968 int KoTextFormat::width( const QChar& ch ) const
00969 {
00970
00971 return KoTextZoomHandler::ptToLayoutUnitPt( refFontMetrics().width( ch ) );
00972 }
00973
00974 void KoTextFormat::applyCharStyle( KoCharStyle *_style )
00975 {
00976 d->m_charStyle = _style;
00977 }
00978
00979 KoCharStyle *KoTextFormat::style() const
00980 {
00981 return d->m_charStyle;
00982 }
00983
00984 QString KoTextFormat::shadowAsCss( double shadowDistanceX, double shadowDistanceY, const QColor& shadowColor )
00985 {
00986
00987
00988
00989 if ( shadowDistanceX != 0 || shadowDistanceY != 0 )
00990 {
00991 QString css = shadowColor.name() + " ";
00992 css += QString::number(shadowDistanceX) + "pt ";
00993 css += QString::number(shadowDistanceY) + "pt";
00994 return css;
00995 }
00996 return "none";
00997 }
00998
00999 QString KoTextFormat::shadowAsCss() const
01000 {
01001 return shadowAsCss( d->m_shadowDistanceX, d->m_shadowDistanceY, d->m_shadowColor );
01002 }
01003
01004 void KoTextFormat::parseShadowFromCss( const QString& _css )
01005 {
01006 QString css = _css.simplifyWhiteSpace();
01007 if ( css.isEmpty() || css == "none" )
01008 {
01009 d->m_shadowDistanceX = 0;
01010 d->m_shadowDistanceY = 0;
01011 d->m_shadowColor = QColor();
01012 } else
01013 {
01014 QStringList tokens = QStringList::split(' ', css);
01015 if ( tokens.isEmpty() ) {
01016 kdWarning(32500) << "Parse error in text-shadow: " << css << endl;
01017 return;
01018 }
01019
01020 QColor col( tokens.first() );
01021 if ( col.isValid() )
01022 tokens.pop_front();
01023 else if ( tokens.count() > 1 )
01024 {
01025 col.setNamedColor( tokens.last() );
01026 if ( col.isValid() )
01027 tokens.pop_back();
01028 }
01029 d->m_shadowColor = col;
01030
01031 if ( !tokens.isEmpty() ) {
01032 d->m_shadowDistanceX = KoUnit::parseValue( tokens.first() );
01033 tokens.pop_front();
01034 }
01035
01036 if ( !tokens.isEmpty() ) {
01037 d->m_shadowDistanceY = KoUnit::parseValue( tokens.first() );
01038 tokens.pop_front();
01039 }
01040
01041 }
01042 update();
01043 }
01044
01045 QColor KoTextFormat::shadowColor() const
01046 {
01047 if ( d->m_shadowColor.isValid() )
01048 return d->m_shadowColor;
01049 else
01050 return col;
01051 }
01052
01053 int KoTextFormat::shadowX( KoZoomHandler *zh ) const
01054 {
01055 return zh->zoomItX( d->m_shadowDistanceX );
01056 }
01057
01058 int KoTextFormat::shadowY( KoZoomHandler *zh ) const
01059 {
01060 return zh->zoomItY( d->m_shadowDistanceY );
01061 }
01062
01063
01064 QString KoTextFormat::underlineStyleToString( KoTextFormat::UnderlineStyle _lineType )
01065 {
01066 QString strLineType;
01067 switch ( _lineType )
01068 {
01069 case KoTextFormat::U_SOLID:
01070 strLineType ="solid";
01071 break;
01072 case KoTextFormat::U_DASH:
01073 strLineType ="dash";
01074 break;
01075 case KoTextFormat::U_DOT:
01076 strLineType ="dot";
01077 break;
01078 case KoTextFormat::U_DASH_DOT:
01079 strLineType="dashdot";
01080 break;
01081 case KoTextFormat::U_DASH_DOT_DOT:
01082 strLineType="dashdotdot";
01083 break;
01084 }
01085 return strLineType;
01086 }
01087
01088 QString KoTextFormat::strikeOutStyleToString( KoTextFormat::StrikeOutStyle _lineType )
01089 {
01090 QString strLineType;
01091 switch ( _lineType )
01092 {
01093 case KoTextFormat::S_SOLID:
01094 strLineType ="solid";
01095 break;
01096 case KoTextFormat::S_DASH:
01097 strLineType ="dash";
01098 break;
01099 case KoTextFormat::S_DOT:
01100 strLineType ="dot";
01101 break;
01102 case KoTextFormat::S_DASH_DOT:
01103 strLineType="dashdot";
01104 break;
01105 case KoTextFormat::S_DASH_DOT_DOT:
01106 strLineType="dashdotdot";
01107 break;
01108 }
01109 return strLineType;
01110 }
01111
01112 KoTextFormat::UnderlineStyle KoTextFormat::stringToUnderlineStyle( const QString & _str )
01113 {
01114 if ( _str =="solid")
01115 return KoTextFormat::U_SOLID;
01116 else if ( _str =="dash" )
01117 return KoTextFormat::U_DASH;
01118 else if ( _str =="dot" )
01119 return KoTextFormat::U_DOT;
01120 else if ( _str =="dashdot")
01121 return KoTextFormat::U_DASH_DOT;
01122 else if ( _str=="dashdotdot")
01123 return KoTextFormat::U_DASH_DOT_DOT;
01124 else
01125 return KoTextFormat::U_SOLID;
01126 }
01127
01128 KoTextFormat::StrikeOutStyle KoTextFormat::stringToStrikeOutStyle( const QString & _str )
01129 {
01130 if ( _str =="solid")
01131 return KoTextFormat::S_SOLID;
01132 else if ( _str =="dash" )
01133 return KoTextFormat::S_DASH;
01134 else if ( _str =="dot" )
01135 return KoTextFormat::S_DOT;
01136 else if ( _str =="dashdot")
01137 return KoTextFormat::S_DASH_DOT;
01138 else if ( _str=="dashdotdot")
01139 return KoTextFormat::S_DASH_DOT_DOT;
01140 else
01141 return KoTextFormat::S_SOLID;
01142 }
01143
01144 QString KoTextFormat::attributeFontToString( KoTextFormat::AttributeStyle _attr )
01145 {
01146 if (_attr == KoTextFormat::ATT_NONE )
01147 return QString("none");
01148 else if ( _attr == KoTextFormat::ATT_UPPER )
01149 return QString("uppercase");
01150 else if ( _attr == KoTextFormat::ATT_LOWER )
01151 return QString("lowercase");
01152 else if ( _attr == KoTextFormat::ATT_SMALL_CAPS )
01153 return QString("smallcaps");
01154 else
01155 return QString("none");
01156 }
01157
01158 KoTextFormat::AttributeStyle KoTextFormat::stringToAttributeFont( const QString & _str )
01159 {
01160 if ( _str == "none" )
01161 return KoTextFormat::ATT_NONE;
01162 else if ( _str == "uppercase")
01163 return KoTextFormat::ATT_UPPER;
01164 else if ( _str == "lowercase")
01165 return KoTextFormat::ATT_LOWER;
01166 else if ( _str == "smallcaps" )
01167 return KoTextFormat::ATT_SMALL_CAPS;
01168 else
01169 return KoTextFormat::ATT_NONE;
01170 }
01171
01172
01173 void KoTextFormat::setHyphenation( bool b )
01174 {
01175 if ( d->m_bHyphenation == b )
01176 return;
01177 d->m_bHyphenation = b;
01178 update();
01179
01180 }
01181
01182 void KoTextFormat::setUnderLineWidth( double ulw )
01183 {
01184 if ( d->m_underLineWidth == ulw )
01185 return;
01186 d->m_underLineWidth = ulw;
01187 update();
01188
01189 }
01190
01191 void KoTextFormat::setLanguage( const QString & _lang)
01192 {
01193 if ( m_language == _lang )
01194 return;
01195 m_language = _lang;
01196 update();
01197 }
01198
01199 QStringList KoTextFormat::underlineTypeList()
01200 {
01201 QStringList lst;
01202 lst <<i18n("Without");
01203 lst <<i18n("Single");
01204 lst <<i18n("Simple Bold");
01205 lst <<i18n("Double");
01206 lst <<i18n("Wave");
01207 return lst;
01208 }
01209
01210 QStringList KoTextFormat::strikeOutTypeList()
01211 {
01212 QStringList lst;
01213 lst <<i18n("Without");
01214 lst <<i18n("Single");
01215 lst <<i18n("Simple Bold");
01216 lst <<i18n("Double");
01217 return lst;
01218 }
01219
01220 QStringList KoTextFormat::fontAttributeList()
01221 {
01222 QStringList lst;
01223 lst <<i18n("Normal");
01224 lst <<i18n("Uppercase");
01225 lst <<i18n("Lowercase");
01226 lst <<i18n("Small Caps");
01227 return lst;
01228 }
01229
01230 QStringList KoTextFormat::underlineStyleList()
01231 {
01232 QStringList lst;
01233 lst <<i18n("Solid Line");
01234 lst <<i18n("Dash Line");
01235 lst <<i18n("Dot Line");
01236 lst <<i18n("Dash Dot Line");
01237 lst <<i18n("Dash Dot Dot Line");
01238 return lst;
01239 }
01240
01241 QStringList KoTextFormat::strikeOutStyleList()
01242 {
01243 QStringList lst;
01244 lst <<i18n("Solid Line");
01245 lst <<i18n("Dash Line");
01246 lst <<i18n("Dot Line");
01247 lst <<i18n("Dash Dot Line");
01248 lst <<i18n("Dash Dot Dot Line");
01249 return lst;
01250 }
01251
01252
01253 #ifndef NDEBUG
01254 void KoTextFormat::printDebug()
01255 {
01256 QString col = color().isValid() ? color().name() : QString("(default)");
01257 kdDebug(32500) << "format '" << key() << "' (" << (void*)this << "):"
01258 << " refcount: " << ref
01259 << " realfont: " << QFontInfo( font() ).family()
01260 << " color: " << col << " shadow=" << shadowAsCss() << endl;
01261 }
01262 #endif
01263
01265
01266 KoTextFormatCollection::KoTextFormatCollection()
01267 : cKey( 307 )
01268 {
01269 #ifdef DEBUG_COLLECTION
01270 kdDebug(32500) << "KoTextFormatCollection::KoTextFormatCollection " << this << endl;
01271 #endif
01272 defFormat = new KoTextFormat( QApplication::font(), QColor(), KGlobal::locale()->language(), false, 1.0 );
01273 lastFormat = cres = 0;
01274 cflags = -1;
01275 cKey.setAutoDelete( TRUE );
01276 cachedFormat = 0;
01277 }
01278
01279 KoTextFormatCollection::KoTextFormatCollection( const QFont& defaultFont, const QColor& defaultColor, const QString & defaultLanguage, bool hyphen, double ulw )
01280 : cKey( 307 )
01281 {
01282 #ifdef DEBUG_COLLECTION
01283 kdDebug(32500) << "KoTextFormatCollection::KoTextFormatCollection " << this << endl;
01284 #endif
01285 defFormat = new KoTextFormat( defaultFont, defaultColor, defaultLanguage, hyphen, ulw );
01286 lastFormat = cres = 0;
01287 cflags = -1;
01288 cKey.setAutoDelete( TRUE );
01289 cachedFormat = 0;
01290 }
01291
01292 KoTextFormatCollection::~KoTextFormatCollection()
01293 {
01294 #ifdef DEBUG_COLLECTION
01295 kdDebug(32500) << "KoTextFormatCollection::~KoTextFormatCollection " << this << endl;
01296 #endif
01297 delete defFormat;
01298 defFormat = 0;
01299 }
01300
01301 KoTextFormat *KoTextFormatCollection::format( const KoTextFormat *f )
01302 {
01303 if ( f->parent() == this || f == defFormat ) {
01304 #ifdef DEBUG_COLLECTION
01305 kdDebug(32500) << " format(f) need '" << f->key() << "', best case!" << endl;
01306 #endif
01307 lastFormat = const_cast<KoTextFormat*>(f);
01308 lastFormat->addRef();
01309 return lastFormat;
01310 }
01311
01312 if ( f == lastFormat || ( lastFormat && f->key() == lastFormat->key() ) ) {
01313 #ifdef DEBUG_COLLECTION
01314 kdDebug(32500) << " format(f) need '" << f->key() << "', good case!" << endl;
01315 #endif
01316 lastFormat->addRef();
01317 return lastFormat;
01318 }
01319
01320 #if 0 // #### disabled, because if this format is not in the
01321
01322
01323
01324 if ( f->isAnchor() ) {
01325 lastFormat = createFormat( *f );
01326 lastFormat->collection = 0;
01327 return lastFormat;
01328 }
01329 #endif
01330
01331 KoTextFormat *fm = cKey.find( f->key() );
01332 if ( fm ) {
01333 #ifdef DEBUG_COLLECTION
01334 kdDebug(32500) << " format(f) need '" << f->key() << "', normal case!" << endl;
01335 #endif
01336 lastFormat = fm;
01337 lastFormat->addRef();
01338 return lastFormat;
01339 }
01340
01341 if ( f->key() == defFormat->key() )
01342 return defFormat;
01343
01344 #ifdef DEBUG_COLLECTION
01345 kdDebug(32500) << " format(f) need '" << f->key() << "', worst case!" << endl;
01346 #endif
01347 lastFormat = createFormat( *f );
01348 lastFormat->collection = this;
01349 cKey.insert( lastFormat->key(), lastFormat );
01350 Q_ASSERT( f->key() == lastFormat->key() );
01351 return lastFormat;
01352 }
01353
01354 KoTextFormat *KoTextFormatCollection::format( const KoTextFormat *of, const KoTextFormat *nf, int flags )
01355 {
01356 if ( cres && kof == of->key() && knf == nf->key() && cflags == flags ) {
01357 #ifdef DEBUG_COLLECTION
01358 kdDebug(32500) << " format(of,nf,flags) mix of '" << of->key() << "' and '" << nf->key() << "', best case!" << endl;
01359 #endif
01360 cres->addRef();
01361 return cres;
01362 }
01363
01364 #ifdef DEBUG_COLLECTION
01365 kdDebug(32500) << " format(of,nf," << flags << ") calling createFormat(of=" << of << " " << of->key() << ")" << endl;
01366 #endif
01367 cres = createFormat( *of );
01368 kof = of->key();
01369 knf = nf->key();
01370 cflags = flags;
01371
01372 #ifdef DEBUG_COLLECTION
01373 kdDebug(32500) << " format(of,nf," << flags << ") calling copyFormat(nf=" << nf << " " << nf->key() << ")" << endl;
01374 #endif
01375 cres->copyFormat( *nf, flags );
01376
01377 KoTextFormat *fm = cKey.find( cres->key() );
01378 if ( !fm ) {
01379 #ifdef DEBUG_COLLECTION
01380 kdDebug(32500) << " format(of,nf,flags) mix of '" << of->key() << "' and '" << nf->key() << ", worst case!" << endl;
01381 #endif
01382 cres->collection = this;
01383 cKey.insert( cres->key(), cres );
01384 } else {
01385 #ifdef DEBUG_COLLECTION
01386 kdDebug(32500) << " format(of,nf,flags) mix of '" << of->key() << "' and '" << nf->key() << ", good case!" << endl;
01387 #endif
01388 delete cres;
01389 cres = fm;
01390 cres->addRef();
01391 }
01392
01393 return cres;
01394 }
01395
01396 KoTextFormat *KoTextFormatCollection::format( const QFont &f, const QColor &c, const QString & language, bool hyphen, double ulw )
01397 {
01398 if ( cachedFormat && cfont == f && ccol == c ) {
01399 #ifdef DEBUG_COLLECTION
01400 kdDebug(32500) << " format of font and col '" << cachedFormat->key() << "' - best case" << endl;
01401 #endif
01402 cachedFormat->addRef();
01403 return cachedFormat;
01404 }
01405
01406 QString key = KoTextFormat::getKey( f, c, FALSE, KoTextFormat::AlignNormal );
01407 cachedFormat = cKey.find( key );
01408 cfont = f;
01409 ccol = c;
01410
01411 if ( cachedFormat ) {
01412 #ifdef DEBUG_COLLECTION
01413 kdDebug(32500) << " format of font and col '" << cachedFormat->key() << "' - good case" << endl;
01414 #endif
01415 cachedFormat->addRef();
01416 return cachedFormat;
01417 }
01418
01419 if ( key == defFormat->key() )
01420 return defFormat;
01421
01422 cachedFormat = createFormat( f, c,language, hyphen, ulw );
01423 cachedFormat->collection = this;
01424 cKey.insert( cachedFormat->key(), cachedFormat );
01425 if ( cachedFormat->key() != key )
01426 kdWarning() << "ASSERT: keys for format not identical: '" << cachedFormat->key() << " '" << key << "'" << endl;
01427 #ifdef DEBUG_COLLECTION
01428 kdDebug(32500) << " format of font and col '" << cachedFormat->key() << "' - worst case" << endl;
01429 #endif
01430 return cachedFormat;
01431 }
01432
01433 void KoTextFormatCollection::remove( KoTextFormat *f )
01434 {
01435 if ( lastFormat == f )
01436 lastFormat = 0;
01437 if ( cres == f )
01438 cres = 0;
01439 if ( cachedFormat == f )
01440 cachedFormat = 0;
01441 cKey.remove( f->key() );
01442 }
01443
01444 #if 0
01445 void KoTextFormatCollection::setPainter( QPainter *p )
01446 {
01447 QDictIterator<KoTextFormat> it( cKey );
01448 KoTextFormat *f;
01449 while ( ( f = it.current() ) ) {
01450 ++it;
01451 f->setPainter( p );
01452 }
01453 }
01454 #endif
01455
01456 #ifndef NDEBUG
01457 void KoTextFormatCollection::debug()
01458 {
01459 kdDebug(32500) << "------------ KoTextFormatCollection: debug --------------- BEGIN" << endl;
01460 kdDebug(32500) << "Default Format: '" << defFormat->key() << "' (" << (void*)defFormat << "): realfont: " << QFontInfo( defFormat->font() ).family() << endl;
01461 QDictIterator<KoTextFormat> it( cKey );
01462 for ( ; it.current(); ++it ) {
01463 Q_ASSERT(it.currentKey() == it.current()->key());
01464 if(it.currentKey() != it.current()->key())
01465 kdDebug(32500) << "**** MISMATCH key=" << it.currentKey() << " (see line below for format)" << endl;
01466 it.current()->printDebug();
01467 }
01468 kdDebug(32500) << "------------ KoTextFormatCollection: debug --------------- END" << endl;
01469 }
01470
01471 #endif