File: windraw.c

package info (click to toggle)
golang-golang-x-exp 0.0~git20150826.1.eb7c1fa-1
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 2,000 kB
  • ctags: 2,884
  • sloc: objc: 239; ansic: 195; sh: 124; asm: 24; makefile: 8
file content (103 lines) | stat: -rw-r--r-- 2,669 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include "_cgo_export.h"
#include "windriver.h"

static HBITMAP mkbitmap(HDC dc, RECT *r, VOID **ppvBits) {
	BITMAPINFO bi;
	LONG dx, dy;
	HBITMAP bitmap;

	dx = r->right - r->left;
	dy = r->bottom - r->top;

	ZeroMemory(&bi, sizeof (BITMAPINFO));
	bi.bmiHeader.biSize = sizeof (BITMAPINFOHEADER);
	bi.bmiHeader.biWidth = (LONG) dx;
	bi.bmiHeader.biHeight = -((LONG) dy); // negative height to force top-down drawing
	bi.bmiHeader.biPlanes = 1;
	bi.bmiHeader.biBitCount = 32;
	bi.bmiHeader.biCompression = BI_RGB;
	bi.bmiHeader.biSizeImage = (DWORD) (dx * dy * 4);

	bitmap = CreateDIBSection(dc, &bi, DIB_RGB_COLORS, ppvBits, 0, 0);
	if (bitmap == NULL) {
		// TODO(andlabs)
	}
	return bitmap;
}

static void blend(HDC dc, HBITMAP bitmap, RECT *dr, LONG sdx, LONG sdy) {
	HDC compatibleDC;
	HBITMAP prevBitmap;
	BLENDFUNCTION blendfunc;

	compatibleDC = CreateCompatibleDC(dc);
	if (compatibleDC == NULL) {
		// TODO(andlabs)
	}
	prevBitmap = SelectObject(compatibleDC, bitmap);
	if (prevBitmap == NULL) {
		// TODO(andlabs)
	}

	ZeroMemory(&blendfunc, sizeof (BLENDFUNCTION));
	blendfunc.BlendOp = AC_SRC_OVER;
	blendfunc.BlendFlags = 0;
	blendfunc.SourceConstantAlpha = 255;  // only use per-pixel alphas
	blendfunc.AlphaFormat = AC_SRC_ALPHA; // premultiplied
	if (AlphaBlend(dc, dr->left, dr->top,
		dr->right - dr->left, dr->bottom - dr->top,
		compatibleDC, 0, 0, sdx, sdy,
		blendfunc) == FALSE) {
		// TODO
	}

	// TODO(andlabs): error check these?
	SelectObject(compatibleDC, prevBitmap);
	DeleteDC(compatibleDC);
}

// TODO(andlabs): Upload

void fillSrc(HDC dc, RECT *r, COLORREF color) {
	HBRUSH brush;

	// COLORREF is 0x00BBGGRR; color is 0xAARRGGBB
	color = RGB((color >> 16) & 0xFF,
		(color >> 8) & 0xFF,
		color & 0xFF);
	brush = CreateSolidBrush(color);
	if (brush == NULL) {
		// TODO
	}
	if (FillRect(dc, r, brush) == 0) {
		// TODO
	}
	// TODO(andlabs) check errors?
	DeleteObject(brush);
}

void fillOver(HDC dc, RECT *r, COLORREF color) {
	HBITMAP bitmap;
	VOID *ppvBits;
	RECT oneByOne;

	// AlphaBlend will stretch the input image (using StretchBlt's
	// COLORONCOLOR mode) to fill the output rectangle. Testing
	// this shows that the result appears to be the same as if we had
	// used a MxN bitmap instead.
	oneByOne.left = 0;
	oneByOne.top = 0;
	oneByOne.right = 1;
	oneByOne.bottom = 1;
	bitmap = mkbitmap(dc, &oneByOne, &ppvBits);
	*((uint32_t *) ppvBits) = color;
	blend(dc, bitmap, r, 1, 1);
	// TODO(andlabs): check errors?
	DeleteObject(bitmap);
}

// TODO(andlabs): Draw