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({
ImageFit fit,
ImageRepeat repeat: ImageRepeat.noRepeat,
Rect centerSlice,
double alignX,
double alignY
FractionalOffset alignment
}) {
assert(canvas != null);
assert(image != null);
......@@ -508,6 +507,7 @@ void paintImage({
outputSize -= sliceBorder;
inputSize -= sliceBorder;
}
Point sourcePosition = Point.origin;
Size sourceSize;
Size destinationSize;
fit ??= centerSlice == null ? ImageFit.scaleDown : ImageFit.fill;
......@@ -525,10 +525,13 @@ void paintImage({
destinationSize = new Size(outputSize.width, sourceSize.height * outputSize.width / sourceSize.width);
break;
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);
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);
sourcePosition = new Point((inputSize.width - sourceSize.width) * (alignment?.dx ?? 0.5), 0.0);
}
destinationSize = outputSize;
break;
case ImageFit.none:
......@@ -566,8 +569,8 @@ void paintImage({
// to nearest-neighbor.
paint.filterQuality = FilterQuality.low;
}
double dx = (outputSize.width - destinationSize.width) * (alignX ?? 0.5);
double dy = (outputSize.height - destinationSize.height) * (alignY ?? 0.5);
double dx = (outputSize.width - destinationSize.width) * (alignment?.dx ?? 0.5);
double dy = (outputSize.height - destinationSize.height) * (alignment?.dy ?? 0.5);
Point destinationPosition = rect.topLeft + new Offset(dx, dy);
Rect destinationRect = destinationPosition & destinationSize;
if (repeat != ImageRepeat.noRepeat) {
......@@ -575,7 +578,7 @@ void paintImage({
canvas.clipRect(rect);
}
if (centerSlice == null) {
Rect sourceRect = Point.origin & sourceSize;
Rect sourceRect = sourcePosition & sourceSize;
for (Rect tileRect in _generateImageTileRects(rect, destinationRect, repeat))
canvas.drawImageRect(image, sourceRect, tileRect, paint);
} else {
......@@ -1035,8 +1038,7 @@ class _BoxDecorationPainter extends BoxPainter {
rect: rect,
image: image,
colorFilter: backgroundImage.colorFilter,
alignX: backgroundImage.alignment?.dx,
alignY: backgroundImage.alignment?.dy,
alignment: backgroundImage.alignment,
fit: backgroundImage.fit,
repeat: backgroundImage.repeat
);
......
......@@ -242,8 +242,7 @@ class RenderImage extends RenderBox {
image: _image,
colorFilter: _colorFilter,
fit: _fit,
alignX: _alignment?.dx,
alignY: _alignment?.dy,
alignment: _alignment,
centerSlice: _centerSlice,
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