I have a Work Path I'd like to convert into a shape layer. It can be done through the UI by pressing the "Shape" button at the Pen tool menu as shown in this answer.

How do I do that through scripting?

I used the Script Listener to capture it, but the output doesn't contain the converting function:

// =======================================================
// Select Work Path
var idslct = charIDToTypeID( "slct" );
    var desc6704 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref4022 = new ActionReference();
        var idPath = charIDToTypeID( "Path" );
        var idWrPt = charIDToTypeID( "WrPt" );
        ref4022.putProperty( idPath, idWrPt );
    desc6704.putReference( idnull, ref4022 );
executeAction( idslct, desc6704, DialogModes.NO );

// =======================================================
// Select Pen Tool
var idslct = charIDToTypeID( "slct" );
    var desc6705 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref4023 = new ActionReference();
        var idpenTool = stringIDToTypeID( "penTool" );
        ref4023.putClass( idpenTool );
    desc6705.putReference( idnull, ref4023 );
    var iddontRecord = stringIDToTypeID( "dontRecord" );
    desc6705.putBoolean( iddontRecord, true );
    var idforceNotify = stringIDToTypeID( "forceNotify" );
    desc6705.putBoolean( idforceNotify, true );
executeAction( idslct, desc6705, DialogModes.NO );

// The End.

I tried to cheat and record it as an Action to trigger through the script, but unsurprisingly transforming Paths into Shapes doesn't get recorded as Action either.

Is there a way to capture and reproduce this action programmatically at all without creating junk custom shapes?


What you need is a Create Solid Fill layer command: when you have path selected it'll create a shape layer based on the active path. Here's the code:

function createShapeLayer(color) {
    if (color == undefined) var color = app.foregroundColor;

    var desc32 = new ActionDescriptor();
        var ref2 = new ActionReference();
        ref2.putClass( sTID('contentLayer') );
    desc32.putReference( cTID('null'), ref2 );
        var desc33 = new ActionDescriptor();
            var desc34 = new ActionDescriptor();
                var desc35 = new ActionDescriptor();
                desc35.putDouble( cTID('Rd  '), color.rgb.red );
                desc35.putDouble( cTID('Grn '), color.rgb.green );
                desc35.putDouble( cTID('Bl  '), color.rgb.blue );
            desc34.putObject( cTID('Clr '), cTID('RGBC'), desc35 );
        desc33.putObject( cTID('Type'), sTID('solidColorLayer'), desc34 );
    desc32.putObject( cTID('Usng'), sTID('contentLayer'), desc33 );
    executeAction( cTID('Mk  '), desc32, DialogModes.NO );

    function cTID(s) { return app.charIDToTypeID(s); };
    function sTID(s) { return app.stringIDToTypeID(s); };
}; // end of createShapeLayer()

This function will use foreground color for the shape by default or a SolidColor passed as an argument.

| improve this answer | |
  • I ended doing something similar, but referencing the work path bounds in the shape layer desc because I had no idea it'd use the active path bounds by default. Thank you, that's way more elegant than my code! – Rhaenys May 18 '19 at 20:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.