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; }
void RenderSliderContainer::layout() { ASSERT(element()->shadowHost()); auto& input = downcast<HTMLInputElement>(*element()->shadowHost()); bool isVertical = hasVerticalAppearance(input); mutableStyle().setFlexDirection(isVertical ? FlowColumn : FlowRow); TextDirection oldTextDirection = style().direction(); if (isVertical) { // FIXME: Work around rounding issues in RTL vertical sliders. We want them to // render identically to LTR vertical sliders. We can remove this work around when // subpixel rendering is enabled on all ports. mutableStyle().setDirection(LTR); } RenderBox* thumb = input.sliderThumbElement() ? input.sliderThumbElement()->renderBox() : nullptr; RenderBox* track = input.sliderTrackElement() ? input.sliderTrackElement()->renderBox() : nullptr; // Force a layout to reset the position of the thumb so the code below doesn't move the thumb to the wrong place. // FIXME: Make a custom Render class for the track and move the thumb positioning code there. if (track) track->setChildNeedsLayout(MarkOnlyThis); RenderFlexibleBox::layout(); mutableStyle().setDirection(oldTextDirection); // These should always exist, unless someone mutates the shadow DOM (e.g., in the inspector). if (!thumb || !track) return; double percentageOffset = sliderPosition(input).toDouble(); LayoutUnit availableExtent = isVertical ? track->contentHeight() : track->contentWidth(); availableExtent -= isVertical ? thumb->height() : thumb->width(); LayoutUnit offset = percentageOffset * availableExtent; LayoutPoint thumbLocation = thumb->location(); if (isVertical) thumbLocation.setY(thumbLocation.y() + track->contentHeight() - thumb->height() - offset); else if (style().isLeftToRightDirection()) thumbLocation.setX(thumbLocation.x() + offset); else thumbLocation.setX(thumbLocation.x() - offset); thumb->setLocation(thumbLocation); thumb->repaint(); }
unsigned ImageInputType::width() const { RefPtr<HTMLInputElement> element = this->element(); if (!element->renderer()) { // Check the attribute first for an explicit pixel value. unsigned width; if (parseHTMLNonNegativeInteger(element->fastGetAttribute(widthAttr), width)) return width; // If the image is available, use its width. if (m_imageLoader && m_imageLoader->image()) return m_imageLoader->image()->imageSizeForRenderer(element->renderer(), 1).width(); } element->document()->updateLayout(); RenderBox* box = element->renderBox(); return box ? adjustForAbsoluteZoom(box->contentWidth(), box) : 0; }
int HTMLImageElement::width(bool ignorePendingStylesheets) const { if (!renderer()) { // check the attribute first for an explicit pixel value bool ok; int width = getAttribute(widthAttr).toInt(&ok); if (ok) return width; // if the image is available, use its width if (m_imageLoader.image()) return m_imageLoader.image()->imageSize(1.0f).width(); } if (ignorePendingStylesheets) document()->updateLayoutIgnorePendingStylesheets(); else document()->updateLayout(); RenderBox* box = renderBox(); return box ? adjustForAbsoluteZoom(box->contentWidth(), box) : 0; }
static AtomicString classNameForShadowRoot(const Node* node) { DEFINE_STATIC_LOCAL(const AtomicString, plugInTinySizeClassName, ("tiny", AtomicString::ConstructFromLiteral)); DEFINE_STATIC_LOCAL(const AtomicString, plugInSmallSizeClassName, ("small", AtomicString::ConstructFromLiteral)); DEFINE_STATIC_LOCAL(const AtomicString, plugInMediumSizeClassName, ("medium", AtomicString::ConstructFromLiteral)); DEFINE_STATIC_LOCAL(const AtomicString, plugInLargeSizeClassName, ("large", AtomicString::ConstructFromLiteral)); RenderBox* renderBox = static_cast<RenderBox*>(node->renderer()); LayoutUnit width = renderBox->contentWidth(); LayoutUnit height = renderBox->contentHeight(); if (width < sizingTinyDimensionThreshold || height < sizingTinyDimensionThreshold) return plugInTinySizeClassName; if (width < sizingSmallWidthThreshold) return plugInSmallSizeClassName; if (width < sizingMediumWidthThreshold || height < sizingMediumHeightThreshold) return plugInMediumSizeClassName; return plugInLargeSizeClassName; }
void updateSnapOffsetsForScrollableArea(ScrollableArea& scrollableArea, HTMLElement& scrollingElement, const RenderBox& scrollingElementBox, const RenderStyle& scrollingElementStyle) { auto* scrollContainer = scrollingElement.renderer(); auto scrollSnapType = scrollingElementStyle.scrollSnapType(); if (!scrollContainer || scrollSnapType.strictness == ScrollSnapStrictness::None || scrollContainer->view().boxesWithScrollSnapPositions().isEmpty()) { scrollableArea.clearHorizontalSnapOffsets(); scrollableArea.clearVerticalSnapOffsets(); return; } Vector<LayoutUnit> verticalSnapOffsets; Vector<LayoutUnit> horizontalSnapOffsets; Vector<ScrollOffsetRange<LayoutUnit>> verticalSnapOffsetRanges; Vector<ScrollOffsetRange<LayoutUnit>> horizontalSnapOffsetRanges; HashSet<float> seenVerticalSnapOffsets; HashSet<float> seenHorizontalSnapOffsets; bool hasHorizontalSnapOffsets = scrollSnapType.axis == ScrollSnapAxis::Both || scrollSnapType.axis == ScrollSnapAxis::XAxis || scrollSnapType.axis == ScrollSnapAxis::Inline; bool hasVerticalSnapOffsets = scrollSnapType.axis == ScrollSnapAxis::Both || scrollSnapType.axis == ScrollSnapAxis::YAxis || scrollSnapType.axis == ScrollSnapAxis::Block; auto maxScrollLeft = scrollingElementBox.scrollWidth() - scrollingElementBox.contentWidth(); auto maxScrollTop = scrollingElementBox.scrollHeight() - scrollingElementBox.contentHeight(); LayoutPoint containerScrollOffset(scrollingElementBox.scrollLeft(), scrollingElementBox.scrollTop()); // The bounds of the scrolling container's snap port, where the top left of the scrolling container's border box is the origin. auto scrollSnapPort = computeScrollSnapPortOrAreaRect(scrollingElementBox.paddingBoxRect(), scrollingElementStyle.scrollPadding(), InsetOrOutset::Inset); #if !LOG_DISABLED LOG(Scrolling, "Computing scroll snap offsets in snap port: %s", snapPortOrAreaToString(scrollSnapPort).utf8().data()); #endif for (auto* child : scrollContainer->view().boxesWithScrollSnapPositions()) { if (child->findEnclosingScrollableContainer() != scrollContainer) continue; // The bounds of the child element's snap area, where the top left of the scrolling container's border box is the origin. // The snap area is the bounding box of the child element's border box, after applying transformations. auto scrollSnapArea = LayoutRect(child->localToContainerQuad(FloatQuad(child->borderBoundingBox()), scrollingElement.renderBox()).boundingBox()); scrollSnapArea.moveBy(containerScrollOffset); scrollSnapArea = computeScrollSnapPortOrAreaRect(scrollSnapArea, child->style().scrollSnapMargin(), InsetOrOutset::Outset); #if !LOG_DISABLED LOG(Scrolling, " Considering scroll snap area: %s", snapPortOrAreaToString(scrollSnapArea).utf8().data()); #endif auto alignment = child->style().scrollSnapAlign(); if (hasHorizontalSnapOffsets && alignment.x != ScrollSnapAxisAlignType::None) { auto absoluteScrollOffset = clampTo<LayoutUnit>(computeScrollSnapAlignOffset(scrollSnapArea.x(), scrollSnapArea.width(), alignment.x) - computeScrollSnapAlignOffset(scrollSnapPort.x(), scrollSnapPort.width(), alignment.x), 0, maxScrollLeft); if (!seenHorizontalSnapOffsets.contains(absoluteScrollOffset)) { seenHorizontalSnapOffsets.add(absoluteScrollOffset); horizontalSnapOffsets.append(absoluteScrollOffset); } } if (hasVerticalSnapOffsets && alignment.y != ScrollSnapAxisAlignType::None) { auto absoluteScrollOffset = clampTo<LayoutUnit>(computeScrollSnapAlignOffset(scrollSnapArea.y(), scrollSnapArea.height(), alignment.y) - computeScrollSnapAlignOffset(scrollSnapPort.y(), scrollSnapPort.height(), alignment.y), 0, maxScrollTop); if (!seenVerticalSnapOffsets.contains(absoluteScrollOffset)) { seenVerticalSnapOffsets.add(absoluteScrollOffset); verticalSnapOffsets.append(absoluteScrollOffset); } } } if (!horizontalSnapOffsets.isEmpty()) { adjustAxisSnapOffsetsForScrollExtent(horizontalSnapOffsets, maxScrollLeft); #if !LOG_DISABLED LOG(Scrolling, " => Computed horizontal scroll snap offsets: %s", snapOffsetsToString(horizontalSnapOffsets).utf8().data()); LOG(Scrolling, " => Computed horizontal scroll snap offset ranges: %s", snapOffsetRangesToString(horizontalSnapOffsetRanges).utf8().data()); #endif if (scrollSnapType.strictness == ScrollSnapStrictness::Proximity) computeAxisProximitySnapOffsetRanges(horizontalSnapOffsets, horizontalSnapOffsetRanges, scrollSnapPort.width()); scrollableArea.setHorizontalSnapOffsets(horizontalSnapOffsets); scrollableArea.setHorizontalSnapOffsetRanges(horizontalSnapOffsetRanges); } else scrollableArea.clearHorizontalSnapOffsets(); if (!verticalSnapOffsets.isEmpty()) { adjustAxisSnapOffsetsForScrollExtent(verticalSnapOffsets, maxScrollTop); #if !LOG_DISABLED LOG(Scrolling, " => Computed vertical scroll snap offsets: %s", snapOffsetsToString(verticalSnapOffsets).utf8().data()); LOG(Scrolling, " => Computed vertical scroll snap offset ranges: %s", snapOffsetRangesToString(verticalSnapOffsetRanges).utf8().data()); #endif if (scrollSnapType.strictness == ScrollSnapStrictness::Proximity) computeAxisProximitySnapOffsetRanges(verticalSnapOffsets, verticalSnapOffsetRanges, scrollSnapPort.height()); scrollableArea.setVerticalSnapOffsets(verticalSnapOffsets); scrollableArea.setVerticalSnapOffsetRanges(verticalSnapOffsetRanges); } else scrollableArea.clearVerticalSnapOffsets(); }