00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <qfont.h>
00022
#include <qfontmetrics.h>
00023
#include <qpainter.h>
00024
00025
#include <kdebug.h>
00026
00027
#include "basicelement.h"
00028
#include "contextstyle.h"
00029
#include "elementtype.h"
00030
#include "sequenceelement.h"
00031
#include "sequenceparser.h"
00032
#include "textelement.h"
00033
00034
00035 KFORMULA_NAMESPACE_BEGIN
00036
00037
int ElementType::evilDestructionCount = 0;
00038
00039
00040
00041
00042
00043
QString format2variant( CharStyle style, CharFamily family )
00044 {
00045
QString result;
00046
00047
switch( family ) {
00048
case normalFamily:
00049
case anyFamily:
00050
switch( style ) {
00051
case normalChar:
00052 result =
"normal";
break;
00053
case boldChar:
00054 result =
"bold";
break;
00055
case italicChar:
00056 result =
"italic";
break;
00057
case boldItalicChar:
00058 result =
"bold-italic";
break;
00059
case anyChar:
00060
break;
00061 }
00062
break;
00063
case scriptFamily:
00064 result =
"script";
00065
if ( style == boldChar || style == boldItalicChar )
00066 result =
"bold-" + result;
00067
break;
00068
case frakturFamily:
00069 result =
"fraktur";
00070
if ( style == boldChar || style == boldItalicChar )
00071 result =
"bold-" + result;
00072
break;
00073
case doubleStruckFamily:
00074 result =
"double-struck";
break;
00075 }
00076
00077
return result;
00078 }
00079
00080 ElementType::ElementType(
SequenceParser* parser )
00081 : from( parser->getStart() ), to( parser->getEnd() ), prev( 0 )
00082 {
00083 evilDestructionCount++;
00084 }
00085
00086 ElementType::~ElementType()
00087 {
00088
delete prev;
00089 evilDestructionCount--;
00090 }
00091
00092
00093 QString ElementType::text(
SequenceElement* seq )
const
00094
{
00095
QString str;
00096
for ( uint i=
start(); i<
end(); ++i ) {
00097 str.append( seq->
getChild( i )->
getCharacter() );
00098 }
00099
return str;
00100 }
00101
00102
00103 luPt
ElementType::getSpaceBefore(
const ContextStyle&,
00104 ContextStyle::TextStyle )
00105 {
00106
return 0;
00107 }
00108
00109 luPt ElementType::getSpaceAfter(
MultiElementType*,
00110
const ContextStyle&,
00111 ContextStyle::TextStyle )
00112 {
00113
return 0;
00114 }
00115
00116 luPt ElementType::getSpaceAfter( OperatorType*,
00117
const ContextStyle&,
00118 ContextStyle::TextStyle )
00119 {
00120
return 0;
00121 }
00122
00123 luPt ElementType::getSpaceAfter( RelationType*,
00124
const ContextStyle&,
00125 ContextStyle::TextStyle )
00126 {
00127
return 0;
00128 }
00129
00130 luPt ElementType::getSpaceAfter( PunctuationType*,
00131
const ContextStyle&,
00132 ContextStyle::TextStyle )
00133 {
00134
return 0;
00135 }
00136
00137 luPt ElementType::getSpaceAfter( BracketType*,
00138
const ContextStyle&,
00139 ContextStyle::TextStyle )
00140 {
00141
return 0;
00142 }
00143
00144 luPt ElementType::getSpaceAfter( ComplexElementType*,
00145
const ContextStyle&,
00146 ContextStyle::TextStyle )
00147 {
00148
return 0;
00149 }
00150
00151 luPt ElementType::getSpaceAfter( InnerElementType*,
00152
const ContextStyle&,
00153 ContextStyle::TextStyle )
00154 {
00155
return 0;
00156 }
00157
00158 luPt ElementType::thinSpaceIfNotScript(
const ContextStyle& context,
00159 ContextStyle::TextStyle tstyle )
00160 {
00161
if ( !context.
isScript( tstyle ) ) {
00162
return context.
getThinSpace( tstyle );
00163 }
00164
return 0;
00165 }
00166
00167 luPt ElementType::mediumSpaceIfNotScript(
const ContextStyle& context,
00168 ContextStyle::TextStyle tstyle )
00169 {
00170
if ( !context.
isScript( tstyle ) ) {
00171
return context.
getMediumSpace( tstyle );
00172 }
00173
return 0;
00174 }
00175
00176 luPt ElementType::thickSpaceIfNotScript(
const ContextStyle& context,
00177 ContextStyle::TextStyle tstyle )
00178 {
00179
if ( !context.
isScript( tstyle ) ) {
00180
return context.
getThickSpace( tstyle );
00181 }
00182
return 0;
00183 }
00184
00185
00186 QFont ElementType::getFont(
const ContextStyle& context)
00187 {
00188
return context.
getDefaultFont();
00189 }
00190
00191 void ElementType::setUpPainter(
const ContextStyle& context,
QPainter& painter)
00192 {
00193 painter.setPen(context.
getDefaultColor());
00194 }
00195
00196 void ElementType::append(
ElementType* element )
00197 {
00198 element->
prev =
this;
00199 }
00200
00201
void ElementType::output()
00202 {
00203 kdDebug( DEBUGID ) <<
start() <<
" - " <<
end() << endl;
00204 }
00205
00206
void ElementType::saveMathML(
SequenceElement* se,
QDomDocument doc,
QDomElement de )
00207 {
00208
for ( uint i = from; i < to; ++i ) {
00209 se->
getChild( i )->
writeMathML( doc, de );
00210 }
00211 }
00212
00213
00214 SequenceType::SequenceType(
SequenceParser* parser )
00215 :
ElementType( parser ), last( 0 )
00216 {
00217
while (
true ) {
00218 parser->
nextToken();
00219
00220
00221
if ( parser->
getTokenType() == END ) {
00222
break;
00223 }
00224
ElementType* nextType = parser->
getPrimitive();
00225
if ( nextType == 0 ) {
00226
break;
00227 }
00228
if ( last != 0 ) {
00229 last->append( nextType );
00230 }
00231 last = nextType;
00232 }
00233 }
00234
00235 SequenceType::~SequenceType()
00236 {
00237
delete last;
00238 }
00239
00240
00241
void SequenceType::output()
00242 {
00243 }
00244
00245
00246 MultiElementType::MultiElementType(
SequenceParser* parser )
00247 :
ElementType( parser )
00248 {
00249
for ( uint i =
start(); i <
end(); i++ ) {
00250 parser->
setElementType( i,
this );
00251 }
00252 m_text = parser->
text();
00253 }
00254
00255
00256 luPt
MultiElementType::getSpaceBefore(
const ContextStyle& context,
00257 ContextStyle::TextStyle tstyle )
00258 {
00259
if ( getPrev() != 0 ) {
00260
return getPrev()->
getSpaceAfter(
this, context, tstyle );
00261 }
00262
return 0;
00263 }
00264
00265 luPt MultiElementType::getSpaceAfter( OperatorType*,
00266
const ContextStyle& context,
00267 ContextStyle::TextStyle tstyle )
00268 {
00269
return mediumSpaceIfNotScript( context, tstyle );
00270 }
00271
00272 luPt MultiElementType::getSpaceAfter( RelationType*,
00273
const ContextStyle& context,
00274 ContextStyle::TextStyle tstyle )
00275 {
00276
return thickSpaceIfNotScript( context, tstyle );
00277 }
00278
00279 luPt MultiElementType::getSpaceAfter( InnerElementType*,
00280
const ContextStyle& context,
00281 ContextStyle::TextStyle tstyle )
00282 {
00283
return thinSpaceIfNotScript( context, tstyle );
00284 }
00285
00286
00287 TextType::TextType(
SequenceParser* parser )
00288 :
MultiElementType( parser )
00289 {
00290 }
00291
00292
void TextType::saveMathML(
SequenceElement* se,
QDomDocument doc,
QDomElement de )
00293 {
00294
for ( uint i =
start(); i <
end(); ++i ) {
00295
QDomElement text = doc.createElement(
"mi" );
00296
BasicElement* be = se->
getChild( i );
00297
TextElement* te = static_cast<TextElement*>( be );
00298
QString mathvariant = format2variant( te->
getCharStyle(), te->
getCharFamily());
00299
if ( !mathvariant.isNull() )
00300 text.setAttribute(
"mathvariant", mathvariant );
00301
if ( be->
getCharacter().latin1() != 0 ) {
00302
00303 text.appendChild( doc.createTextNode( be->
getCharacter() ) );
00304 }
00305
else {
00306
00307
QString s;
00308 text.appendChild( doc.createEntityReference( s.sprintf(
"#x%05X", be->
getCharacter().unicode() ) ) );
00309 }
00310
00311 de.appendChild( text );
00312
if ( i !=
end() - 1 ) {
00313
QDomElement op = doc.createElement(
"mo" );
00314 op.appendChild( doc.createEntityReference(
"InvisibleTimes" ) );
00315 de.appendChild( op );
00316 }
00317 }
00318 }
00319
00320
00321 NameType::NameType(
SequenceParser* parser )
00322 :
MultiElementType( parser )
00323 {
00324 }
00325
00326
void NameType::saveMathML(
SequenceElement* se,
QDomDocument doc,
QDomElement de )
00327 {
00328 se->
getChild(
start() )->
writeMathML( doc, de );
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 }
00341
00342
00343 QFont NameType::getFont(
const ContextStyle& context)
00344 {
00345
return context.
getNameFont();
00346 }
00347
00348 NumberType::NumberType(
SequenceParser* parser )
00349 :
MultiElementType( parser )
00350 {
00351 }
00352
00353 QFont NumberType::getFont(
const ContextStyle& context)
00354 {
00355
return context.
getNumberFont();
00356 }
00357
00358 void NumberType::setUpPainter(
const ContextStyle& context,
QPainter& painter)
00359 {
00360 painter.setPen(context.
getNumberColor());
00361 }
00362
00363
void NumberType::saveMathML(
SequenceElement* se,
QDomDocument doc,
QDomElement de )
00364 {
00365
QDomElement name = doc.createElement(
"mn" );
00366
QString value;
00367
for ( uint i =
start(); i <
end(); ++i ) {
00368
BasicElement* be = se->
getChild( i );
00369 value += be->
getCharacter();
00370 }
00371
TextElement* te = static_cast<TextElement*>( se->
getChild(
start() ) );
00372
QString mathvariant = format2variant( te->
getCharStyle(), te->
getCharFamily() );
00373
if ( !mathvariant.isNull() )
00374 name.setAttribute(
"mathvariant", mathvariant );
00375
00376 name.appendChild( doc.createTextNode( value ) );
00377 de.appendChild( name );
00378 }
00379
00380
00381 SingleElementType::SingleElementType(
SequenceParser* parser )
00382 :
ElementType( parser )
00383 {
00384 parser->
setElementType(
start(),
this );
00385 }
00386
00387 AbstractOperatorType::AbstractOperatorType(
SequenceParser* parser )
00388 :
SingleElementType( parser )
00389 {
00390 }
00391
00392
void AbstractOperatorType::saveMathML(
SequenceElement* se,
QDomDocument doc,
QDomElement de )
00393 {
00394
QDomElement op = doc.createElement(
"mo" );
00395
BasicElement* be = se->
getChild(
start() );
00396
if ( be->
getCharacter().latin1() != 0 ) {
00397
00398 op.appendChild( doc.createTextNode( be->
getCharacter() ) );
00399 }
00400
else {
00401
00402
QString s;
00403 op.appendChild( doc.createEntityReference( s.sprintf(
"#x%05X", be->
getCharacter().unicode() ) ) );
00404 }
00405
TextElement* te = static_cast<TextElement*>( be );
00406
QString mathvariant = format2variant( te->
getCharStyle(), te->
getCharFamily() );
00407
if ( !mathvariant.isNull() )
00408 op.setAttribute(
"mathvariant", mathvariant );
00409
00410 de.appendChild( op );
00411 }
00412
00413 OperatorType::OperatorType(
SequenceParser* parser )
00414 : AbstractOperatorType( parser )
00415 {
00416 }
00417
00418 luPt OperatorType::getSpaceBefore(
const ContextStyle& context,
00419 ContextStyle::TextStyle tstyle )
00420 {
00421
if ( getPrev() != 0 ) {
00422
return getPrev()->
getSpaceAfter(
this, context, tstyle );
00423 }
00424
return 0;
00425 }
00426
00427 luPt OperatorType::getSpaceAfter(
MultiElementType*,
00428
const ContextStyle& context,
00429 ContextStyle::TextStyle tstyle )
00430 {
00431
return mediumSpaceIfNotScript( context, tstyle );
00432 }
00433
00434 luPt OperatorType::getSpaceAfter( BracketType*,
00435
const ContextStyle& context,
00436 ContextStyle::TextStyle tstyle )
00437 {
00438
return mediumSpaceIfNotScript( context, tstyle );
00439 }
00440
00441 luPt OperatorType::getSpaceAfter( ComplexElementType*,
00442
const ContextStyle& context,
00443 ContextStyle::TextStyle tstyle )
00444 {
00445
return mediumSpaceIfNotScript( context, tstyle );
00446 }
00447
00448 luPt OperatorType::getSpaceAfter( InnerElementType*,
00449
const ContextStyle& context,
00450 ContextStyle::TextStyle tstyle )
00451 {
00452
return mediumSpaceIfNotScript( context, tstyle );
00453 }
00454
00455
00456
QFont OperatorType::getFont(
const ContextStyle& context)
00457 {
00458
return context.
getOperatorFont();
00459 }
00460
00461
void OperatorType::setUpPainter(
const ContextStyle& context,
QPainter& painter)
00462 {
00463 painter.setPen(context.
getOperatorColor());
00464 }
00465
00466
00467 RelationType::RelationType(
SequenceParser* parser )
00468 : AbstractOperatorType( parser )
00469 {
00470 }
00471
00472 luPt RelationType::getSpaceBefore(
const ContextStyle& context,
00473 ContextStyle::TextStyle tstyle )
00474 {
00475
if ( getPrev() != 0 ) {
00476
return getPrev()->
getSpaceAfter(
this, context, tstyle );
00477 }
00478
return 0;
00479 }
00480
00481 luPt RelationType::getSpaceAfter(
MultiElementType*,
00482
const ContextStyle& context,
00483 ContextStyle::TextStyle tstyle )
00484 {
00485
return thickSpaceIfNotScript( context, tstyle );
00486 }
00487
00488 luPt RelationType::getSpaceAfter( BracketType*,
00489
const ContextStyle& context,
00490 ContextStyle::TextStyle tstyle )
00491 {
00492
return thickSpaceIfNotScript( context, tstyle );
00493 }
00494
00495 luPt RelationType::getSpaceAfter( ComplexElementType*,
00496
const ContextStyle& context,
00497 ContextStyle::TextStyle tstyle )
00498 {
00499
return thickSpaceIfNotScript( context, tstyle );
00500 }
00501
00502 luPt RelationType::getSpaceAfter( InnerElementType*,
00503
const ContextStyle& context,
00504 ContextStyle::TextStyle tstyle )
00505 {
00506
return thickSpaceIfNotScript( context, tstyle );
00507 }
00508
00509
QFont RelationType::getFont(
const ContextStyle& context )
00510 {
00511
return context.
getOperatorFont();
00512 }
00513
00514
void RelationType::setUpPainter(
const ContextStyle& context,
QPainter& painter )
00515 {
00516 painter.setPen(context.
getOperatorColor());
00517 }
00518
00519
00520
00521 PunctuationType::PunctuationType(
SequenceParser* parser )
00522 : AbstractOperatorType( parser )
00523 {
00524 }
00525
00526 luPt PunctuationType::getSpaceBefore(
const ContextStyle& context,
00527 ContextStyle::TextStyle tstyle )
00528 {
00529
if ( getPrev() != 0 ) {
00530
return getPrev()->
getSpaceAfter(
this, context, tstyle );
00531 }
00532
return 0;
00533 }
00534
00535 luPt PunctuationType::getSpaceAfter(
MultiElementType*,
00536
const ContextStyle& context,
00537 ContextStyle::TextStyle tstyle )
00538 {
00539
return thinSpaceIfNotScript( context, tstyle );
00540 }
00541
00542 luPt PunctuationType::getSpaceAfter( RelationType*,
00543
const ContextStyle& context,
00544 ContextStyle::TextStyle tstyle )
00545 {
00546
return thickSpaceIfNotScript( context, tstyle );
00547 }
00548
00549 luPt PunctuationType::getSpaceAfter( PunctuationType*,
00550
const ContextStyle& context,
00551 ContextStyle::TextStyle tstyle )
00552 {
00553
return thinSpaceIfNotScript( context, tstyle );
00554 }
00555
00556 luPt PunctuationType::getSpaceAfter( BracketType*,
00557
const ContextStyle& context,
00558 ContextStyle::TextStyle tstyle )
00559 {
00560
return thinSpaceIfNotScript( context, tstyle );
00561 }
00562
00563 luPt PunctuationType::getSpaceAfter( ComplexElementType*,
00564
const ContextStyle& context,
00565 ContextStyle::TextStyle tstyle )
00566 {
00567
return thinSpaceIfNotScript( context, tstyle );
00568 }
00569
00570 luPt PunctuationType::getSpaceAfter( InnerElementType*,
00571
const ContextStyle& context,
00572 ContextStyle::TextStyle tstyle )
00573 {
00574
return thinSpaceIfNotScript( context, tstyle );
00575 }
00576
00577
QFont PunctuationType::getFont(
const ContextStyle& context )
00578 {
00579
return context.
getOperatorFont();
00580 }
00581
00582
void PunctuationType::setUpPainter(
const ContextStyle& context,
QPainter& painter )
00583 {
00584 painter.setPen( context.
getDefaultColor() );
00585 }
00586
00587
00588 BracketType::BracketType(
SequenceParser* parser )
00589 :
SingleElementType( parser )
00590 {
00591 }
00592
00593 luPt BracketType::getSpaceBefore(
const ContextStyle& context,
00594 ContextStyle::TextStyle tstyle )
00595 {
00596
if ( getPrev() != 0 ) {
00597
return getPrev()->
getSpaceAfter(
this, context, tstyle );
00598 }
00599
return 0;
00600 }
00601
00602 luPt BracketType::getSpaceAfter( OperatorType*,
00603
const ContextStyle& context,
00604 ContextStyle::TextStyle tstyle )
00605 {
00606
return mediumSpaceIfNotScript( context, tstyle );
00607 }
00608
00609 luPt BracketType::getSpaceAfter( RelationType*,
00610
const ContextStyle& context,
00611 ContextStyle::TextStyle tstyle )
00612 {
00613
return thickSpaceIfNotScript( context, tstyle );
00614 }
00615
00616 luPt BracketType::getSpaceAfter( InnerElementType*,
00617
const ContextStyle& context,
00618 ContextStyle::TextStyle tstyle )
00619 {
00620
return thinSpaceIfNotScript( context, tstyle );
00621 }
00622
00623
00624 ComplexElementType::ComplexElementType(
SequenceParser* parser )
00625 :
SingleElementType( parser )
00626 {
00627 }
00628
00629 luPt ComplexElementType::getSpaceBefore(
const ContextStyle& context,
00630 ContextStyle::TextStyle tstyle )
00631 {
00632
if ( getPrev() != 0 ) {
00633
return getPrev()->
getSpaceAfter(
this, context, tstyle );
00634 }
00635
return 0;
00636 }
00637
00638 luPt ComplexElementType::getSpaceAfter( OperatorType*,
00639
const ContextStyle& context,
00640 ContextStyle::TextStyle tstyle )
00641 {
00642
return mediumSpaceIfNotScript( context, tstyle );
00643 }
00644
00645 luPt ComplexElementType::getSpaceAfter( RelationType*,
00646
const ContextStyle& context,
00647 ContextStyle::TextStyle tstyle )
00648 {
00649
return thickSpaceIfNotScript( context, tstyle );
00650 }
00651
00652 luPt ComplexElementType::getSpaceAfter( InnerElementType*,
00653
const ContextStyle& context,
00654 ContextStyle::TextStyle tstyle )
00655 {
00656
return thinSpaceIfNotScript( context, tstyle );
00657 }
00658
00659
00660 InnerElementType::InnerElementType(
SequenceParser* parser )
00661 :
SingleElementType( parser )
00662 {
00663 }
00664
00665 luPt InnerElementType::getSpaceBefore(
const ContextStyle& context,
00666 ContextStyle::TextStyle tstyle )
00667 {
00668
if ( getPrev() != 0 ) {
00669
return getPrev()->
getSpaceAfter(
this, context, tstyle );
00670 }
00671
return 0;
00672 }
00673
00674 luPt InnerElementType::getSpaceAfter(
MultiElementType*,
00675
const ContextStyle& context,
00676 ContextStyle::TextStyle tstyle )
00677 {
00678
return thinSpaceIfNotScript( context, tstyle );
00679 }
00680
00681 luPt InnerElementType::getSpaceAfter( OperatorType*,
00682
const ContextStyle& context,
00683 ContextStyle::TextStyle tstyle )
00684 {
00685
return mediumSpaceIfNotScript( context, tstyle );
00686 }
00687
00688 luPt InnerElementType::getSpaceAfter( RelationType*,
00689
const ContextStyle& context,
00690 ContextStyle::TextStyle tstyle )
00691 {
00692
return thickSpaceIfNotScript( context, tstyle );
00693 }
00694
00695 luPt InnerElementType::getSpaceAfter( PunctuationType*,
00696
const ContextStyle& context,
00697 ContextStyle::TextStyle tstyle )
00698 {
00699
return thinSpaceIfNotScript( context, tstyle );
00700 }
00701
00702 luPt InnerElementType::getSpaceAfter( BracketType*,
00703
const ContextStyle& context,
00704 ContextStyle::TextStyle tstyle )
00705 {
00706
return thinSpaceIfNotScript( context, tstyle );
00707 }
00708
00709 luPt InnerElementType::getSpaceAfter( ComplexElementType*,
00710
const ContextStyle& context,
00711 ContextStyle::TextStyle tstyle )
00712 {
00713
return thinSpaceIfNotScript( context, tstyle );
00714 }
00715
00716 luPt InnerElementType::getSpaceAfter( InnerElementType*,
00717
const ContextStyle& context,
00718 ContextStyle::TextStyle tstyle )
00719 {
00720
return thinSpaceIfNotScript( context, tstyle );
00721 }
00722
00723
00724 KFORMULA_NAMESPACE_END