Browse Source

Canvas2D: bug fixing

 - Solving the WSC not being adaptive sized anymore
 - ContentArea wasn't computing for primitives in some cases
 - Allow re entrance layout/size computation between siblings (prim P is autoSize and contains prim C1 with a size and prim C2 with autoSize: now C2 is positioned correctly. for you @royibernthal)
 - Allow positioning of primitives that are larger than their parent (thanks @abow for the hint)
 - Fix bad text rendering of premul antialiased, because yes, sometimes I don't test things...enough
nockawa 8 years ago
parent
commit
e24328d7b5

+ 6 - 3
canvas2D/src/Engine/babylon.canvas2d.ts

@@ -1474,12 +1474,12 @@
             }
 
             // Clip values if needed
-            edge = Math.min(edge, this._maxAdaptiveWorldSpaceCanvasSize);
+            edge = Math.min(edge, this._maxAdaptiveWorldSpaceCanvasSize-4); // -4 is to consider the border of 2 pixels, other we couldn't allocate a rect
 
             let newScale = edge / ((isW) ? this.size.width : this.size.height);
-            if (newScale !== this.scale) {
+            if (newScale !== this._renderableData._renderingScale) {
                 let scale = newScale;
-//                console.log(`New adaptive scale for Canvas ${this.id}, w: ${w}, h: ${h}, scale: ${scale}, edge: ${edge}, isW: ${isW}`);
+                //console.log(`New adaptive scale for Canvas ${this.id}, w: ${w}, h: ${h}, scale: ${scale}, edge: ${edge}, isW: ${isW}`);
                 this._setRenderingScale(scale);
             }
         }
@@ -1625,6 +1625,7 @@
             let key = `${useMipMap ? "MipMap" : "NoMipMap"}_${anisotropicLevel}`;
 
             let rd = group._renderableData;
+            let rs = rd._renderingScale;
             let noResizeScale = rd._noResizeOnScale;
             let isCanvas = parent == null;
             let scale: Vector2;
@@ -1633,6 +1634,8 @@
             } else {
                 scale = group.actualScale.multiply(this._canvasLevelScale);
             }
+            scale.x *= rs;
+            scale.y *= rs;
 
             // Determine size
             let size = group.actualSize;

+ 1 - 0
canvas2D/src/Engine/babylon.canvas2dLayoutEngine.ts

@@ -95,6 +95,7 @@
                     prim.layoutArea = contentArea;
                 }
             }
