Example #1
0
void MainPerson::interactionWitnUnlifeObject(vector<UnlifeObject> *unlifeObjects, const Time & deltaTime)// ИСПРАВЬ for enity and mainPerson
{
	float dx(movement.x);
	float dy(movement.y);

	float x;
	float y;
	x = getXPos();
	y = getYPos();

	// Проверка на выход за карту
	if (((x < (SIZE_BLOCK * WIDTH_MAP)) && (x >  0))
			&& (y < (SIZE_BLOCK * (LONG_MAP - 1)) && (y >  0))) {
		Sprite *spriteObject;
		FloatRect objectBound;

		int levelUnlifeObject;
		Sprite *transparentSpiteObject;
		FloatRect objectAltBound;
		FloatRect entityBound;

		vector<UnlifeObject> &objects = *unlifeObjects;
		for (int i = 0; i != objects.size(); ++i) {
			levelUnlifeObject = objects[i].currentLevel;

			spriteObject = objects[i].spriteObject;
			objectBound = spriteObject->getGlobalBounds();

			transparentSpiteObject = objects[i].transparentSpiteObject;
			objectAltBound = transparentSpiteObject->getGlobalBounds();
			entityBound = spriteEntity->getGlobalBounds();

			if (entityBound.intersects(objectBound) && (levelUnlifeObject == currentLevelFloor + 1)) {
				if (direction >= Direction::UP_LEFT) {
					// Чтобы скорость по диагонали была равной скорости по вертикали и горизонтали
					x -= DIAGONAL_SCALE_SPEED * dx * deltaTime.asSeconds();
					y -= DIAGONAL_SCALE_SPEED * dy * deltaTime.asSeconds();
				} else {
					x -= dx * deltaTime.asSeconds();
					y -= dy * deltaTime.asSeconds();
				}
				direction = NONE_DIRECTION;
				break;
			} else if (entityBound.intersects(objectAltBound) && (levelUnlifeObject == currentLevelFloor + 1)) {
				transparentSpiteObject->setColor(TRANSPARENT_COLOR);
			} else {
				transparentSpiteObject->setColor(NORMAL_COLOR);
			}

		}
	} else {
		x = (int)getXPos();
		y = (int)getYPos();
	}

	spriteEntity->setPosition(x, y);
	movement = { 0.f, 0.f };
}
Example #2
0
void le::AI::MoveToObject( Vector2f Factor , Body::TYPE_MOVE typeMove , BasicPersonages *Personage , bool UseY )
{
	FloatRect TempRect = this->Personage->GetRect();

	if ( !UseY )
		TempRect.top = Personage->GetRect().top;

	if ( !TempRect.intersects( Personage->GetRect() ) )
	{
		if ( this->Personage->GetRect().left < Personage->GetRect().left )
		{
			this->Personage->GetBody().MoveBody( Vector2f( Factor.x , 0 ) , typeMove );
			this->Personage->GetAnimationManager().Flip( true );
		}
		else
		{
			this->Personage->GetBody().MoveBody( Vector2f( -Factor.x , 0 ) , typeMove );
			this->Personage->GetAnimationManager().Flip( false );
		}

		if ( UseY )
		{
			if ( this->Personage->GetRect().top < Personage->GetRect().top )
				this->Personage->GetBody().MoveBody( Vector2f( 0 , -Factor.y ) , typeMove );
			else
				this->Personage->GetBody().MoveBody( Vector2f( 0 , Factor.y ) , typeMove );
		}
	}
}
Example #3
0
bool SVGSVGElement::checkIntersection(SVGElement* element, const FloatRect& rect)
{
    // TODO : take into account pointer-events?
    // FIXME: Why is element ignored??
    // FIXME: Implement me (see bug 11274)
    return rect.intersects(getBBox());
}
Example #4
0
void LayerBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity, BitmapTexture* mask)
{
    Vector<TextureMapperTile*> tilesToPaint;

    // We have to do this every time we paint, in case the opacity has changed.
    HashMap<int, LayerBackingStoreTile>::iterator end = m_tiles.end();
    FloatRect coveredRect;
    for (HashMap<int, LayerBackingStoreTile>::iterator it = m_tiles.begin(); it != end; ++it) {
        LayerBackingStoreTile& tile = it->second;
        if (!tile.texture())
            continue;

        if (tile.scale() == m_scale) {
            tilesToPaint.append(&tile);
            coveredRect.unite(tile.rect());
            continue;
        }

        // Only show the previous tile if the opacity is high, otherwise effect looks like a bug.
        // We show the previous-scale tile anyway if it doesn't intersect with any current-scale tile.
        if (opacity < 0.95 && coveredRect.intersects(tile.rect()))
            continue;

        tilesToPaint.prepend(&tile);
    }

    // TODO: When the TextureMapper makes a distinction between some edges exposed and no edges
    // exposed, the value passed should be an accurate reflection of the tile subset that we are
    // passing. For now we just "estimate" since LayerBackingStore doesn't keep information about
    // the total tiled surface rect at the moment.
    unsigned edgesExposed = m_tiles.size() > 1 ? TextureMapper::NoEdges : TextureMapper::AllEdges;
    for (size_t i = 0; i < tilesToPaint.size(); ++i)
        tilesToPaint[i]->paint(textureMapper, transform, opacity, mask, edgesExposed);
}
Example #5
0
//! Checks if all neighbour tile know about the owner of the label
bool Renderer::isCutOff(const FloatRect& box, const FloatRect& owner)
{
	bool tooLarge = false;
	for (int i = 0; i < 8 && !tooLarge; i++)
		tooLarge = box.intersects(neighbours[i]) && !neighbourRequests[i].intersects(owner);
	return tooLarge;
}
Example #6
0
bool SVGRenderSupport::paintInfoIntersectsRepaintRect(const FloatRect& localRepaintRect, const AffineTransform& localTransform, const PaintInfo& paintInfo)
{
    if (localTransform.isIdentity())
        return localRepaintRect.intersects(paintInfo.rect);

    return localTransform.mapRect(localRepaintRect).intersects(paintInfo.rect);
}
void Entity::interactionWitnUnlifeObject(vector<UnlifeObject> &unlifeObjects , const float deltaTime)// ÈÑÏÐÀÂÜ for enity and mainPerson
{
	wasCollision = false;
	collision.clear();

	Sprite *spriteObject;
	FloatRect objectBound;

	int levelUnlifeObject;
	Sprite *transparentSpiteObject;
	FloatRect objectAltBound;

	spriteEntity->move(movement);
	FloatRect entityBound = spriteEntity->getGlobalBounds();
	spriteEntity->move(-movement);


	for (int i = 0; i < unlifeObjects.size(); i++) {
		levelUnlifeObject = unlifeObjects[i].currentLevel;

		spriteObject = unlifeObjects[i].spriteObject;
		objectBound = spriteObject->getGlobalBounds();

		transparentSpiteObject = unlifeObjects[i].transparentSpiteObject;
		objectAltBound = transparentSpiteObject->getGlobalBounds();

		if (entityBound.intersects(objectBound) && (levelUnlifeObject == currentLevelFloor + 1)) {
			wasCollision = true;

			collision.posObject = unlifeObjects[i].getPosition();
			collision.levelObject = unlifeObjects[i].currentLevel;

			directions.directionWalk = NONE_DIRECTION;
			break;
		}
		else if (type->id == idEntity::playerEntity) {
			if (entityBound.intersects(objectAltBound) && (levelUnlifeObject == currentLevelFloor + 1)) {
				transparentSpiteObject->setColor(TRANSPARENT_COLOR);
			}
			else {
				transparentSpiteObject->setColor(NORMAL_COLOR);
			}
		}

	}

}
Example #8
0
bool Enemy::Contact(Player &player)
{
	FloatRect playr = player.GetGlobalBounds();
	FloatRect enmy = GetGlobalBounds();

	if(enmy.intersects(playr)) return true;
	return false;
}
Example #9
0
void RootInlineBox::paintCustomHighlight(RenderObject::PaintInfo& paintInfo, int tx, int ty, const AtomicString& highlightType)
{
    if (!object()->shouldPaintWithinRoot(paintInfo) || object()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
        return;

    // Get the inflated rect so that we can properly hit test.
    FloatRect rootRect(tx + xPos(), ty + selectionTop(), width(), selectionHeight());
    FloatRect inflatedRect = object()->document()->frame()->customHighlightLineRect(highlightType, rootRect);
    if (inflatedRect.intersects(paintInfo.rect))
        object()->document()->frame()->paintCustomHighlight(highlightType, rootRect, rootRect, false, true);
}
// FloatRect::intersects does not consider horizontal or vertical lines (because of isEmpty()).
// So special-case handling of such lines.
static bool intersectsAllowingEmpty(const FloatRect& r, const FloatRect& other)
{
    if (r.isEmpty() && other.isEmpty())
        return false;
    if (r.isEmpty() && !other.isEmpty()) {
        return (other.contains(r.x(), r.y()) && !other.contains(r.maxX(), r.maxY()))
               || (!other.contains(r.x(), r.y()) && other.contains(r.maxX(), r.maxY()));
    }
    if (other.isEmpty() && !r.isEmpty())
        return intersectsAllowingEmpty(other, r);
    return r.intersects(other);
}
Example #11
0
// Returns true if any part of the layer falls within the visibleRect
bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const TransformationMatrix& matrix, const IntRect& visibleRect)
{
    // Form the matrix used by the shader to map the corners of the layer's
    // bounds into clip space.
    TransformationMatrix renderMatrix = matrix;
    renderMatrix.scale3d(layer->bounds().width(), layer->bounds().height(), 1);
    renderMatrix.multiply(m_projectionMatrix);

    FloatRect layerRect(-0.5, -0.5, 1, 1);
    FloatRect mappedRect = renderMatrix.mapRect(layerRect);

    // The layer is visible if it intersects any part of a rectangle whose origin
    // is at (-1, -1) and size is 2x2.
    return mappedRect.intersects(FloatRect(-1, -1, 2, 2));
}
Example #12
0
void TiledBackingStore::dropTilesOutsideRect(const IntRect& keepRect)
{
    FloatRect keepRectF = keepRect;

    Vector<Tile::Coordinate> toRemove;
    TileMap::iterator end = m_tiles.end();
    for (TileMap::iterator it = m_tiles.begin(); it != end; ++it) {
        Tile::Coordinate coordinate = it->second->coordinate();
        FloatRect tileRect = it->second->rect();
        if (!tileRect.intersects(keepRectF))
            toRemove.append(coordinate);
    }
    unsigned removeCount = toRemove.size();
    for (unsigned n = 0; n < removeCount; ++n)
        removeTile(toRemove[n]);
}
Example #13
0
  bool BoundingBox::CollidesWith (
    const ICollidable& other,
    const Vector2& offset) const
  {
    if (GetZ () >= other.GetZ () + other.GetH () ||
        GetZ () + GetH () <= other.GetZ ())
      return false;

    FloatRect rect (
      spatial3Info_.GetRectangle ().left + offset.x,
      spatial3Info_.GetRectangle ().top + offset.y,
      spatial3Info_.GetRectangle ().width,
      spatial3Info_.GetRectangle ().height);

    return rect.intersects (other.GetRectangle ());
  }
void Entity::interactionWithEntity(vector<Entity> *enemys , int id , const float deltaTime)// ÈÑÏÐÀÂÜ for enity and mainPerson
{
	if (!wasCollision) {
		float &dx = movement.x;
		float &dy = movement.y;

		float x;
		float y;
		x = getXPos();
		y = getYPos();


		Sprite *spriteObject;
		FloatRect objectBound;

		int levelUnlifeObject;

		spriteEntity->move(movement);
		FloatRect entityBound = spriteEntity->getGlobalBounds();
		spriteEntity->move(-movement);


		vector<Entity> &objects = *enemys;
		for (int i = 0; i != objects.size(); ++i) {

			if (id != i) {
				levelUnlifeObject = objects[i].currentLevelFloor;

				spriteObject = objects[i].spriteEntity;
				objectBound = spriteObject->getGlobalBounds();


				if (entityBound.intersects(objectBound) && (levelUnlifeObject == currentLevelFloor)) {
					wasCollision = true;

					founds.findEnemy = &objects[i];
					directions.directionWalk = NONE_DIRECTION;
					break;
				}

			}

		}
	}
}
Example #15
0
void RootInlineBox::paintCustomHighlight(RenderObject::PaintInfo& paintInfo, int tx, int ty, const AtomicString& highlightType)
{
    if (!renderer()->shouldPaintWithinRoot(paintInfo) || renderer()->style()->visibility() != VISIBLE || paintInfo.phase != PaintPhaseForeground)
        return;

    Frame* frame = renderer()->document()->frame();
    if (!frame)
        return;
    Page* page = frame->page();
    if (!page)
        return;

    // Get the inflated rect so that we can properly hit test.
    FloatRect rootRect(tx + x(), ty + selectionTop(), width(), selectionHeight());
    FloatRect inflatedRect = page->chrome()->client()->customHighlightRect(renderer()->node(), highlightType, rootRect);
    if (inflatedRect.intersects(paintInfo.rect))
        page->chrome()->client()->paintCustomHighlight(renderer()->node(), highlightType, rootRect, rootRect, false, true);
}
Example #16
0
bool GameObject::TestCollitions(GameObject& target)
{
	FloatRect rect_t = target.GetBound();
	rect_t.height -= 15.0f;
	rect_t.width -= 15.0f;
	rect_t.top += 15.0f;
	rect_t.left += 15.0f;

	FloatRect rect = _sprite.getGlobalBounds();
	rect.height -= 15.0f;
	rect.width -= 15.0f;
	rect.top += 15.0f;
	rect.left += 15.0f;

	if(rect.intersects(rect_t))
	{
		return true;
	}
	return false;
}
Example #17
0
void RenderPath::paint(PaintInfo& paintInfo, int, int)
{
    if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || m_path.isEmpty())
        return;

    FloatRect boundingBox = repaintRectInLocalCoordinates();
    FloatRect nonLocalBoundingBox = m_localTransform.mapRect(boundingBox);
    if (!nonLocalBoundingBox.intersects(paintInfo.rect))
        return;

    PaintInfo childPaintInfo(paintInfo);
    bool drawsOutline = style()->outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
    if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
        childPaintInfo.context->save();
        childPaintInfo.applyTransform(m_localTransform);

        if (childPaintInfo.phase == PaintPhaseForeground) {
            PaintInfo savedInfo(childPaintInfo);

            if (SVGRenderSupport::prepareToRenderSVGContent(this, childPaintInfo)) {
                const SVGRenderStyle* svgStyle = style()->svgStyle();
                if (svgStyle->shapeRendering() == SR_CRISPEDGES)
                    childPaintInfo.context->setShouldAntialias(false);

                fillAndStrokePath(childPaintInfo.context);

                if (svgStyle->hasMarkers())
                    m_markerLayoutInfo.drawMarkers(childPaintInfo);
            }

            SVGRenderSupport::finishRenderSVGContent(this, childPaintInfo, savedInfo.context);
        }

        if (drawsOutline)
            paintOutline(childPaintInfo.context, static_cast<int>(boundingBox.x()), static_cast<int>(boundingBox.y()),
                static_cast<int>(boundingBox.width()), static_cast<int>(boundingBox.height()));
        
        childPaintInfo.context->restore();
    }
}
void CoordinatedBackingStore::paintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
{
    if (m_tiles.isEmpty())
        return;
    ASSERT(!m_size.isZero());

    Vector<TextureMapperTile*> tilesToPaint;
    Vector<TextureMapperTile*> previousTilesToPaint;

    // We have to do this every time we paint, in case the opacity has changed.
    CoordinatedBackingStoreTileMap::iterator end = m_tiles.end();
    FloatRect coveredRect;
    for (CoordinatedBackingStoreTileMap::iterator it = m_tiles.begin(); it != end; ++it) {
        CoordinatedBackingStoreTile& tile = it->value;
        if (!tile.texture())
            continue;

        if (tile.scale() == m_scale) {
            tilesToPaint.append(&tile);
            coveredRect.unite(tile.rect());
            continue;
        }

        // Only show the previous tile if the opacity is high, otherwise effect looks like a bug.
        // We show the previous-scale tile anyway if it doesn't intersect with any current-scale tile.
        if (opacity < 0.95 && coveredRect.intersects(tile.rect()))
            continue;

        previousTilesToPaint.append(&tile);
    }

    // targetRect is on the contents coordinate system, so we must compare two rects on the contents coordinate system.
    // See TiledBackingStore.
    TransformationMatrix adjustedTransform = transform * adjustedTransformForRect(targetRect);

    paintTilesToTextureMapper(previousTilesToPaint, textureMapper, adjustedTransform, opacity, rect());
    paintTilesToTextureMapper(tilesToPaint, textureMapper, adjustedTransform, opacity, rect());
}
void paintFlow(const RenderBlockFlow& flow, const Layout& layout, PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    if (paintInfo.phase != PaintPhaseForeground)
        return;

    RenderStyle& style = flow.style();
    if (style.visibility() != VISIBLE)
        return;

    bool debugBordersEnabled = flow.frame().settings().simpleLineLayoutDebugBordersEnabled();

    GraphicsContext& context = paintInfo.context();
    const FontCascade& font = style.fontCascade();
    TextPaintStyle textPaintStyle = computeTextPaintStyle(flow.frame(), style, paintInfo);
    GraphicsContextStateSaver stateSaver(context, textPaintStyle.strokeWidth > 0);

    updateGraphicsContext(context, textPaintStyle);
    LayoutRect paintRect = paintInfo.rect;
    paintRect.moveBy(-paintOffset);

    auto resolver = runResolver(flow, layout);
    float strokeOverflow = ceilf(flow.style().textStrokeWidth());
    float deviceScaleFactor = flow.document().deviceScaleFactor();
    for (const auto& run : resolver.rangeForRect(paintRect)) {
        FloatRect rect = run.rect();
        rect.inflate(strokeOverflow);
        if (!rect.intersects(paintRect) || run.start() == run.end())
            continue;
        TextRun textRun(run.text());
        textRun.setTabSize(!style.collapseWhiteSpace(), style.tabSize());
        // x position indicates the line offset from the rootbox. It's always 0 in case of simple line layout.
        textRun.setXPos(0);
        FloatPoint textOrigin = FloatPoint(rect.x() + paintOffset.x(), roundToDevicePixel(run.baselinePosition() + paintOffset.y(), deviceScaleFactor));
        context.drawText(font, textRun, textOrigin);
        if (debugBordersEnabled)
            paintDebugBorders(context, LayoutRect(run.rect()), paintOffset);
    }
}
Example #20
0
void RenderPath::paint(PaintInfo& paintInfo, int, int)
{
    if (paintInfo.context->paintingDisabled() || style()->visibility() == HIDDEN || m_path.isEmpty())
        return;

    FloatRect boundingBox = repaintRectInLocalCoordinates();
    FloatRect nonLocalBoundingBox = m_localTransform.mapRect(boundingBox);
    // FIXME: The empty rect check is to deal with incorrect initial clip in renderSubtreeToImage
    // unfortunately fixing that problem is fairly complex unless we were willing to just futz the
    // rect to something "close enough"
    if (!nonLocalBoundingBox.intersects(paintInfo.rect) && !paintInfo.rect.isEmpty())
        return;

    PaintInfo childPaintInfo(paintInfo);
    childPaintInfo.context->save();
    applyTransformToPaintInfo(childPaintInfo, m_localTransform);
    SVGResourceFilter* filter = 0;

    if (childPaintInfo.phase == PaintPhaseForeground) {
        PaintInfo savedInfo(childPaintInfo);

        if (prepareToRenderSVGContent(this, childPaintInfo, boundingBox, filter)) {
            if (style()->svgStyle()->shapeRendering() == SR_CRISPEDGES)
                childPaintInfo.context->setShouldAntialias(false);
            fillAndStrokePath(m_path, childPaintInfo.context, style(), this);

            if (static_cast<SVGStyledElement*>(node())->supportsMarkers())
                m_markerLayoutInfo.drawMarkers(childPaintInfo);
        }
        finishRenderSVGContent(this, childPaintInfo, filter, savedInfo.context);
    }

    if ((childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth())
        paintOutline(childPaintInfo.context, static_cast<int>(boundingBox.x()), static_cast<int>(boundingBox.y()),
            static_cast<int>(boundingBox.width()), static_cast<int>(boundingBox.height()), style());
    
    childPaintInfo.context->restore();
}
static bool findIndicatorsForTextRectsOverlap(const Vector<FloatRect>& textRects)
{
    size_t count = textRects.size();
    if (count <= 1)
        return false;

    Vector<FloatRect> indicatorRects;
    indicatorRects.reserveInitialCapacity(count);

    for (size_t i = 0; i < count; ++i) {
        FloatRect indicatorRect = outsetIndicatorRectIncludingShadow(textRects[i]);

        for (size_t j = indicatorRects.size(); j; ) {
            --j;
            if (indicatorRect.intersects(indicatorRects[j]))
                return true;
        }

        indicatorRects.uncheckedAppend(indicatorRect);
    }

    return false;
}
FloatRect TileController::computeTileCoverageRect(const FloatSize& newSize, const FloatRect& previousVisibleRect, const FloatRect& visibleRect, float contentsScale) const
{
    // If the page is not in a window (for example if it's in a background tab), we limit the tile coverage rect to the visible rect.
    if (!m_isInWindow)
        return visibleRect;

#if PLATFORM(IOS)
    // FIXME: unify the iOS and Mac code.
    UNUSED_PARAM(previousVisibleRect);
    
    if (m_tileCoverage == CoverageForVisibleArea || MemoryPressureHandler::singleton().isUnderMemoryPressure())
        return visibleRect;

    double horizontalMargin = tileSize().width() / contentsScale;
    double verticalMargin = tileSize().height() / contentsScale;

    double currentTime = monotonicallyIncreasingTime();
    double timeDelta = currentTime - m_velocity.lastUpdateTime;

    FloatRect futureRect = visibleRect;
    futureRect.setLocation(FloatPoint(
        futureRect.location().x() + timeDelta * m_velocity.horizontalVelocity,
        futureRect.location().y() + timeDelta * m_velocity.verticalVelocity));

    if (m_velocity.horizontalVelocity) {
        futureRect.setWidth(futureRect.width() + horizontalMargin);
        if (m_velocity.horizontalVelocity < 0)
            futureRect.setX(futureRect.x() - horizontalMargin);
    }

    if (m_velocity.verticalVelocity) {
        futureRect.setHeight(futureRect.height() + verticalMargin);
        if (m_velocity.verticalVelocity < 0)
            futureRect.setY(futureRect.y() - verticalMargin);
    }

    if (!m_velocity.horizontalVelocity && !m_velocity.verticalVelocity) {
        if (m_velocity.scaleChangeRate > 0)
            return visibleRect;
        futureRect.setWidth(futureRect.width() + horizontalMargin);
        futureRect.setHeight(futureRect.height() + verticalMargin);
        futureRect.setX(futureRect.x() - horizontalMargin / 2);
        futureRect.setY(futureRect.y() - verticalMargin / 2);
    }

    // Can't use m_tileCacheLayer->bounds() here, because the size of the underlying platform layer
    // hasn't been updated for the current commit.
    IntSize contentSize = expandedIntSize(newSize);
    if (futureRect.maxX() > contentSize.width())
        futureRect.setX(contentSize.width() - futureRect.width());
    if (futureRect.maxY() > contentSize.height())
        futureRect.setY(contentSize.height() - futureRect.height());
    if (futureRect.x() < 0)
        futureRect.setX(0);
    if (futureRect.y() < 0)
        futureRect.setY(0);

    return futureRect;
#else
    UNUSED_PARAM(contentsScale);

    // FIXME: look at how far the document can scroll in each dimension.
    float coverageHorizontalSize = visibleRect.width();
    float coverageVerticalSize = visibleRect.height();

    bool largeVisibleRectChange = !previousVisibleRect.isEmpty() && !visibleRect.intersects(previousVisibleRect);

    // Inflate the coverage rect so that it covers 2x of the visible width and 3x of the visible height.
    // These values were chosen because it's more common to have tall pages and to scroll vertically,
    // so we keep more tiles above and below the current area.

    if (m_tileCoverage & CoverageForHorizontalScrolling && !largeVisibleRectChange)
        coverageHorizontalSize *= 2;

    if (m_tileCoverage & CoverageForVerticalScrolling && !largeVisibleRectChange)
        coverageVerticalSize *= 3;

    coverageVerticalSize += topMarginHeight() + bottomMarginHeight();
    coverageHorizontalSize += leftMarginWidth() + rightMarginWidth();

    // Can't use m_tileCacheLayer->bounds() here, because the size of the underlying platform layer
    // hasn't been updated for the current commit.
    FloatRect coverageBounds = boundsForSize(newSize);
    float coverageLeft = visibleRect.x() - (coverageHorizontalSize - visibleRect.width()) / 2;
    coverageLeft = std::min(coverageLeft, coverageBounds.maxX() - coverageHorizontalSize);
    coverageLeft = std::max(coverageLeft, coverageBounds.x());

    float coverageTop = visibleRect.y() - (coverageVerticalSize - visibleRect.height()) / 2;
    coverageTop = std::min(coverageTop, coverageBounds.maxY() - coverageVerticalSize);
    coverageTop = std::max(coverageTop, coverageBounds.y());

    return FloatRect(coverageLeft, coverageTop, coverageHorizontalSize, coverageVerticalSize);
#endif
}
Example #23
0
// Recursively walk the layer tree and draw the layers.
void LayerRendererChromium::drawLayersRecursive(LayerChromium* layer, const FloatRect& scissorRect)
{
    static bool depthTestEnabledForSubtree = false;
    static int currentStencilValue = 0;

    // Check if the layer falls within the visible bounds of the page.
    FloatRect layerRect = layer->getDrawRect();
    bool isLayerVisible = scissorRect.intersects(layerRect);

    // Enable depth testing for this layer and all its descendants if preserves3D is set.
    bool mustClearDepth = false;
    if (layer->preserves3D()) {
        if (!depthTestEnabledForSubtree) {
            GLC(glEnable(GL_DEPTH_TEST));
            depthTestEnabledForSubtree = true;

            // Need to clear the depth buffer when we're done rendering this subtree.
            mustClearDepth = true;
        }
    }

    if (isLayerVisible)
        drawLayer(layer);

    // FIXME: We should check here if the layer has descendants that draw content
    // before we setup for clipping.
    FloatRect currentScissorRect = scissorRect;
    bool mustResetScissorRect = false;
    bool didStencilDraw = false;
    if (layer->masksToBounds()) {
        // If the layer isn't rotated then we can use scissoring otherwise we need
        // to clip using the stencil buffer.
        if (layer->drawTransform().isIdentityOrTranslation()) {
            currentScissorRect.intersect(layerRect);
            if (currentScissorRect != scissorRect) {
                scissorToRect(currentScissorRect);
                mustResetScissorRect = true;
            }
        } else if (currentStencilValue < ((1 << m_numStencilBits) - 1)) {
            // Clipping using the stencil buffer works as follows: When we encounter
            // a clipping layer we increment the stencil buffer values for all the pixels
            // the layer touches. As a result 1's will be stored in the stencil buffer for pixels under
            // the first clipping layer found in a traversal, 2's for pixels in the intersection
            // of two nested clipping layers, etc. When the sublayers of a clipping layer are drawn
            // we turn on stencil testing to render only pixels that have the correct stencil
            // value (one that matches the value of currentStencilValue). As the recursion unravels,
            // we decrement the stencil buffer values for each clipping layer. When the entire layer tree
            // is rendered, the stencil values should be all back to zero. An 8 bit stencil buffer
            // will allow us up to 255 nested clipping layers which is hopefully enough.
            if (!currentStencilValue)
                GLC(glEnable(GL_STENCIL_TEST));

            drawLayerIntoStencilBuffer(layer, false);

            currentStencilValue++;
            didStencilDraw = true;
        }
    }
    // Sublayers will render only if the value in the stencil buffer is equal to
    // currentStencilValue.
    if (didStencilDraw) {
        // The sublayers will render only if the stencil test passes.
        GLC(glStencilFunc(GL_EQUAL, currentStencilValue, 0xff));
    }

    // If we're using depth testing then we need to sort the children in Z to
    // get the transparency to work properly.
    if (depthTestEnabledForSubtree) {
        const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
        Vector<LayerChromium*> sublayerList;
        size_t i;
        for (i = 0; i < sublayers.size(); i++)
            sublayerList.append(sublayers[i].get());

        // Sort by the z coordinate of the layer center so that layers further away
        // are drawn first.
        std::stable_sort(sublayerList.begin(), sublayerList.end(), compareLayerZ);

        for (i = 0; i < sublayerList.size(); i++)
            drawLayersRecursive(sublayerList[i], currentScissorRect);
    } else {
        const Vector<RefPtr<LayerChromium> >& sublayers = layer->getSublayers();
        for (size_t i = 0; i < sublayers.size(); i++)
            drawLayersRecursive(sublayers[i].get(), currentScissorRect);
    }

    if (didStencilDraw) {
        // Draw into the stencil buffer subtracting 1 for every pixel hit
        // effectively removing this mask
        drawLayerIntoStencilBuffer(layer, true);
        currentStencilValue--;
        if (!currentStencilValue) {
            // Disable stencil testing.
            GLC(glDisable(GL_STENCIL_TEST));
            GLC(glStencilFunc(GL_ALWAYS, 0, 0xff));
        }
    }

    if (mustResetScissorRect) {
        scissorToRect(scissorRect);
    }

    if (mustClearDepth) {
        GLC(glDisable(GL_DEPTH_TEST));
        GLC(glClear(GL_DEPTH_BUFFER_BIT));
        depthTestEnabledForSubtree = false;
    }
}
Example #24
0
bool IntersectsRects(FloatRect objectRect, FloatRect subjectRect) {
	return objectRect.intersects(subjectRect);
}
void TileController::adjustTileCoverageRect(FloatRect& coverageRect, const FloatSize& newSize, const FloatRect& previousVisibleRect, const FloatRect& visibleRect, float contentsScale) const
{
    // If the page is not in a window (for example if it's in a background tab), we limit the tile coverage rect to the visible rect.
    if (!m_isInWindow) {
        coverageRect = visibleRect;
        return;
    }

#if PLATFORM(IOS)
    // FIXME: unify the iOS and Mac code.
    UNUSED_PARAM(previousVisibleRect);
    
    if (m_tileCoverage == CoverageForVisibleArea || MemoryPressureHandler::singleton().isUnderMemoryPressure()) {
        coverageRect = visibleRect;
        return;
    }

    double horizontalMargin = kDefaultTileSize / contentsScale;
    double verticalMargin = kDefaultTileSize / contentsScale;

    double currentTime = monotonicallyIncreasingTime();
    double timeDelta = currentTime - m_velocity.lastUpdateTime;

    FloatRect futureRect = visibleRect;
    futureRect.setLocation(FloatPoint(
        futureRect.location().x() + timeDelta * m_velocity.horizontalVelocity,
        futureRect.location().y() + timeDelta * m_velocity.verticalVelocity));

    if (m_velocity.horizontalVelocity) {
        futureRect.setWidth(futureRect.width() + horizontalMargin);
        if (m_velocity.horizontalVelocity < 0)
            futureRect.setX(futureRect.x() - horizontalMargin);
    }

    if (m_velocity.verticalVelocity) {
        futureRect.setHeight(futureRect.height() + verticalMargin);
        if (m_velocity.verticalVelocity < 0)
            futureRect.setY(futureRect.y() - verticalMargin);
    }

    if (!m_velocity.horizontalVelocity && !m_velocity.verticalVelocity) {
        if (m_velocity.scaleChangeRate > 0) {
            coverageRect = visibleRect;
            return;
        }
        futureRect.setWidth(futureRect.width() + horizontalMargin);
        futureRect.setHeight(futureRect.height() + verticalMargin);
        futureRect.setX(futureRect.x() - horizontalMargin / 2);
        futureRect.setY(futureRect.y() - verticalMargin / 2);
    }

    // Can't use m_tileCacheLayer->bounds() here, because the size of the underlying platform layer
    // hasn't been updated for the current commit.
    IntSize contentSize = expandedIntSize(newSize);
    if (futureRect.maxX() > contentSize.width())
        futureRect.setX(contentSize.width() - futureRect.width());
    if (futureRect.maxY() > contentSize.height())
        futureRect.setY(contentSize.height() - futureRect.height());
    if (futureRect.x() < 0)
        futureRect.setX(0);
    if (futureRect.y() < 0)
        futureRect.setY(0);

    coverageRect.unite(futureRect);
    return;
#else
    UNUSED_PARAM(contentsScale);

    // FIXME: look at how far the document can scroll in each dimension.
    FloatSize coverageSize = visibleRect.size();

    bool largeVisibleRectChange = !previousVisibleRect.isEmpty() && !visibleRect.intersects(previousVisibleRect);

    // Inflate the coverage rect so that it covers 2x of the visible width and 3x of the visible height.
    // These values were chosen because it's more common to have tall pages and to scroll vertically,
    // so we keep more tiles above and below the current area.
    float widthScale = 1;
    float heightScale = 1;

    if (m_tileCoverage & CoverageForHorizontalScrolling && !largeVisibleRectChange)
        widthScale = 2;

    if (m_tileCoverage & CoverageForVerticalScrolling && !largeVisibleRectChange)
        heightScale = 3;
    
    coverageSize.scale(widthScale, heightScale);

    FloatRect coverageBounds = boundsForSize(newSize);
    
    FloatRect coverage = expandRectWithinRect(visibleRect, coverageSize, coverageBounds);
    LOG_WITH_STREAM(Scrolling, stream << "TileController::computeTileCoverageRect newSize=" << newSize << " mode " << m_tileCoverage << " expanded to " << coverageSize << " bounds with margin " << coverageBounds << " coverage " << coverage);
    coverageRect.unite(coverage);
#endif
}