Skip to main content
Inspiring
August 13, 2013
Answered

Error 21 (Changing color on text)

  • August 13, 2013
  • 1 reply
  • 5168 views

http://forums.adobe.com/message/5580527#5580527

Carlos wrote a script in response to the above thread. It changes CMYK black, and grayscale black to a swatch called "spot black". It's awesome, but it's only aimed at paths. I've made some adjustments to prevent it from effecting white and unpainted objects. I'm going to need it to work on text and gradients. Right now I am working on text.

I've tried to use the same logic that works on the paths on text, but I'm missing something. Help help.

This is the latest working version, it does not effect text or gradients.

// script.name = cmykBlackNgrayscaleToSpotBlack.jsx;

// script.description = changes art color from standard CMYK Black and Grayscale tones to an EXISTING Spot swatch named "spot black";

// script.requirements = an opened document;

// script.parent = CarlosCanto // 08/08/13;

// script.elegant = false;

// reference http://forums.adobe.com/thread/1267562?tstart=0

// Note: color values get rounded to the nearest integer, to avoid values like black = 99.99999999999999

//            Hidden and/or Locked Objects will be ignored, as well as objects in Hidden and/or Locked Layers

#target Illustrator

var idoc = app.activeDocument;

var pi = idoc.pathItems;

var sw = idoc.swatches["spot black"];

var fcounter = 0;

var scounter = 0;

for (j=0; j<pi.length; j++) {

    var ipath = pi;

    if (ipath.layer.visible==true && ipath.layer.locked==false && ipath.hidden==false && ipath.locked==false) {

        var fillColor = ipath.fillColor;

        if (fillColor.typename == "CMYKColor") {

            if (isColorBlack (fillColor)) {

                var fillk = Math.round(fillColor.black);

                cmykBlackToSpot (ipath, true, false, fillk);

                fcounter++;

            }

        }

        else if (fillColor.typename == "GrayColor") {

            if (grayNotWhiteOrClear (fillColor)) {

                var fillk = Math.round(fillColor.gray);

                cmykBlackToSpot (ipath, true, false, fillk);

                fcounter++;

            }

        }

        var strokeColor = ipath.strokeColor;

        if (strokeColor.typename == "CMYKColor") {

            if (isColorBlack (strokeColor)) {

                var strokek = Math.round(strokeColor.black);

                cmykBlackToSpot (ipath, false, true, strokek);

                scounter++;

            }

        }

        else if (strokeColor.typename == "GrayColor") {

            if (grayNotWhiteOrClear (strokeColor)) {

                var strokek = Math.round(strokeColor.gray);

                cmykBlackToSpot (ipath, false, true, strokek);

                scounter++;

            }

        }

    }

}

alert(fcounter + ' Fill(s) & ' + scounter + ' stroke(s) processed');

function cmykBlackToSpot (path, fill, stroke, k) {

    if (fill) {

        path.fillColor = sw.color;

        path.fillColor.tint = k;

    }

    if (stroke) {

        path.strokeColor = sw.color;

        path.strokeColor.tint = k;

    }

}

function isColorBlack (cmykColor) {

    var c = Math.round(cmykColor.cyan);

    var m = Math.round(cmykColor.magenta);

    var y = Math.round(cmykColor.yellow);

    var k = Math.round(cmykColor.black);

    if (c==0 && m==0 && y==0 && k != 0)

        return true

    else

        return false

}

function grayNotWhiteOrClear (GrayColor) {

    var pct = Math.round(GrayColor.gray);

    if (pct != 0)

        return true

    else

        return false

}

This is the version I'm working on now where I'm trying to include the text.

// script.name = cmykBlackNgrayscaleToSpotBlack.jsx;

// script.description = changes art color from standard CMYK Black and Grayscale tones to an EXISTING Spot swatch named "spot black";

// script.requirements = an opened document;

// script.parent = CarlosCanto // 08/08/13;

// script.elegant = false;

// reference http://forums.adobe.com/thread/1267562?tstart=0

// Note: color values get rounded to the nearest integer, to avoid values like black = 99.99999999999999

//            Hidden and/or Locked Objects will be ignored, as well as objects in Hidden and/or Locked Layers

#target Illustrator

var idoc = app.activeDocument;

var pi = idoc.pathItems;

var sw = idoc.swatches["spot black"];

var ch = idoc.textFrames[0].characters[0];

var fcounter = 0;

var scounter = 0;

