void SVGRootInlineBox::layoutRootBox(const FloatRect& childRect) { RenderBlock* parentBlock = block(); ASSERT(parentBlock); // Finally, assign the root block position, now that all content is laid out. LayoutRect boundingRect = enclosingLayoutRect(childRect); parentBlock->setLocation(boundingRect.location()); parentBlock->setSize(boundingRect.size()); // Position all children relative to the parent block. for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) { // Skip generated content. if (!child->renderer()->node()) continue; child->adjustPosition(-childRect.x(), -childRect.y()); } // Position ourselves. setX(0); setY(0); setLogicalWidth(childRect.width()); setLogicalHeight(childRect.height()); setLineTopBottomPositions(0, boundingRect.height(), 0, boundingRect.height()); }
static LayoutRect clipRectForNinePieceImageStrip(const InlineFlowBox& box, const NinePieceImage& image, const LayoutRect& paintRect) { LayoutRect clipRect(paintRect); const ComputedStyle& style = box.lineLayoutItem().styleRef(); LayoutRectOutsets outsets = style.imageOutsets(image); if (box.isHorizontal()) { clipRect.setY(paintRect.y() - outsets.top()); clipRect.setHeight(paintRect.height() + outsets.top() + outsets.bottom()); if (box.includeLogicalLeftEdge()) { clipRect.setX(paintRect.x() - outsets.left()); clipRect.setWidth(paintRect.width() + outsets.left()); } if (box.includeLogicalRightEdge()) clipRect.setWidth(clipRect.width() + outsets.right()); } else { clipRect.setX(paintRect.x() - outsets.left()); clipRect.setWidth(paintRect.width() + outsets.left() + outsets.right()); if (box.includeLogicalLeftEdge()) { clipRect.setY(paintRect.y() - outsets.top()); clipRect.setHeight(paintRect.height() + outsets.top()); } if (box.includeLogicalRightEdge()) clipRect.setHeight(clipRect.height() + outsets.bottom()); } return clipRect; }
IntRect RenderVideo::videoBox() const { if (m_cachedImageSize.isEmpty() && videoElement()->shouldDisplayPosterImage()) return IntRect(); LayoutSize elementSize; if (videoElement()->shouldDisplayPosterImage()) elementSize = m_cachedImageSize; else elementSize = intrinsicSize(); IntRect contentRect = pixelSnappedIntRect(contentBoxRect()); if (elementSize.isEmpty() || contentRect.isEmpty()) return IntRect(); LayoutRect renderBox = contentRect; LayoutUnit ratio = renderBox.width() * elementSize.height() - renderBox.height() * elementSize.width(); if (ratio > 0) { LayoutUnit newWidth = renderBox.height() * elementSize.width() / elementSize.height(); // Just fill the whole area if the difference is one pixel or less (in both sides) if (renderBox.width() - newWidth > 2) renderBox.setWidth(newWidth); renderBox.move((contentRect.width() - renderBox.width()) / 2, 0); } else if (ratio < 0) { LayoutUnit newHeight = renderBox.width() * elementSize.height() / elementSize.width(); if (renderBox.height() - newHeight > 2) renderBox.setHeight(newHeight); renderBox.move(0, (contentRect.height() - renderBox.height()) / 2); } return pixelSnappedIntRect(renderBox); }
LayoutRect RenderReplaced::replacedContentRect(const LayoutSize& intrinsicSize) const { LayoutRect contentRect = contentBoxRect(); ObjectFit objectFit = style().objectFit(); if (objectFit == ObjectFitFill) return contentRect; if (!intrinsicSize.width() || !intrinsicSize.height()) return contentRect; LayoutRect finalRect = contentRect; switch (objectFit) { case ObjectFitContain: case ObjectFitScaleDown: case ObjectFitCover: finalRect.setSize(finalRect.size().fitToAspectRatio(intrinsicSize, objectFit == ObjectFitCover ? AspectRatioFitGrow : AspectRatioFitShrink)); if (objectFit != ObjectFitScaleDown || finalRect.width() <= intrinsicSize.width()) break; // fall through case ObjectFitNone: finalRect.setSize(intrinsicSize); break; case ObjectFitFill: ASSERT_NOT_REACHED(); } // FIXME: This is where object-position should be taken into account, but since it's not // implemented yet, assume the initial value of "50% 50%". LayoutUnit xOffset = (contentRect.width() - finalRect.width()) / 2; LayoutUnit yOffset = (contentRect.height() - finalRect.height()) / 2; finalRect.move(xOffset, yOffset); return finalRect; }
void MediaPlayerPrivate::resizeSourceDimensions() { if (!m_webCorePlayer) return; if (!m_webCorePlayer->mediaPlayerClient()->mediaPlayerIsVideo()) return; // If we have an HTMLVideoElement but the source has no video, then we need to resize the media element. if (!hasVideo() && PlatformPlayer::MediaOK == m_platformPlayer->error()) { LayoutRect rect = m_webCorePlayer->mediaPlayerClient()->mediaPlayerContentBoxRect(); static const int playbookMinAudioElementWidth = 300; static const int playbookMinAudioElementHeight = 32; // If the rect dimensions are less than the allowed minimum, use the minimum instead. int newWidth = max(rect.width().toInt(), playbookMinAudioElementWidth); int newHeight = max(rect.height().toInt(), playbookMinAudioElementHeight); m_webCorePlayer->mediaPlayerClient()->mediaPlayerSetSize(IntSize(newWidth, newHeight)); } // If we don't know what the width and height of the video source is, then we need to set it to something sane. if (m_platformPlayer->sourceWidth() && m_platformPlayer->sourceHeight()) return; LayoutRect rect = m_webCorePlayer->mediaPlayerClient()->mediaPlayerContentBoxRect(); m_platformPlayer->setSourceDimension(rect.width().toUnsigned(), rect.height().toUnsigned()); }
void RoundedRect::inflateWithRadii(const LayoutUnit& size) { LayoutRect old = m_rect; m_rect.inflate(size); // Considering the inflation factor of shorter size to scale the radii seems appropriate here float factor; if (m_rect.width() < m_rect.height()) factor = old.width() ? (float)m_rect.width() / old.width() : int(0); else factor = old.height() ? (float)m_rect.height() / old.height() : int(0); m_radii.scale(factor); }
void IntersectionObserver::applyRootMargin(LayoutRect& rect) const { // TODO(szager): Make sure the spec is clear that left/right margins are resolved against // width and not height. LayoutUnit topMargin = computeMargin(m_topMargin, rect.height()); LayoutUnit rightMargin = computeMargin(m_rightMargin, rect.width()); LayoutUnit bottomMargin = computeMargin(m_bottomMargin, rect.height()); LayoutUnit leftMargin = computeMargin(m_leftMargin, rect.width()); rect.setX(rect.x() - leftMargin); rect.setWidth(rect.width() + leftMargin + rightMargin); rect.setY(rect.y() - topMargin); rect.setHeight(rect.height() + topMargin + bottomMargin); }
static void deflateIfOverlapped(LayoutRect& a, LayoutRect& b) { if (!a.intersects(b) || a.contains(b) || b.contains(a)) return; LayoutUnit deflateFactor = -fudgeFactor(); // Avoid negative width or height values. if ((a.width() + 2 * deflateFactor > 0) && (a.height() + 2 * deflateFactor > 0)) a.inflate(deflateFactor); if ((b.width() + 2 * deflateFactor > 0) && (b.height() + 2 * deflateFactor > 0)) b.inflate(deflateFactor); }
LayoutRect LayoutReplaced::computeObjectFit( const LayoutSize* overriddenIntrinsicSize) const { LayoutRect contentRect = contentBoxRect(); ObjectFit objectFit = style()->getObjectFit(); if (objectFit == ObjectFitFill && style()->objectPosition() == ComputedStyle::initialObjectPosition()) { return contentRect; } // TODO(davve): intrinsicSize doubles as both intrinsic size and intrinsic // ratio. In the case of SVG images this isn't correct since they can have // intrinsic ratio but no intrinsic size. In order to maintain aspect ratio, // the intrinsic size for SVG might be faked from the aspect ratio, // see SVGImage::containerSize(). LayoutSize intrinsicSize = overriddenIntrinsicSize ? *overriddenIntrinsicSize : this->intrinsicSize(); if (!intrinsicSize.width() || !intrinsicSize.height()) return contentRect; LayoutRect finalRect = contentRect; switch (objectFit) { case ObjectFitContain: case ObjectFitScaleDown: case ObjectFitCover: finalRect.setSize(finalRect.size().fitToAspectRatio( intrinsicSize, objectFit == ObjectFitCover ? AspectRatioFitGrow : AspectRatioFitShrink)); if (objectFit != ObjectFitScaleDown || finalRect.width() <= intrinsicSize.width()) break; // fall through case ObjectFitNone: finalRect.setSize(intrinsicSize); break; case ObjectFitFill: break; default: ASSERT_NOT_REACHED(); } LayoutUnit xOffset = minimumValueForLength( style()->objectPosition().x(), contentRect.width() - finalRect.width()); LayoutUnit yOffset = minimumValueForLength( style()->objectPosition().y(), contentRect.height() - finalRect.height()); finalRect.move(xOffset, yOffset); return finalRect; }
void RenderImage::paintIntoRect(GraphicsContext* context, const LayoutRect& rect) { if (!m_imageResource->hasImage() || m_imageResource->errorOccurred() || rect.width() <= 0 || rect.height() <= 0) return; RefPtr<Image> img = m_imageResource->image(rect.width(), rect.height()); if (!img || img->isNull()) return; HTMLImageElement* imageElt = (node() && node()->hasTagName(imgTag)) ? static_cast<HTMLImageElement*>(node()) : 0; CompositeOperator compositeOperator = imageElt ? imageElt->compositeOperator() : CompositeSourceOver; Image* image = m_imageResource->image().get(); bool useLowQualityScaling = shouldPaintAtLowQuality(context, image, image, rect.size()); context->drawImage(m_imageResource->image(rect.width(), rect.height()).get(), style()->colorSpace(), rect, compositeOperator, useLowQualityScaling); }
LayoutRect AccessibilitySpinButtonPart::elementRect() const { // FIXME: This logic should exist in the render tree or elsewhere, but there is no // relationship that exists that can be queried. LayoutRect parentRect = parentObject()->elementRect(); if (m_isIncrementor) parentRect.setHeight(parentRect.height() / 2); else { parentRect.setY(parentRect.y() + parentRect.height() / 2); parentRect.setHeight(parentRect.height() / 2); } return parentRect; }
void TimelineRecordFactory::addRectData(InspectorObject* data, const LayoutRect& rect) { data->setNumber("x", rect.x()); data->setNumber("y", rect.y()); data->setNumber("width", rect.width()); data->setNumber("height", rect.height()); }
bool canScrollInDirection(const Frame* frame, FocusDirection direction) { if (!frame->view()) return false; ScrollbarMode verticalMode; ScrollbarMode horizontalMode; frame->view()->calculateScrollbarModesForLayout(horizontalMode, verticalMode); if ((direction == FocusDirectionLeft || direction == FocusDirectionRight) && ScrollbarAlwaysOff == horizontalMode) return false; if ((direction == FocusDirectionUp || direction == FocusDirectionDown) && ScrollbarAlwaysOff == verticalMode) return false; LayoutSize size = frame->view()->totalContentsSize(); LayoutSize offset = frame->view()->scrollOffset(); LayoutRect rect = frame->view()->visibleContentRectIncludingScrollbars(); switch (direction) { case FocusDirectionLeft: return offset.width() > 0; case FocusDirectionUp: return offset.height() > 0; case FocusDirectionRight: return rect.width() + offset.width() < size.width(); case FocusDirectionDown: return rect.height() + offset.height() < size.height(); default: ASSERT_NOT_REACHED(); return false; } }
ScrollAnchor::ExamineResult ScrollAnchor::examine( const LayoutObject* candidate) const { if (candidate->isLayoutInline()) return ExamineResult(Continue); // Anonymous blocks are not in the DOM tree and it may be hard for // developers to reason about the anchor node. if (candidate->isAnonymous()) return ExamineResult(Continue); if (!candidate->isText() && !candidate->isBox()) return ExamineResult(Skip); if (!candidateMayMoveWithScroller(candidate, m_scroller)) return ExamineResult(Skip); if (candidate->style()->overflowAnchor() == AnchorNone) return ExamineResult(Skip); LayoutRect candidateRect = relativeBounds(candidate, m_scroller); LayoutRect visibleRect = scrollerLayoutBoxItem(m_scroller).overflowClipRect(LayoutPoint()); bool occupiesSpace = candidateRect.width() > 0 && candidateRect.height() > 0; if (occupiesSpace && visibleRect.intersects(candidateRect)) { return ExamineResult( visibleRect.contains(candidateRect) ? Return : Constrain, cornerToAnchor(m_scroller)); } else { return ExamineResult(Skip); } }
RenderRegion* RenderFlowThread::regionAtBlockOffset(LayoutUnit offset, bool extendLastRegion) const { ASSERT(!m_regionsInvalidated); // If no region matches the position and extendLastRegion is true, it will return // the last valid region. It is similar to auto extending the size of the last region. RenderRegion* lastValidRegion = 0; LayoutUnit accumulatedLogicalHeight = 0; // FIXME: The regions are always in order, optimize this search. for (RenderRegionList::const_iterator iter = m_regionList.begin(); iter != m_regionList.end(); ++iter) { RenderRegion* region = *iter; if (offset <= 0) return region; if (extendLastRegion || region->isRenderRegionSet()) lastValidRegion = region; if (region->hasOverrideHeight() && view()->normalLayoutPhase()) { accumulatedLogicalHeight += region->overrideLogicalContentHeight(); if (offset < accumulatedLogicalHeight) return region; continue; } LayoutRect regionRect = region->flowThreadPortionRect(); accumulatedLogicalHeight += isHorizontalWritingMode() ? regionRect.height() : regionRect.width(); if (offset < accumulatedLogicalHeight) return region; } return lastValidRegion; }
LayoutPoint MultiColumnFragmentainerGroup::visualPointToFlowThreadPoint( const LayoutPoint& visualPoint) const { unsigned columnIndex = columnIndexAtVisualPoint(visualPoint); LayoutRect columnRect = columnRectAt(columnIndex); LayoutPoint localPoint(visualPoint); localPoint.moveBy(-columnRect.location()); // Before converting to a flow thread position, if the block direction // coordinate is outside the column, snap to the bounds of the column, and // reset the inline direction coordinate to the start position in the column. // The effect of this is that if the block position is before the column // rectangle, we'll get to the beginning of this column, while if the block // position is after the column rectangle, we'll get to the beginning of the // next column. if (!m_columnSet.isHorizontalWritingMode()) { LayoutUnit columnStart = m_columnSet.style()->isLeftToRightDirection() ? LayoutUnit() : columnRect.height(); if (localPoint.x() < 0) localPoint = LayoutPoint(LayoutUnit(), columnStart); else if (localPoint.x() > logicalHeight()) localPoint = LayoutPoint(logicalHeight(), columnStart); return LayoutPoint(localPoint.x() + logicalTopInFlowThreadAt(columnIndex), localPoint.y()); } LayoutUnit columnStart = m_columnSet.style()->isLeftToRightDirection() ? LayoutUnit() : columnRect.width(); if (localPoint.y() < 0) localPoint = LayoutPoint(columnStart, LayoutUnit()); else if (localPoint.y() > logicalHeight()) localPoint = LayoutPoint(columnStart, logicalHeight()); return LayoutPoint(localPoint.x(), localPoint.y() + logicalTopInFlowThreadAt(columnIndex)); }
void LayoutTextControlSingleLine::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset) const { LayoutTextControl::paint(paintInfo, paintOffset); if (shouldPaintSelfBlockBackground(paintInfo.phase) && m_shouldDrawCapsLockIndicator) { if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible( paintInfo.context, *this, paintInfo.phase)) return; LayoutRect contentsRect = contentBoxRect(); // Center in the block progression direction. if (isHorizontalWritingMode()) contentsRect.setY((size().height() - contentsRect.height()) / 2); else contentsRect.setX((size().width() - contentsRect.width()) / 2); // Convert the rect into the coords used for painting the content contentsRect.moveBy(paintOffset + location()); IntRect snappedRect = pixelSnappedIntRect(contentsRect); LayoutObjectDrawingRecorder recorder(paintInfo.context, *this, paintInfo.phase, snappedRect); LayoutTheme::theme().painter().paintCapsLockIndicator(*this, paintInfo, snappedRect); } }
bool canScrollInDirection(const LocalFrame* frame, FocusType type) { if (!frame->view()) return false; ScrollbarMode verticalMode; ScrollbarMode horizontalMode; frame->view()->calculateScrollbarModesForLayoutAndSetViewportRenderer(horizontalMode, verticalMode); if ((type == FocusTypeLeft || type == FocusTypeRight) && ScrollbarAlwaysOff == horizontalMode) return false; if ((type == FocusTypeUp || type == FocusTypeDown) && ScrollbarAlwaysOff == verticalMode) return false; LayoutSize size = frame->view()->contentsSize(); LayoutSize offset = frame->view()->scrollOffset(); LayoutRect rect = frame->view()->visibleContentRect(IncludeScrollbars); switch (type) { case FocusTypeLeft: return offset.width() > 0; case FocusTypeUp: return offset.height() > 0; case FocusTypeRight: return rect.width() + offset.width() < size.width(); case FocusTypeDown: return rect.height() + offset.height() < size.height(); default: ASSERT_NOT_REACHED(); return false; } }
bool RenderThemeChromiumSkia::paintSearchFieldResultsDecoration(RenderObject* magnifierObject, const PaintInfo& paintInfo, const IntRect& r) { // Get the renderer of <input> element. if (!magnifierObject->node()) return false; Node* input = magnifierObject->node()->shadowHost(); RenderObject* baseRenderer = input ? input->renderer() : magnifierObject; if (!baseRenderer->isBox()) return false; RenderBox* inputRenderBox = toRenderBox(baseRenderer); LayoutRect inputContentBox = inputRenderBox->contentBoxRect(); // Make sure the scaled decoration stays square and will fit in its parent's box. LayoutUnit magnifierSize = std::min(inputContentBox.width(), std::min<LayoutUnit>(inputContentBox.height(), r.height())); // Calculate decoration's coordinates relative to the input element. // Center the decoration 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 magnifierRect(magnifierObject->offsetFromAncestorContainer(inputRenderBox).width(), inputContentBox.y() + (inputContentBox.height() - magnifierSize + 1) / 2, magnifierSize, magnifierSize); IntRect paintingRect = convertToPaintingRect(inputRenderBox, magnifierObject, magnifierRect, r); DEFINE_STATIC_REF(Image, magnifierImage, (Image::loadPlatformResource("searchMagnifier"))); paintInfo.context->drawImage(magnifierImage, paintingRect); return false; }
LayoutRect RenderReplaced::replacedContentRect(const LayoutSize& intrinsicSize) const { LayoutRect contentRect = contentBoxRect(); if (intrinsicSize.isEmpty()) return contentRect; ObjectFit objectFit = style().objectFit(); LayoutRect finalRect = contentRect; switch (objectFit) { case ObjectFitContain: case ObjectFitScaleDown: case ObjectFitCover: finalRect.setSize(finalRect.size().fitToAspectRatio(intrinsicSize, objectFit == ObjectFitCover ? AspectRatioFitGrow : AspectRatioFitShrink)); if (objectFit != ObjectFitScaleDown || finalRect.width() <= intrinsicSize.width()) break; FALLTHROUGH; case ObjectFitNone: finalRect.setSize(intrinsicSize); break; case ObjectFitFill: break; } LengthPoint objectPosition = style().objectPosition(); LayoutUnit xOffset = minimumValueForLength(objectPosition.x(), contentRect.width() - finalRect.width()); LayoutUnit yOffset = minimumValueForLength(objectPosition.y(), contentRect.height() - finalRect.height()); finalRect.move(xOffset, yOffset); return finalRect; }
Vector<IntRect> RenderTextLineBoxes::absoluteRectsForRange(const RenderText& renderer, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const { Vector<IntRect> rects; for (auto box = m_first; box; box = box->nextTextBox()) { // Note: box->end() returns the index of the last character, not the index past it if (start <= box->start() && box->end() < end) { FloatRect boundaries = box->calculateBoundaries(); if (useSelectionHeight) { LayoutRect selectionRect = box->localSelectionRect(start, end); if (box->isHorizontal()) { boundaries.setHeight(selectionRect.height()); boundaries.setY(selectionRect.y()); } else { boundaries.setWidth(selectionRect.width()); boundaries.setX(selectionRect.x()); } } rects.append(renderer.localToAbsoluteQuad(boundaries, 0, wasFixed).enclosingBoundingBox()); continue; } // FIXME: This code is wrong. It's converting local to absolute twice. http://webkit.org/b/65722 FloatRect rect = localQuadForTextBox(*box, start, end, useSelectionHeight); if (!rect.isZero()) rects.append(renderer.localToAbsoluteQuad(rect, 0, wasFixed).enclosingBoundingBox()); } return rects; }
bool RenderThemeChromiumSkia::paintSearchFieldCancelButton(RenderObject* cancelButtonObject, const PaintInfo& paintInfo, const IntRect& r) { // Get the renderer of <input> element. Node* input = cancelButtonObject->node()->shadowHost(); RenderObject* baseRenderer = input ? input->renderer() : cancelButtonObject; if (!baseRenderer->isBox()) return false; RenderBox* inputRenderBox = toRenderBox(baseRenderer); LayoutRect inputContentBox = inputRenderBox->contentBoxRect(); // Make sure the scaled button stays square and will fit in its parent's box. LayoutUnit cancelButtonSize = std::min(inputContentBox.width(), std::min<LayoutUnit>(inputContentBox.height(), r.height())); // Calculate cancel 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 cancelButtonRect(cancelButtonObject->offsetFromAncestorContainer(inputRenderBox).width(), inputContentBox.y() + (inputContentBox.height() - cancelButtonSize + 1) / 2, cancelButtonSize, cancelButtonSize); IntRect paintingRect = convertToPaintingRect(inputRenderBox, cancelButtonObject, cancelButtonRect, r); static Image* cancelImage = Image::loadPlatformResource("searchCancel").leakRef(); static Image* cancelPressedImage = Image::loadPlatformResource("searchCancelPressed").leakRef(); paintInfo.context->drawImage(isPressed(cancelButtonObject) ? cancelPressedImage : cancelImage, cancelButtonObject->style()->colorSpace(), paintingRect); return false; }
Vector<FloatQuad> RenderTextLineBoxes::absoluteQuadsForRange(const RenderText& renderer, unsigned start, unsigned end, bool useSelectionHeight, bool* wasFixed) const { Vector<FloatQuad> quads; for (auto box = m_first; box; box = box->nextTextBox()) { // Note: box->end() returns the index of the last character, not the index past it if (start <= box->start() && box->end() < end) { FloatRect boundaries = box->calculateBoundaries(); if (useSelectionHeight) { LayoutRect selectionRect = box->localSelectionRect(start, end); if (box->isHorizontal()) { boundaries.setHeight(selectionRect.height()); boundaries.setY(selectionRect.y()); } else { boundaries.setWidth(selectionRect.width()); boundaries.setX(selectionRect.x()); } } quads.append(renderer.localToAbsoluteQuad(boundaries, 0, wasFixed)); continue; } FloatRect rect = localQuadForTextBox(*box, start, end, useSelectionHeight); if (!rect.isZero()) quads.append(renderer.localToAbsoluteQuad(rect, 0, wasFixed)); } return quads; }
IntRect enclosingIntRect(const LayoutRect& rect) { // Empty rects with fractional x, y values turn into non-empty rects when converting to enclosing. // We need to ensure that empty rects stay empty after the conversion, because the selection code expects them to be empty. IntPoint location = flooredIntPoint(rect.minXMinYCorner()); IntPoint maxPoint = IntPoint(rect.width() ? rect.maxX().ceil() : location.x(), rect.height() ? rect.maxY().ceil() : location.y()); return IntRect(location, maxPoint - location); }
// FIXME: Move this somewhere more generic. void PrintTo(const LayoutRect& rect, std::ostream* os) { *os << "LayoutRect(" << rect.x().toFloat() << ", " << rect.y().toFloat() << ", " << rect.width().toFloat() << ", " << rect.height().toFloat() << ")"; }
void LayoutImage::updateInnerContentRect() { // Propagate container size to the image resource. LayoutRect containerRect = replacedContentRect(); IntSize containerSize(containerRect.width(), containerRect.height()); if (!containerSize.isEmpty()) m_imageResource->setContainerSizeForLayoutObject(containerSize); }
// Checks if |node| is offscreen the visible area (viewport) of its container // document. In case it is, one can scroll in direction or take any different // desired action later on. bool hasOffscreenRect(Node* node, FocusType type) { // Get the FrameView in which |node| is (which means the current viewport if |node| // is not in an inner document), so we can check if its content rect is visible // before we actually move the focus to it. FrameView* frameView = node->document().view(); if (!frameView) return true; ASSERT(!frameView->needsLayout()); LayoutRect containerViewportRect = frameView->visibleContentRect(); // We want to select a node if it is currently off screen, but will be // exposed after we scroll. Adjust the viewport to post-scrolling position. // If the container has overflow:hidden, we cannot scroll, so we do not pass direction // and we do not adjust for scrolling. switch (type) { case FocusTypeLeft: containerViewportRect.setX(containerViewportRect.x() - ScrollableArea::pixelsPerLineStep()); containerViewportRect.setWidth(containerViewportRect.width() + ScrollableArea::pixelsPerLineStep()); break; case FocusTypeRight: containerViewportRect.setWidth(containerViewportRect.width() + ScrollableArea::pixelsPerLineStep()); break; case FocusTypeUp: containerViewportRect.setY(containerViewportRect.y() - ScrollableArea::pixelsPerLineStep()); containerViewportRect.setHeight(containerViewportRect.height() + ScrollableArea::pixelsPerLineStep()); break; case FocusTypeDown: containerViewportRect.setHeight(containerViewportRect.height() + ScrollableArea::pixelsPerLineStep()); break; default: break; } RenderObject* render = node->renderer(); if (!render) return true; LayoutRect rect(render->absoluteClippedOverflowRect()); if (rect.isEmpty()) return true; return !containerViewportRect.intersects(rect); }
static bool isValidRasterShapeRect(const LayoutRect& rect) { static double maxImageSizeBytes = 0; if (!maxImageSizeBytes) { size_t size32MaxBytes = 0xFFFFFFFF / 4; // Some platforms don't limit maxDecodedImageBytes. maxImageSizeBytes = std::min(size32MaxBytes, Platform::current()->maxDecodedImageBytes()); } return (rect.width().toFloat() * rect.height().toFloat() * 4.0) < maxImageSizeBytes; }
static LayoutRect computeScrollSnapPortOrAreaRect(const LayoutRect& rect, const LengthBox& insetOrOutsetBox, InsetOrOutset insetOrOutset) { LayoutBoxExtent extents(valueForLength(insetOrOutsetBox.top(), rect.height()), valueForLength(insetOrOutsetBox.right(), rect.width()), valueForLength(insetOrOutsetBox.bottom(), rect.height()), valueForLength(insetOrOutsetBox.left(), rect.width())); auto snapPortOrArea(rect); if (insetOrOutset == InsetOrOutset::Inset) snapPortOrArea.contract(extents); else snapPortOrArea.expand(extents); return snapPortOrArea; }
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; }