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