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

📄 rendersvgtext.cpp

📁 linux下开源浏览器WebKit的源码,市面上的很多商用浏览器都是移植自WebKit
💻 CPP
字号:
/* * This file is part of the WebKit project. * * Copyright (C) 2006 Apple Computer, Inc. *               2006 Alexander Kellett <lypanov@kde.org> *               2006 Oliver Hunt <ojh16@student.canterbury.ac.nz> *               2007 Nikolas Zimmermann <zimmermann@kde.org> *               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 "RenderSVGText.h"#include "FloatConversion.h"#include "FloatQuad.h"#include "GraphicsContext.h"#include "PointerEventsHitRules.h"#include "RenderSVGRoot.h"#include "SVGLengthList.h"#include "SVGResourceFilter.h"#include "SVGRootInlineBox.h"#include "SVGTextElement.h"#include "SVGTransformList.h"#include "SVGURIReference.h"#include "SimpleFontData.h"namespace WebCore {RenderSVGText::RenderSVGText(SVGTextElement* node)     : RenderSVGBlock(node){}IntRect RenderSVGText::clippedOverflowRectForRepaint(RenderBoxModelObject* /*repaintContainer*/){    // FIXME: handle non-root repaintContainer    FloatRect repaintRect = absoluteTransform().mapRect(relativeBBox(true));#if ENABLE(SVG_FILTERS)    // Filters can expand the bounding box    SVGResourceFilter* filter = getFilterById(document(), style()->svgStyle()->filter());    if (filter)        repaintRect.unite(filter->filterBBoxForItemBBox(repaintRect));#endif    if (!repaintRect.isEmpty())        repaintRect.inflate(1); // inflate 1 pixel for antialiasing    return enclosingIntRect(repaintRect);}bool RenderSVGText::calculateLocalTransform(){    TransformationMatrix oldTransform = m_localTransform;    m_localTransform = static_cast<SVGTextElement*>(node())->animatedLocalTransform();    return (oldTransform != m_localTransform);}void RenderSVGText::layout(){    ASSERT(needsLayout());        // FIXME: This is a hack to avoid the RenderBlock::layout() partial repainting code which is not (yet) SVG aware    setNeedsLayout(true);    // FIXME: using m_absoluteBounds breaks if containerForRepaint() is not the root    LayoutRepainter repainter(*this, checkForRepaintDuringLayout(), &m_absoluteBounds);    // Best guess for a relative starting point    SVGTextElement* text = static_cast<SVGTextElement*>(node());    int xOffset = (int)(text->x()->getFirst().value(text));    int yOffset = (int)(text->y()->getFirst().value(text));    setLocation(xOffset, yOffset);        calculateLocalTransform();    RenderBlock::layout();    m_absoluteBounds = absoluteClippedOverflowRect();    repainter.repaintAfterLayout();            setNeedsLayout(false);}RootInlineBox* RenderSVGText::createRootBox(){    return new (renderArena()) SVGRootInlineBox(this);}bool RenderSVGText::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction){    PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, style()->pointerEvents());    bool isVisible = (style()->visibility() == VISIBLE);    if (isVisible || !hitRules.requireVisible) {        if ((hitRules.canHitStroke && (style()->svgStyle()->hasStroke() || !hitRules.requireStroke))            || (hitRules.canHitFill && (style()->svgStyle()->hasFill() || !hitRules.requireFill))) {            TransformationMatrix totalTransform = absoluteTransform();            double localX, localY;            totalTransform.inverse().map(_x, _y, localX, localY);            FloatPoint hitPoint(_x, _y);            return RenderBlock::nodeAtPoint(request, result, (int)localX, (int)localY, _tx, _ty, hitTestAction);        }    }    return false;}void RenderSVGText::absoluteRects(Vector<IntRect>& rects, int, int, bool){    RenderSVGRoot* root = findSVGRootObject(parent());    if (!root)        return;    FloatPoint absPos = localToAbsolute();    TransformationMatrix htmlParentCtm = root->RenderBox::absoluteTransform();     // Don't use relativeBBox here, as it's unites the selection rects. Makes it hard    // to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.    for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {        ASSERT(runBox->isInlineFlowBox());        InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);        for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {            FloatRect boxRect(box->x(), box->y(), box->width(), box->height());            boxRect.move(narrowPrecisionToFloat(absPos.x() - htmlParentCtm.e()), narrowPrecisionToFloat(absPos.y() - htmlParentCtm.f()));            // FIXME: broken with CSS transforms            rects.append(enclosingIntRect(absoluteTransform().mapRect(boxRect)));        }    }}void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool){    RenderSVGRoot* root = findSVGRootObject(parent());    if (!root)        return;    FloatPoint absPos = localToAbsolute();    TransformationMatrix htmlParentCtm = root->RenderBox::absoluteTransform();     // Don't use relativeBBox here, as it's unites the selection rects. Makes it hard    // to spot errors, if there are any using WebInspector. Individually feed them into 'rects'.    for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {        ASSERT(runBox->isInlineFlowBox());        InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);        for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine()) {            FloatRect boxRect(box->x(), box->y(), box->width(), box->height());            boxRect.move(narrowPrecisionToFloat(absPos.x() - htmlParentCtm.e()), narrowPrecisionToFloat(absPos.y() - htmlParentCtm.f()));            // FIXME: broken with CSS transforms            quads.append(absoluteTransform().mapRect(boxRect));        }    }}void RenderSVGText::paint(PaintInfo& paintInfo, int, int){       RenderObject::PaintInfo pi(paintInfo);    pi.rect = absoluteTransform().inverse().mapRect(pi.rect);    RenderBlock::paint(pi, 0, 0);}FloatRect RenderSVGText::relativeBBox(bool includeStroke) const{    FloatRect repaintRect;    for (InlineRunBox* runBox = firstLineBox(); runBox; runBox = runBox->nextLineBox()) {        ASSERT(runBox->isInlineFlowBox());        InlineFlowBox* flowBox = static_cast<InlineFlowBox*>(runBox);        for (InlineBox* box = flowBox->firstChild(); box; box = box->nextOnLine())            repaintRect.unite(FloatRect(box->x(), box->y(), box->width(), box->height()));    }    // SVG needs to include the strokeWidth(), not the textStrokeWidth().    if (includeStroke && style()->svgStyle()->hasStroke()) {        float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, style()->svgStyle()->strokeWidth(), 0.0f);#if ENABLE(SVG_FONTS)        const Font& font = style()->font();        if (font.primaryFont()->isSVGFont()) {            float scale = font.unitsPerEm() > 0 ? font.size() / font.unitsPerEm() : 0.0f;            if (scale != 0.0f)                strokeWidth /= scale;        }#endif        repaintRect.inflate(strokeWidth);    }    repaintRect.move(x(), y());    return repaintRect;}}#endif // ENABLE(SVG)// vim:ts=4:noet

⌨️ 快捷键说明

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