clipping fixes

This commit is contained in:
Vadim Lopatin 2014-04-01 23:13:00 +04:00
parent 0fd29831ab
commit 90aa9bbb49
6 changed files with 36 additions and 18 deletions

View File

@ -94,9 +94,19 @@ class DrawBuf : RefCountedObject {
/// 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; }
/// sets new clipping rectangle, when clipRect.isEmpty == true -- means no clipping.
@property void clipRect(const ref Rect rect) {
_clipRect = rect;
_clipRect = rect;
_clipRect.intersect(Rect(0, 0, width, height));
}
/// sets new clipping rectangle, when clipRect.isEmpty == true -- means no clipping.
@property void intersectClipRect(const ref Rect rect) {
if (_clipRect.empty)
_clipRect = rect;
else
_clipRect.intersect(rect);
_clipRect.intersect(Rect(0, 0, width, height));
}
/// apply clipRect and buffer bounds clipping to rectangle
@ -131,8 +141,8 @@ class DrawBuf : RefCountedObject {
rc2.top += _clipRect.top - rc.top;
rc.top = _clipRect.top;
}
if (rc.right > _clipRect.left) {
rc2.right -= rc.right - _clipRect.left;
if (rc.right > _clipRect.right) {
rc2.right -= rc.right - _clipRect.right;
rc.right = _clipRect.right;
}
if (rc.bottom > _clipRect.bottom) {
@ -171,8 +181,8 @@ class DrawBuf : RefCountedObject {
rc2.top += (_clipRect.top - rc.top) * srcdy / dstdy;
rc.top = _clipRect.top;
}
if (rc.right > _clipRect.left) {
rc2.right -= (rc.right - _clipRect.left) * srcdx / dstdx;
if (rc.right > _clipRect.right) {
rc2.right -= (rc.right - _clipRect.right) * srcdx / dstdx;
rc.right = _clipRect.right;
}
if (rc.bottom > _clipRect.bottom) {
@ -235,12 +245,12 @@ alias DrawBufRef = Ref!DrawBuf;
/// RAII setting/restoring of clip rectangle
struct ClipRectSaver {
DrawBuf _buf;
Rect _oldClipRect;
this(DrawBuf buf, Rect newClipRect) {
private DrawBuf _buf;
private Rect _oldClipRect;
this(DrawBuf buf, ref Rect newClipRect) {
_buf = buf;
_oldClipRect = buf.clipRect;
buf.clipRect = newClipRect;
buf.intersectClipRect(newClipRect);
}
~this() {
_buf.clipRect = _oldClipRect;

View File

@ -189,13 +189,21 @@ class Win32Font : Font {
override void drawText(DrawBuf buf, int x, int y, const dchar[] text, uint color) {
int[] widths;
int charsMeasured = measureText(text, widths, 3000);
Rect clip = buf.clipOrFullRect;
if (y + height < clip.top || y >= clip.bottom)
return;
for (int i = 0; i < charsMeasured; i++) {
int xx = (i > 0) ? widths[i - 1] : 0;
if (x + xx > clip.right)
break;
Glyph * glyph = getCharGlyph(text[i]);
if (glyph is null)
continue;
if ( glyph.blackBoxX && glyph.blackBoxY ) {
buf.drawGlyph( x + xx + glyph.originX,
int gx = x + xx + glyph.originX;
if (gx + glyph.blackBoxX < clip.left)
continue;
buf.drawGlyph( gx,
y + _baseline - glyph.originY,
glyph,
color);

View File

@ -50,7 +50,7 @@ class TextWidget : Widget {
super.onDraw(buf);
Rect rc = _pos;
applyMargins(rc);
ClipRectSaver(buf, rc);
auto saver = ClipRectSaver(buf, rc);
applyPadding(rc);
FontRef font = font();
Point sz = font.textSize(text);
@ -110,7 +110,7 @@ class ImageWidget : Widget {
super.onDraw(buf);
Rect rc = _pos;
applyMargins(rc);
ClipRectSaver(buf, rc);
auto saver = ClipRectSaver(buf, rc);
applyPadding(rc);
DrawableRef img = drawable;
if (!img.isNull) {
@ -156,7 +156,7 @@ class Button : Widget {
applyMargins(rc);
buf.fillRect(_pos, backgroundColor);
applyPadding(rc);
ClipRectSaver(buf, rc);
auto saver = ClipRectSaver(buf, rc);
FontRef font = font();
Point sz = font.textSize(text);
applyAlign(rc, sz);
@ -572,7 +572,7 @@ class ScrollBar : AbstractSlider, OnClickHandler {
Rect rc = _pos;
applyMargins(rc);
applyPadding(rc);
ClipRectSaver(buf, rc);
auto saver = ClipRectSaver(buf, rc);
_btnForward.onDraw(buf);
_btnBack.onDraw(buf);
_pageUp.onDraw(buf);

View File

@ -271,7 +271,7 @@ class LinearLayout : WidgetGroup {
Rect rc = _pos;
applyMargins(rc);
applyPadding(rc);
ClipRectSaver(buf, rc);
auto saver = ClipRectSaver(buf, rc);
for (int i = 0; i < _children.count; i++) {
Widget item = _children.get(i);
if (item.visibility != Visibility.Visible)
@ -352,7 +352,7 @@ class FrameLayout : WidgetGroup {
Rect rc = _pos;
applyMargins(rc);
applyPadding(rc);
ClipRectSaver(buf, rc);
auto saver = ClipRectSaver(buf, rc);
for (int i = 0; i < _children.count; i++) {
Widget item = _children.get(i);
if (item.visibility != Visibility.Visible)

View File

@ -369,7 +369,7 @@ class ListWidget : WidgetGroup, OnScrollHandler {
Rect rc = _pos;
applyMargins(rc);
applyPadding(rc);
ClipRectSaver(buf, rc);
auto saver = ClipRectSaver(buf, rc);
// draw scrollbar
if (_needScrollbar)
_scrollbar.onDraw(buf);

View File

@ -306,7 +306,7 @@ class TabControl : WidgetGroup {
Rect rc = _pos;
applyMargins(rc);
applyPadding(rc);
ClipRectSaver(buf, rc);
auto saver = ClipRectSaver(buf, rc);
for (int i = 0; i < _children.count; i++) {
Widget item = _children.get(i);
if (item.visibility != Visibility.Visible)