diff --git a/res/ex-layout/main.xml b/res/ex-layout/main.xml
index 4f7bdc4..75a8d62 100644
--- a/res/ex-layout/main.xml
+++ b/res/ex-layout/main.xml
@@ -5,14 +5,34 @@
background="?colorSurface"
padding="20dp"
orientation="horizontal">
-
+
+
+
+
+
+
+
-
+
\ No newline at end of file
diff --git a/src/br/nullexcept/mux/core/texel/CanvasTexel.java b/src/br/nullexcept/mux/core/texel/CanvasTexel.java
index 0b4edf7..bad422c 100644
--- a/src/br/nullexcept/mux/core/texel/CanvasTexel.java
+++ b/src/br/nullexcept/mux/core/texel/CanvasTexel.java
@@ -1,7 +1,9 @@
package br.nullexcept.mux.core.texel;
import br.nullexcept.mux.graphics.*;
+import br.nullexcept.mux.graphics.shape.ShapeList;
import br.nullexcept.mux.hardware.GLES;
+import br.nullexcept.mux.utils.Log;
import org.lwjgl.opengles.GLES20;
class CanvasTexel implements Canvas {
@@ -15,16 +17,23 @@ public CanvasTexel(int width, int height) {
}
public void begin() {
+ VgTexel.endFrame();
+ VgTexel.setAlpha(alpha);
+ framebuffer.bind();
+ VgTexel.beginFrame(framebuffer.getWidth(), framebuffer.getHeight());
+ CURRENT_CANVAS = id;
+ }
+
+ private void check() {
if (CURRENT_CANVAS != id) {
- VgTexel.endFrame();
- VgTexel.setAlpha(alpha);
- framebuffer.bind();
- VgTexel.beginFrame(framebuffer.getWidth(), framebuffer.getHeight());
+ Log.error("CanvasTexel", "Switching canvas!");
+ begin();
}
}
@Override
public void reset() {
+ check();
this.alpha = 1.0f;
GLES.glClearColor(0, 0, 0, 0);
GLES.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT | GLES.GL_STENCIL_BUFFER_BIT);
@@ -42,14 +51,27 @@ public void alpha(float alpha){
VgTexel.setAlpha(this.alpha);
}
+ @Override
+ public void clip(ShapeList list) {
+ check();
+ VgTexel.beginClip();
+ VgTexel.getPaint().setColor(Color.WHITE);
+ list.asArray().forEach(shape -> {
+ shape.draw(this, VgTexel.getPaint());
+ });
+ VgTexel.endClip(framebuffer.getFramebuffer());
+ }
+
@Override
public void drawColor(int color) {
+ check();
VgTexel.setColor(color);
drawRect(0, 0, getWidth(), getHeight(), VgTexel.getPaint());
}
@Override
public void drawRect(int left, int top, int right, int bottom, Paint paint) {
+ check();
VgTexel.beginElement();
VgTexel.applyPaint(paint);
VgTexel.drawRect(left, top, right - left, bottom - top);
@@ -63,6 +85,7 @@ public void drawRect(Rect rect, Paint paint) {
@Override
public void drawText(CharSequence text, int x, int y, Paint paint) {
+ check();
if (text == null) {
text = "[NULL]";
}
@@ -74,26 +97,19 @@ public void drawText(CharSequence text, int x, int y, Paint paint) {
@Override
public void translate(int x, int y) {
+ check();
VgTexel.move(x,y);
}
@Override
public void rotate(float angle) {
+ check();
VgTexel.rotate(angle);
}
- @Override
- public void drawBitmap(Rect rect, Bitmap bitmap, Paint paint) {
- drawBitmap(rect.left, rect.top, rect.width(), rect.height(), bitmap, paint);
- }
-
- @Override
- public void drawBitmap(int x, int y, Bitmap bitmap, Paint paint) {
- drawBitmap(x, y, bitmap.getWidth(), bitmap.getHeight(), bitmap, paint);
- }
-
@Override
public void drawEllipse(int left, int top, int right, int bottom, Paint paint) {
+ check();
VgTexel.beginElement();
VgTexel.applyPaint(paint);
VgTexel.drawEllipse(left, top, right-left, bottom-top);
@@ -102,14 +118,21 @@ public void drawEllipse(int left, int top, int right, int bottom, Paint paint) {
@Override
public void drawRoundRect(int left, int top, int right, int bottom, int radius, Paint paint) {
+ drawRoundRect(left, top, right, bottom, radius,radius,radius,radius, paint);
+ }
+
+ @Override
+ public void drawRoundRect(int left, int top, int right, int bottom, int radiusLeft, int radiusTop, int radiusRight, int radiusBottom, Paint paint) {
+ check();
VgTexel.beginElement();
VgTexel.applyPaint(paint);
- VgTexel.drawRoundedRect(left,top, right-left, bottom-top, radius);
+ VgTexel.drawRoundedRect(left,top,right-left, bottom-top, radiusLeft, radiusTop, radiusRight, radiusBottom);
VgTexel.endElement();
}
@Override
public void drawPath(Path path, int x, int y, Paint paint) {
+ check();
VgTexel.beginElement();
VgTexel.applyPaint(paint);
translate(x,y);
@@ -118,13 +141,24 @@ public void drawPath(Path path, int x, int y, Paint paint) {
VgTexel.endElement();
}
+ @Override
+ public void drawBitmap(Rect rect, Bitmap bitmap, Paint paint) {
+ drawBitmap(rect.left, rect.top, rect.width(), rect.height(), bitmap, paint);
+ }
+
+ @Override
+ public void drawBitmap(int x, int y, Bitmap bitmap, Paint paint) {
+ drawBitmap(x, y, bitmap.getWidth(), bitmap.getHeight(), bitmap, paint);
+ }
+
@Override
public void drawBitmap(int x, int y, int width, int height, Bitmap bitmap, Paint paint) {
- drawBitmap(x,y,width,height, 0,0, bitmap.getWidth(), getHeight(), bitmap,paint);
+ drawBitmap(x,y,width,height, 0,0, bitmap.getWidth(), bitmap.getHeight(), bitmap,paint);
}
@Override
public void drawBitmap(int x, int y, int width, int height, int srcX, int srcY, int srcWidth, int srcHeight, Bitmap bitmap, Paint paint) {
+ check();
if (!(bitmap instanceof TexelBitmap)){
throw new IllegalArgumentException("Invalid bitmap, bitmap core and canvas core is different!");
}
diff --git a/src/br/nullexcept/mux/core/texel/GLTexel.java b/src/br/nullexcept/mux/core/texel/GLTexel.java
index f526ec8..84179fb 100644
--- a/src/br/nullexcept/mux/core/texel/GLTexel.java
+++ b/src/br/nullexcept/mux/core/texel/GLTexel.java
@@ -121,4 +121,33 @@ public static void drawTexture(float x, float y, float width, float height, GLPr
program.unbind();
glBindTexture(GL_TEXTURE_2D,0);
}
+
+ public static void drawTextureClip(int x, int y, int width, int height, int texture) {
+ GLProgram program = GLShaderList.TEXTURE;
+ glEnable(GL_BLEND);
+ glBlendFuncSeparate(
+ GL_ZERO, GL_SRC_ALPHA,
+ GL_ZERO, GL_SRC_ALPHA
+ );
+ prepareRect(x, y, width, height);
+ program.bind();
+
+ int vPosition = program.attribute(GLProgram.ATTRIBUTE_POSITION);
+ int vTextureCoords = program.attribute(GLProgram.ATTRIBUTE_UV);
+ int uTexture = program.uniform(GLProgram.UNIFORM_TEXTURE);
+
+ glBindTexture(GL_TEXTURE_2D, texture);
+ glVertexAttribPointer(vPosition, 2, GL_FLOAT, false, 0, bufferRect);
+ glVertexAttribPointer(vTextureCoords, 2, GL_FLOAT, false, 0, bufferUV);
+
+ glEnableVertexAttribArray(vPosition);
+ glEnableVertexAttribArray(vTextureCoords);
+
+ glUniform1i(uTexture, GL_TEXTURE_2D);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
+ program.unbind();
+ glBindTexture(GL_TEXTURE_2D,0);
+ glDisable(GL_BLEND);
+ }
}
diff --git a/src/br/nullexcept/mux/core/texel/VgTexel.java b/src/br/nullexcept/mux/core/texel/VgTexel.java
index 951d13d..e50235e 100644
--- a/src/br/nullexcept/mux/core/texel/VgTexel.java
+++ b/src/br/nullexcept/mux/core/texel/VgTexel.java
@@ -1,31 +1,37 @@
package br.nullexcept.mux.core.texel;
import br.nullexcept.mux.C;
-import br.nullexcept.mux.graphics.Color;
-import br.nullexcept.mux.graphics.Paint;
-import br.nullexcept.mux.graphics.Path;
-import br.nullexcept.mux.graphics.Point;
+import br.nullexcept.mux.graphics.*;
+import br.nullexcept.mux.hardware.GLES;
import br.nullexcept.mux.utils.Log;
import org.lwjgl.nanovg.*;
+import org.lwjgl.opengles.GLES20;
import static org.lwjgl.nanovg.NanoVG.*;
class VgTexel {
+ private static long currentContext = 0;
private static long globalContext = 0;
+ private static long clipContext = 0;
private static final Paint globalPaint = new Paint();
private static final NVGColor globalColor = NVGColor.create();
private static final NVGPaint nvgPaint = NVGPaint.create();
private static final NVGPaint tmpPaint = NVGPaint.create();
private static float alpha = 1.0f;
- private static final Point VIEWPORT = new Point();
+ private static final Size drawViewport = new Size();
+ private static GLFramebuffer clipFbo;
public static void initialize(){
try {
globalContext = NanoVGGLES2.nvgCreate(NanoVGGLES2.NVG_ANTIALIAS);
+ clipContext = NanoVGGLES2.nvgCreate(NanoVGGLES2.NVG_ANTIALIAS);
globalPaint.setTextSize(-1f);
C.VG_CONTEXT = globalContext;
C.BITMAP_FACTORY = new TexelBitmapFactory();
GLShaderList.build();
+
+ clipFbo = new GLFramebuffer(1,1);
+ currentContext = globalContext;
} catch (Throwable e){
Log.log("TexelAPI", "Error on initialize nanovg texel.");
Log.log("TexelAPI", e);
@@ -35,27 +41,45 @@ public static void initialize(){
@Deprecated
public static long getContext() {
- return globalContext;
+ return currentContext;
}
public static void applyPaint(Paint paint){
globalPaint.from(paint);
- nvgFontFaceId(globalContext, paint.getTypeface().hashCode());
+ nvgFontFaceId(currentContext, paint.getTypeface().hashCode());
setColor(paint.getColor());
setTextSize(paint.getTextSize());
nvgPaint.innerColor(globalColor);
nvgPaint.outerColor(globalColor);
- nvgFillPaint(globalContext, nvgPaint);
- nvgStrokeColor(globalContext, globalColor);
+ nvgFillPaint(currentContext, nvgPaint);
+ nvgStrokeColor(currentContext, globalColor);
+ }
+
+
+ public static void beginClip() {
+ setCurrentContext(clipContext);
+ clipFbo.resize(drawViewport.width, drawViewport.height);
+ clipFbo.bind();
+ clipFbo.clear(Color.TRANSPARENT);
+ beginFrame(drawViewport.width, drawViewport.height);
+ }
+
+ public static void endClip(int srcFBO) {
+ endFrame();
+ clipFbo.unbind();
+ GLES.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, srcFBO);
+ setCurrentContext(globalContext);
+ flushFrame();
+ GLTexel.drawTextureClip(0,0, drawViewport.width, drawViewport.height,clipFbo.getTexture().getTexture());
}
private static void setTextSize(float textSize) {
globalPaint.setTextSize(textSize);
- nvgFontSize(globalContext, globalPaint.getTextSize());
- nvgTextLetterSpacing(globalContext,0.0f);
+ nvgFontSize(currentContext, globalPaint.getTextSize());
+ nvgTextLetterSpacing(currentContext,0.0f);
}
public static void setColor(int color){
@@ -77,97 +101,114 @@ public static Paint getPaint() {
private static void fill(){
switch (globalPaint.getMode()){
case FILL:
- nvgFill(globalContext);
+ nvgFill(currentContext);
break;
case STROKE:
- nvgStroke(globalContext);
+ nvgStroke(currentContext);
break;
default:
- nvgFill(globalContext);
- nvgStroke(globalContext);
+ nvgFill(currentContext);
+ nvgStroke(currentContext);
break;
}
}
+ public static void setCurrentContext(long context) {
+ currentContext = context;
+ }
+
public static void drawPath(Path path) {
- nvgBeginPath(globalContext);
+ nvgBeginPath(currentContext);
for (int i = 0; i < path.length(); i++) {
- nvgPathWinding(globalContext, NVG_HOLE);
+ nvgPathWinding(currentContext, NVG_HOLE);
Path.Segment seg = path.segment(i);
- nvgMoveTo(globalContext, seg.beginX(), seg.beginY());
+ nvgMoveTo(currentContext, seg.beginX(), seg.beginY());
for (int x = 0; x < seg.partCount(); x++) {
float[] curves = seg.part(x);
- nvgBezierTo(globalContext, curves[0], curves[1], curves[2], curves[3], curves[4], curves[5]);
+ nvgBezierTo(currentContext, curves[0], curves[1], curves[2], curves[3], curves[4], curves[5]);
}
if (seg.closed()) {
- nvgLineTo(globalContext,seg.beginX(), seg.beginY());
+ nvgLineTo(currentContext,seg.beginX(), seg.beginY());
}
}
- nvgClosePath(globalContext);
+ nvgClosePath(currentContext);
fill();
}
- public static void drawRoundedRect(int x, int y, int width, int height, int radius){
- radius = Math.min(Math.max(width,height), radius);
- nvgRoundedRect(globalContext, x,y,width,height,radius);
+ public static void drawRoundedRect(int x, int y, int width, int height, float rl, float rt, float rr, float rb){
+ if (rl == rr && rr == rt && rt == rb) {
+ nvgRoundedRect(currentContext, x, y, width, height, rr);
+ } else {
+ nvgRoundedRectVarying(currentContext, x, y, width, height, rl, rr, rb, rt);
+ }
fill();
}
public static void drawEllipse(int x, int y, int width, int height){
int mw = width/2;
int mh = height/2;
- nvgEllipse(globalContext, x+mw, y+mh, mw, mh);
+ nvgEllipse(currentContext, x+mw, y+mh, mw, mh);
fill();
}
public static void drawRect(int x, int y, int width, int height){
- nvgRect(globalContext, x, y, width, height);
+ nvgRect(currentContext, x, y, width, height);
fill();
}
public static void beginElement(){
- nvgBeginPath(globalContext);
+ nvgBeginPath(currentContext);
}
public static void endElement(){
- nvgClosePath(globalContext);
+ nvgClosePath(currentContext);
}
public static void destroy(){
- NanoVGGLES2.nvgDelete(globalContext);
+ NanoVGGLES2.nvgDelete(currentContext);
+ NanoVGGLES2.nvgDelete(clipContext);
}
public static void beginFrame(int w, int h) {
- nvgBeginFrame(globalContext, w,h,1.0f);
- VIEWPORT.set(w,h);
+ nvgBeginFrame(currentContext, w,h,1.0f);
+ drawViewport.set(w,h);
+ }
+
+ public static void flushFrame() {
+ nvgEndFrame(currentContext);
+ nvgBeginFrame(currentContext, drawViewport.width, drawViewport.height, 1.0f);
}
public static void endFrame() {
- nvgEndFrame(globalContext);
- nvgResetTransform(globalContext);
- nvgReset(globalContext);
- nvgResetScissor(globalContext);
+ nvgEndFrame(currentContext);
+ nvgResetTransform(currentContext);
+ nvgReset(currentContext);
+ nvgResetScissor(currentContext);
alpha = 1.0f;
}
public static void drawImage(TexelBitmap image, float destX, float destY, float destW, float destH, float srcX, float srcY, float srcW, float srcH) {
- float aw = image.getWidth() / srcW;
- float ah = image.getHeight() / srcH;
+ drawImage(image.id(), image.getWidth(), image.getHeight(), destX, destY, destW, destH, srcX, srcY, srcW, srcH);
+ }
+
+ public static void drawImage(int img, int originW, int originH, float destX, float destY, float destW, float destH, float srcX, float srcY, float srcW, float srcH) {
+ float aw = originW / srcW;
+ float ah = originH / srcH;
float imgH = destH * ah;
float imgW = destW * aw;
- float imgX = destX - ((srcX / image.getWidth()) * imgW);
- float imgY = destY - ((srcY / image.getHeight()) * imgH);
+ float imgX = destX - ((srcX / originW) * imgW);
+ float imgY = destY - ((srcY / originH) * imgH);
- nvgImagePattern(globalContext, imgX, imgY, imgW, imgH, 0, image.id(), alpha, tmpPaint);
- nvgRect(globalContext, destX, destY, destW, destH);
- nvgFillPaint(globalContext, tmpPaint);
- nvgFill(globalContext);
- nvgFillPaint(globalContext, nvgPaint);
+ nvgImagePattern(currentContext, imgX, imgY, imgW, imgH, 0, img, alpha, tmpPaint);
+ nvgRect(currentContext, destX, destY, destW, destH);
+ nvgFillPaint(currentContext, tmpPaint);
+ nvgFill(currentContext);
+ nvgFillPaint(currentContext, nvgPaint);
}
public static void setAlpha(float alpha) {
@@ -175,14 +216,14 @@ public static void setAlpha(float alpha) {
}
public static void drawText(int x, int y, CharSequence line) {
- nvgText(globalContext, x,y, line);
+ nvgText(currentContext, x,y, line);
}
public static void rotate(float angle){
- nvgRotate(globalContext, angle);
+ nvgRotate(currentContext, angle);
}
public static void move(int x, int y) {
- nvgTranslate(globalContext, x, y);
+ nvgTranslate(currentContext, x, y);
}
}
diff --git a/src/br/nullexcept/mux/graphics/Canvas.java b/src/br/nullexcept/mux/graphics/Canvas.java
index dd657f4..35f1db1 100644
--- a/src/br/nullexcept/mux/graphics/Canvas.java
+++ b/src/br/nullexcept/mux/graphics/Canvas.java
@@ -1,6 +1,10 @@
package br.nullexcept.mux.graphics;
+import br.nullexcept.mux.graphics.shape.ShapeList;
+
public interface Canvas {
+
+ void clip(ShapeList list);
void drawColor(int color);
default void drawRect(float left, float top, float right, float bottom, Paint paint){
drawRect(Math.round(left), Math.round(top), Math.round(right), Math.round(bottom), paint);
@@ -23,9 +27,13 @@ default void drawEllipse(Rect rect, Paint paint){
}
void drawRoundRect(int left, int top, int right, int bottom, int radius, Paint paint);
+ void drawRoundRect(int left, int top, int right, int bottom, int radiusLeft, int radiusTop, int radiusRight, int radiusBottom, Paint paint);
default void drawRoundRect(Rect rect, int radius, Paint paint){
drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, radius, paint);
}
+ default void drawRoundRect(Rect rect, Rect radius, Paint paint){
+ drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, radius.left, radius.top, radius.right, radius.bottom, paint);
+ }
void drawPath(Path path, int x, int y, Paint paint);
diff --git a/src/br/nullexcept/mux/graphics/shape/RoundedShape.java b/src/br/nullexcept/mux/graphics/shape/RoundedShape.java
index 6117cfc..96b24e3 100644
--- a/src/br/nullexcept/mux/graphics/shape/RoundedShape.java
+++ b/src/br/nullexcept/mux/graphics/shape/RoundedShape.java
@@ -2,16 +2,21 @@
import br.nullexcept.mux.graphics.Canvas;
import br.nullexcept.mux.graphics.Paint;
+import br.nullexcept.mux.graphics.Rect;
public class RoundedShape extends Shape {
- private int radius = 0;
+ private final Rect radius = new Rect();
public void setRadius(int radius) {
- this.radius = radius;
+ this.radius.set(radius,radius,radius,radius);
+ }
+
+ public void setRadius(Rect radius) {
+ this.radius.set(radius);
}
@Override
public void draw(Canvas canvas, Paint paint) {
- canvas.drawRoundRect(0,0,getWidth(),getHeight(), radius,paint);
+ canvas.drawRoundRect(0,0,getWidth(),getHeight(), radius.left, radius.top, radius.right, radius.bottom,paint);
}
}
diff --git a/src/br/nullexcept/mux/graphics/shape/ShapeList.java b/src/br/nullexcept/mux/graphics/shape/ShapeList.java
new file mode 100644
index 0000000..046cb80
--- /dev/null
+++ b/src/br/nullexcept/mux/graphics/shape/ShapeList.java
@@ -0,0 +1,21 @@
+package br.nullexcept.mux.graphics.shape;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class ShapeList {
+ private final ArrayList shapes = new ArrayList<>();
+
+ public ShapeList(Shape... shapes) {
+ this.shapes.addAll(Arrays.asList(shapes));
+ }
+
+ public List asArray() {
+ return new ArrayList<>(shapes);
+ }
+
+ public int getLength() {
+ return shapes.size();
+ }
+}
diff --git a/src/br/nullexcept/mux/res/LayoutInflater.java b/src/br/nullexcept/mux/res/LayoutInflater.java
index 0fb2277..538b308 100644
--- a/src/br/nullexcept/mux/res/LayoutInflater.java
+++ b/src/br/nullexcept/mux/res/LayoutInflater.java
@@ -93,6 +93,7 @@ private ViewGroup.LayoutParams parseLayoutParams(AttributeList attr){
static {
registerView("AbsoluteLayout", AbsoluteLayout::new);
+ registerView("CardLayout", CardLayout::new);
registerView("LinearLayout", LinearLayout::new);
registerView("FrameLayout", FrameLayout::new);
registerView("ScrollView", ScrollView::new);
diff --git a/src/br/nullexcept/mux/res/Parser.java b/src/br/nullexcept/mux/res/Parser.java
index b56fc72..28f1f34 100644
--- a/src/br/nullexcept/mux/res/Parser.java
+++ b/src/br/nullexcept/mux/res/Parser.java
@@ -109,7 +109,13 @@ private static Drawable inflateXmlDrawable(Resources res, XmlElement xml) {
switch (shapeType){
case "rounded": {
RoundedShape shape = new RoundedShape();
- attrs.searchDimension(AttrList.radius, v -> shape.setRadius(Math.round(v)));
+ Rect rect = new Rect();
+ attrs.searchDimension(AttrList.radius, v -> rect.set(v.intValue(),v.intValue(),v.intValue(),v.intValue()));
+ attrs.searchDimension("leftTop", v -> rect.left = v.intValue());
+ attrs.searchDimension("rightTop", v -> rect.right = v.intValue());
+ attrs.searchDimension("leftBottom", v -> rect.top = v.intValue());
+ attrs.searchDimension("rightBottom", v -> rect.bottom = v.intValue());
+ shape.setRadius(rect);
drawable.setShape(shape);
}break;
case "circle":
diff --git a/src/br/nullexcept/mux/widget/CardLayout.java b/src/br/nullexcept/mux/widget/CardLayout.java
new file mode 100644
index 0000000..4863be6
--- /dev/null
+++ b/src/br/nullexcept/mux/widget/CardLayout.java
@@ -0,0 +1,33 @@
+package br.nullexcept.mux.widget;
+
+import br.nullexcept.mux.app.Context;
+import br.nullexcept.mux.graphics.Canvas;
+import br.nullexcept.mux.graphics.shape.RoundedShape;
+import br.nullexcept.mux.graphics.shape.ShapeList;
+import br.nullexcept.mux.res.AttributeList;
+import br.nullexcept.mux.view.AttrList;
+
+public class CardLayout extends AbsoluteLayout {
+ private final RoundedShape shape = new RoundedShape();
+ private final ShapeList clipArea = new ShapeList(shape);
+ public CardLayout(Context context) {
+ this(context, null);
+ }
+
+ public CardLayout(Context context, AttributeList attrs) {
+ super(context, attrs);
+ initialAttributes().searchDimension(AttrList.radius,(dimen) -> shape.setRadius(dimen.intValue()));
+ }
+
+ public void setRadius(int radius) {
+ shape.setRadius(radius);
+ invalidate();
+ }
+
+ @Override
+ public void onDrawForeground(Canvas canvas) {
+ super.onDrawForeground(canvas);
+ shape.resize(canvas.getWidth(),canvas.getHeight());
+ canvas.clip(clipArea);
+ }
+}