About Clipping mask

Anyone, especially newbies, asking for help with Photoshop Scripting and Photoshop Automation - as opposed to those contributing to discussion about an aspect of Photoshop Scripting

Moderators: Kukurykus, Tom, xbytor

Paul MR

About Clipping mask

Post by Paul MR »

I'm sorry but your amended version will fail if your document does not have a background layer, this was the mistake I made with the example, here is the corrected code...

Code: Select allfunction isClippingLayer(){
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Lyr '),charIDToTypeID('Ordn'),charIDToTypeID('Trgt') );
var desc = executeActionGet(ref);
var idx = desc.getInteger (stringIDToTypeID('itemIndex'));
var group = desc.getBoolean(stringIDToTypeID('group'));
var clipInfo=false;
if(group) clipInfo = 'topClippingLayer';
try{
activeDocument.backgroundLayer;
IDX = idx;
}catch(e){IDX = ++idx;}
try{
    var ref = new ActionReference();
   ref.putIndex(charIDToTypeID( 'Lyr ' ), IDX );
   desc =  executeActionGet(ref);
    }catch(e){return clipInfo;}
    group = desc.getBoolean(stringIDToTypeID('group'));
    if(group && clipInfo == 'topClippingLayer' ) clipInfo = 'middleClippingLayer';
    if(group && clipInfo == false ) clipInfo = 'bottomClippingLayer';
    return clipInfo;
};

alert(isClippingLayer());

IsraelThompson

About Clipping mask

Post by IsraelThompson »

My wild guess was right! I figured it had something to do with the background! Thanks Paul!

User avatar
Stephen_A_Marsh
Posts: 17
Joined: Sun Aug 04, 2019 12:37 pm

Re: About Clipping mask

Post by Stephen_A_Marsh »

I know that this is an old topic, however, this doesn't appear to be discussed very much.

I was in need of selecting the bottomClippingLayer if the topClippingLayer or a middleClippingLayer was selected.

Is there an obscure way to do so via AM code for making the bottomClippingLayer active?

This is what I came up with before finding this topic:

Code: Select all

selectGroupedBaseLayer();

function selectGroupedBaseLayer() {
    // Stephen Marsh, v2.0 - 20th September 2022
    // Works with a visible or invisible clipping mask base layer
    //alert('Clipping Mask = ' + activeDocument.activeLayer.grouped);
    for (i = 0; i < activeDocument.layers.length; i++) {
        if (activeDocument.activeLayer.grouped === true) {
            //alert("Grouped, move on...");
            toggleLayerVisibility(true);
            selectForwardORBackwardLayer(false, "backwardEnum");
            toggleLayerVisibility(true);
            //alert('Clipping Mask = ' + activeDocument.activeLayer.grouped);
            //activeDocument.activeLayer.visible = true;
        }
        // Helper Functions
        function toggleLayerVisibility(toggleOptionsPalette) {
            var s2t = function (s) {
                return app.stringIDToTypeID(s);
            };
            var descriptor = new ActionDescriptor();
            var list = new ActionList();
            var reference = new ActionReference();
            reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
            list.putReference(reference);
            descriptor.putList(s2t("null"), list);
            descriptor.putBoolean(s2t("toggleOptionsPalette"), toggleOptionsPalette);
            executeAction(s2t("show"), descriptor, DialogModes.NO);
        }
        function selectForwardORBackwardLayer(makeVisible, forwardORbackward) {
            var s2t = function (s) {
                return app.stringIDToTypeID(s);
            };
            var descriptor = new ActionDescriptor();
            var list = new ActionList();
            var reference = new ActionReference();
            // "forwardEnum" or "backwardEnum"
            reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t(forwardORbackward));
            descriptor.putReference(s2t("null"), reference);
            // true or false
            descriptor.putBoolean(s2t("makeVisible"), makeVisible);
            list.putInteger(15);
            descriptor.putList(s2t("layerID"), list);
            executeAction(s2t("select"), descriptor, DialogModes.NO);
        }
    }
}

User avatar
Kukurykus
Posts: 482
Joined: Mon Jul 25, 2016 12:36 pm

Re: About Clipping mask

Post by Kukurykus »

Code: Select all

sTT = stringIDToTypeID
iI = (aL = (aD = activeDocument).activeLayer)
.itemIndex, prnt = aL.parent.id; function grouped(v) {
	(ref = new ActionReference()).putIndex(sTT('layer'), v)
	return (dsc = executeActionGet(ref)).getBoolean(sTT('group'))
	&& ((id = dsc.getInteger(sTT('parentLayerID'))) < 0 || id == prnt)
}

while(aL.grouped) {
	if (!grouped(--iI)) (ref = new ActionReference()).putIndex(sTT('layer'), ++iI),
	(dsc = new ActionDescriptor()).putReference(sTT('null'), ref),
	executeAction(sTT('select'), dsc), Function('break')
}

User avatar
Stephen_A_Marsh
Posts: 17
Joined: Sun Aug 04, 2019 12:37 pm

Re: About Clipping mask

Post by Stephen_A_Marsh »

Thank you Kukurykus!

The code is selecting the last middleClippingLayer rather than the parent/base "bottomClippingLayer" that all other layers in the clipping group/mask are indented against.

User avatar
Kukurykus
Posts: 482
Joined: Mon Jul 25, 2016 12:36 pm

Re: About Clipping mask

Post by Kukurykus »

I hope it is what you needed, but to be honest your answer confuses me a little, do you mean it shouldn't select the most bottom clipping layer? By middle or top I understand one of clipping layers in the same group, so any over that is on the bottom - the lowest. Enlight me please... ;)

User avatar
Stephen_A_Marsh
Posts: 17
Joined: Sun Aug 04, 2019 12:37 pm

Re: About Clipping mask

Post by Stephen_A_Marsh »

The layer containing transparency that all upper layers are clipped against should be selected, not the last clipped layer.

I was hoping for more refined code that does the same thing as the function that I created and posted... That code is a bit of a hack, exploiting layer visibility and backward layer selection. It works, however, when I found this topic I was excited to learn about the AM property bottomClippingLayer.

Internet searches find very little mention of topClippingLayer, middleClippingLayer or bottomClippingLayer.

User avatar
Kukurykus
Posts: 482
Joined: Mon Jul 25, 2016 12:36 pm

Re: About Clipping mask

Post by Kukurykus »

Okay, I read now the thread from beginning to get to know what you mean by bottomClippingLayer. If I'm right it's just clipping layer, while all others over it should be called clipped, and if there are more of them than one then each clipped layer from the same group is at same time clipping layer to the one over it and clipped layer to one that's below. The terms you use are fictional - created for better description of the problem in this thread, so it's logical you couldn't find much about them, there are no such AM properties ;)

The method you used is slow as it forces selection of other layers before the final one will be found. Use fast calculation by changing ++iI to iI.

By the way to avoid Syntax Error change also Function('break') to aL = aD.activeLayer. Now I hope it does exactly what you needed :D

User avatar
Stephen_A_Marsh
Posts: 17
Joined: Sun Aug 04, 2019 12:37 pm

Re: About Clipping mask

Post by Stephen_A_Marsh »

Thank you, it is all working and clear now! :]