summaryrefslogtreecommitdiffstats
path: root/ksvg/impl/SVGStylableImpl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'ksvg/impl/SVGStylableImpl.cpp')
-rw-r--r--ksvg/impl/SVGStylableImpl.cpp1307
1 files changed, 1307 insertions, 0 deletions
diff --git a/ksvg/impl/SVGStylableImpl.cpp b/ksvg/impl/SVGStylableImpl.cpp
new file mode 100644
index 00000000..4400b236
--- /dev/null
+++ b/ksvg/impl/SVGStylableImpl.cpp
@@ -0,0 +1,1307 @@
+/*
+ Copyright (C) 2001-2003 KSVG Team
+ This file is part of the KDE project
+
+ 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 <kdebug.h>
+
+#include <tqrect.h>
+
+#include "CanvasItem.h"
+#include "KSVGCanvas.h"
+
+#include "SVGPaint.h"
+#include "SVGColorImpl.h"
+#include "SVGPaintImpl.h"
+#include "SVGHelperImpl.h"
+#include "SVGLengthImpl.h"
+#include "SVGDocumentImpl.h"
+#include "SVGStylableImpl.h"
+#include "SVGSVGElementImpl.h"
+#include "SVGStringListImpl.h"
+#include "SVGImageElementImpl.h"
+#include "SVGURIReferenceImpl.h"
+#include "SVGAnimatedLengthImpl.h"
+#include "SVGColorProfileElementImpl.h"
+#include "SVGAnimatedLengthListImpl.h"
+
+using namespace KSVG;
+
+#include "SVGStylableImpl.lut.h"
+#include "ksvg_scriptinterpreter.h"
+#include "ksvg_bridge.h"
+#include "ksvg_ecma.h"
+
+SVGStylableImpl::SVGStylableImpl(SVGElementImpl *object) : m_object(object)
+{
+ KSVG_EMPTY_FLAGS
+
+ // View propidx.html, if you want to verify those default values (Niko)
+ m_flags = SVG_STYLE_FLAG_NONE;
+
+ // Initialize all pointers to 0
+ // Important!
+ m_color = 0;
+ m_fillColor = 0;
+ m_stopColor = 0;
+ m_dashArray = 0;
+ m_dashOffset = 0;
+ m_strokeWidth = 0;
+ m_strokeColor = 0;
+ m_fontFamily = 0;
+
+ m_fillOpacity = 1;
+ m_strokeOpacity = 1;
+ m_opacity = 1;
+
+ // Special case, getFontSize() could be accessed
+ // _before_ processStyle() is called -> no default
+ // value for font-size yet -> crash
+ // SVGLengthImpl access it when parsing em/ex values (Niko)
+ m_fontSize = -1;
+}
+
+SVGStylableImpl::~SVGStylableImpl()
+{
+ if(m_strokeWidth)
+ m_strokeWidth->deref();
+ if(m_fontFamily)
+ m_fontFamily->deref();
+ if(m_strokeColor)
+ m_strokeColor->deref();
+ if(m_fillColor)
+ m_fillColor->deref();
+ if(m_color)
+ m_color->deref();
+ if(m_stopColor)
+ m_stopColor->deref();
+ if(m_dashOffset)
+ m_dashOffset->deref();
+ if(m_dashArray)
+ m_dashArray->deref();
+}
+
+void SVGStylableImpl::processStyle()
+{
+ SVGStylableImpl *parentStyle = 0;
+ if(m_object && m_object->ownerDoc())
+ parentStyle = dynamic_cast<SVGStylableImpl *>(m_object->ownerDoc()->getElementFromHandle((*m_object).parentNode().handle()));
+
+ // Spec: default "none"
+ if(~m_flags & SVG_STYLE_FLAG_STROKE)
+ {
+ m_strokeColor = new SVGPaintImpl(m_object);
+ m_strokeColor->ref();
+
+ SVGPaintImpl *strokeColor = 0L;
+ if(parentStyle)
+ strokeColor = parentStyle->getStrokeColor();
+
+ if(strokeColor)
+ *m_strokeColor = *strokeColor;
+ else
+ m_strokeColor->setPaint(SVG_PAINTTYPE_NONE);
+ }
+
+ // Spec: default "black"
+ if(~m_flags & SVG_STYLE_FLAG_FILL)
+ {
+ m_fillColor = new SVGPaintImpl(m_object);
+ m_fillColor->ref();
+
+ SVGPaintImpl *fillColor = 0;
+ if(parentStyle)
+ fillColor = parentStyle->getFillColor();
+
+ if(fillColor)
+ *m_fillColor = *fillColor;
+ else
+ m_fillColor->setRGBColor(DOM::DOMString("black"));
+ }
+
+ // Spec: no real default
+ if(~m_flags & SVG_STYLE_FLAG_COLOR)
+ {
+ m_color = new SVGColorImpl(m_object);
+ m_color->ref();
+ SVGColorImpl *color = 0;
+ if(parentStyle)
+ color = parentStyle->getColor();
+
+ if(color)
+ *m_color = *color;
+ }
+
+ // Spec: default sRGB
+ if(~m_flags & SVG_STYLE_FLAG_COLOR_INTERPOLATION)
+ {
+ if(parentStyle)
+ m_colorInterpolation = parentStyle->getColorInterpolation();
+ else
+ m_colorInterpolation = CI_SRGB;
+ }
+
+ // Spec: default "1"
+ if(~m_flags & SVG_STYLE_FLAG_STROKE_WIDTH)
+ {
+ m_strokeWidth = new SVGAnimatedLengthImpl(LENGTHMODE_OTHER, m_object);
+ m_strokeWidth->ref();
+
+ SVGAnimatedLengthImpl *strokeWidth = 0;
+ if(parentStyle)
+ strokeWidth = parentStyle->getStrokeWidth();
+
+ if(strokeWidth)
+ *m_strokeWidth = *strokeWidth;
+ else
+ m_strokeWidth->baseVal()->setValue(1.0);
+ }
+
+ // Spec: default "4"
+ if(~m_flags & SVG_STYLE_FLAG_STROKE_MITER_LIMIT)
+ {
+ if(parentStyle)
+ m_strokeMiterlimit = parentStyle->getStrokeMiterlimit();
+ else
+ m_strokeMiterlimit = 4;
+ }
+
+ // Spec: default "butt"
+ if(~m_flags & SVG_STYLE_FLAG_STROKE_LINE_CAP)
+ {
+ if(parentStyle)
+ m_capStyle = parentStyle->getCapStyle();
+ else
+ m_capStyle = PATH_STROKE_CAP_BUTT;
+ }
+
+ // Spec: default "miter"
+ if(~m_flags & SVG_STYLE_FLAG_STROKE_LINE_JOIN)
+ {
+ if(parentStyle)
+ m_joinStyle = parentStyle->getJoinStyle();
+ else
+ m_joinStyle = PATH_STROKE_JOIN_MITER;
+ }
+
+ // Spec: default "auto"
+ if(~m_flags & SVG_STYLE_FLAG_CURSOR)
+ {
+ if(parentStyle)
+ m_cursor = parentStyle->getCursor();
+ else
+ m_cursor = CURSOR_AUTO;
+ }
+
+ // Spec: default "visiblePainted"
+ if(~m_flags & SVG_STYLE_FLAG_POINTER_EVENTS)
+ {
+ if(parentStyle)
+ m_pointerEvents = parentStyle->getPointerEvents();
+ else
+ m_pointerEvents = PE_VISIBLE_PAINTED;
+ }
+
+ // Spec: default "0"
+ if(~m_flags & SVG_STYLE_FLAG_STROKE_DASH_OFFSET)
+ {
+ m_dashOffset = new SVGAnimatedLengthImpl(LENGTHMODE_OTHER, m_object);
+ m_dashOffset->ref();
+
+ SVGAnimatedLengthImpl *dashOffset = 0;
+ if(parentStyle)
+ dashOffset = parentStyle->getDashOffset();
+
+ if(dashOffset)
+ *m_dashOffset = *dashOffset;
+ else
+ m_dashOffset->baseVal()->setValue(0);
+ }
+
+ // Spec: default "none" -> 0 == empty dash array
+ if(~m_flags & SVG_STYLE_FLAG_STROKE_DASH_ARRAY)
+ {
+ SVGAnimatedLengthListImpl *dashArray = 0;
+ if(parentStyle)
+ dashArray = parentStyle->getDashArray();
+
+ if(dashArray)
+ {
+ if (!m_dashArray)
+ {
+ m_dashArray = new SVGAnimatedLengthListImpl();
+ m_dashArray->ref();
+ }
+ *m_dashArray = *dashArray;
+ }
+ else
+ m_dashArray = 0;
+ }
+
+ // Spec: default "1" -> 1 == Not opaque
+ if(~m_flags & SVG_STYLE_FLAG_FILL_OPACITY)
+ {
+ if(parentStyle)
+ m_fillOpacity = parentStyle->getFillOpacity();
+ else
+ m_fillOpacity = 1;
+ }
+
+ if(~m_flags & SVG_STYLE_FLAG_STROKE_OPACITY)
+ {
+ if(parentStyle)
+ m_strokeOpacity = parentStyle->getStrokeOpacity();
+ else
+ m_strokeOpacity = 1;
+ }
+
+ // Fake group opacity by multiplying by our parent's group opacity
+ if(~m_flags & SVG_STYLE_FLAG_OPACITY)
+ {
+ if(parentStyle)
+ m_opacity = parentStyle->getOpacity();
+ else
+ m_opacity = 1;
+ }
+ else
+ if(parentStyle)
+ m_opacity *= parentStyle->getOpacity();
+
+ if(~m_flags & SVG_STYLE_FLAG_CLIP_PATH)
+ m_clipPath = "";
+
+ if(~m_flags & SVG_STYLE_FLAG_MASK)
+ m_mask = "";
+
+ // Spec: default "nonzero"
+ if(~m_flags & SVG_STYLE_FLAG_FILL_RULE)
+ {
+ if(parentStyle)
+ m_fillRule = parentStyle->getFillRule();
+ else
+ m_fillRule = RULE_NONZERO;
+ }
+
+ if(~m_flags & SVG_STYLE_FLAG_CLIP_RULE)
+ {
+ if(parentStyle)
+ m_clipRule = parentStyle->getClipRule();
+ else
+ m_clipRule = RULE_NONZERO;
+ }
+
+ // Spec: default "hidden"
+ if(~m_flags & SVG_STYLE_FLAG_OVERFLOW)
+ {
+ if(parentStyle)
+ m_overflow = parentStyle->getOverflow();
+ else
+ m_overflow = false;
+ }
+
+ // We are not really, spec compatible here, we just
+ // define a bool, to indicate wheter an element should
+ // be rendered or not.
+ if(~m_flags & SVG_STYLE_FLAG_DISPLAY)
+ m_display = true;
+
+ if(~m_flags & SVG_STYLE_FLAG_VISIBILITY)
+ {
+ if(parentStyle)
+ m_visible = parentStyle->getVisible();
+ else
+ m_visible = true;
+ }
+
+ // Spec: default "medium"
+ if(~m_flags & SVG_STYLE_FLAG_FONT_SIZE)
+ {
+ if(parentStyle)
+ m_fontSize = parentStyle->getFontSize();
+ else
+ m_fontSize = fontSizeForText("medium");
+ }
+
+ // Spec: default "depends on user agent" -> "Arial" for SVG
+ if(~m_flags & SVG_STYLE_FLAG_FONT_FAMILY)
+ {
+ if(!m_fontFamily)
+ {
+ m_fontFamily = new SVGStringListImpl();
+ m_fontFamily->ref();
+ }
+
+ SVGStringListImpl *fontFamily = 0;
+ if(parentStyle)
+ fontFamily = parentStyle->getFontFamily();
+
+ if(fontFamily)
+ *m_fontFamily = *fontFamily;
+ else
+ {
+ SharedString *string = new SharedString("Arial");
+ string->ref();
+
+ m_fontFamily->appendItem(string);
+ }
+ }
+
+ // Spec: default "normal"
+ if(~m_flags & SVG_STYLE_FLAG_FONT_STYLE)
+ {
+ if(parentStyle)
+ m_fontStyle = parentStyle->getFontStyle();
+ else
+ m_fontStyle = FSNORMAL;
+ }
+
+ // Spec: default "normal"
+ if(~m_flags & SVG_STYLE_FLAG_FONT_WEIGHT)
+ {
+ if(parentStyle)
+ m_fontWeight = parentStyle->getFontWeight();
+ else
+ m_fontWeight = "normal";
+ }
+
+ // Spec: default "start"
+ if(~m_flags & SVG_STYLE_FLAG_TEXT_ANCHOR)
+ {
+ if(parentStyle)
+ m_textAnchor = parentStyle->getTextAnchor();
+ else
+ m_textAnchor = TASTART;
+ }
+
+ // Spec: default "LTR"
+ if(~m_flags & SVG_STYLE_FLAG_TEXT_DIRECTION)
+ {
+ if(parentStyle)
+ m_textDirection = parentStyle->getTextDirection();
+ else
+ m_textDirection = LTR;
+ }
+
+ // Spec: default "none"
+ if(~m_flags & SVG_STYLE_FLAG_TEXT_DECORATION)
+ {
+ if(parentStyle)
+ m_textDecoration = parentStyle->getTextDecoration();
+ else
+ m_textDecoration = TDNONE;
+ }
+
+ // Spec: default "baseline"
+ if(~m_flags & SVG_STYLE_FLAG_BASELINE_SHIFT)
+ {
+ if(parentStyle)
+ m_baselineShift = parentStyle->getBaselineShift();
+ else
+ m_baselineShift = "baseline";
+ }
+
+ // Spec: default "lr-tb", FIXME
+ if(~m_flags & SVG_STYLE_FLAG_TEXT_WRITING_MODE)
+ {
+ if(parentStyle)
+ m_textWritingMode = parentStyle->getTextWritingMode();
+ else
+ m_textWritingMode = LR;
+ }
+
+ // Spec: default "normal"
+ if(~m_flags & SVG_STYLE_FLAG_TEXT_UNICODE_BIDI)
+ {
+ if(parentStyle)
+ m_textUnicodeBidi = parentStyle->getTextUnicodeBidi();
+ else
+ m_textUnicodeBidi = UBNORMAL;
+ }
+
+ // Spec: default "auto"
+ if(~m_flags & SVG_STYLE_FLAG_GLYPH_ORIENTATION_VERTICAL)
+ {
+ if(parentStyle)
+ m_glyphOrientationVertical = parentStyle->getGlyphOrientationVertical();
+ else
+ m_glyphOrientationVertical = "auto";
+ }
+
+ // Spec: default "auto"
+ if(~m_flags & SVG_STYLE_FLAG_GLYPH_ORIENTATION_HORIZONTAL)
+ {
+ if(parentStyle)
+ m_glyphOrientationHorizontal = parentStyle->getGlyphOrientationHorizontal();
+ else
+ m_glyphOrientationHorizontal = "auto";
+ }
+
+ // Spec: default "normal"
+ if(~m_flags & SVG_STYLE_FLAG_LETTER_SPACING)
+ {
+ if(parentStyle)
+ m_letterSpacing = parentStyle->getLetterSpacing();
+ else
+ m_letterSpacing = "normal";
+ }
+
+ // Spec: default "normal"
+ if(~m_flags & SVG_STYLE_FLAG_WORD_SPACING)
+ {
+ if(parentStyle)
+ m_wordSpacing = parentStyle->getWordSpacing();
+ else
+ m_wordSpacing = "normal";
+ }
+
+ // Spec: default "black"
+ if(~m_flags & SVG_STYLE_FLAG_STOP)
+ {
+ m_stopColor = new SVGColorImpl(m_object);
+ m_stopColor->ref();
+
+ m_stopColor->setRGBColor(DOM::DOMString("black"));
+ }
+
+ // Spec: default "none"
+ if(~m_flags & SVG_STYLE_FLAG_MARKER_START)
+ {
+ if(parentStyle)
+ m_startMarker = parentStyle->getStartMarker();
+ else
+ m_startMarker = TQString();
+ }
+
+ // Spec: default "none"
+ if(~m_flags & SVG_STYLE_FLAG_MARKER_MID)
+ {
+ if(parentStyle)
+ m_midMarker = parentStyle->getMidMarker();
+ else
+ m_midMarker = TQString();
+ }
+
+ // Spec: default "none"
+ if(~m_flags & SVG_STYLE_FLAG_MARKER_END)
+ {
+ if(parentStyle)
+ m_endMarker = parentStyle->getEndMarker();
+ else
+ m_endMarker = TQString();
+ }
+}
+
+bool SVGStylableImpl::isStroked() const
+{
+ if(!m_strokeColor)
+ return false;
+
+ return m_strokeColor->paintType() != SVG_PAINTTYPE_UNKNOWN &&
+ m_strokeColor->paintType() != SVG_PAINTTYPE_NONE &&
+ m_strokeColor->paintType() != SVG_PAINTTYPE_URI_NONE;
+}
+
+bool SVGStylableImpl::isFilled() const
+{
+ if(!m_fillColor)
+ return false;
+
+ return m_fillColor->paintType() != SVG_PAINTTYPE_UNKNOWN &&
+ m_fillColor->paintType() != SVG_PAINTTYPE_NONE &&
+ m_fillColor->paintType() != SVG_PAINTTYPE_URI_NONE;
+}
+
+TQString SVGStylableImpl::extractUrlId(const TQString &url)
+{
+ TQString id;
+
+ if(url.startsWith("url(#"))
+ {
+ int idstart = url.find("#") + 1;
+ id = url.mid(idstart, url.length() - idstart - 1);
+ }
+ else
+ id = url;
+
+ return id;
+}
+
+void SVGStylableImpl::setMarkers(const TQString &marker)
+{
+ setStartMarker(marker);
+ setMidMarker(marker);
+ setEndMarker(marker);
+}
+
+void SVGStylableImpl::setStartMarker(const TQString &startMarker)
+{
+ if(startMarker.startsWith("url(#"))
+ {
+ int idstart = startMarker.find("#") + 1;
+ m_startMarker = startMarker.mid(idstart, startMarker.length() - idstart - 1);
+ }
+ else if(startMarker == "none")
+ m_startMarker = TQString();
+}
+
+void SVGStylableImpl::setMidMarker(const TQString &midMarker)
+{
+ if(midMarker.startsWith("url(#"))
+ {
+ int idstart = midMarker.find("#") + 1;
+ m_midMarker = midMarker.mid(idstart, midMarker.length() - idstart - 1);
+ }
+ else if(midMarker == "none")
+ m_midMarker = TQString();
+}
+
+void SVGStylableImpl::setEndMarker(const TQString &endMarker)
+{
+ if(endMarker.startsWith("url(#"))
+ {
+ int idstart = endMarker.find("#") + 1;
+ m_endMarker = endMarker.mid(idstart, endMarker.length() - idstart - 1);
+ }
+ else if(endMarker == "none")
+ m_endMarker = TQString();
+}
+
+bool SVGStylableImpl::hasMarkers() const
+{
+ return !m_startMarker.isEmpty() || !m_midMarker.isEmpty() || !m_endMarker.isEmpty();
+}
+
+void SVGStylableImpl::setPaint(const TQString &param, SVGPaintImpl *svgPaint)
+{
+ if(param.stripWhiteSpace() == "none")
+ svgPaint->setPaint(SVG_PAINTTYPE_NONE, DOM::DOMString(""), DOM::DOMString(""));
+ else if(SVGURIReferenceImpl::isUrl(param))
+ svgPaint->setUri(SVGURIReferenceImpl::getTarget(param));
+ else
+ setColor(param, svgPaint);
+}
+
+void SVGStylableImpl::setColor(const TQString &param, SVGColorImpl *svgColor)
+{
+ if(param.stripWhiteSpace().startsWith("#"))
+ {
+ if(param.contains("icc-color"))
+ {
+ TQString first = param.left(7);
+ TQString last = param.right(param.length() - 8);
+
+ svgColor->setRGBColorICCColor(first, last);
+ }
+ else
+ {
+ TQColor color;
+ color.setNamedColor(param.stripWhiteSpace());
+ svgColor->setRGBColor(color);
+ }
+ }
+ else if(param.stripWhiteSpace().startsWith("rgb("))
+ {
+ TQString parse = param.stripWhiteSpace();
+ TQStringList colors = TQStringList::split(',', parse);
+ TQString r = colors[0].right((colors[0].length() - 4));
+ TQString g = colors[1];
+ TQString b = colors[2].left((colors[2].length() - 1));
+
+ if(r.contains("%"))
+ {
+ r = r.left(r.length() - 1);
+ r = TQString::number(int((double(255 * r.toDouble()) / 100.0)));
+ }
+
+ if(g.contains("%"))
+ {
+ g = g.left(g.length() - 1);
+ g = TQString::number(int((double(255 * g.toDouble()) / 100.0)));
+ }
+
+ if(b.contains("%"))
+ {
+ b = b.left(b.length() - 1);
+ b = TQString::number(int((double(255 * b.toDouble()) / 100.0)));
+ }
+
+ svgColor->setRGBColor(int(r.toFloat()), int(g.toFloat()), int(b.toFloat()));
+ }
+ else
+ {
+ if(param.stripWhiteSpace().lower() == "currentcolor")
+ svgColor->setColor(SVG_COLORTYPE_CURRENTCOLOR, DOM::DOMString(""), DOM::DOMString(""));
+ else
+ svgColor->setRGBColor(DOM::DOMString(param.stripWhiteSpace().lower()));
+ }
+}
+
+TQRect SVGStylableImpl::clip()
+{
+ return TQRect();
+}
+
+void SVGStylableImpl::setClip(const TQString &)
+{
+}
+
+float SVGStylableImpl::fontSizeForText(const TQString &value)
+{
+ float ret = -1;
+
+ // Spec: "On a computer screen a scaling factor of 1.2 is suggested between adjacent indexes"
+ const float factor = 1.2;
+
+ // Spec: "If the 'medium' font is 12pt, the 'large' font could be 14.4pt."
+ const float mediumFont = 12.0;
+
+ if(value == "xx-small")
+ ret = mediumFont - (3.0 * factor);
+ else if(value == "x-small")
+ ret = mediumFont - (2.0 * factor);
+ else if(value == "small")
+ ret = mediumFont - factor;
+ else if(value == "medium")
+ ret = mediumFont;
+ else if(value == "large")
+ ret = mediumFont + factor;
+ else if(value == "x-large")
+ ret = mediumFont + (2.0 * factor);
+ else if(value == "xx-large")
+ ret = mediumFont + (3.0 * factor);
+
+ return ret;
+}
+
+// Ecma stuff
+
+/*
+@namespace KSVG
+@begin SVGStylableImpl::s_hashTable 47
+ className SVGStylableImpl::ClassName DontDelete|ReadOnly
+ style SVGStylableImpl::Style DontDelete|ReadOnly
+ stroke-width SVGStylableImpl::StrokeWidth DontDelete|ReadOnly
+ stroke-miterlimit SVGStylableImpl::StrokeMiterlimit DontDelete|ReadOnly
+ stroke-linecap SVGStylableImpl::StrokeLineCap DontDelete|ReadOnly
+ stroke-linejoin SVGStylableImpl::StrokeLineJoin DontDelete|ReadOnly
+ stroke SVGStylableImpl::Stroke DontDelete|ReadOnly
+ fill SVGStylableImpl::Fill DontDelete|ReadOnly
+ color SVGStylableImpl::Color DontDelete|ReadOnly
+ stop-color SVGStylableImpl::StopColor DontDelete|ReadOnly
+ font-size SVGStylableImpl::FontSize DontDelete|ReadOnly
+ font-family SVGStylableImpl::FontFamily DontDelete|ReadOnly
+ font-weight SVGStylableImpl::FontWeight DontDelete|ReadOnly
+ font-style SVGStylableImpl::FontStyle DontDelete|ReadOnly
+ text-decoration SVGStylableImpl::TextDecoration DontDelete|ReadOnly
+ text-anchor SVGStylableImpl::TextAnchor DontDelete|ReadOnly
+ direction SVGStylableImpl::Direction DontDelete|ReadOnly
+ writing-mode SVGStylableImpl::WritingMode DontDelete|ReadOnly
+ unicode-bidi SVGStylableImpl::UnicodeBidi DontDelete|ReadOnly
+ opacity SVGStylableImpl::Opacity DontDelete|ReadOnly
+ fill-opacity SVGStylableImpl::FillOpacity DontDelete|ReadOnly
+ stroke-opacity SVGStylableImpl::StrokeOpacity DontDelete|ReadOnly
+ clip-path SVGStylableImpl::ClipPath DontDelete|ReadOnly
+ marker-start SVGStylableImpl::MarkerStart DontDelete|ReadOnly
+ marker-mid SVGStylableImpl::MarkerMid DontDelete|ReadOnly
+ marker-end SVGStylableImpl::MarkerEnd DontDelete|ReadOnly
+ marker SVGStylableImpl::Marker DontDelete|ReadOnly
+ cursor SVGStylableImpl::Cursor DontDelete|ReadOnly
+ display SVGStylableImpl::Display DontDelete|ReadOnly
+ overflow SVGStylableImpl::Overflow DontDelete|ReadOnly
+ clip SVGStylableImpl::Clip DontDelete|ReadOnly
+ visibility SVGStylableImpl::Visibility DontDelete|ReadOnly
+ fill-rule SVGStylableImpl::FillRule DontDelete|ReadOnly
+ clip-rule SVGStylableImpl::ClipRule DontDelete|ReadOnly
+ stroke-dashoffset SVGStylableImpl::StrokeDashOffset DontDelete|ReadOnly
+ stroke-dasharray SVGStylableImpl::StrokeDashArray DontDelete|ReadOnly
+ color-profile SVGStylableImpl::ColorProfile DontDelete|ReadOnly
+ baseline-shift SVGStylableImpl::BaselineShift DontDelete|ReadOnly
+ letter-spacing SVGStylableImpl::LetterSpacing DontDelete|ReadOnly
+ word-spacing SVGStylableImpl::WordSpacing DontDelete|ReadOnly
+ pointer-events SVGStylableImpl::PointerEvents DontDelete|ReadOnly
+ glyph-orientation-vertical SVGStylableImpl::GlyphOrientationVertical DontDelete|ReadOnly
+ glyph-orientation-horizontal SVGStylableImpl::GlyphOrientationHorizontal DontDelete|ReadOnly
+ color-interpolation SVGStylableImpl::ColorInterpolation DontDelete|ReadOnly
+ mask SVGStylableImpl::Mask DontDelete|ReadOnly
+@end
+@namespace KSVG
+@begin SVGStylableImplProto::s_hashTable 2
+ getStyle SVGStylableImpl::GetStyle DontDelete|Function 0
+@end
+*/
+
+KSVG_IMPLEMENT_PROTOTYPE("SVGStylable", SVGStylableImplProto, SVGStylableImplProtoFunc)
+
+Value SVGStylableImpl::getValueProperty(ExecState *, int token) const
+{
+ switch(token)
+ {
+ //case ClassName:
+ // return String(className().string());
+ case Style:
+ return String(m_object ? m_object->DOM::Element::getAttribute("style") : "");
+ case Visibility:
+ return String(m_visible ? "visible" : "hidden");
+ case Display:
+ return String(m_display ? "inline" : "none");
+ default:
+ kdWarning() << "Unhandled token in " << k_funcinfo << " : " << token << endl;
+ return Undefined();
+ }
+}
+
+void SVGStylableImpl::putValueProperty(ExecState *exec, int token, const Value &value, int attr)
+{
+ // This class has just ReadOnly properties, only with the Internal flag set
+ // it's allowed to modify those.
+ if(!(attr & KJS::Internal))
+ return;
+
+ TQString param = value.toString(exec).qstring();
+
+ if (param.isEmpty())
+ return;
+
+ bool redraw = false;
+ bool inherit = (param == "inherit");
+ int update = -1;
+
+ switch(token)
+ {
+ case Style:
+ {
+ if(!m_object)
+ return;
+
+ TQStringList substyles = TQStringList::split(';', param);
+ for(TQStringList::Iterator it = substyles.begin(); it != substyles.end(); ++it)
+ {
+ TQStringList substyle = TQStringList::split(':', (*it));
+ m_object->setAttributeInternal(substyle[0].stripWhiteSpace(), substyle[1].stripWhiteSpace());
+ }
+ break;
+ }
+ case StrokeWidth:
+ if(m_flags & SVG_STYLE_FLAG_STROKE_WIDTH)
+ {
+ redraw = true;
+ update = UPDATE_LINEWIDTH;
+ }
+ if(inherit)
+ m_flags &= ~SVG_STYLE_FLAG_STROKE_WIDTH;
+ else
+ {
+ m_flags |= SVG_STYLE_FLAG_STROKE_WIDTH;
+
+ if(!m_strokeWidth)
+ {
+ m_strokeWidth = new SVGAnimatedLengthImpl(LENGTHMODE_OTHER, m_object);
+ m_strokeWidth->ref();
+ }
+
+ m_strokeWidth->baseVal()->setValueAsString(param);
+ }
+ break;
+ case StrokeMiterlimit:
+ m_flags |= SVG_STYLE_FLAG_STROKE_MITER_LIMIT;
+ if(!inherit)
+ m_strokeMiterlimit = param.toUInt();
+ break;
+ case StrokeLineCap:
+ m_flags |= SVG_STYLE_FLAG_STROKE_LINE_CAP;
+ if(param == "butt")
+ m_capStyle = PATH_STROKE_CAP_BUTT;
+ else if(param == "round")
+ m_capStyle = PATH_STROKE_CAP_ROUND;
+ else if(param == "square")
+ m_capStyle = PATH_STROKE_CAP_SQUARE;
+ break;
+ case StrokeLineJoin:
+ m_flags |= SVG_STYLE_FLAG_STROKE_LINE_JOIN;
+ if(param == "miter")
+ m_joinStyle = PATH_STROKE_JOIN_MITER;
+ else if(param == "round")
+ m_joinStyle = PATH_STROKE_JOIN_ROUND;
+ else if(param == "bevel")
+ m_joinStyle = PATH_STROKE_JOIN_BEVEL;
+ break;
+ case Stroke:
+ if(m_flags & SVG_STYLE_FLAG_STROKE)
+ redraw = true;
+ if(inherit)
+ m_flags &= ~SVG_STYLE_FLAG_STROKE;
+ else
+ {
+ m_flags |= SVG_STYLE_FLAG_STROKE;
+
+ if(!m_strokeColor)
+ {
+ m_strokeColor = new SVGPaintImpl(m_object);
+ m_strokeColor->ref();
+ }
+
+ setPaint(param, m_strokeColor);
+ }
+ break;
+ case Fill:
+ if(m_flags & SVG_STYLE_FLAG_FILL)
+ {
+ redraw = true;
+ update = UPDATE_STYLE;
+ }
+ if(inherit)
+ m_flags &= ~SVG_STYLE_FLAG_FILL;
+ else
+ {
+ m_flags |= SVG_STYLE_FLAG_FILL;
+
+ if(!m_fillColor)
+ {
+ m_fillColor = new SVGPaintImpl(m_object);
+ m_fillColor->ref();
+ }
+
+ setPaint(param, m_fillColor);
+ }
+ break;
+ case Color:
+ if(m_flags & SVG_STYLE_FLAG_COLOR)
+ redraw = true;
+ if(inherit)
+ m_flags &= ~SVG_STYLE_FLAG_COLOR;
+ else
+ {
+ m_flags |= SVG_STYLE_FLAG_COLOR;
+
+ if(!m_color)
+ {
+ m_color = new SVGColorImpl(m_object);
+ m_color->ref();
+ }
+ setColor(param, m_color);
+ }
+ break;
+ case StopColor:
+ m_flags |= SVG_STYLE_FLAG_STOP;
+
+ if(!m_stopColor)
+ {
+ m_stopColor = new SVGColorImpl(m_object);
+ m_stopColor->ref();
+ }
+
+ if(!inherit)
+ setColor(param, m_stopColor);
+ break;
+ case ColorInterpolation:
+ if(inherit)
+ m_flags &= ~SVG_STYLE_FLAG_COLOR_INTERPOLATION;
+ else
+ {
+ m_flags |= SVG_STYLE_FLAG_COLOR_INTERPOLATION;
+ if(param == "auto" || param == "sRGB")
+ m_colorInterpolation = CI_SRGB;
+ else
+ if(param == "linearRGB")
+ m_colorInterpolation = CI_LINEARRGB;
+ }
+ break;
+ case FontSize:
+ {
+ m_flags |= SVG_STYLE_FLAG_FONT_SIZE;
+ if(!inherit)
+ {
+ double temp = fontSizeForText(param);
+ if(temp != -1) // Is "absolute-size"
+ {
+ m_fontSize = temp;
+ break;
+ }
+
+ SVGLengthImpl *length = SVGSVGElementImpl::createSVGLength();
+ length->setContext(m_object);
+ length->setValueAsString(DOM::DOMString(param));
+ m_fontSize = length->value();
+ length->deref();
+ }
+ break;
+ }
+ case FontFamily:
+ m_flags |= SVG_STYLE_FLAG_FONT_FAMILY;
+
+ // Hacks
+ // #1 Replace "'" characters by ""
+ param = param.replace('\'', TQString());
+ // #2 Replace "MS-Gothic" by "MS Gothic"
+ param = param.replace("MS-Gothic", "MS Gothic");
+ // #3 Replace "Helvetica" by "Arial"
+ param = param.replace("Helvetica", "Arial");
+ param = param.replace("helvetica", "Arial");
+
+ if(!m_fontFamily)
+ {
+ m_fontFamily = new SVGStringListImpl();
+ m_fontFamily->ref();
+ }
+
+ if(!inherit)
+ SVGHelperImpl::parseCommaSeperatedList(m_fontFamily, param);
+ break;
+ case FontWeight:
+ m_flags |= SVG_STYLE_FLAG_FONT_WEIGHT;
+ if(!inherit)
+ m_fontWeight = param;
+ break;
+ case FontStyle:
+ m_flags |= SVG_STYLE_FLAG_FONT_STYLE;
+ if(param == "normal")
+ m_fontStyle = FSNORMAL;
+ else if(param == "italic")
+ m_fontStyle = ITALIC;
+ else if(param == "oblique")
+ m_fontStyle = OBLIQUE;
+ break;
+ case TextDecoration:
+ m_flags |= SVG_STYLE_FLAG_TEXT_DECORATION;
+ if(param == "none")
+ m_textDecoration = TDNONE;
+ {
+ // CSS2 allows multiple decorations
+ m_textDecoration = TDNONE;
+ TQStringList decorations = TQStringList::split(' ', param);
+ for(TQStringList::Iterator it = decorations.begin(); it != decorations.end(); ++it)
+ {
+ if(*it == "underline")
+ m_textDecoration |= UNDERLINE;
+ else if(*it == "overline")
+ m_textDecoration |= OVERLINE;
+ else if(*it == "line-through")
+ m_textDecoration |= LINE_THROUGH;
+ }
+ }
+ break;
+ case TextAnchor:
+ m_flags |= SVG_STYLE_FLAG_TEXT_ANCHOR;
+ if(param == "start")
+ m_textAnchor = TASTART;
+ else if(param == "middle")
+ m_textAnchor = TAMIDDLE;
+ else if(param == "end")
+ m_textAnchor = TAEND;
+ break;
+ case Direction:
+ m_flags |= SVG_STYLE_FLAG_TEXT_DIRECTION;
+ // Spec: direction is only processed when unicode-bidi
+ // is set to bidi-override or embedded
+ if(m_textUnicodeBidi == OVERRIDE ||
+ m_textUnicodeBidi == EMBED ||
+ m_textUnicodeBidi == UBNORMAL)
+ {
+ if(param == "rtl")
+ m_textDirection = RTL;
+ else if(param == "ltr")
+ m_textDirection = LTR;
+ }
+ break;
+ case WritingMode:
+ m_flags |= SVG_STYLE_FLAG_TEXT_WRITING_MODE;
+ if(param == "lr-tb" || param == "lr")
+ m_textWritingMode = LR;
+ else if(param == "rl-tb" || param == "rl")
+ m_textWritingMode = RL;
+ else if(param == "tb-lr" || param == "tb")
+ m_textWritingMode = TB;
+ break;
+ case UnicodeBidi:
+ m_flags |= SVG_STYLE_FLAG_TEXT_UNICODE_BIDI;
+ if(param == "normal")
+ m_textUnicodeBidi = UBNORMAL;
+ else if(param == "embed")
+ m_textUnicodeBidi = EMBED;
+ else if(param == "bidi-override")
+ m_textUnicodeBidi = OVERRIDE;
+ break;
+ case GlyphOrientationVertical:
+ m_flags |= SVG_STYLE_FLAG_GLYPH_ORIENTATION_VERTICAL;
+ m_glyphOrientationVertical = param;
+ break;
+ case GlyphOrientationHorizontal:
+ m_flags |= SVG_STYLE_FLAG_GLYPH_ORIENTATION_HORIZONTAL;
+ m_glyphOrientationHorizontal = param;
+ break;
+ case Opacity:
+ m_flags |= SVG_STYLE_FLAG_OPACITY;
+
+ if(!inherit)
+ {
+ SVGLengthImpl::convertPercentageToFloat(value.toString(exec).qstring(), m_opacity);
+ }
+ break;
+ case FillOpacity:
+ m_flags |= SVG_STYLE_FLAG_FILL_OPACITY;
+
+ if(!inherit)
+ {
+ SVGLengthImpl::convertPercentageToFloat(value.toString(exec).qstring(), m_fillOpacity);
+ }
+ break;
+ case StrokeOpacity:
+ m_flags |= SVG_STYLE_FLAG_STROKE_OPACITY;
+
+ if(!inherit)
+ {
+ SVGLengthImpl::convertPercentageToFloat(value.toString(exec).qstring(), m_strokeOpacity);
+ }
+ break;
+ case ClipPath:
+ m_flags |= SVG_STYLE_FLAG_CLIP_PATH;
+ if(!inherit)
+ m_clipPath = extractUrlId(param);
+ break;
+ case Mask:
+ m_flags |= SVG_STYLE_FLAG_MASK;
+ if(!inherit)
+ m_mask = extractUrlId(param);
+ break;
+ case MarkerStart:
+ m_flags |= SVG_STYLE_FLAG_MARKER_START;
+ if(!inherit)
+ setStartMarker(param);
+ break;
+ case MarkerMid:
+ m_flags |= SVG_STYLE_FLAG_MARKER_MID;
+ if(!inherit)
+ setMidMarker(param);
+ break;
+ case MarkerEnd:
+ m_flags |= SVG_STYLE_FLAG_MARKER_END;
+ if(!inherit)
+ setEndMarker(param);
+ break;
+ case Marker:
+ m_flags |= (SVG_STYLE_FLAG_MARKER_START | SVG_STYLE_FLAG_MARKER_MID | SVG_STYLE_FLAG_MARKER_END);
+ if(!inherit)
+ setMarkers(param);
+ break;
+ case PointerEvents:
+ m_flags |= SVG_STYLE_FLAG_POINTER_EVENTS;
+ if(param == "none")
+ m_pointerEvents = PE_NONE;
+ else if(param == "stroke")
+ m_pointerEvents = PE_STROKE;
+ else if(param == "fill")
+ m_pointerEvents = PE_FILL;
+ else if(param == "painted")
+ m_pointerEvents = PE_PAINTED;
+ else if(param == "visibleStroke")
+ m_pointerEvents = PE_VISIBLE_STROKE;
+ else if(param == "visibleFill")
+ m_pointerEvents = PE_VISIBLE_FILL;
+ else if(param == "visiblePainted")
+ m_pointerEvents = PE_VISIBLE_PAINTED;
+ else if(param == "visible")
+ m_pointerEvents = PE_VISIBLE;
+ else if(param == "all")
+ m_pointerEvents = PE_ALL;
+ break;
+ case Cursor:
+ m_flags |= SVG_STYLE_FLAG_CURSOR;
+ if(param == "auto")
+ m_cursor = CURSOR_AUTO;
+ else if(param == "crosshair")
+ m_cursor = CURSOR_CROSSHAIR;
+ else if(param == "default")
+ m_cursor = CURSOR_DEFAULT;
+ else if(param == "pointer")
+ m_cursor = CURSOR_POINTER;
+ else if(param == "move")
+ m_cursor = CURSOR_MOVE;
+ else if(param == "e-resize")
+ m_cursor = CURSOR_E_RESIZE;
+ else if(param == "ne-resize")
+ m_cursor = CURSOR_NE_RESIZE;
+ else if(param == "nw-resize")
+ m_cursor = CURSOR_NW_RESIZE;
+ else if(param == "n-resize")
+ m_cursor = CURSOR_N_RESIZE;
+ else if(param == "se-resize")
+ m_cursor = CURSOR_SE_RESIZE;
+ else if(param == "sw-resize")
+ m_cursor = CURSOR_SW_RESIZE;
+ else if(param == "s-resize")
+ m_cursor = CURSOR_S_RESIZE;
+ else if(param == "w-resize")
+ m_cursor = CURSOR_W_RESIZE;
+ else if(param == "text")
+ m_cursor = CURSOR_TEXT;
+ else if(param == "wait")
+ m_cursor = CURSOR_WAIT;
+ else if(param == "help")
+ m_cursor = CURSOR_HELP;
+ break;
+ case Display:
+ m_flags |= SVG_STYLE_FLAG_DISPLAY;
+
+ if(param == "none")
+ m_display = false;
+ else if(!inherit)
+ m_display = true;
+ break;
+ case Overflow:
+ m_flags |= SVG_STYLE_FLAG_OVERFLOW;
+ if(param == "hidden" || param == "scroll")
+ m_overflow = false;
+ else if(!inherit)
+ m_overflow = true;
+ break;
+ case Clip:
+ m_flags |= SVG_STYLE_FLAG_CLIP_PATH;
+ if(!inherit)
+ setClip(param);
+ break;
+ case Visibility:
+ if(m_flags & SVG_STYLE_FLAG_VISIBILITY)
+ redraw = true;
+ if(inherit)
+ m_flags &= ~SVG_STYLE_FLAG_COLOR;
+ else
+ {
+ m_flags |= SVG_STYLE_FLAG_VISIBILITY;
+
+ if(param == "visible")
+ m_visible = true;
+ else if(!inherit)
+ m_visible = false;
+
+ // Just a quick fix for the script-* files (Niko)
+ // Any better solution??
+ update = UPDATE_TRANSFORM;
+ redraw = true;
+ }
+ SVGHelperImpl::applyContainer<SVGStylableImpl>(this, Visibility, param);
+ break;
+ case FillRule:
+ m_flags |= SVG_STYLE_FLAG_FILL_RULE;
+ if(!inherit)
+ m_fillRule = (param == "evenodd" ? RULE_EVENODD : RULE_NONZERO);
+ break;
+ case ClipRule:
+ m_flags |= SVG_STYLE_FLAG_CLIP_RULE;
+ if(!inherit)
+ m_clipRule = (param == "evenodd" ? RULE_EVENODD : RULE_NONZERO);
+ break;
+ case StrokeDashOffset:
+ m_flags |= SVG_STYLE_FLAG_STROKE_DASH_OFFSET;
+
+ if(!m_dashOffset)
+ {
+ m_dashOffset = new SVGAnimatedLengthImpl(LENGTHMODE_OTHER, m_object);
+ m_dashOffset->ref();
+ }
+
+ if(!inherit)
+ m_dashOffset->baseVal()->setValueAsString(param);
+ break;
+ case StrokeDashArray:
+ {
+ m_flags |= SVG_STYLE_FLAG_STROKE_DASH_ARRAY;
+
+ if(!m_dashArray)
+ {
+ m_dashArray = new SVGAnimatedLengthListImpl();
+ m_dashArray->ref();
+ }
+ else
+ m_dashArray->baseVal()->clear();
+
+ if(param != "none" && !inherit)
+ SVGHelperImpl::parseLengthList(m_dashArray, param);
+ break;
+ }
+ case ColorProfile:
+ {
+ m_flags |= SVG_STYLE_FLAG_COLOR_PROFILE;
+ if(!inherit)
+ {
+ if(!m_object)
+ return;
+
+ SVGColorProfileElementImpl *handle = static_cast<SVGColorProfileElementImpl *>(m_object->ownerSVGElement()->getElementById(SVGURIReferenceImpl::getTarget(param)));
+ if(handle)
+ SVGImageElementImpl::applyColorProfile(handle, static_cast<SVGImageElementImpl *>(this));
+ }
+ break;
+ }
+ case BaselineShift:
+ {
+ m_flags |= SVG_STYLE_FLAG_BASELINE_SHIFT;
+ if(!inherit)
+ m_baselineShift = param;
+ break;
+ }
+ case LetterSpacing:
+ m_flags |= SVG_STYLE_FLAG_LETTER_SPACING;
+ case WordSpacing:
+ {
+ if(!inherit)
+ {
+ if(token == WordSpacing)
+ {
+ m_flags |= SVG_STYLE_FLAG_WORD_SPACING;
+ m_wordSpacing = param;
+ }
+ else
+ m_letterSpacing = param;
+ }
+ break;
+ }
+ default:
+ kdWarning() << "Unhandled token in " << k_funcinfo << " : " << token << endl;
+ }
+
+ if(redraw)
+ {
+ SVGShapeImpl *shape = dynamic_cast<SVGShapeImpl *>(m_object);
+ if(inherit)
+ processStyle();
+
+ if(shape && shape->item())
+ {
+ if(update > -1)
+ shape->item()->update(static_cast<CanvasItemUpdate>(update));
+ else if(m_object)
+ m_object->ownerDoc()->canvas()->invalidate(shape->item(), false);
+ }
+ }
+}
+
+Value SVGStylableImplProtoFunc::call(ExecState *exec, Object &thisObj, const List &)
+{
+ KSVG_CHECK_THIS(SVGStylableImpl)
+
+ switch(id)
+ {
+ case SVGStylableImpl::GetStyle:
+ return Undefined();
+ default:
+ kdWarning() << "Unhandled function id in " << k_funcinfo << " : " << id << endl;
+ break;
+ }
+
+ return Undefined();
+}