void ScrollableAreaPainter::paintScrollCorner(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect) { IntRect absRect = m_scrollableArea.scrollCornerRect(); if (absRect.isEmpty()) return; absRect.moveBy(paintOffset); if (m_scrollableArea.scrollCorner()) { if (!absRect.intersects(damageRect)) return; ScrollbarPainter::paintIntoRect(m_scrollableArea.scrollCorner(), context, paintOffset, LayoutRect(absRect)); return; } if (!RuntimeEnabledFeatures::slimmingPaintEnabled() && !absRect.intersects(damageRect)) return; // We don't want to paint white if we have overlay scrollbars, since we need // to see what is behind it. if (m_scrollableArea.hasOverlayScrollbars()) return; if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*context, m_scrollableArea.box(), DisplayItem::ScrollbarCorner)) return; LayoutObjectDrawingRecorder recorder(*context, m_scrollableArea.box(), DisplayItem::ScrollbarCorner, absRect); context->fillRect(absRect, Color::white); }
void PlatformScrollbar::paintThumb(GraphicsContext* context, const IntRect& rect, const IntRect& damageRect) const { if (!damageRect.intersects(rect)) return; int state; if (!isEnabled()) state = TS_DISABLED; else if (m_pressedPart == ThumbPart) state = TS_ACTIVE; // Thumb always stays active once pressed. else if (m_hoveredPart == ThumbPart) state = TS_HOVER; else state = TS_NORMAL; bool alphaBlend = false; if (scrollbarTheme) alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, m_orientation == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state); HDC hdc = context->getWindowsContext(rect, alphaBlend); RECT themeRect(rect); if (scrollbarTheme) { DrawThemeBackground(scrollbarTheme, hdc, m_orientation == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state, &themeRect, 0); IntRect gripper; if (damageRect.intersects(gripper = gripperRect(rect))) paintGripper(hdc, gripper); } else ::DrawEdge(hdc, &themeRect, EDGE_RAISED, BF_RECT | BF_MIDDLE); context->releaseWindowsContext(hdc, rect, alphaBlend); }
void ScrollView::paint(GraphicsContext* context, const IntRect& rect) { if (platformWidget()) { Widget::paint(context, rect); return; } if (context->paintingDisabled() && !context->updatingControlTints()) return; notifyPageThatContentAreaWillPaint(); // If we encounter any overlay scrollbars as we paint, this will be set to true. m_containsScrollableAreaWithOverlayScrollbars = false; IntRect documentDirtyRect = rect; documentDirtyRect.intersect(frameRect()); context->save(); context->translate(x(), y()); documentDirtyRect.move(-x(), -y()); if (!paintsEntireContents()) { context->translate(-scrollX(), -scrollY()); documentDirtyRect.move(scrollX(), scrollY()); context->clip(visibleContentRect()); } paintContents(context, documentDirtyRect); context->restore(); IntRect horizontalOverhangRect; IntRect verticalOverhangRect; calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect); if (rect.intersects(horizontalOverhangRect) || rect.intersects(verticalOverhangRect)) paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect, rect); // Now paint the scrollbars. if (!m_scrollbarsSuppressed && (m_horizontalScrollbar || m_verticalScrollbar)) { context->save(); IntRect scrollViewDirtyRect = rect; scrollViewDirtyRect.intersect(frameRect()); context->translate(x(), y()); scrollViewDirtyRect.move(-x(), -y()); paintScrollbars(context, scrollViewDirtyRect); context->restore(); } // Paint the panScroll Icon if (m_drawPanScrollIcon) paintPanScrollIcon(context); }
void FramePainter::calculateAndPaintOverhangAreas(GraphicsContext* context, const IntRect& dirtyRect) { IntRect horizontalOverhangRect; IntRect verticalOverhangRect; m_frameView.calculateOverhangAreasForPainting(horizontalOverhangRect, verticalOverhangRect); if (dirtyRect.intersects(horizontalOverhangRect) || dirtyRect.intersects(verticalOverhangRect)) paintOverhangAreas(context, horizontalOverhangRect, verticalOverhangRect, dirtyRect); }
bool SnapToLinesLayouter::isOverlapping() const { IntRect cueBoxRect = m_cueBox.absoluteBoundingBoxRect(); for (LayoutObject* box = m_cueBox.previousSibling(); box; box = box->previousSibling()) { IntRect boxRect = box->absoluteBoundingBoxRect(); if (cueBoxRect.intersects(boxRect)) return true; } if (cueBoxRect.intersects(m_controlsRect)) return true; return false; }
void PlatformScrollbar::paintButton(GraphicsContext* context, const IntRect& rect, bool start, const IntRect& damageRect) const { if (!SafariThemeLibrary()) return; IntRect paintRect = buttonRepaintRect(rect, m_orientation, controlSize(), start); if (!damageRect.intersects(paintRect)) return; ThemePart part; ThemeControlState state = 0; if (m_client->isActive()) state |= ActiveState; if (m_orientation == HorizontalScrollbar) part = start ? ScrollLeftArrowPart : ScrollRightArrowPart; else part = start ? ScrollUpArrowPart : ScrollDownArrowPart; if (isEnabled()) state |= EnabledState; if ((m_pressedPart == BackButtonPart && start) || (m_pressedPart == ForwardButtonPart && !start)) state |= PressedState; paintThemePart(part, context->platformContext(), paintRect, controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize, state); }
void Frame::scrollOverflowLayer(RenderLayer* layer, const IntRect& visibleRect, const IntRect& exposeRect) { if (!layer) return; RenderBox* box = layer->renderBox(); if (!box) return; if (visibleRect.intersects(exposeRect)) return; // FIXME: Why isn't this just calling RenderLayer::scrollRectToVisible()? ScrollOffset scrollOffset = layer->scrollOffset(); int exposeLeft = exposeRect.x(); int exposeRight = exposeLeft + exposeRect.width(); int clientWidth = roundToInt(box->clientWidth()); if (exposeLeft <= 0) scrollOffset.setX(std::max(0, scrollOffset.x() + exposeLeft - clientWidth / 2)); else if (exposeRight >= clientWidth) scrollOffset.setX(std::min(box->scrollWidth() - clientWidth, scrollOffset.x() + clientWidth / 2)); int exposeTop = exposeRect.y(); int exposeBottom = exposeTop + exposeRect.height(); int clientHeight = roundToInt(box->clientHeight()); if (exposeTop <= 0) scrollOffset.setY(std::max(0, scrollOffset.y() + exposeTop - clientHeight / 2)); else if (exposeBottom >= clientHeight) scrollOffset.setY(std::min(box->scrollHeight() - clientHeight, scrollOffset.y() + clientHeight / 2)); layer->scrollToOffset(scrollOffset); selection().setCaretRectNeedsUpdate(); selection().updateAppearance(); }
// Subtracts out the intersection of |a| and |b| from |a|, assuming |b| fully // overlaps with |a| in either the x- or y-direction. If there is no full // overlap, then |a| is returned. static IntRect subtractIntersection(const IntRect& a, const IntRect& b) { // boundary cases: if (!a.intersects(b)) return a; if (b.contains(a)) return IntRect(); int rx = a.x(); int ry = a.y(); int rr = a.maxX(); int rb = a.maxY(); if (b.y() <= a.y() && b.maxY() >= a.maxY()) { // complete intersection in the y-direction if (b.x() <= a.x()) rx = b.maxX(); else rr = b.x(); } else if (b.x() <= a.x() && b.maxX() >= a.maxX()) { // complete intersection in the x-direction if (b.y() <= a.y()) ry = b.maxY(); else rb = b.y(); } return IntRect(rx, ry, rr - rx, rb - ry); }
void PlatformScrollbar::defaultpaint(GraphicsContext* context, const IntRect& damageRect) { if (context->updatingControlTints()) { invalidate(); return; } if (context->paintingDisabled()) return; // Don't paint anything if the scrollbar doesn't intersect the damage rect. if (!frameGeometry().intersects(damageRect)) return; IntRect track = trackRect(); paintTrack(context, track, true, damageRect); if (hasButtons()) { paintButton(context, backButtonRect(), true, damageRect); paintButton(context, forwardButtonRect(), false, damageRect); } if (hasThumb() && damageRect.intersects(track)) { IntRect startTrackRect, thumbRect, endTrackRect; splitTrack(track, startTrackRect, thumbRect, endTrackRect); paintThumb(context, thumbRect, damageRect); } Widget::paint(context, damageRect); }
void Scrollbar::setFrameRect(const IntRect& rect) { // Get our window resizer rect and see if we overlap. Adjust to avoid the overlap // if necessary. IntRect adjustedRect(rect); bool overlapsResizer = false; ScrollView* view = parent(); if (view && !rect.isEmpty() && !view->windowResizerRect().isEmpty()) { IntRect resizerRect = view->convertFromContainingWindow(view->windowResizerRect()); if (rect.intersects(resizerRect)) { if (orientation() == HorizontalScrollbar) { int overlap = rect.maxX() - resizerRect.x(); if (overlap > 0 && resizerRect.maxX() >= rect.maxX()) { adjustedRect.setWidth(rect.width() - overlap); overlapsResizer = true; } } else { int overlap = rect.maxY() - resizerRect.y(); if (overlap > 0 && resizerRect.maxY() >= rect.maxY()) { adjustedRect.setHeight(rect.height() - overlap); overlapsResizer = true; } } } } if (overlapsResizer != m_overlapsResizer) { m_overlapsResizer = overlapsResizer; if (view) view->adjustScrollbarsAvoidingResizerCount(m_overlapsResizer ? 1 : -1); } Widget::setFrameRect(adjustedRect); }
void Frame::scrollOverflowLayer(RenderLayer* layer, const IntRect& visibleRect, const IntRect& exposeRect) { if (!layer) return; RenderBox* box = layer->renderBox(); if (!box) return; if (visibleRect.intersects(exposeRect)) return; int x = layer->scrollXOffset(); int exposeLeft = exposeRect.x(); int exposeRight = exposeLeft + exposeRect.width(); int clientWidth = roundToInt(box->clientWidth()); if (exposeLeft <= 0) x = std::max(0, x + exposeLeft - clientWidth / 2); else if (exposeRight >= clientWidth) x = std::min(box->scrollWidth() - clientWidth, x + clientWidth / 2); int y = layer->scrollYOffset(); int exposeTop = exposeRect.y(); int exposeBottom = exposeTop + exposeRect.height(); int clientHeight = roundToInt(box->clientHeight()); if (exposeTop <= 0) y = std::max(0, y + exposeTop - clientHeight / 2); else if (exposeBottom >= clientHeight) y = std::min(box->scrollHeight() - clientHeight, y + clientHeight / 2); layer->scrollToOffset(IntSize(x, y)); selection().setCaretRectNeedsUpdate(); selection().updateAppearance(); }
bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty) { tx += m_x; ty += m_y; // Hit test the markup box. if (m_markupBox) { RenderStyle* style = m_renderer->style(m_firstLine); int mtx = tx + m_width - m_markupBox->x(); int mty = ty + style->font().ascent() - (m_markupBox->y() + m_markupBox->renderer()->style(m_firstLine)->font().ascent()); if (m_markupBox->nodeAtPoint(request, result, x, y, mtx, mty)) { renderer()->updateHitTestResult(result, IntPoint(x - mtx, y - mty)); return true; } } IntRect boundsRect = IntRect(tx, ty, m_width, m_height); if (visibleToHitTesting() && boundsRect.intersects(result.rectFromPoint(x, y))) { renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, boundsRect)) return true; } return false; }
void PlatformScrollbar::setRect(const IntRect& rect) { // Get our window resizer rect and see if we overlap. Adjust to avoid the overlap // if necessary. IntRect adjustedRect(rect); if (parent() && parent()->isFrameView()) { bool overlapsResizer = false; FrameView* view = static_cast<FrameView*>(parent()); IntRect resizerRect = view->windowResizerRect(); resizerRect.setLocation(view->convertFromContainingWindow(resizerRect.location())); if (rect.intersects(resizerRect)) { if (orientation() == HorizontalScrollbar) { int overlap = rect.right() - resizerRect.x(); if (overlap > 0 && resizerRect.right() >= rect.right()) { adjustedRect.setWidth(rect.width() - overlap); overlapsResizer = true; } } else { int overlap = rect.bottom() - resizerRect.y(); if (overlap > 0 && resizerRect.bottom() >= rect.bottom()) { adjustedRect.setHeight(rect.height() - overlap); overlapsResizer = true; } } } if (overlapsResizer != m_overlapsResizer) { m_overlapsResizer = overlapsResizer; view->adjustOverlappingScrollbarCount(m_overlapsResizer ? 1 : -1); } } setFrameGeometry(adjustedRect); }
double TiledBackingStore::tileDistance(const IntRect& viewport, const Tile::Coordinate& tileCoordinate) const { if (viewport.intersects(tileRectForCoordinate(tileCoordinate))) return 0; IntPoint viewCenter = viewport.location() + IntSize(viewport.width() / 2, viewport.height() / 2); Tile::Coordinate centerCoordinate = tileCoordinateForPoint(viewCenter); return std::max(abs(centerCoordinate.y() - tileCoordinate.y()), abs(centerCoordinate.x() - tileCoordinate.x())); }
void PlatformScrollbar::paintThumb(GraphicsContext* context, const IntRect& rect, const IntRect& damageRect) const { if (!damageRect.intersects(rect)) return; context->save(); paintRectWithBorder(context, rect, Color::gray, Color::lightGray); context->restore(); }
void PlatformScrollbar::paintButton(GraphicsContext* context, const IntRect& rect, bool start, const IntRect& damageRect) const { IntRect paintRect = buttonRepaintRect(rect, m_orientation, controlSize(), start); if (!damageRect.intersects(paintRect)) return; context->save(); // Draw the square with a border. context->setStrokeStyle(SolidStroke); paintRectWithBorder(context, rect, Color::gray, Color::lightGray); // Draw the arrow in one of four directions. EA::Raster::Orientation o; IntRect inner( rect.x()+cArrowInset, rect.y()+cArrowInset, rect.width()-(2*cArrowInset), rect.height()-(2*cArrowInset) ); int arrowX; int arrowY; if (start) // If the button is the up or left button as opposed to the down or right button... { if (m_orientation == HorizontalScrollbar) // If we are drawing a [<] arrow... { o = EA::Raster::kOLeft; arrowX = inner.x() + 1; arrowY = (inner.bottom() + inner.y()) / 2; } else // else we are drawing a [^] arrow... { o = EA::Raster::kOUp; arrowX = (inner.x() + inner.right()) / 2; arrowY = inner.y() + 1; } } else { if (m_orientation == HorizontalScrollbar) // If we are drawing a [>] arrow... { o = EA::Raster::kORight; arrowX = inner.right() - 1; arrowY = (inner.bottom() + inner.y()) / 2; } else // Else we are drawing a [v] arrow... { o = EA::Raster::kODown; arrowX = (inner.x() + inner.right()) / 2; arrowY = inner.bottom() - 1; } } EA::Raster::Surface* pSurface = context->platformContext(); EA::Raster::SimpleTriangle(pSurface, arrowX, arrowY, 3, o, Color(0xff000000)); // To consider: Make this color configurable or make it it match the text color or something. context->restore(); }
void SmartClip::collectOverlappingChildNodes(Node* parentNode, const IntRect& cropRect, WillBeHeapVector<RawPtrWillBeMember<Node> >& hitNodes) { if (!parentNode) return; IntRect resizedCropRect = parentNode->document().view()->windowToContents(cropRect); for (Node* child = parentNode->firstChild(); child; child = child->nextSibling()) { IntRect childRect = child->pixelSnappedBoundingBox(); if (resizedCropRect.intersects(childRect)) hitNodes.append(child); } }
bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const IntRect& layerBounds) { RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end(); for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) { const IntRect& bounds = it->second; if (layerBounds.intersects(bounds)) return true; } return false; }
void TextureMapperLayer::paintUsingOverlapRegions(const TextureMapperPaintOptions& options) { Region overlapRegion; Region nonOverlapRegion; computeOverlapRegions(overlapRegion, nonOverlapRegion, ResolveSelfOverlapAlways); if (overlapRegion.isEmpty()) { paintSelfAndChildrenWithReplica(options); return; } // Having both overlap and non-overlap regions carries some overhead. Avoid it if the overlap area // is big anyway. if (overlapRegion.bounds().size().area() > nonOverlapRegion.bounds().size().area()) { overlapRegion.unite(nonOverlapRegion); nonOverlapRegion = Region(); } nonOverlapRegion.translate(options.offset); Vector<IntRect> rects = nonOverlapRegion.rects(); for (size_t i = 0; i < rects.size(); ++i) { IntRect rect = rects[i]; if (!rect.intersects(options.textureMapper->clipBounds())) continue; options.textureMapper->beginClip(TransformationMatrix(), rects[i]); paintSelfAndChildrenWithReplica(options); options.textureMapper->endClip(); } rects = overlapRegion.rects(); static const size_t OverlapRegionConsolidationThreshold = 4; if (nonOverlapRegion.isEmpty() && rects.size() > OverlapRegionConsolidationThreshold) { rects.clear(); rects.append(overlapRegion.bounds()); } IntSize maxTextureSize = options.textureMapper->maxTextureSize(); IntRect adjustedClipBounds(options.textureMapper->clipBounds()); adjustedClipBounds.move(-options.offset); for (size_t i = 0; i < rects.size(); ++i) { IntRect rect = rects[i]; for (int x = rect.x(); x < rect.maxX(); x += maxTextureSize.width()) { for (int y = rect.y(); y < rect.maxY(); y += maxTextureSize.height()) { IntRect tileRect(IntPoint(x, y), maxTextureSize); tileRect.intersect(rect); if (!tileRect.intersects(adjustedClipBounds)) continue; paintWithIntermediateSurface(options, tileRect); } } } }
void LayerRendererChromium::drawLayer(CCLayerImpl* layer, RenderSurfaceChromium* targetSurface) { if (layer->renderSurface() && layer->renderSurface() != targetSurface) { layer->renderSurface()->draw(layer->getDrawRect()); return; } if (!layer->drawsContent()) return; if (layer->bounds().isEmpty()) { layer->unreserveContentsTexture(); return; } setScissorToRect(layer->scissorRect()); IntRect targetSurfaceRect = m_currentRenderSurface ? m_currentRenderSurface->contentRect() : m_defaultRenderSurface->contentRect(); IntRect scissorRect = layer->scissorRect(); if (!scissorRect.isEmpty()) targetSurfaceRect.intersect(scissorRect); // Check if the layer falls within the visible bounds of the page. IntRect layerRect = layer->getDrawRect(); bool isLayerVisible = targetSurfaceRect.intersects(layerRect); if (!isLayerVisible) { layer->unreserveContentsTexture(); return; } // FIXME: Need to take into account the commulative render surface transforms all the way from // the default render surface in order to determine visibility. TransformationMatrix combinedDrawMatrix = (layer->targetRenderSurface() ? layer->targetRenderSurface()->drawTransform().multiply(layer->drawTransform()) : layer->drawTransform()); if (!layer->doubleSided()) { FloatRect layerRect(FloatPoint(0, 0), FloatSize(layer->bounds())); FloatQuad mappedLayer = combinedDrawMatrix.mapQuad(FloatQuad(layerRect)); FloatSize horizontalDir = mappedLayer.p2() - mappedLayer.p1(); FloatSize verticalDir = mappedLayer.p4() - mappedLayer.p1(); FloatPoint3D xAxis(horizontalDir.width(), horizontalDir.height(), 0); FloatPoint3D yAxis(verticalDir.width(), verticalDir.height(), 0); FloatPoint3D zAxis = xAxis.cross(yAxis); if (zAxis.z() < 0) { layer->unreserveContentsTexture(); return; } } layer->draw(targetSurfaceRect); // Draw the debug border if there is one. layer->drawDebugBorder(); }
void Scrollbar::paint(GraphicsContext* context, const IntRect& damageRect) { if (!frameRect().intersects(damageRect)) return; IntRect startTrackRect; IntRect thumbRect; IntRect endTrackRect; splitTrack(trackRect(), startTrackRect, thumbRect, endTrackRect); if (damageRect.intersects(thumbRect)) paintThumb(context, thumbRect); }
void TileGrid::setNeedsDisplay() { for (auto& entry : m_tiles) { TileInfo& tileInfo = entry.value; IntRect tileRect = rectForTileIndex(entry.key); if (tileRect.intersects(m_primaryTileCoverageRect) && tileInfo.layer->superlayer()) tileInfo.layer->setNeedsDisplay(); else tileInfo.hasStaleContent = true; } }
void PlatformScrollbar::paintTrack(GraphicsContext* context, const IntRect& rect, bool start, const IntRect& damageRect) const { IntRect paintRect = hasButtons() ? trackRepaintRect(rect, m_orientation, controlSize()) : rect; if (!damageRect.intersects(paintRect)) return; context->save(); context->drawRect(rect); context->fillRect(rect, Color::darkGray); context->restore(); }
double TiledBackingStore::tileDistance(const IntRect& viewport, const Tile::Coordinate& tileCoordinate) const { if (viewport.intersects(tileRectForCoordinate(tileCoordinate))) return 0; IntPoint viewCenter = viewport.location() + IntSize(viewport.width() / 2, viewport.height() / 2); Tile::Coordinate centerCoordinate = tileCoordinateForPoint(viewCenter); // Manhattan distance, biased so that vertical distances are shorter. const double horizontalBias = 1.3; return abs(centerCoordinate.y() - tileCoordinate.y()) + horizontalBias * abs(centerCoordinate.x() - tileCoordinate.x()); }
void ScrollableAreaPainter::paintResizer(GraphicsContext* context, const IntPoint& paintOffset, const IntRect& damageRect) { if (m_scrollableArea.box().style()->resize() == RESIZE_NONE) return; IntRect absRect = m_scrollableArea.resizerCornerRect(m_scrollableArea.box().pixelSnappedBorderBoxRect(), ResizerForPointer); if (absRect.isEmpty()) return; absRect.moveBy(paintOffset); if (m_scrollableArea.resizer()) { if (!absRect.intersects(damageRect)) return; ScrollbarPainter::paintIntoRect(m_scrollableArea.resizer(), context, paintOffset, LayoutRect(absRect)); return; } if (!RuntimeEnabledFeatures::slimmingPaintEnabled() && !absRect.intersects(damageRect)) return; if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*context, m_scrollableArea.box(), DisplayItem::Resizer)) return; LayoutObjectDrawingRecorder recorder(*context, m_scrollableArea.box(), DisplayItem::Resizer, absRect); drawPlatformResizerImage(context, absRect); // Draw a frame around the resizer (1px grey line) if there are any scrollbars present. // Clipping will exclude the right and bottom edges of this frame. if (!m_scrollableArea.hasOverlayScrollbars() && m_scrollableArea.hasScrollbar()) { GraphicsContextStateSaver stateSaver(*context); context->clip(absRect); IntRect largerCorner = absRect; largerCorner.setSize(IntSize(largerCorner.width() + 1, largerCorner.height() + 1)); context->setStrokeColor(Color(217, 217, 217)); context->setStrokeThickness(1.0f); context->setFillColor(Color::transparent); context->drawRect(largerCorner); } }
bool overlapsLayers(const IntRect& bounds) const { // Checking with the bounding box will quickly reject cases when // layers are created for lists of items going in one direction and // never overlap with each other. if (!bounds.intersects(m_boundingBox)) return false; for (unsigned i = 0; i < m_layerRects.size(); i++) { if (m_layerRects[i].intersects(bounds)) return true; } return false; }
static void deflateIfOverlapped(IntRect& a, IntRect& b) { if (!a.intersects(b) || a.contains(b) || b.contains(a)) return; static const int fudgeFactor = -2; // Avoid negative width or height values. if ((a.width() + 2 * fudgeFactor > 0) && (a.height() + 2 * fudgeFactor > 0)) a.inflate(fudgeFactor); if ((b.width() + 2 * fudgeFactor > 0) && (b.height() + 2 * fudgeFactor > 0)) b.inflate(fudgeFactor); }
void PlatformScrollbar::paintTrack(GraphicsContext* context, const IntRect& rect, bool start, const IntRect& damageRect) const { if (!damageRect.intersects(rect)) return; int part; if (m_orientation == HorizontalScrollbar) part = start ? SP_TRACKSTARTHOR : SP_TRACKENDHOR; else part = start ? SP_TRACKSTARTVERT : SP_TRACKENDVERT; int state; if (!isEnabled()) state = TS_DISABLED; else if ((m_hoveredPart == BackTrackPart && start) || (m_hoveredPart == ForwardTrackPart && !start)) state = (m_pressedPart == m_hoveredPart ? TS_ACTIVE : TS_HOVER); else state = TS_NORMAL; bool alphaBlend = false; if (scrollbarTheme) alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, part, state); HDC hdc = context->getWindowsContext(rect, alphaBlend); RECT themeRect(rect); if (scrollbarTheme) DrawThemeBackground(scrollbarTheme, hdc, part, state, &themeRect, 0); else { DWORD color3DFace = ::GetSysColor(COLOR_3DFACE); DWORD colorScrollbar = ::GetSysColor(COLOR_SCROLLBAR); DWORD colorWindow = ::GetSysColor(COLOR_WINDOW); if ((color3DFace != colorScrollbar) && (colorWindow != colorScrollbar)) ::FillRect(hdc, &themeRect, HBRUSH(COLOR_SCROLLBAR+1)); else { static WORD patternBits[8] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 }; HBITMAP patternBitmap = ::CreateBitmap(8, 8, 1, 1, patternBits); HBRUSH brush = ::CreatePatternBrush(patternBitmap); SaveDC(hdc); ::SetTextColor(hdc, ::GetSysColor(COLOR_3DHILIGHT)); ::SetBkColor(hdc, ::GetSysColor(COLOR_3DFACE)); ::SetBrushOrgEx(hdc, rect.x(), rect.y(), NULL); ::SelectObject(hdc, brush); ::FillRect(hdc, &themeRect, brush); ::RestoreDC(hdc, -1); ::DeleteObject(brush); ::DeleteObject(patternBitmap); } } context->releaseWindowsContext(hdc, rect, alphaBlend); }
bool canBeScrolledIntoView(FocusDirection direction, const FocusCandidate& candidate) { ASSERT(candidate.visibleNode && candidate.isOffscreen); IntRect candidateRect = candidate.rect; for (Node* parentNode = candidate.visibleNode->parentNode(); parentNode; parentNode = parentNode->parentNode()) { IntRect parentRect = nodeRectInAbsoluteCoordinates(parentNode); if (!candidateRect.intersects(parentRect)) { if (((direction == FocusDirectionLeft || direction == FocusDirectionRight) && parentNode->renderer()->style()->overflowX() == OHIDDEN) || ((direction == FocusDirectionUp || direction == FocusDirectionDown) && parentNode->renderer()->style()->overflowY() == OHIDDEN)) return false; } if (parentNode == candidate.enclosingScrollableBox) return canScrollInDirection(parentNode, direction); } return true; }
bool snapTo(const SubtargetGeometry& geom, const IntPoint& touchPoint, const IntRect& touchArea, IntPoint& adjustedPoint) { FrameView* view = geom.node()->document()->view(); FloatQuad quad = geom.quad(); if (quad.isRectilinear()) { IntRect contentBounds = geom.boundingBox(); // Convert from frame coordinates to window coordinates. IntRect bounds = view->contentsToWindow(contentBounds); if (bounds.contains(touchPoint)) { adjustedPoint = touchPoint; return true; } if (bounds.intersects(touchArea)) { bounds.intersect(touchArea); adjustedPoint = bounds.center(); return true; } return false; } // The following code tries to adjust the point to place inside a both the touchArea and the non-rectilinear quad. // FIXME: This will return the point inside the touch area that is the closest to the quad center, but does not // guarantee that the point will be inside the quad. Corner-cases exist where the quad will intersect but this // will fail to adjust the point to somewhere in the intersection. // Convert quad from content to window coordinates. FloatPoint p1 = contentsToWindow(view, quad.p1()); FloatPoint p2 = contentsToWindow(view, quad.p2()); FloatPoint p3 = contentsToWindow(view, quad.p3()); FloatPoint p4 = contentsToWindow(view, quad.p4()); quad = FloatQuad(p1, p2, p3, p4); if (quad.containsPoint(touchPoint)) { adjustedPoint = touchPoint; return true; } // Pull point towards the center of the element. FloatPoint center = quad.center(); adjustPointToRect(center, touchArea); adjustedPoint = roundedIntPoint(center); return quad.containsPoint(adjustedPoint); }