blob: ac88a016c9e0e29bacaeeada318035d07a2d4357 [file] [log] [blame]
// 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.
// +build windows
package windriver
import (
"syscall"
"unsafe"
)
func mkbitmap(dc syscall.Handle, r *_RECT) (syscall.Handle, *byte, error) {
dx := r.Right - r.Left
dy := r.Bottom - r.Top
var bi _BITMAPINFO
bi.Header.Size = uint32(unsafe.Sizeof(bi.Header))
bi.Header.Width = dx
bi.Header.Height = -dy // negative height to force top-down drawing
bi.Header.Planes = 1
bi.Header.BitCount = 32
bi.Header.Compression = _BI_RGB
bi.Header.SizeImage = uint32(dx * dy * 4)
var ppvBits *byte
bitmap, err := _CreateDIBSection(dc, &bi, _DIB_RGB_COLORS, &ppvBits, 0, 0)
if err != nil {
return 0, nil, err
}
return bitmap, ppvBits, nil
}
func blend(dc syscall.Handle, bitmap syscall.Handle, dr *_RECT, sdx int32, sdy int32) error {
compatibleDC, err := _CreateCompatibleDC(dc)
if err != nil {
return err
}
prevBitmap, err := _SelectObject(compatibleDC, bitmap)
if err != nil {
return err
}
var blendfunc _BLENDFUNCTION
blendfunc.BlendOp = _AC_SRC_OVER
blendfunc.BlendFlags = 0
blendfunc.SourceConstantAlpha = 255 // only use per-pixel alphas
blendfunc.AlphaFormat = _AC_SRC_ALPHA // premultiplied
err = _AlphaBlend(dc, dr.Left, dr.Top,
dr.Right-dr.Left, dr.Bottom-dr.Top,
compatibleDC, 0, 0, sdx, sdy,
blendfunc.ToUintptr())
if err != nil {
return err
}
_, err = _SelectObject(compatibleDC, prevBitmap)
if err != nil {
return err
}
return _DeleteDC(compatibleDC)
}
// TODO(andlabs): Upload
func fillSrc(dc syscall.Handle, r *_RECT, color _COLORREF) error {
// COLORREF is 0x00BBGGRR; color is 0xAARRGGBB
color = _RGB(byte((color >> 16)), byte((color >> 8)), byte(color))
brush, err := _CreateSolidBrush(color)
if err != nil {
return err
}
err = _FillRect(dc, r, brush)
if err != nil {
return err
}
return _DeleteObject(brush)
}
func fillOver(dc syscall.Handle, r *_RECT, color _COLORREF) error {
// 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 := _RECT{
Left: 0,
Top: 0,
Right: 1,
Bottom: 1,
}
bitmap, bitvalues, err := mkbitmap(dc, &oneByOne)
if err != nil {
return err
}
*(*_COLORREF)(unsafe.Pointer(bitvalues)) = color
err = blend(dc, bitmap, r, 1, 1)
if err != nil {
return err
}
return _DeleteObject(bitmap)
}
// TODO(andlabs): Draw