1// LAF OS Library
2// Copyright (C) 2018-2022 Igara Studio S.A.
3// Copyright (C) 2012-2017 David Capello
4//
5// This file is released under the terms of the MIT license.
6// Read LICENSE.txt for more information.
7
8#ifndef OS_SKIA_SKIA_SYSTEM_INCLUDED
9#define OS_SKIA_SKIA_SYSTEM_INCLUDED
10#pragma once
11
12#include "gfx/color_space.h"
13#include "gfx/size.h"
14#include "os/common/system.h"
15#include "os/skia/skia_color_space.h"
16#include "os/skia/skia_font_manager.h"
17#include "os/skia/skia_surface.h"
18#include "os/skia/skia_window.h"
19#include "os/window_spec.h"
20
21#if LAF_WINDOWS
22 #include "os/win/color_space.h"
23 #include "os/win/system.h"
24 #define SkiaSystemBase SystemWin
25#elif LAF_MACOS
26 #include "os/osx/color_space.h"
27 #include "os/osx/system.h"
28 #define SkiaSystemBase SystemOSX
29#elif LAF_LINUX
30 #include "os/x11/system.h"
31 #define SkiaSystemBase SystemX11
32#endif
33
34#include "include/core/SkGraphics.h"
35
36#include <algorithm>
37#include <memory>
38
39namespace os {
40
41class SkiaSystem : public SkiaSystemBase {
42public:
43 SkiaSystem()
44 : m_defaultWindow(nullptr)
45 , m_gpuAcceleration(false) {
46 SkGraphics::Init();
47 }
48
49 ~SkiaSystem() {
50 // Do nothing
51 }
52
53 Capabilities capabilities() const override {
54 return Capabilities(
55 int(Capabilities::MultipleWindows) |
56 int(Capabilities::CanResizeWindow) |
57 int(Capabilities::WindowScale) |
58 int(Capabilities::CustomMouseCursor) |
59 int(Capabilities::ColorSpaces)
60#ifndef __APPLE__
61 | int(Capabilities::CanStartWindowResize)
62#endif
63#if SK_SUPPORT_GPU
64 | int(Capabilities::GpuAccelerationSwitch)
65#endif
66 );
67 }
68
69 bool gpuAcceleration() const override {
70 return m_gpuAcceleration;
71 }
72
73 void setGpuAcceleration(bool state) override {
74 m_gpuAcceleration = state;
75 }
76
77 void setTabletAPI(TabletAPI api) override {
78#if LAF_WINDOWS
79 SkiaSystemBase::setTabletAPI(api);
80 if (SkiaWindow* window = dynamic_cast<SkiaWindow*>(defaultWindow())) {
81 window->onTabletAPIChange();
82 }
83#endif
84 }
85
86 Window* defaultWindow() override {
87 return m_defaultWindow;
88 }
89
90 WindowRef makeWindow(const WindowSpec& spec) override {
91 auto window = make_ref<SkiaWindow>(spec);
92 if (!m_defaultWindow)
93 m_defaultWindow = window.get();
94 if (window && m_windowCS)
95 window->setColorSpace(m_windowCS);
96 return window;
97 }
98
99 SurfaceRef makeSurface(int width, int height,
100 const os::ColorSpaceRef& colorSpace) override {
101 auto sur = make_ref<SkiaSurface>();
102 sur->create(width, height, colorSpace);
103 return sur;
104 }
105
106 SurfaceRef makeRgbaSurface(int width, int height,
107 const os::ColorSpaceRef& colorSpace) override {
108 auto sur = make_ref<SkiaSurface>();
109 sur->createRgba(width, height, colorSpace);
110 return sur;
111 }
112
113 SurfaceRef loadSurface(const char* filename) override {
114 return SkiaSurface::loadSurface(filename);
115 }
116
117 SurfaceRef loadRgbaSurface(const char* filename) override {
118 return loadSurface(filename);
119 }
120
121 FontManager* fontManager() override {
122 if (!m_fontManager)
123 m_fontManager.reset(new SkiaFontManager);
124 return m_fontManager.get();
125 }
126
127 void setTranslateDeadKeys(bool state) override {
128 if (m_defaultWindow)
129 m_defaultWindow->setTranslateDeadKeys(state);
130 }
131
132 void listColorSpaces(std::vector<os::ColorSpaceRef>& list) override {
133 list.push_back(makeColorSpace(gfx::ColorSpace::MakeNone()));
134 list.push_back(makeColorSpace(gfx::ColorSpace::MakeSRGB()));
135
136#if LAF_WINDOWS || LAF_MACOS
137 list_display_colorspaces(list);
138#endif
139 }
140
141 os::ColorSpaceRef makeColorSpace(const gfx::ColorSpaceRef& cs) override {
142 return os::make_ref<SkiaColorSpace>(cs);
143 }
144
145 Ref<ColorSpaceConversion> convertBetweenColorSpace(
146 const os::ColorSpaceRef& src,
147 const os::ColorSpaceRef& dst) override {
148 return os::make_ref<SkiaColorSpaceConversion>(src, dst);
149 }
150
151 void setWindowsColorSpace(const os::ColorSpaceRef& cs) override {
152 m_windowCS = cs;
153
154 if (m_defaultWindow)
155 m_defaultWindow->setColorSpace(m_windowCS);
156
157 // TODO change the color space of all windows
158 }
159
160 os::ColorSpaceRef windowsColorSpace() override {
161 return m_windowCS;
162 }
163
164private:
165 SkiaWindow* m_defaultWindow;
166 Ref<FontManager> m_fontManager;
167 bool m_gpuAcceleration;
168 ColorSpaceRef m_windowCS;
169};
170
171} // namespace os
172
173#endif
174