SVGRect SVGTextQuery::extentOfCharacter(unsigned position) const { if (m_textBoxes.isEmpty()) return SVGRect(); ExtentOfCharacterData data(position); executeQuery(&data, &SVGTextQuery::extentOfCharacterCallback); return data.extent; }
SVGRect SVGTextContentElement::getExtentOfChar(unsigned charnum, ExceptionState& es) { document().updateLayoutIgnorePendingStylesheets(); if (charnum > getNumberOfChars()) { es.throwUninformativeAndGenericDOMException(IndexSizeError); return SVGRect(); } return SVGTextQuery(renderer()).extentOfCharacter(charnum); }
/* static */ OP_STATUS SVGFilter::FetchValues(SVGFilter* filter, HTML_Element* filter_elm, SVGElementResolver* resolver, SVGDocumentContext* doc_ctx, HTML_Element* filter_target_elm, const SVGValueContext& vcxt, SVGBoundingBox* override_targetbbox) { // Handle filter attributes // filterUnits, primitiveUnits, x, y, width, height, // filterRes, xlink:href<to other filter> // this means we should inherit from the referenced element HTML_Element* parent_filter_elm = SVGUtils::FindHrefReferredNode(resolver, doc_ctx, filter_elm); if (parent_filter_elm && !parent_filter_elm->IsMatchingType(Markup::SVGE_FILTER, NS_SVG)) parent_filter_elm = NULL; if (parent_filter_elm) { doc_ctx->RegisterDependency(filter_elm, parent_filter_elm); SVGElementResolverStack resolver_mark(resolver); RETURN_IF_ERROR(resolver_mark.Push(parent_filter_elm)); RETURN_IF_ERROR(FetchValues(filter, parent_filter_elm, resolver, doc_ctx, filter_target_elm, vcxt, override_targetbbox)); } // If this element has no relevant children, and the referenced // element does (possibly due to its own href attribute), then // this element inherits the children from the referenced element. if (parent_filter_elm && !SVGUtils::HasChildren(filter_elm)) { filter->SetChildRoot(filter->GetChildRoot()); } else { filter->SetChildRoot(filter_elm); } if (AttrValueStore::HasObject(filter_elm, Markup::SVGA_FILTERUNITS, NS_IDX_SVG)) { SVGUnitsType units; OP_STATUS status = AttrValueStore::GetUnits(filter_elm, Markup::SVGA_FILTERUNITS, units, SVGUNITS_OBJECTBBOX); if (OpStatus::IsSuccess(status)) filter->SetFilterUnits(units); } if (AttrValueStore::HasObject(filter_elm, Markup::SVGA_PRIMITIVEUNITS, NS_IDX_SVG)) { SVGUnitsType units; OP_STATUS status = AttrValueStore::GetUnits(filter_elm, Markup::SVGA_PRIMITIVEUNITS, units, SVGUNITS_USERSPACEONUSE); if (OpStatus::IsSuccess(status)) filter->SetPrimitiveUnits(units); } // Need target bounding box SVGBoundingBox bbox; if (override_targetbbox) { bbox = *override_targetbbox; } else { SVGNumberPair vp(vcxt.viewport_width, vcxt.viewport_height); RETURN_IF_ERROR(GetElementBBox(doc_ctx, filter_target_elm, vp, bbox)); } filter->SetSourceElementBBox(bbox); SVGRect filter_region = filter->GetRegionInUnits(); if (!parent_filter_elm) { // Set defaults filter_region = SVGRect(-0.1, -0.1, 1.2, 1.2); if (filter->GetFilterUnits() == SVGUNITS_USERSPACEONUSE) { filter_region.x *= vcxt.viewport_width; filter_region.width *= vcxt.viewport_width; filter_region.y *= vcxt.viewport_height; filter_region.height *= vcxt.viewport_height; } } SVGUtils::GetResolvedLengthWithUnits(filter_elm, Markup::SVGA_X, SVGLength::SVGLENGTH_X, filter->GetFilterUnits(), vcxt, filter_region.x); SVGUtils::GetResolvedLengthWithUnits(filter_elm, Markup::SVGA_Y, SVGLength::SVGLENGTH_Y, filter->GetFilterUnits(), vcxt, filter_region.y); SVGUtils::GetResolvedLengthWithUnits(filter_elm, Markup::SVGA_WIDTH, SVGLength::SVGLENGTH_X, filter->GetFilterUnits(), vcxt, filter_region.width); SVGUtils::GetResolvedLengthWithUnits(filter_elm, Markup::SVGA_HEIGHT, SVGLength::SVGLENGTH_Y, filter->GetFilterUnits(), vcxt, filter_region.height); // "Negative values for width or height are an error" if (filter_region.width < 0 || filter_region.height < 0) return OpSVGStatus::INVALID_ARGUMENT; // "Zero values disable rendering of the element which referenced the filter." if (filter_region.width.Equal(0) || filter_region.height.Equal(0)) return OpSVGStatus::ELEMENT_IS_INVISIBLE; filter->SetRegionInUnits(filter_region); if (filter->GetFilterUnits() == SVGUNITS_OBJECTBBOX) { SVGMatrix bbox_xfrm; /* bbox set earlier */ bbox_xfrm.SetValues(bbox.maxx - bbox.minx, 0, 0, bbox.maxy - bbox.miny, bbox.minx, bbox.miny); filter_region = bbox_xfrm.ApplyToRect(filter_region); } filter->SetFilterRegion(filter_region); if (AttrValueStore::HasObject(filter_elm, Markup::SVGA_FILTERRES, NS_IDX_SVG)) { SVGNumberPair filt_res; OP_STATUS status = SVGUtils::GetNumberOptionalNumber(filter_elm, Markup::SVGA_FILTERRES, filt_res); if (OpStatus::IsSuccess(status)) { // "Negative or zero values disable rendering of the element which referenced the filter." if (filt_res.x <= 0 || filt_res.y <= 0) return OpSVGStatus::ELEMENT_IS_INVISIBLE; filter->SetFilterResolution(filt_res.x, filt_res.y); } } return OpStatus::OK; }