The only ``specification'' of the tgif file (obj/sym) format is in
a file called "tgif.pl" which is part of the
tgif source distribution. This is not
a Perl file; instead, it's a file containing Prolog code.
If you know Prolog, it should be fairly easy to figure things out.
If you don't know Prolog, below is a brief description on how to read
"tgif.pl". The size of "tgif.pl" is big because it contains information
about all versions of tgif objects. This also makes the description about
file format a little big involved.
Notation, Notation, Notation...
Each tgif object is represented as a Prolog 'term' which has the form
- functor(arg1,arg2,...,argN)
where N is called the 'arity' of the term.
Every top-level object is terminated with a period immediately
after the term specifying the object.
Another important construct is a Prolog 'list' which has
the following form:
- [term1,term2,...,termK]
where K is the length of the list (which can be 0). Please note
that an argument in a term can be a list.
Finally, a line that begins with % is a comment and
variables in Prolog do not need to be declared. A name that begins with
either a capitalized letter or a underscore character is a variable.
File Version...
The first line in a tgif file is a comment that contains the version
information about the tgif that writes the file.
The second line (which is the first object) in a tgif file is a state
object (a term whose functor is state). The 2nd argument
of the state term is called the file version of the
file. Let's look at a sample file generated by tgif:
%TGIF 2.16-p12
state(0,32,300,0,0,0,16,1,3,1,1,0,0,3,0,1,1,'Times-Roman',
0,20,0,0,0,10,0,0,1,1,0,16,1,0,1,1,1,1,1089,1407).
%
% @(#)$Header: /mm2/home/william/cvs/bc-src/tgif/httpd/faq/RCS/format.html,v 1.5 2022/03/16 23:09:34 william Exp william $
% %W%
%
page(1,"").
text('blue',96,64,'Times-Roman',0,20,1,1,0,1,94,22,2,0,18,4,0,0,0,0,[
"Hello World"]).
(Actually, there's no wrap-around in the state line. It's wrapped
around here so it's easier to read.)
The file version is 32. There are 3 top-level objects (including the
state object) in the file above. You can tell that they are top-level
objects because if you match the paranthesis immediately follow either
the name state, page, or text, the
closing paranthesis is immediately followed by a period.
Text Object Example...
Let's see how you can parse the text object using the information
in "tgif.pl".
First, find the section in "tgif.pl" with clauses that start with
tgif_text. The clauses that contain the string "FileVersion"
are relevant. You will see that the first such clause contains the
following line:
FileVersion =< 2, !,
This means, use this clause for file versions 1 and 2.
And the second such clause contains:
FileVersion =< 6, !,
This means, use this clause for file versions 3 through 6; etc.
For file version 32, you will find a clause that contains the
following line:
FileVersion =< 32, !,
In this case, this clause is for file version 30 through 32.
And it looks like the following:
tgif_text(Obj,Parms) :-
current_predicate(tgif_file_version,tgif_file_version(_)),
tgif_file_version(FileVersion),
FileVersion =< 32, !,
% From version 30 on, the FontSize is the actual size;
% the TextSize in older versions is a size index.
( var(Obj) -> OutputObj = true ; OutputObj = false ),
Obj = text(_Color,_X,_Y,_FontName,_TextStyle,_FontSize,_NumLines,
_TextJust,_TextRotate,_PenPat,_BBoxW,_BBoxH,_Id,0,_Asc,_Des,
_ObjFill,_VSpace,_Rotation,_Locked,StrList),
tgif_chk_output(OutputObj,Obj),
Parms = [color=_Color,x=_X,y=_Y,font_name=_FontName,
text_style=_TextStyle,font_size=_FontSize,num_lines=_NumLines,
text_just=_TextJust,text_rotate=_TextRotate,pen_pat=_PenPat,
bbox_w=_BBoxW,bbox_h=_BBoxH,id=_Id,asc=_Asc,des=_Des,
obj_fill=_ObjFill,v_space=_VSpace,rotation=_Rotation,
obj_locked=_Locked,strs=StrList],
tgif_strs(StrList).
The most important part of the above clause is:
Obj = text(_Color,_X,_Y,_FontName,_TextStyle,_FontSize,_NumLines,
_TextJust,_TextRotate,_PenPat,_BBoxW,_BBoxH,_Id,0,_Asc,_Des,
_ObjFill,_VSpace,_Rotation,_Locked,StrList),
This is what you need to use to match against a text object in a tgif file.
Recall from the above example:
text('blue',96,64,'Times-Roman',0,20,1,1,0,1,94,22,2,0,18,4,0,0,0,0,[
"Hello World"]).
It's not hard to see that _Color matches 'blue',
_X matches 96,
_Y matches 64,
_FontName matches 'Times-Roman', ..., and finally,
StrList matches ["Hello World"].
In this example, ["Hello World"] is a list contain a single
term which is a string. (In Prolog, a string is a list of characters,
but let's not get into that.)
Tabs and Line Breaks in a Tgif File...
In the above example, ["Hello World"] is broken up in the
tgif file. the [ is followed by a line break and
"Hello World"] is preceeded with a character. It's
very important to note that the line break and the character
are significant to the tgif parser (although they are
ignored by a Prolog parser). The rules for them are somewhat difficult
to explain. If you are generating a tgif file
(either by hand or by code), please experiment with tgif with the
objects you are trying to generate. Save the file and look at the
file with a text editor and try to match the line breaks and tabs.
And of couse, test it with tgif and check for missing objects after
you've created your own tgif file.