diff options
Diffstat (limited to 'WebCore/rendering/SVGCharacterLayoutInfo.cpp')
-rw-r--r-- | WebCore/rendering/SVGCharacterLayoutInfo.cpp | 535 |
1 files changed, 0 insertions, 535 deletions
diff --git a/WebCore/rendering/SVGCharacterLayoutInfo.cpp b/WebCore/rendering/SVGCharacterLayoutInfo.cpp deleted file mode 100644 index 287aeac..0000000 --- a/WebCore/rendering/SVGCharacterLayoutInfo.cpp +++ /dev/null @@ -1,535 +0,0 @@ -/* - * This file is part of the WebKit project. - * - * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> - * - * 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 "SVGCharacterLayoutInfo.h" - -#include "InlineFlowBox.h" -#include "InlineTextBox.h" -#include "SVGLengthList.h" -#include "SVGNumberList.h" -#include "SVGTextPositioningElement.h" -#include "RenderSVGTextPath.h" - -#include <float.h> - -namespace WebCore { - -// Helper function -static float calculateBaselineShift(RenderObject* item) -{ - const Font& font = item->style()->font(); - const SVGRenderStyle* svgStyle = item->style()->svgStyle(); - - float baselineShift = 0.0f; - if (svgStyle->baselineShift() == BS_LENGTH) { - CSSPrimitiveValue* primitive = static_cast<CSSPrimitiveValue*>(svgStyle->baselineShiftValue()); - baselineShift = primitive->getFloatValue(); - - if (primitive->primitiveType() == CSSPrimitiveValue::CSS_PERCENTAGE) - baselineShift = baselineShift / 100.0f * font.pixelSize(); - } else { - float baselineAscent = font.ascent() + font.descent(); - - switch (svgStyle->baselineShift()) { - case BS_BASELINE: - break; - case BS_SUB: - baselineShift = -baselineAscent / 2.0f; - break; - case BS_SUPER: - baselineShift = baselineAscent / 2.0f; - break; - default: - ASSERT_NOT_REACHED(); - } - } - - return baselineShift; -} - -SVGCharacterLayoutInfo::SVGCharacterLayoutInfo(Vector<SVGChar>& chars) - : curx(0.0f) - , cury(0.0f) - , angle(0.0f) - , dx(0.0f) - , dy(0.0f) - , shiftx(0.0f) - , shifty(0.0f) - , pathExtraAdvance(0.0f) - , pathTextLength(0.0f) - , pathChunkLength(0.0f) - , svgChars(chars) - , nextDrawnSeperated(false) - , xStackChanged(false) - , yStackChanged(false) - , dxStackChanged(false) - , dyStackChanged(false) - , angleStackChanged(false) - , baselineShiftStackChanged(false) - , pathLayout(false) - , currentOffset(0.0f) - , startOffset(0.0f) - , layoutPathLength(0.0f) -{ -} - -bool SVGCharacterLayoutInfo::xValueAvailable() const -{ - return xStack.isEmpty() ? false : xStack.last().position() < xStack.last().size(); -} - -bool SVGCharacterLayoutInfo::yValueAvailable() const -{ - return yStack.isEmpty() ? false : yStack.last().position() < yStack.last().size(); -} - -bool SVGCharacterLayoutInfo::dxValueAvailable() const -{ - return dxStack.isEmpty() ? false : dxStack.last().position() < dxStack.last().size(); -} - -bool SVGCharacterLayoutInfo::dyValueAvailable() const -{ - return dyStack.isEmpty() ? false : dyStack.last().position() < dyStack.last().size(); -} - -bool SVGCharacterLayoutInfo::angleValueAvailable() const -{ - return angleStack.isEmpty() ? false : angleStack.last().position() < angleStack.last().size(); -} - -bool SVGCharacterLayoutInfo::baselineShiftValueAvailable() const -{ - return !baselineShiftStack.isEmpty(); -} - -float SVGCharacterLayoutInfo::xValueNext() const -{ - ASSERT(!xStack.isEmpty()); - return xStack.last().valueAtCurrentPosition(); -} - -float SVGCharacterLayoutInfo::yValueNext() const -{ - ASSERT(!yStack.isEmpty()); - return yStack.last().valueAtCurrentPosition(); -} - -float SVGCharacterLayoutInfo::dxValueNext() const -{ - ASSERT(!dxStack.isEmpty()); - return dxStack.last().valueAtCurrentPosition(); -} - -float SVGCharacterLayoutInfo::dyValueNext() const -{ - ASSERT(!dyStack.isEmpty()); - return dyStack.last().valueAtCurrentPosition(); -} - -float SVGCharacterLayoutInfo::angleValueNext() const -{ - ASSERT(!angleStack.isEmpty()); - return angleStack.last().valueAtCurrentPosition(); -} - -float SVGCharacterLayoutInfo::baselineShiftValueNext() const -{ - ASSERT(!baselineShiftStack.isEmpty()); - return baselineShiftStack.last(); -} - -void SVGCharacterLayoutInfo::processedSingleCharacter() -{ - xStackWalk(); - yStackWalk(); - dxStackWalk(); - dyStackWalk(); - angleStackWalk(); - baselineShiftStackWalk(); -} - -void SVGCharacterLayoutInfo::processedChunk(float savedShiftX, float savedShiftY) -{ - // baseline-shift doesn't span across ancestors, unlike dx/dy. - curx += savedShiftX - shiftx; - cury += savedShiftY - shifty; - - if (inPathLayout()) { - shiftx = savedShiftX; - shifty = savedShiftY; - } - - // rotation also doesn't span - angle = 0.0f; - - if (xStackChanged) { - ASSERT(!xStack.isEmpty()); - xStack.removeLast(); - xStackChanged = false; - } - - if (yStackChanged) { - ASSERT(!yStack.isEmpty()); - yStack.removeLast(); - yStackChanged = false; - } - - if (dxStackChanged) { - ASSERT(!dxStack.isEmpty()); - dxStack.removeLast(); - dxStackChanged = false; - } - - if (dyStackChanged) { - ASSERT(!dyStack.isEmpty()); - dyStack.removeLast(); - dyStackChanged = false; - } - - if (angleStackChanged) { - ASSERT(!angleStack.isEmpty()); - angleStack.removeLast(); - angleStackChanged = false; - } - - if (baselineShiftStackChanged) { - ASSERT(!baselineShiftStack.isEmpty()); - baselineShiftStack.removeLast(); - baselineShiftStackChanged = false; - } -} - -bool SVGCharacterLayoutInfo::nextPathLayoutPointAndAngle(float glyphAdvance, float extraAdvance, float newOffset) -{ - if (layoutPathLength <= 0.0f) - return false; - - if (newOffset != FLT_MIN) - currentOffset = startOffset + newOffset; - - // Respect translation along path (extraAdvance is orthogonal to the path) - currentOffset += extraAdvance; - - float offset = currentOffset + glyphAdvance / 2.0f; - currentOffset += glyphAdvance + pathExtraAdvance; - - if (offset < 0.0f || offset > layoutPathLength) - return false; - - bool ok = false; - FloatPoint point = layoutPath.pointAtLength(offset, ok); - ASSERT(ok); - - curx = point.x(); - cury = point.y(); - - angle = layoutPath.normalAngleAtLength(offset, ok); - ASSERT(ok); - - // fprintf(stderr, "t: %f, x: %f, y: %f, angle: %f, glyphAdvance: %f\n", currentOffset, x, y, angle, glyphAdvance); - return true; -} - -bool SVGCharacterLayoutInfo::inPathLayout() const -{ - return pathLayout; -} - -void SVGCharacterLayoutInfo::setInPathLayout(bool value) -{ - pathLayout = value; - - pathExtraAdvance = 0.0f; - pathTextLength = 0.0f; - pathChunkLength = 0.0f; -} - -void SVGCharacterLayoutInfo::addLayoutInformation(InlineFlowBox* flowBox, float textAnchorStartOffset) -{ - bool isInitialLayout = xStack.isEmpty() && yStack.isEmpty() && - dxStack.isEmpty() && dyStack.isEmpty() && - angleStack.isEmpty() && baselineShiftStack.isEmpty() && - curx == 0.0f && cury == 0.0f; - - RenderSVGTextPath* textPath = static_cast<RenderSVGTextPath*>(flowBox->object()); - Path path = textPath->layoutPath(); - - float baselineShift = calculateBaselineShift(textPath); - - layoutPath = path; - layoutPathLength = path.length(); - - if (layoutPathLength <= 0.0f) - return; - - startOffset = textPath->startOffset(); - - if (textPath->startOffset() >= 0.0f && textPath->startOffset() <= 1.0f) - startOffset *= layoutPathLength; - - startOffset += textAnchorStartOffset; - currentOffset = startOffset; - - // Only baseline-shift is handled through the normal layout system - addStackContent(BaselineShiftStack, baselineShift); - - if (isInitialLayout) { - xStackChanged = false; - yStackChanged = false; - dxStackChanged = false; - dyStackChanged = false; - angleStackChanged = false; - baselineShiftStackChanged = false; - } -} - -void SVGCharacterLayoutInfo::addLayoutInformation(SVGTextPositioningElement* element) -{ - bool isInitialLayout = xStack.isEmpty() && yStack.isEmpty() && - dxStack.isEmpty() && dyStack.isEmpty() && - angleStack.isEmpty() && baselineShiftStack.isEmpty() && - curx == 0.0f && cury == 0.0f; - - float baselineShift = calculateBaselineShift(element->renderer()); - - addStackContent(XStack, element->x(), element); - addStackContent(YStack, element->y(), element); - addStackContent(DxStack, element->dx(), element); - addStackContent(DyStack, element->dy(), element); - addStackContent(AngleStack, element->rotate()); - addStackContent(BaselineShiftStack, baselineShift); - - if (isInitialLayout) { - xStackChanged = false; - yStackChanged = false; - dxStackChanged = false; - dyStackChanged = false; - angleStackChanged = false; - baselineShiftStackChanged = false; - } -} - -void SVGCharacterLayoutInfo::addStackContent(StackType type, SVGNumberList* list) -{ - unsigned length = list->numberOfItems(); - if (!length) - return; - - PositionedFloatVector newLayoutInfo; - - // TODO: Convert more efficiently! - ExceptionCode ec = 0; - for (unsigned i = 0; i < length; ++i) { - float value = list->getItem(i, ec); - ASSERT(ec == 0); - - newLayoutInfo.append(value); - } - - addStackContent(type, newLayoutInfo); -} - -void SVGCharacterLayoutInfo::addStackContent(StackType type, SVGLengthList* list, const SVGElement* context) -{ - unsigned length = list->numberOfItems(); - if (!length) - return; - - PositionedFloatVector newLayoutInfo; - - ExceptionCode ec = 0; - for (unsigned i = 0; i < length; ++i) { - float value = list->getItem(i, ec).value(context); - ASSERT(ec == 0); - - newLayoutInfo.append(value); - } - - addStackContent(type, newLayoutInfo); -} - -void SVGCharacterLayoutInfo::addStackContent(StackType type, const PositionedFloatVector& list) -{ - switch (type) { - case XStack: - xStackChanged = true; - xStack.append(list); - break; - case YStack: - yStackChanged = true; - yStack.append(list); - break; - case DxStack: - dxStackChanged = true; - dxStack.append(list); - break; - case DyStack: - dyStackChanged = true; - dyStack.append(list); - break; - case AngleStack: - angleStackChanged = true; - angleStack.append(list); - break; - default: - ASSERT_NOT_REACHED(); - } -} - -void SVGCharacterLayoutInfo::addStackContent(StackType type, float value) -{ - if (value == 0.0f) - return; - - switch (type) { - case BaselineShiftStack: - baselineShiftStackChanged = true; - baselineShiftStack.append(value); - break; - default: - ASSERT_NOT_REACHED(); - } -} - -void SVGCharacterLayoutInfo::xStackWalk() -{ - unsigned i = 1; - - while (!xStack.isEmpty()) { - PositionedFloatVector& cur = xStack.last(); - if (i + cur.position() < cur.size()) { - cur.advance(i); - break; - } - - i += cur.position(); - xStack.removeLast(); - xStackChanged = false; - } -} - -void SVGCharacterLayoutInfo::yStackWalk() -{ - unsigned i = 1; - - while (!yStack.isEmpty()) { - PositionedFloatVector& cur = yStack.last(); - if (i + cur.position() < cur.size()) { - cur.advance(i); - break; - } - - i += cur.position(); - yStack.removeLast(); - yStackChanged = false; - } -} - -void SVGCharacterLayoutInfo::dxStackWalk() -{ - unsigned i = 1; - - while (!dxStack.isEmpty()) { - PositionedFloatVector& cur = dxStack.last(); - if (i + cur.position() < cur.size()) { - cur.advance(i); - break; - } - - i += cur.position(); - dxStack.removeLast(); - dxStackChanged = false; - } -} - -void SVGCharacterLayoutInfo::dyStackWalk() -{ - unsigned i = 1; - - while (!dyStack.isEmpty()) { - PositionedFloatVector& cur = dyStack.last(); - if (i + cur.position() < cur.size()) { - cur.advance(i); - break; - } - - i += cur.position(); - dyStack.removeLast(); - dyStackChanged = false; - } -} - -void SVGCharacterLayoutInfo::angleStackWalk() -{ - unsigned i = 1; - - while (!angleStack.isEmpty()) { - PositionedFloatVector& cur = angleStack.last(); - if (i + cur.position() < cur.size()) { - cur.advance(i); - break; - } - - i += cur.position(); - angleStack.removeLast(); - angleStackChanged = false; - } -} - -void SVGCharacterLayoutInfo::baselineShiftStackWalk() -{ - if (!baselineShiftStack.isEmpty()) { - baselineShiftStack.removeLast(); - baselineShiftStackChanged = false; - } -} - -bool SVGChar::isHidden() const -{ - return pathData && pathData->hidden; -} - -AffineTransform SVGChar::characterTransform() const -{ - AffineTransform ctm; - - // Rotate character around angle, and possibly scale. - ctm.translate(x, y); - ctm.rotate(angle); - - if (pathData) { - ctm.scale(pathData->xScale, pathData->yScale); - ctm.translate(pathData->xShift, pathData->yShift); - ctm.rotate(pathData->orientationAngle); - } - - ctm.translate(orientationShiftX - x, orientationShiftY - y); - return ctm; -} - -} // namespace WebCore - -#endif // ENABLE(SVG) |