mirror of https://github.com/buggins/dlangui.git
rework clipping
This commit is contained in:
parent
b1e133c21b
commit
108709d0de
|
@ -207,27 +207,36 @@ class DrawBuf : RefCountedObject {
|
||||||
// ===================================================
|
// ===================================================
|
||||||
// clipping rectangle functions
|
// clipping rectangle functions
|
||||||
|
|
||||||
|
/// init clip rectangle to full buffer size
|
||||||
|
void resetClipping() {
|
||||||
|
_clipRect = Rect(0, 0, width, 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.
|
||||||
@property Rect clipOrFullRect() { return _clipRect.empty ? Rect(0,0,width,height) : _clipRect; }
|
//@property Rect clipOrFullRect() { return _clipRect.empty ? Rect(0,0,width,height) : _clipRect; }
|
||||||
/// sets new clipping rectangle, when clipRect.isEmpty == true -- means no clipping.
|
/// sets new clipping rectangle, when clipRect.isEmpty == true -- means no clipping.
|
||||||
@property void clipRect(const ref Rect rect) {
|
@property void clipRect(const ref Rect rect) {
|
||||||
_clipRect = rect;
|
_clipRect = rect;
|
||||||
_clipRect.intersect(Rect(0, 0, width, height));
|
_clipRect.intersect(Rect(0, 0, width, height));
|
||||||
}
|
}
|
||||||
/// sets new clipping rectangle, when clipRect.isEmpty == true -- means no clipping.
|
/// sets new clipping rectangle, intersect with previous one.
|
||||||
@property void intersectClipRect(const ref Rect rect) {
|
@property void intersectClipRect(const ref Rect rect) {
|
||||||
if (_clipRect.empty)
|
//if (_clipRect.empty)
|
||||||
_clipRect = rect;
|
// _clipRect = rect;
|
||||||
else
|
//else
|
||||||
_clipRect.intersect(rect);
|
_clipRect.intersect(rect);
|
||||||
_clipRect.intersect(Rect(0, 0, width, height));
|
_clipRect.intersect(Rect(0, 0, width, height));
|
||||||
}
|
}
|
||||||
|
/// returns true if rectangle is completely clipped out and cannot be drawn.
|
||||||
|
@property bool isClippedOut(const ref Rect rect) {
|
||||||
|
//Rect rc = clipOrFullRect();
|
||||||
|
return !_clipRect.intersects(rect);
|
||||||
|
}
|
||||||
/// apply clipRect and buffer bounds clipping to rectangle
|
/// apply clipRect and buffer bounds clipping to rectangle
|
||||||
bool applyClipping(ref Rect rc) {
|
bool applyClipping(ref Rect rc) {
|
||||||
if (!_clipRect.empty())
|
//if (!_clipRect.empty())
|
||||||
rc.intersect(_clipRect);
|
rc.intersect(_clipRect);
|
||||||
if (rc.left < 0)
|
if (rc.left < 0)
|
||||||
rc.left = 0;
|
rc.left = 0;
|
||||||
if (rc.top < 0)
|
if (rc.top < 0)
|
||||||
|
@ -242,12 +251,12 @@ class DrawBuf : RefCountedObject {
|
||||||
bool applyClipping(ref Rect rc, ref Rect rc2) {
|
bool applyClipping(ref Rect rc, ref Rect rc2) {
|
||||||
if (rc.empty || rc2.empty)
|
if (rc.empty || rc2.empty)
|
||||||
return false;
|
return false;
|
||||||
if (!_clipRect.empty())
|
//if (!_clipRect.empty())
|
||||||
if (!rc.intersects(_clipRect))
|
if (!rc.intersects(_clipRect))
|
||||||
return false;
|
return false;
|
||||||
if (rc.width == rc2.width && rc.height == rc2.height) {
|
if (rc.width == rc2.width && rc.height == rc2.height) {
|
||||||
// unscaled
|
// unscaled
|
||||||
if (!_clipRect.empty()) {
|
//if (!_clipRect.empty) {
|
||||||
if (rc.left < _clipRect.left) {
|
if (rc.left < _clipRect.left) {
|
||||||
rc2.left += _clipRect.left - rc.left;
|
rc2.left += _clipRect.left - rc.left;
|
||||||
rc.left = _clipRect.left;
|
rc.left = _clipRect.left;
|
||||||
|
@ -264,7 +273,7 @@ class DrawBuf : RefCountedObject {
|
||||||
rc2.bottom -= rc.bottom - _clipRect.bottom;
|
rc2.bottom -= rc.bottom - _clipRect.bottom;
|
||||||
rc.bottom = _clipRect.bottom;
|
rc.bottom = _clipRect.bottom;
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
if (rc.left < 0) {
|
if (rc.left < 0) {
|
||||||
rc2.left += -rc.left;
|
rc2.left += -rc.left;
|
||||||
rc.left = 0;
|
rc.left = 0;
|
||||||
|
@ -287,7 +296,7 @@ class DrawBuf : RefCountedObject {
|
||||||
int dstdy = rc.height;
|
int dstdy = rc.height;
|
||||||
int srcdx = rc2.width;
|
int srcdx = rc2.width;
|
||||||
int srcdy = rc2.height;
|
int srcdy = rc2.height;
|
||||||
if (!_clipRect.empty()) {
|
//if (!_clipRect.empty) {
|
||||||
if (rc.left < _clipRect.left) {
|
if (rc.left < _clipRect.left) {
|
||||||
rc2.left += (_clipRect.left - rc.left) * srcdx / dstdx;
|
rc2.left += (_clipRect.left - rc.left) * srcdx / dstdx;
|
||||||
rc.left = _clipRect.left;
|
rc.left = _clipRect.left;
|
||||||
|
@ -304,7 +313,7 @@ class DrawBuf : RefCountedObject {
|
||||||
rc2.bottom -= (rc.bottom - _clipRect.bottom) * srcdy / dstdy;
|
rc2.bottom -= (rc.bottom - _clipRect.bottom) * srcdy / dstdy;
|
||||||
rc.bottom = _clipRect.bottom;
|
rc.bottom = _clipRect.bottom;
|
||||||
}
|
}
|
||||||
}
|
//}
|
||||||
if (rc.left < 0) {
|
if (rc.left < 0) {
|
||||||
rc2.left -= (rc.left) * srcdx / dstdx;
|
rc2.left -= (rc.left) * srcdx / dstdx;
|
||||||
rc.left = 0;
|
rc.left = 0;
|
||||||
|
@ -397,7 +406,9 @@ class DrawBuf : RefCountedObject {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {}
|
void clear() {
|
||||||
|
resetClipping();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
alias DrawBufRef = Ref!DrawBuf;
|
alias DrawBufRef = Ref!DrawBuf;
|
||||||
|
@ -576,7 +587,7 @@ class ColorDrawBufBase : DrawBuf {
|
||||||
ubyte[] src = glyph.glyph;
|
ubyte[] src = glyph.glyph;
|
||||||
int srcdx = glyph.blackBoxX;
|
int srcdx = glyph.blackBoxX;
|
||||||
int srcdy = glyph.blackBoxY;
|
int srcdy = glyph.blackBoxY;
|
||||||
bool clipping = !_clipRect.empty();
|
bool clipping = true; //!_clipRect.empty();
|
||||||
color = applyAlpha(color);
|
color = applyAlpha(color);
|
||||||
for (int yy = 0; yy < srcdy; yy++) {
|
for (int yy = 0; yy < srcdy; yy++) {
|
||||||
int liney = y + yy;
|
int liney = y + yy;
|
||||||
|
@ -646,6 +657,7 @@ class GrayDrawBuf : DrawBuf {
|
||||||
_dx = width;
|
_dx = width;
|
||||||
_dy = height;
|
_dy = height;
|
||||||
_buf.length = _dx * _dy;
|
_buf.length = _dx * _dy;
|
||||||
|
resetClipping();
|
||||||
}
|
}
|
||||||
override void fill(uint color) {
|
override void fill(uint color) {
|
||||||
int len = _dx * _dy;
|
int len = _dx * _dy;
|
||||||
|
@ -772,7 +784,7 @@ class GrayDrawBuf : DrawBuf {
|
||||||
ubyte[] src = glyph.glyph;
|
ubyte[] src = glyph.glyph;
|
||||||
int srcdx = glyph.blackBoxX;
|
int srcdx = glyph.blackBoxX;
|
||||||
int srcdy = glyph.blackBoxY;
|
int srcdy = glyph.blackBoxY;
|
||||||
bool clipping = !_clipRect.empty();
|
bool clipping = true; //!_clipRect.empty();
|
||||||
ubyte cl = cast(ubyte)(color & 255);
|
ubyte cl = cast(ubyte)(color & 255);
|
||||||
for (int yy = 0; yy < srcdy; yy++) {
|
for (int yy = 0; yy < srcdy; yy++) {
|
||||||
int liney = y + yy;
|
int liney = y + yy;
|
||||||
|
@ -854,6 +866,7 @@ class ColorDrawBuf : ColorDrawBufBase {
|
||||||
_dx = width;
|
_dx = width;
|
||||||
_dy = height;
|
_dy = height;
|
||||||
_buf.length = _dx * _dy;
|
_buf.length = _dx * _dy;
|
||||||
|
resetClipping();
|
||||||
}
|
}
|
||||||
override void fill(uint color) {
|
override void fill(uint color) {
|
||||||
int len = _dx * _dy;
|
int len = _dx * _dy;
|
||||||
|
|
|
@ -273,7 +273,7 @@ class Font : RefCountedObject {
|
||||||
if (_textSizeBuffer.length < text.length)
|
if (_textSizeBuffer.length < text.length)
|
||||||
_textSizeBuffer.length = text.length;
|
_textSizeBuffer.length = text.length;
|
||||||
int charsMeasured = measureText(text, _textSizeBuffer, MAX_WIDTH_UNSPECIFIED, tabSize, tabOffset, textFlags);
|
int charsMeasured = measureText(text, _textSizeBuffer, MAX_WIDTH_UNSPECIFIED, tabSize, tabOffset, textFlags);
|
||||||
Rect clip = buf.clipOrFullRect;
|
Rect clip = buf.clipRect; //clipOrFullRect;
|
||||||
if (clip.empty)
|
if (clip.empty)
|
||||||
return; // not visible - clipped out
|
return; // not visible - clipped out
|
||||||
if (y + height < clip.top || y >= clip.bottom)
|
if (y + height < clip.top || y >= clip.bottom)
|
||||||
|
|
|
@ -71,6 +71,7 @@ class GLDrawBuf : DrawBuf {
|
||||||
override void resize(int width, int height) {
|
override void resize(int width, int height) {
|
||||||
_dx = width;
|
_dx = width;
|
||||||
_dy = height;
|
_dy = height;
|
||||||
|
resetClipping();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// fill the whole buffer with solid color (no clipping applied)
|
/// fill the whole buffer with solid color (no clipping applied)
|
||||||
|
|
|
@ -344,6 +344,7 @@ version(USE_SDL) {
|
||||||
if (!_drawbuf)
|
if (!_drawbuf)
|
||||||
_drawbuf = new ColorDrawBuf(_dx, _dy);
|
_drawbuf = new ColorDrawBuf(_dx, _dy);
|
||||||
_drawbuf.resize(_dx, _dy);
|
_drawbuf.resize(_dx, _dy);
|
||||||
|
_drawbuf.resetClipping();
|
||||||
_drawbuf.fill(_backgroundColor);
|
_drawbuf.fill(_backgroundColor);
|
||||||
onDraw(_drawbuf);
|
onDraw(_drawbuf);
|
||||||
draw(_drawbuf);
|
draw(_drawbuf);
|
||||||
|
|
|
@ -281,6 +281,7 @@ class Win32Window : Window {
|
||||||
_drawbuf = new Win32ColorDrawBuf(_dx, _dy);
|
_drawbuf = new Win32ColorDrawBuf(_dx, _dy);
|
||||||
else
|
else
|
||||||
_drawbuf.resize(_dx, _dy);
|
_drawbuf.resize(_dx, _dy);
|
||||||
|
_drawbuf.resetClipping();
|
||||||
return _drawbuf;
|
return _drawbuf;
|
||||||
}
|
}
|
||||||
override void show() {
|
override void show() {
|
||||||
|
|
|
@ -103,6 +103,7 @@ class TextWidget : Widget {
|
||||||
applyMargins(rc);
|
applyMargins(rc);
|
||||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||||
applyPadding(rc);
|
applyPadding(rc);
|
||||||
|
|
||||||
FontRef font = font();
|
FontRef font = font();
|
||||||
Point sz = font.textSize(text);
|
Point sz = font.textSize(text);
|
||||||
applyAlign(rc, sz);
|
applyAlign(rc, sz);
|
||||||
|
@ -795,7 +796,7 @@ class ScrollBar : AbstractSlider, OnClickHandler {
|
||||||
|
|
||||||
/// Draw widget at its position to buffer
|
/// Draw widget at its position to buffer
|
||||||
override void onDraw(DrawBuf buf) {
|
override void onDraw(DrawBuf buf) {
|
||||||
if (visibility != Visibility.Visible)
|
if (visibility != Visibility.Visible && !buf.isClippedOut(_pos))
|
||||||
return;
|
return;
|
||||||
super.onDraw(buf);
|
super.onDraw(buf);
|
||||||
Rect rc = _pos;
|
Rect rc = _pos;
|
||||||
|
|
|
@ -99,18 +99,24 @@ class ScrollWidgetBase : WidgetGroup, OnScrollHandler {
|
||||||
return;
|
return;
|
||||||
Rect rc = _pos;
|
Rect rc = _pos;
|
||||||
applyMargins(rc);
|
applyMargins(rc);
|
||||||
auto saver = ClipRectSaver(buf, rc, alpha);
|
{
|
||||||
DrawableRef bg = backgroundDrawable;
|
auto saver = ClipRectSaver(buf, rc, alpha);
|
||||||
if (!bg.isNull) {
|
DrawableRef bg = backgroundDrawable;
|
||||||
bg.drawTo(buf, rc, state);
|
if (!bg.isNull) {
|
||||||
}
|
bg.drawTo(buf, rc, state);
|
||||||
applyPadding(rc);
|
}
|
||||||
if (_hscrollbar)
|
applyPadding(rc);
|
||||||
_hscrollbar.onDraw(buf);
|
if (_hscrollbar)
|
||||||
if (_vscrollbar)
|
_hscrollbar.onDraw(buf);
|
||||||
_vscrollbar.onDraw(buf);
|
if (_vscrollbar)
|
||||||
auto saver2 = ClipRectSaver(buf, _clientRect, alpha);
|
_vscrollbar.onDraw(buf);
|
||||||
drawClient(buf);
|
// apply clipping
|
||||||
|
{
|
||||||
|
auto saver2 = ClipRectSaver(buf, _clientRect, alpha);
|
||||||
|
drawClient(buf);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
_needDraw = false;
|
_needDraw = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue