summaryrefslogtreecommitdiffstats
path: root/lib/kformula/styleelement.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/kformula/styleelement.cpp')
-rw-r--r--lib/kformula/styleelement.cpp390
1 files changed, 390 insertions, 0 deletions
diff --git a/lib/kformula/styleelement.cpp b/lib/kformula/styleelement.cpp
new file mode 100644
index 00000000..de760453
--- /dev/null
+++ b/lib/kformula/styleelement.cpp
@@ -0,0 +1,390 @@
+/* This file is part of the KDE project
+ 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 "basicelement.h"
+#include "styleelement.h"
+
+KFORMULA_NAMESPACE_BEGIN
+
+StyleElement::StyleElement( BasicElement* parent ) : TokenStyleElement( parent ),
+ m_scriptMinSizeType( NoSize ),
+ m_veryVeryThinMathSpaceType( NoSize ),
+ m_veryThinMathSpaceType( NoSize ),
+ m_thinMathSpaceType( NoSize ),
+ m_mediumMathSpaceType( NoSize ),
+ m_thickMathSpaceType( NoSize ),
+ m_veryThickMathSpaceType( NoSize ),
+ m_veryVeryThickMathSpaceType( NoSize ),
+ m_customScriptLevel( false ),
+ m_relativeScriptLevel( false ),
+ m_customDisplayStyle( false ),
+ m_customScriptSizeMultiplier( false ),
+ m_customBackground( false )
+{
+}
+
+bool StyleElement::readAttributesFromMathMLDom( const TQDomElement& element )
+{
+ if ( !BasicElement::readAttributesFromMathMLDom( element ) ) {
+ return false;
+ }
+
+ TQString scriptlevelStr = element.attribute( "scriptlevel" );
+ if ( ! scriptlevelStr.isNull() ) {
+ if ( scriptlevelStr[0] == '+' || scriptlevelStr[0] == '-' ) {
+ m_relativeScriptLevel = true;
+ }
+ bool ok;
+ m_scriptLevel = scriptlevelStr.toInt( &ok );
+ if ( ! ok ) {
+ kdWarning( DEBUGID ) << "Invalid scriptlevel attribute value: "
+ << scriptlevelStr << endl;
+ }
+ else {
+ m_customScriptLevel = true;
+ }
+ }
+ TQString displaystyleStr = element.attribute( "displaystyle" );
+ if ( ! displaystyleStr.isNull() ) {
+ if ( displaystyleStr.lower() == "true" ) {
+ m_displayStyle = true;
+ }
+ else {
+ m_displayStyle = false;
+ }
+ m_customDisplayStyle = true;
+ }
+ TQString scriptsizemultiplierStr = element.attribute( "scriptsizemultiplier" );
+ if ( ! scriptsizemultiplierStr.isNull() ) {
+ bool ok;
+ m_scriptSizeMultiplier = scriptsizemultiplierStr.toDouble( &ok );
+ if ( ! ok ) {
+ kdWarning( DEBUGID ) << "Invalid scriptsizemultiplier attribute value: "
+ << scriptsizemultiplierStr << endl;
+ }
+ else {
+ m_customScriptSizeMultiplier = true;
+ }
+ }
+ TQString scriptminsizeStr = element.attribute( "scriptminsize" );
+ if ( ! scriptminsizeStr.isNull() ) {
+ readSizeAttribute( scriptminsizeStr, &m_scriptMinSizeType, &m_scriptMinSize );
+ }
+ TQString backgroundStr = element.attribute( "background" );
+ if ( ! backgroundStr.isNull() ) {
+ // TODO: tranparent background
+ m_customBackground = true;
+ if ( backgroundStr[0] != '#' ) {
+ m_background = TQColor( getHtmlColor( backgroundStr ) );
+ }
+ else {
+ m_background = TQColor( backgroundStr );
+ }
+ }
+ TQString veryverythinmathspaceStr = element.attribute( "veryverythinmathspace" );
+ if ( ! veryverythinmathspaceStr.isNull() ) {
+ readSizeAttribute( veryverythinmathspaceStr, &m_veryVeryThinMathSpaceType, &m_veryVeryThinMathSpace );
+ }
+ TQString verythinmathspaceStr = element.attribute( "verythinmathspace" );
+ if ( ! verythinmathspaceStr.isNull() ) {
+ readSizeAttribute( verythinmathspaceStr, &m_veryThinMathSpaceType, &m_veryThinMathSpace );
+ }
+ TQString thinmathspaceStr = element.attribute( "thinmathspace" );
+ if ( ! thinmathspaceStr.isNull() ) {
+ readSizeAttribute( thinmathspaceStr, &m_thinMathSpaceType, &m_thinMathSpace );
+ }
+ TQString mediummathspaceStr = element.attribute( "mediummathspace" );
+ if ( ! mediummathspaceStr.isNull() ) {
+ readSizeAttribute( mediummathspaceStr, &m_mediumMathSpaceType, &m_mediumMathSpace );
+ }
+ TQString thickmathspaceStr = element.attribute( "thickmathspace" );
+ if ( ! thickmathspaceStr.isNull() ) {
+ readSizeAttribute( thickmathspaceStr, &m_thickMathSpaceType, &m_thickMathSpace );
+ }
+ TQString verythickmathspaceStr = element.attribute( "verythickmathspace" );
+ if ( ! verythickmathspaceStr.isNull() ) {
+ readSizeAttribute( verythickmathspaceStr, &m_veryThickMathSpaceType, &m_veryThickMathSpace );
+ }
+ TQString veryverythickmathspaceStr = element.attribute( "veryverythickmathspace" );
+ if ( ! veryverythickmathspaceStr.isNull() ) {
+ readSizeAttribute( veryverythickmathspaceStr, &m_veryVeryThickMathSpaceType, &m_veryVeryThickMathSpace );
+ }
+ return inherited::readAttributesFromMathMLDom( element );
+}
+
+void StyleElement::writeMathMLAttributes( TQDomElement& element ) const
+{
+ if ( m_customScriptLevel ) {
+ TQString prefix;
+ if ( m_relativeScriptLevel && m_scriptLevel >= 0 ) {
+ prefix = "+";
+ }
+ element.setAttribute( "scriptlevel", prefix + TQString( "%1" ).arg( m_scriptLevel ) );
+ }
+ if ( m_customDisplayStyle ) {
+ element.setAttribute( "displaystyle", m_displayStyle ? "true" : "false" );
+ }
+ if ( m_customScriptSizeMultiplier ) {
+ element.setAttribute( "scriptsizemultiplier", TQString( "%1" ).arg( m_scriptSizeMultiplier ) );
+ }
+ writeSizeAttribute( element, "scriptminsize", m_scriptMinSizeType, m_scriptMinSize );
+ if ( m_customBackground ) {
+ element.setAttribute( "background", m_background.name() );
+ }
+ writeSizeAttribute( element, "veryverythinmathspace", m_veryVeryThinMathSpaceType, m_veryVeryThinMathSpace );
+ writeSizeAttribute( element, "verythinmathspace", m_veryThinMathSpaceType, m_veryThinMathSpace );
+ writeSizeAttribute( element, "thinmathspace", m_thinMathSpaceType, m_thinMathSpace );
+ writeSizeAttribute( element, "mediummathspace", m_mediumMathSpaceType, m_mediumMathSpace );
+ writeSizeAttribute( element, "thickmathspace", m_thickMathSpaceType, m_thickMathSpace );
+ writeSizeAttribute( element, "verythickmathspace", m_veryThickMathSpaceType, m_veryThickMathSpace );
+ writeSizeAttribute( element, "veryverythickmathspace", m_veryVeryThickMathSpaceType, m_veryVeryThickMathSpace );
+
+ inherited::writeMathMLAttributes( element );
+}
+
+
+void StyleElement::setStyleSize( const ContextStyle& context, StyleAttributes& style )
+{
+ if ( m_customScriptLevel ) {
+ if ( m_relativeScriptLevel ) {
+ style.setScriptLevel( style.scriptLevel() + m_scriptLevel );
+ }
+ else {
+ style.setScriptLevel( m_scriptLevel );
+ }
+ }
+ else {
+ style.setScriptLevel( style.scriptLevel() );
+ }
+ if ( m_customDisplayStyle || style.customDisplayStyle() ) {
+ style.setCustomDisplayStyle( true );
+ if ( m_customDisplayStyle ) {
+ style.setDisplayStyle( m_displayStyle );
+ }
+ else {
+ style.setDisplayStyle( style.displayStyle() );
+ }
+ }
+ else {
+ style.setCustomDisplayStyle( false );
+ }
+ if ( m_customScriptSizeMultiplier ) {
+ style.setScriptSizeMultiplier( m_scriptSizeMultiplier );
+ }
+ else {
+ style.setScriptSizeMultiplier( style.scriptSizeMultiplier() );
+ }
+
+ // Get scriptminsize attribute in absolute units, so we don't depend on
+ // context to get the default value
+ double basesize = context.layoutUnitPtToPt( context.getBaseSize() );
+ double size = style.scriptMinSize();
+ switch ( m_scriptMinSizeType ) {
+ case AbsoluteSize:
+ size = m_scriptMinSize;
+ case RelativeSize:
+ size = m_scriptMinSize * basesize;
+ case PixelSize:
+ size = context.pixelXToPt( m_scriptMinSize );
+ default:
+ break;
+ }
+ style.setScriptMinSize( size );
+
+ style.setVeryVeryThinMathSpace( sizeFactor( context,
+ m_veryVeryThinMathSpaceType,
+ m_veryVeryThinMathSpace,
+ style.veryVeryThinMathSpace() ));
+ style.setVeryThinMathSpace( sizeFactor( context, m_veryThinMathSpaceType,
+ m_veryThinMathSpace,
+ style.veryThinMathSpace() ));
+ style.setThinMathSpace( sizeFactor( context, m_thinMathSpaceType,
+ m_thinMathSpace,
+ style.thinMathSpace() ));
+ style.setMediumMathSpace( sizeFactor( context, m_mediumMathSpaceType,
+ m_mediumMathSpace,
+ style.mediumMathSpace() ));
+ style.setThickMathSpace( sizeFactor( context, m_thickMathSpaceType,
+ m_thickMathSpace,
+ style.thickMathSpace() ));
+ style.setVeryThickMathSpace( sizeFactor( context, m_veryThickMathSpaceType,
+ m_veryThickMathSpace,
+ style.veryThickMathSpace() ));
+ style.setVeryVeryThickMathSpace( sizeFactor( context,
+ m_veryVeryThickMathSpaceType,
+ m_veryVeryThickMathSpace,
+ style.veryVeryThickMathSpace() ));
+ inherited::setStyleSize( context, style );
+}
+
+double StyleElement::sizeFactor( const ContextStyle& context, SizeType st,
+ double length, double defvalue )
+{
+ double basesize = context.layoutUnitPtToPt( context.getBaseSize() );
+ switch ( st ) {
+ case AbsoluteSize:
+ return length / basesize;
+ case RelativeSize:
+ return length;
+ case PixelSize:
+ return context.pixelXToPt( length ) / basesize;
+ default:
+ break;
+ }
+ return defvalue;
+}
+
+void StyleElement::setStyleVariant( StyleAttributes& style )
+{
+ if ( customMathVariant() ) {
+ style.setCustomMathVariant ( true );
+ style.setCustomFontWeight( false );
+ style.setCustomFontStyle( false );
+ style.setCustomFont( false );
+ if ( customMathVariant() ) {
+ style.setCharFamily ( charFamily() );
+ style.setCharStyle( charStyle() );
+ }
+ else {
+ style.setCharFamily( style.charFamily() );
+ style.setCharStyle( style.charStyle() );
+ }
+ }
+ else {
+ style.setCustomMathVariant( false );
+ if ( customFontFamily() ) {
+ style.setCustomFont( true );
+ style.setFont( TQFont(fontFamily()) );
+ }
+
+ bool fontweight = false;
+ if ( customFontWeight() || style.customFontWeight() ) {
+ style.setCustomFontWeight( true );
+ if ( customFontWeight() ) {
+ fontweight = fontWeight();
+ }
+ else {
+ fontweight = style.fontWeight();
+ }
+ style.setFontWeight( fontweight );
+ }
+ else {
+ style.setCustomFontWeight( false );
+ }
+
+ bool fontstyle = false;
+ if ( customFontStyle() || style.customFontStyle() ) {
+ style.setCustomFontStyle( true );
+ if ( customFontStyle() ) {
+ fontstyle = fontStyle();
+ }
+ else {
+ fontstyle = style.fontStyle();
+ }
+ style.setFontStyle( fontstyle );
+ }
+ else {
+ style.setCustomFontStyle( false );
+ }
+
+ if ( fontweight && fontstyle ) {
+ style.setCharStyle( boldItalicChar );
+ }
+ else if ( fontweight && ! fontstyle ) {
+ style.setCharStyle( boldChar );
+ }
+ else if ( ! fontweight && fontstyle ) {
+ style.setCharStyle( italicChar );
+ }
+ else {
+ style.setCharStyle( normalChar );
+ }
+ }
+}
+
+void StyleElement::setStyleBackground( StyleAttributes& style )
+{
+ if ( customMathBackground() ) {
+ style.setBackground( mathBackground() );
+ }
+ else if ( m_customBackground ) {
+ style.setBackground( m_background );
+ }
+ else {
+ style.setBackground( style.background() );
+ }
+}
+
+void StyleElement::resetStyle( StyleAttributes& style )
+{
+ inherited::resetStyle( style );
+ style.resetScriptLevel();
+ style.resetScriptSizeMultiplier();
+ style.resetScriptMinSize();
+ style.resetVeryVeryThinMathSpace();
+ style.resetVeryThinMathSpace();
+ style.resetThinMathSpace();
+ style.resetMediumMathSpace();
+ style.resetThickMathSpace();
+ style.resetVeryThickMathSpace();
+ style.resetVeryVeryThickMathSpace();
+ style.resetDisplayStyle();
+}
+
+void StyleElement::readSizeAttribute( const TQString& str, SizeType* st, double* s )
+{
+ if ( st == 0 || s == 0 ){
+ return;
+ }
+ if ( str == "small" ) {
+ *st = RelativeSize;
+ *s = 0.8; // ### Arbitrary size
+ }
+ else if ( str == "normal" ) {
+ *st = RelativeSize;
+ *s = 1.0;
+ }
+ else if ( str == "big" ) {
+ *st = RelativeSize;
+ *s = 1.2; // ### Arbitrary size
+ }
+ else {
+ *s = getSize( str, st );
+ }
+}
+
+void StyleElement::writeSizeAttribute( TQDomElement element, const TQString& str, SizeType st, double s ) const
+{
+ switch ( st ) {
+ case AbsoluteSize:
+ element.setAttribute( str, TQString( "%1pt" ).arg( s ) );
+ break;
+ case RelativeSize:
+ element.setAttribute( str, TQString( "%1%" ).arg( s * 100.0 ) );
+ break;
+ case PixelSize:
+ element.setAttribute( str, TQString( "%1px" ).arg( s ) );
+ break;
+ default:
+ break;
+ }
+}
+
+
+KFORMULA_NAMESPACE_END