summaryrefslogtreecommitdiffstats
path: root/lib/kformula/spaceelement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kformula/spaceelement.cpp')
-rw-r--r--lib/kformula/spaceelement.cpp431
1 files changed, 431 insertions, 0 deletions
diff --git a/lib/kformula/spaceelement.cpp b/lib/kformula/spaceelement.cpp
new file mode 100644
index 000000000..7d3723602
--- /dev/null
+++ b/lib/kformula/spaceelement.cpp
@@ -0,0 +1,431 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001 Andrea Rizzi <rizzi@kde.org>
+ Ulrich Kuettler <ulrich.kuettler@mailbox.tu-dresden.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 <tqfontmetrics.h>
+#include <tqpainter.h>
+
+#include <kdebug.h>
+#include <kprinter.h>
+
+#include "contextstyle.h"
+#include "elementvisitor.h"
+#include "spaceelement.h"
+
+
+KFORMULA_NAMESPACE_BEGIN
+
+
+SpaceElement::SpaceElement( SpaceWidth space, bool tab, BasicElement* parent )
+ : BasicElement( parent ),
+ m_tab( tab ),
+ m_widthType( NoSize ),
+ m_heightType( NoSize ),
+ m_depthType( NoSize ),
+ m_lineBreak( NoBreakType )
+{
+ // Backwards compatibility with KFO format
+ switch ( space ) {
+ case NEGTHIN:
+ m_widthType = NegativeThinMathSpace;
+ break;
+ case THIN:
+ m_widthType = ThinMathSpace;
+ break;
+ case MEDIUM:
+ m_widthType = MediumMathSpace;
+ break;
+ case THICK:
+ m_widthType = ThickMathSpace;
+ break;
+ case QUAD:
+ m_widthType = VeryVeryThickMathSpace;
+ break;
+ }
+}
+
+
+SpaceElement::SpaceElement( const SpaceElement& other )
+ : BasicElement( other ),
+ m_widthType( other.m_widthType ),
+ m_width( other.m_width ),
+ m_heightType( other.m_heightType ),
+ m_height( other.m_height ),
+ m_depthType( other.m_depthType ),
+ m_depth( other.m_depth ),
+ m_lineBreak( other.m_lineBreak )
+{
+}
+
+
+bool SpaceElement::accept( ElementVisitor* visitor )
+{
+ return visitor->visit( this );
+}
+
+
+void SpaceElement::calcSizes( const ContextStyle& context,
+ ContextStyle::TextStyle tstyle,
+ ContextStyle::IndexStyle /*istyle*/,
+ StyleAttributes& style )
+{
+ double factor = style.sizeFactor();
+ luPt mySize = context.getAdjustedSize( tstyle, factor );
+ TQFont font = context.getDefaultFont();
+ font.setPointSize( mySize );
+
+ TQFontMetrics fm( font );
+ TQChar w = 'M';
+ LuPixelRect hbound = fm.boundingRect( w );
+ TQChar h = 'x';
+ LuPixelRect vbound = fm.boundingRect( h );
+
+ double width = style.getSpace( m_widthType, m_width );
+ if ( m_widthType == AbsoluteSize ) {
+ width = m_width / context.layoutUnitPtToPt( context.getBaseSize() );
+ }
+ else if ( m_widthType == PixelSize ) {
+ width = context.pixelYToPt( m_width ) / context.layoutUnitPtToPt( context.getBaseSize() );
+ }
+ double height = style.getSpace( m_heightType, m_height );
+ if ( m_heightType == AbsoluteSize ) {
+ height = m_height / context.layoutUnitPtToPt( context.getBaseSize() );
+ }
+ else if ( m_heightType == PixelSize ) {
+ height = context.pixelYToPt( m_height ) / context.layoutUnitPtToPt( context.getBaseSize() );
+ }
+ double depth = style.getSpace( m_depthType, m_depth );
+ if ( m_depthType == AbsoluteSize ) {
+ depth = m_depth / context.layoutUnitPtToPt( context.getBaseSize() );
+ }
+ else if ( m_depthType == PixelSize ) {
+ depth = context.pixelYToPt( m_depth ) / context.layoutUnitPtToPt( context.getBaseSize() );
+ }
+
+ setWidth( hbound.width() * width );
+ setHeight( vbound.height() * height + vbound.height() * depth );
+ setBaseline( vbound.height() * height );
+
+ if ( m_tab ) {
+ getParent()->registerTab( this );
+ }
+}
+
+void SpaceElement::draw( TQPainter& painter, const LuPixelRect& /*r*/,
+ const ContextStyle& context,
+ ContextStyle::TextStyle /*tstyle*/,
+ ContextStyle::IndexStyle /*istyle*/,
+ StyleAttributes& /*style*/,
+ const LuPixelPoint& parentOrigin )
+{
+ LuPixelPoint myPos(parentOrigin.x()+getX(), parentOrigin.y()+getY());
+ // there is such a thing as negative space!
+ //if ( !LuPixelRect( myPos.x(), myPos.y(), getWidth(), getHeight() ).intersects( r ) )
+ // return;
+
+ if ( context.edit() ) {
+ painter.setPen( context.getEmptyColor() );
+ painter.drawLine( context.layoutUnitToPixelX( myPos.x() ),
+ context.layoutUnitToPixelY( myPos.y()+getHeight() ),
+ context.layoutUnitToPixelX( myPos.x()+getWidth()-1 ),
+ context.layoutUnitToPixelY( myPos.y()+getHeight() ) );
+ painter.drawLine( context.layoutUnitToPixelX( myPos.x() ),
+ context.layoutUnitToPixelY( myPos.y()+getHeight() ),
+ context.layoutUnitToPixelX( myPos.x() ),
+ context.layoutUnitToPixelY( myPos.y()+getHeight()-getHeight()/5 ) );
+ painter.drawLine( context.layoutUnitToPixelX( myPos.x()+getWidth()-1 ),
+ context.layoutUnitToPixelY( myPos.y()+getHeight() ),
+ context.layoutUnitToPixelX( myPos.x()+getWidth()-1 ),
+ context.layoutUnitToPixelY( myPos.y()+getHeight()-getHeight()/5 ) );
+ }
+}
+
+
+void SpaceElement::writeDom(TQDomElement element)
+{
+ BasicElement::writeDom(element);
+ switch ( m_widthType ) {
+ case NegativeVeryVeryThinMathSpace:
+ case NegativeVeryThinMathSpace:
+ case NegativeThinMathSpace:
+ case NegativeMediumMathSpace:
+ case NegativeThickMathSpace:
+ case NegativeVeryThickMathSpace:
+ case NegativeVeryVeryThickMathSpace:
+ element.setAttribute( "WIDTH", "negthin" );
+ break;
+ case VeryVeryThinMathSpace:
+ case VeryThinMathSpace:
+ case ThinMathSpace:
+ element.setAttribute( "WIDTH", "thin" );
+ break;
+ case MediumMathSpace:
+ element.setAttribute( "WIDTH", "medium" );
+ break;
+ case ThickMathSpace:
+ element.setAttribute( "WIDTH", "thick" );
+ break;
+ case VeryThickMathSpace:
+ case VeryVeryThickMathSpace:
+ element.setAttribute( "WIDTH", "quad" );
+ break;
+ case AbsoluteSize:
+ case RelativeSize:
+ case PixelSize:
+ if ( m_width < 0 ) {
+ element.setAttribute( "WIDTH", "negthin" );
+ }
+ else {
+ element.setAttribute( "WIDTH", "thin" );
+ }
+ default:
+ break;
+ }
+ if ( m_tab ) {
+ element.setAttribute( "TAB", "true" );
+ }
+}
+
+bool SpaceElement::readAttributesFromDom( TQDomElement element )
+{
+ if ( !BasicElement::readAttributesFromDom( element ) ) {
+ return false;
+ }
+ TQString widthStr = element.attribute( "WIDTH" );
+ if( !widthStr.isNull() ) {
+ if ( widthStr.lower() == "quad" ) {
+ m_widthType = VeryVeryThickMathSpace;
+ }
+ else if ( widthStr.lower() == "thick" ) {
+ m_widthType = ThickMathSpace;
+ }
+ else if ( widthStr.lower() == "medium" ) {
+ m_widthType = MediumMathSpace;
+ }
+ else if ( widthStr.lower() == "negthin" ) {
+ m_widthType = NegativeThinMathSpace;
+ }
+ else {
+ m_widthType = ThinMathSpace;
+ }
+ }
+ else {
+ return false;
+ }
+ TQString tabStr = element.attribute( "TAB" );
+ m_tab = !tabStr.isNull();
+ return true;
+}
+
+bool SpaceElement::readContentFromDom(TQDomNode& node)
+{
+ return BasicElement::readContentFromDom( node );
+}
+
+bool SpaceElement::readAttributesFromMathMLDom(const TQDomElement& element)
+{
+ if ( ! BasicElement::readAttributesFromMathMLDom( element ) ) {
+ return false;
+ }
+
+ TQString widthStr = element.attribute( "width" ).stripWhiteSpace().lower();
+ if ( ! widthStr.isNull() ) {
+ m_width = getSize( widthStr, &m_widthType );
+ if ( m_widthType == NoSize ) {
+ m_widthType = getSpace( widthStr );
+ }
+ }
+ TQString heightStr = element.attribute( "height" ).stripWhiteSpace().lower();
+ if ( ! heightStr.isNull() ) {
+ m_height = getSize( heightStr, &m_heightType );
+ }
+ TQString depthStr = element.attribute( "depth" ).stripWhiteSpace().lower();
+ if ( ! depthStr.isNull() ) {
+ m_depth = getSize( depthStr, &m_depthType );
+ }
+ TQString linebreakStr = element.attribute( "linebreak" ).stripWhiteSpace().lower();
+ if ( ! linebreakStr.isNull() ) {
+ if ( linebreakStr == "auto" ) {
+ m_lineBreak = AutoBreak;
+ }
+ else if ( linebreakStr == "newline" ) {
+ m_lineBreak = NewLineBreak;
+ }
+ else if ( linebreakStr == "indentingnewline" ) {
+ m_lineBreak = IndentingNewLineBreak;
+ }
+ else if ( linebreakStr == "nobreak" ) {
+ m_lineBreak = NoBreak;
+ }
+ else if ( linebreakStr == "goodbreak" ) {
+ m_lineBreak = GoodBreak;
+ }
+ else if ( linebreakStr == "badbreak" ) {
+ m_lineBreak = BadBreak;
+ }
+ }
+ return true;
+}
+
+void SpaceElement::writeMathMLAttributes( TQDomElement& element ) const
+{
+ switch ( m_widthType ) {
+ case AbsoluteSize:
+ element.setAttribute( "width", TQString( "%1pt" ).arg( m_width ) );
+ break;
+ case RelativeSize:
+ element.setAttribute( "width", TQString( "%1%" ).arg( m_width * 100.0 ) );
+ break;
+ case PixelSize:
+ element.setAttribute( "width", TQString( "%1px" ).arg( m_width ) );
+ break;
+ case NegativeVeryVeryThinMathSpace:
+ element.setAttribute( "width", "negativeveryverythinmathspace" );
+ break;
+ case NegativeVeryThinMathSpace:
+ element.setAttribute( "width", "negativeverythinmathspace" );
+ break;
+ case NegativeThinMathSpace:
+ element.setAttribute( "width", "negativethinmathspace" );
+ break;
+ case NegativeMediumMathSpace:
+ element.setAttribute( "width", "negativemediummathspace" );
+ break;
+ case NegativeThickMathSpace:
+ element.setAttribute( "width", "negativethickmathspace" );
+ break;
+ case NegativeVeryThickMathSpace:
+ element.setAttribute( "width", "negativeverythickmathspace" );
+ break;
+ case NegativeVeryVeryThickMathSpace:
+ element.setAttribute( "width", "negativeveryverythickmathspace" );
+ break;
+ case VeryVeryThinMathSpace:
+ element.setAttribute( "width", "veryverythinmathspace" );
+ break;
+ case VeryThinMathSpace:
+ element.setAttribute( "width", "verythinmathspace" );
+ break;
+ case ThinMathSpace:
+ element.setAttribute( "width", "thinmathspace" );
+ break;
+ case MediumMathSpace:
+ element.setAttribute( "width", "mediummathspace" );
+ break;
+ case ThickMathSpace:
+ element.setAttribute( "width", "thickmathspace" );
+ break;
+ case VeryThickMathSpace:
+ element.setAttribute( "width", "verythickmathspace" );
+ break;
+ case VeryVeryThickMathSpace:
+ element.setAttribute( "width", "veryverythickmathspace" );
+ break;
+ default:
+ break;
+ }
+ switch ( m_heightType ) {
+ case AbsoluteSize:
+ element.setAttribute( "height", TQString( "%1pt" ).arg( m_height ) );
+ break;
+ case RelativeSize:
+ element.setAttribute( "height", TQString( "%1%" ).arg( m_height * 100.0 ) );
+ break;
+ case PixelSize:
+ element.setAttribute( "height", TQString( "%1px" ).arg( m_height ) );
+ break;
+ default:
+ break;
+ }
+ switch ( m_depthType ) {
+ case AbsoluteSize:
+ element.setAttribute( "depth", TQString( "%1pt" ).arg( m_depth ) );
+ break;
+ case RelativeSize:
+ element.setAttribute( "depth", TQString( "%1%" ).arg( m_depth * 100.0 ) );
+ break;
+ case PixelSize:
+ element.setAttribute( "depth", TQString( "%1px" ).arg( m_depth ) );
+ break;
+ default:
+ break;
+ }
+ switch ( m_lineBreak ) {
+ case AutoBreak:
+ element.setAttribute( "linebreak", "auto" );
+ break;
+ case NewLineBreak:
+ element.setAttribute( "linebreak", "newline" );
+ break;
+ case IndentingNewLineBreak:
+ element.setAttribute( "linebreak", "indentingnewline" );
+ break;
+ case NoBreak:
+ element.setAttribute( "linebreak", "nobreak" );
+ break;
+ case GoodBreak:
+ element.setAttribute( "linebreak", "goodbreak" );
+ break;
+ case BadBreak:
+ element.setAttribute( "linebreak", "badbreak" );
+ break;
+ default:
+ break;
+ }
+}
+
+TQString SpaceElement::toLatex()
+{
+ switch ( m_widthType ) {
+ case NegativeVeryVeryThinMathSpace:
+ case NegativeVeryThinMathSpace:
+ case NegativeThinMathSpace:
+ case NegativeMediumMathSpace:
+ case NegativeThickMathSpace:
+ case NegativeVeryThickMathSpace:
+ case NegativeVeryVeryThickMathSpace:
+ return "\\!";
+ case VeryVeryThinMathSpace:
+ case VeryThinMathSpace:
+ case ThinMathSpace:
+ return "\\,";
+ case MediumMathSpace:
+ return "\\>";
+ case ThickMathSpace:
+ return "\\;";
+ case VeryThickMathSpace:
+ case VeryVeryThickMathSpace:
+ return "\\quad ";
+ case AbsoluteSize:
+ case RelativeSize:
+ case PixelSize:
+ if ( m_width < 0 ) {
+ return "\\!";
+ }
+ else {
+ return "\\,";
+ }
+ default:
+ break;
+ }
+ return "";
+}
+
+KFORMULA_NAMESPACE_END