RenderObject* RenderFieldset::layoutSpecialExcludedChild(bool relayoutChildren) { RenderBox* legend = findLegend(); if (legend) { if (relayoutChildren) legend->setNeedsLayout(true); legend->layoutIfNeeded(); LayoutUnit logicalLeft; if (style()->isLeftToRightDirection()) { switch (legend->style()->textAlign()) { case CENTER: logicalLeft = (logicalWidth() - logicalWidthForChild(legend)) / 2; break; case RIGHT: logicalLeft = logicalWidth() - borderEnd() - paddingEnd() - logicalWidthForChild(legend); break; default: logicalLeft = borderStart() + paddingStart() + marginStartForChild(legend); break; } } else { switch (legend->style()->textAlign()) { case LEFT: logicalLeft = borderStart() + paddingStart(); break; case CENTER: { // Make sure that the extra pixel goes to the end side in RTL (since it went to the end side // in LTR). LayoutUnit centeredWidth = logicalWidth() - logicalWidthForChild(legend); logicalLeft = centeredWidth - centeredWidth / 2; break; } default: logicalLeft = logicalWidth() - borderStart() - paddingStart() - marginStartForChild(legend) - logicalWidthForChild(legend); break; } } setLogicalLeftForChild(legend, logicalLeft); LayoutUnit b = borderBefore(); LayoutUnit h = logicalHeightForChild(legend); setLogicalTopForChild(legend, max<LayoutUnit>((b - h) / 2, 0)); setLogicalHeight(max(b, h) + paddingBefore()); } return legend; }
LayoutUnit RenderReplaced::computeReplacedLogicalHeight() const { // 10.5 Content height: the 'height' property: http://www.w3.org/TR/CSS21/visudet.html#propdef-height if (hasReplacedLogicalHeight()) return computeReplacedLogicalHeightRespectingMinMaxHeight(computeReplacedLogicalHeightUsing(style()->logicalHeight())); RenderBox* contentRenderer = embeddedContentBox(); // 10.6.2 Inline, replaced elements: http://www.w3.org/TR/CSS21/visudet.html#inline-replaced-height bool isPercentageIntrinsicSize = false; double intrinsicRatio = 0; FloatSize intrinsicSize; if (contentRenderer) contentRenderer->computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize); else computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize); if (intrinsicRatio && !isHorizontalWritingMode()) intrinsicRatio = 1 / intrinsicRatio; bool widthIsAuto = style()->logicalWidth().isAuto(); bool hasIntrinsicHeight = m_hasIntrinsicSize || (!isPercentageIntrinsicSize && intrinsicSize.height() > 0); // If 'height' and 'width' both have computed values of 'auto' and the element also has an intrinsic height, then that intrinsic height is the used value of 'height'. if (widthIsAuto && hasIntrinsicHeight) { if (m_hasIntrinsicSize) return computeReplacedLogicalHeightRespectingMinMaxHeight(calcAspectRatioLogicalHeight()); return static_cast<LayoutUnit>(intrinsicSize.height() * style()->effectiveZoom()); } // Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic ratio then the used value of 'height' is: // (used width) / (intrinsic ratio) if (intrinsicRatio && !isPercentageIntrinsicSize) { // FIXME: Remove unnecessary rounding when layout is off ints: webkit.org/b/63656 return computeReplacedLogicalHeightRespectingMinMaxHeight(round(availableLogicalWidth() / intrinsicRatio)); } // Otherwise, if 'height' has a computed value of 'auto', and the element has an intrinsic height, then that intrinsic height is the used value of 'height'. if (hasIntrinsicHeight) { if (m_hasIntrinsicSize) return computeReplacedLogicalHeightRespectingMinMaxHeight(calcAspectRatioLogicalHeight()); return static_cast<LayoutUnit>(intrinsicSize.height() * style()->effectiveZoom()); } // Otherwise, if 'height' has a computed value of 'auto', but none of the conditions above are met, then the used value of 'height' must be set to the height // of the largest rectangle that has a 2:1 ratio, has a height not greater than 150px, and has a width not greater than the device width. return computeReplacedLogicalHeightRespectingMinMaxHeight(cDefaultHeight); }
static inline LayoutUnit borderAndPaddingBeforeInWritingMode(const RenderBox& renderer, WritingMode writingMode) { switch (writingMode) { case TopToBottomWritingMode: return renderer.borderTop() + renderer.paddingTop(); case BottomToTopWritingMode: return renderer.borderBottom() + renderer.paddingBottom(); case LeftToRightWritingMode: return renderer.borderLeft() + renderer.paddingLeft(); case RightToLeftWritingMode: return renderer.borderRight() + renderer.paddingRight(); } ASSERT_NOT_REACHED(); return renderer.borderAndPaddingBefore(); }
void RenderMediaVolumeSliderContainer::layout() { RenderBlock::layout(); if (style()->display() == NONE || !nextSibling() || !nextSibling()->isBox()) return; RenderBox* buttonBox = toRenderBox(nextSibling()); int absoluteOffsetTop = buttonBox->localToAbsolute(FloatPoint(0, -size().height())).y(); LayoutStateDisabler layoutStateDisabler(view()); // If the slider would be rendered outside the page, it should be moved below the controls. if (UNLIKELY(absoluteOffsetTop < 0)) setY(buttonBox->offsetTop() + theme()->volumeSliderOffsetFromMuteButton(buttonBox, pixelSnappedSize()).y()); }
std::unique_ptr<FloatingObject> FloatingObject::create(RenderBox& renderer) { auto object = std::make_unique<FloatingObject>(renderer); object->setShouldPaint(!renderer.hasSelfPaintingLayer()); // If a layer exists, the float will paint itself. Otherwise someone else will. object->setIsDescendant(true); return object; }
int RenderView::docHeight() const { int h = lowestPosition(); // FIXME: This doesn't do any margin collapsing. // Instead of this dh computation we should keep the result // when we call RenderBlock::layout. int dh = 0; for (RenderBox* c = firstChildBox(); c; c = c->nextSiblingBox()) dh += c->height() + c->marginTop() + c->marginBottom(); if (dh > h) h = dh; return h; }
void RenderGrid::resolveContentBasedTrackSizingFunctionsForItems(TrackSizingDirection direction, Vector<GridTrack>& columnTracks, Vector<GridTrack>& rowTracks, size_t i, SizingFunction sizingFunction, AccumulatorGetter trackGetter, AccumulatorGrowFunction trackGrowthFunction) { GridTrack& track = (direction == ForColumns) ? columnTracks[i] : rowTracks[i]; for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { size_t cellIndex = resolveGridPosition(direction, child); if (cellIndex != i) continue; LayoutUnit contentSize = (this->*sizingFunction)(child, direction, columnTracks); LayoutUnit additionalBreadthSpace = contentSize - (track.*trackGetter)(); Vector<GridTrack*> tracks; tracks.append(&track); // FIXME: We should pass different values for |tracksForGrowthAboveMaxBreadth|. distributeSpaceToTracks(tracks, &tracks, trackGetter, trackGrowthFunction, additionalBreadthSpace); } }
void RenderTheme::updateControlStatesForRenderer(const RenderBox& box, ControlStates& controlStates) const { ControlStates newStates = extractControlStatesForRenderer(box); controlStates.setStates(newStates.states()); if (isFocused(box)) controlStates.setTimeSinceControlWasFocused(box.document().page()->focusController().timeSinceFocusWasSet()); }
PassOwnPtr<GridSpan> GridResolvedPosition::resolveGridPositionsFromStyle(const RenderStyle& gridContainerStyle, const RenderBox& gridItem, GridTrackSizingDirection direction) { GridPosition initialPosition = (direction == ForColumns) ? gridItem.style()->gridColumnStart() : gridItem.style()->gridRowStart(); const GridPositionSide initialPositionSide = (direction == ForColumns) ? ColumnStartSide : RowStartSide; GridPosition finalPosition = (direction == ForColumns) ? gridItem.style()->gridColumnEnd() : gridItem.style()->gridRowEnd(); const GridPositionSide finalPositionSide = (direction == ForColumns) ? ColumnEndSide : RowEndSide; // We must handle the placement error handling code here instead of in the StyleAdjuster because we don't want to // overwrite the specified values. if (initialPosition.isSpan() && finalPosition.isSpan()) finalPosition.setAutoPosition(); if (initialPosition.isNamedGridArea() && !gridContainerStyle.namedGridArea().contains(initialPosition.namedGridLine())) initialPosition.setAutoPosition(); if (finalPosition.isNamedGridArea() && !gridContainerStyle.namedGridArea().contains(finalPosition.namedGridLine())) finalPosition.setAutoPosition(); if (initialPosition.shouldBeResolvedAgainstOppositePosition() && finalPosition.shouldBeResolvedAgainstOppositePosition()) { if (gridContainerStyle.gridAutoFlow() == AutoFlowNone) return adoptPtr(new GridSpan(0, 0)); // We can't get our grid positions without running the auto placement algorithm. return nullptr; } if (initialPosition.shouldBeResolvedAgainstOppositePosition()) { // Infer the position from the final position ('auto / 1' or 'span 2 / 3' case). GridResolvedPosition finalResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalPositionSide); return resolveGridPositionAgainstOppositePosition(gridContainerStyle, finalResolvedPosition, initialPosition, initialPositionSide); } if (finalPosition.shouldBeResolvedAgainstOppositePosition()) { // Infer our position from the initial position ('1 / auto' or '3 / span 2' case). GridResolvedPosition initialResolvedPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialPositionSide); return resolveGridPositionAgainstOppositePosition(gridContainerStyle, initialResolvedPosition, finalPosition, finalPositionSide); } GridResolvedPosition resolvedInitialPosition = resolveGridPositionFromStyle(gridContainerStyle, initialPosition, initialPositionSide); GridResolvedPosition resolvedFinalPosition = resolveGridPositionFromStyle(gridContainerStyle, finalPosition, finalPositionSide); // If 'grid-after' specifies a line at or before that specified by 'grid-before', it computes to 'span 1'. if (resolvedFinalPosition < resolvedInitialPosition) resolvedFinalPosition = resolvedInitialPosition; return adoptPtr(new GridSpan(resolvedInitialPosition, resolvedFinalPosition)); }
bool ContainerNode::getLowerRightCorner(FloatPoint& point) const { if (!renderer()) return false; RenderObject* o = renderer(); if (!o->isInline() || o->isReplaced()) { RenderBox* box = toRenderBox(o); point = o->localToAbsolute(LayoutPoint(box->size()), UseTransforms); return true; } // find the last text/image child, to get a position while (o) { if (o->lastChild()) o = o->lastChild(); else if (o->previousSibling()) o = o->previousSibling(); else { RenderObject* prev = 0; while (!prev) { o = o->parent(); if (!o) return false; prev = o->previousSibling(); } o = prev; } ASSERT(o); if (o->isText() || o->isReplaced()) { point = FloatPoint(); if (o->isText()) { RenderText* text = toRenderText(o); IntRect linesBox = text->linesBoundingBox(); if (!linesBox.maxX() && !linesBox.maxY()) continue; point.moveBy(linesBox.maxXMaxYCorner()); } else { RenderBox* box = toRenderBox(o); point.moveBy(box->frameRect().maxXMaxYCorner()); } point = o->container()->localToAbsolute(point, UseTransforms); return true; } } return true; }
bool ShapeOutsideInfo::isEnabledFor(const RenderBox& box) { ShapeValue* shapeValue = box.style()->shapeOutside(); if (!box.isFloating() || !shapeValue) return false; switch (shapeValue->type()) { case ShapeValue::Shape: return shapeValue->shape(); case ShapeValue::Image: return shapeValue->isImageValid() && checkShapeImageOrigin(box.document(), *(shapeValue->image())); case ShapeValue::Box: return true; } return false; }
void RenderThemeSymbian::paintButtonDecorations(RenderObject* o, const RenderObject::PaintInfo& i, const IntRect& r) { RenderBox* b = static_cast<RenderBox*>(o); int my = max(r.y(), i.rect.y()); int mh; if (r.y() < i.rect.y()) mh = max(0, r.height() - (i.rect.y() - r.y())); else mh = std::min(i.rect.height(), r.height()); if (o->style()->hasBackground()) { b->paintBackgroundExtended(i.context, o->style()->backgroundColor(), o->style()->backgroundLayers(), my, mh, r.x(), r.y(), r.width(), r.height()); } if (o->style()->hasBorder()) { b->paintBorder(i.context, r.x(), r.y(), r.width(), r.height(), o->style()); } }
void RenderFieldset::paintMask(PaintInfo& paintInfo, int tx, int ty) { if (style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseMask) return; int w = width(); int h = height(); RenderBox* legend = findLegend(); if (!legend) return RenderBlock::paintMask(paintInfo, tx, ty); int yOff = (legend->y() > 0) ? 0 : (legend->height() - borderTop()) / 2; h -= yOff; ty += yOff; paintMaskImages(paintInfo, tx, ty, w, h); }
static bool isElementLargeEnoughForMainContent(const HTMLMediaElement& element) { static const double elementMainContentAreaMinimum = 400 * 300; static const double maximumAspectRatio = 1.8; // Slightly larger than 16:9. static const double minimumAspectRatio = .5; // Slightly smaller than 16:9. // Elements which have not yet been laid out, or which are not yet in the DOM, cannot be main content. RenderBox* renderer = downcast<RenderBox>(element.renderer()); if (!renderer) return false; double width = renderer->clientWidth(); double height = renderer->clientHeight(); double area = width * height; double aspectRatio = width / height; return area >= elementMainContentAreaMinimum && aspectRatio >= minimumAspectRatio && aspectRatio <= maximumAspectRatio; }
bool GraphicsContext3DInternal::lockFrontBuffer(T& image, SkRect& rect) { LOGWEBGL("GraphicsContext3DInternal::lockFrontBuffer()"); MutexLocker lock(m_fboMutex); FBO* fbo = m_frontFBO; if (!fbo || !fbo->image()) { LOGWEBGL("-GraphicsContext3DInternal::lockFrontBuffer(), fbo = %p", fbo); return false; } fbo->setLocked(true); image = (T)(fbo->image()); RenderObject* renderer = m_canvas->renderer(); if (renderer && renderer->isBox()) { RenderBox* box = (RenderBox*)renderer; rect.setXYWH(box->borderLeft() + box->paddingLeft(), box->borderTop() + box->paddingTop(), box->contentWidth(), box->contentHeight()); } return true; }
float SVGLength::PercentageOfViewport(float value, const SVGElement* context, SVGLengthMode mode) { ASSERT(context); float width = 0.0f, height = 0.0f; SVGElement* viewportElement = context->viewportElement(); // PercentageOfViewport() is used to resolve all relative-positioned values within a SVG document (fragment) Document* doc = context->document(); if (doc->documentElement() == context) { // Resolve value against outermost <svg> element if (RenderView* view = toRenderView(doc->renderer())) { width = view->viewWidth(); height = view->viewHeight(); } } else if (viewportElement && viewportElement->isSVG()) { // Resolve value against nearest viewport element (common case: inner <svg> elements) const SVGSVGElement* svg = static_cast<const SVGSVGElement*>(viewportElement); if (svg->hasAttribute(SVGNames::viewBoxAttr)) { width = svg->viewBox().width(); height = svg->viewBox().height(); } else { width = svg->width().value(svg); height = svg->height().value(svg); } } else if (context->parent() && !context->parent()->isSVGElement()) { // Resolve value against enclosing non-SVG RenderBox if (RenderObject* renderer = context->renderer()) { if (renderer->isBox()) { RenderBox* box = toRenderBox(renderer); width = box->width(); height = box->height(); } } } if (mode == LengthModeWidth) return value * width; else if (mode == LengthModeHeight) return value * height; else if (mode == LengthModeOther) return value * sqrtf(powf(width, 2) + powf(height, 2)) / sqrtf(2.0f); return 0.0f; }
void RenderMedia::layout() { IntSize oldSize = contentBoxRect().size(); RenderImage::layout(); RenderBox* controlsRenderer = m_controls->renderBox(); if (!controlsRenderer) return; IntSize newSize = contentBoxRect().size(); if (newSize == oldSize && !controlsRenderer->needsLayout()) return; // When calling layout() on a child node, a parent must either push a LayoutStateMaintainter, or // call view()->disableLayoutState(). Since using a LayoutStateMaintainer is slightly more efficient, // and this method will be called many times per second during playback, use a LayoutStateMaintainer: LayoutStateMaintainer statePusher(view(), this, IntSize(x(), y()), hasTransform() || hasReflection() || style()->isFlippedBlocksWritingMode()); controlsRenderer->setLocation(borderLeft() + paddingLeft(), borderTop() + paddingTop()); controlsRenderer->style()->setHeight(Length(newSize.height(), Fixed)); controlsRenderer->style()->setWidth(Length(newSize.width(), Fixed)); controlsRenderer->setNeedsLayout(true, false); controlsRenderer->layout(); setChildNeedsLayout(false); statePusher.pop(); }
bool SVGLength::determineViewport(const SVGElement* context, float& width, float& height) const { if (!context) return false; // Take size from outermost <svg> element. Document* document = context->document(); if (document->documentElement() == context) { if (RenderView* view = toRenderView(document->renderer())) { width = view->viewWidth(); height = view->viewHeight(); return true; } return false; } // Resolve value against nearest viewport element (common case: inner <svg> elements) SVGElement* viewportElement = context->viewportElement(); if (viewportElement && viewportElement->isSVG()) { const SVGSVGElement* svg = static_cast<const SVGSVGElement*>(viewportElement); if (svg->hasAttribute(SVGNames::viewBoxAttr)) { width = svg->viewBox().width(); height = svg->viewBox().height(); } else { width = svg->width().value(svg); height = svg->height().value(svg); } return true; } // Resolve value against enclosing non-SVG RenderBox if (!context->parentNode() || context->parentNode()->isSVGElement()) return false; RenderObject* renderer = context->renderer(); if (!renderer || !renderer->isBox()) return false; RenderBox* box = toRenderBox(renderer); width = box->width(); height = box->height(); return true; }
static inline void appendZoomableSubtargets(Node* node, SubtargetGeometryList& subtargets) { RenderBox* renderer = toRenderBox(node->renderer()); ASSERT(renderer); Vector<FloatQuad> quads; FloatRect borderBoxRect = renderer->borderBoxRect(); FloatRect contentBoxRect = renderer->contentBoxRect(); quads.append(renderer->localToAbsoluteQuad(borderBoxRect)); if (borderBoxRect != contentBoxRect) quads.append(renderer->localToAbsoluteQuad(contentBoxRect)); // FIXME: For RenderBlocks, add column boxes and content boxes cleared for floats. Vector<FloatQuad>::const_iterator it = quads.begin(); const Vector<FloatQuad>::const_iterator end = quads.end(); for (; it != end; ++it) subtargets.append(SubtargetGeometry(node, *it)); }
void RenderInline::absoluteRects(Vector<IntRect>& rects, int tx, int ty, bool topLevel) { for (InlineRunBox* curr = firstLineBox(); curr; curr = curr->nextLineBox()) rects.append(IntRect(tx + curr->xPos(), ty + curr->yPos(), curr->width(), curr->height())); for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) { if (curr->isBox()) { RenderBox* box = toRenderBox(curr); curr->absoluteRects(rects, tx + box->x(), ty + box->y(), false); } } if (continuation() && topLevel) continuation()->absoluteRects(rects, tx - containingBlock()->x() + continuation()->x(), ty - containingBlock()->y() + continuation()->y(), topLevel); }
int HTMLBodyElement::scrollTop() { Document& document = this->document(); document.updateLayoutIgnorePendingStylesheets(); if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) { RenderBox* render = renderBox(); if (!render) return 0; if (render->hasOverflowClip()) return adjustForAbsoluteZoom(render->scrollTop(), render); if (!document.inQuirksMode()) return 0; } FrameView* view = document.view(); return view ? adjustForZoom(view->scrollY(), &document) : 0; }
void RenderMediaVolumeSliderContainer::layout() { RenderBlock::layout(); if (style()->display() == NONE || !previousSibling() || !previousSibling()->isBox()) return; RenderBox* buttonBox = toRenderBox(previousSibling()); if (view()) view()->disableLayoutState(); IntPoint offset = theme()->volumeSliderOffsetFromMuteButton(buttonBox, IntSize(width(), height())); setX(offset.x() + buttonBox->offsetLeft()); setY(offset.y() + buttonBox->offsetTop()); if (view()) view()->enableLayoutState(); }
void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads) { InlineRunBox* firstBox = firstLineBox(); SVGRootInlineBox* rootBox = firstBox ? static_cast<SVGInlineTextBox*>(firstBox)->svgRootInlineBox() : 0; RenderBox* object = rootBox ? rootBox->block() : 0; if (!object) return; int xRef = object->x(); int yRef = object->y(); for (InlineRunBox* curr = firstBox; curr; curr = curr->nextLineBox()) { FloatRect rect(xRef + curr->x(), yRef + curr->y(), curr->width(), curr->height()); quads.append(localToAbsoluteQuad(rect)); } }
// Return a set of rectangles that should not be overdrawn by the // plugin ("cutouts"). This helps implement the "iframe shim" // technique of overlaying a windowed plugin with content from the // page. In a nutshell, iframe elements should occlude plugins when // they occur higher in the stacking order. void getPluginOcclusions(Element* element, Widget* parentWidget, const IntRect& frameRect, Vector<IntRect>& occlusions) { RenderObject* pluginNode = element->renderer(); ASSERT(pluginNode); if (!pluginNode->style()) return; Vector<const RenderObject*> pluginZstack; Vector<const RenderObject*> iframeZstack; getObjectStack(pluginNode, &pluginZstack); if (!parentWidget->isFrameView()) return; FrameView* parentFrameView = static_cast<FrameView*>(parentWidget); const HashSet<RefPtr<Widget> >* children = parentFrameView->children(); for (HashSet<RefPtr<Widget> >::const_iterator it = children->begin(); it != children->end(); ++it) { // We only care about FrameView's because iframes show up as FrameViews. if (!(*it)->isFrameView()) continue; const FrameView* frameView = static_cast<const FrameView*>((*it).get()); // Check to make sure we can get both the element and the RenderObject // for this FrameView, if we can't just move on to the next object. if (!frameView->frame() || !frameView->frame()->ownerElement() || !frameView->frame()->ownerElement()->renderer()) continue; HTMLElement* element = frameView->frame()->ownerElement(); RenderObject* iframeRenderer = element->renderer(); if (element->hasTagName(HTMLNames::iframeTag) && iframeRenderer->absoluteBoundingBoxRect().intersects(frameRect) && (!iframeRenderer->style() || iframeRenderer->style()->visibility() == VISIBLE)) { getObjectStack(iframeRenderer, &iframeZstack); if (iframeIsAbovePlugin(iframeZstack, pluginZstack)) { IntPoint point = roundedIntPoint(iframeRenderer->localToAbsolute()); RenderBox* rbox = toRenderBox(iframeRenderer); IntSize size(rbox->width(), rbox->height()); occlusions.append(IntRect(point, size)); } } } }
void RenderMathMLFraction::paint(PaintInfo& info, const LayoutPoint& paintOffset) { RenderMathMLBlock::paint(info, paintOffset); if (info.context().paintingDisabled() || info.phase != PaintPhaseForeground || style().visibility() != VISIBLE) return; RenderBox* denominatorWrapper = lastChildBox(); if (!denominatorWrapper || !m_lineThickness) return; IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location() + denominatorWrapper->location() + LayoutPoint(0, m_lineThickness / 2)); GraphicsContextStateSaver stateSaver(info.context()); info.context().setStrokeThickness(m_lineThickness); info.context().setStrokeStyle(SolidStroke); info.context().setStrokeColor(style().visitedDependentColor(CSSPropertyColor)); info.context().drawLine(adjustedPaintOffset, roundedIntPoint(LayoutPoint(adjustedPaintOffset.x() + denominatorWrapper->offsetWidth(), adjustedPaintOffset.y()))); }
void RenderImage::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const { RenderReplaced::computeIntrinsicRatioInformation(intrinsicSize, intrinsicRatio, isPercentageIntrinsicSize); // Our intrinsicSize is empty if we're rendering generated images with relative width/height. Figure out the right intrinsic size to use. if (intrinsicSize.isEmpty() && (m_imageResource->imageHasRelativeWidth() || m_imageResource->imageHasRelativeHeight())) { RenderObject* containingBlock = isOutOfFlowPositioned() ? container() : this->containingBlock(); if (containingBlock->isBox()) { RenderBox* box = toRenderBox(containingBlock); intrinsicSize.setWidth(box->availableLogicalWidth()); intrinsicSize.setHeight(box->availableLogicalHeight(IncludeMarginBorderPadding)); } } // Don't compute an intrinsic ratio to preserve historical WebKit behavior if we're painting alt text and/or a broken image. if (m_imageResource && m_imageResource->errorOccurred()) { intrinsicRatio = 1; return; } }
float SVGLength::PercentageOfViewport(float value, const SVGElement* context, SVGLengthMode mode) { ASSERT(context); float width = 0.0f, height = 0.0f; SVGElement* viewportElement = context->viewportElement(); Document* doc = context->document(); if (doc->documentElement() == context) { // We have to ask the canvas for the full "canvas size"... RenderView* view = toRenderView(doc->renderer()); if (view && view->frameView()) { width = view->frameView()->visibleWidth(); // TODO: recheck! height = view->frameView()->visibleHeight(); // TODO: recheck! } } else if (viewportElement && viewportElement->isSVG()) { const SVGSVGElement* svg = static_cast<const SVGSVGElement*>(viewportElement); if (svg->hasAttribute(SVGNames::viewBoxAttr)) { width = svg->viewBox().width(); height = svg->viewBox().height(); } else { width = svg->width().value(svg); height = svg->height().value(svg); } } else if (context->parent() && !context->parent()->isSVGElement()) { if (RenderObject* renderer = context->renderer()) { if (renderer->isBox()) { RenderBox* box = toRenderBox(renderer); width = box->width(); height = box->height(); } } } if (mode == LengthModeWidth) return value * width; else if (mode == LengthModeHeight) return value * height; else if (mode == LengthModeOther) return value * sqrtf(powf(width, 2) + powf(height, 2)) / sqrtf(2.0f); return 0.0f; }
bool RenderInputSpeech::paintInputFieldSpeechButton(RenderObject* object, const PaintInfo& paintInfo, const IntRect& rect) { Element* element = object->node()->isElementNode() ? toElement(object->node()) : 0; if (!element || !element->isInputFieldSpeechButtonElement()) return false; // Get the renderer of <input> element. Node* input = object->node()->shadowHost(); if (!input->renderer()->isBox()) return false; RenderBox* inputRenderBox = toRenderBox(input->renderer()); LayoutRect inputContentBox = inputRenderBox->contentBoxRect(); // Make sure the scaled button stays square and will fit in its parent's box. LayoutUnit buttonSize = std::min(inputContentBox.width(), std::min<LayoutUnit>(inputContentBox.height(), rect.height())); // Calculate button's coordinates relative to the input element. // Center the button vertically. Round up though, so if it has to be one pixel off-center, it will // be one pixel closer to the bottom of the field. This tends to look better with the text. LayoutRect buttonRect(object->offsetFromAncestorContainer(inputRenderBox).width(), inputContentBox.y() + (inputContentBox.height() - buttonSize + 1) / 2, buttonSize, buttonSize); // Compute an offset between the part renderer and the input renderer. LayoutSize offsetFromInputRenderer = -(object->offsetFromAncestorContainer(inputRenderBox)); // Move the rect into partRenderer's coords. buttonRect.move(offsetFromInputRenderer); // Account for the local drawing offset. buttonRect.moveBy(rect.location()); DEFINE_STATIC_LOCAL(RefPtr<Image>, imageStateNormal, (Image::loadPlatformResource("inputSpeech"))); DEFINE_STATIC_LOCAL(RefPtr<Image>, imageStateRecording, (Image::loadPlatformResource("inputSpeechRecording"))); DEFINE_STATIC_LOCAL(RefPtr<Image>, imageStateWaiting, (Image::loadPlatformResource("inputSpeechWaiting"))); InputFieldSpeechButtonElement* speechButton = toInputFieldSpeechButtonElement(element); Image* image = imageStateNormal.get(); if (speechButton->state() == InputFieldSpeechButtonElement::Recording) image = imageStateRecording.get(); else if (speechButton->state() == InputFieldSpeechButtonElement::Recognizing) image = imageStateWaiting.get(); paintInfo.context->drawImage(image, object->style()->colorSpace(), pixelSnappedIntRect(buttonRect)); return false; }
static void getShapeImageAndRect(const ShapeValue& shapeValue, const RenderBox& renderBox, const LayoutSize& referenceBoxSize, Image*& image, LayoutRect& rect) { ASSERT(shapeValue.isImageValid()); StyleImage* styleImage = shapeValue.image(); const LayoutSize& imageSize = renderBox.calculateImageIntrinsicDimensions(styleImage, roundedIntSize(referenceBoxSize), RenderImage::ScaleByEffectiveZoom); styleImage->setContainerSizeForRenderer(&renderBox, imageSize, renderBox.style().effectiveZoom()); image = nullptr; if (styleImage->isCachedImage() || styleImage->isCachedImageSet()) image = styleImage->cachedImage()->imageForRenderer(&renderBox); else if (styleImage->isGeneratedImage()) image = styleImage->image(const_cast<RenderBox*>(&renderBox), imageSize).get(); if (renderBox.isRenderImage()) rect = toRenderImage(&renderBox)->replacedContentRect(renderBox.intrinsicSize()); else rect = LayoutRect(LayoutPoint(), imageSize); }
double HTMLBodyElement::scrollTop() { Document& document = this->document(); document.updateLayoutIgnorePendingStylesheets(); if (RuntimeEnabledFeatures::scrollTopLeftInteropEnabled()) { RenderBox* render = renderBox(); if (!render) return 0; if (render->hasOverflowClip()) return adjustLayoutUnitForAbsoluteZoom(render->scrollTop(), *render); if (!document.inQuirksMode()) return 0; } if (FrameView* view = document.view()) return adjustScrollForAbsoluteZoom(view->scrollY(), document.frame()->pageZoomFactor()); return 0; }