blob: bc4a4327b47c2f028d98b3fb8af7c3fb0d8af940 [file] [log] [blame]
// Copyright 2017 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.
#include "ui/gfx/paint_vector_icon.h"
#include <gtest/gtest.h>
#include <vector>
#include "base/i18n/rtl.h"
#include "cc/paint/paint_record.h"
#include "cc/paint/paint_recorder.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkPath.h"
#include "ui/gfx/canvas.h"
#include "ui/gfx/vector_icon_types.h"
namespace gfx {
namespace {
class MockCanvas : public SkCanvas {
public:
MockCanvas(int width, int height) : SkCanvas(width, height) {}
// SkCanvas overrides:
void onDrawPath(const SkPath& path, const SkPaint& paint) override {
paths_.push_back(path);
}
const std::vector<SkPath>& paths() const { return paths_; }
private:
std::vector<SkPath> paths_;
DISALLOW_COPY_AND_ASSIGN(MockCanvas);
};
// Tests that a relative move to command (R_MOVE_TO) after a close command
// (CLOSE) uses the correct starting point. See crbug.com/697497
TEST(VectorIconTest, RelativeMoveToAfterClose) {
cc::PaintRecorder recorder;
Canvas canvas(recorder.beginRecording(100, 100), 1.0f);
const PathElement elements[] = {
MOVE_TO, 4, 5,
LINE_TO, 10, 11,
CLOSE,
// This move should use (4, 5) as the start point rather than (10, 11).
R_MOVE_TO, 20, 21,
R_LINE_TO, 50, 51,
END,
};
const VectorIcon icon = {elements, nullptr};
PaintVectorIcon(&canvas, icon, 100, SK_ColorMAGENTA);
sk_sp<cc::PaintRecord> record = recorder.finishRecordingAsPicture();
MockCanvas mock(100, 100);
record->Playback(&mock);
ASSERT_EQ(1U, mock.paths().size());
SkPoint last_point;
EXPECT_TRUE(mock.paths()[0].getLastPt(&last_point));
EXPECT_EQ(SkIntToScalar(74), last_point.x());
EXPECT_EQ(SkIntToScalar(77), last_point.y());
}
TEST(VectorIconTest, FlipsInRtl) {
// Set the locale to a rtl language otherwise FLIPS_IN_RTL will do nothing.
base::i18n::SetICUDefaultLocale("he");
ASSERT_TRUE(base::i18n::IsRTL());
const int canvas_size = 20;
const SkColor color = SK_ColorWHITE;
Canvas canvas(gfx::Size(canvas_size, canvas_size), 1.0f, true);
// Create a 20x20 square icon which has FLIPS_IN_RTL, and CANVAS_DIMENSIONS
// are twice as large as |canvas|.
const PathElement elements[] = {
CANVAS_DIMENSIONS, 2 * canvas_size,
FLIPS_IN_RTL,
MOVE_TO, 10, 10,
R_H_LINE_TO, 20,
R_V_LINE_TO, 20,
R_H_LINE_TO, -20,
CLOSE,
END,
};
const VectorIcon icon = {elements, nullptr};
PaintVectorIcon(&canvas, icon, canvas_size, color);
// Count the number of pixels in the canvas.
auto bitmap = canvas.GetBitmap();
int colored_pixel_count = 0;
for (int i = 0; i < bitmap.width(); ++i) {
for (int j = 0; j < bitmap.height(); ++j) {
if (bitmap.getColor(i, j) == color)
colored_pixel_count++;
}
}
// Verify that the amount of colored pixels on the canvas bitmap should be a
// quarter of the original icon, since each side should be scaled down by a
// factor of two.
EXPECT_EQ(100, colored_pixel_count);
}
} // namespace
} // namespace gfx