summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering/SVGTextLayoutUtilities.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering/SVGTextLayoutUtilities.cpp')
-rw-r--r--WebCore/rendering/SVGTextLayoutUtilities.cpp375
1 files changed, 0 insertions, 375 deletions
diff --git a/WebCore/rendering/SVGTextLayoutUtilities.cpp b/WebCore/rendering/SVGTextLayoutUtilities.cpp
deleted file mode 100644
index 2debf28..0000000
--- a/WebCore/rendering/SVGTextLayoutUtilities.cpp
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
- 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"
-#include "SVGTextLayoutUtilities.h"
-
-#if ENABLE(SVG)
-#include "FloatPoint.h"
-#include "InlineTextBox.h"
-#include "RenderObject.h"
-#include "SVGCharacterData.h"
-#include "SVGCharacterLayoutInfo.h"
-#include "SVGFontElement.h"
-#include "SVGRenderStyle.h"
-#include "SVGTextChunkLayoutInfo.h"
-#include "TextRun.h"
-#include "UnicodeRange.h"
-
-#include <float.h>
-
-namespace WebCore {
-
-bool isVerticalWritingMode(const SVGRenderStyle* style)
-{
- return style->writingMode() == WM_TBRL || style->writingMode() == WM_TB;
-}
-
-static inline EAlignmentBaseline dominantBaselineToShift(bool isVerticalText, const RenderObject* text, const Font& font)
-{
- ASSERT(text);
-
- const SVGRenderStyle* style = text->style() ? text->style()->svgStyle() : 0;
- ASSERT(style);
-
- const SVGRenderStyle* parentStyle = text->parent() && text->parent()->style() ? text->parent()->style()->svgStyle() : 0;
-
- EDominantBaseline baseline = style->dominantBaseline();
- if (baseline == DB_AUTO) {
- if (isVerticalText)
- baseline = DB_CENTRAL;
- else
- baseline = DB_ALPHABETIC;
- }
-
- switch (baseline) {
- case DB_USE_SCRIPT:
- // TODO: The dominant-baseline and the baseline-table components are set by
- // determining the predominant script of the character data content.
- return AB_ALPHABETIC;
- case DB_NO_CHANGE:
- {
- if (parentStyle)
- return dominantBaselineToShift(isVerticalText, text->parent(), font);
-
- ASSERT_NOT_REACHED();
- return AB_AUTO;
- }
- case DB_RESET_SIZE:
- {
- if (parentStyle)
- return dominantBaselineToShift(isVerticalText, text->parent(), font);
-
- ASSERT_NOT_REACHED();
- return AB_AUTO;
- }
- case DB_IDEOGRAPHIC:
- return AB_IDEOGRAPHIC;
- case DB_ALPHABETIC:
- return AB_ALPHABETIC;
- case DB_HANGING:
- return AB_HANGING;
- case DB_MATHEMATICAL:
- return AB_MATHEMATICAL;
- case DB_CENTRAL:
- return AB_CENTRAL;
- case DB_MIDDLE:
- return AB_MIDDLE;
- case DB_TEXT_AFTER_EDGE:
- return AB_TEXT_AFTER_EDGE;
- case DB_TEXT_BEFORE_EDGE:
- return AB_TEXT_BEFORE_EDGE;
- default:
- ASSERT_NOT_REACHED();
- return AB_AUTO;
- }
-}
-
-float alignmentBaselineToShift(bool isVerticalText, const RenderObject* text, const Font& font)
-{
- ASSERT(text);
-
- const SVGRenderStyle* style = text->style() ? text->style()->svgStyle() : 0;
- ASSERT(style);
-
- const SVGRenderStyle* parentStyle = text->parent() && text->parent()->style() ? text->parent()->style()->svgStyle() : 0;
-
- EAlignmentBaseline baseline = style->alignmentBaseline();
- if (baseline == AB_AUTO) {
- if (parentStyle && style->dominantBaseline() == DB_AUTO)
- baseline = dominantBaselineToShift(isVerticalText, text->parent(), font);
- else
- baseline = dominantBaselineToShift(isVerticalText, text, font);
-
- ASSERT(baseline != AB_AUTO);
- }
-
- // Note: http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling
- switch (baseline) {
- case AB_BASELINE:
- {
- if (parentStyle)
- return dominantBaselineToShift(isVerticalText, text->parent(), font);
-
- return 0.0f;
- }
- case AB_BEFORE_EDGE:
- case AB_TEXT_BEFORE_EDGE:
- return font.ascent();
- case AB_MIDDLE:
- return font.xHeight() / 2.0f;
- case AB_CENTRAL:
- // Not needed, we're taking this into account already for vertical text!
- // return (font.ascent() - font.descent()) / 2.0f;
- return 0.0f;
- case AB_AFTER_EDGE:
- case AB_TEXT_AFTER_EDGE:
- case AB_IDEOGRAPHIC:
- return font.descent();
- case AB_ALPHABETIC:
- return 0.0f;
- case AB_HANGING:
- return font.ascent() * 8.0f / 10.0f;
- case AB_MATHEMATICAL:
- return font.ascent() / 2.0f;
- default:
- ASSERT_NOT_REACHED();
- return 0.0f;
- }
-}
-
-float glyphOrientationToAngle(const SVGRenderStyle* svgStyle, bool isVerticalText, const UChar& character)
-{
- switch (isVerticalText ? svgStyle->glyphOrientationVertical() : svgStyle->glyphOrientationHorizontal()) {
- case GO_AUTO:
- {
- // Spec: Fullwidth ideographic and fullwidth Latin text will be set with a glyph-orientation of 0-degrees.
- // Text which is not fullwidth will be set with a glyph-orientation of 90-degrees.
- unsigned int unicodeRange = findCharUnicodeRange(character);
- if (unicodeRange == cRangeSetLatin || unicodeRange == cRangeArabic)
- return 90.0f;
-
- return 0.0f;
- }
- case GO_90DEG:
- return 90.0f;
- case GO_180DEG:
- return 180.0f;
- case GO_270DEG:
- return 270.0f;
- case GO_0DEG:
- default:
- return 0.0f;
- }
-}
-
-static inline bool glyphOrientationIsMultiplyOf180Degrees(float orientationAngle)
-{
- return fabsf(fmodf(orientationAngle, 180.0f)) == 0.0f;
-}
-
-float applyGlyphAdvanceAndShiftRespectingOrientation(bool isVerticalText, float orientationAngle, float glyphWidth, float glyphHeight, const Font& font, SVGChar& svgChar, float& xOrientationShift, float& yOrientationShift)
-{
- bool orientationIsMultiplyOf180Degrees = glyphOrientationIsMultiplyOf180Degrees(orientationAngle);
-
- // The function is based on spec requirements:
- //
- // Spec: If the 'glyph-orientation-horizontal' results in an orientation angle that is not a multiple of
- // of 180 degrees, then the current text position is incremented according to the vertical metrics of the glyph.
- //
- // Spec: If if the 'glyph-orientation-vertical' results in an orientation angle that is not a multiple of
- // 180 degrees,then the current text position is incremented according to the horizontal metrics of the glyph.
-
- // vertical orientation handling
- if (isVerticalText) {
- if (orientationAngle == 0.0f) {
- xOrientationShift = -glyphWidth / 2.0f;
- yOrientationShift = font.ascent();
- } else if (orientationAngle == 90.0f) {
- xOrientationShift = -glyphHeight;
- yOrientationShift = font.descent();
- svgChar.orientationShiftY = -font.ascent();
- } else if (orientationAngle == 270.0f) {
- xOrientationShift = glyphHeight;
- yOrientationShift = font.descent();
- svgChar.orientationShiftX = -glyphWidth;
- svgChar.orientationShiftY = -font.ascent();
- } else if (orientationAngle == 180.0f) {
- yOrientationShift = font.ascent();
- svgChar.orientationShiftX = -glyphWidth / 2.0f;
- svgChar.orientationShiftY = font.ascent() - font.descent();
- }
-
- // vertical advance calculation
- if (orientationAngle != 0.0f && !orientationIsMultiplyOf180Degrees)
- return glyphWidth;
-
- return glyphHeight;
- }
-
- // horizontal orientation handling
- if (orientationAngle == 90.0f) {
- xOrientationShift = glyphWidth / 2.0f;
- yOrientationShift = -font.descent();
- svgChar.orientationShiftX = -glyphWidth / 2.0f - font.descent();
- svgChar.orientationShiftY = font.descent();
- } else if (orientationAngle == 270.0f) {
- xOrientationShift = -glyphWidth / 2.0f;
- yOrientationShift = -font.descent();
- svgChar.orientationShiftX = -glyphWidth / 2.0f + font.descent();
- svgChar.orientationShiftY = glyphHeight;
- } else if (orientationAngle == 180.0f) {
- xOrientationShift = glyphWidth / 2.0f;
- svgChar.orientationShiftX = -glyphWidth / 2.0f;
- svgChar.orientationShiftY = font.ascent() - font.descent();
- }
-
- // horizontal advance calculation
- if (orientationAngle != 0.0f && !orientationIsMultiplyOf180Degrees)
- return glyphHeight;
-
- return glyphWidth;
-}
-
-FloatPoint topLeftPositionOfCharacterRange(Vector<SVGChar>::iterator it, Vector<SVGChar>::iterator end)
-{
- float lowX = FLT_MAX, lowY = FLT_MAX;
- for (; it != end; ++it) {
- if (it->isHidden())
- continue;
-
- float x = (*it).x;
- float y = (*it).y;
-
- if (x < lowX)
- lowX = x;
-
- if (y < lowY)
- lowY = y;
- }
-
- return FloatPoint(lowX, lowY);
-}
-
-float cummulatedWidthOfInlineBoxCharacterRange(SVGInlineBoxCharacterRange& range)
-{
- ASSERT(!range.isOpen());
- ASSERT(range.isClosed());
- ASSERT(range.box->isSVGInlineTextBox());
-
- InlineTextBox* textBox = static_cast<InlineTextBox*>(range.box);
- RenderText* text = textBox->textRenderer();
- RenderStyle* style = text->style();
- return style->font().floatWidth(svgTextRunForInlineTextBox(text->characters() + textBox->start() + range.startOffset, range.endOffset - range.startOffset, style, textBox));
-}
-
-float cummulatedHeightOfInlineBoxCharacterRange(SVGInlineBoxCharacterRange& range)
-{
- ASSERT(!range.isOpen());
- ASSERT(range.isClosed());
- ASSERT(range.box->isSVGInlineTextBox());
-
- InlineTextBox* textBox = static_cast<InlineTextBox*>(range.box);
- return (range.endOffset - range.startOffset) * textBox->textRenderer()->style()->font().height();
-}
-
-TextRun svgTextRunForInlineTextBox(const UChar* characters, int length, const RenderStyle* style, const InlineTextBox* textBox)
-{
- ASSERT(textBox);
- ASSERT(style);
-
- TextRun run(characters
- , length
- , false /* allowTabs */
- , 0 /* xPos, only relevant with allowTabs=true */
- , 0 /* padding, only relevant for justified text, not relevant for SVG */
- , textBox->direction() == RTL
- , textBox->m_dirOverride || style->visuallyOrdered() /* directionalOverride */);
-
-#if ENABLE(SVG_FONTS)
- run.setReferencingRenderObject(textBox->textRenderer()->parent());
-#endif
-
- // Disable any word/character rounding.
- run.disableRoundingHacks();
-
- // We handle letter & word spacing ourselves.
- run.disableSpacing();
- return run;
-}
-
-float calculateCSSKerning(SVGElement* context, const RenderStyle* style)
-{
- const Font& font = style->font();
- const SVGRenderStyle* svgStyle = style->svgStyle();
-
- SVGLength kerningLength = svgStyle->kerning();
- if (kerningLength.unitType() == LengthTypePercentage)
- return kerningLength.valueAsPercentage() * font.pixelSize();
-
- return kerningLength.value(context);
-}
-
-bool applySVGKerning(SVGCharacterLayoutInfo& info, const RenderStyle* style, SVGLastGlyphInfo& lastGlyph, const String& unicodeString, const String& glyphName, bool isVerticalText)
-{
-#if ENABLE(SVG_FONTS)
- float kerning = 0.0f;
-
- const Font& font = style->font();
- if (!font.isSVGFont()) {
- lastGlyph.isValid = false;
- return false;
- }
-
- SVGFontElement* svgFont = font.svgFont();
- ASSERT(svgFont);
-
- if (lastGlyph.isValid) {
- if (isVerticalText)
- kerning = svgFont->verticalKerningForPairOfStringsAndGlyphs(lastGlyph.unicode, lastGlyph.glyphName, unicodeString, glyphName);
- else
- kerning = svgFont->horizontalKerningForPairOfStringsAndGlyphs(lastGlyph.unicode, lastGlyph.glyphName, unicodeString, glyphName);
- }
-
- lastGlyph.unicode = unicodeString;
- lastGlyph.glyphName = glyphName;
- lastGlyph.isValid = true;
- kerning *= style->font().size() / style->font().primaryFont()->unitsPerEm();
-
- if (kerning != 0.0f) {
- if (isVerticalText)
- info.cury -= kerning;
- else
- info.curx -= kerning;
- return true;
- }
-#else
- UNUSED_PARAM(info);
- UNUSED_PARAM(item);
- UNUSED_PARAM(lastGlyph);
- UNUSED_PARAM(unicodeString);
- UNUSED_PARAM(glyphName);
-#endif
- return false;
-}
-
-}
-
-#endif