void computePageRectsForFrame(Frame* frame, const IntRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, Vector<IntRect>& pages, int& outPageHeight) { ASSERT(frame); pages.clear(); outPageHeight = 0; if (!frame->document() || !frame->view() || !frame->document()->renderer()) return; RenderView* root = toRenderView(frame->document()->renderer()); if (!root) { LOG_ERROR("document to be printed has no renderer"); return; } if (userScaleFactor <= 0) { LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor); return; } float ratio = (float)printRect.height() / (float)printRect.width(); float pageWidth = (float) root->rightLayoutOverflow(); float pageHeight = pageWidth * ratio; outPageHeight = (int) pageHeight; // this is the height of the page adjusted by margins pageHeight -= (headerHeight + footerHeight); if (pageHeight <= 0) { LOG_ERROR("pageHeight has bad value %.2f", pageHeight); return; } float currPageHeight = pageHeight / userScaleFactor; float docHeight = root->layer()->height(); float docWidth = root->layer()->width(); float currPageWidth = pageWidth / userScaleFactor; // always return at least one page, since empty files should print a blank page float printedPagesHeight = 0.0; do { float proposedBottom = min(docHeight, printedPagesHeight + pageHeight); frame->view()->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight); currPageHeight = max(1.0f, proposedBottom - printedPagesHeight); pages.append(IntRect(0, printedPagesHeight, currPageWidth, currPageHeight)); printedPagesHeight += currPageHeight; } while (printedPagesHeight < docHeight); }
void ScrollView::scrollTo(const IntSize& newOffset) { IntSize scrollDelta = newOffset - m_scrollOffset; if (scrollDelta == IntSize()) return; m_scrollOffset = newOffset; #if PLATFORM(ANDROID) if (parent()) { FrameView* frameView = this->frameView(); // IFrames are composited on a layer, we do not need to repaint them // when scrolling if (frameView) { RenderView* renderer = frameView->frame()->contentRenderer(); if (renderer) { RenderLayer* layer = renderer->layer(); if (layer->backing()) { GraphicsLayerAndroid* backing = static_cast<GraphicsLayerAndroid*>( layer->backing()->graphicsLayer()); backing->updateScrollOffset(); } } return; } } #endif if (scrollbarsSuppressed()) return; repaintFixedElementsAfterScrolling(); scrollContents(scrollDelta); }
void write(TextStream& ts, const RenderObject& o, int indent) { #if ENABLE(SVG) if (o.isRenderPath()) { write(ts, *toRenderPath(&o), indent); return; } if (o.isSVGContainer()) { writeSVGContainer(ts, o, indent); return; } if (o.isSVGRoot()) { write(ts, *toRenderSVGRoot(&o), indent); return; } if (o.isSVGText()) { if (!o.isText()) writeSVGText(ts, *toRenderBlock(&o), indent); else writeSVGInlineText(ts, *toRenderText(&o), indent); return; } if (o.isSVGImage()) { writeSVGImage(ts, *toRenderImage(&o), indent); return; } #endif writeIndent(ts, indent); ts << o << "\n"; if (o.isText() && !o.isBR()) { const RenderText& text = *toRenderText(&o); for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) { writeIndent(ts, indent + 1); writeTextRun(ts, text, *box); } } for (RenderObject* child = o.firstChild(); child; child = child->nextSibling()) { if (child->hasLayer()) continue; write(ts, *child, indent + 1); } if (o.isWidget()) { Widget* widget = toRenderWidget(&o)->widget(); if (widget && widget->isFrameView()) { FrameView* view = static_cast<FrameView*>(widget); RenderView* root = view->frame()->contentRenderer(); if (root) { view->layout(); RenderLayer* l = root->layer(); if (l) writeLayers(ts, l, l, IntRect(l->x(), l->y(), l->width(), l->height()), indent + 1); } } } }
void RenderLayerScrollableArea::paintOverflowControls(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect, bool paintingOverlayControls) { // Don't do anything if we have no overflow. if (!box().hasOverflowClip()) return; IntPoint adjustedPaintOffset = paintOffset; if (paintingOverlayControls) adjustedPaintOffset = m_cachedOverlayScrollbarOffset; // Move the scrollbar widgets if necessary. We normally move and resize widgets during layout, // but sometimes widgets can move without layout occurring (most notably when you scroll a // document that contains fixed positioned elements). positionOverflowControls(toIntSize(adjustedPaintOffset)); // Overlay scrollbars paint in a second pass through the layer tree so that they will paint // on top of everything else. If this is the normal painting pass, paintingOverlayControls // will be false, and we should just tell the root layer that there are overlay scrollbars // that need to be painted. That will cause the second pass through the layer tree to run, // and we'll paint the scrollbars then. In the meantime, cache tx and ty so that the // second pass doesn't need to re-enter the RenderTree to get it right. if (hasOverlayScrollbars() && !paintingOverlayControls) { m_cachedOverlayScrollbarOffset = paintOffset; IntRect localDamgeRect = damageRect; localDamgeRect.moveBy(-paintOffset); if (!overflowControlsIntersectRect(localDamgeRect)) return; RenderView* renderView = box().view(); RenderLayer* paintingRoot = layer()->enclosingLayerWithCompositedLayerMapping(IncludeSelf); if (!paintingRoot) paintingRoot = renderView->layer(); paintingRoot->setContainsDirtyOverlayScrollbars(true); return; } // This check is required to avoid painting custom CSS scrollbars twice. if (paintingOverlayControls && !hasOverlayScrollbars()) return; // Now that we're sure the scrollbars are in the right place, paint them. if (m_hBar) m_hBar->paint(context, damageRect); if (m_vBar) m_vBar->paint(context, damageRect); }
void FrameView::paint(GraphicsContext* context, const IntRect& rect) { #ifndef NDEBUG bool fillWithRed; if (isTransparent()) fillWithRed = false; // Transparent, don't fill with red. else fillWithRed = true; if (fillWithRed) context->fillRect(rect, Color(0xFF, 0, 0)); #endif RenderView* renderView = this->renderView(); if (!renderView) { WTF_LOG_ERROR("called FrameView::paint with nil renderer"); return; } RELEASE_ASSERT(!needsLayout()); bool isTopLevelPainter = !s_inPaintContents; s_inPaintContents = true; FontCachePurgePreventer fontCachePurgePreventer; ASSERT(!m_isPainting); m_isPainting = true; #if ENABLE(ASSERT) renderView->assertSubtreeIsLaidOut(); RenderObject::SetLayoutNeededForbiddenScope forbidSetNeedsLayout(*renderView); #endif LayerPaintingInfo paintingInfo(renderView->layer(), pixelSnappedIntRect(renderView->viewRect()), LayoutSize()); renderView->paintLayer(context, paintingInfo); m_isPainting = false; m_lastPaintTime = currentTime(); if (isTopLevelPainter) { // Everything that happens after paintContents completions is considered // to be part of the next frame. s_currentFrameTimeStamp = currentTime(); s_inPaintContents = false; } }
void WebPage::gestureWillBegin(const WebCore::IntPoint& point, bool& canBeginPanning) { m_gestureReachedScrollingLimit = false; bool hitScrollbar = false; HitTestRequest request(HitTestRequest::ReadOnly); for (Frame* childFrame = m_page->mainFrame(); childFrame; childFrame = EventHandler::subframeForTargetNode(m_gestureTargetNode.get())) { ScrollView* scollView = childFrame->view(); if (!scollView) break; RenderView* renderView = childFrame->document()->renderView(); if (!renderView) break; RenderLayer* layer = renderView->layer(); if (!layer) break; HitTestResult result = scollView->windowToContents(point); layer->hitTest(request, result); m_gestureTargetNode = result.innerNode(); if (!hitScrollbar) hitScrollbar = result.scrollbar(); } if (hitScrollbar) { canBeginPanning = false; return; } if (!m_gestureTargetNode) { canBeginPanning = false; return; } for (RenderObject* renderer = m_gestureTargetNode->renderer(); renderer; renderer = renderer->parent()) { if (renderer->isBox() && toRenderBox(renderer)->canBeScrolledAndHasScrollableArea()) { canBeginPanning = true; return; } } canBeginPanning = false; }
void PrintContext::computePageRects(const FloatRect& printRect, float headerHeight, float footerHeight, float userScaleFactor, float& outPageHeight) { m_pageRects.clear(); outPageHeight = 0; if (!m_frame->document() || !m_frame->view() || !m_frame->document()->renderer()) return; RenderView* root = static_cast<RenderView*>(m_frame->document()->renderer()); if (!root) { LOG_ERROR("document to be printed has no renderer"); return; } if (userScaleFactor <= 0) { LOG_ERROR("userScaleFactor has bad value %.2f", userScaleFactor); return; } float ratio = printRect.height() / printRect.width(); float pageWidth = (float)root->docWidth(); float pageHeight = pageWidth * ratio; outPageHeight = pageHeight; // this is the height of the page adjusted by margins pageHeight -= headerHeight + footerHeight; if (pageHeight <= 0) { LOG_ERROR("pageHeight has bad value %.2f", pageHeight); return; } float currPageHeight = pageHeight / userScaleFactor; float docHeight = root->layer()->height(); float currPageWidth = pageWidth / userScaleFactor; // always return at least one page, since empty files should print a blank page float printedPagesHeight = 0.0; do { float proposedBottom = std::min(docHeight, printedPagesHeight + pageHeight); m_frame->adjustPageHeight(&proposedBottom, printedPagesHeight, proposedBottom, printedPagesHeight); currPageHeight = max(1.0f, proposedBottom - printedPagesHeight); m_pageRects.append(IntRect(0, (int)printedPagesHeight, (int)currPageWidth, (int)currPageHeight)); printedPagesHeight += currPageHeight; } while (printedPagesHeight < docHeight); }
PassRefPtr<WebRenderLayer> WebRenderLayer::create(WebPage* page) { Frame* mainFrame = page->mainFrame(); if (!mainFrame) return 0; if (!mainFrame->loader().client().hasHTMLView()) return 0; RenderView* contentRenderer = mainFrame->contentRenderer(); if (!contentRenderer) return 0; RenderLayer* rootLayer = contentRenderer->layer(); if (!rootLayer) return 0; return adoptRef(new WebRenderLayer(rootLayer)); }
void write(TextStream& ts, const RenderObject& o, int indent, RenderAsTextBehavior behavior) { #if ENABLE(SVG) if (o.isSVGShape()) { write(ts, *toRenderSVGShape(&o), indent); return; } if (o.isSVGGradientStop()) { writeSVGGradientStop(ts, *toRenderSVGGradientStop(&o), indent); return; } if (o.isSVGResourceContainer()) { writeSVGResourceContainer(ts, o, indent); return; } if (o.isSVGContainer()) { writeSVGContainer(ts, o, indent); return; } if (o.isSVGRoot()) { write(ts, *toRenderSVGRoot(&o), indent); return; } if (o.isSVGText()) { writeSVGText(ts, *toRenderSVGText(&o), indent); return; } if (o.isSVGInlineText()) { writeSVGInlineText(ts, *toRenderSVGInlineText(&o), indent); return; } if (o.isSVGImage()) { writeSVGImage(ts, *toRenderSVGImage(&o), indent); return; } #endif writeIndent(ts, indent); RenderTreeAsText::writeRenderObject(ts, o, behavior); ts << "\n"; if (o.isText() && !o.isBR()) { const RenderText& text = *toRenderText(&o); for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) { writeIndent(ts, indent + 1); writeTextRun(ts, text, *box); } } for (RenderObject* child = o.firstChild(); child; child = child->nextSibling()) { if (child->hasLayer()) continue; write(ts, *child, indent + 1, behavior); } if (o.isWidget()) { Widget* widget = toRenderWidget(&o)->widget(); if (widget && widget->isFrameView()) { FrameView* view = static_cast<FrameView*>(widget); RenderView* root = view->frame()->contentRenderer(); if (root) { view->layout(); RenderLayer* l = root->layer(); if (l) writeLayers(ts, l, l, l->rect(), indent + 1, behavior); } } } }