Jump to content
Developer Wiki and Function Reference Links Read more... ×
Sign in to follow this  
atari2600

newbie vectorscript question: find & replace font

Recommended Posts

Hi there,

I have been using VW for years, but never had the time to dive into vectorscript. I am currently testing VW2009 for our office, and notice that we have to switch out our primary font because it's open type, and is not supported in 2009 (even though it shows up fine in 12.5)

Either way, in order to clean up our templates, I thought it would be faster to run a script which finds and replaces all our instances of "Tekton Pro" with "Tekton". I'd rather have the template cleaned up instead of each station relying on the "replace font mappings" feature.

I have no trouble writing the "find" part, but am really stuck on how to write the "replace" part of the script.

I assume this is VS101 for most of you, but I assume that someone has done this before so I shouldn't re-invent the wheel (not to mention- "seeing it" will go a long way in helping me better understand Vectorscript.)

thanks a lot,

Matt

Share this post


Link to post

Hi Matt,

???Actually, it's VS 102 and the fastest way to learn it is by example. This is untested code, so try it on a test file first and I'm sure you can make it work. It's a basic template you can use to make global changes to files and you can get as specific as you want with your matching criteria just by changing the logic in called function (ChangeFont, in this example).

Raymond

PROCEDURE SwapFonts;
{ Change the Font Face of every text object in a file. }
{ 09 Sept 09 - Raymond J Mullin }
CONST
Font0 = 'Tekton Pro';
Font1 = 'Tekton';
VAR
H :Handle;
FID0, FID1 :Integer;

function ChangeFont(H :Handle) :Boolean;
Var
	FID :Integer;
Begin
	if (GetType(H) = 10) then begin
		FID := GetTextFont(H, 0);	{ font ID of text object - first character }
		if (FID = FID0) then 
			SetTextFont(H, 0, len(GetText(H)), FID1);
	end;		{ if GetType }
End;		{ ChangeFont }


BEGIN
FID0 := GetFontID(Font0);		{ original Font ID }
FID1 := GetFontID(Font1);		{ new Font ID }

ForEachObjectInLayer(ChangeFont, 0, 2, 1);		{ All objects, Deep, All layers }
ForEachObjectInList(ChangeFont, 0, 2, FSymDef);	{ All objects, Deep, All symbol definitions }

Sysbeep;		{ beep when done }
END;
Run(SwapFonts);

Edited by MullinRJ

Share this post


Link to post

Custom Modification will only get you part way as it will not edit fonts inside of symbols. For that I think you will need to write a custom script.

Technically the easiest way is probably to build a resource list of all the symbols, get a handle to the first symbol, get a handle to the first 2D object in the symbol, if it is text, change it to the correct font, if not skip it. Get the next object until all of the objects in the 2D portion of the symbol have been fixed, then get a handle to the next symbol def and repeat until they are all done.

See the BuildResourceList and GetResourcefromList commands in the scripting guide.

If you don't get it, let me know and I will see what I can come up with over the weekend.

Share this post


Link to post

Hi Pat,

???I believe my second FEOIL(ist) will look inside Symbols adequately, but I don't think my code will modify any PIOs containing text. They may need to be done manually, or with some knowledge which PIOs are used.

???I modified the function ChangeFont to test for text objects, an omission resulting from having a good thought and not acting on it before it evaporated.

???One assumption my code makes is that it judges the Font Face of a text block by its first character. If you mix Font Faces inside text blocks, then the code will need to be modified to check each character in each text block for the old font and change it accordingly. Not hard, just a little more tedious.

Raymond

Share this post


Link to post

Hello Gentlemen,

So I read the first few posts, had dinner and then thought I might play with criteria a little. Came back to find Ray's script. As usual he is more thorough than I.

Figure I might as well post anyway,since for the learning two examples might be interesting.

PROCEDURE change;

PROCEDURE setFont(h:HANDLE);

????Begin

????????setTextFont(h,0,GetTextLength(h),GetFontID('Helvetica'));

????End;

BEGIN

???ForEachObject(setFont,((FOT='Geneva') & INSYMBOL & INOBJECT));

END;

RUN(change);

I don't have a PIO with text to try it on, but it seems it should get in there.

It takes care of symbol instances in the drawing, but I don't see why it would get symbol defs. Didn't test that.

I did learn something about FEO: it will go into groups without any further criteria than FOT='font name', so it does viewports as well. It does need INSYMBOL to get into those.

I guess it might be possible to declare setFont as a procedure for FEO, and as a function for FEOIL to cover everything.

A question for Ray: Will your FEOIL get into symbol folders, or will the list only be the symbols on the top level? I seem to recall that some further acrobatics are needed if there are folders present, possibly involving FInFolder.

