Change determineChange(const RenderStyle& s1, const RenderStyle& s2) { if (s1.display() != s2.display()) return Detach; if (s1.hasPseudoStyle(FIRST_LETTER) != s2.hasPseudoStyle(FIRST_LETTER)) return Detach; // We just detach if a renderer acquires or loses a column-span, since spanning elements // typically won't contain much content. if (s1.columnSpan() != s2.columnSpan()) return Detach; if (!s1.contentDataEquivalent(&s2)) return Detach; // When text-combine property has been changed, we need to prepare a separate renderer object. // When text-combine is on, we use RenderCombineText, otherwise RenderText. // https://bugs.webkit.org/show_bug.cgi?id=55069 if (s1.hasTextCombine() != s2.hasTextCombine()) return Detach; // We need to reattach the node, so that it is moved to the correct RenderFlowThread. if (s1.flowThread() != s2.flowThread()) return Detach; // When the region thread has changed, we need to prepare a separate render region object. if (s1.regionThread() != s2.regionThread()) return Detach; // FIXME: Multicolumn regions not yet supported (http://dev.w3.org/csswg/css-regions/#multi-column-regions) // When the node has region style and changed its multicol style, we have to prepare // a separate render region object. if (s1.hasFlowFrom() && (s1.specifiesColumns() != s2.specifiesColumns())) return Detach; if (s1 != s2) { if (s1.inheritedNotEqual(&s2)) return Inherit; return NoInherit; } // If the pseudoStyles have changed, we want any StyleChange that is not NoChange // because setStyle will do the right thing with anything else. if (s1.hasAnyPublicPseudoStyles()) { for (PseudoId pseudoId = FIRST_PUBLIC_PSEUDOID; pseudoId < FIRST_INTERNAL_PSEUDOID; pseudoId = static_cast<PseudoId>(pseudoId + 1)) { if (s1.hasPseudoStyle(pseudoId)) { RenderStyle* ps2 = s2.getCachedPseudoStyle(pseudoId); if (!ps2) return NoInherit; RenderStyle* ps1 = s1.getCachedPseudoStyle(pseudoId); if (!ps1 || *ps1 != *ps2) return NoInherit; } } } return NoChange; }
bool HTMLFormElement::rendererIsNeeded(const RenderStyle& style) { if (!m_wasDemoted) return HTMLElement::rendererIsNeeded(style); auto parent = parentNode(); auto parentRenderer = parent->renderer(); if (!parentRenderer) return false; // FIXME: Shouldn't we also check for table caption (see |formIsTablePart| below). bool parentIsTableElementPart = (parentRenderer->isTable() && isHTMLTableElement(parent)) || (parentRenderer->isTableRow() && parent->hasTagName(trTag)) || (parentRenderer->isTableSection() && parent->hasTagName(tbodyTag)) || (parentRenderer->isRenderTableCol() && parent->hasTagName(colTag)) || (parentRenderer->isTableCell() && parent->hasTagName(trTag)); if (!parentIsTableElementPart) return true; EDisplay display = style.display(); bool formIsTablePart = display == TABLE || display == INLINE_TABLE || display == TABLE_ROW_GROUP || display == TABLE_HEADER_GROUP || display == TABLE_FOOTER_GROUP || display == TABLE_ROW || display == TABLE_COLUMN_GROUP || display == TABLE_COLUMN || display == TABLE_CELL || display == TABLE_CAPTION; return formIsTablePart; }
SVGResource* SVGClipPathElement::canvasResource() { if (!m_clipper) m_clipper = SVGResourceClipper::create(); else m_clipper->resetClipData(); bool bbox = clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; RenderStyle* clipPathStyle = styleForRenderer(parent()->renderer()); // FIXME: Manual style resolution is a hack for (Node* n = firstChild(); n; n = n->nextSibling()) { if (n->isSVGElement() && static_cast<SVGElement*>(n)->isStyledTransformable()) { SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(n); RenderStyle* pathStyle = document()->styleSelector()->styleForElement(styled, clipPathStyle); if (pathStyle->display() != NONE) { Path pathData = styled->toClipPath(); // FIXME: How do we know the element has done a layout? pathData.transform(styled->animatedLocalTransform()); if (!pathData.isEmpty()) m_clipper->addClipData(pathData, pathStyle->svgStyle()->clipRule(), bbox); } pathStyle->deref(document()->renderArena()); } } if (m_clipper->clipData().isEmpty()) { Path pathData; pathData.addRect(FloatRect()); m_clipper->addClipData(pathData, RULE_EVENODD, bbox); } clipPathStyle->deref(document()->renderArena()); return m_clipper.get(); }
bool HTMLFormElement::rendererIsNeeded(const RenderStyle& style) { if (!m_wasDemoted) return HTMLElement::rendererIsNeeded(style); ContainerNode* node = parentNode(); RenderObject* parentRenderer = node->renderer(); // FIXME: Shouldn't we also check for table caption (see |formIsTablePart| below). // FIXME: This check is not correct for Shadow DOM. bool parentIsTableElementPart = (parentRenderer->isTable() && isHTMLTableElement(node)) || (parentRenderer->isTableRow() && node->hasTagName(trTag)) || (parentRenderer->isTableSection() && node->hasTagName(tbodyTag)) || (parentRenderer->isRenderTableCol() && node->hasTagName(colTag)) || (parentRenderer->isTableCell() && node->hasTagName(trTag)); if (!parentIsTableElementPart) return true; EDisplay display = style.display(); bool formIsTablePart = display == TABLE || display == INLINE_TABLE || display == TABLE_ROW_GROUP || display == TABLE_HEADER_GROUP || display == TABLE_FOOTER_GROUP || display == TABLE_ROW || display == TABLE_COLUMN_GROUP || display == TABLE_COLUMN || display == TABLE_CELL || display == TABLE_CAPTION; return formIsTablePart; }
void HTMLIFrameElementImpl::attach() { assert(!attached()); assert(!m_render); assert(parentNode()); updateFrame(); name = getAttribute(ATTR_NAME); if(name.isNull()) name = getAttribute(ATTR_ID); RenderStyle *style = getDocument()->styleSelector()->styleForElement(this); style->ref(); if(getDocument()->isURLAllowed(url.string()) && parentNode()->renderer() && style->display() != NONE) { m_render = new(getDocument()->renderArena()) RenderPartObject(this); m_render->setStyle(style); parentNode()->renderer()->addChild(m_render, nextRenderer()); } style->deref(); NodeBaseImpl::attach(); if(m_render) { // we need a unique name for every frame in the frameset. Hope that's unique enough. KHTMLView *w = getDocument()->view(); if(w && (name.isEmpty() || w->part()->frameExists(name.string()))) name = DOMString(w->part()->requestFrameName()); needWidgetUpdate = false; static_cast< RenderPartObject * >(m_render)->updateWidget(); } }
FloatRect RenderSVGResourceClipper::resourceBoundingBox(const FloatRect& objectBoundingBox) const { FloatRect clipRect; for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) { if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyledTransformable()) continue; SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(childNode); RenderStyle* style = styled->renderer() ? styled->renderer()->style() : 0; if (!style || style->display() == NONE) continue; clipRect.unite(styled->renderer()->objectBoundingBox()); } if (clipRect.isEmpty()) return FloatRect(); if (static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { AffineTransform obbTransform; obbTransform.translate(objectBoundingBox.x(), objectBoundingBox.y()); obbTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); return obbTransform.mapRect(clipRect); } return clipRect; }
void RenderSVGResourceClipper::createDisplayList(GraphicsContext* context, const AffineTransform& contentTransformation) { ASSERT(context); ASSERT(frame()); // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinates) to avoid the intersection // with local clips/mask, which may yield incorrect results when mixing objectBoundingBox and // userSpaceOnUse units (http://crbug.com/294900). FloatRect bounds = strokeBoundingBox(); context->beginRecording(bounds); // Switch to a paint behavior where all children of this <clipPath> will be rendered using special constraints: // - fill-opacity/stroke-opacity/opacity set to 1 // - masker/filter not applied when rendering the children // - fill is set to the initial fill paint server (solid, black) // - stroke is set to the initial stroke paint server (none) PaintBehavior oldBehavior = frame()->view()->paintBehavior(); frame()->view()->setPaintBehavior(oldBehavior | PaintBehaviorRenderingSVGMask); for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) { RenderObject* renderer = childElement->renderer(); if (!renderer) continue; RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; WindRule newClipRule = style->svgStyle().clipRule(); bool isUseElement = isSVGUseElement(*childElement); if (isUseElement) { SVGUseElement& useElement = toSVGUseElement(*childElement); renderer = useElement.rendererClipChild(); if (!renderer) continue; if (!useElement.hasAttribute(SVGNames::clip_ruleAttr)) newClipRule = renderer->style()->svgStyle().clipRule(); } // Only shapes, paths and texts are allowed for clipping. if (!renderer->isSVGShape() && !renderer->isSVGText()) continue; context->setFillRule(newClipRule); if (isUseElement) renderer = childElement->renderer(); SVGRenderingContext::renderSubtree(context, renderer, contentTransformation); } frame()->view()->setPaintBehavior(oldBehavior); m_clipContentDisplayList = context->endRecording(); }
void HTMLBodyElementImpl::attach() { assert(!m_render); assert(parentNode()); RenderStyle* style = getDocument()->styleSelector()->styleForElement(this); style->ref(); if (parentNode()->renderer() && style->display() != NONE) { if (style->display() == BLOCK) // only use the quirky class for block display m_render = new (getDocument()->renderArena()) RenderBody(this); else m_render = RenderObject::createObject(this, style); m_render->setStyle(style); parentNode()->renderer()->addChild(m_render, nextRenderer()); } style->deref(); NodeBaseImpl::attach(); }
bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const AffineTransform& animatedLocalTransform, const FloatRect& objectBoundingBox) { // If the current clip-path gets clipped itself, we have to fallback to masking. if (!style()->svgStyle()->clipperResource().isEmpty()) return false; WindRule clipRule = RULE_NONZERO; Path clipPath = Path(); // If clip-path only contains one visible shape or path, we can use path-based clipping. Invisible // shapes don't affect the clipping and can be ignored. If clip-path contains more than one // visible shape, the additive clipping may not work, caused by the clipRule. EvenOdd // as well as NonZero can cause self-clipping of the elements. // See also http://www.w3.org/TR/SVG/painting.html#FillRuleProperty for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) { RenderObject* renderer = childNode->renderer(); if (!renderer) continue; // Only shapes or paths are supported for direct clipping. We need to fallback to masking for texts. if (renderer->isSVGText()) return false; if (!childNode->isSVGElement() || !toSVGElement(childNode)->isStyledTransformable()) continue; SVGStyledTransformableElement* styled = toSVGStyledTransformableElement(childNode); RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; const SVGRenderStyle* svgStyle = style->svgStyle(); // Current shape in clip-path gets clipped too. Fallback to masking. if (!svgStyle->clipperResource().isEmpty()) return false; // Fallback to masking, if there is more than one clipping path. if (clipPath.isEmpty()) { styled->toClipPath(clipPath); clipRule = svgStyle->clipRule(); } else return false; } // Only one visible shape/path was found. Directly continue clipping and transform the content to userspace if necessary. if (static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { AffineTransform transform; transform.translate(objectBoundingBox.x(), objectBoundingBox.y()); transform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); clipPath.transform(transform); } // Transform path by animatedLocalTransform. clipPath.transform(animatedLocalTransform); // The SVG specification wants us to clip everything, if clip-path doesn't have a child. if (clipPath.isEmpty()) clipPath.addRect(FloatRect()); context->clipPath(clipPath, clipRule); return true; }
bool HTMLOptionElement::isDisplayNone() const { ContainerNode* parent = parentNode(); // Check for parent optgroup having display NONE if (parent && isHTMLOptGroupElement(*parent)) { if (toHTMLOptGroupElement(*parent).isDisplayNone()) return true; } RenderStyle* style = nonRendererStyle(); return style && style->display() == NONE; }
~CheckForVisibilityChangeOnRecalcStyle() { if (!WKObservingContentChanges()) return; RenderStyle* style = m_element->renderStyle(); if (!style) return; if ((m_previousDisplay == NONE && style->display() != NONE) || (m_previousVisibility == HIDDEN && style->visibility() != HIDDEN) || (m_previousImplicitVisibility == HIDDEN && elementImplicitVisibility(m_element.get()) == VISIBLE)) WKSetObservedContentChange(WKContentVisibilityChange); }
void RenderSVGResourceMasker::calculateMaskContentRepaintRect() { for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) { RenderObject* renderer = childNode->renderer(); if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer) continue; RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; m_maskBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates())); } }
void RenderSVGResourceMasker::calculateMaskContentPaintInvalidationRect() { for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) { RenderObject* renderer = childElement->renderer(); if (!renderer) continue; RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; m_maskContentBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->paintInvalidationRectInLocalCoordinates())); } }
PassRefPtr<DisplayList> RenderSVGResourceClipper::asDisplayList(GraphicsContext* context, const AffineTransform& contentTransformation) { ASSERT(context); ASSERT(frame()); context->beginRecording(repaintRectInLocalCoordinates()); // Switch to a paint behavior where all children of this <clipPath> will be rendered using special constraints: // - fill-opacity/stroke-opacity/opacity set to 1 // - masker/filter not applied when rendering the children // - fill is set to the initial fill paint server (solid, black) // - stroke is set to the initial stroke paint server (none) PaintBehavior oldBehavior = frame()->view()->paintBehavior(); frame()->view()->setPaintBehavior(oldBehavior | PaintBehaviorRenderingSVGMask); for (Node* childNode = element()->firstChild(); childNode; childNode = childNode->nextSibling()) { RenderObject* renderer = childNode->renderer(); if (!childNode->isSVGElement() || !renderer) continue; RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; WindRule newClipRule = style->svgStyle()->clipRule(); bool isUseElement = childNode->hasTagName(SVGNames::useTag); if (isUseElement) { SVGUseElement* useElement = toSVGUseElement(childNode); renderer = useElement->rendererClipChild(); if (!renderer) continue; if (!useElement->hasAttribute(SVGNames::clip_ruleAttr)) newClipRule = renderer->style()->svgStyle()->clipRule(); } // Only shapes, paths and texts are allowed for clipping. if (!renderer->isSVGShape() && !renderer->isSVGText()) continue; context->setFillRule(newClipRule); if (isUseElement) renderer = childNode->renderer(); SVGRenderingContext::renderSubtree(context, renderer, contentTransformation); } frame()->view()->setPaintBehavior(oldBehavior); return context->endRecording(); }
void RenderSVGResourceMasker::drawContentIntoMaskImage(MaskerData* maskerData, const SVGMaskElement* maskElement, RenderObject* object) { GraphicsContext* maskImageContext = maskerData->maskImage->context(); ASSERT(maskImageContext); // Eventually adjust the mask image context according to the target objectBoundingBox. AffineTransform maskContentTransformation; if (maskElement->maskContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { FloatRect objectBoundingBox = object->objectBoundingBox(); maskContentTransformation.translate(objectBoundingBox.x(), objectBoundingBox.y()); maskContentTransformation.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); maskImageContext->concatCTM(maskContentTransformation); } // Draw the content into the ImageBuffer. for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) { RenderObject* renderer = node->renderer(); if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !renderer) continue; RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; SVGImageBufferTools::renderSubtreeToImageBuffer(maskerData->maskImage.get(), renderer, maskContentTransformation); } maskImageContext->restore(); #if !PLATFORM(CG) maskerData->maskImage->transformColorSpace(ColorSpaceDeviceRGB, ColorSpaceLinearRGB); #endif // Create the luminance mask. IntRect maskImageRect(IntPoint(), maskerData->maskImage->size()); RefPtr<ImageData> imageData = maskerData->maskImage->getUnmultipliedImageData(maskImageRect); ByteArray* srcPixelArray = imageData->data()->data(); unsigned pixelArrayLength = srcPixelArray->length(); for (unsigned pixelOffset = 0; pixelOffset < pixelArrayLength; pixelOffset += 4) { unsigned char a = srcPixelArray->get(pixelOffset + 3); if (!a) continue; unsigned char r = srcPixelArray->get(pixelOffset); unsigned char g = srcPixelArray->get(pixelOffset + 1); unsigned char b = srcPixelArray->get(pixelOffset + 2); double luma = (r * 0.2125 + g * 0.7154 + b * 0.0721) * ((double)a / 255.0); srcPixelArray->set(pixelOffset + 3, luma); } maskerData->maskImage->putUnmultipliedImageData(imageData.get(), maskImageRect, IntPoint()); }
bool RenderSVGResourceClipper::applyResource(RenderObject* object, GraphicsContext* context) { ASSERT(object); ASSERT(context); m_clipper.add(object); context->beginPath(); AffineTransform obbTransform; FloatRect objectBoundingBox = object->objectBoundingBox(); bool bbox = static_cast<SVGClipPathElement*>(node())->clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX; if (bbox) { obbTransform.translate(objectBoundingBox.x(), objectBoundingBox.y()); obbTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height()); } bool hasClipPath = false; WindRule clipRule = RULE_EVENODD; for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) { if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyledTransformable()) continue; SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(childNode); RenderStyle* style = styled->renderer() ? styled->renderer()->style() : 0; if (!style || style->display() == NONE) continue; Path pathData = styled->toClipPath(); if (pathData.isEmpty()) continue; if (bbox) pathData.transform(obbTransform); hasClipPath = true; context->addPath(pathData); clipRule = style->svgStyle()->clipRule(); } if (!hasClipPath) { Path clipPath; clipPath.addRect(FloatRect()); context->addPath(clipPath); } // FIXME! // We don't currently allow for heterogenous clip rules. // we would have to detect such, draw to a mask, and then clip // to that mask context->clipPath(clipRule); return true; }
static bool affectsRenderedSubtree(Element& element, const RenderStyle& newStyle) { if (element.renderer()) return true; if (newStyle.display() != NONE) return true; if (element.rendererIsNeeded(newStyle)) return true; #if ENABLE(CSS_REGIONS) if (element.shouldMoveToFlowThread(newStyle)) return true; #endif return false; }
bool Text::textRendererIsNeeded(const RenderStyle& style, const RenderObject& parent) { if (!parent.canHaveChildren()) return false; if (isEditingText()) return true; if (!length()) return false; if (style.display() == NONE) return false; if (!containsOnlyWhitespace()) return true; if (!canHaveWhitespaceChildren(parent)) return false; if (style.preserveNewline()) // pre/pre-wrap/pre-line always make renderers. return true; const RenderObject* prev = NodeRenderingTraversal::previousSiblingRenderer(*this); if (prev && prev->isBR()) // <span><br/> <br/></span> return false; if (parent.isRenderInline()) { // <span><div/> <div/></span> if (prev && !prev->isInline()) return false; } else { if (parent.isRenderBlock() && !parent.childrenInline() && (!prev || !prev->isInline())) return false; // Avoiding creation of a Renderer for the text node is a non-essential memory optimization. // So to avoid blowing up on very wide DOMs, we limit the number of siblings to visit. unsigned maxSiblingsToVisit = 50; RenderObject* first = parent.slowFirstChild(); while (first && first->isFloatingOrOutOfFlowPositioned() && maxSiblingsToVisit--) first = first->nextSibling(); if (!first || first == renderer() || NodeRenderingTraversal::nextSiblingRenderer(*this) == first) // Whitespace at the start of a block just goes away. Don't even // make a render object for this text. return false; } return true; }
void RenderSVGResourceClipper::calculateClipContentRepaintRect() { // This is a rough heuristic to appraise the clip size and doesn't consider clip on clip. for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) { RenderObject* renderer = childNode->renderer(); if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer) continue; if (!renderer->isSVGPath() && !renderer->isSVGText() && !renderer->isSVGShadowTreeRootContainer()) continue; RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; m_clipBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates())); } }
void RenderSVGResourceClipper::calculateClipContentRepaintRect() { // This is a rough heuristic to appraise the clip size and doesn't consider clip on clip. for (Node* childNode = clipPathElement().firstChild(); childNode; childNode = childNode->nextSibling()) { RenderObject* renderer = childNode->renderer(); if (!childNode->isSVGElement() || !renderer) continue; if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag)) continue; RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; m_clipBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->repaintRectInLocalCoordinates())); } m_clipBoundaries = clipPathElement().animatedLocalTransform().mapRect(m_clipBoundaries); }
void RenderSVGResourceClipper::calculateClipContentPaintInvalidationRect() { // This is a rough heuristic to appraise the clip size and doesn't consider clip on clip. for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) { RenderObject* renderer = childElement->renderer(); if (!renderer) continue; if (!renderer->isSVGShape() && !renderer->isSVGText() && !isSVGUseElement(*childElement)) continue; RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; m_clipBoundaries.unite(renderer->localToParentTransform().mapRect(renderer->paintInvalidationRectInLocalCoordinates())); } m_clipBoundaries = toSVGClipPathElement(element())->animatedLocalTransform().mapRect(m_clipBoundaries); }
RenderObject *RenderObject::createObject(DOM::NodeImpl *node) { RenderStyle *style = node->style(); RenderObject *o = 0; switch(style->display()) { case INLINE: case BLOCK: o = new RenderFlow(); break; case LIST_ITEM: o = new RenderListItem(); break; case RUN_IN: case COMPACT: case MARKER: break; case TABLE: case INLINE_TABLE: // ### set inline/block right //kdDebug( 6040 ) << "creating RenderTable" << endl; o = new RenderTable(); break; case TABLE_ROW_GROUP: case TABLE_HEADER_GROUP: case TABLE_FOOTER_GROUP: o = new RenderTableSection(); break; case TABLE_ROW: o = new RenderTableRow(); break; case TABLE_COLUMN_GROUP: case TABLE_COLUMN: o = new RenderTableCol(); break; case TABLE_CELL: o = new RenderTableCell(); break; case TABLE_CAPTION: o = new RenderTableCaption(); break; case NONE: return 0; } if(o) o->setStyle(style); return o; }
void HTMLBodyElementImpl::attach() { assert(!m_render); assert(parentNode()); assert(parentNode()->renderer()); RenderStyle* style = getDocument()->styleSelector()->styleForElement(this); style->ref(); if (style->display() != NONE) { m_render = new RenderBody(this); m_render->setStyle(style); parentNode()->renderer()->addChild(m_render, nextRenderer()); } style->deref(); NodeBaseImpl::attach(); }
bool HTMLOptionElement::isDisplayNone() const { // If m_style is not set, then the node is still unattached. // We have to wait till it gets attached to read the display property. if (!m_style) return false; if (m_style->display() != NONE) { Element* parent = parentElement(); ASSERT(parent); if (isHTMLOptGroupElement(*parent)) { RenderStyle* parentStyle = parent->renderStyle() ? parent->renderStyle() : parent->computedStyle(); return !parentStyle || parentStyle->display() == NONE; } } return m_style->display() == NONE; }
void HTMLBRElementImpl::attach() { assert(!attached()); assert(!m_render); assert(parentNode()); if (parentNode()->renderer()) { RenderStyle* style = getDocument()->styleSelector()->styleForElement( this ); style->ref(); if( style->display() != NONE ) { m_render = new (getDocument()->renderArena()) RenderBR(this); m_render->setStyle(style); parentNode()->renderer()->addChild(m_render, nextRenderer()); } style->deref(); } NodeImpl::attach(); }
WebString WebAccessibilityObject::computedStyleDisplay() const { if (m_private.isNull()) return WebString(); Document* document = m_private->document(); if (document) document->updateStyleIfNeeded(); Node* node = m_private->node(); if (!node) return WebString(); RenderStyle* renderStyle = node->computedStyle(); if (!renderStyle) return WebString(); return WebString(CSSPrimitiveValue::create(renderStyle->display())->getStringValue()); }
void RenderDataGrid::paintColumnHeaders(PaintInfo& paintInfo, int tx, int ty) { DataGridColumnList* columns = gridElement()->columns(); unsigned length = columns->length(); for (unsigned i = 0; i < length; ++i) { DataGridColumn* column = columns->item(i); RenderStyle* columnStyle = headerStyle(column); // Don't render invisible columns. if (!columnStyle || columnStyle->display() == NONE || columnStyle->visibility() != VISIBLE) continue; // Paint the column header if it intersects the dirty rect. IntRect columnRect(column->rect()); columnRect.move(tx, ty); if (columnRect.intersects(paintInfo.rect)) paintColumnHeader(column, paintInfo, tx, ty); } }
PopupMenuStyle RenderMenuList::itemStyle(unsigned listIndex) const { const Vector<HTMLElement*>& listItems = toHTMLSelectElement(node())->listItems(); if (listIndex >= listItems.size()) { // If we are making an out of bounds access, then we want to use the style // of a different option element (index 0). However, if there isn't an option element // before at index 0, we fall back to the menu's style. if (!listIndex) return menuStyle(); // Try to retrieve the style of an option element we know exists (index 0). listIndex = 0; } HTMLElement* element = listItems[listIndex]; RenderStyle* style = element->renderStyle() ? element->renderStyle() : element->computedStyle(); return style ? PopupMenuStyle(style->visitedDependentColor(CSSPropertyColor), itemBackgroundColor(listIndex), style->font(), style->visibility() == VISIBLE, style->display() == NONE, style->textIndent(), style->direction(), isOverride(style->unicodeBidi())) : menuStyle(); }
void RenderSVGResourceMasker::createDisplayList(GraphicsContext* context, const AffineTransform& contentTransform) { ASSERT(context); // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinates) to avoid the intersection // with local clips/mask, which may yield incorrect results when mixing objectBoundingBox and // userSpaceOnUse units (http://crbug.com/294900). FloatRect bounds = strokeBoundingBox(); context->beginRecording(bounds); for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) { RenderObject* renderer = childElement->renderer(); if (!renderer) continue; RenderStyle* style = renderer->style(); if (!style || style->display() == NONE || style->visibility() != VISIBLE) continue; SVGRenderingContext::renderSubtree(context, renderer, contentTransform); } m_maskContentDisplayList = context->endRecording(); }
static bool textRendererIsNeeded(const Text& textNode, const RenderObject& parentRenderer, const RenderStyle& style) { if (textNode.isEditingText()) return true; if (!textNode.length()) return false; if (style.display() == NONE) return false; if (!textNode.containsOnlyWhitespace()) return true; // This text node has nothing but white space. We may still need a renderer in some cases. if (parentRenderer.isTable() || parentRenderer.isTableRow() || parentRenderer.isTableSection() || parentRenderer.isRenderTableCol() || parentRenderer.isFrameSet()) return false; if (style.preserveNewline()) // pre/pre-wrap/pre-line always make renderers. return true; RenderObject* previousRenderer = previousSiblingRenderer(textNode); if (previousRenderer && previousRenderer->isBR()) // <span><br/> <br/></span> return false; if (parentRenderer.isRenderInline()) { // <span><div/> <div/></span> if (previousRenderer && !previousRenderer->isInline()) return false; } else { if (parentRenderer.isRenderBlock() && !parentRenderer.childrenInline() && (!previousRenderer || !previousRenderer->isInline())) return false; RenderObject* first = parentRenderer.firstChild(); while (first && first->isFloatingOrOutOfFlowPositioned()) first = first->nextSibling(); RenderObject* nextRenderer = nextSiblingRenderer(textNode); if (!first || nextRenderer == first) { // Whitespace at the start of a block just goes away. Don't even make a render object for this text. return false; } } return true; }