diff options
Diffstat (limited to 'lib/kformula/styleelement.cpp')
-rw-r--r-- | lib/kformula/styleelement.cpp | 390 |
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 |