Share this post


Link to post

Hi Charles,

???I would hope DEEP meant FEIOL would crawl into Folders as they are just another container type, but I don't know off the top of my head. Will check tomorrow. Zzzzzzz time now.

Raymond

Share this post


Link to post

Thanks for all the help (esp. Ray & Charles :) ) I created two new scripts and pasted your suggestions in. They both compiled sucessfully, but when I ran them, nothing seemed to happen with either script.

Am I forgetting to do something mundane? (I saved the file after compiling.)

Either way, I am convinced I need some VS basics. Any suggestions of a good tutorial?

thanks again,

Matt

Share this post


Link to post

Matt,

Are you sure the font names are spelled correctly? Very important! This script worked in a test file I created to change Helvetica to Calibri.

Try this one line script on a selected text block to check its Font Name spelling as compared to the name shown in the Font Menu name. They should be the same, but if not, try the name in the message window.

message('Font ID = ', GetTextFont(FSActLayer, 0), ' Font name = ', GetFontName(GetTextFont(FSActLayer, 0)));

If the name is blank, you aren't getting a good Font ID because the font isn't recognized in VW.

If the number returned is -1, then the FontID is not being found. You may have to use VW12.5 to prepare the template files with this script and then reconvert the files to VW 2009.

Raymond

Share this post


Link to post
Software Customization Services has a PIO.

It's $20.00

Dear me! That's probably your monthly allowance.

Now, does it represent value as comes to the price of VW?

A brudger is a man who knows the price of everything but the value of nothing.

? Kool ?Oscar Wilde? Aid

Share this post


Link to post

But better than a poke in the eye.

It's less fun than reinventing the wheel.

You remind me of Amhed Ouahi.

Edited by brudgers

Share this post


Link to post

Maybe so, if your mother raises your allowance so that you can continue to play with VectorWorks.

May I remind that YOU specifically raised the issue at hand: that the price of add-on functions need to somehow relate to the price of the program itself. As a percentage.

Does this discussed function increase one's productivity sufficiently in the Brudgers Formula?

Share this post


Link to post
I created two new scripts and pasted your suggestions in. They both compiled sucessfully, but when I ran them, nothing seemed to happen with either script.

My script worked fine on my system. Like Ray, I would first suspect the spelling, or that the font that's written in the script doesn't exist. Anything between quotes in vScript is a literal, so spelling (including punctuation & spaces) is taken literally. I've been tripped up by the occasional space in front of a name a few times. Or...maybe it's a version thing.

If you haven't already, I would suggest trying and buying the plug-in that Brudgers linked to. That's a monumental piece of work and unbelievably cheap if you ask me. If I cared at all about text I would buy it in a heart-beat.

The chief functional difference between that script and the approach we've taken, is that Mr. Chandler has put in the effort to make a 'fool-proof' and fully developed tool. It reads all the fonts in use and displays them in a dialog for the choosing, instead of hard-coding them as we've done, thus by-passing literals and mucking about in the script editor altogether. I'm not sure off-hand where you can actually see an example of this type code, but I think you might be surprised at how much work that takes.

As for a tutorial....I wish I knew. As I've said before, bone-headed determination and an interest in puzzles and language are invaluable. Just keep thinking of things that you wish you could do, try to imagine the steps that you might need to do them, apply the above mentioned attributes, and post questions here.

Oh...and while you're here, do read Brudgers and Kool-Aid, but please try to see past their game. In amongst all the flame you can occasionally find some usable fuel to keep you going forward.

Happy puzzling!

PS to Ray if he makes it this far: I was remembering something I wrote a long time ago when everything seemed to start with WHILE etc DO etc nextHandle etc. If I ever need to edit symbol defs again I will try to think of FEOIList.

Thanks for posting.

Share this post


Link to post

Hello Guys,

Thanks for all your advice. After trying the various scripts and buying the plug-in (worth it.) I concluded the only sure way to replace the font is to remove the "tekton-pro" font family off my computer, so VW is forced to replace it with the "tekton.ttf" font family.

It seemed i would open files up where I replaced the font, and find it reverted back to the original font (which as I mentioned before appears as "arial".

This would never have been an issue if our company had realized years ago that VW doesn't support OpenType fonts. Supported or not, the open type fonts always worked in VW 12, but not in VW 2008 on up.

thanks again,

Matt

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

 

7150 Riverwood Drive, Columbia, Maryland 21046, USA   |   Contact Us:   410-290-5114

 

© 2018 Vectorworks, Inc. All Rights Reserved. Vectorworks, Inc. is part of the Nemetschek Group.

×