1 // Written in the D programming language.
2 
3 /**
4 
5 This module contains drawing buffer implementation for Win32 platform
6 
7 Part of Win32 platform support.
8 
9 Usually you don't need to use this module directly.
10 
11 
12 Synopsis:
13 
14 ----
15 import dlangui.platforms.windows.win32drawbuf;
16 ----
17 
18 Copyright: Vadim Lopatin, 2014
19 License:   Boost License 1.0
20 Authors:   Vadim Lopatin, coolreader.org@gmail.com
21 */
22 module dlangui.platforms.windows.win32drawbuf;
23 
24 version(Windows):
25 public import dlangui.core.config;
26 static if (BACKEND_GUI):
27 
28 import core.sys.windows.windows;
29 import dlangui.core.logger;
30 import dlangui.graphics.drawbuf;
31 
32 /// Win32 context ARGB drawing buffer
33 class Win32ColorDrawBuf : ColorDrawBufBase {
34     private uint * _pixels;
35     private HDC _drawdc;
36     private HBITMAP _drawbmp;
37     /// returns handle of win32 device context
38     @property HDC dc() { return _drawdc; }
39     /// returns handle of win32 bitmap
40     @property HBITMAP bmp() { return _drawdc; }
41     this(int width, int height) {
42         resize(width, height);
43     }
44     /// create resized copy of ColorDrawBuf
45     this(ColorDrawBuf v, int dx, int dy) {
46         this(dx, dy);
47         resetClipping();
48         fill(0xFFFFFFFF);
49         if (_dx == dx && _dy == dy)
50             drawImage(0, 0, v);
51         else
52             drawRescaled(Rect(0, 0, dx, dy), v, Rect(0, 0, v.width, v.height));
53     }
54     /// invert alpha in buffer content
55     void invertAlpha() {
56         for(int i = _dx * _dy - 1; i >= 0; i--)
57             _pixels[i] ^= 0xFF000000;
58     }
59     /// returns HBITMAP for alpha
60     HBITMAP createTransparencyBitmap() {
61         int hbytes = (((_dx + 7) / 8) + 1) & 0xFFFFFFFE;
62         static __gshared ubyte[] buf;
63         buf.length = hbytes * _dy * 2;
64         //for (int y = 0; y < _dy; y++) {
65         //    uint * src = scanLine(y);
66         //    ubyte * dst1 = buf.ptr + (_dy - 1 - y) * hbytes;
67         //    ubyte * dst2 = buf.ptr + (_dy - 1 - y) * hbytes + hbytes * _dy;
68         //    for (int x = 0; x < _dx; x++) {
69         //        ubyte pixel1 = 0x80; //(src[x] >> 24) > 0x80 ? 0 : 0x80;
70         //        ubyte pixel2 = (src[x] >> 24) < 0x80 ? 0 : 0x80;
71         //        int xi = x >> 3;
72         //        dst1[xi] |= (pixel1 >> (x & 7));
73         //        dst2[xi] |= (pixel2 >> (x & 7));
74         //    }
75         //}
76         // debug
77         for(int i = 0; i < hbytes * _dy; i++)
78             buf[i] = 0xFF;
79         for(int i = hbytes * _dy; i < buf.length; i++)
80             buf[i] = 0; //0xFF;
81 
82         BITMAP b;
83         b.bmWidth = _dx;
84         b.bmHeight = _dy;
85         b.bmWidthBytes = hbytes;
86         b.bmPlanes = 1;
87         b.bmBitsPixel = 1;
88         b.bmBits = buf.ptr;
89         return CreateBitmapIndirect(&b);
90         //return CreateBitmap(_dx, _dy, 1, 1, buf.ptr);
91     }
92     /// destroy object, but leave bitmap as is
93     HBITMAP destroyLeavingBitmap() {
94         HBITMAP res = _drawbmp;
95         _drawbmp = null;
96         destroy(this);
97         return res;
98     }
99     /// Returns pointer to scan line
100     override uint * scanLine(int y) {
101         if (y >= 0 && y < _dy)
102             return _pixels + _dx * (_dy - 1 - y);
103         return null;
104     }
105     ~this() {
106         clear();
107     }
108     /// Clear buffer contents, set dimension to 0, 0
109     override void clear() {
110         if (_drawbmp !is null || _drawdc !is null) {
111             if (_drawbmp)
112                 DeleteObject(_drawbmp);
113             if (_drawdc)
114                 DeleteObject(_drawdc);
115             _drawbmp = null;
116             _drawdc = null;
117             _pixels = null;
118             _dx = 0;
119             _dy = 0;
120         }
121     }
122     /// Change buffer size
123     override void resize(int width, int height) {
124         if (width< 0)
125             width = 0;
126         if (height < 0)
127             height = 0;
128         if (_dx == width && _dy == height)
129             return;
130         clear();
131         _dx = width;
132         _dy = height;
133         if (_dx > 0 && _dy > 0) {
134             BITMAPINFO bmi;
135             //memset( &bmi, 0, sizeof(bmi) );
136             bmi.bmiHeader.biSize = (bmi.bmiHeader.sizeof);
137             bmi.bmiHeader.biWidth = _dx;
138             bmi.bmiHeader.biHeight = _dy;
139             bmi.bmiHeader.biPlanes = 1;
140             bmi.bmiHeader.biBitCount = 32;
141             bmi.bmiHeader.biCompression = BI_RGB;
142             bmi.bmiHeader.biSizeImage = 0;
143             bmi.bmiHeader.biXPelsPerMeter = 1024;
144             bmi.bmiHeader.biYPelsPerMeter = 1024;
145             bmi.bmiHeader.biClrUsed = 0;
146             bmi.bmiHeader.biClrImportant = 0;
147             _drawbmp = CreateDIBSection( NULL, &bmi, DIB_RGB_COLORS, cast(void**)(&_pixels), NULL, 0 );
148             _drawdc = CreateCompatibleDC(NULL);
149             SelectObject(_drawdc, _drawbmp);
150         }
151     }
152     /// fill with solid color
153     override void fill(uint color) {
154         if (hasClipping) {
155             fillRect(_clipRect, color);
156             return;
157         }
158         int len = _dx * _dy;
159         //for (int i = 0; i < len; i++)
160         //    _pixels[i] = color;
161         _pixels[0 .. len] = color;
162     }
163     /// draw to win32 device context
164     void drawTo(HDC dc, int x, int y) {
165         BitBlt(dc, x, y, _dx, _dy, _drawdc, 0, 0, SRCCOPY);
166     }
167 }