for (j=0; j<pi.length; j++) {

    var ipath = pi;

    if (ipath.layer.visible==true && ipath.layer.locked==false && ipath.hidden==false && ipath.locked==false) {

        var fillColor = ipath.fillColor;

        if (fillColor.typename == "CMYKColor") {

            if (isColorBlack (fillColor)) {

                var fillk = Math.round(fillColor.black);

                cmykBlackToSpot (ipath, true, false, fillk);

                fcounter++;

            }

        }

        else if (fillColor.typename == "GrayColor") {

            if (grayNotWhiteOrClear (fillColor)) {

                var fillk = Math.round(fillColor.gray);

                cmykBlackToSpot (ipath, true, false, fillk);

                fcounter++;

            }

        }

        var strokeColor = ipath.strokeColor;

        if (strokeColor.typename == "CMYKColor") {

            if (isColorBlack (strokeColor)) {

                var strokek = Math.round(strokeColor.black);

                cmykBlackToSpot (ipath, false, true, strokek);

                scounter++;

            }

        }

        else if (strokeColor.typename == "GrayColor") {

            if (grayNotWhiteOrClear (strokeColor)) {

                var strokek = Math.round(strokeColor.gray);

                cmykBlackToSpot (ipath, false, true, strokek);

                scounter++;

            }

        }

    }

}

for (t=0; t<ch.length; t++) {

    var txt = ch;

    if (txt.layer.visible==true && txt.layer.locked==false && txt.hidden==false && txt.locked==false) {

        var fillColor = txt.fillColor;

        if (fillColor.typename == "CMYKColor") {

            if (isColorBlack (fillColor)) {

                var fillk = Math.round(fillColor.black);

                cmykBlackToSpot (txt, true, false, fillk);

                fcounter++;

            }

        }

        else if (fillColor.typename == "GrayColor") {

            if (grayNotWhiteOrClear (fillColor)) {

                var fillk = Math.round(fillColor.gray);

                cmykBlackToSpot (txt, true, false, fillk);

                fcounter++;

            }

        }

        var strokeColor = txt.strokeColor;

        if (strokeColor.typename == "CMYKColor") {

            if (isColorBlack (strokeColor)) {

                var strokek = Math.round(strokeColor.black);

                cmykBlackToSpot (txt, false, true, strokek);

                scounter++;

            }

        }

        else if (strokeColor.typename == "GrayColor") {

            if (grayNotWhiteOrClear (strokeColor)) {

                var strokek = Math.round(strokeColor.gray);

                cmykBlackToSpot (txt, false, true, strokek);

                scounter++;

            }

        }

    }

}

alert(fcounter + ' Fill(s) & ' + scounter + ' stroke(s) processed');

function cmykBlackToSpot (path, fill, stroke, k) {

    if (fill) {

        path.fillColor = sw.color;

        path.fillColor.tint = k;

    }

    if (stroke) {

        path.strokeColor = sw.color;

        path.strokeColor.tint = k;

    }

}

function isColorBlack (cmykColor) {

    var c = Math.round(cmykColor.cyan);

    var m = Math.round(cmykColor.magenta);

    var y = Math.round(cmykColor.yellow);

    var k = Math.round(cmykColor.black);

    if (c==0 && m==0 && y==0 && k != 0)

        return true

    else

        return false

}

function grayNotWhiteOrClear (GrayColor) {

    var pct = Math.round(GrayColor.gray);

    if (pct != 0)

        return true

    else

        return false

}

Here is a test file

https://docs.google.com/file/d/0BzEoJSYDhH_WdENjc092SF9GN0U/edit?usp=sharing

Thanks for playing.

This topic has been closed for replies.
Correct answer elDudereno

it just dawned on me, even though the "layer" property is not listed in the text frame properties, a text frame is still a subset of the "super class" pageItem...so

for page items we have

