void centerPixmaps(QPixmap &from, QPixmap &to) { if (from.size() == to.size() && from.hasAlphaChannel() && to.hasAlphaChannel()) { return; } QRect fromRect(from.rect()); QRect toRect(to.rect()); QRect actualRect = QRect(QPoint(0,0), fromRect.size().expandedTo(toRect.size())); fromRect.moveCenter(actualRect.center()); toRect.moveCenter(actualRect.center()); if (from.size() != actualRect.size() || !from.hasAlphaChannel()) { QPixmap result(actualRect.size()); result.fill(Qt::transparent); QPainter p(&result); p.setCompositionMode(QPainter::CompositionMode_Source); p.drawPixmap(fromRect.topLeft(), from); p.end(); from = result; } if (to.size() != actualRect.size() || !to.hasAlphaChannel()) { QPixmap result(actualRect.size()); result.fill(Qt::transparent); QPainter p(&result); p.setCompositionMode(QPainter::CompositionMode_Source); p.drawPixmap(toRect.topLeft(), to); p.end(); to = result; } }
/** * @brief Relation::recalculateLine */ void Relation::recalculateLine() { QPolygonF fromRect(m_From->mapToScene(m_From->frameRect())); QPolygonF toRect(m_To->mapToScene(m_To->frameRect())); setVisible(fromRect.intersected(toRect).isEmpty()); if (isVisible()) { setP1(intersection(fromRect, QLineF(m_From->pos(), line().p2()))); setP2(intersection(toRect, QLineF(line().p1(), m_To->pos()))); } }
TEST(AffineTransform, MakeMapBetweenRects) { WebCore::AffineTransform transform; WebCore::FloatRect fromRect(10.0f, 10.0f, 100.0f, 100.0f); WebCore::FloatRect toRect(70.0f, 70.0f, 200.0f, 50.0f); auto mapBetween = WebCore::makeMapBetweenRects(fromRect, toRect); EXPECT_DOUBLE_EQ(2.0, mapBetween.a()); EXPECT_DOUBLE_EQ(0.0, mapBetween.b()); EXPECT_DOUBLE_EQ(0.0, mapBetween.c()); EXPECT_DOUBLE_EQ(0.5, mapBetween.d()); EXPECT_DOUBLE_EQ(60.0, mapBetween.e()); EXPECT_DOUBLE_EQ(60.0, mapBetween.f()); }
void Image::drawTiled(GraphicsContext& ctxt, const FloatRect& destRect, const FloatPoint& srcPoint, const FloatSize& scaledTileSize, const FloatSize& spacing, CompositeOperator op, BlendMode blendMode) { if (mayFillWithSolidColor()) { fillWithSolidColor(ctxt, destRect, solidColor(), op); return; } ASSERT(!isBitmapImage() || notSolidColor()); #if PLATFORM(IOS) FloatSize intrinsicTileSize = originalSize(); #else FloatSize intrinsicTileSize = size(); #endif if (hasRelativeWidth()) intrinsicTileSize.setWidth(scaledTileSize.width()); if (hasRelativeHeight()) intrinsicTileSize.setHeight(scaledTileSize.height()); FloatSize scale(scaledTileSize.width() / intrinsicTileSize.width(), scaledTileSize.height() / intrinsicTileSize.height()); FloatRect oneTileRect; FloatSize actualTileSize(scaledTileSize.width() + spacing.width(), scaledTileSize.height() + spacing.height()); oneTileRect.setX(destRect.x() + fmodf(fmodf(-srcPoint.x(), actualTileSize.width()) - actualTileSize.width(), actualTileSize.width())); oneTileRect.setY(destRect.y() + fmodf(fmodf(-srcPoint.y(), actualTileSize.height()) - actualTileSize.height(), actualTileSize.height())); oneTileRect.setSize(scaledTileSize); // Check and see if a single draw of the image can cover the entire area we are supposed to tile. if (oneTileRect.contains(destRect) && !ctxt.drawLuminanceMask()) { FloatRect visibleSrcRect; visibleSrcRect.setX((destRect.x() - oneTileRect.x()) / scale.width()); visibleSrcRect.setY((destRect.y() - oneTileRect.y()) / scale.height()); visibleSrcRect.setWidth(destRect.width() / scale.width()); visibleSrcRect.setHeight(destRect.height() / scale.height()); draw(ctxt, destRect, visibleSrcRect, op, blendMode, ImageOrientationDescription()); return; } #if PLATFORM(IOS) // When using accelerated drawing on iOS, it's faster to stretch an image than to tile it. if (ctxt.isAcceleratedContext()) { if (size().width() == 1 && intersection(oneTileRect, destRect).height() == destRect.height()) { FloatRect visibleSrcRect; visibleSrcRect.setX(0); visibleSrcRect.setY((destRect.y() - oneTileRect.y()) / scale.height()); visibleSrcRect.setWidth(1); visibleSrcRect.setHeight(destRect.height() / scale.height()); draw(ctxt, destRect, visibleSrcRect, op, BlendModeNormal, ImageOrientationDescription()); return; } if (size().height() == 1 && intersection(oneTileRect, destRect).width() == destRect.width()) { FloatRect visibleSrcRect; visibleSrcRect.setX((destRect.x() - oneTileRect.x()) / scale.width()); visibleSrcRect.setY(0); visibleSrcRect.setWidth(destRect.width() / scale.width()); visibleSrcRect.setHeight(1); draw(ctxt, destRect, visibleSrcRect, op, BlendModeNormal, ImageOrientationDescription()); return; } } #endif // Patterned images and gradients can use lots of memory for caching when the // tile size is large (<rdar://problem/4691859>, <rdar://problem/6239505>). // Memory consumption depends on the transformed tile size which can get // larger than the original tile if user zooms in enough. #if PLATFORM(IOS) const float maxPatternTilePixels = 512 * 512; #else const float maxPatternTilePixels = 2048 * 2048; #endif FloatRect transformedTileSize = ctxt.getCTM().mapRect(FloatRect(FloatPoint(), scaledTileSize)); float transformedTileSizePixels = transformedTileSize.width() * transformedTileSize.height(); FloatRect currentTileRect = oneTileRect; if (transformedTileSizePixels > maxPatternTilePixels) { GraphicsContextStateSaver stateSaver(ctxt); ctxt.clip(destRect); currentTileRect.shiftYEdgeTo(destRect.y()); float toY = currentTileRect.y(); while (toY < destRect.maxY()) { currentTileRect.shiftXEdgeTo(destRect.x()); float toX = currentTileRect.x(); while (toX < destRect.maxX()) { FloatRect toRect(toX, toY, currentTileRect.width(), currentTileRect.height()); FloatRect fromRect(toFloatPoint(currentTileRect.location() - oneTileRect.location()), currentTileRect.size()); fromRect.scale(1 / scale.width(), 1 / scale.height()); draw(ctxt, toRect, fromRect, op, BlendModeNormal, ImageOrientationDescription()); toX += currentTileRect.width(); currentTileRect.shiftXEdgeTo(oneTileRect.x()); } toY += currentTileRect.height(); currentTileRect.shiftYEdgeTo(oneTileRect.y()); } return; } AffineTransform patternTransform = AffineTransform().scaleNonUniform(scale.width(), scale.height()); FloatRect tileRect(FloatPoint(), intrinsicTileSize); drawPattern(ctxt, tileRect, patternTransform, oneTileRect.location(), spacing, op, destRect, blendMode); #if PLATFORM(IOS) startAnimation(DoNotCatchUp); #else startAnimation(); #endif }