Jump to content

CopyFitting text on a business card


TroyM68

Recommended Posts

I have a client that is having difficulty using copyfit. They are trying to create a business card template as follows:

 

Let me preface, this is a hospital and the Drs. like their certifications and credentials. For the purpose of this example, we are just calling them "Cert(s)".

 

 

1) First and Last Name, Cert, Cert, Cert

2) Cert, Cert, Cert, Cert, Cert, Cert, Cert

3) Title

4) Department

5) Address | City, St. Zip

6) Phone1 | Phone2

7) Phone3 | Phone4

8) Email

 

They would like the field "Certs", shown above in red, to be able to fill the remaining space on line 1 of the text frame. Since Doctors like to show all of their certifications, the customer would like to have multiple certifications roll to line 2, if necessary (if they all don't fit on line 1).

(All certifications will be entered into 1 field separated by commas) They do not, however, want certifications to roll to a 3rd line of text.

If the certifications exceed the space on line 2 of the text frame, the customer would like to return "Certifications exceed the allotted space".

 

When they were doing these cards manually, they would adjust the spacing between the letters and the letter width, while not affecting the font height.

 

When experimenting with CopyFit, they found all the text shrunk by a percentage and would role to more then to two line limitation.

 

I haven't been able to figure this one out on my own, so I am reaching out to see if anyone has run into something similar in the past...or... has any suggestions on how I can accomplish this?

 

Thank you!!!

Link to comment
Share on other sites

Are you really trying to copyfit the certs, or are you just trying to limit them to two lines? In other words, should the rule try to shrink the certs down to a specific size to try to fit them onto two lines? Or is the idea just to see if they fit on two lines at the original point size, and report an error if they don't?
Link to comment
Share on other sites

What They currently do is one of two things pending the number of certs. They either squeeze the text (width-wise) as much as 85% (to get the certs all on only the first line) or...If the certs still can't fit on line 1, they abandon the "Text Squeeze" and wrap the text to a second line with no adjustment to the font whatsoever.

 

Right now the customer doesn't know if they can have both options.

 

The perfect scenario would be for a rule to look at the space available in the first line of text to see if the certs could be "squeezed", no more then 85%, to keep all the text on line 1...

 

If it is too long to fit on that first line... They would like to abandon the "text squeeze", and instead, roll the text to a second line, but not to exceed the spaces available on line two... If that limit is exceeded...they would like a message telling them the maximum number of characters has been exceeded.

 

If this is too crazy... please let me know... But thanks for listening and for your input1

 

Troy

Link to comment
Share on other sites

Based off of Dan's and Step's code here on the forum.

 

//Field names
var v_field = [Field('First and Last Name'), Field('Cert1'), Field('Cert2'), Field('Cert3'), Field('Cert4')].filter(String);
//Font
var font_name = "2Volkswagon Heavy-K";
//Font Size
var v_size = "12";
//Frame Width in inches
var v_frame = "3";


var var1_n =  '<f name="' + font_name + '">';
var var1_s =  '<z newsize="' + v_size + '">';
var var2 = v_field.join(', '); //combine fields
var var3 = v_frame*72; //get frame width in points
var var4 = var1_n + var1_s + var2;
var tm = new FusionProTextMeasure;
tm.CalculateTextExtent(var4);
var tmwidth = tm.textWidth;
if (tmwidth < var3*100){return var4;} //if no scaling needed return without magnify
var factor = Round(var3 / tm.textWidth * 10000, 0) - 1;
if (factor >= 85){return "<magnify type=setwidth factor=" + factor + ">" + var4 + "</magnify>";} //if scaling is above 85% return with scaling
if (tmwidth < var3*200){return var4;} //if it can fit 2 lines without scaling return

//error Message
Print ("the maximum number of characters has been exceeded");
return "Certifications exceed the allotted space";

 

The line that contains "if (tmwidth < var3*200){return var4;}" might need the 200 value adjusted lower. Since some text breaks at different points.

Link to comment
Share on other sites

One thing you could do is to create a text rule to return your name and credentials called "Name":

var name = Field('name');
var creds = Field('creds');

return []
   .concat(name, creds.split(','))
   .map( function(s) {
       return Trim(s);
   })
   .filter(String)
   .join(', ');

 

Then you could insert that into a text frame along with other rules/variables and let onCopyfit handle the resizing of your text by inserting this into the onCopyFit callback:

var cf = FusionPro.Composition.CurrentFlow
var rule = 'Name';
if (!Copyfit(new MagnifyAttributes("text", 25, 400, 6, 72))) {
 ReportWarning("Could not copyfit text in flow " + 
               FusionPro.Composition.CurrentFlow.name);
} else {
 if (Rule(rule)) {
   var factor = Int((cf.content.match(/factor="(\d+)"/) || ['','100'])[1]) / 100;
   var tag = '<variable name="' + rule + '">';
   var find = new RegExp('<para.*?(?='+tag+')', '')
   var paragraph = (cf.content.match(find) || [''])[0];
   var font = (paragraph.match(/<f name="([^"]+)"/) || ['','Arial'])[1];
   var size = Int((paragraph.match(/<z newsize="([^"]+)"/) || ['','12'])[1]) * factor;

   var tm = new FusionProTextMeasure;
   tm.font = font;
   tm.pointSize = Int(size) + 'pt';
   tm.maxWidth = GetSettableTextWidth(FindTextFrame(cf.name));
   tm.CalculateTextExtent(Rule(rule));

   if (tm.textLines > 2)
     cf.content = cf.content.replace(new RegExp(tag, ''), 
       '<color name="Red">Certifications exceed the allotted space</color>');
 }
}

 

That allows you to more accurately determine if "Name" will require 1 or 2 lines after the frame has been "copyfit" to ensure the text flow fits in the frame. I suppose you could play around with those settings in order to reduce the tracking to a minimum of 85% before wrapping the "Name" to a second line if you wanted to but I'll leave that up to you.

Link to comment
Share on other sites

Scott, when I re-create your rule:

 

//Field names

var v_field = [Field('First Name') + " " + Field('Last Name ') + ", " + Field('Credentials') ].filter(String);

//Font

var font_name = "Arial";

//Font Size

var v_size = "11";

//Frame Width in inches

var v_frame = "2.05";

 

var var1_n = '<f name="' + font_name + '">';

var var1_s = '<z newsize="' + v_size + '">';

var var2 = v_field.join(' '); //combine fields

var var3 = v_frame*72; //get frame width in points

var var4 = var1_n + var1_s + var2;

var tm = new FusionProTextMeasure;

tm.CalculateTextExtent(var4);

var tmwidth = tm.textWidth;

if (tmwidth < var3*100){return var4;} //if no scaling needed return without magnify

var factor = Round(var3 / tm.textWidth * 10000, 0) - 1;

if (factor >= 85){return "<magnify type=setwidth factor=" + factor + ">" + var4 + "</magnify>";} //if scaling is above 85% return with scaling

if (tmwidth < var3*200){return var4;} //if it can fit 2 lines without scaling return

//error Message

Print ("the maximum number of characters has been exceeded");

return "Certifications exceed the allotted space";

 

I receive the following message when I try to validate:

<f name="Arial"><z newsize="11">Troy Marshall, cred, cred, cred, cred, cred, cred,

 

This is also what appears on the Business Card.

 

What am I doing wrong???

Link to comment
Share on other sites

The v_field is a variable array. So it should only include values separated by a comma. The concatenation with the + is not needed, as that is handled later on.

So I would change it to:

var FirstLast = Field('First Name') + " " + Field('Last Name ') + ", ";
var v_field = [FirstLast, Field('Credentials') ].filter(String);

 

This way we can modify the FirstLast later if needed, while still using the rest of the code.

Link to comment
Share on other sites

Step,

When I change the OnCopyFit rule (modified below)

 

var cf = FusionPro.Composition.CurrentFlow

var rule = 'name';

if (!Copyfit(new MagnifyAttributes("text", 25, 400, 6, 72))) {

ReportWarning("Could not copyfit text in flow " +

FusionPro.Composition.CurrentFlow.name);

} else {

if (Rule('name')) {

var factor = Int((cf.content.match(/factor="(\d+)"/) || ['','100'])[1]) / 100;

var tag = '<variable name="' + rule + '">';

var find = new RegExp('<para.*?(?='+tag+')', '')

var paragraph = (cf.content.match(find) || [''])[0];

var font = (paragraph.match(/<f name="([^"]+)"/) || ['','Arial'])[1];

var size = Int((paragraph.match(/<z newsize="([^"]+)"/) || ['','12'])[1]) * factor;

var tm = new FusionProTextMeasure;

tm.font = font;

tm.pointSize = Int(size) + 'pt';

tm.maxWidth = GetSettableTextWidth(FindTextFrame(cf.name));

tm.CalculateTextExtent(Rule(rule));

if (tm.textLines > 2)

cf.content = cf.content.replace(new RegExp(tag, ''),

'<color name="Red">Certifications exceed the allotted space</color>');

}

}

 

I receive the following error message when I try to validate the rule.

C:\Program Files (x86)\PTI\FusionPro\Builtins.js line 3316 ERROR: in FindFrame(), no frame specified

Any ideas?

Link to comment
Share on other sites

Step,

When I change the OnCopyFit rule (modified below)

 

var cf = FusionPro.Composition.CurrentFlow

var rule = 'name';

if (!Copyfit(new MagnifyAttributes("text", 25, 400, 6, 72))) {

ReportWarning("Could not copyfit text in flow " +

FusionPro.Composition.CurrentFlow.name);

} else {

if (Rule('name')) {

var factor = Int((cf.content.match(/factor="(\d+)"/) || ['','100'])[1]) / 100;

var tag = '<variable name="' + rule + '">';

var find = new RegExp('<para.*?(?='+tag+')', '')

var paragraph = (cf.content.match(find) || [''])[0];

var font = (paragraph.match(/<f name="([^"]+)"/) || ['','Arial'])[1];

var size = Int((paragraph.match(/<z newsize="([^"]+)"/) || ['','12'])[1]) * factor;

var tm = new FusionProTextMeasure;

tm.font = font;

tm.pointSize = Int(size) + 'pt';

tm.maxWidth = GetSettableTextWidth(FindTextFrame(cf.name));

tm.CalculateTextExtent(Rule(rule));

if (tm.textLines > 2)

cf.content = cf.content.replace(new RegExp(tag, ''),

'<color name="Red">Certifications exceed the allotted space</color>');

}

}

 

I receive the following error message when I try to validate the rule.

C:\Program Files (x86)\PTI\FusionPro\Builtins.js line 3316 ERROR: in FindFrame(), no frame specified

Any ideas?

 

You need to name the frame that the Rule('name') is shown in.

Link to comment
Share on other sites

The v_field is a variable array. So it should only include values separated by a comma. The concatenation with the + is not needed, as that is handled later on.

So I would change it to:

var FirstLast = Field('First Name') + " " + Field('Last Name ') + ", ";
var v_field = [FirstLast, Field('Credentials') ].filter(String);

 

This way we can modify the FirstLast later if needed, while still using the rest of the code.

 

Doing this pretty much defeats the purpose of the 'filter' method. Consider a situation where both fields ("First Name" and "Last Name") are empty:

var FirstLast = Field('First Name') + " " + Field('Last Name ') + ", "; // FirstLast = [color="Red"]" , "[/color]
var v_field = [FirstLast, Field('Credentials') ].filter(String); // v_field = [[color="red"]" , "[/color], Field('Credentials')]

 

A more appropriate way to handle that is:

var FirstLast = Field('First Name') + ' ' + Field('Last Name');   // FirstLast = ' '
if (FirstLast = Trim(FirstLast))                                            
 FirstLast += ', ';

var v_field = [ FirstLast, Field('Credentials') ].filter(String); // v_field = [ Field('Credentials') ]

 

Or:

var v_field = [[Field('First Name'),Field('Last Name')].filter(String).join(' '), Field('Credentials')].filter(String).join(', '); // v_field = [ Field('Credentials') ]

Link to comment
Share on other sites

Scott, I made the change and I still get the <f name="Arial"><newsize="12">FirstLast, Credentials

Are the literal tags showing in the text frame when you preview/compose? If so, there's a pretty good chance that you didn't check the "Treat returned strings as tagged text" checkbox at the top of the rule editor. Checking that box will cause FP to actually interpret those tags and apply the font and size to your text rather than print them.

Link to comment
Share on other sites

The text frame is named "name"

 

The rule is named "name" in that text field.

 

I am still getting the error:

Builtins.js line 3316 ERROR: in FindFrame(), No frame specified.

 

Also... Without this working... All the text font size reduces (ex: from 11pt to 6pt) Font size needs to remain at 11pt. Just the spacing between characters needs to adjust from no more then 100% down to no less then 85% of normal spacing. This may be because the OnCopyFit rule isn't working???

 

NameRule.JPG.b7c6ea6a6900aacbdcc84651b05fe457.JPG

 

OnCopyFit.JPG.6c7db84e9b13c3d63e139011e54c9502.JPG

 

Error.JPG.47deb204a2d3e7b74672222767a5458b.JPG

 

TextFrame.JPG.67b014c407bc5a54fcd64fee7466eda0.JPG

Link to comment
Share on other sites

You don't actually have to do all of this in the OnCopyfit callback rule, but if you do, then you want to write the rule like this, with your actual frame name on the first line:

if (FusionPro.Composition.CurrentFlow.name == "Name of frame with custom copyfitting")
{
   // Custom copyfitting logic here.
   return;
}
//else
// default copyfitting

if (!Copyfit(new MagnifyAttributes("text", 25, 400, 6, 72)))
   ReportWarning("Could not copyfit text in flow " + 
                 FusionPro.Composition.CurrentFlow.name);

Link to comment
Share on other sites

  • 3 weeks later...

Ran into a glitch...

This rule works great until the credentials field is left blank (it's not a required field). When the credentials field is blank... the return is:

First Last, (It returns a comma)

 

When the credentials are present the return is:

First Last, Credential (exactly as it should be)

 

How would I modify the rule to address this issue? Only use a "," if the credentials field is not empty?

 

Thanks again!

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...