From 6cd45908c3d62f845f1847009a0c38504f0d0082 Mon Sep 17 00:00:00 2001 From: Bent Bisballe Nyeng Date: Sun, 4 Sep 2016 21:15:39 +0200 Subject: Add Canvas base class for the Painter to draw on. This is done in preparation for a new Painter unittest. --- plugingui/canvas.h | 50 ++++++++++++++++++++++ plugingui/painter.cc | 119 ++++++++++++++++++++++++--------------------------- plugingui/painter.h | 6 +-- plugingui/widget.cc | 21 +++++++++ plugingui/widget.h | 15 ++++++- plugingui/window.h | 11 +++-- 6 files changed, 151 insertions(+), 71 deletions(-) create mode 100644 plugingui/canvas.h diff --git a/plugingui/canvas.h b/plugingui/canvas.h new file mode 100644 index 0000000..8cfe083 --- /dev/null +++ b/plugingui/canvas.h @@ -0,0 +1,50 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/*************************************************************************** + * canvas.h + * + * Sun Sep 4 13:03:51 CEST 2016 + * Copyright 2016 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. + */ +#pragma once + +#include "pixelbuffer.h" + +namespace GUI +{ + +//! Abstract class that can be used by the Paiter to draw on. +class Canvas +{ +public: + //! @returns a reference to the pixel buffer. + virtual PixelBufferAlpha& GetPixelBuffer() = 0; + + //! Signal the beginning of a paint operation. + virtual void beginPaint() = 0; + + //! Signal the ending of a paint operation + //! This might trigger a redraw operation. + virtual void endPaint() = 0; + +}; + +} // GUI:: diff --git a/plugingui/painter.cc b/plugingui/painter.cc index 7d55294..db67a0e 100644 --- a/plugingui/painter.cc +++ b/plugingui/painter.cc @@ -26,32 +26,22 @@ */ #include "painter.h" -#include "window.h" - #include namespace GUI { -Painter::Painter(Widget& widget) - : widget(widget) +Painter::Painter(Canvas& canvas) + : canvas(canvas) + , pixbuf(canvas.GetPixelBuffer()) { - if(widget.window()) - { - widget.window()->beginPaint(); - } - - pixbuf = &widget.pixbuf; + canvas.beginPaint(); colour = Colour(0.0f, 0.0f, 0.0f, 0.5f); } Painter::~Painter() { - if(widget.window()) - { - widget.window()->endPaint(); - } - + canvas.endPaint(); flush(); } @@ -60,20 +50,20 @@ void Painter::setColour(const Colour& colour) this->colour = colour; } -static void plot(PixelBufferAlpha* pixbuf, const Colour& colour, +static void plot(PixelBufferAlpha& pixbuf, const Colour& colour, int x, int y, double c) { - if((x >= (int)pixbuf->width) || (y >= (int)pixbuf->height)) + if((x >= (int)pixbuf.width) || (y >= (int)pixbuf.height)) { return; } // plot the pixel at (x, y) with brightness c (where 0 ≤ c ≤ 1) - pixbuf->addPixel(x, y, - (unsigned char)(colour.red() * 255.0), - (unsigned char)(colour.green() * 255.0), - (unsigned char)(colour.blue() * 255.0), - (unsigned char)(colour.alpha() * 255 * c)); + pixbuf.addPixel(x, y, + (unsigned char)(colour.red() * 255.0), + (unsigned char)(colour.green() * 255.0), + (unsigned char)(colour.blue() * 255.0), + (unsigned char)(colour.alpha() * 255 * c)); } @@ -175,11 +165,11 @@ void Painter::drawFilledRectangle(int x1, int y1, int x2, int y2) void Painter::clear() { - for(int x = 0; x < (int)pixbuf->width; ++x) + for(int x = 0; x < (int)pixbuf.width; ++x) { - for(int y = 0; y < (int)pixbuf->height; ++y) + for(int y = 0; y < (int)pixbuf.height; ++y) { - pixbuf->setPixel(x, y, 0, 0, 0, 0); + pixbuf.setPixel(x, y, 0, 0, 0, 0); } } } @@ -192,7 +182,7 @@ void Painter::drawText(int x0, int y0, const Font& font, y0 -= textbuf->height; // The y0 offset (baseline) is the bottom of the text. // If the text offset is outside the buffer; skip it. - if((x0 > (int)pixbuf->width) || (y0 > (int)pixbuf->height)) + if((x0 > (int)pixbuf.width) || (y0 > (int)pixbuf.height)) { delete textbuf; return; @@ -200,15 +190,15 @@ void Painter::drawText(int x0, int y0, const Font& font, // Make sure we don't try to draw outside the pixbuf. int renderWidth = textbuf->width; - if(renderWidth > (int)(pixbuf->width - x0)) + if(renderWidth > (int)(pixbuf.width - x0)) { - renderWidth = pixbuf->width - x0; + renderWidth = pixbuf.width - x0; } int renderHeight = textbuf->height; - if(renderHeight > ((int)pixbuf->height - y0)) + if(renderHeight > ((int)pixbuf.height - y0)) { - renderHeight = ((int)pixbuf->height - y0); + renderHeight = ((int)pixbuf.height - y0); } if(nocolour) @@ -219,7 +209,7 @@ void Painter::drawText(int x0, int y0, const Font& font, { unsigned char r, g, b, a; textbuf->pixel(x, y, &r, &g, &b, &a); - pixbuf->addPixel(x + x0, y + y0, r, g, b, a); + pixbuf.addPixel(x + x0, y + y0, r, g, b, a); } } } @@ -231,11 +221,11 @@ void Painter::drawText(int x0, int y0, const Font& font, { unsigned char r,g,b,a; textbuf->pixel(x, y, &r, &g, &b, &a); - pixbuf->addPixel(x + x0, y + y0, - colour.red() * 255, - colour.green() * 255, - colour.blue() * 255, - colour.alpha() * a); + pixbuf.addPixel(x + x0, y + y0, + colour.red() * 255, + colour.green() * 255, + colour.blue() * 255, + colour.alpha() * a); } } } @@ -245,11 +235,11 @@ void Painter::drawText(int x0, int y0, const Font& font, void Painter::drawPoint(int x, int y) { - pixbuf->setPixel(x, y, - (unsigned char)(colour.red() * 255.0), - (unsigned char)(colour.green() * 255.0), - (unsigned char)(colour.blue() * 255.0), - (unsigned char)(colour.alpha() * 255.0)); + pixbuf.setPixel(x, y, + (unsigned char)(colour.red() * 255.0), + (unsigned char)(colour.green() * 255.0), + (unsigned char)(colour.blue() * 255.0), + (unsigned char)(colour.alpha() * 255.0)); } static void plot4points(Painter *p, int cx, int cy, int x, int y) @@ -348,26 +338,31 @@ void Painter::drawFilledCircle(int cx, int cy, int radius) void Painter::drawImage(int x0, int y0, const Drawable& image) { - size_t fw = image.width(); - size_t fh = image.height(); + int fw = image.width(); + int fh = image.height(); // Make sure we don't try to draw outside the pixbuf. - if(fw > (pixbuf->width - x0)) + if(fw > (int)(pixbuf.width - x0)) { - fw = (pixbuf->width - x0); + fw = (int)(pixbuf.width - x0); } - if(fh > (pixbuf->height - y0)) + if(fh > (int)(pixbuf.height - y0)) { - fh = (pixbuf->height - y0); + fh = (int)(pixbuf.height - y0); + } + + if((fw < 1) || (fh < 1)) + { + return; } - for(size_t y = 0; y < fh; ++y) + for(std::size_t y = -1 * std::min(0, y0); y < (std::size_t)fh; ++y) { - for(size_t x = 0; x < fw; ++x) + for(std::size_t x = -1 * std::min(0, x0); x < (std::size_t)fw; ++x) { auto& c = image.getPixel(x, y); - pixbuf->addPixel(x0 + x, y0 + y, c); + pixbuf.addPixel(x0 + x, y0 + y, c); } } } @@ -375,33 +370,33 @@ void Painter::drawImage(int x0, int y0, const Drawable& image) void Painter::drawImageStretched(int x0, int y0, const Drawable& image, int width, int height) { - if((width < 1) || (height < 1)) - { - return; - } - float fw = image.width(); float fh = image.height(); // Make sure we don't try to draw outside the pixbuf. - if(width > (int)(pixbuf->width - x0)) + if(width > (int)(pixbuf.width - x0)) { - width = pixbuf->width - x0; + width = pixbuf.width - x0; } - if(height > (int)(pixbuf->height - y0)) + if(height > (int)(pixbuf.height - y0)) { - height = pixbuf->height - y0; + height = pixbuf.height - y0; + } + + if((width < 1) || (height < 1)) + { + return; } - for(int y = 0; y < height; ++y) + for(int y = -1 * std::min(0, y0); y < height; ++y) { - for(int x = 0; x < width; ++x) + for(int x = -1 * std::min(0, x0); x < width; ++x) { int lx = ((float)x / (float)width) * fw; int ly = ((float)y / (float)height) * fh; auto& c = image.getPixel(lx, ly); - pixbuf->addPixel(x0 + x, y0 + y, c); + pixbuf.addPixel(x0 + x, y0 + y, c); } } } diff --git a/plugingui/painter.h b/plugingui/painter.h index 233d157..7e1fede 100644 --- a/plugingui/painter.h +++ b/plugingui/painter.h @@ -42,7 +42,7 @@ namespace GUI class Painter { public: - Painter(Widget& widget); + Painter(Canvas& canvas); ~Painter(); void flush(); @@ -84,8 +84,8 @@ public: void clear(); private: - Widget& widget; - PixelBufferAlpha* pixbuf; + Canvas& canvas; + PixelBufferAlpha& pixbuf; Colour colour; }; diff --git a/plugingui/widget.cc b/plugingui/widget.cc index 5cd013d..3d9d47c 100644 --- a/plugingui/widget.cc +++ b/plugingui/widget.cc @@ -133,6 +133,27 @@ size_t Widget::height() return _height; } +PixelBufferAlpha& Widget::GetPixelBuffer() +{ + return pixbuf; +} + +void Widget::beginPaint() +{ + if(_window) + { + _window->beginPaint(); + } +} + +void Widget::endPaint() +{ + if(_window) + { + _window->endPaint(); + } +} + size_t Widget::windowX() { size_t window_x = x(); diff --git a/plugingui/widget.h b/plugingui/widget.h index bbe85d0..26070c5 100644 --- a/plugingui/widget.h +++ b/plugingui/widget.h @@ -30,15 +30,21 @@ #include "pixelbuffer.h" #include "notifier.h" #include "layout.h" +#include "canvas.h" #include -namespace GUI { +namespace GUI +{ class ImageCache; class Window; -class Widget : public Listener, public LayoutItem { +class Widget + : public Listener + , public LayoutItem + , public Canvas +{ friend class Painter; public: Widget(Widget* parent); @@ -55,6 +61,11 @@ public: virtual size_t width() override; virtual size_t height() override; + // From Canvas + PixelBufferAlpha& GetPixelBuffer() override; + void beginPaint() override; + void endPaint() override; + virtual size_t windowX(); virtual size_t windowY(); diff --git a/plugingui/window.h b/plugingui/window.h index 9eb9d6d..8b186e9 100644 --- a/plugingui/window.h +++ b/plugingui/window.h @@ -34,11 +34,14 @@ #include "eventhandler.h" #include "imagecache.h" -namespace GUI { +namespace GUI +{ -class Window : public Widget { +class Window + : public Widget +{ public: - Window(void* native_window); + Window(void* native_window = nullptr); ~Window(); void setFixedSize(int width, int height); @@ -74,7 +77,7 @@ protected: void updateBuffer(); // For the Painter - friend class Painter; + friend class Widget; void beginPaint(); void endPaint(); -- cgit v1.2.3