本文整理汇总了C++中RenderElement类的典型用法代码示例。如果您正苦于以下问题:C++ RenderElement类的具体用法?C++ RenderElement怎么用?C++ RenderElement使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了RenderElement类的12个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: firstChild
void RenderRubyAsInline::addChild(RenderObject* child, RenderObject* beforeChild)
{
// Insert :before and :after content before/after the RenderRubyRun(s)
if (child->isBeforeContent()) {
if (child->isInline()) {
// Add generated inline content normally
RenderInline::addChild(child, firstChild());
} else {
// Wrap non-inline content with an anonymous inline-block.
RenderBlock* beforeBlock = rubyBeforeBlock(this);
if (!beforeBlock) {
beforeBlock = createAnonymousRubyInlineBlock(*this);
RenderInline::addChild(beforeBlock, firstChild());
}
beforeBlock->addChild(child);
}
return;
}
if (child->isAfterContent()) {
if (child->isInline()) {
// Add generated inline content normally
RenderInline::addChild(child);
} else {
// Wrap non-inline content with an anonymous inline-block.
RenderBlock* afterBlock = rubyAfterBlock(this);
if (!afterBlock) {
afterBlock = createAnonymousRubyInlineBlock(*this);
RenderInline::addChild(afterBlock);
}
afterBlock->addChild(child);
}
return;
}
// If the child is a ruby run, just add it normally.
if (child->isRubyRun()) {
RenderInline::addChild(child, beforeChild);
return;
}
if (beforeChild && !isAfterContent(beforeChild)) {
// insert child into run
ASSERT(!beforeChild->isRubyRun());
RenderElement* run = beforeChild->parent();
while (run && !run->isRubyRun())
run = run->parent();
if (run) {
run->addChild(child, beforeChild);
return;
}
ASSERT_NOT_REACHED(); // beforeChild should always have a run as parent!
// Emergency fallback: fall through and just append.
}
// If the new child would be appended, try to add the child to the previous run
// if possible, or create a new run otherwise.
// (The RenderRubyRun object will handle the details)
RenderRubyRun* lastRun = lastRubyRun(this);
if (!lastRun || lastRun->hasRubyText()) {
lastRun = RenderRubyRun::staticCreateRubyRun(this);
RenderInline::addChild(lastRun, beforeChild);
}
lastRun->addChild(child);
}
示例2: postApplyResource
void RenderSVGResourceFilter::postApplyResource(RenderElement& renderer, GraphicsContext*& context, unsigned short resourceMode, const Path*, const RenderSVGShape*)
{
ASSERT(context);
ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);
FilterData* filterData = m_filter.get(&renderer);
if (!filterData)
return;
switch (filterData->state) {
case FilterData::MarkedForRemoval:
m_filter.remove(&renderer);
return;
case FilterData::CycleDetected:
case FilterData::Applying:
// We have a cycle if we are already applying the data.
// This can occur due to FeImage referencing a source that makes use of the FEImage itself.
// This is the first place we've hit the cycle, so set the state back to PaintingSource so the return stack
// will continue correctly.
filterData->state = FilterData::PaintingSource;
return;
case FilterData::PaintingSource:
if (!filterData->savedContext) {
removeClientFromCache(renderer);
return;
}
context = filterData->savedContext;
filterData->savedContext = 0;
break;
case FilterData::Built: { } // Empty
}
FilterEffect* lastEffect = filterData->builder->lastEffect();
if (lastEffect && !filterData->boundaries.isEmpty() && !lastEffect->filterPrimitiveSubregion().isEmpty()) {
// This is the real filtering of the object. It just needs to be called on the
// initial filtering process. We just take the stored filter result on a
// second drawing.
if (filterData->state != FilterData::Built)
filterData->filter->setSourceImage(WTF::move(filterData->sourceGraphicBuffer));
// Always true if filterData is just built (filterData->state == FilterData::Built).
if (!lastEffect->hasResult()) {
filterData->state = FilterData::Applying;
lastEffect->applyAll();
lastEffect->correctFilterResultIfNeeded();
lastEffect->transformResultColorSpace(ColorSpaceDeviceRGB);
}
filterData->state = FilterData::Built;
ImageBuffer* resultImage = lastEffect->asImageBuffer();
if (resultImage) {
context->concatCTM(filterData->shearFreeAbsoluteTransform.inverse());
context->scale(FloatSize(1 / filterData->filter->filterResolution().width(), 1 / filterData->filter->filterResolution().height()));
context->drawImageBuffer(*resultImage, renderer.style().colorSpace(), lastEffect->absolutePaintRect());
context->scale(filterData->filter->filterResolution());
context->concatCTM(filterData->shearFreeAbsoluteTransform);
}
}
filterData->sourceGraphicBuffer.reset();
}
示例3: applyResource
bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const RenderStyle&, GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(context);
ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);
if (m_filter.contains(&renderer)) {
FilterData* filterData = m_filter.get(&renderer);
if (filterData->state == FilterData::PaintingSource || filterData->state == FilterData::Applying)
filterData->state = FilterData::CycleDetected;
return false; // Already built, or we're in a cycle, or we're marked for removal. Regardless, just do nothing more now.
}
auto filterData = std::make_unique<FilterData>();
FloatRect targetBoundingBox = renderer.objectBoundingBox();
filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(&filterElement(), filterElement().filterUnits(), targetBoundingBox);
if (filterData->boundaries.isEmpty())
return false;
// Determine absolute transformation matrix for filter.
AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
if (!absoluteTransform.isInvertible())
return false;
// Eliminate shear of the absolute transformation matrix, to be able to produce unsheared tile images for feTile.
filterData->shearFreeAbsoluteTransform = AffineTransform(absoluteTransform.xScale(), 0, 0, absoluteTransform.yScale(), 0, 0);
// Determine absolute boundaries of the filter and the drawing region.
FloatRect absoluteFilterBoundaries = filterData->shearFreeAbsoluteTransform.mapRect(filterData->boundaries);
filterData->drawingRegion = renderer.strokeBoundingBox();
filterData->drawingRegion.intersect(filterData->boundaries);
FloatRect absoluteDrawingRegion = filterData->shearFreeAbsoluteTransform.mapRect(filterData->drawingRegion);
// Create the SVGFilter object.
bool primitiveBoundingBoxMode = filterElement().primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
filterData->filter = SVGFilter::create(filterData->shearFreeAbsoluteTransform, absoluteDrawingRegion, targetBoundingBox, filterData->boundaries, primitiveBoundingBoxMode);
// Create all relevant filter primitives.
filterData->builder = buildPrimitives(*filterData->filter);
if (!filterData->builder)
return false;
// Calculate the scale factor for the use of filterRes.
// Also see http://www.w3.org/TR/SVG/filters.html#FilterEffectsRegion
FloatSize scale(1, 1);
if (filterElement().hasAttribute(SVGNames::filterResAttr)) {
scale.setWidth(filterElement().filterResX() / absoluteFilterBoundaries.width());
scale.setHeight(filterElement().filterResY() / absoluteFilterBoundaries.height());
}
if (scale.isEmpty())
return false;
// Determine scale factor for filter. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
FloatRect tempSourceRect = absoluteDrawingRegion;
ImageBuffer::sizeNeedsClamping(tempSourceRect.size(), scale);
tempSourceRect.scale(scale.width(), scale.height());
// Set the scale level in SVGFilter.
filterData->filter->setFilterResolution(scale);
static const unsigned maxTotalOfEffectInputs = 100;
FilterEffect* lastEffect = filterData->builder->lastEffect();
if (!lastEffect || lastEffect->totalNumberOfEffectInputs() > maxTotalOfEffectInputs)
return false;
RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(*lastEffect);
FloatRect subRegion = lastEffect->maxEffectRect();
// At least one FilterEffect has a too big image size,
// recalculate the effect sizes with new scale factors.
if (ImageBuffer::sizeNeedsClamping(subRegion.size(), scale)) {
filterData->filter->setFilterResolution(scale);
RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(*lastEffect);
}
// If the drawingRegion is empty, we have something like <g filter=".."/>.
// Even if the target objectBoundingBox() is empty, we still have to draw the last effect result image in postApplyResource.
if (filterData->drawingRegion.isEmpty()) {
ASSERT(!m_filter.contains(&renderer));
filterData->savedContext = context;
m_filter.set(&renderer, WTF::move(filterData));
return false;
}
// Change the coordinate transformation applied to the filtered element to reflect the resolution of the filter.
AffineTransform effectiveTransform;
effectiveTransform.scale(scale.width(), scale.height());
effectiveTransform.multiply(filterData->shearFreeAbsoluteTransform);
RenderingMode renderingMode = renderer.frame().settings().acceleratedFiltersEnabled() ? Accelerated : Unaccelerated;
auto sourceGraphic = SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, ColorSpaceLinearRGB, renderingMode);
if (!sourceGraphic) {
ASSERT(!m_filter.contains(&renderer));
filterData->savedContext = context;
m_filter.set(&renderer, WTF::move(filterData));
return false;
}
// Set the rendering mode from the page's settings.
//.........这里部分代码省略.........
示例4: PROFILING
void RendererOpenGL::RenderPrimitives( const RenderElement& _Primitives )
#endif
{
PROFILING( "Render Primitives" );
#ifdef MULTIPLE_RENDER_ELEMENTS
RenderElementPrimitives::Type eType = _spPrimitives->GetType();
const CFoundation::Color& color = _spPrimitives->GetColor();
Float16 f16Thickness = _spPrimitives->GetThickness();
const RenderElementPrimitives::PointVec& avPoints = _spPrimitives->GetPoints();
#else
RenderElement::Type eType = _Primitives.GetType();
const CFoundation::Color& color = _Primitives.GetColor();
Float16 f16Thickness = _Primitives.GetThickness();
const RenderElement::PointVec& avPoints = _Primitives.GetPoints();
#endif
// Get opengl type
Unsigned32 u32Type = 0;
switch ( eType )
{
#ifdef MULTIPLE_RENDER_ELEMENTS
case RenderElementPrimitives::TYPE_POINTS:
#else
case RenderElement::TYPE_POINTS:
#endif
{
u32Type = GL_POINTS;
}
break;
#ifdef MULTIPLE_RENDER_ELEMENTS
case RenderElementPrimitives::TYPE_LINES:
#else
case RenderElement::TYPE_LINES:
#endif
{
u32Type = GL_LINES;
}
break;
#ifdef MULTIPLE_RENDER_ELEMENTS
case RenderElementPrimitives::TYPE_TRIANGLES:
#else
case RenderElement::TYPE_TRIANGLES:
#endif
{
u32Type = GL_TRIANGLES;
}
break;
#ifdef MULTIPLE_RENDER_ELEMENTS
case RenderElementPrimitives::TYPE_QUADS:
#else
case RenderElement::TYPE_QUADS:
#endif
{
u32Type = GL_QUADS;
}
break;
}
// Set color
Float16 f16R, f16G, f16B, f16A;
color.ToRGBA( f16R, f16G, f16B, f16A );
glColor4f( f16R, f16G, f16B, f16A );
// Set line thickness
glLineWidth( f16Thickness );
// Render primitives
glLoadIdentity();
glDisable( GL_TEXTURE_2D );
glBegin( u32Type );
Unsigned32 u32NumPoints = avPoints.size();
for ( Unsigned32 u32Idx = 0; u32Idx < u32NumPoints; ++u32Idx )
{
const CFoundation::Vector2Df& vPoint = avPoints[ u32Idx ];
glVertex3d( vPoint.GetX(), vPoint.GetY(), 0 );
}
glEnd();
}
示例5: includeLeadingForBox
//.........这里部分代码省略.........
affectsAscent = true;
affectsDescent = true;
}
}
LayoutUnit RootInlineBox::verticalPositionForBox(InlineBox* box, VerticalPositionCache& verticalPositionCache)
{
if (box->renderer().isTextOrLineBreak())
return box->parent()->logicalTop();
RenderBoxModelObject* renderer = box->boxModelObject();
ASSERT(renderer->isInline());
if (!renderer->isInline())
return 0;
// This method determines the vertical position for inline elements.
bool firstLine = isFirstLine();
if (firstLine && !renderer->document().styleSheetCollection().usesFirstLineRules())
firstLine = false;
// Check the cache.
bool isRenderInline = renderer->isRenderInline();
if (isRenderInline && !firstLine) {
LayoutUnit verticalPosition = verticalPositionCache.get(renderer, baselineType());
if (verticalPosition != PositionUndefined)
return verticalPosition;
}
LayoutUnit verticalPosition = 0;
EVerticalAlign verticalAlign = renderer->style().verticalAlign();
if (verticalAlign == TOP || verticalAlign == BOTTOM)
return 0;
RenderElement* parent = renderer->parent();
if (parent->isRenderInline() && parent->style().verticalAlign() != TOP && parent->style().verticalAlign() != BOTTOM)
verticalPosition = box->parent()->logicalTop();
if (verticalAlign != BASELINE) {
const RenderStyle& parentLineStyle = firstLine ? parent->firstLineStyle() : parent->style();
const Font& font = parentLineStyle.font();
const FontMetrics& fontMetrics = font.fontMetrics();
int fontSize = font.pixelSize();
LineDirectionMode lineDirection = parent->isHorizontalWritingMode() ? HorizontalLine : VerticalLine;
if (verticalAlign == SUB)
verticalPosition += fontSize / 5 + 1;
else if (verticalAlign == SUPER)
verticalPosition -= fontSize / 3 + 1;
else if (verticalAlign == TEXT_TOP)
verticalPosition += renderer->baselinePosition(baselineType(), firstLine, lineDirection) - fontMetrics.ascent(baselineType());
else if (verticalAlign == MIDDLE)
verticalPosition = (verticalPosition - LayoutUnit(fontMetrics.xHeight() / 2) - renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType(), firstLine, lineDirection)).round();
else if (verticalAlign == TEXT_BOTTOM) {
verticalPosition += fontMetrics.descent(baselineType());
// lineHeight - baselinePosition is always 0 for replaced elements (except inline blocks), so don't bother wasting time in that case.
if (!renderer->isReplaced() || renderer->isInlineBlockOrInlineTable())
verticalPosition -= (renderer->lineHeight(firstLine, lineDirection) - renderer->baselinePosition(baselineType(), firstLine, lineDirection));
} else if (verticalAlign == BASELINE_MIDDLE)
verticalPosition += -renderer->lineHeight(firstLine, lineDirection) / 2 + renderer->baselinePosition(baselineType(), firstLine, lineDirection);
else if (verticalAlign == LENGTH) {
LayoutUnit lineHeight;
//Per http://www.w3.org/TR/CSS21/visudet.html#propdef-vertical-align: 'Percentages: refer to the 'line-height' of the element itself'.
if (renderer->style().verticalAlignLength().isPercent())
lineHeight = renderer->style().computedLineHeight();
else
示例6: styleChanged
void SVGRenderSupport::styleChanged(RenderElement& renderer)
{
auto parent = renderer.parent();
SVGRenderSupport::setRendererHasSVGShadow(renderer, (parent && SVGRenderSupport::rendererHasSVGShadow(*parent)) || renderer.style().svgStyle().shadow());
}
示例7: RenderTexturedRect
void RendererOpenGL::RenderTexturedRect( const RenderElement& _TexturedRect )
#endif
{
PROFILING( "Render Texture" );
// Get settings
#ifdef MULTIPLE_RENDER_ELEMENTS
const CFoundation::Vector2Di& vPosition = _spTexturedRect->GetPosition();
const Texture& mask = _spTexturedRect->GetMask();
const Texture& texture = _spTexturedRect->GetTexture();
const CFoundation::RectF16& rectTexture = _spTexturedRect->GetRelativeTextureRect();
const CFoundation::Vector2Du& vSize = _spTexturedRect->GetSize();
bool bBgVisible = _spTexturedRect->IsBgVisible();
const CFoundation::Color& bgColor = _spTexturedRect->GetBgColor();
Float16 f16Angle = _spTexturedRect->GetAngle();
#else
const CFoundation::Vector2Di& vPosition = _TexturedRect.GetPosition();
const Texture& mask = _TexturedRect.GetMask();
const Texture& texture = _TexturedRect.GetTexture();
const CFoundation::RectF16& rectTexture = _TexturedRect.GetRelativeTextureRect();
const CFoundation::Vector2Du& vSize = _TexturedRect.GetSize();
bool bBgVisible = _TexturedRect.IsBgVisible();
const CFoundation::Color& bgColor = _TexturedRect.GetBgColor();
Float16 f16Angle = _TexturedRect.GetAngle();
#endif
// Compute size
Float16 f16HalfWidth = vSize.GetX() * 0.5f;
Float16 f16HalfHeight = vSize.GetY() * 0.5f;
Unsigned32 u32Width = vSize.GetX();
Unsigned32 u32Height = vSize.GetY();
// Render mask
if ( mask.IsValid() )
{
// Enable stencil buffer
glClear( GL_STENCIL_BUFFER_BIT );
glEnable( GL_STENCIL_TEST );
glStencilOp( GL_KEEP, GL_KEEP, GL_REPLACE );
glStencilFunc( GL_ALWAYS, 1, 1 );
// Enable mask
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, mask.GetID() );
// Draw only non-transparent pixels into the stencil buffer
glEnable( GL_ALPHA_TEST );
glAlphaFunc( GL_GREATER, 0.01f );
// Draw nothing on the screen
glColorMask( 0, 0, 0, 0 );
// Move to right position
glLoadIdentity();
glTranslated( vPosition.GetX(), vPosition.GetY(), 0 );
// Draw mask into stencil buffer
glBegin( GL_QUADS );
glTexCoord2f( rectTexture.GetLeft(), rectTexture.GetBottom() ); glVertex3d( 0, 0, 0 );
glTexCoord2f( rectTexture.GetRight(), rectTexture.GetBottom() ); glVertex3d( u32Width, 0, 0 );
glTexCoord2f( rectTexture.GetRight(), rectTexture.GetTop() ); glVertex3d( u32Width, u32Height, 0 );
glTexCoord2f( rectTexture.GetLeft(), rectTexture.GetTop() ); glVertex3d( 0, u32Height, 0 );
glEnd();
// Draw again on the screen
glColorMask( 1, 1, 1, 1 );
// Setup stencil test for background/texture
glStencilFunc( GL_EQUAL, 1, 1 );
glStencilOp( GL_KEEP, GL_KEEP, GL_KEEP );
}
// Render background
if ( bBgVisible )
{
glLoadIdentity();
glDisable( GL_TEXTURE_2D );
Drawer::GetInstance().DrawSolidRect( CFoundation::RectI32( vPosition, vSize ), bgColor, f16Angle );
}
// Render texture
glLoadIdentity();
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texture.GetID() );
// Set color
Float16 f16R, f16G, f16B, f16A;
bgColor.ToRGBA( f16R, f16G, f16B, f16A );
glColor4f( f16R, f16G, f16B, f16A );
// Translation
//glTranslated( vPosition.GetX(), vPosition.GetY(), 0.0f );
glTranslatef( vPosition.GetX() + f16HalfWidth, vPosition.GetY() + f16HalfHeight, 0.0f );
// Rotate
glRotatef( f16Angle, 0.0f, 0.0f, 1.0f );
// Render texture
//.........这里部分代码省略.........
示例8: layoutSizeOfNearestViewportChanged
void SVGRenderSupport::layoutChildren(RenderElement& start, bool selfNeedsLayout)
{
bool layoutSizeChanged = layoutSizeOfNearestViewportChanged(start);
bool transformChanged = transformToRootChanged(&start);
bool hasSVGShadow = rendererHasSVGShadow(start);
bool needsBoundariesUpdate = start.needsBoundariesUpdate();
HashSet<RenderObject*> notlayoutedObjects;
for (RenderObject* child = start.firstChild(); child; child = child->nextSibling()) {
bool needsLayout = selfNeedsLayout;
bool childEverHadLayout = child->everHadLayout();
if (needsBoundariesUpdate && hasSVGShadow) {
// If we have a shadow, our shadow is baked into our children's cached boundaries,
// so they need to update.
child->setNeedsBoundariesUpdate();
needsLayout = true;
}
if (transformChanged) {
// If the transform changed we need to update the text metrics (note: this also happens for layoutSizeChanged=true).
if (child->isSVGText())
toRenderSVGText(child)->setNeedsTextMetricsUpdate();
needsLayout = true;
}
if (layoutSizeChanged) {
// When selfNeedsLayout is false and the layout size changed, we have to check whether this child uses relative lengths
if (SVGElement* element = child->node()->isSVGElement() ? toSVGElement(child->node()) : 0) {
if (element->hasRelativeLengths()) {
// When the layout size changed and when using relative values tell the RenderSVGShape to update its shape object
if (child->isSVGShape())
toRenderSVGShape(child)->setNeedsShapeUpdate();
else if (child->isSVGText()) {
toRenderSVGText(child)->setNeedsTextMetricsUpdate();
toRenderSVGText(child)->setNeedsPositioningValuesUpdate();
}
needsLayout = true;
}
}
}
if (needsLayout)
child->setNeedsLayout(MarkOnlyThis);
if (child->needsLayout()) {
toRenderElement(child)->layout();
// Renderers are responsible for repainting themselves when changing, except
// for the initial paint to avoid potential double-painting caused by non-sensical "old" bounds.
// We could handle this in the individual objects, but for now it's easier to have
// parent containers call repaint(). (RenderBlock::layout* has similar logic.)
if (!childEverHadLayout)
child->repaint();
} else if (layoutSizeChanged)
notlayoutedObjects.add(child);
ASSERT(!child->needsLayout());
}
if (!layoutSizeChanged) {
ASSERT(notlayoutedObjects.isEmpty());
return;
}
// If the layout size changed, invalidate all resources of all children that didn't go through the layout() code path.
HashSet<RenderObject*>::iterator end = notlayoutedObjects.end();
for (HashSet<RenderObject*>::iterator it = notlayoutedObjects.begin(); it != end; ++it)
invalidateResourcesOfChildren(*it);
}
示例9: isRunningAcceleratedAnimationOnRenderer
bool AnimationController::isRunningAcceleratedAnimationOnRenderer(RenderElement& renderer, CSSPropertyID property, AnimationBase::RunningState runningState) const
{
return renderer.isCSSAnimating() && m_data->isRunningAcceleratedAnimationOnRenderer(renderer, property, runningState);
}
示例10: clonePtr
std::unique_ptr<RenderStyle> AnimationController::getAnimatedStyleForRenderer(RenderElement& renderer)
{
if (!renderer.isCSSAnimating())
return RenderStyle::clonePtr(renderer.style());
return m_data->getAnimatedStyleForRenderer(renderer);
}
示例11: hasVisibleTextArea
static inline bool hasVisibleTextArea(RenderElement& textControl, TextControlInnerTextElement* innerText)
{
return textControl.style()->visibility() != HIDDEN && innerText && innerText->renderer() && innerText->renderBox()->height();
}
示例12: roundf
bool TextAutoSizingValue::adjustNodeSizes()
{
bool objectsRemoved = false;
// Remove stale nodes. Nodes may have had their renderers detached. We'll
// also need to remove the style from the documents m_textAutoSizedNodes
// collection. Return true indicates we need to do that removal.
Vector<RefPtr<Node> > nodesForRemoval;
HashSet<RefPtr<Node> >::iterator end = m_autoSizedNodes.end();
for (HashSet<RefPtr<Node> >::iterator i = m_autoSizedNodes.begin(); i != end; ++i) {
RefPtr<Node> autoSizingNode = *i;
RenderText* text = static_cast<RenderText*>(autoSizingNode->renderer());
if (!text || !text->style().textSizeAdjust().isAuto() || !text->candidateComputedTextSize()) {
// remove node.
nodesForRemoval.append(autoSizingNode);
objectsRemoved = true;
}
}
unsigned count = nodesForRemoval.size();
for (unsigned i = 0; i < count; i++)
m_autoSizedNodes.remove(nodesForRemoval[i]);
// If we only have one piece of text with the style on the page don't
// adjust it's size.
if (m_autoSizedNodes.size() <= 1)
return objectsRemoved;
// Compute average size
float cumulativeSize = 0;
end = m_autoSizedNodes.end();
for (HashSet<RefPtr<Node> >::iterator i = m_autoSizedNodes.begin(); i != end; ++i) {
RefPtr<Node> autoSizingNode = *i;
RenderText* renderText = static_cast<RenderText*>(autoSizingNode->renderer());
cumulativeSize += renderText->candidateComputedTextSize();
}
float averageSize = roundf(cumulativeSize / m_autoSizedNodes.size());
// Adjust sizes
bool firstPass = true;
end = m_autoSizedNodes.end();
for (HashSet<RefPtr<Node> >::iterator i = m_autoSizedNodes.begin(); i != end; ++i) {
const RefPtr<Node>& autoSizingNode = *i;
RenderText* text = static_cast<RenderText*>(autoSizingNode->renderer());
if (text && text->style().fontDescription().computedSize() != averageSize) {
float specifiedSize = text->style().fontDescription().specifiedSize();
float scaleChange = averageSize / specifiedSize;
if (scaleChange > MAX_SCALE_INCREASE && firstPass) {
firstPass = false;
averageSize = roundf(specifiedSize * MAX_SCALE_INCREASE);
scaleChange = averageSize / specifiedSize;
}
RefPtr<RenderStyle> style = cloneRenderStyleWithState(text->style());
FontDescription fontDescription = style->fontDescription();
fontDescription.setComputedSize(averageSize);
style->setFontDescription(fontDescription);
style->font().update(autoSizingNode->document().ensureStyleResolver().fontSelector());
text->parent()->setStyle(style.releaseNonNull());
RenderElement* parentRenderer = text->parent();
if (parentRenderer->isAnonymousBlock())
parentRenderer = parentRenderer->parent();
// If we have a list we should resize ListMarkers separately.
RenderObject* listMarkerRenderer = parentRenderer->firstChild();
if (listMarkerRenderer->isListMarker()) {
RefPtr<RenderStyle> style = cloneRenderStyleWithState(listMarkerRenderer->style());
style->setFontDescription(fontDescription);
style->font().update(autoSizingNode->document().ensureStyleResolver().fontSelector());
toRenderListMarker(*listMarkerRenderer).setStyle(style.releaseNonNull());
}
// Resize the line height of the parent.
const RenderStyle& parentStyle = parentRenderer->style();
Length lineHeightLength = parentStyle.specifiedLineHeight();
int specifiedLineHeight = 0;
if (lineHeightLength.isPercent())
specifiedLineHeight = minimumValueForLength(lineHeightLength, fontDescription.specifiedSize());
else
specifiedLineHeight = lineHeightLength.value();
int lineHeight = specifiedLineHeight * scaleChange;
if (!lineHeightLength.isFixed() || lineHeightLength.value() != lineHeight) {
RefPtr<RenderStyle> newParentStyle = cloneRenderStyleWithState(parentStyle);
newParentStyle->setLineHeight(Length(lineHeight, Fixed));
newParentStyle->setSpecifiedLineHeight(lineHeightLength);
newParentStyle->setFontDescription(fontDescription);
newParentStyle->font().update(autoSizingNode->document().ensureStyleResolver().fontSelector());
parentRenderer->setStyle(newParentStyle.releaseNonNull());
}
}
}
return objectsRemoved;
}