/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * paintertest.cc * * Fri Nov 29 18:08:57 CET 2013 * Copyright 2013 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of DrumGizmo. * * DrumGizmo is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * DrumGizmo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with DrumGizmo; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include #include #include #include #include class TestColour { public: TestColour(std::uint8_t r, std::uint8_t g, std::uint8_t b, std::uint8_t a) : colour(r, g, b, a) {} TestColour(const dggui::Colour& colour) : colour(colour) {} bool operator!=(const TestColour& other) const { return colour.red() != other.colour.red() || colour.green() != other.colour.green() || colour.blue() != other.colour.blue() || colour.alpha() != other.colour.alpha() ; } const dggui::Colour colour; }; std::ostream& operator<<(std::ostream& stream, const TestColour& col) { stream << "(" << static_cast(col.colour.red()) << ", " << static_cast(col.colour.green()) << ", " << static_cast(col.colour.blue()) << ", " << static_cast(col.colour.alpha()) << ")"; return stream; } class TestableCanvas : public dggui::Canvas { public: TestableCanvas(std::size_t width, std::size_t height) : pixbuf(width, height) {} dggui::PixelBufferAlpha& getPixelBuffer() override { return pixbuf; } private: dggui::PixelBufferAlpha pixbuf; }; class TestImage : public dggui::Image { public: TestImage(std::uint8_t width, std::uint8_t height, bool alpha) : dggui::Image(":resources/logo.png") // just load some default image { _width = width; _height = height; has_alpha = alpha; image_data.resize(_width * _height); image_data_raw.resize(_width * _height); // Store x and y coordinates as red and green colour components for(std::uint8_t x = 0; x < _width; ++x) { for(std::uint8_t y = 0; y < _height; ++y) { image_data[x + _width * y] = dggui::Colour(x, y, 0, alpha ? 128 : 255); image_data_raw[4 * (x + _width * y) + 0] = x; image_data_raw[4 * (x + _width * y) + 1] = y; image_data_raw[4 * (x + _width * y) + 2] = 0; image_data_raw[4 * (x + _width * y) + 3] = alpha ? 128 : 255; } } valid = true; } }; class PainterTest : public uUnit { public: PainterTest() { uUNIT_TEST(PainterTest::testDrawImage); uUNIT_TEST(PainterTest::testDrawText); uUNIT_TEST(PainterTest::testClipping); } void testDrawImage() { // Success criterion is simply to not assert in the drawing routines... dggui::Image image(":resources/logo.png"); { // Image fits in pixelbuffer TestableCanvas canvas(image.width(), image.height()); dggui::Painter painter(canvas); painter.drawImage(0, 0, image); } { // Image fits in pixelbuffer, negative offset TestableCanvas canvas(image.width(), image.height()); dggui::Painter painter(canvas); painter.drawImage(-10, -10, image); } { // Image too big for pixelbuffer TestableCanvas canvas(image.width() / 2, image.height() / 2); dggui::Painter painter(canvas); painter.drawImage(0, 0, image); } { // Image fits in pixelbuffer but offset so it is drawn over the edge. TestableCanvas canvas(image.width(), image.height()); dggui::Painter painter(canvas); painter.drawImage(10, 10, image); } { // Image is offset to the right and down so nothing is to be drawn. TestableCanvas canvas(image.width(), image.height()); dggui::Painter painter(canvas); painter.drawImage(image.width() + 1, image.height() + 1, image); } { // Image is offset to the left and up so nothing is to be drawn. TestableCanvas canvas(image.width(), image.height()); dggui::Painter painter(canvas); painter.drawImage(-1 * (image.width() + 1), -1 * (image.height() + 1), image); } } void testDrawText() { // Success criterion is simply to not assert in the drawing routines... dggui::Font font; // a string with unicode characters std::string someText = "Hello World - лæ Библиотека"; std::size_t width = font.textWidth(someText); std::size_t height = font.textHeight(someText); { // Text fits in pixelbuffer TestableCanvas canvas(width, height); dggui::Painter painter(canvas); painter.drawText(0, 0, font, someText); } { // Text fits in pixelbuffer, negative offset TestableCanvas canvas(width, height); dggui::Painter painter(canvas); painter.drawText(-10, -10, font, someText); } { // Text too big for pixelbuffer TestableCanvas canvas(width / 2, height / 2); dggui::Painter painter(canvas); painter.drawText(0, 0, font, someText); } { // Text fits in pixelbuffer but offset so it is drawn over the edge. TestableCanvas canvas(width, height); dggui::Painter painter(canvas); painter.drawText(10, 10, font, someText); } { // Text is offset to the right and down so nothing is to be drawn. TestableCanvas canvas(width, height); dggui::Painter painter(canvas); painter.drawText(width + 1, height + 1, font, someText); } { // Text is offset to the left and up so nothing is to be drawn. TestableCanvas canvas(width, height); dggui::Painter painter(canvas); painter.drawText(-1 * (width + 1), -1 * (height + 1), font, someText); } } // Test rendering images outside the container is being clipped correctly. void testClipping() { TestableCanvas canvas(100, 100); dggui::Painter painter(canvas); { // Without alpha TestImage image(16, 16, false); painter.clear(); painter.drawImage(-10, -10, image); auto& pixbuf = canvas.getPixelBuffer(); // Top left corner pixel should have the RGBA value (10, 10, 0, 255) uUNIT_ASSERT_EQUAL(TestColour(10, 10, 0, 255), TestColour(pixbuf.pixel(0, 0))); } { // With alpha (different pipeline) TestImage image(16, 16, true); painter.clear(); painter.drawImage(-10, -10, image); auto& pixbuf = canvas.getPixelBuffer(); // Top left corner pixel should have the RGBA value (10, 10, 0, 128) uUNIT_ASSERT_EQUAL(TestColour(10, 10, 0, 128), TestColour(pixbuf.pixel(0, 0))); } } }; // Registers the fixture into the 'registry' static PainterTest test;