15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/* 25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) Research In Motion Limited 2010. All rights reserved. 35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is free software; you can redistribute it and/or 55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modify it under the terms of the GNU Library General Public 65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * License as published by the Free Software Foundation; either 75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * version 2 of the License, or (at your option) any later version. 85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * This library is distributed in the hope that it will be useful, 105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * but WITHOUT ANY WARRANTY; without even the implied warranty of 115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Library General Public License for more details. 135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * You should have received a copy of the GNU Library General Public License 155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * along with this library; see the file COPYING.LIB. If not, write to 165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Boston, MA 02110-1301, USA. 185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */ 195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "config.h" 215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/SVGTextLayoutEngineBaseline.h" 2353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) 2453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/RenderObject.h" 2553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/style/SVGRenderStyle.h" 2653e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/rendering/svg/SVGTextMetrics.h" 2753e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/svg/SVGLengthContext.h" 28a854de003a23bf3c7f95ec0f8154ada64092ff5cTorne (Richard Coles)#include "platform/fonts/Font.h" 291e202183a5dc46166763171984b285173f8585e5Torne (Richard Coles)#include "platform/text/UnicodeRange.h" 305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore { 325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)SVGTextLayoutEngineBaseline::SVGTextLayoutEngineBaseline(const Font& font) 345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) : m_font(font) 355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGTextLayoutEngineBaseline::calculateBaselineShift(const SVGRenderStyle* style, SVGElement* contextElement) const 395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (style->baselineShift() == BS_LENGTH) { 4109380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) RefPtr<SVGLength> baselineShiftValueLength = style->baselineShiftValue(); 4209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) if (baselineShiftValueLength->unitType() == LengthTypePercentage) 4309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return baselineShiftValueLength->valueAsPercentage() * m_font.fontDescription().computedPixelSize(); 445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) SVGLengthContext lengthContext(contextElement); 4609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles) return baselineShiftValueLength->value(lengthContext); 475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (style->baselineShift()) { 505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case BS_BASELINE: 515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case BS_SUB: 535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return -m_font.fontMetrics().floatHeight() / 2; 545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case BS_SUPER: 555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return m_font.fontMetrics().floatHeight() / 2; 565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)EAlignmentBaseline SVGTextLayoutEngineBaseline::dominantBaselineToAlignmentBaseline(bool isVerticalText, const RenderObject* textRenderer) const 635c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(textRenderer); 655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(textRenderer->style()); 665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(textRenderer->parent()); 675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(textRenderer->parent()->style()); 685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const SVGRenderStyle* style = textRenderer->style()->svgStyle(); 705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(style); 715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EDominantBaseline baseline = style->dominantBaseline(); 735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (baseline == DB_AUTO) { 745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isVerticalText) 755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baseline = DB_CENTRAL; 765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else 775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baseline = DB_ALPHABETIC; 785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (baseline) { 815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DB_USE_SCRIPT: 825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // FIXME: The dominant-baseline and the baseline-table components are set by determining the predominant script of the character data content. 835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return AB_ALPHABETIC; 845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DB_NO_CHANGE: 855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return dominantBaselineToAlignmentBaseline(isVerticalText, textRenderer->parent()); 865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DB_RESET_SIZE: 875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return dominantBaselineToAlignmentBaseline(isVerticalText, textRenderer->parent()); 885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DB_IDEOGRAPHIC: 895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return AB_IDEOGRAPHIC; 905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DB_ALPHABETIC: 915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return AB_ALPHABETIC; 925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DB_HANGING: 935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return AB_HANGING; 945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DB_MATHEMATICAL: 955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return AB_MATHEMATICAL; 965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DB_CENTRAL: 975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return AB_CENTRAL; 985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DB_MIDDLE: 995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return AB_MIDDLE; 1005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DB_TEXT_AFTER_EDGE: 1015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return AB_TEXT_AFTER_EDGE; 1025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case DB_TEXT_BEFORE_EDGE: 1035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return AB_TEXT_BEFORE_EDGE; 1045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 1055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return AB_AUTO; 1075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGTextLayoutEngineBaseline::calculateAlignmentBaselineShift(bool isVerticalText, const RenderObject* textRenderer) const 1115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(textRenderer); 1135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(textRenderer->style()); 1145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(textRenderer->style()->svgStyle()); 1155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(textRenderer->parent()); 1165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const RenderObject* textRendererParent = textRenderer->parent(); 1185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(textRendererParent); 1195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) EAlignmentBaseline baseline = textRenderer->style()->svgStyle()->alignmentBaseline(); 1215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (baseline == AB_AUTO) { 1225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) baseline = dominantBaselineToAlignmentBaseline(isVerticalText, textRendererParent); 1235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(baseline != AB_AUTO); 1245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FontMetrics& fontMetrics = m_font.fontMetrics(); 1275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Note: http://wiki.apache.org/xmlgraphics-fop/LineLayout/AlignmentHandling 1295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (baseline) { 1305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AB_BASELINE: 1315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return dominantBaselineToAlignmentBaseline(isVerticalText, textRendererParent); 1325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AB_BEFORE_EDGE: 1335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AB_TEXT_BEFORE_EDGE: 1345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fontMetrics.floatAscent(); 1355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AB_MIDDLE: 1365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fontMetrics.xHeight() / 2; 1375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AB_CENTRAL: 1385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return (fontMetrics.floatAscent() - fontMetrics.floatDescent()) / 2; 1395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AB_AFTER_EDGE: 1405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AB_TEXT_AFTER_EDGE: 1415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AB_IDEOGRAPHIC: 1425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fontMetrics.floatDescent(); 1435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AB_ALPHABETIC: 1445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AB_HANGING: 1465c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fontMetrics.floatAscent() * 8 / 10.f; 1475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case AB_MATHEMATICAL: 1485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return fontMetrics.floatAscent() / 2; 1495c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 1505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT_NOT_REACHED(); 1515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1535c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1555c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGTextLayoutEngineBaseline::calculateGlyphOrientationAngle(bool isVerticalText, const SVGRenderStyle* style, const UChar& character) const 1565c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1575c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) ASSERT(style); 1585c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1595c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) switch (isVerticalText ? style->glyphOrientationVertical() : style->glyphOrientationHorizontal()) { 1605c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case GO_AUTO: { 1615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Spec: Fullwidth ideographic and fullwidth Latin text will be set with a glyph-orientation of 0-degrees. 1625c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Text which is not fullwidth will be set with a glyph-orientation of 90-degrees. 16307a852d8c1953036774d8f3b65d18dcfea3bb4a2Ben Murdoch unsigned unicodeRange = findCharUnicodeRange(character); 1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (unicodeRange == cRangeSetLatin || unicodeRange == cRangeArabic) 1655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 90; 1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case GO_90DEG: 1705c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 90; 1715c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case GO_180DEG: 1725c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 180; 1735c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case GO_270DEG: 1745c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 270; 1755c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) case GO_0DEG: 1765c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) default: 1775c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return 0; 1785c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 1795c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1805c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1815c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)static inline bool glyphOrientationIsMultiplyOf180Degrees(float orientationAngle) 1825c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1835c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return !fabsf(fmodf(orientationAngle, 180)); 1845c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 1855c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1865c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)float SVGTextLayoutEngineBaseline::calculateGlyphAdvanceAndOrientation(bool isVerticalText, SVGTextMetrics& metrics, float angle, float& xOrientationShift, float& yOrientationShift) const 1875c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles){ 1885c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) bool orientationIsMultiplyOf180Degrees = glyphOrientationIsMultiplyOf180Degrees(angle); 1895c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1905c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // The function is based on spec requirements: 1915c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 1925c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Spec: If the 'glyph-orientation-horizontal' results in an orientation angle that is not a multiple of 1935c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // of 180 degrees, then the current text position is incremented according to the vertical metrics of the glyph. 1945c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 1955c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Spec: If if the 'glyph-orientation-vertical' results in an orientation angle that is not a multiple of 1965c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // 180 degrees, then the current text position is incremented according to the horizontal metrics of the glyph. 1975c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 1985c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) const FontMetrics& fontMetrics = m_font.fontMetrics(); 1995c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2005c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Vertical orientation handling. 2015c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (isVerticalText) { 2025c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) float ascentMinusDescent = fontMetrics.floatAscent() - fontMetrics.floatDescent(); 2035c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (!angle) { 2045c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) xOrientationShift = (ascentMinusDescent - metrics.width()) / 2; 2055c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) yOrientationShift = fontMetrics.floatAscent(); 2065c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (angle == 180) 2075c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) xOrientationShift = (ascentMinusDescent + metrics.width()) / 2; 2085c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (angle == 270) { 2095c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) yOrientationShift = metrics.width(); 2105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) xOrientationShift = ascentMinusDescent; 2115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Vertical advance calculation. 2145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (angle && !orientationIsMultiplyOf180Degrees) 2155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return metrics.width(); 2165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return metrics.height(); 2185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } 2195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Horizontal orientation handling. 2215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (angle == 90) 2225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) yOrientationShift = -metrics.width(); 2235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) else if (angle == 180) { 2245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) xOrientationShift = metrics.width(); 2255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) yOrientationShift = -fontMetrics.floatAscent(); 2265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) } else if (angle == 270) 2275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) xOrientationShift = metrics.width(); 2285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) // Horizontal advance calculation. 2305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) if (angle && !orientationIsMultiplyOf180Degrees) 2315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return metrics.height(); 2325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) return metrics.width(); 2345c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 2355c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) 2365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)} 237