HISE Logo Forum
    • Categories
    • Register
    • Login

    applyMask behaves differently at different UI scales

    Scheduled Pinned Locked Moved Bug Reports
    16 Posts 7 Posters 981 Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • ulrikU
      ulrik @Fergler
      last edited by

      @Fergler said in applyMask behaves differently at different UI scales:

      LookAndFeel.js

      Your snippet doesn't contain the "LookAndFeel.js" file, you have to provide that file as well

      Hise Develop branch
      MacOs 15.3.1, Xcode 16.2
      http://musikboden.se

      F 1 Reply Last reply Reply Quote 0
      • F
        Fergler @ulrik
        last edited by

        @ulrik Oh, first timer snippeting. I thought it just bundled all xml js into one.

        Here is the look and feel:

        
        namespace LookAndFeel {
        
        const themeColour = 0xFFEBEBEB;
        const themeColourTrans = 0x99EBEBEB;
        
        function drawArc(x, y, g, path, start, end, color, arcThickness, scale) {
        
            path.clear(); // Clear previous path data
        
            path.addArc([x, y, 1, 1], start, end);
            g.setColour(color);
            var pathArea = path.getBounds(scale - arcThickness);
        
            pathArea[0] += arcThickness / 2;
            pathArea[1] += arcThickness / 2;
            g.drawPath(path, pathArea, arcThickness);
        
        }
        
            laf.registerFunction("drawRotarySlider", function(g, obj) {
                var isBiDirectional = obj.min < 0 ? true : false;
                var startOffset = Math.toRadians(126); // Convert degrees to radians
                var minArcLength = Math.toRadians(4); // Convert degrees to radians
                var centerX = obj.area[0];
                var centerY = obj.area[1];
                var size = obj.area[2];
        
                var p1 = Content.createPath();
                var normalizedValue = obj.valueNormalized;
        
                // Static white arc (background)
                drawArc(centerX, centerY, g, p1, -startOffset, startOffset, themeColour, 1, size);
        
                var centerAngle = 0;
                var startAngle = -startOffset;
                var endAngle = startOffset;
        
                if (isBiDirectional) {
                    var centerDeviation = minArcLength; // Deviation at the center
        
                    if (normalizedValue <= 0.5) {
                        // Scale the left deviation based on normalized value approaching 0.5 from 0
                        var scale = 1 - (normalizedValue / 0.5);
                        var leftDeviation = centerDeviation + scale * (startOffset - centerDeviation);
                        startAngle = -leftDeviation;
                        endAngle = centerAngle + centerDeviation; // Minimum arc on the right
                    } else {
                        // Scale the right deviation based on normalized value approaching 1 from 0.5
                        var scale = (normalizedValue - 0.5) / 0.5;
                        var rightDeviation = centerDeviation + scale * (startOffset - centerDeviation);
                        startAngle = centerAngle - centerDeviation; // Minimum arc on the left
                        endAngle = rightDeviation;
                    }
                } else {
                    // Non-bidirectional knob starts a little after the far left
                    startAngle = -startOffset; // Adjusting start point to include minimum length
                    endAngle = startAngle + normalizedValue * (2 * startOffset); // Stretching end point based on normalized value
                    endAngle = Math.max(endAngle, startAngle + 2 * minArcLength); // Ensuring visible minimum length
                }
        
                // Draw the dynamic arcs
                drawArc(centerX, centerY, g, p1, startAngle, endAngle, themeColour, 6, size);
            
            // Math.pow(0.001, size)
        g.setFont("Oxygen", Math.pow(size/3.4, 2)/(size/2));
        g.drawAlignedText("PUNCH", obj.area, "centred");
            });
            
        
        laf.registerFunction("drawLinearSlider", function(g, obj) {
            var left = obj.area[0];
            var top = obj.area[1];
            var width = obj.area[2];
            var height = obj.area[3];
            var normalizedValue = obj.valueNormalized;
            
            g.beginLayer(1);
            var border = Content.createPath(); 
            var innerMask = Content.createPath(); 
            var midline = Content.createPath();
            
            g.setColour(themeColourTrans);
            g.fillRoundedRectangle(obj.area, 4);
            border.addRoundedRectangle([left, top, width, height], 4); 
            g.applyMask(border, [left+1.5, top+2, (width*2)-3, (height*2)-4], 1);
            g.endLayer();
            
            g.beginLayer(1);
            
            g.setColour(themeColourTrans);  
            g.fillRect([(width/2)-0.5, top, 1, height]);
        
            var center = left + width * 0.5;
        
            // Calculate the filled rectangle dimensions
            var filledWidth, filledLeft;
        
            if (obj.min < 0) { // Check if the slider is bidirectional
                if (normalizedValue < 0.5) {
                    // Fill from center to left
                    filledWidth = (0.5 - normalizedValue) * width;
                    filledLeft = center - filledWidth;
                } else {
                    // Fill from center to right
                    filledWidth = (normalizedValue - 0.5) * width;
                    filledLeft = center;
                }
            } else {
                // Non-bidirectional, fill from left to current value
                filledWidth = normalizedValue * width;
                filledLeft = left;
            }
        
            // Draw the filled rectangle
            
            g.setColour(themeColour);
            g.fillRect([filledLeft, top, filledWidth, height]);
            
            g.applyMask(border, [left, top, (width*2), (height*2)], 0);
            g.endLayer();
          
            
        });
        
        
            
        }
        
        
        F 1 Reply Last reply Reply Quote 0
        • F
          Fergler @Fergler
          last edited by

          Example:

          ezgif-7-9f12eb21e7.gif

          ulrikU 1 Reply Last reply Reply Quote 0
          • ulrikU
            ulrik @Fergler
            last edited by

            @Fergler sorry but your snippet reference to a lot of "included .js files" so it's impossible to read it without those files, could you provide a small example that shows the problem?

            Hise Develop branch
            MacOs 15.3.1, Xcode 16.2
            http://musikboden.se

            F 1 Reply Last reply Reply Quote 0
            • F
              Fergler @ulrik
              last edited by

              @ulrik Here is an example snippet as simple as I could make it

              HiseSnippet 991.3ocsV0saaaCElxIJX1sqXcnO.B4JE.OOozttALLz1jXGXzjTi3ztATTTPKRYyYJRARpznFz61yydE5yReC5av1ghVwJqFosFX9Bac9kemCOmO4QJYBUqkJjW6yJyoHua6OtTXls+LLSfFd.x6N9Gi0FpJvoZuxbrVSIHOuMNzpvq8lnpOe7Q6g4XQBcoJD5ERVB8HVFyrT6nG+TFmO.SnmwxZ38Cd7vDoXeIWV.3YC+HTNNYNdJ8Dr0sV9Hus5SXFoZrAanZvm8jjxwyjuQ37+ELMaBmZEhQigD4Ti1eFiSFUWqZDxayQKq7MbU987OlQXWoeYG36pLDrLhl8.uV2Djh+JfjWCHsoCR20ebhhkaVZwhma4OT.WHoXnU2DJNeQs98V96KAODldY34zAJP3pHBeXTT2.3qc90NP2VaB33zfeKnuXJSP6knnPcbHWNAyc46Hob9SDjATJODhoC3dOEcJyNSLnPjXXRQ31DE9MmJMXU4XNiPUa2MHs13ztAxI+4NAW1oS6o8l.wJNBWRUgwP9.MZpwcoG59QC4m3LkBCJmRSLgPB5gArYU2o84XUPdLf555zA6QXyrPmG4w8vDxoxBAgRrY.KlxogurNOuL5U+3tcuRJ9ZR6dMo6CRupaPbjCR37bdIrRLOLOtpvp7pafQUPcm8zdTAwUgfh2YaZtNstp0z.1.DepPNIb6ynZy1ci5ZOi59VfTbhzPelHbmNWB48ccB9ulRSWoMa5URN2BfUX1t0oto.CEEYSnptAmi4PQU6HLVd8Y8s9xl0SbUaCGkhgBl4Y4zExCjbhcF197mtYfVztr6HKPH3poZC4NK1PbScHFjjs7scSTE1aREgd9vCvFbcVfDBGRNUYX1Zw6.54.Ukauqs+AT8biLux2rbovd7d29yclWf778rGUY8CZSosgrku8dFkwHDNcjTyrM7FTmuG1lxGydaEfu7d+8ge3s+0ixZxthPY3KZR1pKRSYWTQKBaIYZC.ogY.aIx668etlFPno3BNL0MGxCmIlSImIq7G8oLM.GmjTvwlqS7YY3WXvB3lrMVFEATHkMA0WAaXzMxF9kBw65OhYRlsZL1ZEXDt9++.iKdGx252OMEXaVBvM8G7Gq6KL9LGOvtYXhoGigqd6j2IEYiA5yDJb5BAkqsCgsr6ON4n5gxw.+Tkv+.eVXL1J6svXbsQXnKQIechaqy9VpuoRCfIQ0KkaC+6.PNHtdey2OpWjcPm85jDa4+CwHzpiY20Hl6uFw7f0HleZMh4gqQL+7ZDyubiwX+uJOovHybqCfhQ8q38775KvvjU0TH5eA9EXuz.
              
              ulrikU 1 Reply Last reply Reply Quote 0
              • ulrikU
                ulrik @Fergler
                last edited by ulrik

                @Fergler Yes I can see the problem here as well.
                I made a gif of what is happening.

                The path (p1) is used as a mask (the black rounded rectangle) , I also draw the same path with

                g.drawPath(p1, obj.area, 4);
                

                the white rounded rectangle

                As you can see, the mask is not following the scaling but the same path alone does.

                @Christoph-Hart this looks like a bug.

                maskissue.gif

                HiseSnippet 939.3ocsV8taaaCDmzIpX1scnAXO.B4SJ.BtVoo+AXXnoIwtvnwoFQYECnHnflh1lyTjBTzISsneauW6YouA8MX6nnUrbi65fwp9frNd+ti+ti2czC0JJKOWoQ3lWTjwP364EWHMSOdJgKQ8OAguuWNkH3xIYDyTzQEYj7bVBBi25kVH3laiJe97yOhHHRJa4RHzaTbJ6TdJ2rb0gG9JtPzijvtfmVC8AG1mpjGqDp4.c1xqCJiPmQlvNiXg0vCguS2DtQoiMDCKGg29HURQ7T00RG92vy4iDLqPDJFbja4dJQhkw1UQGOkKRFVE14HvKCWlD1xkD9IuA7D9MquLY7fRE9Ksnd9.2XU5s0JzKpN85TidqgR3ZTZaGk1wKlp4YlkZr74td8kFldLAR60ohCKpwe0v6XEfPZZmRlw5oAgarH3Ic5D5Cu16maAY9biufL1+W76Jmvkr1TMChiWJTiHBm+NUol8BYROFSD.1.naqYS34f+5MWRMbkLX2DM45yUFhtHVvSX5cC8GWobRnuZzuum+GZ0p4j14Li6zNv8SN3sDvufpwPEx4LpI.f2l.DwtbqlWQz9YQ.EqBJGGGBUlANDSZOBXj7TRASGXzyY1kyhZSRRNWMWB0AV2RjSDrf2V47214xva9Np126e4C2eozi.oKC8i533HIKSTLfjOKHKpLtJQE5uXWsPXxDGSpH2sC4qmxMLmCsYtxPw5uMjbGX24OZe4NQyKOCpkwfDwqjpQA6dAK2raXmPazTc.4qjmoLrWKC1q0G.F+wV9eopwiWqNq60JgvFqqQssSW+uYXfbd5HlNz+Jh.ReU.gx+U6o7958T0a4otnsFPkrujadcFS90FDfVjhr8eKXE.0T188iK59bkzHNzjcGOaFDUx25i7P+Z+SHFRkW.GBaRFSa3V9iOgcELRz0S2z6DV9LiJqDaZlRZ2dr22ZO+C.C1tUEUe.sfYw72WQjC+z6+ymit8PDX7kJYtfXVcllcP9BEvgxJCRrCKj4bSQ8A8+uMn6+JE2waH2PmtdN1XMbDx9eO33hqGtuW2wigwHKI31d89suO2EffwVF312ADilaO3OadZLL4fxfcWJYBaSAtgs70I2oplHFl9TJ72vyBkQVY7BkQUJQoDpV8Npqn2dAzOTtBvIY4cuM8FXk8itc4dJbe36nzUc0sLb+M0vGsoFdvlZ3i2TCexlZ3S2TCe121P6eW4EyMpTWaCBMXX2xwSXbWIAp.KqVQ+CffzY8m
                

                Hise Develop branch
                MacOs 15.3.1, Xcode 16.2
                http://musikboden.se

                F 1 Reply Last reply Reply Quote 0
                • F
                  Fergler @ulrik
                  last edited by

                  I should mention this also applies to the plugin preview window if you changed zoom scale - but I have not tested a built plugin yet.

                  1 Reply Last reply Reply Quote 0
                  • GoodflowG
                    Goodflow
                    last edited by

                    This issue is still present on the latest develop build. I'm getting inconsistent results when testing across platforms.

                    OSX - scaling bug in plugin preview, but compiled plugin has no issues

                    WIN - scaling bug in plugin preview and compiled plugin

                    Added a UI zoom tile to the prior snippet for convenience:

                    HiseSnippet 1196.3ocsVstaaaCElxILq1ccqEXO.B4WJ.FdVtYa.aXnIwWxBpcrQbZ1.BB5nkns4BEofDUxbCBv9wvds1yxdC1aP2ghRwRINaMAq5GRjma76bz4BGEI8nwwxHjU0iWDRQVeJd7BgZd64Dl.cPGj0yvwdDNSLKjnli1aQHINl5irrVaesHVUWGk972uZOBmH7nKIgPmHYdz9r.lZI0Q67ZFm2i3SOlETP5s24.OonsjKS.3rFtIJj3cNYF8PhVrJXj0Fc8YJYzXEQQiQVqumzew34xKEF4OgEylvo5MtnwfgLj6I49ZDqohZOmw8Gk61wHvJiVFDVyDD9B7.lO6F5KCFOOkg8RMJFOrpTFdqUBdtEgWyBvaEPxp.jV2.oWfG6EwBUK4nwySwGHTznoDHrWDJFYQU9yJ31RPBgpQ.4bZuHXyMZ370MaV2Fds02UCh7wJaNYp82a2ULiInM7hnferOWNgvM1quTd9tB+dTJ2AzAjtQDcFKFrWuDgmhIENa5GQt7HohDsXLm4Si1rt8zblypaKm7KaYeUsZUm0HlpL+scLehAq4C1EXMExPNh5ob.waP.fnIWq5EjH6PW.h4NkAiifLSGiDyZLAPjnOYAMxQEkP0jCcaP78ORlHf7.sYIhYbpyo4F+zlmU+l0tEV25rur0xcuD1cVca2lFLRBC4KFPhO2IzM0uRkptc1opEgJ7MHIGb20kubNSQMFTG4RcEs8djfaa8Ies9k4OZb5+fBQLHP7ZgbhylGSiUaVuYcs2j+CxVJNTpnCENaU6J.wWWy91rlNck7zlORx4ZecEr0U5Q+aJ5HRBlPipaeAgCgubAgz+x0T36ulpXIumwaKHnTbffoFFRE2Wi.TVHRW+kgJPTUZ02mkU8YRoQLnHaCrNBhRwawVdn2bPGhhjaEvfvgDRiTLM9s5Pu.ZIZpoqh6PiOWICgtaskAgRg93sv+Wm4uBxXoOpE4KfRvvwr2kCjc9q286uBUvjUUY80LlrGWRTPK8iYPnSa3OGWjjq9Dx7neityha17yzcx7IiC7bb6jXkLXLUo0MFMYVd+6pa.x+dsRP9cPIpnxTaUjbZnqxeXgupls8lchXW.cP9V6oDdLsdJoz3WIRCSTgIpRj1KY5TZjNhTh7XRPHmdDjJUhroG2diFTVXETWE.t0.o+sLCLPj1i3A4k.cc8dJ4zgc6F.sYTCR3JVHmcKv2lSIQ5IHsauBb0W5QzUE2xemjbWD7lXpNUd+92Gt5CckAdmBjssa13qpms3axV41nY9hV2PJaQqFMgumU6ZXV8clCAS.k9Ibhp7XQ8cAxX.dPoYQ54MhXlZQw6J7+1rxOTH9B7Hlxa9pwXkUfQn.9iAFytgwyvcgLTO0R.tNt2O8w45DHXxmt7b.QEwz8NNLIXLT34QgSWHnbceUqJ5Nfl8MyaqLFFfkt48vSFSW8dqLlt4LQADuH4a8L8M02g4IoT.LIRu91mf62ans6c6WF.kCu0yqrgtkZsdbp8xGmZa+PUCiOoa+GpRafOb3wcenZ8D7Q6dXmgCdn58T7fgcr+wen6GBP0cn1MA5qaJTPnAi5l1X1xpqf.4bo4mn+APXBroF
                    

                    I keep coming back to this commented-out line 191 in PostGraphicsRenderer.cpp:

                    if (scale)
                    	{
                    		other = path;
                    		Rectangle<float> area(0.0f, 0.0f, bd.width, bd.height);
                    		PathFactory::scalePath(other, area);
                    		pathToUse = &other;
                    	}
                    	else if (scaleFactor != 1.0f)
                    	{
                    		other = path;
                    		//other.applyTransform(AffineTransform::scale(scaleFactor));
                    		pathToUse = &other;
                    	}
                    

                    @Christoph-Hart should there be something in this spot to handle the non-1.0f scaling for applyMask? I've tried uncommenting the line, adding variations on the two lines from "if(scale)" to the "else if" section, and removing both conditionals/leaving the contents of "if(scale)", but no luck so far.

                    A 1 Reply Last reply Reply Quote 0
                    • A
                      aaronventure @Goodflow
                      last edited by

                      @Goodflow same as drop shadow from alpha.

                      GoodflowG 1 Reply Last reply Reply Quote 0
                      • GoodflowG
                        Goodflow @aaronventure
                        last edited by

                        @aaronventure I may be poking around the wrong part of the source code, then. The scaling op for that is in ScriptedDrawingActions.cpp, can't make sense of it though.

                        After a few tweaks to the snippet there's some progress:

                        • "bool drawOnParent" should be false in the beginLayer call

                        • the Path.addWhateverShape call should be done before beginLayer, then use fillPath inside the Layer before applyMask

                        This new snippet works on 50% scale and above on OSX , 75% and above on Windows.

                        HiseSnippet 1244.3ocsV0raaaDDdorYRjbZaBPe.H7IY.AUJY2jzZzFYqebMp9CVNtE0vHcE4Josd4tDjKsqhgA5gdtuQ8deM5aPeCZmkKoDorcpc.BunclYmY9lQyO6v.gCILTDfLJd7beBx3olilykyZNCS4nCagLdjojDJQ6O2GGFRbQFFqcfRlQw0Qwe+yq2GyvbGxRVHzIBpCoK0iJWxcXiumxXcvtjiodYt8NMNzQvaJXhH.GqYZi7wNmimR5iUWqfI.h1tToHXjDCfAYr99B24ilItjqu+IzP5XFQQTCMBLjlcGAyUgXEWTyYTl6vz3MDAVY3xneMcz+4l8ntzE7WlEdVr.qkZjMeXTHO7VKG7pkEd1Yf2s.IiLPZcMjdt4Hm.puboDEd1v7PtjDLACo8rPQeWTg+nfYSAbCtrpG9bRm.fXgFkegscEq511asaIHyGJsX3IVeiUa9TJmT0If.wwALwXLSautBw46wc6PHrxfNvsqFPlRCA60Ih6HoBd4McCvWdjPhClOhQcIAaVwZRpvoUrDi+ksrtpTohWfCrv0A2cJvpJFb1o0O6K1oxBpsyQAxpmSV8y1ErRohSqNAJm1iwJqKcBAL4Bnqn1E90.WjlCzgzPrblB+E8qUE65djHhC0GGQbjX9TFoLtdEqZ1ZSLs5XHB4cwyIAkmfYgDE+oUCIRs6V30oADBWKTAnXm3WKNfiwrVD12mMuGN77XYJOkZTkTB2U6oTmeS2b4LpLACpL8B2nL0NJyb8V6llusD79BIY.u7VktBL30krVUzjI2pLUBKPvXJnbKhUMtAuOEKyi7FSBpXcAlEQVbQnZNeKh4c2hjsC1Q++WlKJ3GxoxA9D9c0WiR9SW0NkfJ3px3loOMoYRWghntp4aGqluEi2rSvPu4vVXIN0JfAAm3SBjTE9MZQt.lvoaQKZ1hDdtT3CCqZJ77Ebk6Md7+mO+0k9i1X9RhusAzY4Oh9tT.03ue2u+5KotxYPly3u.NyHzoyjJpeBEGxK75FxjIYZu1gIvRJe5wTH6p78mYlkUsLfnwOmAD+FtQRXqiwmY1LJTJ7FQjJcCQimlNw9ol6T+kup1WYa+JaDTj5kcT9R55ZFwI0B+og4Ukrr1rU.8BXTwWq6FpDyJNyli0fHoejLGq8ilLgDnxQ4XOB64yHGAEY4XqGls+vd4urDZO8fnomvcEy3fYjNXGnhE3KChzri2psmGL2P1KhIo9L5JfuIifCTqJZ17VvUWgCV0urR7NN5lH3MgDUQ9AcuKb0EF+BxNEXaYYWsdkzCeY5osSOrS5gEhdQ5gWt3PhrZUsSOTeAqjC0qZC+dVoqQI0hoENQMRqGSKg62.cyUYvRTgaDCKyuYU8bhDAPtI25L0JKdHUNO6yMVcc652u0su+WCbeg6yMGRkNytc7V3VvKL.4iMdSd7xmX1F5IbjKA65lc9wONuTAAKOUyA5gkATXDhY+HuQPStCA7NmSXpY7FETilzz1JZU1XDrqKl3eguDg0TzFIBqkJD4gcBDu0QOCW87nmDyAvDO9kgO1ramAV0t4raOnA7sNN4MzJpU+CSss+vTamGpZllmzt6CUoGY1evwsenZ8Dyi1qeqA8dn5sgYuAsr9guq88AnpYh6EAKPzMMHTugsiWEXXzligZt35Sz+AH5Kxc.
                        
                        bendursoB 1 Reply Last reply Reply Quote 0
                        • bendursoB
                          bendurso @Goodflow
                          last edited by

                          I'm still having the same issue. @d-healey are you still using cropped rounded png images to avoid this issue? I saw in other related post you used to do that :)

                          d.healeyD 1 Reply Last reply Reply Quote 0
                          • d.healeyD
                            d.healey @bendurso
                            last edited by

                            @bendurso I'm using masks now. However below 1x scaling I run into the same issue, so as a workaround I've limited my plugin's minimum zoom to 1.

                            Libre Wave - Freedom respecting instruments and effects
                            My Patreon - HISE tutorials
                            YouTube Channel - Public HISE tutorials

                            ustkU 1 Reply Last reply Reply Quote 1
                            • ustkU
                              ustk @d.healey
                              last edited by

                              @d-healey @bendurso I started reporting those bad re-scaling of masks, shadows, and different layer operations years ago. Added to the very poor shadow efficiency (except for font), the paint methods really really need a cleaning/fixing session ☺

                              Can't help pressing F5 in the forum...

                              1 Reply Last reply Reply Quote 2
                              • F
                                Fergler
                                last edited by

                                Another interesting thing. Content.createScreenshot will take a screenshot but the results have different mask scaling than the UI, even when my zoom is at 100% and everything looks correct.

                                A 1 Reply Last reply Reply Quote 1
                                • A
                                  aaronventure @Fergler
                                  last edited by

                                  @Fergler that mask is one of the final bosses of HISE UI stuff

                                  1 Reply Last reply Reply Quote 0
                                  • First post
                                    Last post

                                  36

                                  Online

                                  1.7k

                                  Users

                                  11.7k

                                  Topics

                                  102.0k

                                  Posts