diff --git a/src/dlangui/core/types.d b/src/dlangui/core/types.d index e96a77bc..7a4e8fba 100644 --- a/src/dlangui/core/types.d +++ b/src/dlangui/core/types.d @@ -35,6 +35,7 @@ struct Rect { @property bool empty() { return right <= left || bottom <= top; } + /// updates this rect to intersection with rc, returns true if result is non empty bool intersect(Rect rc) { if (left < rc.left) left = rc.left; @@ -46,6 +47,12 @@ struct Rect { bottom = rc.bottom; return right > left && bottom > top; } + /// returns true if this rect has nonempty intersection with rc + bool intersects(Rect rc) { + if (rc.left >= right || rc.top >= bottom || rc.right <= left || rc.bottom <= top) + return false; + return true; + } } class RefCountedObject { diff --git a/src/dlangui/graphics/drawbuf.d b/src/dlangui/graphics/drawbuf.d index f6cd7197..78d269d8 100644 --- a/src/dlangui/graphics/drawbuf.d +++ b/src/dlangui/graphics/drawbuf.d @@ -96,6 +96,11 @@ class DrawBuf : RefCountedObject { } /// apply clipRect and buffer bounds clipping to rectangle; if clippinup applied to first rectangle, reduce second rectangle bounds proportionally. 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 (rc.width == rc2.width && rc.height == rc2.height) { // unscaled if (!_clipRect.empty()) { @@ -470,10 +475,12 @@ class ImageDrawable : Drawable { return _image.ninePatch.padding; return Rect(0,0,0,0); } - private static void correctFrameBounds(ref int n1, ref int n2) { + private static void correctFrameBounds(ref int n1, ref int n2, ref int n3, ref int n4) { if (n1 > n2) { - int middle = (n1 + n2) / 2; - n1 = n2 = middle; + assert(n2 - n1 == n4 - n3); + int middledist = (n1 + n2) / 2 - n1; + n1 = n2 = n1 + middledist; + n3 = n4 = n3 + middledist; } } override void drawTo(DrawBuf buf, Rect rc, int tilex0 = 0, int tiley0 = 0) { @@ -487,14 +494,14 @@ class ImageDrawable : Drawable { int h = height; Rect dstrect = rc; Rect srcrect = Rect(1, 1, w + 1, h + 1); - if (buf.applyClipping(dstrect, srcrect)) { + if (true) { //buf.applyClipping(dstrect, srcrect)) { int x0 = srcrect.left; - int x1 = 1 + p.frame.left; - int x2 = w - p.frame.right; + int x1 = srcrect.left + p.frame.left; + int x2 = srcrect.right - p.frame.right; int x3 = srcrect.right; int y0 = srcrect.top; - int y1 = 1 + p.frame.top; - int y2 = h - p.frame.bottom; + int y1 = srcrect.top + p.frame.top; + int y2 = srcrect.bottom - p.frame.bottom; int y3 = srcrect.bottom; int dstx0 = rc.left; int dstx1 = rc.left + p.frame.left; @@ -504,12 +511,16 @@ class ImageDrawable : Drawable { int dsty1 = rc.top + p.frame.top; int dsty2 = rc.bottom - p.frame.bottom; int dsty3 = rc.bottom; - //Log.d("src x bounds: ", x0, ", ", x1, ", ", x2, ", ", x3, " dst ", dstx0, ", ", dstx1, ", ", dstx2, ", ", dstx3); - //Log.d("src y bounds: ", y0, ", ", y1, ", ", y2, ", ", y3, " dst ", dsty0, ", ", dsty1, ", ", dsty2, ", ", dsty3); - correctFrameBounds(x1, x2); - correctFrameBounds(y1, y2); - correctFrameBounds(dstx1, dstx2); - correctFrameBounds(dsty1, dsty2); + //Log.d("x bounds: ", x0, ", ", x1, ", ", x2, ", ", x3, " dst ", dstx0, ", ", dstx1, ", ", dstx2, ", ", dstx3); + //Log.d("y bounds: ", y0, ", ", y1, ", ", y2, ", ", y3, " dst ", dsty0, ", ", dsty1, ", ", dsty2, ", ", dsty3); + + correctFrameBounds(x1, x2, dstx1, dstx2); + correctFrameBounds(y1, y2, dsty1, dsty2); + + //correctFrameBounds(x1, x2); + //correctFrameBounds(y1, y2); + //correctFrameBounds(dstx1, dstx2); + //correctFrameBounds(dsty1, dsty2); if (y0 < y1 && dsty0 < dsty1) { // top row if (x0 < x1 && dstx0 < dstx1) diff --git a/src/dlangui/graphics/gldrawbuf.d b/src/dlangui/graphics/gldrawbuf.d index 2ce63f4f..4fa5afa4 100644 --- a/src/dlangui/graphics/gldrawbuf.d +++ b/src/dlangui/graphics/gldrawbuf.d @@ -63,20 +63,26 @@ class GLDrawBuf : DrawBuf { /// draw source buffer rectangle contents to destination buffer override void drawFragment(int x, int y, DrawBuf src, Rect srcrect) { assert(_scene !is null); - GLImageCacheItem item = glImageCache.get(src.id); - if (item is null) - item = glImageCache.set(src); Rect dstrect = Rect(x, y, x + srcrect.width, y + srcrect.height); - // TODO: clipping - _scene.add(new TextureSceneItem(src.id, dstrect, srcrect, 0xFFFFFF, 0, null, 0)); + //Log.v("GLDrawBuf.frawFragment dst=", dstrect, " src=", srcrect); + if (applyClipping(dstrect, srcrect)) { + GLImageCacheItem item = glImageCache.get(src.id); + if (item is null) + item = glImageCache.set(src); + // TODO: clipping + _scene.add(new TextureSceneItem(src.id, dstrect, srcrect, 0xFFFFFF, 0, null, 0)); + } } /// draw source buffer rectangle contents to destination buffer rectangle applying rescaling override void drawRescaled(Rect dstrect, DrawBuf src, Rect srcrect) { assert(_scene !is null); - GLImageCacheItem item = glImageCache.get(src.id); - if (item is null) - item = glImageCache.set(src); - _scene.add(new TextureSceneItem(src.id, dstrect, srcrect, 0xFFFFFF, 0, null, 0)); + //Log.v("GLDrawBuf.frawRescaled dst=", dstrect, " src=", srcrect); + if (applyClipping(dstrect, srcrect)) { + GLImageCacheItem item = glImageCache.get(src.id); + if (item is null) + item = glImageCache.set(src); + _scene.add(new TextureSceneItem(src.id, dstrect, srcrect, 0xFFFFFF, 0, null, 0)); + } } override void clear() { } @@ -416,7 +422,7 @@ public: dstrc.bottom -= clip.bottom; } if (!dstrc.empty) - drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, false); //srcrc.width() != dstrc.width() || srcrc.height() != dstrc.height() + drawColorAndTextureRect(_textureId, _tdx, _tdy, srcrc, dstrc, color, srcrc.width() != dstrc.width() || srcrc.height() != dstrc.height()); //drawColorAndTextureRect(vertices, texcoords, color, _textureId); if (rotationAngle) { diff --git a/src/dlangui/graphics/glsupport.d b/src/dlangui/graphics/glsupport.d index e3371a4e..e4d51efa 100644 --- a/src/dlangui/graphics/glsupport.d +++ b/src/dlangui/graphics/glsupport.d @@ -67,7 +67,7 @@ void drawSolidFillRect(Rect rc, uint color1, uint color2, uint color3, uint colo } void drawColorAndTextureRect(uint textureId, int tdx, int tdy, Rect srcrc, Rect dstrc, uint color, bool linear) { - Log.v("drawColorAndTextureRect tx=", textureId, " src=", srcrc, " dst=", dstrc); + //Log.v("drawColorAndTextureRect tx=", textureId, " src=", srcrc, " dst=", dstrc); drawColorAndTextureRect(textureId, tdx, tdy, srcrc.left, srcrc.top, srcrc.width(), srcrc.height(), dstrc.left, dstrc.top, dstrc.width(), dstrc.height(), color, linear); } @@ -487,7 +487,7 @@ class SolidFillProgram : GLProgram { "varying " ~ LOWP ~ " vec4 col;\n" "void main(void)\n" "{\n" - " gl_FragColor = col; // vec4(1,0,0,1); \n" + " gl_FragColor = col;\n" "}\n"; } diff --git a/src/dlangui/platforms/windows/win32fonts.d b/src/dlangui/platforms/windows/win32fonts.d index 429fc1fe..11af8a6b 100644 --- a/src/dlangui/platforms/windows/win32fonts.d +++ b/src/dlangui/platforms/windows/win32fonts.d @@ -332,7 +332,7 @@ class Win32FontManager : FontManager { /// get font by properties override ref FontRef getFont(int size, int weight, bool italic, FontFamily family, string face) { - Log.i("getFont()"); + //Log.i("getFont()"); FontDef * def = findFace(family, face); if (def !is null) { int index = _activeFonts.find(size, weight, italic, def.family, def.face); diff --git a/src/dlangui/platforms/windows/winapp.d b/src/dlangui/platforms/windows/winapp.d index 3dc00f55..6880e92c 100644 --- a/src/dlangui/platforms/windows/winapp.d +++ b/src/dlangui/platforms/windows/winapp.d @@ -244,26 +244,30 @@ class Win32Window : Window { wglMakeCurrent(hdc, _hGLRC); glDisable(GL_DEPTH_TEST); glViewport(0, 0, _dx, _dy); - glClearColor(0.5f, 0.5f, 0.5f, 1.0f); + glClearColor(0.9f, 0.9f, 0.9f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); GLDrawBuf buf = new GLDrawBuf(_dx, _dy, false); buf.beforeDrawing(); - buf.fillRect(Rect(100, 100, 200, 200), 0x704020); - buf.fillRect(Rect(40, 70, 100, 120), 0x000000); - buf.fillRect(Rect(80, 80, 150, 150), 0x80008000); // green - DrawableRef img = drawableCache.get("exit"); - if (!img.isNull) { - img.drawTo(buf, Rect(300, 100, 364, 164)); - img.drawTo(buf, Rect(400, 200, 528, 328)); - } - DrawableRef img2 = drawableCache.get("btn_default_pressed"); - if (!img2.isNull) { - img2.drawTo(buf, Rect(300, 200, 564, 264)); - img2.drawTo(buf, Rect(600, 200, 628, 328)); - } - drawableCache.get("btn_default_normal").drawTo(buf, Rect(300, 0, 400, 50));; - drawableCache.get("btn_default_selected").drawTo(buf, Rect(0, 0, 100, 50));; + if (false) { + buf.fillRect(Rect(100, 100, 200, 200), 0x704020); + buf.fillRect(Rect(40, 70, 100, 120), 0x000000); + buf.fillRect(Rect(80, 80, 150, 150), 0x80008000); // green + DrawableRef img = drawableCache.get("exit"); + if (!img.isNull) { + img.drawTo(buf, Rect(300, 100, 364, 164)); + img.drawTo(buf, Rect(400, 200, 528, 328)); + } + DrawableRef img2 = drawableCache.get("btn_default_pressed"); + if (!img2.isNull) { + img2.drawTo(buf, Rect(300, 200, 564, 264)); + img2.drawTo(buf, Rect(600, 200, 628, 328)); + } + drawableCache.get("btn_default_normal").drawTo(buf, Rect(300, 0, 400, 50)); + drawableCache.get("btn_default_selected").drawTo(buf, Rect(0, 0, 100, 50)); + } else { + onDraw(buf); + } buf.afterDrawing(); //Log.d("onPaint() end drawing opengl"); SwapBuffers(hdc);