Revision: 1048
Author: allain.lalonde
Date: Thu Aug 26 11:02:54 2010
Log: Fixing PText bounds bug, making repaint use the visible region when clipping, and caching globalFullBounds. Also, fixed bug in the events example, where the highlighted node wasn't updated until an animation occured.
http://code.google.com/p/piccolo2d/source/detail?r=1048

Modified:
 /piccolo2d.js/trunk/examples/events.html
 /piccolo2d.js/trunk/piccolo2d.js
 /piccolo2d.js/trunk/test.html

=======================================
--- /piccolo2d.js/trunk/examples/events.html    Mon Jan  4 10:15:57 2010
+++ /piccolo2d.js/trunk/examples/events.html    Thu Aug 26 11:02:54 2010
@@ -57,13 +57,13 @@
           if (this.highlighted) {
             ctx.fillStyle = "rgb(0,0,255)";
             ctx.lineWidth = 10;
-            ctx.strokeRect(0, 0, this.bounds.width, this.bounds.height);
+            ctx.strokeRect(0, 0, this.bounds.width, this.bounds.height);
           }
         }
       })

       for (var x=0; x<10; x++) {
-        for (var y=0; y<10; y++) {
+        for (var y=0; y<10; y++) {
           layer.addChild(new ZoomNode({
fillStyle: "rgb("+Math.round(Math.random()*255)+","+Math.round(Math.random()*255)+","+Math.round(Math.random()*255)+")",
             bounds: new PBounds(0,0, 100, 100),
@@ -81,10 +81,12 @@

         mouseout: function(event) {
           event.pickedNodes[0].highlighted = false;
+          event.pickedNodes[0].invalidatePaint();
         },

         mouseover: function(event) {
           event.pickedNodes[0].highlighted = true;
+          event.pickedNodes[0].invalidatePaint();
         }
       });
     }
=======================================
--- /piccolo2d.js/trunk/piccolo2d.js    Tue Jun  8 07:48:28 2010
+++ /piccolo2d.js/trunk/piccolo2d.js    Thu Aug 26 11:02:54 2010
@@ -59,7 +59,7 @@
         abs = Math.abs,
         sin = Math.sin,
         cos = Math.cos;
-
+
     PTransform = Class.extend({
         init: function (values) {
             this.values = values || [1, 0, 0, 1, 0, 0];
@@ -275,6 +275,13 @@
             }

return x >= this.x && x < this.x + this.width && y >= this.y && y < this.y + this.height;
+        },
+
+        intersects: function(bounds) {
+            return !(bounds.x + bounds.width < this.x
+                || bounds.x > this.x + this.width
+                || bounds.y + bounds.height < this.y
+                || bounds.y > this.y + this.height);
         }
     });

@@ -284,6 +291,7 @@
             this.children = [];
             this.listeners = [];
             this.fullBounds = null;
+            this.globalFullBounds = null;

             this.transform = new PTransform();
             this.visible = true;
@@ -314,29 +322,29 @@
         paintAfterChildren: function (ctx) {
         },

-        fullPaint: function (ctx) {
- if (!this.visible) { //TODO: fullIntersects(paintContext.getLocalClip())) {
-                return;
-            }
-
-            ctx.save();
-
-            this.transform.applyTo(ctx);
-
-            this.paint(ctx);
-
-            for (var i = 0; i < this.children.length; i += 1) {
-                this.children[i].fullPaint(ctx);
-            }
-
-            this.paintAfterChildren(ctx);
-
-            ctx.restore();
+        fullPaint: function (ctx) {
+ var inViewport = !ctx.clipBounds || ctx.clipBounds.intersects(this.getGlobalFullBounds());
+            if (this.visible && inViewport) {
+              ctx.save();
+
+              this.transform.applyTo(ctx);
+
+              this.paint(ctx);
+
+              for (var i = 0; i < this.children.length; i += 1) {
+                  this.children[i].fullPaint(ctx);
+              }
+
+              this.paintAfterChildren(ctx);
+
+              ctx.restore();
+            }
         },

         scale: function (ratio) {
             this.transform.scale(ratio);
             this.fullBounds = null;
+            this.globalFullBounds = null;
             this.invalidatePaint();

             return this;
@@ -345,6 +353,7 @@
         translate: function (dx, dy) {
             this.transform.translate(dx, dy);
             this.fullBounds = null;
+            this.globalFullBounds = null;
             this.invalidatePaint();

             return this;
@@ -360,6 +369,7 @@
         addChild: function (child) {
             this.children.push(child);
             this.fullBounds = null;
+            this.globalFullBounds = null;
             child.parent = this;
             this.invalidatePaint();

@@ -369,6 +379,7 @@
         removeChild: function (child) {
             child.parent = null;
             this.fullBounds = null;
+            this.globalFullBounds = null;
             this.children = this.children.remove(child);
             this.invalidatePaint();

@@ -378,6 +389,7 @@
         setTransform: function (transform) {
             this.transform = transform;
             this.fullBounds = null;
+            this.globalFullBounds = null;
             this.invalidatePaint();

             return this;
@@ -414,23 +426,27 @@
         },

         getGlobalFullBounds: function () {
-            var fullBounds = this.getFullBounds(),
-                currentNode = this,
-                tl = new PPoint(fullBounds.x, fullBounds.y),
- br = new PPoint(fullBounds.x + fullBounds.width, fullBounds.y + fullBounds.height);
-
-            while (currentNode.parent) {
-                tl = currentNode.transform.transform(tl);
-                br = currentNode.transform.transform(br);
-                currentNode = currentNode.parent;
-            }
-
-            return new PBounds(
-                min(tl.x, br.x),
-                min(tl.y, br.y),
-                abs(tl.x - br.x),
-                abs(tl.y - br.y)
-                );
+            if (!this.globalFullBounds) {
+                var fullBounds = this.getFullBounds(),
+                    currentNode = this,
+                    tl = new PPoint(fullBounds.x, fullBounds.y),
+ br = new PPoint(fullBounds.x + fullBounds.width, fullBounds.y + fullBounds.height);
+
+                while (currentNode.parent) {
+                    tl = currentNode.transform.transform(tl);
+                    br = currentNode.transform.transform(br);
+                    currentNode = currentNode.parent;
+                }
+
+                this.globalFullBounds = new PBounds(
+                    min(tl.x, br.x),
+                    min(tl.y, br.y),
+                    abs(tl.x - br.x),
+                    abs(tl.y - br.y)
+                    );
+            }
+
+            return this.globalFullBounds;
         },

         getGlobalTransform: function () {
@@ -475,10 +491,11 @@
     });

     PText = PNode.extend({
-        init: function (arg) {
+        init: function (arg) {
             if (typeof arg === "string") {
                 this._super();
                 this.text = arg;
+                this.recomputeBounds();
             } else if (arg) {
                 this.text = arg.text;
                 this._super(arg);
@@ -487,7 +504,7 @@
             }
         },

-        paint: function (ctx) {
+        paint: function (ctx) {
             if (this.fillStyle) {
                 ctx.fillStyle = this.fillStyle;
             } else {
@@ -495,9 +512,18 @@
             }
             ctx.textBaseline = "top";
             ctx.fillText(this.text, this.bounds.x, this.bounds.y);
+        },
+
+        recomputeBounds: function() {
+          var metric = PText.hiddenContext.measureText(this.text);
+          this.bounds.width = metric.width;
+          this.bounds.height = this.text ? PText.fontSize : 0;
         }
     });
-
+ PText.hiddenContext = document.createElement("canvas").getContext("2d");
+    PText.fontSize = 20;
+
+
     PImage = PNode.extend({
         init: function (arg) {
             if (typeof arg === "string") {
@@ -559,7 +585,9 @@
             ctx.save();

             this.viewTransform.applyTo(ctx);
-
+            var viewInverse = this.viewTransform.getInverse();
+            ctx.clipBounds = viewInverse.transform(this.bounds);
+
             for (var i = 0; i < this.layers.length; i += 1) {
                 this.layers[i].fullPaint(ctx);
             }
@@ -636,8 +664,10 @@
                 throw "Canvas provided to Piccolo is invalid!";
             }

-            var _pCanvas = this;
+            var _pCanvas = this;
+
             this.canvas = canvas;
+            canvas.font = PText.fontSize + "px Arial";

             this.root =  root || new PRoot();
             this.camera = new PCamera();
@@ -726,7 +756,8 @@
         paint: function () {
             var root = this.camera.getRoot();
             if (root.invalidPaint) {
-                var ctx = this.canvas.getContext('2d');
+                var ctx = this.canvas.getContext('2d');
+
                 ctx.font = "16pt Helvetica";
                 ctx.fillStyle = this.fillStyle || "rgb(255,255,255)";

=======================================
--- /piccolo2d.js/trunk/test.html       Thu Aug 26 08:58:51 2010
+++ /piccolo2d.js/trunk/test.html       Thu Aug 26 11:02:54 2010
@@ -498,7 +498,21 @@
           var ctx = mock("fillText");
           t.paint(ctx);
           same(ctx.calls.fillText[0], ["Hello", 0, 0]);
-        })
+        });
+
+        test("FullBounds are empty when text is empty", function() {
+          var t = new PText("");
+          var bounds = t.getFullBounds();
+ equal(bounds.width, 0, "Bounds should have no weight when text is empty"); + equal(bounds.height, 0, "Bounds should have no height when text is empty");
+        });
+
+        test("FullBounds not empty when text is not empty", function() {
+          var t = new PText("Hello");
+          var bounds = t.getFullBounds();
+ ok(bounds.width != 0, "Bounds should have width when text is not empty"); + ok(bounds.height != 0, "Bounds should have height when text is not empty");
+        });
       }

       function testPImage() {

--
Piccolo2D Developers Group: http://groups.google.com/group/piccolo2d-dev?hl=en

Reply via email to