1 // SHE library
2 // Copyright (C) 2016-2017 David Capello
3 //
4 // This file is released under the terms of the MIT license.
5 // Read LICENSE.txt for more information.
6
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10
11 #include "she/skia/skia_window_x11.h"
12
13 #include "gfx/size.h"
14 #include "she/event.h"
15 #include "she/event_queue.h"
16 #include "she/skia/skia_display.h"
17 #include "she/skia/skia_surface.h"
18 #include "she/x11/x11.h"
19
20 #include "SkBitmap.h"
21
22 namespace she {
23
24 namespace {
25
convert_skia_bitmap_to_ximage(const SkBitmap & bitmap,XImage & image)26 bool convert_skia_bitmap_to_ximage(const SkBitmap& bitmap, XImage& image)
27 {
28 memset(&image, 0, sizeof(image));
29 int bpp = 8*bitmap.bytesPerPixel();
30 image.width = bitmap.width();
31 image.height = bitmap.height();
32 image.format = ZPixmap;
33 image.data = (char*)bitmap.getPixels();
34 image.byte_order = LSBFirst;
35 image.bitmap_unit = bpp;
36 image.bitmap_bit_order = LSBFirst;
37 image.bitmap_pad = bpp;
38 image.depth = 24;
39 image.bytes_per_line = bitmap.rowBytes() - 4*bitmap.width();
40 image.bits_per_pixel = bpp;
41
42 bool result = XInitImage(&image);
43
44 return result;
45 }
46
47 } // anonymous namespace
48
SkiaWindow(EventQueue * queue,SkiaDisplay * display,int width,int height,int scale)49 SkiaWindow::SkiaWindow(EventQueue* queue, SkiaDisplay* display,
50 int width, int height, int scale)
51 : X11Window(X11::instance()->display(), width, height, scale)
52 , m_queue(queue)
53 , m_display(display)
54 {
55 }
56
~SkiaWindow()57 SkiaWindow::~SkiaWindow()
58 {
59 }
60
setVisible(bool visible)61 void SkiaWindow::setVisible(bool visible)
62 {
63 }
64
maximize()65 void SkiaWindow::maximize()
66 {
67 }
68
isMaximized() const69 bool SkiaWindow::isMaximized() const
70 {
71 return false;
72 }
73
isMinimized() const74 bool SkiaWindow::isMinimized() const
75 {
76 return false;
77 }
78
queueEvent(Event & ev)79 void SkiaWindow::queueEvent(Event& ev)
80 {
81 ev.setDisplay(m_display);
82 m_queue->queueEvent(ev);
83 }
84
paintGC(const gfx::Rect & rc)85 void SkiaWindow::paintGC(const gfx::Rect& rc)
86 {
87 SkiaSurface* surface = static_cast<SkiaSurface*>(m_display->getSurface());
88 const SkBitmap& bitmap = surface->bitmap();
89
90 int scale = this->scale();
91 if (scale == 1) {
92 XImage image;
93 if (convert_skia_bitmap_to_ximage(bitmap, image)) {
94 XPutImage(
95 x11display(), handle(), gc(), &image,
96 rc.x, rc.y,
97 rc.x, rc.y,
98 rc.w, rc.h);
99 }
100 }
101 else {
102 SkBitmap scaled;
103 if (scaled.tryAllocPixels(
104 SkImageInfo::Make(rc.w, rc.h,
105 bitmap.info().colorType(),
106 bitmap.info().alphaType()))) {
107 SkPaint paint;
108 paint.setBlendMode(SkBlendMode::kSrc);
109
110 SkCanvas canvas(scaled);
111 SkRect srcRect = SkRect::Make(SkIRect::MakeXYWH(rc.x/scale, rc.y/scale, rc.w/scale, rc.h/scale));
112 SkRect dstRect = SkRect::Make(SkIRect::MakeXYWH(0, 0, rc.w, rc.h));
113 canvas.drawBitmapRect(bitmap, srcRect, dstRect, &paint,
114 SkCanvas::kStrict_SrcRectConstraint);
115
116 XImage image;
117 if (convert_skia_bitmap_to_ximage(scaled, image)) {
118 XPutImage(
119 x11display(), handle(), gc(), &image,
120 0, 0,
121 rc.x, rc.y,
122 rc.w, rc.h);
123 }
124 }
125 }
126 }
127
resizeDisplay(const gfx::Size & sz)128 void SkiaWindow::resizeDisplay(const gfx::Size& sz)
129 {
130 m_display->resize(sz);
131 updateWindow(gfx::Rect(sz / scale()));
132 }
133
134 } // namespace she
135