+            C2DLogging.setPostMessage(() => `Prim: ${prim.id} has layoutArea: ${prim.layoutArea}`);
         }
 
         get isChildPositionAllowed(): boolean {

+ 14 - 8
canvas2D/src/Engine/babylon.group2d.ts

@@ -350,8 +350,15 @@
 
             // Update the Global Transformation and visibility status of the changed primitives
             let rd = this._renderableData;
-            if ((rd._primDirtyList.length > 0) || context.forceRefreshPrimitive) {
-                sortedDirtyList = rd._primDirtyList.sort((a, b) => a.hierarchyDepth - b.hierarchyDepth);
+            let curPrimDirtyList = rd._primDirtyList;
+            if ((curPrimDirtyList.length > 0) || context.forceRefreshPrimitive) {
+                // From now on we use the 'curPrimDirtyList' variable to process the primitives that was marked as dirty
+                // But we also allocate a new array in the object's member to get the prim that will be dirty again during the process
+                //  and that would need another process next time.
+                rd._primDirtyList = new Array<Prim2DBase>();
+
+                // Sort the primitives to process them from the highest in the tree to the lowest
+                sortedDirtyList = curPrimDirtyList.sort((a, b) => a.hierarchyDepth - b.hierarchyDepth);
                 this.updateCachedStatesOf(sortedDirtyList, true);
             }
 
@@ -394,7 +401,7 @@
                 this._viewportSize.height = sh;
             }
 
-            if ((rd._primDirtyList.length > 0) || context.forceRefreshPrimitive) {
+            if ((curPrimDirtyList.length > 0) || context.forceRefreshPrimitive) {
                 // If the group is cached, set the dirty flag to true because of the incoming changes
                 this._cacheGroupDirty = this._isCachedGroup;
 
@@ -411,7 +418,7 @@
                     // Each primitive that changed at least once was added into the primDirtyList, we have to sort this level using
                     //  the hierarchyDepth in order to prepare primitives from top to bottom
                     if (!sortedDirtyList) {
-                        sortedDirtyList = rd._primDirtyList.sort((a, b) => a.hierarchyDepth - b.hierarchyDepth);
+                        sortedDirtyList = curPrimDirtyList.sort((a, b) => a.hierarchyDepth - b.hierarchyDepth);
                     }
 
                     sortedDirtyList.forEach(p => {
@@ -425,15 +432,14 @@
                 }
 
                 // Everything is updated, clear the dirty list
-                rd._primDirtyList.forEach(p => {
+                curPrimDirtyList.forEach(p => {
                     if (rd._primNewDirtyList.indexOf(p) === -1) {
                         p._resetPropertiesDirty();
                     } else {
                         p._setFlags(SmartPropertyPrim.flagNeedRefresh);
                     }
                 });
-                rd._primDirtyList.splice(0);
-                rd._primDirtyList = rd._primDirtyList.concat(rd._primNewDirtyList);
+                rd._primDirtyList = curPrimDirtyList.concat(rd._primNewDirtyList);
             }
 
             // A renderable group has a list of direct children that are also renderable groups, we recurse on them to also prepare them
@@ -839,7 +845,7 @@
             let sizeChanged = !Group2D._s.equals(rd._cacheSize);
 
             if (rd._cacheNode) {
-                let size = Group2D._s;
+                let size = Group2D._s2;
                 rd._cacheNode.getInnerSizeToRef(size);
 
                 // Check if we have to deallocate because the size is too small

+ 25 - 29
canvas2D/src/Engine/babylon.prim2dBase.ts

@@ -4114,7 +4114,7 @@
                 let primNewSize: Size = Prim2DBase._size;
                 let hasH = false;
                 let hasV = false;
-                let paddingApplied = false;
+                //let paddingApplied = false;
                 let hasPadding = this._hasPadding;
 
                 // Compute the size
@@ -4155,39 +4155,35 @@
                     }
                 }
 
-                if (!isVSizeAuto || !isHSizeAuto) {
-                    Prim2DBase._curContentArea.copyFrom(this._contentArea);
+                Prim2DBase._curContentArea.copyFrom(this._contentArea);
 
-                    if (hasPadding) {
-                        let area = Prim2DBase._icArea;
-                        let zone = Prim2DBase._icZone;
+                if (hasPadding) {
+                    let area = Prim2DBase._icArea;
+                    let zone = Prim2DBase._icZone;
 
-                        this._getInitialContentAreaToRef(primNewSize, zone, area);
-                        area.width = Math.max(0, area.width);
-                        area.height = Math.max(0, area.height);
+                    this._getInitialContentAreaToRef(primNewSize, zone, area);
+                    area.width = Math.max(0, area.width);
+                    area.height = Math.max(0, area.height);
 
-                        this.padding.compute(area, this._paddingOffset, Prim2DBase._size2);
+                    this.padding.compute(area, this._paddingOffset, Prim2DBase._size2);
 
-                        if (!isHSizeAuto) {
-                            this._paddingOffset.x += zone.x;
-                            this._paddingOffset.z -= zone.z;
-                            this._contentArea.width = Prim2DBase._size2.width;
-                        }
-
-                        if (!isVSizeAuto) {
-                            this._paddingOffset.y += zone.y;
-                            this._paddingOffset.w -= zone.w;
-                            this._contentArea.height = Prim2DBase._size2.height;
-                        }
-                    } else {
-                        this._contentArea.copyFrom(primNewSize);
+                    if (!isHSizeAuto) {
+                        this._paddingOffset.x += zone.x;
+                        this._paddingOffset.z -= zone.z;
+                        this._contentArea.width = Prim2DBase._size2.width;
                     }
 
-                    if (!Prim2DBase._curContentArea.equals(this._contentArea)) {
-                        this._setLayoutDirty();
+                    if (!isVSizeAuto) {
+                        this._paddingOffset.y += zone.y;
+                        this._paddingOffset.w -= zone.w;
+                        this._contentArea.height = Prim2DBase._size2.height;
                     }
+                } else {
+                    this._contentArea.copyFrom(primNewSize);
+                }
 
-                    paddingApplied = true;
+                if (!Prim2DBase._curContentArea.equals(this._contentArea)) {
+                    this._setLayoutDirty();
                 }
 
                 // Finally we apply margin to determine the position
@@ -4196,10 +4192,10 @@
                     let mo = this._marginOffset;
                     let margin = this.margin;
 
-                    // We compute margin only if the layoutArea is as big as the contentSize, sometime this code is triggered when the layoutArea is
-                    //  not yet set and computing alignment would result into a bad size.
+                    // We compute margin only if the layoutArea is "real": a valid object with dimensions greater than 0
+                    //  otherwise sometimes this code would be triggered with and invalid layoutArea, resulting to an invalid positioning
                     // So we make sure with compute alignment only if the layoutArea is good
-                    if (layoutArea && layoutArea.width >= transformedBSize.width && layoutArea.height >= transformedBSize.height) {
+                    if (layoutArea && layoutArea.width > 0 && layoutArea.height > 0) {
                         margin.computeWithAlignment(layoutArea, transformedBSize, ma, levelScale, mo, Prim2DBase._size2);
                     } else {
                         mo.copyFromFloats(0, 0, 0, 0);

+ 1 - 1
canvas2D/src/shaders/text2d.fragment.fx

@@ -26,7 +26,7 @@ void main(void) {
 		discard;
 	}
 #ifdef FontTexture
-	gl_FragColor = vec4(color.xxx*vColor.xyz*vColor.a, vColor.a);
+	gl_FragColor = vec4(color.xxx*vColor.xyz*vColor.a, color.x*vColor.a);
 #else
 	gl_FragColor = color*vColor;
 #endif