if (ipath.layer.visible==true && ipath.layer.locked==false && ipath.hidden==false && ipath.locked==false) {

for text, do the same

if (iTxtFrm.layer.visible==true && iTxtFrm.layer.locked==false && iTxtFrm.hidden==false && iTxtFrm.locked==false) {

and forget about meeting the parents


Carlos, you are right about that. I had a logic knot that was preventing it from working on text in groups AND directly on layers at the same time. I ended up using a version that didn't use your fix, even though it was viable.

Here is my final script. Works like a charm. Thanks for all the help.

// script.name = BlackToSpotBlack.jsx;

// script.description = changes art color from standard CMYK Black and Grayscale tones to a Spot swatch named "spot black";

// script.requirements = an opened document;

// script.parent = CarlosCanto // 08/08/13;

// script.elegant = false;

// reference http://forums.adobe.com/thread/1267562?tstart=0 && http://forums.adobe.com/message/5610447#5610447

// Note: color values get rounded to the nearest integer, to avoid values like black = 99.99999999999999

//              Hidden and/or Locked Objects will be ignored, as well as objects in Hidden and/or Locked Layers

#target Illustrator

var idoc = app.activeDocument;

var pi = idoc.pathItems;

var tf = idoc.textFrames;

createSpotBlack();

var sw = idoc.swatches["spot black"];

var fcounter = 0;

var scounter = 0;

var gcounter = 0;

//apply spot to paths and gradient stops

for (j=0; j<pi.length; j++) {

    var ipath = pi;

    if (ipath.layer.visible==true && ipath.layer.locked==false && ipath.hidden==false && ipath.locked==false) {

        var fillColor = ipath.fillColor;

        if (fillColor.typename == "CMYKColor") {

            if (isColorBlack (fillColor)) {

                var fillk = Math.round(fillColor.black);

                cmykBlackToSpot (ipath, true, false, fillk);

                fcounter++;

            }

        }

        else if (fillColor.typename == "GrayColor") {

            if (grayNotWhiteOrClear (fillColor)) {

                var fillk = Math.round(fillColor.gray);

                cmykBlackToSpot (ipath, true, false, fillk);

                fcounter++;

            }

        }

        else if (fillColor.typename == "GradientColor") {

            var stops = ipath.fillColor.gradient.gradientStops;

            for (s=0; s<stops.length; s++) {

                var iStop = stops;

                var stopColor = iStop.color;

                if (stopColor.typename == "CMYKColor") {

                    if (isColorBlack (stopColor)) {

                        var stopk = Math.round(stopColor.black);

                        iStop.color = sw.color;

                        iStop.color.tint = stopk;

                        gcounter++;

                    }

                }

                if (stopColor.typename == "GrayColor") {

                    if (grayNotWhiteOrClear (stopColor)) {

                        var stopk = Math.round(stopColor.gray);

                        iStop.color = sw.color;

                        iStop.color.tint = stopk;

                        gcounter++;

                    }

                }

            }

        }

        var strokeColor = ipath.strokeColor;

        if (strokeColor.typename == "CMYKColor") {

            if (isColorBlack (strokeColor)) {

                var strokek = Math.round(strokeColor.black);

                cmykBlackToSpot (ipath, false, true, strokek);

                scounter++;

            }

        }

        else if (strokeColor.typename == "GrayColor") {

            if (grayNotWhiteOrClear (strokeColor)) {

                var strokek = Math.round(strokeColor.gray);

                cmykBlackToSpot (ipath, false, true, strokek);

                scounter++;

            }

        }

        else if (strokeColor.typename == "GradientColor") {

            var stops = ipath.strokeColor.gradient.gradientStops;

            for (s=0; s<stops.length; s++) {

                var iStop = stops;

                var stopColor = iStop.color;

                if (stopColor.typename == "CMYKColor") {

                    if (isColorBlack (stopColor)) {

                        var stopk = Math.round(stopColor.black);

                        iStop.color = sw.color;

                        iStop.color.tint = stopk;

                        gcounter++;

                    }

                }

                if (stopColor.typename == "GrayColor") {

                    if (grayNotWhiteOrClear (stopColor)) {

                        var stopk = Math.round(stopColor.gray);

                        iStop.color = sw.color;

                        iStop.color.tint = stopk;

                        gcounter++;

                    }

                }

            }

        }

    }

}

// choose text and change

for (t=0; t<tf.length; t++) {

    var iTxtFrm = tf;

    if (iTxtFrm.locked==false && iTxtFrm.hidden==false) {

        if (meetTheParents(iTxtFrm) == "isLayerFree"){

            if (isLayerFree(iTxtFrm.parent)){

                changeText(iTxtFrm)

            } else {

                if (isGroupFree(iTxtFrm)){

                changeText(iTxtFrm)

                }

            }

        }

    }

}

alert(fcounter + ' Fill(s), ' + scounter + ' stroke(s) & ' + gcounter + ' Gradient Stop(s) processed.');

function meetTheParents(textFrame){

    if (textFrame.parent.typename = "Layer"){

        return "isLayerFree";

    } else if (textFrame.parent.typename = "GroupItem"){

        return "isGroupFree";

    }

}

function isGroupFree(groupItem){

    if (groupItem.parent.hidden==false && groupItem.parent.editable==true){

        if (groupItem.parent.typename == "Layer"){

            var greatgpa = groupItem.parent;

            isLayerFree(greatgpa);

        }else if (groupItem.parent.typename = "GroupItem"){

            var gpa = groupItem.parent;

            if (isGroupFree(gpa));

            return true

            } else {

            return false

        }

    }

}

function isLayerFree(layer){

    if (layer.locked == false && layer.visible == true){

        var gpa = layer.parent;

        isLayerFree(gpa);

        return true

        } else {

        return false

    }

}

// actually changes text

function changeText(textFrame){

    var chars = textFrame.characters;

    for (c=0; c<chars.length; c++) {

        var ltr = chars;

        if (ltr.characterAttributes.fillColor.typename == "CMYKColor"){

            if (isColorBlack (ltr.characterAttributes.fillColor)) {

                var fillk = Math.round(ltr.characterAttributes.fillColor.black);

                cmykBlackToSpot (ltr, true, false, fillk);

                fcounter++;

            }

        }

        if (ltr.characterAttributes.fillColor.typename == "GrayColor"){

            if (grayNotWhiteOrClear (ltr.characterAttributes.fillColor)) {

                var fillk = Math.round(ltr.characterAttributes.fillColor.gray);

                cmykBlackToSpot (ltr, true, false, fillk);

                fcounter++;

            }

        }

        if (ltr.characterAttributes.strokeColor.typename == "CMYKColor"){

            if (isColorBlack (ltr.characterAttributes.strokeColor)) {

                var strokek = Math.round(ltr.characterAttributes.strokeColor.black);

                cmykBlackToSpot (ltr, false, true, strokek);

                scounter++;

            }

        }

        if (ltr.characterAttributes.strokeColor.typename == "GrayColor"){

            if (grayNotWhiteOrClear (ltr.characterAttributes.strokeColor)) {

                var strokek = Math.round(ltr.characterAttributes.strokeColor.gray);

                cmykBlackToSpot (ltr, false, true, strokek);

                scounter++;

            }

        }

    }

};

function cmykBlackToSpot (path, fill, stroke, k) {

    if (fill) {

        path.fillColor = sw.color;

        path.fillColor.tint = k;

    }

    if (stroke) {

        path.strokeColor = sw.color;

        path.strokeColor.tint = k;

    }

}

function isColorBlack (cmykColor) {

    var c = Math.round(cmykColor.cyan);

    var m = Math.round(cmykColor.magenta);

    var y = Math.round(cmykColor.yellow);

    var k = Math.round(cmykColor.black);

    if (c==0 && m==0 && y==0 && k != 0)

        return true

    else

        return false

}

function grayNotWhiteOrClear (GrayColor) {

    var pct = Math.round(GrayColor.gray);

    if (pct != 0)

        return true

    else

        return false

}

function createSpotBlack(){

    if (!doesColorExist("spot black")){

        // Create CMYKColor

        var cmykColor = new CMYKColor();

        cmykColor.cyan = 9;

        cmykColor.magenta = 9;

        cmykColor.yellow = 9;

        cmykColor.black = 96;

        // Create Spot

        var spot = idoc.spots.add();

        spot.color = cmykColor;

        spot.colorType = ColorModel.SPOT;

        spot.name = "spot black";

    }

}

function doesColorExist(){

    var clrs = idoc.swatches;

    for (var i=0;i<clrs.length;i++){

        if (clrs.name=="spot black"){

            return true;

        }

    }

    return false;

}

1 reply

Inspiring
August 13, 2013

I doubt you are going to be able to utilize the same syntax for your differing items… Anyhows…

var pi = idoc.pathItems; // Carlos sets variable to a collection…

var ch = idoc.textFrames[0].characters[0]; // Here your variable is to a single character… I doubt this can be tested for locked or hidden…

var ch = idoc.textFrames; // Will give you something to loop thru but you will need to dig deeper still as every character can be different…

Personally I would go for stories when looking thru text…

Inspiring
August 13, 2013

So...

var ch = idoc.stories[0].textRanges[0].CharacterAttributes;

I'm looking in "Adobe IllustratorCS5 Scripting Reference: JavaScript" on page 226 (textRange) and I'm not seeing locked, hidden, or layers as textRange properties. So I'm guessing I can't test for them for stories either.

My scripting powers mostly consist of looking at an example, deciphering it, and applying what I need to make it work in my instance. Where could I go to find an example of a script that changes the fill and stroke of cmyk and grayscale text that isn't locked or hidden?

I'm pretty ignorant at all of this, so please bear with me.

P.S. If I didn't care if locked or hidden text was changed could I use idoc.textFrames[0].characters[0];  ?

CarlosCanto
Community Expert
Community Expert
August 16, 2013

This is another way to do it wrong. Again, I am getting no errors out of this code, just text that is unchanged.

// script.name = cmykBlackNgrayscaleToSpotBlack.jsx;

// script.description = changes art color from standard CMYK Black and Grayscale tones to a Spot swatch named "spot black";

// script.requirements = an opened document;

// script.parent = CarlosCanto // 08/08/13;

// script.elegant = false;

// reference http://forums.adobe.com/thread/1267562?tstart=0

// Note: color values get rounded to the nearest integer, to avoid values like black = 99.99999999999999

//              Hidden and/or Locked Objects will be ignored, as well as objects in Hidden and/or Locked Layers

#target Illustrator

var idoc = app.activeDocument;

var pi = idoc.pathItems;

var tf = idoc.textFrames;

createSpotBlack();

var sw = idoc.swatches["spot black"];

var fcounter = 0;

var scounter = 0;

for (t=0; t<tf.length; t++)

    var itxt = tf;

    if (itxt.visible==true && itxt.locked==false && itxt.hidden==false) {

    var chars = itxt.contents.characters;

    for (c=0; c<chars.length; c++) {

        var iChar = chars;

        if (iChar.characterAttributes.fillColor == "CMYKColor"){

            if (isColorBlack (fillColor)) {

                var fillk = Math.round(fillColor.black);

                cmykBlackToSpot (iChar, true, false, fillk);

                fcounter++;

            }

        }

    }

}

//apply spot to paths

for (j=0; j<pi.length; j++) {

    var ipath = pi;

    if (ipath.layer.visible==true && ipath.layer.locked==false && ipath.hidden==false && ipath.locked==false) {

        var fillColor = ipath.fillColor;

        if (fillColor.typename == "CMYKColor") {

            if (isColorBlack (fillColor)) {

                var fillk = Math.round(fillColor.black);

                cmykBlackToSpot (ipath, true, false, fillk);

                fcounter++;

            }

        }

        else if (fillColor.typename == "GrayColor") {

            if (grayNotWhiteOrClear (fillColor)) {

                var fillk = Math.round(fillColor.gray);

                cmykBlackToSpot (ipath, true, false, fillk);

                fcounter++;

            }

        }

   

        var strokeColor = ipath.strokeColor;

        if (strokeColor.typename == "CMYKColor") {

            if (isColorBlack (strokeColor)) {

                var strokek = Math.round(strokeColor.black);

                cmykBlackToSpot (ipath, false, true, strokek);

                scounter++;

            }

        }

        else if (strokeColor.typename == "GrayColor") {

            if (grayNotWhiteOrClear (strokeColor)) {

                var strokek = Math.round(strokeColor.gray);

                cmykBlackToSpot (ipath, false, true, strokek);

                scounter++;

            }

        }

    }

}

alert(fcounter + ' Fill(s) & ' + scounter + ' stroke(s) processed');

function cmykBlackToSpot (path, fill, stroke, k) {

    if (fill) {

        path.fillColor = sw.color;

        path.fillColor.tint = k;

    }

    if (stroke) {

        path.strokeColor = sw.color;

        path.strokeColor.tint = k;

    }

}

function isColorBlack (cmykColor) {

    var c = Math.round(cmykColor.cyan);

    var m = Math.round(cmykColor.magenta);

    var y = Math.round(cmykColor.yellow);

    var k = Math.round(cmykColor.black);

   

    if (c==0 && m==0 && y==0 && k != 0)

        return true

    else

        return false

}

function grayNotWhiteOrClear (GrayColor) {

    var pct = Math.round(GrayColor.gray);

    if (pct != 0)

        return true

    else

        return false

}

function createSpotBlack(){

    if (!doesColorExist("spot black")){

        // Create CMYKColor

        var cmykColor = new CMYKColor();

        cmykColor.cyan = 9;

        cmykColor.magenta = 9;

        cmykColor.yellow = 9;

        cmykColor.black = 96;

        // Create Spot

        var spot = idoc.spots.add();

        spot.color = cmykColor;

        spot.colorType = ColorModel.SPOT;

        spot.name = "spot black";

    }

}

function doesColorExist(){

    var clrs = idoc.swatches;

    for (i=0;i<clrs.length;i++){

        if (clrs.name=="spot black"){

            return true;

        }

    }

    return false;

}

redraw();


Hi, I don't have a chance to try your code at the moment but

change this

var chars = itxt.contents.characters;

to this

var chars = itxt.characters;