lib Library API Documentation

cmstyle.cc

00001 /* This file is part of the KDE project 00002 Copyright (C) 2003 Ulrich Kuettler <ulrich.kuettler@gmx.de> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00017 Boston, MA 02111-1307, USA. 00018 */ 00019 00020 #include <qpainter.h> 00021 #include <qpen.h> 00022 00023 #include <kdebug.h> 00024 #include <klocale.h> 00025 00026 #include "kformuladefs.h" 00027 #include "cmstyle.h" 00028 00029 00030 KFORMULA_NAMESPACE_BEGIN 00031 00032 #include "cmmapping.cc" 00033 00034 bool CMStyle::init( ContextStyle* context ) 00035 { 00036 SymbolTable* st = symbolTable(); 00037 st->init( context ); 00038 00039 SymbolTable::NameTable tempNames; 00040 fillNameTable( tempNames ); 00041 00042 st->initFont( cmbx10Map, "cmbx10", tempNames ); 00043 st->initFont( cmex10Map, "cmex10", tempNames ); 00044 st->initFont( cmmi10Map, "cmmi10", tempNames ); 00045 st->initFont( cmr10Map, "cmr10", tempNames ); 00046 st->initFont( cmsy10Map, "cmsy10", tempNames ); 00047 st->initFont( msam10Map, "msam10", tempNames ); 00048 st->initFont( msbm10Map, "msbm10", tempNames ); 00049 00050 return true; 00051 } 00052 00053 00054 const AlphaTable* CMStyle::alphaTable() const 00055 { 00056 return &m_alphaTable; 00057 } 00058 00059 00060 Artwork* CMStyle::createArtwork( SymbolType type ) const 00061 { 00062 return new CMArtwork( type ); 00063 } 00064 00065 00066 CMAlphaTable::CMAlphaTable() 00067 { 00068 } 00069 00070 00071 AlphaTableEntry CMAlphaTable::entry( short pos, 00072 CharFamily family, 00073 CharStyle /*style*/ ) const 00074 { 00075 /* 00076 static short uppercase_greek[] = { 00077 0x0393, // Gamma 00078 0x0394, // Delta 00079 0x0398, // Theta 00080 0x039B, // Lambda 00081 0x039E, // Xi 00082 0x03A0, // Pi 00083 0x03A3, // Sigma 00084 0x03A6, // Phi 00085 0x03A8, // Psi 00086 0x03A9, // Omega 00087 0x03D2, // Upsilon 00088 0 00089 }; 00090 */ 00091 00092 AlphaTableEntry entry; 00093 switch( family ) { 00094 //case normal: 00095 case scriptFamily: 00096 /* 00097 for ( int i=0; uppercase_greek[i] != 0; ++i ) { 00098 if ( pos == uppercase_greek[i] ) { 00099 entry.pos = pos; 00100 entry.font = QFont( "cmsl10" ); 00101 return; 00102 } 00103 } 00104 */ 00105 if ( ( pos >= 'A' ) && ( pos <= 'Z' ) ) { 00106 entry.pos = pos; 00107 entry.font = QFont( "cmsy10" ); 00108 } 00109 break; 00110 case frakturFamily: 00111 break; 00112 case doubleStruckFamily: 00113 if ( ( pos >= 'A' ) && ( pos <= 'Z' ) ) { 00114 entry.pos = pos; 00115 entry.font = QFont( "msbm10" ); 00116 } 00117 break; 00118 default: 00119 break; 00120 } 00121 return entry; 00122 } 00123 00124 00125 static const char cmex_LeftSquareBracket = 163; 00126 static const char cmex_RightSquareBracket = 164; 00127 static const char cmex_LeftCurlyBracket = 169; 00128 static const char cmex_RightCurlyBracket = 170; 00129 static const char cmex_LeftCornerBracket = 173; 00130 static const char cmex_RightCornerBracket = 174; 00131 static const char cmex_LeftRoundBracket = 161; 00132 static const char cmex_RightRoundBracket = 162; 00133 static const char cmex_SlashBracket = 177; 00134 static const char cmex_BackSlashBracket = 178; 00135 //static const char cmex_LeftLineBracket = 0x4b; 00136 //static const char cmex_RightLineBracket = 0x4b; 00137 00138 // use the big symbols here 00139 static const char cmex_Int = 90; 00140 static const char cmex_Sum = 88; 00141 static const char cmex_Prod = 89; 00142 00143 00144 // cmex is a special font with symbols in four sizes. 00145 static short cmex_nextchar( short ch ) 00146 { 00147 switch ( ch ) { 00148 case 161: return 179; 00149 case 162: return 180; 00150 case 163: return 104; 00151 case 164: return 105; 00152 case 169: return 110; 00153 case 170: return 111; 00154 case 165: return 106; 00155 case 166: return 107; 00156 case 167: return 108; 00157 case 168: return 109; 00158 case 173: return 68; 00159 case 174: return 69; 00160 case 177: return 46; 00161 case 178: return 47; 00162 00163 case 179: return 181; 00164 case 180: return 182; 00165 case 104: return 183; 00166 case 105: return 184; 00167 case 110: return 189; 00168 case 111: return 190; 00169 case 106: return 185; 00170 case 107: return 186; 00171 case 108: return 187; 00172 case 109: return 188; 00173 case 68: return 191; 00174 case 69: return 192; 00175 case 46: return 193; 00176 case 47: return 194; 00177 00178 case 181: return 195; 00179 case 182: return 33; 00180 case 183: return 34; 00181 case 184: return 35; 00182 case 189: return 40; 00183 case 190: return 41; 00184 case 185: return 36; 00185 case 186: return 37; 00186 case 187: return 38; 00187 case 188: return 39; 00188 case 191: return 42; 00189 case 192: return 43; 00190 case 193: return 44; 00191 case 194: return 45; 00192 } 00193 return 0; 00194 } 00195 00196 CMArtwork::CMArtwork( SymbolType t ) 00197 : Artwork( t ), cmChar( -1 ) 00198 { 00199 } 00200 00201 00202 void CMArtwork::calcSizes( const ContextStyle& style, 00203 ContextStyle::TextStyle tstyle, 00204 luPt parentSize ) 00205 { 00206 setBaseline( -1 ); 00207 cmChar = -1; 00208 luPt mySize = style.getAdjustedSize( tstyle ); 00209 switch (getType()) { 00210 case LeftSquareBracket: 00211 if ( calcCMDelimiterSize( style, cmex_LeftSquareBracket, 00212 mySize, parentSize ) ) { 00213 return; 00214 } 00215 calcRoundBracket( style, leftSquareBracket, parentSize, mySize ); 00216 break; 00217 case RightSquareBracket: 00218 if ( calcCMDelimiterSize( style, cmex_RightSquareBracket, 00219 mySize, parentSize ) ) { 00220 return; 00221 } 00222 calcRoundBracket( style, rightSquareBracket, parentSize, mySize ); 00223 break; 00224 case LeftLineBracket: 00225 calcRoundBracket( style, leftLineBracket, parentSize, mySize ); 00226 setWidth( getWidth()/2 ); 00227 break; 00228 case RightLineBracket: 00229 calcRoundBracket( style, rightLineBracket, parentSize, mySize ); 00230 setWidth( getWidth()/2 ); 00231 break; 00232 case SlashBracket: 00233 if ( calcCMDelimiterSize( style, cmex_SlashBracket, 00234 mySize, parentSize ) ) { 00235 return; 00236 } 00237 calcLargest( style, cmex_SlashBracket, mySize ); 00238 break; 00239 case BackSlashBracket: 00240 if ( calcCMDelimiterSize( style, cmex_BackSlashBracket, 00241 mySize, parentSize ) ) { 00242 return; 00243 } 00244 calcLargest( style, cmex_BackSlashBracket, mySize ); 00245 break; 00246 case LeftCornerBracket: 00247 if ( calcCMDelimiterSize( style, cmex_LeftCornerBracket, 00248 mySize, parentSize ) ) { 00249 return; 00250 } 00251 calcLargest( style, cmex_LeftCornerBracket, mySize ); 00252 break; 00253 case RightCornerBracket: 00254 if ( calcCMDelimiterSize( style, cmex_RightCornerBracket, 00255 mySize, parentSize ) ) { 00256 return; 00257 } 00258 calcLargest( style, cmex_RightCornerBracket, mySize ); 00259 break; 00260 case LeftRoundBracket: 00261 if ( calcCMDelimiterSize( style, cmex_LeftRoundBracket, 00262 mySize, parentSize ) ) { 00263 return; 00264 } 00265 calcRoundBracket( style, leftRoundBracket, parentSize, mySize ); 00266 break; 00267 case RightRoundBracket: 00268 if ( calcCMDelimiterSize( style, cmex_RightRoundBracket, 00269 mySize, parentSize ) ) { 00270 return; 00271 } 00272 calcRoundBracket( style, rightRoundBracket, parentSize, mySize ); 00273 break; 00274 case EmptyBracket: 00275 setHeight(parentSize); 00276 //setWidth(style.getEmptyRectWidth()); 00277 setWidth(0); 00278 break; 00279 case LeftCurlyBracket: 00280 if ( calcCMDelimiterSize( style, cmex_LeftCurlyBracket, 00281 mySize, parentSize ) ) { 00282 return; 00283 } 00284 calcCurlyBracket( style, leftCurlyBracket, parentSize, mySize ); 00285 break; 00286 case RightCurlyBracket: 00287 if ( calcCMDelimiterSize( style, cmex_RightCurlyBracket, 00288 mySize, parentSize ) ) { 00289 return; 00290 } 00291 calcCurlyBracket( style, rightCurlyBracket, parentSize, mySize ); 00292 break; 00293 case Integral: 00294 calcCharSize( style, QFont( "cmex10" ), mySize, cmex_Int ); 00295 break; 00296 case Sum: 00297 calcCharSize( style, QFont( "cmex10" ), mySize, cmex_Sum ); 00298 break; 00299 case Product: 00300 calcCharSize( style, QFont( "cmex10" ), mySize, cmex_Prod ); 00301 break; 00302 } 00303 } 00304 00305 00306 void CMArtwork::calcSizes( const ContextStyle& style, 00307 ContextStyle::TextStyle tstyle ) 00308 { 00309 luPt mySize = style.getAdjustedSize( tstyle ); 00310 switch (getType()) { 00311 case LeftLineBracket: 00312 case RightLineBracket: 00313 calcCharSize(style, mySize, 0x2223); 00314 break; 00315 default: 00316 Artwork::calcSizes( style, tstyle ); 00317 break; 00318 } 00319 } 00320 00321 00322 void CMArtwork::draw( QPainter& painter, const LuPixelRect& r, 00323 const ContextStyle& style, 00324 ContextStyle::TextStyle tstyle, 00325 const LuPixelPoint& parentOrigin ) 00326 { 00327 luPt mySize = style.getAdjustedSize( tstyle ); 00328 luPixel myX = parentOrigin.x() + getX(); 00329 luPixel myY = parentOrigin.y() + getY(); 00330 if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) ) 00331 return; 00332 00333 painter.setPen(style.getDefaultColor()); 00334 00335 switch (getType()) { 00336 case LeftLineBracket: 00337 case RightLineBracket: 00338 drawCharacter(painter, style, myX, myY, mySize, 0x2223); 00339 break; 00340 default: 00341 Artwork::draw( painter, r, style, tstyle, parentOrigin ); 00342 break; 00343 } 00344 } 00345 00346 00347 void CMArtwork::draw(QPainter& painter, const LuPixelRect& r, 00348 const ContextStyle& style, ContextStyle::TextStyle tstyle, 00349 luPt /*parentSize*/, const LuPixelPoint& origin) 00350 { 00351 luPt mySize = style.getAdjustedSize( tstyle ); 00352 luPixel myX = origin.x() + getX(); 00353 luPixel myY = origin.y() + getY(); 00354 if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) ) 00355 return; 00356 00357 painter.setPen(style.getDefaultColor()); 00358 00359 switch (getType()) { 00360 case LeftSquareBracket: 00361 if ( cmChar != -1 ) { 00362 drawCMDelimiter( painter, style, myX, myY, mySize ); 00363 } 00364 else { 00365 drawBigRoundBracket( painter, style, leftSquareBracket, myX, myY, mySize ); 00366 } 00367 break; 00368 case RightSquareBracket: 00369 if ( cmChar != -1 ) { 00370 drawCMDelimiter( painter, style, myX, myY, mySize ); 00371 } 00372 else { 00373 drawBigRoundBracket( painter, style, rightSquareBracket, myX, myY, mySize ); 00374 } 00375 break; 00376 case LeftCurlyBracket: 00377 if ( cmChar != -1 ) { 00378 drawCMDelimiter( painter, style, myX, myY, mySize ); 00379 } 00380 else { 00381 drawBigCurlyBracket( painter, style, leftCurlyBracket, myX, myY, mySize ); 00382 } 00383 break; 00384 case RightCurlyBracket: 00385 if ( cmChar != -1 ) { 00386 drawCMDelimiter( painter, style, myX, myY, mySize ); 00387 } 00388 else { 00389 drawBigCurlyBracket( painter, style, rightCurlyBracket, myX, myY, mySize ); 00390 } 00391 break; 00392 case LeftLineBracket: { 00393 luPixel halfWidth = getWidth()/2; 00394 drawBigRoundBracket( painter, style, leftLineBracket, 00395 myX-halfWidth, myY, mySize ); 00396 } 00397 break; 00398 case RightLineBracket: { 00399 luPixel halfWidth = getWidth()/2; 00400 drawBigRoundBracket( painter, style, rightLineBracket, 00401 myX-halfWidth, myY, mySize ); 00402 } 00403 break; 00404 case SlashBracket: 00405 if ( cmChar != -1 ) { 00406 drawCMDelimiter( painter, style, myX, myY, mySize ); 00407 } 00408 break; 00409 case BackSlashBracket: 00410 if ( cmChar != -1 ) { 00411 drawCMDelimiter( painter, style, myX, myY, mySize ); 00412 } 00413 break; 00414 case LeftCornerBracket: 00415 if ( cmChar != -1 ) { 00416 drawCMDelimiter( painter, style, myX, myY, mySize ); 00417 } 00418 else drawCharacter(painter, style, myX, myY, mySize, leftAngleBracketChar); 00419 break; 00420 case RightCornerBracket: 00421 if ( cmChar != -1 ) { 00422 drawCMDelimiter( painter, style, myX, myY, mySize ); 00423 } 00424 else drawCharacter(painter, style, myX, myY, mySize, rightAngleBracketChar); 00425 break; 00426 case LeftRoundBracket: 00427 if ( cmChar != -1 ) { 00428 drawCMDelimiter( painter, style, myX, myY, mySize ); 00429 } 00430 else { 00431 drawBigRoundBracket( painter, style, leftRoundBracket, myX, myY, mySize ); 00432 } 00433 break; 00434 case RightRoundBracket: 00435 if ( cmChar != -1 ) { 00436 drawCMDelimiter( painter, style, myX, myY, mySize ); 00437 } 00438 else { 00439 drawBigRoundBracket( painter, style, rightRoundBracket, myX, myY, mySize ); 00440 } 00441 break; 00442 case EmptyBracket: 00443 break; 00444 case Integral: 00445 drawCharacter(painter, style, QFont( "cmex10" ), myX, myY, mySize, cmex_Int); 00446 break; 00447 case Sum: 00448 drawCharacter(painter, style, QFont( "cmex10" ), myX, myY, mySize, cmex_Sum); 00449 break; 00450 case Product: 00451 drawCharacter(painter, style, QFont( "cmex10" ), myX, myY, mySize, cmex_Prod); 00452 break; 00453 } 00454 00455 // debug 00456 // painter.setBrush(Qt::NoBrush); 00457 // painter.setPen(Qt::green); 00458 // painter.drawRect( style.layoutUnitToPixelX( myX ), 00459 // style.layoutUnitToPixelY( myY ), 00460 // style.layoutUnitToPixelX( getWidth() ), 00461 // style.layoutUnitToPixelY( getHeight() ) ); 00462 } 00463 00464 00465 bool CMArtwork::isNormalChar() const 00466 { 00467 return Artwork::isNormalChar() && ( cmChar == -1 ); 00468 } 00469 00470 double CMArtwork::slant() const 00471 { 00472 if ( getType() == Integral ) { 00473 return 0.25; 00474 } 00475 return 0; 00476 } 00477 00478 bool CMArtwork::calcCMDelimiterSize( const ContextStyle& context, 00479 uchar c, 00480 luPt fontSize, 00481 luPt parentSize ) 00482 { 00483 QFont f( "cmex10" ); 00484 f.setPointSizeFloat( context.layoutUnitPtToPt( fontSize ) ); 00485 QFontMetrics fm( f ); 00486 00487 for ( char i=1; c != 0; ++i ) { 00488 LuPixelRect bound = fm.boundingRect( c ); 00489 00490 luPt height = context.ptToLayoutUnitPt( bound.height() ); 00491 if ( height >= parentSize ) { 00492 luPt width = context.ptToLayoutUnitPt( fm.width( c ) ); 00493 luPt baseline = context.ptToLayoutUnitPt( -bound.top() ); 00494 00495 cmChar = c; 00496 00497 setHeight( height ); 00498 setWidth( width ); 00499 setBaseline( baseline ); 00500 00501 return true; 00502 } 00503 c = cmex_nextchar( c ); 00504 } 00505 00506 // Build it up from pieces. 00507 return false; 00508 } 00509 00510 00511 void CMArtwork::calcLargest( const ContextStyle& context, 00512 uchar c, luPt fontSize ) 00513 { 00514 QFont f( "cmex10" ); 00515 f.setPointSizeFloat( context.layoutUnitPtToPt( fontSize ) ); 00516 QFontMetrics fm( f ); 00517 00518 cmChar = c; 00519 for ( ;; ) { 00520 c = cmex_nextchar( c ); 00521 if ( c == 0 ) { 00522 break; 00523 } 00524 cmChar = c; 00525 } 00526 00527 LuPixelRect bound = fm.boundingRect( cmChar ); 00528 00529 luPt height = context.ptToLayoutUnitPt( bound.height() ); 00530 luPt width = context.ptToLayoutUnitPt( fm.width( cmChar ) ); 00531 luPt baseline = context.ptToLayoutUnitPt( -bound.top() ); 00532 00533 setHeight( height ); 00534 setWidth( width ); 00535 setBaseline( baseline ); 00536 } 00537 00538 00539 void CMArtwork::drawCMDelimiter( QPainter& painter, const ContextStyle& style, 00540 luPixel x, luPixel y, 00541 luPt height ) 00542 { 00543 QFont f( "cmex10" ); 00544 f.setPointSizeFloat( style.layoutUnitToFontSize( height, false ) ); 00545 00546 painter.setFont( f ); 00547 painter.drawText( style.layoutUnitToPixelX( x ), 00548 style.layoutUnitToPixelY( y + getBaseline() ), 00549 QString( QChar( cmChar ) ) ); 00550 00551 // Debug 00552 #if 0 00553 QFontMetrics fm( f ); 00554 LuPixelRect bound = fm.boundingRect( cmChar ); 00555 painter.setBrush(Qt::NoBrush); 00556 painter.setPen(Qt::green); 00557 painter.drawRect( style.layoutUnitToPixelX( x ), 00558 style.layoutUnitToPixelY( y ), 00559 fm.width( cmChar ), 00560 bound.height() ); 00561 #endif 00562 } 00563 00564 00565 KFORMULA_NAMESPACE_END
KDE Logo
This file is part of the documentation for lib Library Version 1.3.3.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Sep 28 04:03:58 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003