Jump to content

CreateResource Orientation


step

Recommended Posts

I've read a couple of threads regarding determining the orientation of a resource.

 

Is there a way to do this without physically adding the resource (pdf's in my case) as a FusionProResource?

 

I am setting up a template that will pull in pdfs and output a portrait file. The data that is passed to me consists of the file names so I won't be able to automate the process if I have to physically add them as resources of the template.

 

Am I able to get the width and height of the image using the text measure function if I pass it the path within graphic tags?

 

Is there a different solution that I may have overlooked?

Link to comment
Share on other sites

I've read a couple of threads regarding determining the orientation of a resource.

Okay, I assume you're talking about the function in this post:

http://forums.pti.com/showpost.php?p=1367&postcount=2

 

Specifically:

function IsResourceLandscape(res)
{
 if (!res instanceof FusionProResource)
   throw "Not a resource: " + res;

 if (!res.exists)
   throw "Resource not found: " + res;

 var TM = new FusionProTextMeasure;
 TM.useTags = true;

 var err=TM.CalculateTextExtent(res.content);
 if (err)
   throw "Error measuring resource: " + res + ": " + TM.messages;

 Print(res + ": Width=" + TM.textWidth + ", Depth=" + TM.textHeight);
 return TM.textWidth > TM.textHeight;
}

Is there a way to do this without physically adding the resource (pdf's in my case) as a FusionProResource?

Well, I think the way you're asking that question sheds light on what's confusing you.

 

The IsResourceLandscape function does indeed expect an object of type FusionProResource. However, you don't "physically add a resource as a FusionProResource". FusionProResource is a JavaScript class, objects of which can be created in two ways:

 

  1. Call the Resource() function, with the name of a named resource which has been added to the template in the Resources dialog; OR
  2. Call the CreateResource() function, with the file name of a file on disk, whether it's been added as a named resource or not.

Either one of those returns a valid FusionProResource object, which can be passed to the IsResourceLandscape function.

 

The example in that thread of calling the function just happens to show, as an example, obtaining a FusionProResource object by calling the Resource function, which accesses a named resource added to the job. But you can call CreateResource instead, to load up any arbitrary graphic, by file name, whether it's been added as a named resource to the job or not.

 

So you want to do something like this:

var MyResource = CreateResource(Field("Picture")); // base this on a field or some other per-record data
if (IsResourceLandscape(MyResource))
 return MyResource;
//else
return NullResource();

I am setting up a template that will pull in pdfs and output a portrait file. The data that is passed to me consists of the file names so I won't be able to automate the process if I have to physically add them as resources of the template.

 

Am I able to get the width and height of the image using the text measure function if I pass it the path within graphic tags?

No, you don't need graphic tags, you just need to call CreateResource().

 

You can specify the full path in the call to CreateResource(), as well as the file name, if you want, and that will work fine. But that generally makes jobs less portable. It's better practice to specify just the file name, without a path, in the CreateResource() call, and add Search Paths as necessary on the Advanced tab of the Composition Settings dialog. Of course, if the resource you're trying to load is already in the same folder as either the template PDF or the input data file, then it will be automatically found, without having to specify any paths anywhere.

Is there a different solution that I may have overlooked?

Well, there are lots of ways to skin this particular cat. You could build up a <graphic> tag manually, and pass that to the call to FusionProTextMeasure.CalculateTextExtent instead of using a resource, but it's a lot easier to let the FusionProResource object do that for you.

Link to comment
Share on other sites

Oh, I see.

 

When I'm trying to validate the rule I get an uncaught exception saying that FP has had an "Error measuring the resource." I noticed where the error was being generated in the code but thought it was because the resource wasn't physically linked to the template as a resource.

 

After I composed the file, however, the results were as I expected it to me. In FP8 does TextMeasure not run until composition?

Link to comment
Share on other sites

When I'm trying to validate the rule I get an uncaught exception saying that FP has had an "Error measuring the resource." I noticed where the error was being generated in the code but thought it was because the resource wasn't physically linked to the template as a resource.

Can you tell me what the rest of the error message is?

After I composed the file, however, the results were as I expected it to me. In FP8 does TextMeasure not run until composition?

Well, text measurement generally works at rule validation time, but all the underlying mechanisms to locate resources and such aren't fully set up until composition time. So this particular trick of measuring graphics might only work at composition time. You can always add some logic to the function to account for this; something like:

// Text measurement of graphics may not work at validation time.
if (FusionPro.inValidation)
   return true;

Link to comment
Share on other sites

The error message says:

"***Error*** (uncaught exception: Error measuring resource: Resource("/Volumes/path/to/resource.pdf"): )

 

For full disclosure: I am attempting to populate my graphic frames in the OnRecordStart call back. By adding this line of code I'm able to get the job to compose and impose as I'd expect (locally):

(I'm guessing it works because it causes the code to stop executing before it gets to the IsResourceLandscape function but I'm not sure why I'm not seeing the same results when composing the job server side. But I'm hoping Dan can elaborate more on this object).

if(FusionPro.Composition.inPreprocessing)
return ;

 

But when I attempt composition on our FP Server (using Producer), the file errors at record 1.

 

I'm pasting my code as it is (with the exception of the path being modified) in hopes that one of you kind-hearted souls can help me out with getting the results I need. Thanks in advance!

var path = "/Volumes/path/to/";
path = (FusionPro.isMac) ? path : path.replace("Volumes","ServerName").replace(/\//g,"//");

var pdf = CreateResource(path + Field("name"),'graphic',true);
var pages = pdf.countPages;
FusionPro.Composition.repeatRecordCount = pages;
pdf.pagenumber = FusionPro.Composition.repeatRecordNumber;

// Enables desktop composition
/*
if(FusionPro.Composition.inPreprocessing)
return ;
*/

function IsResourceLandscape(res)
{
 if (typeof TestedGraphics[res] != "undefined")
   return TestedGraphics[res];

 if (!res instanceof FusionProResource)
   throw "Not a resource: " + res;

 if (!res.exists)
   throw "Resource not found: " + res;

 var TM = new FusionProTextMeasure;
 TM.useTags = true;

 var err=TM.CalculateTextExtent(res.content);
 if (err)
   throw "Error measuring resource: " + res + ": " + TM.messages;

 var result = TM.textWidth > TM.textHeight;
 TestedGraphics[res] = result;
 return result;
}

var orientation = (IsResourceLandscape(pdf)) ? "landscape" : "portrait";

FindGraphicFrame("page_" + orientation).SetGraphic(pdf); 

Link to comment
Share on other sites

For full disclosure: I am attempting to populate my graphic frames in the OnRecordStart call back. By adding this line of code I'm able to get the job to compose and impose as I'd expect (locally):

(I'm guessing it works because it causes the code to stop executing before it gets to the IsResourceLandscape function but I'm not sure why I'm not seeing the same results when composing the job server side. But I'm hoping Dan can elaborate more on this object).

You're hard-coding a local path on your client Mac. The graphic is not at that same path when you compose the job on the server, which is running Windows.

 

Like I said in my previous post:

You can specify the full path in the call to CreateResource(), as well as the file name, if you want, and that will work fine. But that generally makes jobs less portable. It's better practice to specify just the file name, without a path, in the CreateResource() call, and add Search Paths as necessary on the Advanced tab of the Composition Settings dialog. Of course, if the resource you're trying to load is already in the same folder as either the template PDF or the input data file, then it will be automatically found, without having to specify any paths anywhere.

The upshot is that you're better off not specifying any path at all in the JavaScript rule.

 

Now, what I can't tell you is what path to put in there so that the job composing on the Windows server can find it. Usually, for jobs composed on remote servers like this which access graphic resources, you have to remove the hard-coded path from the rule, and then do one of two things:

 

  1. Add the graphics as named resources to the job, so that they get collected up with the job. Then you can access them with either Resource() or CreateResource() in your rules.
    OR
  2. Put the graphics on a shared network location, which can be accessed with a UNC path (like \\servername\folder) on Windows, and via some kind of sharing mechanism like SMB (as a path such as /Volumes/servername/folder) on Mac. Then you can add both paths (delimited with a semicolon) to the Search Path on the Advanced tab of the Composition Settings.

The first option is easier to set up, but then all the graphics have to be collected up, which can be unwieldy for a distributed system. The second option requires some work to set up the shares so that both the client machine (Mac in this case) and the FP Producer/Server remote composition machine can access the resources on the LAN.

 

There are other options as well, such as using FusionPro.isMac or FusionPro.isWindows in your rule to hard-code different paths for each platform (and also possibly using FusionPro.Composition.isBatch to differentiate between FP Creator/Desktop compositions on Windows versus FP Producer/Server compositions).

 

It looks like you're actually trying to do something like this in your rule, but what you have there doesn't make sense:

var path = "/Volumes/path/to/";
path = (FusionPro.isMac) ? path : path.replace("Volumes","ServerName").replace(/\//g,"//");

All that those first two lines are going to is result in the path "/ServerName/path/to/" on your Mac, which is clearly wrong. If anything, I would expect the full POSIX path to start with "/Volumes/" and THEN the server name; something like "/Volumes/StepsServerName/SomeFolderName". You can find out the exact path by locating one of the files in the Finder and doing "Get Info" (command+I).

 

Even though the path to the graphics on your Mac seems to be invalid, FusionPro is probably finding the graphics anyway. My guess is that they're in the same folder as the either the template PDF or the input data file, both of which are automatically searched.

 

On Windows, the path in the rule makes even less sense. "/Volumes/path/to/" is clearly wrong. You probably need some kind of UNC path, in a form such as "\\StepsServerName\SomeFolderName". You should be able to navigate to the folder on Windows to find the right path.

 

So, if you really do want to hard-code the path in the rule, despite my recommendation not to do that, you'll be better off just hard-coding the full path on each platform instead of trying to do some tricks with string manipulation to convert the path from one platform's format to another's. For instance:

// Note that each backslash needs to be escaped with two backslashes
// in the string literal, so "\\Server\ShareName" needs to be "\\\\Server\\ShareName"
var path = "\\\\StepsServerName\\SomeFolderName"; // for Windows
if (FusionPro.isMac)
   path = "/Volumes/StepsServerName/SomeFolderName";

But instead of doing that, I would take that out of the rule and add something like this into the Search Path box in the Composition Settings:

/Volumes/StepsServerName/SomeFolderName;\\StepsServerName\SomeFolderName

Note that you don't have to mess around with escaping backslashes there in the dialog, like you do in JavaScript.

 

As to your question about this logic:

if(FusionPro.Composition.inPreprocessing)
  return ;

The purpose of that is so that this measurement happens only during the main composition pass, not during the preprocessing pass, which is most likely occurring because you're using "Infinite Stack" Imposition, and FusionPro needs to run through the job once to determine how many records are being output so that it knows how deep to make the stack. Or, you're using FP Expression images in the job, and those are being created at preprocessing time. Either way, that's not really relevant to the main issue, which is that you need to accurately tell FusionPro where to locate the graphics on each platform.

 

Anyway, nobody else can tell you what the correct path to use to locate the graphics is on your LAN.

Link to comment
Share on other sites

Dan, in this line of code, I replace "Volumes" with the server name and replace forward slashes with //:

path = (FusionPro.isMac) ? path : path.replace("Volumes","ServerName").replace(/\//g,"//");

 

The hardcoded path (as it's written above) works for composition on a Windows server when there is no imposition applied.

 

Once the imposition is applied, the job errors if I'm not running it locally (via Creator).

 

That being said, I took your advice and removed the path variable from my CreateResource and added both paths as a "search path" in the composition dialog box. And that didn't work either.

 

Is there an issue with using infinite stacked impositions on Producer?

Link to comment
Share on other sites

Dan, in this line of code, I replace "Volumes" with the server name and replace forward slashes with //:

path = (FusionPro.isMac) ? path : path.replace("Volumes","ServerName").replace(/\//g,"//");

The hardcoded path (as it's written above) works for composition on a Windows server when there is no imposition applied.

Okay, if you say so. Although it's my understanding that, while forward slashes (/) can generally be used interchangeably with backward slashes (\) on Windows, UNC share designations still have to start with backslashes. But if it works, then fine.

Once the imposition is applied, the job errors if I'm not running it locally (via Creator).

Can you be more specific regarding what you mean by "errors?" Exactly what is the failure mode? Does the job fail to create output, or do you just get warning messages in the log file? If it does create output, are the graphics there?

That being said, I took your advice and removed the path variable from my CreateResource and added both paths as a "search path" in the composition dialog box. And that didn't work either.

Well, again, what exactly do you mean by, "didn't work?" Presumably it's finding (or not finding) the graphics the same way.

Is there an issue with using infinite stacked impositions on Producer?

Not that I know of. I explained why that line of code with "inPreprocessing" may be needed, but that shouldn't work any differently in Producer than Creator (Desktop). At any rate, I'm not sure why you think that the preprocessing, or imposition in general, has anything to do with whether the graphics can be located during the main composition pass. If you don't impose, does it find the graphics then?

Link to comment
Share on other sites

So after reading your post in this thread, you stated that "the search path for finding graphics isn't completely set up at preprocessing time." If that still remains true, that could be my problem. Since I'm repeating my records based on the number of pages in my PDF resource, it would be impossible for FP to know how many times to repeat a record and calculate infinite stacking if the graphics aren't completely set during the preprocessing.

 

var path = "/Volumes/path/to/";
path = (FusionPro.isMac) ? path : path.replace("Volumes","ServerName").replace(/\//g,"//");

var pdf = CreateResource(path + Field("name"),'graphic',true);
[color="Red"]var pages = pdf.countPages;
FusionPro.Composition.repeatRecordCount = pages;
pdf.pagenumber = FusionPro.Composition.repeatRecordNumber;[/color]

// Enables desktop composition
/*
if(FusionPro.Composition.inPreprocessing)
return ;
*/

function IsResourceLandscape(res)
{
 if (typeof TestedGraphics[res] != "undefined")
   return TestedGraphics[res];

 if (!res instanceof FusionProResource)
   throw "Not a resource: " + res;

 if (!res.exists)
   throw "Resource not found: " + res;

 var TM = new FusionProTextMeasure;
 TM.useTags = true;

 var err=TM.CalculateTextExtent(res.content);
 if (err)
   throw "Error measuring resource: " + res + ": " + TM.messages;

 var result = TM.textWidth > TM.textHeight;
 TestedGraphics[res] = result;
 return result;
}

var orientation = (IsResourceLandscape(pdf)) ? "landscape" : "portrait";

FindGraphicFrame("page_" + orientation).SetGraphic(pdf);

 

I'm able to get the page count supplied to me in the data so once I added that field and removed the .countPages, the job imposed correctly on Producer.

 

Does that sound like a probable cause for my problem?

Link to comment
Share on other sites

So after reading your post in this thread, you stated that "the search path for finding graphics isn't completely set up at preprocessing time." If that still remains true, that could be my problem. Since I'm repeating my records based on the number of pages in my PDF resource, it would be impossible for FP to know how many times to repeat a record and calculate infinite stacking if the graphics aren't completely set during the preprocessing.

Okay, this is all good information, but it sounds like this problem you're describing now, where you can't get the page count at preprocessing time, is not directly related to the original problem in the thread, which is that you were having trouble orienting graphics.

 

As I said in that other thread, there is a combination of things going on in this job. Just because there may be issues with locating graphics at preprocessing time, that doesn't mean that there's a general issue with using infinite stacked impositions in FP Producer.

I'm able to get the page count supplied to me in the data so once I added that field and removed the .countPages, the job imposed correctly on Producer.

 

Does that sound like a probable cause for my problem?

Possibly, although you still haven't specified exactly what you mean by "the job imposed correctly," or "the job errors." And you've kind of switched to talking about a different problem along the way here.

 

This seems to be the second time that I've tried to troubleshoot this job without seeing it. And like I said in that other thread, it's very difficult, if not impossible, to analyze problems like this through a keyhole. If you need a more definitive answer, then I suggest collecting up the job, with a comprehensive description of exactly what the failure mode is in the Producer composition, and sending it to Support.

Link to comment
Share on other sites

I realize that I've gotten off topic and I apologize for that. I just started the thread whilst in the middle of debugging the code and what I initially thought was causing the problem (IsResourceLandscape) turned out not to be. I realized that yesterday but thought it would be better to consolidate my posts into this one thread instead of bombarding the forum with every potential culprit for my problem.

 

I do, however, appreciate you taking the time to respond and helping me troubleshoot despite the vague description of the problem!

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...