root/paper-tape-project/trunk/schriften/font_files.htm

Revision 23, 12.4 kB (checked in by sven, 3 years ago)

Documentation:

* documentation/index.php: New small wrapper system that puts any

HTM file in this reposity in a small homepage

* README.txt => README.htm conversion in most of the subprojects

-- Sven @ workstation

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