summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
diff options
context:
space:
mode:
authorSteve Block <steveblock@google.com>2011-05-06 11:45:16 +0100
committerSteve Block <steveblock@google.com>2011-05-12 13:44:10 +0100
commitcad810f21b803229eb11403f9209855525a25d57 (patch)
tree29a6fd0279be608e0fe9ffe9841f722f0f4e4269 /WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
parent121b0cf4517156d0ac5111caf9830c51b69bae8f (diff)
downloadexternal_webkit-cad810f21b803229eb11403f9209855525a25d57.zip
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.gz
external_webkit-cad810f21b803229eb11403f9209855525a25d57.tar.bz2
Merge WebKit at r75315: Initial merge by git.
Change-Id: I570314b346ce101c935ed22a626b48c2af266b84
Diffstat (limited to 'WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp')
-rw-r--r--WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp308
1 files changed, 0 insertions, 308 deletions
diff --git a/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp b/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
deleted file mode 100644
index 3122912..0000000
--- a/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
+++ /dev/null
@@ -1,308 +0,0 @@
-/*
- * Copyright (C) Research In Motion Limited 2010. All rights reserved.
- *
- * 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 "config.h"
-
-#if ENABLE(SVG)
-#include "SVGTextLayoutAttributesBuilder.h"
-
-#include "RenderSVGInlineText.h"
-#include "RenderSVGText.h"
-#include "SVGTextPositioningElement.h"
-
-// Set to a value > 0 to dump the text layout attributes
-#define DUMP_TEXT_LAYOUT_ATTRIBUTES 0
-
-namespace WebCore {
-
-SVGTextLayoutAttributesBuilder::SVGTextLayoutAttributesBuilder()
-{
-}
-
-void SVGTextLayoutAttributesBuilder::buildLayoutAttributesForTextSubtree(RenderSVGText* textRoot)
-{
- ASSERT(textRoot);
- m_scopes.clear();
-
- // Build list of x/y/dx/dy/rotate values for each subtree element that may define these values (tspan/textPath etc).
- unsigned atCharacter = 0;
- UChar lastCharacter = '\0';
- buildLayoutScopes(textRoot, atCharacter, lastCharacter);
-
- if (!atCharacter)
- return;
-
- // Build list of x/y/dx/dy/rotate values for the outermost <text> element.
- buildOutermostLayoutScope(textRoot, atCharacter);
-
- // Propagate layout attributes to each RenderSVGInlineText object.
- atCharacter = 0;
- lastCharacter = '\0';
- propagateLayoutAttributes(textRoot, atCharacter, lastCharacter);
-}
-
-static inline void extractFloatValuesFromSVGLengthList(SVGElement* lengthContext, const SVGLengthList& list, Vector<float>& floatValues, unsigned textContentLength)
-{
- ASSERT(lengthContext);
-
- unsigned length = list.size();
- if (length > textContentLength)
- length = textContentLength;
- floatValues.reserveCapacity(length);
-
- for (unsigned i = 0; i < length; ++i) {
- const SVGLength& length = list.at(i);
- floatValues.append(length.value(lengthContext));
- }
-}
-
-static inline void extractFloatValuesFromSVGNumberList(const SVGNumberList& list, Vector<float>& floatValues, unsigned textContentLength)
-{
- unsigned length = list.size();
- if (length > textContentLength)
- length = textContentLength;
- floatValues.reserveCapacity(length);
-
- for (unsigned i = 0; i < length; ++i)
- floatValues.append(list.at(i));
-}
-
-void SVGTextLayoutAttributesBuilder::buildLayoutScope(LayoutScope& scope, RenderObject* renderer, unsigned textContentStart, unsigned textContentLength) const
-{
- ASSERT(renderer);
- ASSERT(renderer->style());
-
- scope.textContentStart = textContentStart;
- scope.textContentLength = textContentLength;
-
- SVGTextPositioningElement* element = SVGTextPositioningElement::elementFromRenderer(renderer);
- if (!element)
- return;
-
- SVGTextLayoutAttributes& attributes = scope.attributes;
- extractFloatValuesFromSVGLengthList(element, element->x(), attributes.xValues(), textContentLength);
- extractFloatValuesFromSVGLengthList(element, element->y(), attributes.yValues(), textContentLength);
- extractFloatValuesFromSVGLengthList(element, element->dx(), attributes.dxValues(), textContentLength);
- extractFloatValuesFromSVGLengthList(element, element->dy(), attributes.dyValues(), textContentLength);
- extractFloatValuesFromSVGNumberList(element->rotate(), attributes.rotateValues(), textContentLength);
-
- // The last rotation value spans the whole scope.
- Vector<float>& rotateValues = attributes.rotateValues();
- if (rotateValues.isEmpty())
- return;
-
- unsigned rotateValuesSize = rotateValues.size();
- if (rotateValuesSize == textContentLength)
- return;
-
- float lastRotation = rotateValues.last();
-
- rotateValues.resize(textContentLength);
- for (unsigned i = rotateValuesSize; i < textContentLength; ++i)
- rotateValues.at(i) = lastRotation;
-}
-
-static inline bool characterIsSpace(const UChar& character)
-{
- return character == ' ';
-}
-
-static inline bool characterIsSpaceOrNull(const UChar& character)
-{
- return character == ' ' || character == '\0';
-}
-
-static inline bool shouldPreserveAllWhiteSpace(RenderStyle* style)
-{
- ASSERT(style);
- return style->whiteSpace() == PRE;
-}
-
-void SVGTextLayoutAttributesBuilder::buildLayoutScopes(RenderObject* start, unsigned& atCharacter, UChar& lastCharacter)
-{
- for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
- if (child->isSVGInlineText()) {
- RenderSVGInlineText* text = toRenderSVGInlineText(child);
-
- if (!shouldPreserveAllWhiteSpace(text->style())) {
- const UChar* characters = text->characters();
- unsigned textLength = text->textLength();
- for (unsigned textPosition = 0; textPosition < textLength; ++textPosition) {
- const UChar& currentCharacter = characters[textPosition];
- if (characterIsSpace(currentCharacter) && characterIsSpaceOrNull(lastCharacter))
- continue;
-
- lastCharacter = currentCharacter;
- ++atCharacter;
- }
- } else
- atCharacter += text->textLength();
-
- continue;
- }
-
- if (!child->isSVGInline())
- continue;
-
- unsigned textContentStart = atCharacter;
- buildLayoutScopes(child, atCharacter, lastCharacter);
-
- LayoutScope scope;
- buildLayoutScope(scope, child, textContentStart, atCharacter - textContentStart);
- m_scopes.append(scope);
- }
-}
-
-void SVGTextLayoutAttributesBuilder::buildOutermostLayoutScope(RenderSVGText* textRoot, unsigned textLength)
-{
- LayoutScope scope;
- buildLayoutScope(scope, textRoot, 0, textLength);
-
- // Handle <text> x/y default attributes.
- Vector<float>& xValues = scope.attributes.xValues();
- if (xValues.isEmpty())
- xValues.append(0);
-
- Vector<float>& yValues = scope.attributes.yValues();
- if (yValues.isEmpty())
- yValues.append(0);
-
- m_scopes.prepend(scope);
-}
-
-void SVGTextLayoutAttributesBuilder::propagateLayoutAttributes(RenderObject* start, unsigned& atCharacter, UChar& lastCharacter) const
-{
- for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
- if (child->isSVGInlineText()) {
- RenderSVGInlineText* text = toRenderSVGInlineText(child);
- const UChar* characters = text->characters();
- unsigned textLength = text->textLength();
- bool preserveWhiteSpace = shouldPreserveAllWhiteSpace(text->style());
-
- SVGTextLayoutAttributes attributes;
- attributes.reserveCapacity(textLength);
-
- unsigned valueListPosition = atCharacter;
- unsigned metricsLength = 1;
- for (unsigned textPosition = 0; textPosition < textLength; textPosition += metricsLength) {
- const UChar& currentCharacter = characters[textPosition];
-
- SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(text, textPosition, 1);
- metricsLength = metrics.length();
-
- if (!preserveWhiteSpace && characterIsSpace(currentCharacter) && characterIsSpaceOrNull(lastCharacter)) {
- assignEmptyLayoutAttributesForCharacter(attributes);
- attributes.textMetricsValues().append(SVGTextMetrics::emptyMetrics());
- continue;
- }
-
- assignLayoutAttributesForCharacter(attributes, metrics, valueListPosition);
-
- if (metricsLength > 1) {
- for (unsigned i = 0; i < metricsLength - 1; ++i)
- assignEmptyLayoutAttributesForCharacter(attributes);
- }
-
- lastCharacter = currentCharacter;
- valueListPosition += metricsLength;
- }
-
-#if DUMP_TEXT_LAYOUT_ATTRIBUTES > 0
- fprintf(stderr, "\nDumping layout attributes for RenderSVGInlineText, renderer=%p, node=%p (atCharacter: %i)\n", text, text->node(), atCharacter);
- attributes.dump();
-#endif
-
- text->storeLayoutAttributes(attributes);
- atCharacter = valueListPosition;
- continue;
- }
-
- if (!child->isSVGInline())
- continue;
-
- propagateLayoutAttributes(child, atCharacter, lastCharacter);
- }
-}
-
-float SVGTextLayoutAttributesBuilder::nextLayoutValue(LayoutValueType type, unsigned atCharacter) const
-{
- for (int i = m_scopes.size() - 1; i >= 0; --i) {
- const LayoutScope& scope = m_scopes.at(i);
- if (scope.textContentStart > atCharacter || scope.textContentStart + scope.textContentLength < atCharacter)
- continue;
-
- const Vector<float>* valuesPointer = 0;
- switch (type) {
- case XValueAttribute:
- valuesPointer = &scope.attributes.xValues();
- break;
- case YValueAttribute:
- valuesPointer = &scope.attributes.yValues();
- break;
- case DxValueAttribute:
- valuesPointer = &scope.attributes.dxValues();
- break;
- case DyValueAttribute:
- valuesPointer = &scope.attributes.dyValues();
- break;
- case RotateValueAttribute:
- valuesPointer = &scope.attributes.rotateValues();
- break;
- default:
- ASSERT_NOT_REACHED();
- }
-
- ASSERT(valuesPointer);
- const Vector<float>& values = *valuesPointer;
- if (values.isEmpty())
- continue;
-
- unsigned position = atCharacter - scope.textContentStart;
- if (position >= values.size())
- continue;
-
- return values.at(position);
- }
-
- return SVGTextLayoutAttributes::emptyValue();
-}
-
-void SVGTextLayoutAttributesBuilder::assignLayoutAttributesForCharacter(SVGTextLayoutAttributes& attributes, SVGTextMetrics& metrics, unsigned valueListPosition) const
-{
- attributes.xValues().append(nextLayoutValue(XValueAttribute, valueListPosition));
- attributes.yValues().append(nextLayoutValue(YValueAttribute, valueListPosition));
- attributes.dxValues().append(nextLayoutValue(DxValueAttribute, valueListPosition));
- attributes.dyValues().append(nextLayoutValue(DyValueAttribute, valueListPosition));
- attributes.rotateValues().append(nextLayoutValue(RotateValueAttribute, valueListPosition));
- attributes.textMetricsValues().append(metrics);
-}
-
-void SVGTextLayoutAttributesBuilder::assignEmptyLayoutAttributesForCharacter(SVGTextLayoutAttributes& attributes) const
-{
- attributes.xValues().append(SVGTextLayoutAttributes::emptyValue());
- attributes.yValues().append(SVGTextLayoutAttributes::emptyValue());
- attributes.dxValues().append(SVGTextLayoutAttributes::emptyValue());
- attributes.dyValues().append(SVGTextLayoutAttributes::emptyValue());
- attributes.rotateValues().append(SVGTextLayoutAttributes::emptyValue());
- // This doesn't add an empty value to textMetricsValues() on purpose!
-}
-
-}
-
-#endif // ENABLE(SVG)