Commit cdc2aefc authored by Adam Barth's avatar Adam Barth

ImageFit.cover doesn't respect alignment

We need to apply the alignment to the source rect because the ouput rect fills
the destination rect.

Fixes #1514
parent eba2d44f
...@@ -492,8 +492,7 @@ void paintImage({ ...@@ -492,8 +492,7 @@ void paintImage({
ImageFit fit, ImageFit fit,
ImageRepeat repeat: ImageRepeat.noRepeat, ImageRepeat repeat: ImageRepeat.noRepeat,
Rect centerSlice, Rect centerSlice,
double alignX, FractionalOffset alignment
double alignY
}) { }) {
assert(canvas != null); assert(canvas != null);
assert(image != null); assert(image != null);
...@@ -508,6 +507,7 @@ void paintImage({ ...@@ -508,6 +507,7 @@ void paintImage({
outputSize -= sliceBorder; outputSize -= sliceBorder;
inputSize -= sliceBorder; inputSize -= sliceBorder;
} }
Point sourcePosition = Point.origin;
Size sourceSize; Size sourceSize;
Size destinationSize; Size destinationSize;
fit ??= centerSlice == null ? ImageFit.scaleDown : ImageFit.fill; fit ??= centerSlice == null ? ImageFit.scaleDown : ImageFit.fill;
...@@ -525,10 +525,13 @@ void paintImage({ ...@@ -525,10 +525,13 @@ void paintImage({
destinationSize = new Size(outputSize.width, sourceSize.height * outputSize.width / sourceSize.width); destinationSize = new Size(outputSize.width, sourceSize.height * outputSize.width / sourceSize.width);
break; break;
case ImageFit.cover: case ImageFit.cover:
if (outputSize.width / outputSize.height > inputSize.width / inputSize.height) if (outputSize.width / outputSize.height > inputSize.width / inputSize.height) {
sourceSize = new Size(inputSize.width, inputSize.width * outputSize.height / outputSize.width); sourceSize = new Size(inputSize.width, inputSize.width * outputSize.height / outputSize.width);
else sourcePosition = new Point(0.0, (inputSize.height - sourceSize.height) * (alignment?.dy ?? 0.5));
} else {
sourceSize = new Size(inputSize.height * outputSize.width / outputSize.height, inputSize.height); sourceSize = new Size(inputSize.height * outputSize.width / outputSize.height, inputSize.height);
sourcePosition = new Point((inputSize.width - sourceSize.width) * (alignment?.dx ?? 0.5), 0.0);
}
destinationSize = outputSize; destinationSize = outputSize;
break; break;
case ImageFit.none: case ImageFit.none:
...@@ -566,8 +569,8 @@ void paintImage({ ...@@ -566,8 +569,8 @@ void paintImage({
// to nearest-neighbor. // to nearest-neighbor.
paint.filterQuality = FilterQuality.low; paint.filterQuality = FilterQuality.low;
} }
double dx = (outputSize.width - destinationSize.width) * (alignX ?? 0.5); double dx = (outputSize.width - destinationSize.width) * (alignment?.dx ?? 0.5);
double dy = (outputSize.height - destinationSize.height) * (alignY ?? 0.5); double dy = (outputSize.height - destinationSize.height) * (alignment?.dy ?? 0.5);
Point destinationPosition = rect.topLeft + new Offset(dx, dy); Point destinationPosition = rect.topLeft + new Offset(dx, dy);
Rect destinationRect = destinationPosition & destinationSize; Rect destinationRect = destinationPosition & destinationSize;
if (repeat != ImageRepeat.noRepeat) { if (repeat != ImageRepeat.noRepeat) {
...@@ -575,7 +578,7 @@ void paintImage({ ...@@ -575,7 +578,7 @@ void paintImage({
canvas.clipRect(rect); canvas.clipRect(rect);
} }
if (centerSlice == null) { if (centerSlice == null) {
Rect sourceRect = Point.origin & sourceSize; Rect sourceRect = sourcePosition & sourceSize;
for (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat)) for (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat))
canvas.drawImageRect(image, sourceRect, tileRect, paint); canvas.drawImageRect(image, sourceRect, tileRect, paint);
} else { } else {
...@@ -1035,8 +1038,7 @@ class _BoxDecorationPainter extends BoxPainter { ...@@ -1035,8 +1038,7 @@ class _BoxDecorationPainter extends BoxPainter {
rect: rect, rect: rect,
image: image, image: image,
colorFilter: backgroundImage.colorFilter, colorFilter: backgroundImage.colorFilter,
alignX: backgroundImage.alignment?.dx, alignment: backgroundImage.alignment,
alignY: backgroundImage.alignment?.dy,
fit: backgroundImage.fit, fit: backgroundImage.fit,
repeat: backgroundImage.repeat repeat: backgroundImage.repeat
); );
......
...@@ -242,8 +242,7 @@ class RenderImage extends RenderBox { ...@@ -242,8 +242,7 @@ class RenderImage extends RenderBox {
image: _image, image: _image,
colorFilter: _colorFilter, colorFilter: _colorFilter,
fit: _fit, fit: _fit,
alignX: _alignment?.dx, alignment: _alignment,
alignY: _alignment?.dy,
centerSlice: _centerSlice, centerSlice: _centerSlice,
repeat: _repeat repeat: _repeat
); );
......
// Copyright 2015 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'dart:ui' as ui;
import 'package:flutter/painting.dart';
import 'package:test/test.dart';
class TestImage implements ui.Image {
TestImage({ this.width, this.height });
final int width;
final int height;
void dispose() { }
}
class TestCanvas implements Canvas {
final List<Invocation> invocations = <Invocation>[];
void noSuchMethod(Invocation invocation) {
invocations.add(invocation);
}
}
void main() {
test("Cover and align", () {
TestImage image = new TestImage(width: 300, height: 300);
TestCanvas canvas = new TestCanvas();
paintImage(
canvas: canvas,
rect: new Rect.fromLTWH(50.0, 75.0, 200.0, 100.0),
image: image,
fit: ImageFit.cover,
alignment: new FractionalOffset(0.0, 0.5)
);
Invocation command = canvas.invocations.firstWhere((Invocation invocation) {
return invocation.memberName == #drawImageRect;
});
expect(command, isNotNull);
expect(command.positionalArguments[0], equals(image));
expect(command.positionalArguments[1], equals(new Rect.fromLTWH(0.0, 75.0, 300.0, 150.0)));
expect(command.positionalArguments[2], equals(new Rect.fromLTWH(50.0, 75.0, 200.0, 100.0)));
});
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment