diff --git a/src/she/CMakeLists.txt b/src/she/CMakeLists.txt index 8c44c4868..d3be9ead9 100644 --- a/src/she/CMakeLists.txt +++ b/src/she/CMakeLists.txt @@ -86,6 +86,8 @@ if(USE_SKIA_BACKEND) CACHE INTERNAL "Skia libraries") list(APPEND SHE_SOURCES + skia/skia_display.cpp + skia/skia_window.cpp skia/she.cpp) if(WIN32) diff --git a/src/she/common/font.h b/src/she/common/font.h index 862070698..a85332fd3 100644 --- a/src/she/common/font.h +++ b/src/she/common/font.h @@ -10,6 +10,9 @@ #include "base/string.h" #include "she/font.h" +#include "she/locked_surface.h" +#include "she/scoped_surface_lock.h" +#include "she/surface.h" namespace she { diff --git a/src/she/skia/she.cpp b/src/she/skia/she.cpp index a087b6986..7592e7987 100644 --- a/src/she/skia/she.cpp +++ b/src/she/skia/she.cpp @@ -14,18 +14,6 @@ #include "she/common/system.h" -#ifdef _WIN32 - #include - - #include "she/win/window.h" -#else - #error There is no Window implementation -#endif - -#include "she/skia/skia_surface.h" -#include "she/skia/skia_event_queue.h" -#include "she/skia/skia_window.h" -#include "she/skia/skia_display.h" #include "she/skia/skia_system.h" namespace she { diff --git a/src/she/skia/skia_display.cpp b/src/she/skia/skia_display.cpp new file mode 100644 index 000000000..c3a1f294d --- /dev/null +++ b/src/she/skia/skia_display.cpp @@ -0,0 +1,131 @@ +// SHE library +// Copyright (C) 2012-2015 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "she/skia/skia_display.h" + +namespace she { + +SkiaDisplay::SkiaDisplay(int width, int height, int scale) + : m_window(&m_queue, this) + , m_surface(new SkiaSurface) +{ + m_surface->create(width, height); + m_window.setScale(scale); + m_window.setVisible(true); + m_recreated = false; +} + +void SkiaDisplay::resize(const gfx::Size& size) +{ + m_surface->dispose(); + m_surface = new SkiaSurface; + m_surface->create(size.w, size.h); + m_recreated = true; +} + +void SkiaDisplay::dispose() +{ + delete this; +} + +int SkiaDisplay::width() const +{ + return m_window.clientSize().w; +} + +int SkiaDisplay::height() const +{ + return m_window.clientSize().h; +} + +int SkiaDisplay::originalWidth() const +{ + return m_window.restoredSize().w; +} + +int SkiaDisplay::originalHeight() const +{ + return m_window.restoredSize().h; +} + +void SkiaDisplay::setScale(int scale) +{ + m_window.setScale(scale); +} + +int SkiaDisplay::scale() const +{ + return m_window.scale(); +} + +NonDisposableSurface* SkiaDisplay::getSurface() +{ + return static_cast(m_surface); +} + +// Flips all graphics in the surface to the real display. Returns +// false if the flip couldn't be done because the display was +// resized. +bool SkiaDisplay::flip() +{ + if (m_recreated) { + m_recreated = false; + return false; + } + + m_window.invalidate(); + return true; +} + +void SkiaDisplay::maximize() +{ + m_window.maximize(); +} + +bool SkiaDisplay::isMaximized() const +{ + return m_window.isMaximized(); +} + +void SkiaDisplay::setTitleBar(const std::string& title) +{ + m_window.setText(title); +} + +EventQueue* SkiaDisplay::getEventQueue() +{ + return &m_queue; +} + +bool SkiaDisplay::setNativeMouseCursor(NativeCursor cursor) +{ + return true; +} + +void SkiaDisplay::setMousePosition(const gfx::Point& position) +{ +} + +void SkiaDisplay::captureMouse() +{ + m_window.captureMouse(); +} + +void SkiaDisplay::releaseMouse() +{ + m_window.releaseMouse(); +} + +DisplayHandle SkiaDisplay::nativeHandle() +{ + return (DisplayHandle)m_window.handle(); +} + +} // namespace she diff --git a/src/she/skia/skia_display.h b/src/she/skia/skia_display.h index 7117c025b..d763d3dcf 100644 --- a/src/she/skia/skia_display.h +++ b/src/she/skia/skia_display.h @@ -4,101 +4,63 @@ // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. +#ifndef SHE_SKIA_SKIA_DISPLAY_INCLUDED +#define SHE_SKIA_SKIA_DISPLAY_INCLUDED +#pragma once + +#include "she/display.h" +#include "she/skia/skia_event_queue.h" +#include "she/skia/skia_window.h" + namespace she { +class SkiaSurface; + class SkiaDisplay : public Display { public: - SkiaDisplay(int width, int height, int scale) - : m_window(&m_queue, this) { - m_surface.create(width, height); - m_window.setScale(scale); - m_window.setVisible(true); - } + SkiaDisplay(int width, int height, int scale); - void dispose() override { - delete this; - } + void resize(const gfx::Size& size); + void dispose() override; // Returns the real and current display's size (without scale applied). - int width() const override { - return m_window.clientSize().w; - } - - int height() const override { - return m_window.clientSize().h; - } + int width() const override; + int height() const override; // Returns the display when it was not maximized. - int originalWidth() const override { - return m_window.restoredSize().w; - } + int originalWidth() const override; + int originalHeight() const override; - int originalHeight() const override { - return m_window.restoredSize().h; - } - - void setScale(int scale) override { - m_window.setScale(scale); - } - - int scale() const override { - return m_window.scale(); - } + void setScale(int scale) override; + int scale() const override; // Returns the main surface to draw into this display. // You must not dispose this surface. - NonDisposableSurface* getSurface() override { - return static_cast(&m_surface); - } + NonDisposableSurface* getSurface() override; // Flips all graphics in the surface to the real display. Returns // false if the flip couldn't be done because the display was // resized. - bool flip() override { - m_window.invalidate(); - return true; - } - - void maximize() override { - m_window.maximize(); - } - - bool isMaximized() const override { - return m_window.isMaximized(); - } - - void setTitleBar(const std::string& title) override { - m_window.setText(title); - } - - EventQueue* getEventQueue() override { - return &m_queue; - } - - bool setNativeMouseCursor(NativeCursor cursor) override { - return true; - } - - void setMousePosition(const gfx::Point& position) override { - } - - void captureMouse() override { - m_window.captureMouse(); - } - - void releaseMouse() override { - m_window.releaseMouse(); - } + bool flip() override; + void maximize() override; + bool isMaximized() const override; + void setTitleBar(const std::string& title) override; + EventQueue* getEventQueue() override; + bool setNativeMouseCursor(NativeCursor cursor) override; + void setMousePosition(const gfx::Point& position) override; + void captureMouse() override; + void releaseMouse() override; // Returns the HWND on Windows. - DisplayHandle nativeHandle() override { - return (DisplayHandle)m_window.handle(); - } + DisplayHandle nativeHandle() override; private: SkiaEventQueue m_queue; SkiaWindow m_window; - SkiaSurface m_surface; + SkiaSurface* m_surface; + bool m_recreated; }; } // namespace she + +#endif diff --git a/src/she/skia/skia_event_queue.h b/src/she/skia/skia_event_queue.h index f49976a11..facb65472 100644 --- a/src/she/skia/skia_event_queue.h +++ b/src/she/skia/skia_event_queue.h @@ -4,8 +4,17 @@ // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. +#ifndef SHE_SKIA_SKIA_EVENT_QUEUE_INCLUDED +#define SHE_SKIA_SKIA_EVENT_QUEUE_INCLUDED +#pragma once + #include +#include + +#include "she/event.h" +#include "she/event_queue.h" + namespace she { class SkiaEventQueue : public EventQueue { @@ -56,3 +65,5 @@ private: }; } // namespace she + +#endif diff --git a/src/she/skia/skia_system.h b/src/she/skia/skia_system.h index d9be7ed51..604c20274 100644 --- a/src/she/skia/skia_system.h +++ b/src/she/skia/skia_system.h @@ -4,12 +4,19 @@ // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. +#ifndef SHE_SKIA_SKIA_SYSTEM_INCLUDED +#define SHE_SKIA_SKIA_SYSTEM_INCLUDED +#pragma once + #include "base/file_handle.h" #include "SkImageDecoder.h" #include "SkPixelRef.h" #include "SkStream.h" +#include "she/skia/skia_display.h" +#include "she/skia/skia_surface.h" + namespace she { class SkiaSystem : public CommonSystem { @@ -88,3 +95,5 @@ private: }; } // namespace she + +#endif diff --git a/src/she/skia/skia_window.cpp b/src/she/skia/skia_window.cpp new file mode 100644 index 000000000..8295ba56b --- /dev/null +++ b/src/she/skia/skia_window.cpp @@ -0,0 +1,62 @@ +// SHE library +// Copyright (C) 2012-2015 David Capello +// +// This file is released under the terms of the MIT license. +// Read LICENSE.txt for more information. + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "she/skia/skia_window.h" + +#include "she/skia/skia_display.h" + +namespace she { + +SkiaWindow::SkiaWindow(SkiaEventQueue* queue, SkiaDisplay* display) + : m_queue(queue) + , m_display(display) +{ +} + +void SkiaWindow::queueEventImpl(Event& ev) +{ + ev.setDisplay(m_display); + m_queue->queueEvent(ev); +} + +void SkiaWindow::paintImpl(HDC hdc) +{ + SkiaSurface* surface = static_cast(m_display->getSurface()); + const SkBitmap& bitmap = surface->bitmap(); + + BITMAPINFO bmi; + memset(&bmi, 0, sizeof(bmi)); + bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmi.bmiHeader.biWidth = bitmap.width(); + bmi.bmiHeader.biHeight = -bitmap.height(); + bmi.bmiHeader.biPlanes = 1; + bmi.bmiHeader.biBitCount = 32; + bmi.bmiHeader.biCompression = BI_RGB; + bmi.bmiHeader.biSizeImage = 0; + + ASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes()); + bitmap.lockPixels(); + + int ret = StretchDIBits(hdc, + 0, 0, bitmap.width()*scale(), bitmap.height()*scale(), + 0, 0, bitmap.width(), bitmap.height(), + bitmap.getPixels(), + &bmi, DIB_RGB_COLORS, SRCCOPY); + (void)ret; + + bitmap.unlockPixels(); +} + +void SkiaWindow::resizeImpl(const gfx::Size& size) +{ + m_display->resize(size); +} + +} // namespace she diff --git a/src/she/skia/skia_window.h b/src/she/skia/skia_window.h index f586e0fc9..068b0c3fd 100644 --- a/src/she/skia/skia_window.h +++ b/src/she/skia/skia_window.h @@ -4,50 +4,35 @@ // This file is released under the terms of the MIT license. // Read LICENSE.txt for more information. +#ifndef SHE_SKIA_SKIA_WINDOW_INCLUDED +#define SHE_SKIA_SKIA_WINDOW_INCLUDED +#pragma once + +#ifdef _WIN32 + #include "she/win/window.h" +#else + #error There is no Window implementation +#endif + +#include "she/skia/skia_event_queue.h" +#include "she/skia/skia_surface.h" + namespace she { +class SkiaDisplay; + class SkiaWindow : public Window { public: - SkiaWindow(SkiaEventQueue* queue, Display* display) - : m_queue(queue) - , m_display(display) { - } - - void queueEventImpl(Event& ev) { - ev.setDisplay(m_display); - m_queue->queueEvent(ev); - } - - void paintImpl(HDC hdc) { - SkiaSurface* surface = static_cast(m_display->getSurface()); - const SkBitmap& bitmap = surface->bitmap(); - - BITMAPINFO bmi; - memset(&bmi, 0, sizeof(bmi)); - bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - bmi.bmiHeader.biWidth = bitmap.width(); - bmi.bmiHeader.biHeight = -bitmap.height(); - bmi.bmiHeader.biPlanes = 1; - bmi.bmiHeader.biBitCount = 32; - bmi.bmiHeader.biCompression = BI_RGB; - bmi.bmiHeader.biSizeImage = 0; - - ASSERT(bitmap.width() * bitmap.bytesPerPixel() == bitmap.rowBytes()); - bitmap.lockPixels(); - - int ret = StretchDIBits(hdc, - 0, 0, bitmap.width()*scale(), bitmap.height()*scale(), - 0, 0, bitmap.width(), bitmap.height(), - bitmap.getPixels(), - &bmi, DIB_RGB_COLORS, SRCCOPY); - (void)ret; - - bitmap.unlockPixels(); - } + SkiaWindow(SkiaEventQueue* queue, SkiaDisplay* display); + void queueEventImpl(Event& ev); + void paintImpl(HDC hdc); + void resizeImpl(const gfx::Size& size); private: SkiaEventQueue* m_queue; - Display* m_display; + SkiaDisplay* m_display; }; } // namespace she + +#endif diff --git a/src/she/win/window.h b/src/she/win/window.h index 7a4aa830b..7fa7e7d37 100644 --- a/src/she/win/window.h +++ b/src/she/win/window.h @@ -12,6 +12,8 @@ #include #include +#include "gfx/size.h" +#include "she/event.h" #include "she/keys.h" #ifndef WM_MOUSEHWHEEL @@ -118,6 +120,8 @@ namespace she { case SIZE_RESTORED: m_clientSize.w = GET_X_LPARAM(lparam); m_clientSize.h = GET_Y_LPARAM(lparam); + + static_cast(this)->resizeImpl(m_clientSize); break; }