4 Replies Latest reply on Nov 20, 2010 11:53 AM by Kasyan Servetsky

How to move the ends of skewed lines to the bleed bounds

Hi all,

I am developing a script that trims page items to the bleed. To achieve this I collect all page items (except text frames) located partially on the pasteboard, create a temporary mask and 'crop' them with Pathfinder's Subtract feature. However this approach doesn't work with graphic lines so I am attempting to move ends of lines to the bounds of bleed box. (I'm assuming that these are simple straight lines consisting of two end points.)

I've figured out how to deal with orthogonal lines -- it's quite easy:

```if (theItem.constructor.name == "GraphicLine" && theItem.paths.length === 1) {
path = theItem.paths[0];
if (path.pathPoints.length === 2) {
ep = path.entirePath;
w = ep[1][0]-ep[0][0];
h = ep[1][1]-ep[0 ][1];

if (w > h) {
newEp = [ [ spreadWithBleedBounds[1], ep[0][1] ], [ spreadWithBleedBounds[3], ep[1][1] ] ];
path.entirePath = newEp;
}
else if (h > w) {
newEp = [ [ ep[0][0], spreadWithBleedBounds[0] ], [ ep[1][0], spreadWithBleedBounds[2] ] ];
path.entirePath = newEp;
}
}
}
```

This moves A1 to A2, B1 to B2, C1 to C2, D1 to D2.

But how to deal with skewed lines? How to calculate coordinates for points E2 and F2? Is there some magic formula? Or can anybody point me to the right direction: e.g. some book to read?

I guess this has something to do with geometry/trigonometry, but I haven't studied this stuff at school. (I graduated an art school -- studied to draw nude models instead.)

If someone is going to answer to my question, please do it on elementary level since I am a total noob in this.

Below is the whole script:

```if (Number(String(app.version).split(".")[0]) == 7) ErrorExit("This script can't work with InDesign CS5 so far.", true);

var doc = app.activeDocument;
var ungroupErrors = 0;

var originalHorUnits =  doc.viewPreferences.horizontalMeasurementUnits;
var originalVerUnits =  doc.viewPreferences.verticalMeasurementUnits;
doc.viewPreferences.horizontalMeasurementUnits = doc.viewPreferences.verticalMeasurementUnits = MeasurementUnits.INCHES;
doc.zeroPoint = [0, 0];

if (doc.layers.itemByName("Temporary Layer") == null ) {
var tempLayer = doc.layers.add({name:"Temporary Layer"});
}
else {
var tempLayer = doc.layers.itemByName("Temporary Layer");
}

UngroupAllGroups(doc.groups);

DeleteObjectsOnPasteboard();

tempLayer.remove();

doc.viewPreferences.horizontalMeasurementUnits = originalHorUnits;
doc.viewPreferences.verticalMeasurementUnits = originalVerUnits;

var msg = (ungroupErrors > 0) ? " Failed to ungroup " + ungroupErrors + " groups since they are too large." : "";
alert("Done." + msg, "Trim Pages Script");

//================================== FUNCTONS ===========================================
var spread, path, ep, w, h;
for (var s = 0; s < spreads.length; s++) {

var theItem, theMask, newItem;
for (var i = gPartiallyOutOfSpreadItems.length-1; i >= 0; i--) {
if (theItem.constructor.name == "GraphicLine" && theItem.paths.length === 1) {
path = theItem.paths[0];
if (path.pathPoints.length === 2) {
ep = path.entirePath;
w = ep[1][0]-ep[0][0];
h = ep[1][1]-ep[0 ][1];

if (w > h) {
newEp = [ [ spreadWithBleedBounds[1], ep[0][1] ], [ spreadWithBleedBounds[3], ep[1][1] ] ];
path.entirePath = newEp;
}
else if (h > w) {
newEp = [ [ ep[0][0], spreadWithBleedBounds[0] ], [ ep[1][0], spreadWithBleedBounds[2] ] ];
path.entirePath = newEp;
}
}
}
else {
try {
}
catch (err) {
\$.writeln("2 - " + err);
}
}
}
}
}
//--------------------------------------------------------------------------------------------------------------
var result = false;
if (pageItem.constructor.name == "TextFrame" ||
pageItem.constructor.name == "Group" ||
pageItem.parent.constructor.name == "Group")
{
return result;
}

var visBounds = pageItem.visibleBounds;
if (visBounds[0] < spreadBounds[0] && visBounds[2] > spreadBounds[0] ||
visBounds[1] < spreadBounds[1] && visBounds[3] > spreadBounds[1] ||
visBounds[2] > spreadBounds[2] && visBounds[0] < spreadBounds[2] ||
visBounds[3] > spreadBounds[3] && visBounds[1] < spreadBounds[3]  ) {
result = true;
}
return result;
}
//--------------------------------------------------------------------------------------------------------------
function GetSpreadBound(spread, bleed) { // including bleed -boolean
if (bleed == undefined) bleed = false;

with (doc.documentPreferences) {
var topBleed = documentBleedTopOffset
var leftBleed = documentBleedInsideOrLeftOffset;
var bottomBleed = documentBleedBottomOffset;
var rightBleed = documentBleedOutsideOrRightOffset;
}

var bFirst = spread.pages.item(0).bounds; // bounds of the first page
var bLast = spread.pages.item(-1).bounds; // bounds of the last page
return [     ((bleed) ? bFirst[0]-topBleed : bFirst[0]),
((bleed) ? bFirst[1]-leftBleed : bFirst[1]),
((bleed) ? bLast[2]+bottomBleed : bFirst[2]),
((bleed) ? bLast[3]+rightBleed : bLast[3])
];
}
//--------------------------------------------------------------------------------------------------------------
var unitValue = new UnitValue (app.pasteboardPreferences.minimumSpaceAboveAndBelow, "mm");
var unitValueAsInch = unitValue.as("in");
var outerRectangleBounds = [spreadWithBleedBounds[0]-unitValueAsInch,
];

var outerRectangle = spread.rectangles.add(tempLayer, undefined, undefined, {geometricBounds:outerRectangleBounds});
var mask = outerRectangle.excludeOverlapPath(innerRectangle);
}
//--------------------------------------------------------------------------------------------------------------
var allPageItems = spread.allPageItems;
var partiallyOutOfSpreadItems = [];
var currentItem;

for (var i = 0; i < allPageItems.length; i++) {
currentItem = allPageItems[i];
}

}
//--------------------------------------------------------------------------------------------------------------
function DeleteObjectsOnPasteboard() {
var objs = app.documents[0].pageItems.everyItem().getElements();
while (obj=objs.pop()) {
try {
if(obj.parent instanceof Spread || obj.parent instanceof MasterSpread){ obj.remove() }
}
catch(err) {
//\$.writeln("2 - " + err);
}
}
}
//--------------------------------------------------------------------------------------------------------------
function ErrorExit(myMessage, myIcon) {
alert(myMessage, "Trim Pages Script", myIcon);
exit();
}
//--------------------------------------------------------------------------------------------------------------
function UngroupAllGroups(groups) {
for (var i = groups.length-1; i >= 0; i--) {
var gr = groups[i];
if (gr.groups.length > 0) {
var subGroups = [];
for (var j = gr.groups.length-1; j >= 0; j--) {
subGroups.push(gr.groups[j].id);
}
try {
gr.ungroup();
}
catch(err) {
//\$.writeln("1 - " + err);
ungroupErrors++;
}

for (var k = subGroups.length-1; k >= 0; k--) {
try {
doc.groups.itemByID(subGroups[k]).ungroup();
}
catch(err) {
//\$.writeln("2 - " + err);
ungroupErrors++;
}
}
}
else {
try {
gr.ungroup();
}
catch(err) {
//\$.writeln("1 - " + err);
ungroupErrors++;
}
}
}
}
//--------------------------------------------------------------------------------------------------------------```

Kasyan

• 1. Re: How to move the ends of skewed lines to the bleed bounds

Hey Kasyan!

I don't know would this help, but you can take a look:

http://www.indiscripts.com/post/2009/10/work-around-the-width-height-gap

--

tomaxxi

http://indisnip.wordpress.com/

• 2. Re: How to move the ends of skewed lines to the bleed bounds

Hi Kasyan!

I didn't try to integrate this into your script, so you might have to adjust it a little bit. The trick is to define a function that finds the intersection point of two lines --- and, obviously, you should only call it for the lines that are sure to cross the page border! (Otherwise, it would simply extend *any* line up and over the border.)

I think it would be wise to allow for a tiny error for lines that appear to run "up to" the page edge -- I tested a line for "x <= 0" on a line that appeared to start on 0; the control panel told me so. However, I didn't type that 0 in; I dragged the line to the edge. Apparently, it was *NOT* at precisely "0mm", but something like "0.001mm", because the script simply didn't "see" the line.

My function comes from this page: http://local.wasp.uwa.edu.au/~pbourke/geometry/lineline2d/ and I didn't test what it does to orthogonal lines

(but of course you could add this as an exception), and this is my line-extending script, with a little wrapper to set things up.

The function tests *any* line against *any* other line, so if one crosses the page bounding box, I get the intersection with the bleed box on the side where it crosses the page bbox.

```line = app.selection[0];
// pg size in "regular" [y1,x1, y2,x2] format
pagebbox = [0,0, app.activeDocument.documentPreferences.pageHeight,app.activeDocument.documentPreferences.pageWidth ];
bleedDist = 5; //
bleedbbox = [ pagebbox[0] - bleedDist, pagebbox[1] - bleedDist, pagebbox[2] + bleedDist, pagebbox[3] + bleedDist ];
pt1 = line.paths[0].pathPoints[0].anchor;
pt2 = line.paths[0].pathPoints.lastItem().anchor;
// Start point:
if (pt1[0] <= pagebbox[1] || pt1[0] >= pagebbox[3] ||
pt1[1] <= pagebbox[0] || pt1[1] >= pagebbox[2])
{
if (pt1[0] <= pagebbox[1])
intersectPt = IntersectionPt ( [pt1, pt2], [ [ bleedbbox[1], bleedbbox[0]], [bleedbbox[1], bleedbbox[2] ] ] );

if (pt1[0] >= pagebbox[3])
intersectPt = IntersectionPt ( [pt1, pt2], [ [ bleedbbox[3], bleedbbox[0]], [bleedbbox[3], bleedbbox[2] ] ] );

if (pt1[1] <= pagebbox[0])
intersectPt = IntersectionPt ( [pt1, pt2], [ [ bleedbbox[1], bleedbbox[0]], [bleedbbox[3], bleedbbox[0] ] ] );
if (pt1[1] >= pagebbox[2])
intersectPt = IntersectionPt ( [pt1, pt2], [ [ bleedbbox[1], bleedbbox[2]], [bleedbbox[3], bleedbbox[2] ] ] );
line.paths[0].pathPoints[0].anchor = intersectPt;
}
// End point:
if (pt2[0] <= pagebbox[1] || pt2[0] >= pagebbox[3] ||
pt2[1] <= pagebbox[0] || pt2[1] >= pagebbox[2])
{
if (pt2[0] <= pagebbox[1])
intersectPt = IntersectionPt ( [pt1, pt2], [ [ bleedbbox[1], bleedbbox[0]], [bleedbbox[1], bleedbbox[2] ] ] );

if (pt2[0] >= pagebbox[3])
intersectPt = IntersectionPt ( [pt1, pt2], [ [ bleedbbox[3], bleedbbox[0]], [bleedbbox[3], bleedbbox[2] ] ] );

if (pt2[1] <= pagebbox[0])
intersectPt = IntersectionPt ( [pt1, pt2], [ [ bleedbbox[1], bleedbbox[0]], [bleedbbox[3], bleedbbox[0] ] ] );
if (pt2[1] >= pagebbox[2])
intersectPt = IntersectionPt ( [pt1, pt2], [ [ bleedbbox[1], bleedbbox[2]], [bleedbbox[3], bleedbbox[2] ] ] );
line.paths[0].pathPoints.lastItem().anchor = intersectPt;
}

function IntersectionPt (ln1, ln2)
{
var ua;
var x1 = ln1[0][0], x2 = ln1[1][0], x3 = ln2[0][0], x4 = ln2[1][0];
var y1 = ln1[0][1], y2 = ln1[1][1], y3 = ln2[0][1], y4 = ln2[1][1];
ua = ((x4 - x3)*(y1 - y3) - (y4 - y3)*(x1 - x3))/((y4 - y3)*(x2 - x1) - (x4 - x3)*(y2 - y1));

return [ x1 + ua*(x2-x1), y1 + ua*(y2-y1) ];
}
```
• 3. Re: How to move the ends of skewed lines to the bleed bounds

Further reflections:

You can use the same code for straight paths with more points, but in that case you should not test the first and last point, but rather the first and second point (*) for the start case, and the last and second-to-last point for the end.

(*) You might want to make sure these points don't fall on top of each other...

A similar construction *might* even work for curved lines. It's fairly easy to deconstruct a bezier curve into straight line segments, so you could do that first, then use the same 'straight line' path algorithm above to extend the final line segment.

But you might have to do that with a circle! Ideally, it should work something like in this picture -- but it makes stuff *much* harder

-- possibly above & beyond what's practical.

1 person found this helpful
• 4. Re: How to move the ends of skewed lines to the bleed bounds

Hi Jongware and Marijan,

Thank you both for your quick responses.

Jongware's answer is exactly what I was looking for. After a little tweaking it does what I want: moves the ends of lines to the spread's bleed box.

Thank you very much again, Jongware.

Regards,

Kasyan