void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom) { GraphicsContext* context = paintInfo.context; RenderStyle* style = renderer().style(isFirstLineStyle()); const Font& font = style->font(); FloatPoint boxOrigin = locationIncludingFlipping(); boxOrigin.moveBy(FloatPoint(paintOffset)); if (!isHorizontal()) boxOrigin.move(0, -virtualLogicalHeight()); FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), virtualLogicalHeight())); GraphicsContextStateSaver stateSaver(*context); if (!isHorizontal()) context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clockwise)); FloatPoint textOrigin(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent()); bool isPrinting = renderer().document().printing(); bool haveSelection = !isPrinting && paintInfo.phase != PaintPhaseTextClip && selectionState() != RenderObject::SelectionNone; if (haveSelection) paintSelection(context, boxOrigin, style, font); else if (paintInfo.phase == PaintPhaseSelection) return; TextPainter::Style textStyle = TextPainter::textPaintingStyle(renderer(), style, paintInfo.forceBlackText(), isPrinting); if (haveSelection) textStyle = TextPainter::selectionPaintingStyle(renderer(), true, paintInfo.forceBlackText(), isPrinting, textStyle); TextRun textRun = constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion); TextPainter textPainter(context, font, textRun, textOrigin, boxRect, isHorizontal()); textPainter.paint(0, m_str.length(), m_str.length(), textStyle); paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, style); }
FloatPoint VisualViewport::rootFrameToViewport(const FloatPoint& pointInRootFrame) const { FloatPoint pointInViewport = pointInRootFrame; pointInViewport.moveBy(-location()); pointInViewport.scale(scale(), scale()); return pointInViewport; }
bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) { LayoutPoint adjustedLocation = accumulatedOffset + roundedLayoutPoint(topLeft()); // Hit test the markup box. if (InlineBox* markupBox = this->markupBox()) { RenderStyle* style = renderer().style(isFirstLineStyle()); LayoutUnit mtx = adjustedLocation.x() + m_logicalWidth - markupBox->x(); LayoutUnit mty = adjustedLocation.y() + style->fontMetrics().ascent() - (markupBox->y() + markupBox->renderer().style(isFirstLineStyle())->fontMetrics().ascent()); if (markupBox->nodeAtPoint(request, result, locationInContainer, LayoutPoint(mtx, mty), lineTop, lineBottom)) { renderer().updateHitTestResult(result, locationInContainer.point() - LayoutSize(mtx, mty)); return true; } } FloatPoint boxOrigin = locationIncludingFlipping(); boxOrigin.moveBy(accumulatedOffset); FloatRect boundsRect(boxOrigin, size()); if (visibleToHitTestRequest(request) && boundsRect.intersects(HitTestLocation::rectForPoint(locationInContainer.point(), 0, 0, 0, 0))) { renderer().updateHitTestResult(result, locationInContainer.point() - toLayoutSize(adjustedLocation)); if (!result.addNodeToRectBasedTestResult(renderer().node(), request, locationInContainer, boundsRect)) return true; } return false; }
FloatPoint VisualViewport::viewportCSSPixelsToRootFrame(const FloatPoint& point) const { // Note, this is in CSS Pixels so we don't apply scale. FloatPoint pointInRootFrame = point; pointInRootFrame.moveBy(location()); return pointInRootFrame; }
FloatPoint VisualViewport::viewportToRootFrame(const FloatPoint& pointInViewport) const { FloatPoint pointInRootFrame = pointInViewport; pointInRootFrame.scale(1 / scale(), 1 / scale()); pointInRootFrame.moveBy(location()); return pointInRootFrame; }
bool ScrollingTree::shouldHandleWheelEventSynchronously(const PlatformWheelEvent& wheelEvent) { // This method is invoked by the event handling thread MutexLocker lock(m_mutex); if (m_hasWheelEventHandlers) return true; bool shouldSetLatch = wheelEvent.shouldConsiderLatching(); if (hasLatchedNode() && !shouldSetLatch) return false; if (shouldSetLatch) m_latchedNode = 0; if (!m_nonFastScrollableRegion.isEmpty()) { // FIXME: This is not correct for non-default scroll origins. FloatPoint position = wheelEvent.position(); position.moveBy(m_mainFrameScrollPosition); if (m_nonFastScrollableRegion.contains(roundedIntPoint(position))) return true; } return false; }
void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom) { GraphicsContext* context = paintInfo.context; RenderStyle* style = renderer().style(isFirstLineStyle()); const Font& font = style->font(); FloatPoint boxOrigin = locationIncludingFlipping(); boxOrigin.moveBy(FloatPoint(paintOffset)); if (!isHorizontal()) boxOrigin.move(0, -virtualLogicalHeight()); FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), virtualLogicalHeight())); GraphicsContextStateSaver stateSaver(*context); if (!isHorizontal()) context->concatCTM(InlineTextBox::rotation(boxRect, InlineTextBox::Clockwise)); FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent()); Color styleTextColor = renderer().resolveColor(style, CSSPropertyWebkitTextFillColor); if (styleTextColor != context->fillColor()) context->setFillColor(styleTextColor); if (selectionState() != RenderObject::SelectionNone) { paintSelection(context, boxOrigin, style, font); // Select the correct color for painting the text. Color foreground = paintInfo.forceBlackText() ? Color::black : renderer().selectionForegroundColor(); if (foreground != styleTextColor) context->setFillColor(foreground); } // Text shadows are disabled when printing. http://crbug.com/258321 const ShadowList* shadowList = context->printing() ? 0 : style->textShadow(); bool hasShadow = shadowList; if (hasShadow) { OwnPtr<DrawLooperBuilder> drawLooperBuilder = DrawLooperBuilder::create(); for (size_t i = shadowList->shadows().size(); i--; ) { const ShadowData& shadow = shadowList->shadows()[i]; float shadowX = isHorizontal() ? shadow.x() : shadow.y(); float shadowY = isHorizontal() ? shadow.y() : -shadow.x(); FloatSize offset(shadowX, shadowY); drawLooperBuilder->addShadow(offset, shadow.blur(), shadow.color(), DrawLooperBuilder::ShadowRespectsTransforms, DrawLooperBuilder::ShadowIgnoresAlpha); } drawLooperBuilder->addUnmodifiedContent(); context->setDrawLooper(drawLooperBuilder.release()); } TextRun textRun = RenderBlockFlow::constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion); TextRunPaintInfo textRunPaintInfo(textRun); textRunPaintInfo.bounds = boxRect; context->drawText(font, textRunPaintInfo, textOrigin); // Restore the regular fill color. if (styleTextColor != context->fillColor()) context->setFillColor(styleTextColor); if (hasShadow) context->clearDrawLooper(); paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, style); }
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; }
ScrollResultOneDimensional ScrollAnimator::userScroll( ScrollbarOrientation orientation, ScrollGranularity granularity, float step, float delta) { if (!m_scrollableArea->scrollAnimatorEnabled()) return ScrollAnimatorBase::userScroll(orientation, granularity, step, delta); TRACE_EVENT0("blink", "ScrollAnimator::scroll"); if (granularity == ScrollByPrecisePixel) return ScrollAnimatorBase::userScroll(orientation, granularity, step, delta); float usedPixelDelta = computeDeltaToConsume(orientation, step * delta); FloatPoint pixelDelta = (orientation == VerticalScrollbar ? FloatPoint(0, usedPixelDelta) : FloatPoint(usedPixelDelta, 0)); FloatPoint targetPos = desiredTargetPosition(); targetPos.moveBy(pixelDelta); if (m_animationCurve) { if ((targetPos - m_targetOffset).isZero()) { // Report unused delta only if there is no animation running. See // comment below regarding scroll latching. return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0); } m_targetOffset = targetPos; ASSERT(m_runState == RunState::RunningOnMainThread || m_runState == RunState::RunningOnCompositor || m_runState == RunState::RunningOnCompositorButNeedsUpdate); if (m_runState == RunState::RunningOnCompositor || m_runState == RunState::RunningOnCompositorButNeedsUpdate) { if (registerAndScheduleAnimation()) m_runState = RunState::RunningOnCompositorButNeedsUpdate; return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0); } // Running on the main thread, simply update the target offset instead // of sending to the compositor. m_animationCurve->updateTarget(m_timeFunction() - m_startTime, targetPos); return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0); } if ((targetPos - currentPosition()).isZero()) { // Report unused delta only if there is no animation and we are not // starting one. This ensures we latch for the duration of the // animation rather than animating multiple scrollers at the same time. return ScrollResultOneDimensional(/* didScroll */ false, delta); } m_targetOffset = targetPos; m_startTime = m_timeFunction(); if (registerAndScheduleAnimation()) m_runState = RunState::WaitingToSendToCompositor; return ScrollResultOneDimensional(/* didScroll */ true, /* unusedScrollDelta */ 0); }
bool InlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit /* lineTop */, LayoutUnit /*lineBottom*/) { if (isLineBreak()) return false; FloatPoint boxOrigin = locationIncludingFlipping(); boxOrigin.moveBy(accumulatedOffset); FloatRect rect(boxOrigin, size()); if (m_truncation != cFullTruncation && visibleToHitTestRequest(request) && locationInContainer.intersects(rect)) { renderer().updateHitTestResult(result, flipForWritingMode(locationInContainer.point() - toLayoutSize(accumulatedOffset))); if (!result.addNodeToRectBasedTestResult(renderer().node(), request, locationInContainer, rect)) return true; } return false; }
// Translate local snap coordinates into snap container's scrolling content // coordinate space. static Vector<FloatPoint> localToContainerSnapCoordinates( const LayoutBox& containerBox, const LayoutBox& snapArea) { Vector<FloatPoint> result; LayoutPoint scrollOffset(containerBox.scrollLeft(), containerBox.scrollTop()); const Vector<LengthPoint>& snapCoordinates = snapArea.style()->scrollSnapCoordinate(); for (auto& coordinate : snapCoordinates) { FloatPoint localPoint = floatPointForLengthPoint(coordinate, FloatSize(snapArea.size())); FloatPoint containerPoint = snapArea.localToAncestorPoint(localPoint, &containerBox); containerPoint.moveBy(scrollOffset); result.append(containerPoint); } return result; }
void EllipsisBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom) { GraphicsContext* context = paintInfo.context; RenderStyle* style = renderer().style(isFirstLineStyle()); const Font& font = style->font(); FloatPoint boxOrigin = locationIncludingFlipping(); boxOrigin.moveBy(FloatPoint(paintOffset)); FloatRect boxRect(boxOrigin, LayoutSize(logicalWidth(), virtualLogicalHeight())); GraphicsContextStateSaver stateSaver(*context); FloatPoint textOrigin = FloatPoint(boxOrigin.x(), boxOrigin.y() + font.fontMetrics().ascent()); Color styleTextColor = renderer().resolveColor(style, CSSPropertyWebkitTextFillColor); if (styleTextColor != context->fillColor()) context->setFillColor(styleTextColor); if (selectionState() != RenderObject::SelectionNone) { paintSelection(context, boxOrigin, style, font); // Select the correct color for painting the text. Color foreground = paintInfo.forceBlackText() ? Color::black : renderer().selectionForegroundColor(); if (foreground != styleTextColor) context->setFillColor(foreground); } const ShadowList* shadowList = style->textShadow(); bool hasShadow = shadowList; if (hasShadow) context->setDrawLooper(shadowList->createDrawLooper(DrawLooperBuilder::ShadowIgnoresAlpha)); TextRun textRun = constructTextRun(&renderer(), font, m_str, style, TextRun::AllowTrailingExpansion); TextRunPaintInfo textRunPaintInfo(textRun); textRunPaintInfo.bounds = boxRect; context->drawText(font, textRunPaintInfo, textOrigin); // Restore the regular fill color. if (styleTextColor != context->fillColor()) context->setFillColor(styleTextColor); if (hasShadow) context->clearDrawLooper(); paintMarkupBox(paintInfo, paintOffset, lineTop, lineBottom, style); }
FloatPoint ScrollAnimatorCompositorCoordinator::blinkOffsetFromCompositorOffset(FloatPoint offset) { offset.moveBy(-scrollableArea()->scrollOrigin()); return offset; }
bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const { if (!renderer()) return false; // What is this code really trying to do? RenderObject* o = renderer(); RenderObject* p = o; if (!o->isInline() || o->isReplaced()) { point = o->localToAbsolute(FloatPoint(), UseTransforms); return true; } // find the next text/image child, to get a position while (o) { p = o; if (o->firstChild()) o = o->firstChild(); else if (o->nextSibling()) o = o->nextSibling(); else { RenderObject* next = 0; while (!next && o->parent()) { o = o->parent(); next = o->nextSibling(); } o = next; if (!o) break; } ASSERT(o); if (!o->isInline() || o->isReplaced()) { point = o->localToAbsolute(FloatPoint(), UseTransforms); return true; } if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) { // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor } else if ((o->isText() && !o->isBR()) || o->isReplaced()) { point = FloatPoint(); if (o->isText() && toRenderText(o)->firstTextBox()) { point.move(toRenderText(o)->linesBoundingBox().x(), toRenderText(o)->firstTextBox()->root()->lineTop()); } else if (o->isBox()) { RenderBox* box = toRenderBox(o); point.moveBy(box->location()); } point = o->container()->localToAbsolute(point, UseTransforms); return true; } } // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be // at the end of the document. Scroll to the bottom. FIXME: who said anything about scrolling? if (!o && document().view()) { point = FloatPoint(0, document().view()->contentsHeight()); return true; } return false; }