Tgif Home
----
About Tgif
Current Release & Download
FAQ
Copyright Info
A Screendump of Tgif
Release History
Tools That Tgif Uses
Tools That Work with Tgif
Author of Tgif
Miscellaneous Info
----
 
Return to Tgif's Home Page
William Chia-Wei Cheng
(bill.cheng@acm.org)
 

Tgif FAQ - Tgif File Format

(Polish version of this page)
 
Is the specification of tgif's obj/sym file format published anywhere?
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.4 2014/11/12 05:25:47 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 relavent. 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 cause 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.