⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svgtextcontentelement.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*    Copyright (C) 2004, 2005, 2007, 2008 Nikolas Zimmermann <zimmermann@kde.org>                  2004, 2005, 2006, 2007, 2008 Rob Buis <buis@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 "SVGTextContentElement.h"#include "CSSPropertyNames.h"#include "CSSValueKeywords.h"#include "ExceptionCode.h"#include "FloatPoint.h"#include "FloatRect.h"#include "Frame.h"#include "Position.h"#include "RenderSVGText.h"#include "SelectionController.h"#include "SVGCharacterLayoutInfo.h"#include "SVGRootInlineBox.h"#include "SVGLength.h"#include "SVGInlineTextBox.h"#include "SVGNames.h"#include "XMLNames.h"#include <wtf/StdLibExtras.h>namespace WebCore {char SVGTextContentElementIdentifier[] = "SVGTextContentElement";SVGTextContentElement::SVGTextContentElement(const QualifiedName& tagName, Document* doc)    : SVGStyledElement(tagName, doc)    , SVGTests()    , SVGLangSpace()    , SVGExternalResourcesRequired()    , m_textLength(this, SVGNames::textLengthAttr, LengthModeOther)    , m_lengthAdjust(this, SVGNames::lengthAdjustAttr, LENGTHADJUST_SPACING){}SVGTextContentElement::~SVGTextContentElement(){}static inline float cumulativeCharacterRangeLength(const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end, SVGInlineTextBox* textBox,                                                   int startOffset, long startPosition, long length, bool isVerticalText, long& atCharacter){    if (!length)        return 0.0f;    float textLength = 0.0f;    RenderStyle* style = textBox->textRenderer()->style();    bool usesFullRange = (startPosition == -1 && length == -1);    for (Vector<SVGChar>::iterator it = start; it != end; ++it) {        if (usesFullRange || (atCharacter >= startPosition && atCharacter <= startPosition + length)) {            unsigned int newOffset = textBox->start() + (it - start) + startOffset;            // Take RTL text into account and pick right glyph width/height.            if (textBox->direction() == RTL)                newOffset = textBox->start() + textBox->end() - newOffset;            // FIXME: does this handle multichar glyphs ok? not sure            int charsConsumed = 0;            String glyphName;            if (isVerticalText)                textLength += textBox->calculateGlyphHeight(style, newOffset, 0);            else                textLength += textBox->calculateGlyphWidth(style, newOffset, 0, charsConsumed, glyphName);        }        if (!usesFullRange) {            if (atCharacter == startPosition + length - 1)                break;            atCharacter++;        }    }    return textLength;}// Helper class for querying certain glyph informationstruct SVGInlineTextBoxQueryWalker {    typedef enum {        NumberOfCharacters,        TextLength,        SubStringLength,        StartPosition,        EndPosition,        Extent,        Rotation,        CharacterNumberAtPosition    } QueryMode;    SVGInlineTextBoxQueryWalker(const SVGTextContentElement* reference, QueryMode mode)        : m_reference(reference)        , m_mode(mode)        , m_queryStartPosition(0)        , m_queryLength(0)        , m_queryPointInput()        , m_queryLongResult(0)        , m_queryFloatResult(0.0f)        , m_queryPointResult()        , m_queryRectResult()        , m_stopProcessing(true)            , m_atCharacter(0)    {    }    void chunkPortionCallback(SVGInlineTextBox* textBox, int startOffset, const TransformationMatrix&,                              const Vector<SVGChar>::iterator& start, const Vector<SVGChar>::iterator& end)    {        RenderStyle* style = textBox->textRenderer()->style();        bool isVerticalText = style->svgStyle()->writingMode() == WM_TBRL || style->svgStyle()->writingMode() == WM_TB;        switch (m_mode) {        case NumberOfCharacters:        {                m_queryLongResult += (end - start);            m_stopProcessing = false;            return;        }        case TextLength:        {            float textLength = cumulativeCharacterRangeLength(start, end, textBox, startOffset, -1, -1, isVerticalText, m_atCharacter);            if (isVerticalText)                m_queryFloatResult += textLength;            else                m_queryFloatResult += textLength;            m_stopProcessing = false;            return;        }        case SubStringLength:        {            long startPosition = m_queryStartPosition;            long length = m_queryLength;            float textLength = cumulativeCharacterRangeLength(start, end, textBox, startOffset, startPosition, length, isVerticalText, m_atCharacter);            if (isVerticalText)                m_queryFloatResult += textLength;            else                m_queryFloatResult += textLength;            if (m_atCharacter == startPosition + length)                m_stopProcessing = true;            else                m_stopProcessing = false;            return;        }        case StartPosition:        {            for (Vector<SVGChar>::iterator it = start; it != end; ++it) {                if (m_atCharacter == m_queryStartPosition) {                    m_queryPointResult = FloatPoint(it->x, it->y);                    m_stopProcessing = true;                    return;                }                m_atCharacter++;            }            m_stopProcessing = false;            return;        }        case EndPosition:        {            for (Vector<SVGChar>::iterator it = start; it != end; ++it) {                if (m_atCharacter == m_queryStartPosition) {                    unsigned int newOffset = textBox->start() + (it - start) + startOffset;                    // Take RTL text into account and pick right glyph width/height.                    if (textBox->direction() == RTL)                        newOffset = textBox->start() + textBox->end() - newOffset;                    int charsConsumed;                    String glyphName;                    // calculateGlyph{Height,Width} will consume at least one character. This is the number of characters available                    // to them beyond that first one.                    int extraCharactersAvailable = end - it - 1;                    if (isVerticalText)                        m_queryPointResult.move(it->x, it->y + textBox->calculateGlyphHeight(style, newOffset, extraCharactersAvailable));                    else                        m_queryPointResult.move(it->x + textBox->calculateGlyphWidth(style, newOffset, extraCharactersAvailable, charsConsumed, glyphName), it->y);                    m_stopProcessing = true;                    return;                }                m_atCharacter++;            }            m_stopProcessing = false;            return;        }        case Extent:        {            for (Vector<SVGChar>::iterator it = start; it != end; ++it) {                if (m_atCharacter == m_queryStartPosition) {                    unsigned int newOffset = textBox->start() + (it - start) + startOffset;                    m_queryRectResult = textBox->calculateGlyphBoundaries(style, newOffset, *it);                    m_stopProcessing = true;                    return;                }                m_atCharacter++;            }            m_stopProcessing = false;            return;        }        case Rotation:        {            for (Vector<SVGChar>::iterator it = start; it != end; ++it) {                if (m_atCharacter == m_queryStartPosition) {                    m_queryFloatResult = it->angle;                    m_stopProcessing = true;                    return;                }                m_atCharacter++;            }            m_stopProcessing = false;            return;        }        case CharacterNumberAtPosition:        {            int offset = 0;            SVGChar* charAtPos = textBox->closestCharacterToPosition(m_queryPointInput.x(), m_queryPointInput.y(), offset);            offset += m_atCharacter;            if (charAtPos && offset > m_queryLongResult)                m_queryLongResult = offset;            m_atCharacter += end - start;            m_stopProcessing = false;            return;        }        default:            ASSERT_NOT_REACHED();            m_stopProcessing = true;            return;        }    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -