fix DrawBuf.fill behavior - apply clipping rectangle

This commit is contained in:
Vadim Lopatin 2015-11-03 10:49:57 +03:00
parent a147dd2fee
commit a6a818a884
5 changed files with 182 additions and 162 deletions

View File

@ -70,11 +70,11 @@
<doXGeneration>1</doXGeneration> <doXGeneration>1</doXGeneration>
<xfilename>$(IntDir)\$(TargetName).json</xfilename> <xfilename>$(IntDir)\$(TargetName).json</xfilename>
<debuglevel>0</debuglevel> <debuglevel>0</debuglevel>
<debugids /> <debugids>DebugFocus FontResources</debugids>
<versionlevel>0</versionlevel> <versionlevel>0</versionlevel>
<versionids>EmbedStandardResources Unicode USE_FREETYPE</versionids> <versionids>EmbedStandardResources Unicode USE_FREETYPE</versionids>
<dump_source>0</dump_source> <dump_source>0</dump_source>
<mapverbosity>3</mapverbosity> <mapverbosity>0</mapverbosity>
<createImplib>0</createImplib> <createImplib>0</createImplib>
<defaultlibname /> <defaultlibname />
<debuglibname /> <debuglibname />
@ -90,7 +90,7 @@
<objfiles /> <objfiles />
<linkswitches /> <linkswitches />
<libfiles>dlangui.lib phobos.lib ole32.lib kernel32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib</libfiles> <libfiles>dlangui.lib phobos.lib ole32.lib kernel32.lib user32.lib comctl32.lib comdlg32.lib shell32.lib</libfiles>
<libpaths>../../Debug ../../../DerelictOpenGL3/source</libpaths> <libpaths>../../Debug</libpaths>
<deffile /> <deffile />
<resfile /> <resfile />
<exefile>$(OutDir)\$(ProjectName).exe</exefile> <exefile>$(OutDir)\$(ProjectName).exe</exefile>

View File

@ -190,6 +190,7 @@ extern (C) int UIAppMain(string[] args) {
// always use trace, even for release builds // always use trace, even for release builds
Log.setLogLevel(LogLevel.Trace); Log.setLogLevel(LogLevel.Trace);
Log.setFileLogger(std.stdio.File("ui.log", "w"));
// resource directory search paths // resource directory search paths
// not required if only embedded resources are used // not required if only embedded resources are used
@ -875,6 +876,7 @@ void main()
CanvasWidget canvas = new CanvasWidget("canvas"); CanvasWidget canvas = new CanvasWidget("canvas");
canvas.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT); canvas.layoutWidth(FILL_PARENT).layoutHeight(FILL_PARENT);
canvas.onDrawListener = delegate(CanvasWidget canvas, DrawBuf buf, Rect rc) { canvas.onDrawListener = delegate(CanvasWidget canvas, DrawBuf buf, Rect rc) {
Log.w("canvas.onDrawListener clipRect=" ~ to!string(buf.clipRect));
buf.fill(0xFFFFFF); buf.fill(0xFFFFFF);
int x = rc.left; int x = rc.left;
int y = rc.top; int y = rc.top;

View File

@ -21,7 +21,6 @@ public import dlangui.core.types;
import dlangui.core.logger; import dlangui.core.logger;
import dlangui.graphics.colors; import dlangui.graphics.colors;
/** /**
* 9-patch image scaling information (see Android documentation). * 9-patch image scaling information (see Android documentation).
* *
@ -120,6 +119,9 @@ class DrawBuf : RefCountedObject {
void resetClipping() { void resetClipping() {
_clipRect = Rect(0, 0, width, height); _clipRect = Rect(0, 0, width, height);
} }
@property bool hasClipping() {
return _clipRect.left != 0 || _clipRect.top != 0 || _clipRect.right != width || _clipRect.bottom != height;
}
/// returns clipping rectangle, when clipRect.isEmpty == true -- means no clipping. /// returns clipping rectangle, when clipRect.isEmpty == true -- means no clipping.
@property ref Rect clipRect() { return _clipRect; } @property ref Rect clipRect() { return _clipRect; }
/// returns clipping rectangle, or (0,0,dx,dy) when no clipping. /// returns clipping rectangle, or (0,0,dx,dy) when no clipping.
@ -736,6 +738,10 @@ class GrayDrawBuf : DrawBuf {
resetClipping(); resetClipping();
} }
override void fill(uint color) { override void fill(uint color) {
if (hasClipping) {
fillRect(_clipRect, color);
return;
}
int len = _dx * _dy; int len = _dx * _dy;
ubyte * p = _buf.ptr; ubyte * p = _buf.ptr;
ubyte cl = rgbToGray(color); ubyte cl = rgbToGray(color);
@ -961,6 +967,10 @@ class ColorDrawBuf : ColorDrawBufBase {
resetClipping(); resetClipping();
} }
override void fill(uint color) { override void fill(uint color) {
if (hasClipping) {
fillRect(_clipRect, color);
return;
}
int len = _dx * _dy; int len = _dx * _dy;
uint * p = _buf.ptr; uint * p = _buf.ptr;
for (int i = 0; i < len; i++) for (int i = 0; i < len; i++)

View File

@ -90,6 +90,10 @@ class GLDrawBuf : DrawBuf, GLConfigCallback {
/// fill the whole buffer with solid color (no clipping applied) /// fill the whole buffer with solid color (no clipping applied)
override void fill(uint color) { override void fill(uint color) {
if (hasClipping) {
fillRect(_clipRect, color);
return;
}
assert(_scene !is null); assert(_scene !is null);
_scene.add(new SolidRectSceneItem(Rect(0, 0, _dx, _dy), applyAlpha(color))); _scene.add(new SolidRectSceneItem(Rect(0, 0, _dx, _dy), applyAlpha(color)));
} }

View File

@ -1,161 +1,165 @@
// Written in the D programming language. // Written in the D programming language.
/**
This module contains drawing buffer implementation for Win32 platform
Part of Win32 platform support.
Usually you don't need to use this module directly.
Synopsis:
----
import dlangui.platforms.windows.win32drawbuf;
----
Copyright: Vadim Lopatin, 2014
License: Boost License 1.0
Authors: Vadim Lopatin, coolreader.org@gmail.com
*/
module dlangui.platforms.windows.win32drawbuf;
version(Windows):
import win32.windows; /**
import dlangui.core.logger;
import dlangui.graphics.drawbuf; This module contains drawing buffer implementation for Win32 platform
/// Win32 context ARGB drawing buffer Part of Win32 platform support.
class Win32ColorDrawBuf : ColorDrawBufBase {
private uint * _pixels; Usually you don't need to use this module directly.
private HDC _drawdc;
private HBITMAP _drawbmp;
/// returns handle of win32 device context Synopsis:
@property HDC dc() { return _drawdc; }
/// returns handle of win32 bitmap ----
@property HBITMAP bmp() { return _drawdc; } import dlangui.platforms.windows.win32drawbuf;
this(int width, int height) { ----
resize(width, height);
} Copyright: Vadim Lopatin, 2014
/// create resized copy of ColorDrawBuf License: Boost License 1.0
this(ColorDrawBuf v, int dx, int dy) { Authors: Vadim Lopatin, coolreader.org@gmail.com
this(dx, dy); */
resetClipping(); module dlangui.platforms.windows.win32drawbuf;
fill(0xFFFFFFFF);
if (_dx == dx && _dy == dy) version(Windows):
drawImage(0, 0, v);
else import win32.windows;
drawRescaled(Rect(0, 0, dx, dy), v, Rect(0, 0, v.width, v.height)); import dlangui.core.logger;
} import dlangui.graphics.drawbuf;
/// invert alpha in buffer content
void invertAlpha() { /// Win32 context ARGB drawing buffer
for(int i = _dx * _dy - 1; i >= 0; i--) class Win32ColorDrawBuf : ColorDrawBufBase {
_pixels[i] ^= 0xFF000000; private uint * _pixels;
} private HDC _drawdc;
/// returns HBITMAP for alpha private HBITMAP _drawbmp;
HBITMAP createTransparencyBitmap() { /// returns handle of win32 device context
int hbytes = (((_dx + 7) / 8) + 1) & 0xFFFFFFFE; @property HDC dc() { return _drawdc; }
static __gshared ubyte[] buf; /// returns handle of win32 bitmap
buf.length = hbytes * _dy * 2; @property HBITMAP bmp() { return _drawdc; }
//for (int y = 0; y < _dy; y++) { this(int width, int height) {
// uint * src = scanLine(y); resize(width, height);
// ubyte * dst1 = buf.ptr + (_dy - 1 - y) * hbytes; }
// ubyte * dst2 = buf.ptr + (_dy - 1 - y) * hbytes + hbytes * _dy; /// create resized copy of ColorDrawBuf
// for (int x = 0; x < _dx; x++) { this(ColorDrawBuf v, int dx, int dy) {
// ubyte pixel1 = 0x80; //(src[x] >> 24) > 0x80 ? 0 : 0x80; this(dx, dy);
// ubyte pixel2 = (src[x] >> 24) < 0x80 ? 0 : 0x80; resetClipping();
// int xi = x >> 3; fill(0xFFFFFFFF);
// dst1[xi] |= (pixel1 >> (x & 7)); if (_dx == dx && _dy == dy)
// dst2[xi] |= (pixel2 >> (x & 7)); drawImage(0, 0, v);
// } else
//} drawRescaled(Rect(0, 0, dx, dy), v, Rect(0, 0, v.width, v.height));
// debug }
for(int i = 0; i < hbytes * _dy; i++) /// invert alpha in buffer content
buf[i] = 0xFF; void invertAlpha() {
for(int i = hbytes * _dy; i < buf.length; i++) for(int i = _dx * _dy - 1; i >= 0; i--)
buf[i] = 0; //0xFF; _pixels[i] ^= 0xFF000000;
}
BITMAP b; /// returns HBITMAP for alpha
b.bmWidth = _dx; HBITMAP createTransparencyBitmap() {
b.bmHeight = _dy; int hbytes = (((_dx + 7) / 8) + 1) & 0xFFFFFFFE;
b.bmWidthBytes = hbytes; static __gshared ubyte[] buf;
b.bmPlanes = 1; buf.length = hbytes * _dy * 2;
b.bmBitsPixel = 1; //for (int y = 0; y < _dy; y++) {
b.bmBits = buf.ptr; // uint * src = scanLine(y);
return CreateBitmapIndirect(&b); // ubyte * dst1 = buf.ptr + (_dy - 1 - y) * hbytes;
//return CreateBitmap(_dx, _dy, 1, 1, buf.ptr); // ubyte * dst2 = buf.ptr + (_dy - 1 - y) * hbytes + hbytes * _dy;
} // for (int x = 0; x < _dx; x++) {
/// destroy object, but leave bitmap as is // ubyte pixel1 = 0x80; //(src[x] >> 24) > 0x80 ? 0 : 0x80;
HBITMAP destroyLeavingBitmap() { // ubyte pixel2 = (src[x] >> 24) < 0x80 ? 0 : 0x80;
HBITMAP res = _drawbmp; // int xi = x >> 3;
_drawbmp = null; // dst1[xi] |= (pixel1 >> (x & 7));
destroy(this); // dst2[xi] |= (pixel2 >> (x & 7));
return res; // }
} //}
/// Returns pointer to scan line // debug
override uint * scanLine(int y) { for(int i = 0; i < hbytes * _dy; i++)
if (y >= 0 && y < _dy) buf[i] = 0xFF;
return _pixels + _dx * (_dy - 1 - y); for(int i = hbytes * _dy; i < buf.length; i++)
return null; buf[i] = 0; //0xFF;
}
~this() { BITMAP b;
clear(); b.bmWidth = _dx;
} b.bmHeight = _dy;
/// Clear buffer contents, set dimension to 0, 0 b.bmWidthBytes = hbytes;
override void clear() { b.bmPlanes = 1;
if (_drawbmp !is null || _drawdc !is null) { b.bmBitsPixel = 1;
if (_drawbmp) b.bmBits = buf.ptr;
DeleteObject(_drawbmp); return CreateBitmapIndirect(&b);
if (_drawdc) //return CreateBitmap(_dx, _dy, 1, 1, buf.ptr);
DeleteObject(_drawdc); }
_drawbmp = null; /// destroy object, but leave bitmap as is
_drawdc = null; HBITMAP destroyLeavingBitmap() {
_pixels = null; HBITMAP res = _drawbmp;
_dx = 0; _drawbmp = null;
_dy = 0; destroy(this);
} return res;
} }
/// Change buffer size /// Returns pointer to scan line
override void resize(int width, int height) { override uint * scanLine(int y) {
if (width< 0) if (y >= 0 && y < _dy)
width = 0; return _pixels + _dx * (_dy - 1 - y);
if (height < 0) return null;
height = 0; }
if (_dx == width && _dy == height) ~this() {
clear();
}
/// Clear buffer contents, set dimension to 0, 0
override void clear() {
if (_drawbmp !is null || _drawdc !is null) {
if (_drawbmp)
DeleteObject(_drawbmp);
if (_drawdc)
DeleteObject(_drawdc);
_drawbmp = null;
_drawdc = null;
_pixels = null;
_dx = 0;
_dy = 0;
}
}
/// Change buffer size
override void resize(int width, int height) {
if (width< 0)
width = 0;
if (height < 0)
height = 0;
if (_dx == width && _dy == height)
return;
clear();
_dx = width;
_dy = height;
if (_dx > 0 && _dy > 0) {
BITMAPINFO bmi;
//memset( &bmi, 0, sizeof(bmi) );
bmi.bmiHeader.biSize = (bmi.bmiHeader.sizeof);
bmi.bmiHeader.biWidth = _dx;
bmi.bmiHeader.biHeight = _dy;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 1024;
bmi.bmiHeader.biYPelsPerMeter = 1024;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
_drawbmp = CreateDIBSection( NULL, &bmi, DIB_RGB_COLORS, cast(void**)(&_pixels), NULL, 0 );
_drawdc = CreateCompatibleDC(NULL);
SelectObject(_drawdc, _drawbmp);
}
}
/// fill with solid color
override void fill(uint color) {
if (hasClipping) {
fillRect(_clipRect, color);
return; return;
clear();
_dx = width;
_dy = height;
if (_dx > 0 && _dy > 0) {
BITMAPINFO bmi;
//memset( &bmi, 0, sizeof(bmi) );
bmi.bmiHeader.biSize = (bmi.bmiHeader.sizeof);
bmi.bmiHeader.biWidth = _dx;
bmi.bmiHeader.biHeight = _dy;
bmi.bmiHeader.biPlanes = 1;
bmi.bmiHeader.biBitCount = 32;
bmi.bmiHeader.biCompression = BI_RGB;
bmi.bmiHeader.biSizeImage = 0;
bmi.bmiHeader.biXPelsPerMeter = 1024;
bmi.bmiHeader.biYPelsPerMeter = 1024;
bmi.bmiHeader.biClrUsed = 0;
bmi.bmiHeader.biClrImportant = 0;
_drawbmp = CreateDIBSection( NULL, &bmi, DIB_RGB_COLORS, cast(void**)(&_pixels), NULL, 0 );
_drawdc = CreateCompatibleDC(NULL);
SelectObject(_drawdc, _drawbmp);
} }
} int len = _dx * _dy;
/// fill with solid color //for (int i = 0; i < len; i++)
override void fill(uint color) { // _pixels[i] = color;
int len = _dx * _dy; _pixels[0 .. len - 1] = color;
//for (int i = 0; i < len; i++) }
// _pixels[i] = color; /// draw to win32 device context
_pixels[0 .. len - 1] = color; void drawTo(HDC dc, int x, int y) {
} BitBlt(dc, x, y, _dx, _dy, _drawdc, 0, 0, SRCCOPY);
/// draw to win32 device context }
void drawTo(HDC dc, int x, int y) { }
BitBlt(dc, x, y, _dx, _dy, _drawdc, 0, 0, SRCCOPY);
}
}