Creating a Rectangle and applying a gradient feather with a script

Hi,

On InDesign, I create two documents, A and B.

On document A, I’m using the “app.activeDocument.pages[0].rectangles.add()” to create a new rectangle on the first page.

In document B, I create the same rectangle using the tool (manually).

I export both documents as an IDML and extract the XML files for the same spread, comparing their contents. In the IDML of document A ItemTransform of the rectangle is “1 0 0 1 5 -391” while in document B ItemTransform is “1 0 0 1 0 0”. Also in document A most of the properties like GradientFillStart, GradientStrokeStart, PathPointType, etc values for X and Y are sifted by 5 and -391.

The problem is that when I’m trying to create a GradientFeather using a script providing the proper values for gradientStart, angle, length, etc the result is never correct on Document A but always ok on document B.

I search by printing out all the properties for the two documents, spreads, pages, and rectangles and everything returns the same values for all the properties…

I saw in the IDML’s specs that those two numbers in the ItemTranform are “the horizontal and vertical distances to move the object, relative to the center of the pasteboard”. How can I change that with script thought…

If I change those two values and build back the IDML gradient feather is the same in documents A and B.

Regards,

Jim

Hi Jim,

Could you give us your document A, your document B and the code you’re using to create the gradient feather (that works correctly on document B but not A). Without the sample files and code, I can’t work out what might be going wrong. Off the top of my head I can’t immediately think why a rectangle created programmatically should behave differently to a rectangle created manually . . . assuming, of course, that after programmatically creating your rectangle you are putting it on the same coordinates as the manually created rectangle.

Philip

Hi,
I’m sending you here the files you need to reproduce this.

Thanks for the quick responce.

Regards,
Jim

Hi Jim,

Add the following line after line 29 in your script (after your line ’var gradientStart = gradientFeatherSettings.gradientStart;’):

gradientStart = rectangle.resolve([gradientStart, CoordinateSpaces.INNER_COORDINATES], CoordinateSpaces.PAGE_COORDINATES)[0];

That, as far as I can tell, fixes it.

I think what is going on is that when you are reading the x, y gradient feather start property from your first rectangle, the rectangle that you have manually drawn on the page, it is giving you the numbers in relation to the rectangle itself, its inner coordinates. You can tell that that is the case by moving the rectangle about on the page and repeatedly querying it – the numbers are always the same. When, however, you apply the x, y start value from your first rectangle to your second rectangle, the rectangle you have programmatically created, then, as (I have to admit) the documentation says, it wants the pair of numbers in relation to the page, the page coordinates. So the line I have given you takes in the values in the inner coordinate space and gives back the values in the page coordinate space. Your variable, gradientStart, now holds those ‘page coordinate space’ values, and it is those values which are applied to your second, programmatically created, rectangle (your line 55).

I believe the definitive guide to coordinate spaces is the PDF eBook written by the brilliant Marc Autret, downloadable from this page on his website:

[Indiscripts :: Coordinate Spaces & Transformations in InDesign [UPDATE]]

By way of full disclosure, I should add that most of what is in that eBook is way beyond my understanding! I’m just glad that someone is both clever enough to understand the subject and patient/persistent enough to write it all down.

Philip

Hi Philip,

Thank you again for that quick response and the time you spent to write me.

The solution you propose indeed solves the visual problem, but it does not solve the problem with the manual and programmatically creation of a rectangle (or any other pageItem).

If you select the rectangle in Document A and ask for the app.selection[0].transformValuesOf(CoordinateSpaces.PASTEBOARD_COORDINATES)[0].matrixValues you’ll get 1,0,0,1,0,0.
If you do the same for the rectangle that was created with a script in Document B you’ll get 1,0,0,1,5,-391
This is what I want to change when I’m creating the object with a script.
I see there is a ‘transform’ method and now I’m playing with this in case I can change that value to 1,0,0,1,0,0 before I set the other properties.

If I find out how to do that, the IDMLs of those two documents will have the same properties for these objects and my system will work properly.

Now the IDMLs look like this: rectangles

In case you think of something please reply.

Thanks again,

Jim

Hi Jim,

I thought your problem was with the positioning of the gradient feather within the rectangle, and I really don’t understand why you’re so obsessed with those ***** numbers! :wink:

But anyway, FWIW here are some lines of code to reset those numbers to the numbers you want:

var rectangle = app.activeDocument.pages[0].rectangles.add();
var geometricBounds = rectangle.geometricBounds;
var currentMatrix = rectangle.transformValuesOf(CoordinateSpaces.PASTEBOARD_COORDINATES)[0];
$.writeln(currentMatrix.matrixValues.toString()); // 1,0,0,1,5,-415.944881889
var invertedMatrix = currentMatrix.invertMatrix();
rectangle.transform(CoordinateSpaces.PASTEBOARD_COORDINATES, AnchorPoint.CENTER_ANCHOR, invertedMatrix);
rectangle.geometricBounds = geometricBounds;
currentMatrix = rectangle.transformValuesOf(CoordinateSpaces.PASTEBOARD_COORDINATES)[0];
$.writeln(currentMatrix.matrixValues.toString()); // 1,0,0,1,0,0

Line 1 – we’re creating our rectangle

Line 2 – we’re assigning the geometric bounds of the rectangle to a variable (for use later). This isn’t critical for what we’re doing.

Line 3 – we’re getting the transformation matrix (in the pasteboard space) from the rectangle. This is the code you already have.

Line 4 – we’re simply logging the matrix values of the transformation matrix. These are the values that you want to change. On my computer the numbers I get are: 1,0,0,1,5,-415.944881889.

The last two numbers are the values of the horizontalTranslation and verticalTranslation properties of the transformation matrix.

My guess is that when InDesign creates a page item, such as our rectangle, it initially exists somewhere in the pasteboard space and InDesign simply moves it so that it sits at the top left corner of the page – where you see a newly created page item. That moving is a transformation, the values of which are appended to the object’s transformation matrix.

Lines 5 and 6 are the critical lines of code.

Line 5 – we create a new inverted transformation matrix from the current transformation matrix. The function invertMatrix() inverts (reverses) the transformations in the source matrix. In other words, if the source matrix says, as it were, “move 20 units horizontally to the right”, the inverted matrix will say “move 20 units horizontally to the left”.

Line 6 – we apply our inverted transformation matrix to the rectangle using the transform() function.

Line 7 – we re-apply the original geometric bounds to the rectangle so it again sits at the top left corner of the page. Interestingly, if you comment out this line and run the code, then choose “Entire Pasteboard” from the View menu, you see the rectangle right in the centre of the pasteboard, which tells me that that is where InDesign initially creates it before moving it to the top left corner of the page.

Lines 8 and 9 are a dupe of lines 3 and 4, just so we can check what values the transformation matrix now has. I get: 1,0,0,1,0,0.

Philip

1 Like

Thank you, Philip!

Now the IDMLs are the same.

Regards,

Jim