summaryrefslogtreecommitdiffstats
path: root/lib/kformula/fontstyle.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kformula/fontstyle.cpp')
-rw-r--r--lib/kformula/fontstyle.cpp891
1 files changed, 891 insertions, 0 deletions
diff --git a/lib/kformula/fontstyle.cpp b/lib/kformula/fontstyle.cpp
new file mode 100644
index 00000000..33f9e9f7
--- /dev/null
+++ b/lib/kformula/fontstyle.cpp
@@ -0,0 +1,891 @@
+/* This file is part of the KDE project
+ Copyright (C) 2003 Ulrich Kuettler <ulrich.kuettler@gmx.de>
+ Copyright (C) 2006 Alfredo Beaumont Sainz <alfredo.beaumont@gmail.com>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+*/
+
+#include <tqpainter.h>
+#include <tqpen.h>
+#include <tqfontdatabase.h>
+#include <tqapplication.h>
+
+#include <kstaticdeleter.h>
+#include <tdelocale.h>
+#include <kstandarddirs.h>
+#include <tdeio/netaccess.h>
+#include <tdeio/job.h>
+#include <tdemessagebox.h>
+
+#include "fontstyle.h"
+
+
+KFORMULA_NAMESPACE_BEGIN
+
+#include "unicodetable.cpp"
+
+bool FontStyle::m_installed = false;
+
+bool FontStyle::init( ContextStyle* style, bool install )
+{
+ if (!m_installed && install)
+ installFonts();
+ m_symbolTable.init( style->getMathFont() );
+
+ return true;
+}
+
+// Cache the family list from TQFontDatabase after fixing it up (no foundry, lowercase)
+class FontList {
+public:
+ FontList() {
+ TQFontDatabase db;
+ const TQStringList lst = db.families();
+ for ( TQStringList::const_iterator it = lst.begin(), end = lst.end() ; it != end ; ++it ) {
+ const TQString name = *it;
+ int i = name.find('[');
+ TQString family = name;
+ // Remove foundry
+ if ( i > -1 ) {
+ const int li = name.findRev(']');
+ if (i < li) {
+ if (name[i - 1] == ' ')
+ i--;
+ family = name.left(i);
+ }
+ }
+ m_fontNames.append( family.lower() );
+ }
+ }
+ bool hasFont( const TQString& fontName ) const {
+ return m_fontNames.find( fontName ) != m_fontNames.end();
+ }
+ TQStringList m_fontNames;
+};
+static FontList* s_fontList = 0;
+static KStaticDeleter<FontList> s_fontList_sd;
+
+void FontStyle::testFont( TQStringList& missing, const TQString& fontName ) {
+ if ( !s_fontList )
+ s_fontList_sd.setObject( s_fontList, new FontList() );
+ if ( !s_fontList->hasFont( fontName ) ) {
+ kdWarning(39001) << "Font '" << fontName << "' not found" << endl;
+ missing.append( fontName );
+ }
+}
+
+
+TQStringList FontStyle::missingFonts( bool install )
+{
+ if (!m_installed && install)
+ installFonts();
+
+ TQStringList missing = missingFontsInternal();
+ return missing;
+}
+
+TQStringList FontStyle::missingFontsInternal()
+{
+ TQStringList missing;
+
+ testFont( missing, "cmex10" );
+ testFont( missing, "arev sans");
+
+ return missing;
+}
+
+void FontStyle::installFonts()
+{
+ if (m_installed)
+ return;
+ TQStringList missing = missingFontsInternal();
+ if (!missing.isEmpty())
+ {
+ TQStringList urlList;
+ for (TQStringList::iterator it = missing.begin(); it != missing.end(); ++it)
+ {
+ if ( *it == "arev sans" ) {
+ if (!TDEIO::NetAccess::exists("fonts:/Personal/Arev.ttf", true, NULL))
+ urlList.append(locate("data", "kformula/fonts/Arev.ttf"));
+ if (!TDEIO::NetAccess::exists("fonts:/Personal/ArevIt.ttf", true, NULL))
+ urlList.append(locate("data", "kformula/fonts/ArevIt.ttf"));
+ if (!TDEIO::NetAccess::exists("fonts:/Personal/ArevBd.ttf", true, NULL))
+ urlList.append(locate("data", "kformula/fonts/ArevBd.ttf"));
+ if (!TDEIO::NetAccess::exists("fonts:/Personal/ArevBI.ttf", true, NULL))
+ urlList.append(locate("data", "kformula/fonts/ArevBI.ttf"));
+ }
+ else {
+ if (!TDEIO::NetAccess::exists("fonts:/Personal/" + *it + ".ttf", true, NULL))
+ urlList.append(locate("data", "kformula/fonts/" + *it + ".ttf"));
+ }
+ }
+ TDEIO::copy(urlList, "fonts:/Personal/", false);
+ KMessageBox::information(tqApp->mainWidget(),
+ i18n("Some fonts have been installed to assure that symbols in formulas are properly visualized. You must restart the application in order so that changes take effect"));
+ }
+ m_installed = true;
+}
+
+Artwork* FontStyle::createArtwork( SymbolType type ) const
+{
+ return new Artwork( type );
+}
+
+// We claim that all chars come from the same font.
+// It's up to the font tables to ensure this.
+const TQChar leftRoundBracket[] = {
+ 0x30, // uppercorner
+ 0x40, // lowercorner
+ 0x42 // line
+};
+const TQChar leftSquareBracket[] = {
+ 0x32, // uppercorner
+ 0x34, // lowercorner
+ 0x36 // line
+};
+const TQChar leftCurlyBracket[] = {
+ 0x38, // uppercorner
+ 0x3A, // lowercorner
+ 0x3E, // line
+ 0x3C // middle
+};
+
+const TQChar leftLineBracket[] = {
+ 0x36, // line
+ 0x36, // line
+ 0x36 // line
+};
+const TQChar rightLineBracket[] = {
+ 0x37, // line
+ 0x37, // line
+ 0x37 // line
+};
+
+const TQChar rightRoundBracket[] = {
+ 0x31, // uppercorner
+ 0x41, // lowercorner
+ 0x43 // line
+};
+const TQChar rightSquareBracket[] = {
+ 0x33, // uppercorner
+ 0x35, // lowercorner
+ 0x37 // line
+};
+const TQChar rightCurlyBracket[] = {
+ 0x39, // uppercorner
+ 0x3B, // lowercorner
+ 0x3E, // line
+ 0x3D // middle
+};
+
+
+static const char cmex_LeftSquareBracket = 163;
+static const char cmex_RightSquareBracket = 164;
+static const char cmex_LeftCurlyBracket = 169;
+static const char cmex_RightCurlyBracket = 170;
+static const char cmex_LeftCornerBracket = 173;
+static const char cmex_RightCornerBracket = 174;
+static const char cmex_LeftRoundBracket = 161;
+static const char cmex_RightRoundBracket = 162;
+static const char cmex_SlashBracket = 177;
+static const char cmex_BackSlashBracket = 178;
+//static const char cmex_LeftLineBracket = 0x4b;
+//static const char cmex_RightLineBracket = 0x4b;
+
+// use the big symbols here
+static const char cmex_Int = 90;
+static const char cmex_Sum = 88;
+static const char cmex_Prod = 89;
+
+
+// cmex is a special font with symbols in four sizes.
+static short cmex_nextchar( short ch )
+{
+ switch ( ch ) {
+ case 161: return 179;
+ case 162: return 180;
+ case 163: return 104;
+ case 164: return 105;
+ case 169: return 110;
+ case 170: return 111;
+ case 165: return 106;
+ case 166: return 107;
+ case 167: return 108;
+ case 168: return 109;
+ case 173: return 68;
+ case 174: return 69;
+ case 177: return 46;
+ case 178: return 47;
+
+ case 179: return 181;
+ case 180: return 182;
+ case 104: return 183;
+ case 105: return 184;
+ case 110: return 189;
+ case 111: return 190;
+ case 106: return 185;
+ case 107: return 186;
+ case 108: return 187;
+ case 109: return 188;
+ case 68: return 191;
+ case 69: return 192;
+ case 46: return 193;
+ case 47: return 194;
+
+ case 181: return 195;
+ case 182: return 33;
+ case 183: return 34;
+ case 184: return 35;
+ case 189: return 40;
+ case 190: return 41;
+ case 185: return 36;
+ case 186: return 37;
+ case 187: return 38;
+ case 188: return 39;
+ case 191: return 42;
+ case 192: return 43;
+ case 193: return 44;
+ case 194: return 45;
+ }
+ return 0;
+}
+
+bool Artwork::calcCMDelimiterSize( const ContextStyle& context,
+ uchar c,
+ luPt fontSize,
+ luPt parentSize )
+{
+ TQFont f( "cmex10" );
+ f.setPointSizeFloat( context.layoutUnitPtToPt( fontSize ) );
+ TQFontMetrics fm( f );
+
+ for ( char i=1; c != 0; ++i ) {
+ LuPixelRect bound = fm.boundingRect( c );
+
+ luPt height = context.ptToLayoutUnitPt( bound.height() );
+ if ( height >= parentSize ) {
+ luPt width = context.ptToLayoutUnitPt( fm.width( c ) );
+ luPt baseline = context.ptToLayoutUnitPt( -bound.top() );
+
+ cmChar = c;
+
+ setHeight( height );
+ setWidth( width );
+ setBaseline( baseline );
+
+ return true;
+ }
+ c = cmex_nextchar( c );
+ }
+
+ // Build it up from pieces.
+ return false;
+}
+
+
+void Artwork::calcLargest( const ContextStyle& context,
+ uchar c, luPt fontSize )
+{
+ TQFont f( "cmex10" );
+ f.setPointSizeFloat( context.layoutUnitPtToPt( fontSize ) );
+ TQFontMetrics fm( f );
+
+ cmChar = c;
+ for ( ;; ) {
+ c = cmex_nextchar( c );
+ if ( c == 0 ) {
+ break;
+ }
+ cmChar = c;
+ }
+
+ LuPixelRect bound = fm.boundingRect( cmChar );
+
+ luPt height = context.ptToLayoutUnitPt( bound.height() );
+ luPt width = context.ptToLayoutUnitPt( fm.width( cmChar ) );
+ luPt baseline = context.ptToLayoutUnitPt( -bound.top() );
+
+ setHeight( height );
+ setWidth( width );
+ setBaseline( baseline );
+}
+
+
+void Artwork::drawCMDelimiter( TQPainter& painter, const ContextStyle& style,
+ luPixel x, luPixel y,
+ luPt height )
+{
+ TQFont f( "cmex10" );
+ f.setPointSizeFloat( style.layoutUnitToFontSize( height, false ) );
+
+ painter.setFont( f );
+ painter.drawText( style.layoutUnitToPixelX( x ),
+ style.layoutUnitToPixelY( y + getBaseline() ),
+ TQString( TQChar( cmChar ) ) );
+
+ // Debug
+#if 0
+ TQFontMetrics fm( f );
+ LuPixelRect bound = fm.boundingRect( cmChar );
+ painter.setBrush(TQt::NoBrush);
+ painter.setPen(TQt::green);
+ painter.drawRect( style.layoutUnitToPixelX( x ),
+ style.layoutUnitToPixelY( y ),
+ fm.width( cmChar ),
+ bound.height() );
+#endif
+}
+
+
+Artwork::Artwork(SymbolType t)
+ : baseline( -1 ), type(t)
+{
+}
+
+
+void Artwork::calcSizes( const ContextStyle& style,
+ ContextStyle::TextStyle tstyle,
+ double factor,
+ luPt parentSize )
+{
+ setBaseline( -1 );
+ cmChar = -1;
+ luPt mySize = style.getAdjustedSize( tstyle, factor );
+ switch (getType()) {
+ case LeftSquareBracket:
+ if ( calcCMDelimiterSize( style, cmex_LeftSquareBracket,
+ mySize, parentSize ) ) {
+ return;
+ }
+ calcRoundBracket( style, leftSquareBracket, parentSize, mySize );
+ break;
+ case RightSquareBracket:
+ if ( calcCMDelimiterSize( style, cmex_RightSquareBracket,
+ mySize, parentSize ) ) {
+ return;
+ }
+ calcRoundBracket( style, rightSquareBracket, parentSize, mySize );
+ break;
+ case LeftLineBracket:
+ calcRoundBracket( style, leftLineBracket, parentSize, mySize );
+ setWidth( getWidth()/2 );
+ break;
+ case RightLineBracket:
+ calcRoundBracket( style, rightLineBracket, parentSize, mySize );
+ setWidth( getWidth()/2 );
+ break;
+ case SlashBracket:
+ if ( calcCMDelimiterSize( style, cmex_SlashBracket,
+ mySize, parentSize ) ) {
+ return;
+ }
+ calcLargest( style, cmex_SlashBracket, mySize );
+ break;
+ case BackSlashBracket:
+ if ( calcCMDelimiterSize( style, cmex_BackSlashBracket,
+ mySize, parentSize ) ) {
+ return;
+ }
+ calcLargest( style, cmex_BackSlashBracket, mySize );
+ break;
+ case LeftCornerBracket:
+ if ( calcCMDelimiterSize( style, cmex_LeftCornerBracket,
+ mySize, parentSize ) ) {
+ return;
+ }
+ calcLargest( style, cmex_LeftCornerBracket, mySize );
+ break;
+ case RightCornerBracket:
+ if ( calcCMDelimiterSize( style, cmex_RightCornerBracket,
+ mySize, parentSize ) ) {
+ return;
+ }
+ calcLargest( style, cmex_RightCornerBracket, mySize );
+ break;
+ case LeftRoundBracket:
+ if ( calcCMDelimiterSize( style, cmex_LeftRoundBracket,
+ mySize, parentSize ) ) {
+ return;
+ }
+ calcRoundBracket( style, leftRoundBracket, parentSize, mySize );
+ break;
+ case RightRoundBracket:
+ if ( calcCMDelimiterSize( style, cmex_RightRoundBracket,
+ mySize, parentSize ) ) {
+ return;
+ }
+ calcRoundBracket( style, rightRoundBracket, parentSize, mySize );
+ break;
+ case EmptyBracket:
+ setHeight(parentSize);
+ //setWidth(style.getEmptyRectWidth());
+ setWidth(0);
+ break;
+ case LeftCurlyBracket:
+ if ( calcCMDelimiterSize( style, cmex_LeftCurlyBracket,
+ mySize, parentSize ) ) {
+ return;
+ }
+ calcCurlyBracket( style, leftCurlyBracket, parentSize, mySize );
+ break;
+ case RightCurlyBracket:
+ if ( calcCMDelimiterSize( style, cmex_RightCurlyBracket,
+ mySize, parentSize ) ) {
+ return;
+ }
+ calcCurlyBracket( style, rightCurlyBracket, parentSize, mySize );
+ break;
+ case Integral:
+ calcCharSize( style, style.getBracketFont(), mySize, cmex_Int );
+ break;
+ case Sum:
+ calcCharSize( style, style.getBracketFont(), mySize, cmex_Sum );
+ break;
+ case Product:
+ calcCharSize( style, style.getBracketFont(), mySize, cmex_Prod );
+ break;
+ }
+}
+
+void Artwork::calcSizes( const ContextStyle& style,
+ ContextStyle::TextStyle tstyle,
+ double factor )
+{
+ luPt mySize = style.getAdjustedSize( tstyle, factor );
+ switch (type) {
+ case LeftSquareBracket:
+ calcCharSize(style, mySize, leftSquareBracketChar);
+ break;
+ case RightSquareBracket:
+ calcCharSize(style, mySize, rightSquareBracketChar);
+ break;
+ case LeftLineBracket:
+ case RightLineBracket:
+ calcCharSize(style, mySize, verticalLineChar);
+ break;
+ case SlashBracket:
+ calcCharSize(style, mySize, slashChar);
+ break;
+ case BackSlashBracket:
+ calcCharSize(style, mySize, backSlashChar);
+ break;
+ case LeftCornerBracket:
+ calcCharSize(style, mySize, leftAngleBracketChar);
+ break;
+ case RightCornerBracket:
+ calcCharSize(style, mySize, rightAngleBracketChar);
+ break;
+ case LeftRoundBracket:
+ calcCharSize(style, mySize, leftParenthesisChar);
+ break;
+ case RightRoundBracket:
+ calcCharSize(style, mySize, rightParenthesisChar);
+ break;
+ case EmptyBracket:
+ //calcCharSize(style, mySize, spaceChar);
+ setHeight(0);
+ //setWidth(style.getEmptyRectWidth());
+ setWidth(0);
+ break;
+ case LeftCurlyBracket:
+ calcCharSize(style, mySize, leftCurlyBracketChar);
+ break;
+ case RightCurlyBracket:
+ calcCharSize(style, mySize, rightCurlyBracketChar);
+ break;
+ case Integral:
+ case Sum:
+ case Product:
+ break;
+ }
+}
+
+
+void Artwork::draw(TQPainter& painter, const LuPixelRect& /*r*/,
+ const ContextStyle& context, ContextStyle::TextStyle tstyle,
+ StyleAttributes& style, const LuPixelPoint& parentOrigin)
+{
+ luPt mySize = context.getAdjustedSize( tstyle, style.sizeFactor() );
+ luPixel myX = parentOrigin.x() + getX();
+ luPixel myY = parentOrigin.y() + getY();
+ /*
+ if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) )
+ return;
+ */
+
+ painter.setPen(context.getDefaultColor());
+
+ switch (type) {
+ case LeftSquareBracket:
+ drawCharacter(painter, context, myX, myY, mySize, leftSquareBracketChar);
+ break;
+ case RightSquareBracket:
+ drawCharacter(painter, context, myX, myY, mySize, rightSquareBracketChar);
+ break;
+ case LeftCurlyBracket:
+ drawCharacter(painter, context, myX, myY, mySize, leftCurlyBracketChar);
+ break;
+ case RightCurlyBracket:
+ drawCharacter(painter, context, myX, myY, mySize, rightCurlyBracketChar);
+ break;
+ case LeftLineBracket:
+ case RightLineBracket:
+ drawCharacter(painter, context, myX, myY, mySize, verticalLineChar);
+ break;
+ case SlashBracket:
+ drawCharacter(painter, context, myX, myY, mySize, slashChar);
+ break;
+ case BackSlashBracket:
+ drawCharacter(painter, context, myX, myY, mySize, backSlashChar);
+ break;
+ case LeftCornerBracket:
+ drawCharacter(painter, context, myX, myY, mySize, leftAngleBracketChar);
+ break;
+ case RightCornerBracket:
+ drawCharacter(painter, context, myX, myY, mySize, rightAngleBracketChar);
+ break;
+ case LeftRoundBracket:
+ drawCharacter(painter, context, myX, myY, mySize, leftParenthesisChar);
+ break;
+ case RightRoundBracket:
+ drawCharacter(painter, context, myX, myY, mySize, rightParenthesisChar);
+ break;
+ case EmptyBracket:
+ break;
+ case Integral:
+ case Sum:
+ case Product:
+ break;
+ }
+}
+
+void Artwork::draw(TQPainter& painter, const LuPixelRect& ,
+ const ContextStyle& context, ContextStyle::TextStyle tstyle,
+ StyleAttributes& style, luPt , const LuPixelPoint& origin)
+{
+ luPt mySize = context.getAdjustedSize( tstyle, style.sizeFactor() );
+ luPixel myX = origin.x() + getX();
+ luPixel myY = origin.y() + getY();
+ /*
+ if ( !LuPixelRect( myX, myY, getWidth(), getHeight() ).intersects( r ) )
+ return;
+ */
+
+ painter.setPen(context.getDefaultColor());
+
+ switch (getType()) {
+ case LeftSquareBracket:
+ if ( cmChar != -1 ) {
+ drawCMDelimiter( painter, context, myX, myY, mySize );
+ }
+ else {
+ drawBigRoundBracket( painter, context, leftSquareBracket, myX, myY, mySize );
+ }
+ break;
+ case RightSquareBracket:
+ if ( cmChar != -1 ) {
+ drawCMDelimiter( painter, context, myX, myY, mySize );
+ }
+ else {
+ drawBigRoundBracket( painter, context, rightSquareBracket, myX, myY, mySize );
+ }
+ break;
+ case LeftCurlyBracket:
+ if ( cmChar != -1 ) {
+ drawCMDelimiter( painter, context, myX, myY, mySize );
+ }
+ else {
+ drawBigCurlyBracket( painter, context, leftCurlyBracket, myX, myY, mySize );
+ }
+ break;
+ case RightCurlyBracket:
+ if ( cmChar != -1 ) {
+ drawCMDelimiter( painter, context, myX, myY, mySize );
+ }
+ else {
+ drawBigCurlyBracket( painter, context, rightCurlyBracket, myX, myY, mySize );
+ }
+ break;
+ case LeftLineBracket: {
+ luPixel halfWidth = getWidth()/2;
+ drawBigRoundBracket( painter, context, leftLineBracket,
+ myX-halfWidth, myY, mySize );
+ }
+ break;
+ case RightLineBracket: {
+ luPixel halfWidth = getWidth()/2;
+ drawBigRoundBracket( painter, context, rightLineBracket,
+ myX-halfWidth, myY, mySize );
+ }
+ break;
+ case SlashBracket:
+ if ( cmChar != -1 ) {
+ drawCMDelimiter( painter, context, myX, myY, mySize );
+ }
+ break;
+ case BackSlashBracket:
+ if ( cmChar != -1 ) {
+ drawCMDelimiter( painter, context, myX, myY, mySize );
+ }
+ break;
+ case LeftCornerBracket:
+ if ( cmChar != -1 ) {
+ drawCMDelimiter( painter, context, myX, myY, mySize );
+ }
+ else drawCharacter(painter, context, myX, myY, mySize, leftAngleBracketChar);
+ break;
+ case RightCornerBracket:
+ if ( cmChar != -1 ) {
+ drawCMDelimiter( painter, context, myX, myY, mySize );
+ }
+ else drawCharacter(painter, context, myX, myY, mySize, rightAngleBracketChar);
+ break;
+ case LeftRoundBracket:
+ if ( cmChar != -1 ) {
+ drawCMDelimiter( painter, context, myX, myY, mySize );
+ }
+ else {
+ drawBigRoundBracket( painter, context, leftRoundBracket, myX, myY, mySize );
+ }
+ break;
+ case RightRoundBracket:
+ if ( cmChar != -1 ) {
+ drawCMDelimiter( painter, context, myX, myY, mySize );
+ }
+ else {
+ drawBigRoundBracket( painter, context, rightRoundBracket, myX, myY, mySize );
+ }
+ break;
+ case EmptyBracket:
+ break;
+ case Integral:
+ drawCharacter(painter, context, TQFont( "cmex10" ), myX, myY, mySize, cmex_Int);
+ break;
+ case Sum:
+ drawCharacter(painter, context, TQFont( "cmex10" ), myX, myY, mySize, cmex_Sum);
+ break;
+ case Product:
+ drawCharacter(painter, context, TQFont( "cmex10" ), myX, myY, mySize, cmex_Prod);
+ break;
+ }
+
+ // debug
+// painter.setBrush(TQt::NoBrush);
+// painter.setPen(TQt::green);
+// painter.drawRect( context.layoutUnitToPixelX( myX ),
+// context.layoutUnitToPixelY( myY ),
+// context.layoutUnitToPixelX( getWidth() ),
+// context.layoutUnitToPixelY( getHeight() ) );
+}
+
+void Artwork::calcCharSize( const ContextStyle& style, luPt height, TQChar ch )
+{
+ calcCharSize( style, style.getMathFont(), height, ch );
+}
+
+
+void Artwork::drawCharacter( TQPainter& painter, const ContextStyle& style,
+ luPixel x, luPixel y,
+ luPt height, TQChar ch )
+{
+ drawCharacter( painter, style, style.getMathFont(), x, y, height, ch );
+}
+
+
+void Artwork::calcCharSize( const ContextStyle& style, TQFont f,
+ luPt height, TQChar c )
+{
+ f.setPointSizeFloat( style.layoutUnitPtToPt( height ) );
+ //f.setPointSize( height );
+ TQFontMetrics fm(f);
+ setWidth( style.ptToLayoutUnitPt( fm.width( c ) ) );
+ LuPixelRect bound = fm.boundingRect( c );
+ setHeight( style.ptToLayoutUnitPt( bound.height() ) );
+ setBaseline( style.ptToLayoutUnitPt( -bound.top() ) );
+}
+
+
+void Artwork::drawCharacter( TQPainter& painter, const ContextStyle& style,
+ TQFont f,
+ luPixel x, luPixel y, luPt height, uchar c )
+{
+ f.setPointSizeFloat( style.layoutUnitToFontSize( height, false ) );
+
+ painter.setFont( f );
+ painter.drawText( style.layoutUnitToPixelX( x ),
+ style.layoutUnitToPixelY( y+getBaseline() ),
+ TQString( TQChar( c ) ) );
+}
+
+
+void Artwork::calcRoundBracket( const ContextStyle& style, const TQChar chars[],
+ luPt height, luPt charHeight )
+{
+ uchar uppercorner = chars[0];
+ uchar lowercorner = chars[1];
+ //uchar line = style.symbolTable().character( chars[2] );
+
+ TQFont f = style.getBracketFont();
+ f.setPointSizeFloat( style.layoutUnitPtToPt( charHeight ) );
+ TQFontMetrics fm( f );
+ LuPtRect upperBound = fm.boundingRect( uppercorner );
+ LuPtRect lowerBound = fm.boundingRect( lowercorner );
+ //LuPtRect lineBound = fm.boundingRect( line );
+
+ setWidth( style.ptToLayoutUnitPt( fm.width( TQChar( uppercorner ) ) ) );
+ luPt edgeHeight = style.ptToLayoutUnitPt( upperBound.height()+lowerBound.height() );
+ //luPt lineHeight = style.ptToLayoutUnitPt( lineBound.height() );
+
+ //setHeight( edgeHeight + ( ( height-edgeHeight-1 ) / lineHeight + 1 ) * lineHeight );
+ setHeight( TQMAX( edgeHeight, height ) );
+}
+
+void Artwork::drawBigRoundBracket( TQPainter& p, const ContextStyle& style, const TQChar chars[],
+ luPixel x, luPixel y, luPt charHeight )
+{
+ uchar uppercorner = chars[0];
+ uchar lowercorner = chars[1];
+ uchar line = chars[2];
+
+ TQFont f = style.getBracketFont();
+ f.setPointSizeFloat( style.layoutUnitToFontSize( charHeight, false ) );
+ p.setFont(f);
+
+ TQFontMetrics fm(f);
+ TQRect upperBound = fm.boundingRect(uppercorner);
+ TQRect lowerBound = fm.boundingRect(lowercorner);
+ TQRect lineBound = fm.boundingRect(line);
+
+ pixel ptX = style.layoutUnitToPixelX( x );
+ pixel ptY = style.layoutUnitToPixelY( y );
+ pixel height = style.layoutUnitToPixelY( getHeight() );
+
+// p.setPen( TQt::red );
+// //p.drawRect( ptX, ptY, upperBound.width(), upperBound.height() + lowerBound.height() );
+// p.drawRect( ptX, ptY, style.layoutUnitToPixelX( getWidth() ),
+// style.layoutUnitToPixelY( getHeight() ) );
+
+// p.setPen( TQt::black );
+ p.drawText( ptX, ptY-upperBound.top(), TQString( TQChar( uppercorner ) ) );
+ p.drawText( ptX, ptY+height-lowerBound.top()-lowerBound.height(),
+ TQString( TQChar( lowercorner ) ) );
+
+ // for printing
+ //pt safety = lineBound.height() / 10.0;
+ pixel safety = 0;
+
+ pixel gap = height - upperBound.height() - lowerBound.height();
+ pixel lineHeight = lineBound.height() - safety;
+ int lineCount = tqRound( static_cast<double>( gap ) / lineHeight );
+ pixel start = upperBound.height()-lineBound.top() - safety;
+
+ for (int i = 0; i < lineCount; i++) {
+ p.drawText( ptX, ptY+start+i*lineHeight, TQString(TQChar(line)));
+ }
+ pixel remaining = gap - lineCount*lineHeight;
+ pixel dist = ( lineHeight - remaining ) / 2;
+ p.drawText( ptX, ptY+height-upperBound.height()+dist-lineBound.height()-lineBound.top(),
+ TQString( TQChar( line ) ) );
+}
+
+void Artwork::calcCurlyBracket( const ContextStyle& style, const TQChar chars[],
+ luPt height, luPt charHeight )
+{
+ uchar uppercorner = chars[0];
+ uchar lowercorner = chars[1];
+ //uchar line = style.symbolTable().character( chars[2] );
+ uchar middle = chars[3];
+
+ TQFont f = style.getBracketFont();
+ f.setPointSizeFloat( style.layoutUnitPtToPt( charHeight ) );
+ TQFontMetrics fm( f );
+ LuPtRect upperBound = fm.boundingRect( uppercorner );
+ LuPtRect lowerBound = fm.boundingRect( lowercorner );
+ //LuPtRect lineBound = fm.boundingRect( line );
+ LuPtRect middleBound = fm.boundingRect( middle );
+
+ setWidth( style.ptToLayoutUnitPt( fm.width( TQChar( uppercorner ) ) ) );
+ luPt edgeHeight = style.ptToLayoutUnitPt( upperBound.height()+
+ lowerBound.height()+
+ middleBound.height() );
+ //luPt lineHeight = style.ptToLayoutUnitPt( lineBound.height() );
+
+ //setHeight( edgeHeight + ( ( height-edgeHeight-1 ) / lineHeight + 1 ) * lineHeight );
+ setHeight( TQMAX( edgeHeight, height ) );
+}
+
+void Artwork::drawBigCurlyBracket( TQPainter& p, const ContextStyle& style, const TQChar chars[],
+ luPixel x, luPixel y, luPt charHeight )
+{
+ //TQFont f = style.getSymbolFont();
+ TQFont f = style.getBracketFont();
+ f.setPointSizeFloat( style.layoutUnitToFontSize( charHeight, false ) );
+ p.setFont(f);
+
+ uchar uppercorner = chars[0];
+ uchar lowercorner = chars[1];
+ uchar line = chars[2];
+ uchar middle = chars[3];
+
+ TQFontMetrics fm(p.fontMetrics());
+ TQRect upperBound = fm.boundingRect(uppercorner);
+ TQRect lowerBound = fm.boundingRect(lowercorner);
+ TQRect middleBound = fm.boundingRect(middle);
+ TQRect lineBound = fm.boundingRect(line);
+
+ pixel ptX = style.layoutUnitToPixelX( x );
+ pixel ptY = style.layoutUnitToPixelY( y );
+ pixel height = style.layoutUnitToPixelY( getHeight() );
+
+ //p.setPen(TQt::gray);
+ //p.drawRect(x, y, upperBound.width() + offset, height);
+
+ p.drawText( ptX, ptY-upperBound.top(), TQString( TQChar( uppercorner ) ) );
+ p.drawText( ptX, ptY+(height-middleBound.height())/2-middleBound.top(),
+ TQString( TQChar( middle ) ) );
+ p.drawText( ptX, ptY+height-lowerBound.top()-lowerBound.height(),
+ TQString( TQChar( lowercorner ) ) );
+
+ // for printing
+ // If the world was perfect and the urw-symbol font correct
+ // this could be 0.
+ //lu safety = lineBound.height() / 10;
+ pixel safety = 0;
+
+ pixel lineHeight = lineBound.height() - safety;
+ pixel gap = height/2 - upperBound.height() - middleBound.height() / 2;
+
+ if (gap > 0) {
+ TQString ch = TQString(TQChar(line));
+ int lineCount = tqRound( gap / lineHeight ) + 1;
+
+ pixel start = (height - middleBound.height()) / 2 + safety;
+ for (int i = 0; i < lineCount; i++) {
+ p.drawText( ptX, ptY-lineBound.top()+TQMAX( start-(i+1)*lineHeight,
+ upperBound.width() ),
+ ch );
+ }
+
+ start = (height + middleBound.height()) / 2 - safety;
+ for (int i = 0; i < lineCount; i++) {
+ p.drawText( ptX, ptY-lineBound.top()+TQMIN( start+i*lineHeight,
+ height-upperBound.width()-lineBound.height() ),
+ ch );
+ }
+ }
+}
+
+KFORMULA_NAMESPACE_END