source: projects/schriften/FONT_FILES.txt @ 13

Last change on this file since 13 was 13, checked in by sven, 11 years ago

Greatly improved the papertapefont algorithms and routines. Now even tested.
Everything compiles with "-Wall -O2" and is, of course, very performant :-)

Added detailed documentation in FONT_FILES.txt.

-- Sven @ dual head workstation

File size: 11.9 KB
Line 
1
2  The Paper Tape Project -- Paper Tape Font files
3  ===============================================
4
5I have developed a portable and easy to use ASCII storage format
6for paper tape fonts. While paper tape fonts were formerly
7implemented as (perl) scripts, with C (and C++) that's no more
8practical, because setting up big nested hashes is not really
9possible. Apart from that, it would not be a good style to set
10up a giant header file with so much static data.
11
12I have considered using popular and approved data formats like
13XML or Jason instead of a "proprietary" new, perhaps even binary
14data format. On the one hand, using XML would have been really
15portable, but also very unhandy, because I would have to look
16for XML processors for Windows, and compiling would be get
17complex and even more complex.
18
19Therefore I've decided in favor of simple ASCII files with some
20not very strict layout. It's really obvious how it works:
21
22|***.***  |a   You can write texts almost everywhere in the file,
23|   .*  * |a   just the very first letters, which actually
24|***.***  |a   *look* like a papertape (direction of movement, of
25|   .     |    course, from top down), define the bytes from
26|***.*****|e   that the letters are made up, which stand directly
27|*  .*   *|e   next to the paper tape.
28|*  .*   *|e   Yes, that's it! This file is a complete papertape
29|*  .    *|e   font file, containing (until now) the letters a and e.
30
31
32  Specification of Paper Tape files
33  =================================
34
35This is a typical paper tape file:
36
37---- Start of example file ----
38The Paper Tape Project -- PAPERTAPE_FONT file.
39The content of this file describes a paper tape font...
40See this small key how the document is structured:
41 bits     |identification
42 123.45678|char/string
43|   .     |
44|+++.+++++|m
45|   .   + |m
46|   .  +  |m    this is a comment.
47|   .   + |m
48|+++.+++++|m
49|+  .    +|I
50|+++.+++++|I
51|+  .    +|I
52|   .     |
53|   .     |
54|   .     |
55|   .     |
56|+++.+++++|0
57  Comments can be typed
58right anywhere, everything that doesn't look like
59a paper tape on the right place, is ignored.
60  |+  .   ++| <- even this one.
61|+  .    +|0
62|+++.+++++|0
63|   .     |
64|   .     | =white_space    this is a comment, too.
65|   .     | =white_space
66|   .     |
67
68----  End of example file  ----
69
70As you see, paper tape files are quite funny ASCII files. Here are the
71rules you have to observe:
72
73 * All lines are ignored, if there's not a papertape border in the
74   very first position. The papertape border is defined as
75   the pipe character, "|".
76
77 * The papertape "flows" from top to down, like western european
78   people write. The bit positions are also from left to right, like
79   a real paper tape looks like, including the feed hole between
80   bit 3 and 4. Therefore, as the key says, you read a paper tape byte
81   like that:
82
83        |123.45678| <- bit positions
84        |012.34567| <- how computers count the bits
85   e.g. | * . ** *| -> byte value = 2^1 + 2^4 + 2^5 + 2^7 = 178 = 0xbd
86
87 * It's up to you which character you use for indicating an hole
88   (logical 1). The only limitation is, that a logical 0 (not holed)
89   MUST be an white space (no tab! Only the whitespace character).
90   So all these bytes have the equal values:
91        |+ +.++ ++|
92        |h e.ll oo|
93        |# #.## ##|
94        || |.|| ||| (not recommended ;-) )
95        |( ).() ()| (also not recommendable)
96        |* *.** **|
97
98 * To allocate a byte to a character, you write that character directly
99   after the papertape,
100     like this:         | * . ** *|r
101     but not like this: |  *.* ***| w
102   That character is called the "ASCII identifier", because it shall be
103   ASCII (8bit). You can write comments right after the identifier,
104   because everything afterwards will be ignored.
105
106 * There are three cases of bytes:
107    * the normal byte        |***.*****|p
108      that belongs to an     |   .*   *|p
109      ASCII character:       |   . *** |p
110    * bytes which have no    |   .     |
111      identifier at all      |   .     |
112      They are ignored.      |   .     |
113    * bytes that belong to   |** . ****| special_character
114      special characters.    |  *.*    | special_character
115   We give attention to special characters later.
116
117 * Typically your paper tape letters span across multiple bytes. In
118   Paper Tape files, you write next to *every* byte the character where
119   it belongs to. This is read afterwards from up to down, like the
120   virtual paper tape direction is:
121       |***.*****|p
122       |   .*   *|p
123       |   . *** |p
124       |   .     |   <- this line doesn't belong to p any more.
125   Don't mix up with letters. Compare these examples:
126       |***.*****|p                  |***.*****|p
127       |   .*   *|p                  |   .*   *|p
128       |   . *** |p                  |   . *** |p
129       |   .     |                   |   .     |
130       |   .    *|y                  |   .    *|y
131       |   .   * |y                  |   .   * |p
132       |   .***  |y                  |   .***  |y
133       |   .   * |y                  |   .   * |y
134       |   .    *|y                  |   .    *|y
135   The typo at the right ("p" instead of "y") will overwrite the
136   defined paper tape letter "p" above, because letters will always
137   be read as blocks. Furthermore the first "y" line is overwritten,
138   too, by the later 3 "y" lines. That is, due to the typo error, all
139   previous definitions of "p" and "y" before are thrown away.
140   Compare also these examples:
141       |***.*****|p                  |***.*****|p
142       |   .*   *|p                  |   .*   *|p
143       this does nothing.            |   .     |
144       |   . *** |p                  |   . *** |p
145       |   .     |                   |   .     |
146   While the comment line on the left hand example is simply ignored,
147   the white space byte on the right hand side is parsed and therefore
148   the "p" value destroyed, like in the "y" and "p" example above.
149
150 * Next to the normal ASCII characters, there are special characters.
151   Principally, they are treated like ordinary characters, but they
152   are not identified with an ASCII value, but with a full name:
153       |***.*****|p
154       |   .*   *|p  This is an ordinary ASCII character
155       |   . *** |p
156       |   .     |
157       |   .     | =white_space    This is typically used to define
158       |   .     | =white_space    how white_spaces have to look
159       |   .     | =white_space    like. They typically contain
160       |   .     |                 only NULL bytes, of course ;-)
161       |   .     |
162       |   .     | =char_spacing   And this defines how much space
163       |   .     |                 is packed between characters.
164       |   .     |                 Typically one NULL byte.
165       |   .     |
166       |  *.*  * | =secret_file
167       |*  .* ** | =secret_file    The name of a special character
168       | **.* ** | =secret_file    may not contain whitespaces.
169       |* *. *** | =secret_file    Thereby normal text/comments
170       |   .**** | =secret_file    can be written next to "special
171       |   .  *  | =secret_file    character" bytes just like next
172       | * . *** | =secret_file    to ordinary bytes.
173       |***.* ** | =secret_file
174       |** .  ** | =secret_file    After all, the same limitiations
175       |** .* ** | =secret_file    exist like for normal multiple
176       |** . *** | =secret_file    byte definitions: Don't break in
177       |*  .  *  | =secret_file    the flow, like
178       |   .     |                 <- here, because this would
179       | * .*    | =secret_file    truncate secret_file to <-this byte.
180
181 * Take care that the papertapefont implementation can also write
182   paper tape font files. If the utility program is called to change
183   one character in your font file, it will read in (and parse) the
184   font file and write back the parsed files (including the changes,
185   of course). In this process, *ALL* your comments are *LOST*.
186   The implementation cannot take care of your comments, this would
187   be too complex.
188   So if your font file is well commented, don't let the implementation
189   write to it.
190
191
192
193  Specification of the papertapefont.h library
194  ============================================
195
196  I've developed a tiny stand alone C library which does not need
197  auxillary libraries like Glib and which will compile at windows,
198  too. It's quite simple to use that library. At first, there even
199  exists a command line interface that implements most of the
200  features. But here's how to use the C functions:
201
202  The main "object like" structure is the PAPERTAPE_FONT structure.
203  It can be built directly by parsing an already opened file:
204
205    #include <stdio.h>
206    #include "papertapefont.h"
207
208    FILE* font_file = fopen("/path/to/your/font.file", "r");
209    PAPERTAPE_FONT* font = papertape_font_new_from_file(font_file);
210
211  Now the file has been parsed and every available letter is stored
212  in RAM. So you can directly go and generate labels:
213
214    int label_size;
215    byte_t* label_bytes;
216
217    label_bytes = papertape_font_get_label(font,
218                  "Hello World!", &label_size);
219
220    // further use, e.g. with LOCHSTREIFEN*:
221    LOCHSTREIFEN* papertape = lochstreifen_new();
222    lochstreifen_set_data(label_bytes, label_size);
223
224  Of course you can check if your string can be fully generated, too:
225
226    if(! papertape_font_string_is_printable(font, "{H4x05]!")) {
227        printf("Sorry dude, the current font is not"
228               "script kiddie compatible.\n");
229    }
230
231  And after all, changing the papertape is fully implemented:
232
233    bytes_t* user_generated;
234    int len;
235
236    let_user_generate_letter("Please make an 'A'",
237      &user_generated, &len);
238
239    papertape_font_set_char(font, 'A', user_generated, len);
240
241  This will change the letter immediately. So the following output
242  will give out "ABBA" on the papertape at the end (and not "ABAB"):
243
244    bytes_t* output, buf_for_a, buf_for_b;
245    int      o_len,  a_len,     b_len;
246
247    // print out "ab" on papertape
248    output = papertape_font_get_label(font, "ab", &o_len);
249    send_to_papertape_puncher(output, o_len);
250
251    // flip a and b
252    buf_for_a = papertape_font_get_label(font, "a", &a_len);
253    buf_for_b = papertape_font_get_label(font, "b", &b_len);
254    papertape_font_set_char(font, 'B', buf_for_a, a_len);
255    papertape_font_set_char(font, 'A', buf_for_b, b_len);
256
257    // print out "ab" on papertape...
258    output = papertape_font_get_label(font, "ab", &o_len);
259    send_to_papertape_puncher(output, o_len);
260
261  If you feel destructive, you can also delete characters:
262
263    // clean up all the mess by deleting everything!!111
264    papertape_font_del_char(font, 'a');
265    papertape_font_del_char(font, 'b');
266    if(!papertape_font_del_char(font, 'b'))
267        printf("There is no more 'b'. Of course!");
268    output = papertape_font_get_label(font, "abba", &len);
269    // this will give out 4 errors at stderr, because
270    // no character can be generated.
271
272  At last, after messing around you can save the whole changed
273  thing (back) to a file.
274
275    FILE* target = fopen("/existing/or/new.font.txt", "w");
276    papertape_font_write_to_file(font, target);
277
278  Be aware that the following example will stripe out *ALL*
279  comments out of your font file:
280
281    FILE* needs_cleanup = fopen("font.txt", "r+");
282    PAPERTAPE_FONT* font = papertape_font_new_from_file(needs_cleanup);
283    papertape_font_write_to_file(font, needs_cleanup);
284
285  In the end, an issue that is a bit more complicated: Special
286  characters. This includes white spaces, letter spacing, etc.
287  The names for these special characters are noted in the
288  papertapefont.h header file, so you can access them directly,
289  too, if you want:
290
291    byte_t *white = calloc(sizeof(byte_t), 100);
292    papertape_font_set_special(font, PAPERTAPE_FONT_SPACE_NAME,
293      white, 100);
294    // about 1k of bytes:
295    papertape_font_get_label(font, "A fairly long text ! ! ! ", &somewhere)
296    // deletion sets the space to some kind of default value
297    papertape_font_del_special(font, PAPERTAPE_FONT_SPACE_NAME);
298    // so this is quite short:
299    papertape_font_get_label(font, "  s h o r t  ", &somewhere);
300
301  I think that's all, for the moment. Happy coding :-)
302
303
304  -- Sven Köppel, 04.09.2008
Note: See TracBrowser for help on using the repository browser.
© 2008 - 2013 technikum29 • Sven Köppel • Some rights reserved
Powered by Trac
Expect where otherwise noted, content on this site is licensed under a Creative Commons 3.0 License