Center images in their bounds when painting

Eventually we'll plumb positionX and positionY out so that developers can
control them.
This commit is contained in:
Adam Barth 2015-08-19 10:45:17 -07:00
parent 2e3cb06fdd
commit 7f4aa210c0

View File

@ -236,54 +236,55 @@ void paintImage({
sky.Image image, sky.Image image,
sky.ColorFilter colorFilter, sky.ColorFilter colorFilter,
fit: ImageFit.scaleDown, fit: ImageFit.scaleDown,
repeat: ImageRepeat.noRepeat repeat: ImageRepeat.noRepeat,
double positionX: 0.5,
double positionY: 0.5
}) { }) {
Size bounds = rect.size; Size bounds = rect.size;
Size imageSize = new Size(image.width.toDouble(), image.height.toDouble()); Size imageSize = new Size(image.width.toDouble(), image.height.toDouble());
Size src; Size sourceSize;
Size dst; Size destinationSize;
switch(fit) { switch(fit) {
case ImageFit.fill: case ImageFit.fill:
src = imageSize; sourceSize = imageSize;
dst = bounds; destinationSize = bounds;
break; break;
case ImageFit.contain: case ImageFit.contain:
src = imageSize; sourceSize = imageSize;
if (bounds.width / bounds.height > src.width / src.height) { if (bounds.width / bounds.height > sourceSize.width / sourceSize.height)
dst = new Size(bounds.width, src.height * bounds.width / src.width); destinationSize = new Size(sourceSize.width * bounds.height / sourceSize.height, bounds.height);
} else { else
dst = new Size(src.width * bounds.height / src.height, bounds.height); destinationSize = new Size(bounds.width, sourceSize.height * bounds.width / sourceSize.width);
}
break; break;
case ImageFit.cover: case ImageFit.cover:
if (bounds.width / bounds.height > imageSize.width / imageSize.height) { if (bounds.width / bounds.height > imageSize.width / imageSize.height)
src = new Size(imageSize.width, imageSize.width * bounds.height / bounds.width); sourceSize = new Size(imageSize.width, imageSize.width * bounds.height / bounds.width);
} else { else
src = new Size(imageSize.height * bounds.width / bounds.height, imageSize.height); sourceSize = new Size(imageSize.height * bounds.width / bounds.height, imageSize.height);
} destinationSize = bounds;
dst = bounds;
break; break;
case ImageFit.none: case ImageFit.none:
src = new Size(math.min(imageSize.width, bounds.width), sourceSize = new Size(math.min(imageSize.width, bounds.width),
math.min(imageSize.height, bounds.height)); math.min(imageSize.height, bounds.height));
dst = src; destinationSize = sourceSize;
break; break;
case ImageFit.scaleDown: case ImageFit.scaleDown:
src = imageSize; sourceSize = imageSize;
dst = bounds; destinationSize = bounds;
if (src.height > dst.height) { if (sourceSize.height > destinationSize.height)
dst = new Size(src.width * dst.height / src.height, src.height); destinationSize = new Size(sourceSize.width * destinationSize.height / sourceSize.height, sourceSize.height);
} if (sourceSize.width > destinationSize.width)
if (src.width > dst.width) { destinationSize = new Size(destinationSize.width, sourceSize.height * destinationSize.width / sourceSize.width);
dst = new Size(dst.width, src.height * dst.width / src.width);
}
break; break;
} }
// TODO(abarth): Implement |repeat|. // TODO(abarth): Implement |repeat|.
Paint paint = new Paint(); Paint paint = new Paint();
if (colorFilter != null) if (colorFilter != null)
paint.setColorFilter(colorFilter); paint.setColorFilter(colorFilter);
canvas.drawImageRect(image, Point.origin & src, rect.topLeft & dst, paint); double dx = (bounds.width - destinationSize.width) * positionX;
double dy = (bounds.height - destinationSize.height) * positionY;
Point destinationPosition = rect.topLeft + new Offset(dx, dy);
canvas.drawImageRect(image, Point.origin & sourceSize, destinationPosition & destinationSize, paint);
} }
typedef void BackgroundImageChangeListener(); typedef void BackgroundImageChangeListener();