mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
136 lines
4.1 KiB
C++
136 lines
4.1 KiB
C++
/*
|
|
* Copyright (C) 1999 Lars Knoll (knoll@kde.org)
|
|
* (C) 1999 Antti Koivisto (koivisto@kde.org)
|
|
* (C) 2001 Dirk Mueller (mueller@kde.org)
|
|
* Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
|
|
* Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
|
|
* Copyright (C) 2011 Google Inc. 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 "sky/engine/core/dom/RenderTreeBuilder.h"
|
|
|
|
#include "sky/engine/core/css/resolver/StyleResolver.h"
|
|
#include "sky/engine/core/dom/Node.h"
|
|
#include "sky/engine/core/dom/Text.h"
|
|
#include "sky/engine/core/dom/shadow/InsertionPoint.h"
|
|
#include "sky/engine/core/rendering/RenderObject.h"
|
|
#include "sky/engine/core/rendering/RenderText.h"
|
|
#include "sky/engine/core/rendering/RenderView.h"
|
|
|
|
namespace blink {
|
|
|
|
RenderObject* RenderTreeBuilder::nextRenderer() const
|
|
{
|
|
ASSERT(m_renderingParent);
|
|
|
|
// Avoid an O(N^2) walk over the children when reattaching all children of a node.
|
|
if (m_renderingParent->needsAttach())
|
|
return 0;
|
|
|
|
return NodeRenderingTraversal::nextSiblingRenderer(m_node);
|
|
}
|
|
|
|
RenderObject* RenderTreeBuilder::parentRenderer() const
|
|
{
|
|
ASSERT(m_renderingParent);
|
|
return m_renderingParent->renderer();
|
|
}
|
|
|
|
bool RenderTreeBuilder::shouldCreateRenderer() const
|
|
{
|
|
if (!m_renderingParent)
|
|
return false;
|
|
RenderObject* parentRenderer = this->parentRenderer();
|
|
if (!parentRenderer)
|
|
return false;
|
|
if (!parentRenderer->canHaveChildren())
|
|
return false;
|
|
if (isActiveInsertionPoint(*m_node))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
RenderStyle& RenderTreeBuilder::style() const
|
|
{
|
|
if (!m_style)
|
|
m_style = toElement(m_node)->styleForRenderer();
|
|
return *m_style;
|
|
}
|
|
|
|
void RenderTreeBuilder::createRendererForElementIfNeeded()
|
|
{
|
|
ASSERT(!m_node->renderer());
|
|
|
|
if (!shouldCreateRenderer())
|
|
return;
|
|
|
|
Element* element = toElement(m_node);
|
|
RenderStyle& style = this->style();
|
|
|
|
if (style.display() == NONE)
|
|
return;
|
|
|
|
RenderObject* newRenderer = element->createRenderer(&style);
|
|
if (!newRenderer)
|
|
return;
|
|
|
|
RenderObject* parentRenderer = this->parentRenderer();
|
|
|
|
if (!parentRenderer->isChildAllowed(newRenderer, &style)) {
|
|
newRenderer->destroy();
|
|
return;
|
|
}
|
|
|
|
RenderObject* nextRenderer = this->nextRenderer();
|
|
element->setRenderer(newRenderer);
|
|
newRenderer->setStyle(&style); // setStyle() can depend on renderer() already being set.
|
|
|
|
// Note: Adding newRenderer instead of renderer(). renderer() may be a child of newRenderer.
|
|
parentRenderer->addChild(newRenderer, nextRenderer);
|
|
}
|
|
|
|
void RenderTreeBuilder::createRendererForTextIfNeeded()
|
|
{
|
|
ASSERT(!m_node->renderer());
|
|
|
|
if (!shouldCreateRenderer())
|
|
return;
|
|
|
|
Text* textNode = toText(m_node);
|
|
RenderObject* parentRenderer = this->parentRenderer();
|
|
|
|
m_style = parentRenderer->style();
|
|
|
|
if (!textNode->textRendererIsNeeded(*m_style, *parentRenderer))
|
|
return;
|
|
|
|
RenderText* newRenderer = textNode->createTextRenderer(m_style.get());
|
|
if (!parentRenderer->isChildAllowed(newRenderer, m_style.get())) {
|
|
newRenderer->destroy();
|
|
return;
|
|
}
|
|
|
|
RenderObject* nextRenderer = this->nextRenderer();
|
|
textNode->setRenderer(newRenderer);
|
|
newRenderer->setStyle(m_style.release());
|
|
parentRenderer->addChild(newRenderer, nextRenderer);
|
|
}
|
|
|
|
}
|