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