redraw() cases.
I want to start a post where we can keep adding things to and use as reference regarding the usage of the app.redraw() function.
Sometimes we have to resort to using this function to make something work in Illustrator that otherwise doesn't. This occurs in varying degrees of frequency, with some scripters not having to touch it at all as their projects never have an issue that needs it. However for those of us that do rely on this function, it has its drawbacks and I personally try to use it as sparingly as possible.
One issue is that doing a redraw adds some time to the document processing. The script may run a little faster on large files when not using redraw.
Another perhaps less critical issue is that it will create a new Undo point where there wasn't one previously. So a script that could be undone using one Undo command will now need multiple undos.
var doc = app.activeDocument;
var knownColors = ["CMYK Red", "CMYK Yellow", "CMYK Blue"];
var thisPath, thisColor;
for (var i = 0; i < knownColors.length; i++) {
thisPath = doc.pathItems[i];
thisColor = knownColors[i];
thisPath.fillColor = doc.swatches.getByName(thisColor).color;
app.redraw(); // makes 3 undos
}
This thread can help note all the various cases where an undo is needed to solve an issue.
Here is one:
Removing new swatches
Description: I am making new gradients using document.gradients.add(), but I don't want them to appear in the swatch panel. So, I run an action that has a recorded "Delete Swatch Selection" command which removes selected swatches from the swatch panel. As the new gradient swatch is added to the swatch panel, it is also automatically selected at which point the action will delete them.
Issue: when doing multiple such gradients in a loop, the swatch panel does not yet see a new item in it and the action does not delete anything: the new gradient swatches appear only after the script is done.
How redraw() solves the issue: Adding .redraw() after the gradient is added inside the loop using the gradients.add() call, it will ensure that the new swatch item is in the panel and is selected so it can be deleted.
Optimization: Perhaps there could be a way to do the loop first and collect all the new gradient's names into an array. After the loop, redraw() could be used once and this array could be looped through to create temporary items filled with the gradient color and hopefully this will select the swatch and delete it in the panel. This will not work if the swatch does not get selected in the panel and redraw is needed still, that would defeat the purpose.
I will add that the biggest issue with redraw() is the unpredictable nature of how it may affect the document state in relation to our scripting process and its expectation of the document state. If items behave a certain way before a redraw() and a different way afterwards, it may not be just the items we are interested in that can act differently.
