JSValue jsSVGPathSegPathSegTypeAsLetter(ExecState* exec, JSValue slotBase, const Identifier&) { JSSVGPathSeg* castedThis = static_cast<JSSVGPathSeg*>(asObject(slotBase)); UNUSED_PARAM(exec); SVGPathSeg* imp = static_cast<SVGPathSeg*>(castedThis->impl()); JSValue result = jsString(exec, imp->pathSegTypeAsLetter()); return result; }
unsigned SVGPathSegList::getPathSegAtLength(float) { // FIXME : to be useful this will need to support non-normalized SVGPathSegLists ExceptionCode ec = 0; int len = numberOfItems(); // FIXME: Eventually this will likely move to a "path applier"-like model, until then PathTraversalState is less useful as we could just use locals PathTraversalState traversalState(PathTraversalState::TraversalSegmentAtLength); for (int i = 0; i < len; ++i) { SVGPathSeg* segment = getItem(i, ec).get(); float segmentLength = 0; switch (segment->pathSegType()) { case SVGPathSeg::PATHSEG_MOVETO_ABS: { SVGPathSegMovetoAbs* moveTo = static_cast<SVGPathSegMovetoAbs*>(segment); segmentLength = traversalState.moveTo(FloatPoint(moveTo->x(), moveTo->y())); break; } case SVGPathSeg::PATHSEG_LINETO_ABS: { SVGPathSegLinetoAbs* lineTo = static_cast<SVGPathSegLinetoAbs*>(segment); segmentLength = traversalState.lineTo(FloatPoint(lineTo->x(), lineTo->y())); break; } case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS: { SVGPathSegCurvetoCubicAbs* curveTo = static_cast<SVGPathSegCurvetoCubicAbs*>(segment); segmentLength = traversalState.cubicBezierTo(FloatPoint(curveTo->x1(), curveTo->y1()), FloatPoint(curveTo->x2(), curveTo->y2()), FloatPoint(curveTo->x(), curveTo->y())); break; } case SVGPathSeg::PATHSEG_CLOSEPATH: segmentLength = traversalState.closeSubpath(); break; default: ASSERT(false); // FIXME: This only works with normalized/processed path data. break; } traversalState.m_totalLength += segmentLength; if ((traversalState.m_action == PathTraversalState::TraversalSegmentAtLength) && (traversalState.m_totalLength > traversalState.m_desiredLength)) { return traversalState.m_segmentIndex; } traversalState.m_segmentIndex++; } return 0; // The SVG spec is unclear as to what to return when the distance is not on the path }
JSValue* JSSVGPathSeg::getValueProperty(ExecState* exec, int token) const { switch (token) { case PathSegTypeAttrNum: { SVGPathSeg* imp = static_cast<SVGPathSeg*>(impl()); return jsNumber(exec, imp->pathSegType()); } case PathSegTypeAsLetterAttrNum: { SVGPathSeg* imp = static_cast<SVGPathSeg*>(impl()); return jsString(exec, imp->pathSegTypeAsLetter()); } case ConstructorAttrNum: return getConstructor(exec); } return 0; }
Path SVGPathSegList::toPathData() { // FIXME : This should also support non-normalized PathSegLists Path pathData; ExceptionCode ec = 0; int len = numberOfItems(); for (int i = 0; i < len; ++i) { SVGPathSeg* segment = getItem(i, ec).get();; switch (segment->pathSegType()) { case SVGPathSeg::PATHSEG_MOVETO_ABS: { SVGPathSegMovetoAbs* moveTo = static_cast<SVGPathSegMovetoAbs*>(segment); pathData.moveTo(FloatPoint(moveTo->x(), moveTo->y())); break; } case SVGPathSeg::PATHSEG_LINETO_ABS: { SVGPathSegLinetoAbs* lineTo = static_cast<SVGPathSegLinetoAbs*>(segment); pathData.addLineTo(FloatPoint(lineTo->x(), lineTo->y())); break; } case SVGPathSeg::PATHSEG_CURVETO_CUBIC_ABS: { SVGPathSegCurvetoCubicAbs* curveTo = static_cast<SVGPathSegCurvetoCubicAbs*>(segment); pathData.addBezierCurveTo(FloatPoint(curveTo->x1(), curveTo->y1()), FloatPoint(curveTo->x2(), curveTo->y2()), FloatPoint(curveTo->x(), curveTo->y())); break; } case SVGPathSeg::PATHSEG_CLOSEPATH: pathData.closeSubpath(); break; default: ASSERT(false); // FIXME: This only works with normalized/processed path data. break; } } return pathData; }
static v8::Handle<v8::Value> pathSegTypeAsLetterAttrGetter(v8::Local<v8::String> name, const v8::AccessorInfo& info) { SVGPathSeg* imp = V8SVGPathSeg::toNative(info.Holder()); return v8String(imp->pathSegTypeAsLetter(), info.GetIsolate()); }