123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291 |
- // 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 {
- SkColor GetColorAtTopLeft(const Canvas& canvas) {
- return canvas.GetBitmap().getColor(0, 0);
- }
- class MockCanvas : public SkCanvas {
- public:
- MockCanvas(int width, int height) : SkCanvas(width, height) {}
- MockCanvas(const MockCanvas&) = delete;
- MockCanvas& operator=(const MockCanvas&) = delete;
- // 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_;
- };
- // 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};
- const VectorIconRep rep_list[] = {{elements, std::size(elements)}};
- const VectorIcon icon(rep_list, 1u, 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};
- const VectorIconRep rep_list[] = {{elements, std::size(elements)}};
- const VectorIcon icon(rep_list, 1u, 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);
- }
- TEST(VectorIconTest, CorrectSizePainted) {
- // Create a set of 5 icons reps, sized {48, 32, 24, 20, 16} for the test icon.
- // Color each of them differently so they can be differentiated (the parts of
- // an icon painted with PATH_COLOR_ARGB will not be overwritten by the color
- // provided to it at creation time).
- const SkColor kPath48Color = SK_ColorRED;
- const PathElement elements48[] = {CANVAS_DIMENSIONS,
- 48,
- PATH_COLOR_ARGB,
- 0xFF,
- SkColorGetR(kPath48Color),
- SkColorGetG(kPath48Color),
- SkColorGetB(kPath48Color),
- MOVE_TO,
- 0,
- 0,
- H_LINE_TO,
- 48,
- V_LINE_TO,
- 48,
- H_LINE_TO,
- 0,
- V_LINE_TO,
- 0,
- CLOSE};
- const SkColor kPath32Color = SK_ColorGREEN;
- const PathElement elements32[] = {CANVAS_DIMENSIONS,
- 32,
- PATH_COLOR_ARGB,
- 0xFF,
- SkColorGetR(kPath32Color),
- SkColorGetG(kPath32Color),
- SkColorGetB(kPath32Color),
- MOVE_TO,
- 0,
- 0,
- H_LINE_TO,
- 32,
- V_LINE_TO,
- 32,
- H_LINE_TO,
- 0,
- V_LINE_TO,
- 0,
- CLOSE};
- const SkColor kPath24Color = SK_ColorBLUE;
- const PathElement elements24[] = {CANVAS_DIMENSIONS,
- 24,
- PATH_COLOR_ARGB,
- 0xFF,
- SkColorGetR(kPath24Color),
- SkColorGetG(kPath24Color),
- SkColorGetB(kPath24Color),
- MOVE_TO,
- 0,
- 0,
- H_LINE_TO,
- 24,
- V_LINE_TO,
- 24,
- H_LINE_TO,
- 0,
- V_LINE_TO,
- 0,
- CLOSE};
- const SkColor kPath20Color = SK_ColorYELLOW;
- const PathElement elements20[] = {CANVAS_DIMENSIONS,
- 20,
- PATH_COLOR_ARGB,
- 0xFF,
- SkColorGetR(kPath20Color),
- SkColorGetG(kPath20Color),
- SkColorGetB(kPath20Color),
- MOVE_TO,
- 0,
- 0,
- H_LINE_TO,
- 20,
- V_LINE_TO,
- 20,
- H_LINE_TO,
- 0,
- V_LINE_TO,
- 0,
- CLOSE};
- const SkColor kPath16Color = SK_ColorCYAN;
- const PathElement elements16[] = {CANVAS_DIMENSIONS,
- 16,
- PATH_COLOR_ARGB,
- 0xFF,
- SkColorGetR(kPath16Color),
- SkColorGetG(kPath16Color),
- SkColorGetB(kPath16Color),
- MOVE_TO,
- 0,
- 0,
- H_LINE_TO,
- 16,
- V_LINE_TO,
- 16,
- H_LINE_TO,
- 0,
- V_LINE_TO,
- 0,
- CLOSE};
- // VectorIconReps are always sorted in descending order of size.
- const VectorIconRep rep_list[] = {{elements48, std::size(elements48)},
- {elements32, std::size(elements32)},
- {elements24, std::size(elements24)},
- {elements20, std::size(elements20)},
- {elements16, std::size(elements16)}};
- const VectorIcon icon(rep_list, 5u, nullptr);
- // Test exact sizes paint the correctly sized icon, including the largest and
- // smallest icon.
- Canvas canvas_100(gfx::Size(100, 100), 1.0, true);
- PaintVectorIcon(&canvas_100, icon, 48, SK_ColorBLACK);
- EXPECT_EQ(kPath48Color, GetColorAtTopLeft(canvas_100));
- PaintVectorIcon(&canvas_100, icon, 32, SK_ColorBLACK);
- EXPECT_EQ(kPath32Color, GetColorAtTopLeft(canvas_100));
- PaintVectorIcon(&canvas_100, icon, 16, SK_ColorBLACK);
- EXPECT_EQ(kPath16Color, GetColorAtTopLeft(canvas_100));
- // The largest icon may be upscaled to a size larger than what it was
- // designed for.
- PaintVectorIcon(&canvas_100, icon, 50, SK_ColorBLACK);
- EXPECT_EQ(kPath48Color, GetColorAtTopLeft(canvas_100));
- // Other requests will be satisfied by downscaling.
- PaintVectorIcon(&canvas_100, icon, 27, SK_ColorBLACK);
- EXPECT_EQ(kPath32Color, GetColorAtTopLeft(canvas_100));
- PaintVectorIcon(&canvas_100, icon, 8, SK_ColorBLACK);
- EXPECT_EQ(kPath16Color, GetColorAtTopLeft(canvas_100));
- // Except in cases where an exact divisor is found.
- PaintVectorIcon(&canvas_100, icon, 40, SK_ColorBLACK);
- EXPECT_EQ(kPath20Color, GetColorAtTopLeft(canvas_100));
- PaintVectorIcon(&canvas_100, icon, 64, SK_ColorBLACK);
- EXPECT_EQ(kPath32Color, GetColorAtTopLeft(canvas_100));
- // Test icons at a scale factor < 100%, still with an exact size, paint the
- // correctly sized icon.
- Canvas canvas_75(gfx::Size(100, 100), 0.75, true);
- PaintVectorIcon(&canvas_75, icon, 32, SK_ColorBLACK); // 32 * 0.75 = 24.
- EXPECT_EQ(kPath24Color, GetColorAtTopLeft(canvas_75));
- // Test icons at a scale factor > 100%, still with an exact size, paint the
- // correctly sized icon.
- Canvas canvas_125(gfx::Size(100, 100), 1.25, true);
- PaintVectorIcon(&canvas_125, icon, 16, SK_ColorBLACK); // 16 * 1.25 = 20.
- EXPECT_EQ(kPath20Color, GetColorAtTopLeft(canvas_125));
- // Inexact sizes at scale factors < 100%.
- PaintVectorIcon(&canvas_75, icon, 12, SK_ColorBLACK); // 12 * 0.75 = 9.
- EXPECT_EQ(kPath16Color, GetColorAtTopLeft(canvas_75));
- PaintVectorIcon(&canvas_75, icon, 28, SK_ColorBLACK); // 28 * 0.75 = 21.
- EXPECT_EQ(kPath24Color, GetColorAtTopLeft(canvas_75));
- // Inexact sizes at scale factors > 100%.
- PaintVectorIcon(&canvas_125, icon, 12, SK_ColorBLACK); // 12 * 1.25 = 15.
- EXPECT_EQ(kPath16Color, GetColorAtTopLeft(canvas_125));
- PaintVectorIcon(&canvas_125, icon, 28, SK_ColorBLACK); // 28 * 1.25 = 35.
- EXPECT_EQ(kPath48Color, GetColorAtTopLeft(canvas_125));
- // Painting without a requested size will default to the smallest icon rep.
- PaintVectorIcon(&canvas_100, icon, SK_ColorBLACK);
- EXPECT_EQ(kPath16Color, GetColorAtTopLeft(canvas_100));
- // But doing this in another scale factor should assume the smallest icon rep
- // size, then scale it up by the DSF.
- PaintVectorIcon(&canvas_125, icon, SK_ColorBLACK); // 16 * 1.25 = 20.
- EXPECT_EQ(kPath20Color, GetColorAtTopLeft(canvas_125));
- }
- } // namespace
- } // namespace gfx
|