File: splinefont.html

package info (click to toggle)
fontforge-doc 20120731.b-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 7,536 kB
  • ctags: 1,461
  • sloc: makefile: 2
file content (873 lines) | stat: -rw-r--r-- 38,083 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
<HTML>
<HEAD>
  <!-- Created with AOLpress/2.0 -->
  <!-- AP: Created on: 11-Feb-2001 -->
  <!-- AP: Last modified: 29-Jun-2005 -->
  <TITLE>The basic spline data structures of FontForge</TITLE>
  <LINK REL="icon" href="fftype16.png">
  <LINK REL="stylesheet" TYPE="text/css" HREF="FontForge.css">
</HEAD>
<BODY>
<DIV id="in">
<H2>
  Data Types
</H2>
<P>
This describes two different types of fonts, a SplineFont (which is a postscript
or truetype font) and a BDFFont (bitmap font, essentially a bdf file). There
are some similarities between the two data structures, each is basically
an array (possibly with holes in it) of characters. Each font also contains
information like the fontname.
<P>
The <A HREF="#SplineFont">SplineFont</A> consists of a bunch of
<A HREF="#SplineChar">SplineChars</A>, each containing four layers,
<UL>
  <LI>
    A foreground layer which contains all the interesting stuff that gets put
    into the final font
    <UL>
      <LI>
	a series of paths (called <A HREF="#SplinePointList">SplineSet</A>s or
	<A HREF="#SplinePointList">SplinePointList</A> sorry, I gave the data structure
	two different names)
      <LI>
	a series of references to other characters (called
	<A HREF="#RefChar">RefChar</A>s)
      <LI>
	a width
      <LI>
	<A HREF="#Undoes">undoes</A>
    </UL>
  <LI>
    A background layer (which is used to allow people to trace images of characters)
    and can contain
    <UL>
      <LI>
	a series of <A HREF="#SplinePointList">SplineSet</A>s
      <LI>
	A series of <A HREF="#ImageList">images</A>
      <LI>
	<A HREF="#Undoes">undoes</A>
    </UL>
  <LI>
    A grid layer, which is shared by all the characters in a font and in which
    you can put lines to indicate the Cap Height, X Height, etc. Actually you
    can put anything there but those are the obviously useful things. It will
    be seen in all characters. It contains
    <UL>
      <LI>
	A series of <A HREF="#SplinePointList">SplineSet</A>s
      <LI>
	<A HREF="#Undoes">undoes</A>
    </UL>
  <LI>
    A hint layer, whose format is completely different from anything else and
    consists of horizontal and vertical hints, which in turn are just a starting
    location and a width (indicating the stem. The width can be negative.)
    <UL>
      <LI>
	A set of <A HREF="#Hints">hints</A>. Hints need the special tools from the
	hint menu for editing them.
      <LI>
	<STRONG>!!!! I do not have a way of undoing hint operations !!!!</STRONG>
    </UL>
</UL>
<P>
In multilayered mode there can be many foreground layers which can be stroked
or filled. Bitmap images may also be included.
<P>
Every SplineChar has a name associated with it, a unicode encoding and a
its original position in the font.
<P>
A SplineSet consists of a start point and an end point, and whatever splines
connect them. The start point and the end point may be the same, this either
indicates a closed path, or a degenerate path with only one point on it.
<P>
A SplinePoint contains an x,y location of the point, and the locations of
the two control points associated with that point. A control point may be
coincident with the main point. SplinePoints may connect to two splines,
a previous Spline and a next Spline. A Spline contains pointers to two
SplinePoints (a start and an end point) it also contains the parameters of
the B&eacute;zier curve that those two points describe (x = a*t^3+b*t^2+c*t+d,
y=ditto). Splines are straight lines if the two control points that are
meaningful to that spline are coincident with their respective SplinePoints.
A spline contains a bit indicating whether it is order2 (truetype quadratic
format) or order3 (postscript cubic format). If it is quadratic there is
really only one control point, ff uses the convention that the control points
on the start and end SplinePoints have the same location.
<P>
A font's encoding is stored in a separate data structure called an EncMap.
This structure controls what glyph goes where and also contains a pointer
to an Encoding structure which provides a name for the encoding. The EncMap
contains two arrays, the <CODE>map</CODE> and the <CODE>backmap</CODE>. The
map is indexed by the character's encoding and provides the position (in
the associated splinefont's glyph list) of the associated glyph. The backmap
provides the reverse mapping, it is indexed by a glyph's position in the
splinefont and provides an encoding for that glyph. (Note: the map array
may map several encodings to one glyph, the backmap will only indicate one
of those.)
<P>
A <A HREF="#BDFFont">BDFFont</A> is always associated with a (possibly empty)
SplineFont and its EncMap, it consists of an array of
<A HREF="#BDFChar">BDFChars</A>, each containing
<UL>
  <LI>
    a bitmap
  <LI>
    possibly a floating selection
  <LI>
    a name
  <LI>
    <A HREF="#Undoes">undoes</A>
  <LI>
    A pointer to the <A HREF="#SplineChar">SplineChar</A> with which it is associated
</UL>
<P>
The array is ordered the same way the SplineFont's array is ordered, and
the same EncMap can be used for both.
<BLOCKQUOTE>
  <PRE>/* Copyright (C) 2000-2003 by George Williams */
/*
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.

 * The name of the author may not be used to endorse or promote products
 * derived from this software without specific prior written permission.

 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
#ifndef _SPLINEFONT_H
#define _SPLINEFONT_H

#include "basics.h"
#include "charset.h"

enum <A NAME="linejoin">linejoin</A> {
    lj_miter,		/* Extend lines until they meet */
    lj_round,		/* circle centered at the join of expand radius */
    lj_bevel		/* Straight line between the ends of next and prev */
};
enum <A NAME="linecap">linecap</A> {
    lc_butt,		/* equiv to lj_bevel, straight line extends from one side to other */
    lc_round,		/* semi-circle */
    lc_square		/* Extend lines by radius, then join them */
};

typedef struct strokeinfo {
    double radius;
    enum linejoin join;
    enum linecap cap;
    unsigned int calligraphic: 1;
    double penangle;
    double thickness;			/* doesn't work */
} <A NAME="StrokeInfo">StrokeInfo</A>;
</PRE>
</BLOCKQUOTE>
<P>
The above data structure is used by the ExpandStroke routines which will
turn a path into a filled shape. The information above provides the various
controls for those routines. They mean essentially what you expect them to
me in postscript.
<BLOCKQUOTE>
  <PRE>typedef struct ipoint {
    int x;
    int y;
} <A NAME="IPoint">IPoint</A>;
</PRE>
</BLOCKQUOTE>
<P>
An integer point.
<BLOCKQUOTE>
  <PRE>typedef struct basepoint {
    double x;
    double y;
} <A NAME="BasePoint">BasePoint</A>;
</PRE>
</BLOCKQUOTE>
<P>
A double point. This provides the location of
<A HREF="#SplinePoint">SplinePoints</A> and their control points.
<BLOCKQUOTE>
  <PRE>typedef struct tpoint {
    double x;
    double y;
    double t;
} <A NAME="TPoint">TPoint</A>;
</PRE>
</BLOCKQUOTE>
<P>
A double point with a "t" value. Indicates where that location occurs on
a spline. (the start point itself is a t=0, the end point at t=1, intermediate
points have intermediate values). Used when trying to approximate new splines.
<BLOCKQUOTE>
  <PRE>typedef struct dbounds {
    double minx, maxx;
    double miny, maxy;
} DBounds;
</PRE>
</BLOCKQUOTE>
<P>
The bounding box of a <A HREF="#Spline">Spline</A>,
<A HREF="#SplineChar">SplineChar</A>, <A HREF="#RefChar">RefChar</A>,
<A HREF="#ImageList">Image</A>, or whatever else needs a bounding box.
<BLOCKQUOTE>
  <PRE>typedef struct bdffloat {
    int16 xmin,xmax,ymin,ymax;
    int16 bytes_per_line;
    uint8 *bitmap;
} <A NAME="BDFFloat">BDFFloat</A>;
</PRE>
</BLOCKQUOTE>
<P>
The floating selection in a <A HREF="#BDFChar">BDFChar</A>.
<BLOCKQUOTE>
  <PRE>typedef struct undoes {
    struct undoes *next;
    enum undotype { ut_none=0, ut_state, ut_tstate, ut_width,
	    ut_bitmap, ut_bitmapsel, ut_composite, ut_multiple } undotype;
    union {
	struct {
	    int16 width;
	    int16 lbearingchange;
	    <A HREF="#SplinePointList">struct splinepointlist</A> *splines;
	    <A HREF="#RefChar">struct refchar</A> *refs;
	    <A HREF="#ImageList">struct imagelist</A> *images;
	} state;
	int width;
	struct {
	    /*int16 width;*/	/* width should be controlled by postscript */
	    int16 xmin,xmax,ymin,ymax;
	    int16 bytes_per_line;
	    uint8 *bitmap;
	    <A HREF="#BDFFloat">BDFFloat</A> *selection;
	    int pixelsize;
	} bmpstate;
	struct {		/* copy contains an outline state and a set of bitmap states */
	    struct undoes *state;
	    struct undoes *bitmaps;
	} composite;
	struct {
	    struct undoes *mult; /* copy contains several sub copies (composites, or states or widths or...) */
	} multiple;
    uint8 *bitmap;
    } u;
} <A NAME="Undoes">Undoes</A>;
</PRE>
</BLOCKQUOTE>
<P>
The undo data structure. Used by both <A HREF="#SplineChar">SplineChar</A>
and <A HREF="#BDFChar">BDFChar</A>. Also used to contain the local clipboard.
Every character layer has several Undoes (up to about 10 or so, it's
configurable) that allow it to go back several operations, these are linked
together on the next field (redos are handled similarly, of course).
<P>
Undoes come in several types, ut_none is only used by the clipboard when
it is empty.
<P>
ut_state is used by SplineChars and it contains a dump of the current state
of one layer of the character. Obviously things could be optimized a great
deal here, but this is easy. ut_tstate has the same data structure as ut_state,
it is used during transformations and is just a flag that tells the display
to draw the original as well as the currently transformed thing (so you can
see what you've done).
<P>
ut_state is also used by the clipboard when copying a SplineChar or a piece
of a SplineChar.
<P>
ut_width is used by SplineChars when the width (and nothing else) changes.
<P>
ut_bitmap is used by BDFChars and is a dump of the current state of the bitmap.
Again there is room for optimization here, but this is easy.
<P>
ut_bitmapsel is used when doing a copy of a BDFChar. If there is a selection
it (and it alone) gets copied into the selection field of the bmpstate structure.
If there is no selection the entire bitmap is converted into a
<A HREF="#BDFFloat">floating selection</A> and copied into the selection
field.
<P>
ut_composite is used when doing a copy from the
<A HREF="views.html#FontView">FontView</A> where you are copying both the
splines and the bitmaps of a character.
<P>
ut_mult is used when doing a copy from the FontView where you are copying
more than one character.
<BLOCKQUOTE>
  <PRE>typedef struct bdfchar {
    <A HREF="#SplineChar">struct splinechar</A> *sc;
    int16 xmin,xmax,ymin,ymax;
    int16 width;
    int16 bytes_per_line;
    uint8 *bitmap;
    int orig_pos;
    <A HREF="views.html#BitmapView">struct bitmapview</A> *views;
    <A HREF="#Undoes">Undoes</A> *undoes;
    <A HREF="#Undoes">Undoes</A> *redoes;
    unsigned int changed: 1;
    unsigned int byte_data: 1;		/* for anti-aliased chars entries are grey-scale bytes not bw bits */
    <A HREF="#BDFFloat">BDFFloat</A> *selection;
} <A NAME="BDFChar">BDFChar</A>;
</PRE>
</BLOCKQUOTE>
<P>
The basic bitmap character structure. There's a link to the SplineChar used
to create the bitmap. Then the bounding box of the bitmap, the character's
width (in pixels of course), the number of bytes per row of the bitmap array,
a pointer to an array containing the bitmap. The bitmap is stored with 8bits
packed into a byte, the high order bit is left most. Every row begins on
a new byte boundary. There are (xmax-xmin+1) bits in each row and (xmax-xmin+8)/8
bytes in each row. There are (ymax-ymin+1) rows. A bit-value of 1 means there
bit should be drawn, 0 means it is transparent. Then the encoding in the
current font. A linked list of BitmapView structures all of which look at
this bitmap (so any changes to this bitmap need to cause a redraw in all
views). A set of undoes and redoes. A flag indicating whether the thing has
been changed since it was last saved to disk.
<P>
Up to this point I've been talking about bitmaps. It is also possible to
have a bytemap. The data structure is exactly the same, except that each
pixel is represented by a byte rather than a bit. There is a clut for this
in the BDFFont (it's the same for every character), but basically
0=&gt;transparent, (2^n-1) =&gt;fully drawn, other values are shades of grey
between. Can handle depths of 1,2,4 and 8 bits/pixel.
<P>
The last thing in the BDFChar is a (/an optional) floating selection. Only
present if the user has made a selection or done a paste or something like
that.
<BLOCKQUOTE>
  <PRE>typedef struct bdffont {
    <A HREF="#SplineFont">struct splinefont</A> *sf;
    int glyphcnt;
    <A HREF="#BDFChar">BDFChar</A> **glyphs;		/* an array of charcnt entries */
    int pixelsize;
    int ascent, descent;
    struct bdffont *next;
    struct clut *clut;		/* Only for anti-aliased fonts */
} <A NAME="BDFFont">BDFFont</A>;
</PRE>
</BLOCKQUOTE>
<P>
The basic bitmap font. Contains a reference to the
<A HREF="#SplineFont">SplineFont</A> to which it is attached. Then a size
and an array of BDFChars (note there may be NULL entries in the array if
no character is defined for that encoding). Then a temporary array which
is used in one set of routines while reencoding the font. The pixelsize of
the em-square. The ascent and descent (in pixels), these should sum to the
em-square. A character set which will match that in the SplineFont. A pointer
to the next bitmap font associated with this SplineFont.
<P>
If we are dealing with a byte font, then there will also be a clut. This
contains a count of the number of entries in the array, and then the array
itself. Currently the number of entries here is always 16, but that could
change.
<BLOCKQUOTE>
  <PRE>enum pointtype { pt_curve, pt_corner, pt_tangent };
typedef struct splinepoint {
    <A HREF="#BasePoint">BasePoint</A> me;
    <A HREF="#BasePoint">BasePoint</A> nextcp;		/* control point */
    <A HREF="#BasePoint">BasePoint</A> prevcp;		/* control point */
    unsigned int nonextcp:1;
    unsigned int noprevcp:1;
    unsigned int nextcpdef:1;
    unsigned int prevcpdef:1;
    unsigned int selected:1;	/* for UI */
    unsigned int pointtype:2;
    unsigned int isintersection: 1;
    uint16 flex;		/* This is a flex serif have to go through icky flex output */
    <A HREF="#Spline">struct spline</A> *next;
    <A HREF="#Spline">struct spline</A> *prev;
} <A NAME="SplinePoint">SplinePoint</A>;
</PRE>
</BLOCKQUOTE>
<P>
A SplinePoint is located at the position specified by "me". The control point
associated with the next <A HREF="#Spline">Spline</A> is positioned at nextcp,
while that associated with the previous Spline is at prevcp. Then there are
a couple of flags that simplify tests. If the nextcp is degenerate (ie. at
the same place as me) then nonextcp is set, similarly for prevcp. If the
user has not touched the control points then they will have their default
values, and when the user moves the point around fontforge will update the
control points appropriately, if they do not have default values then fontforge
will only offset them.
<P>
If the point is selected then that bit will be set.
<P>
Every point is classified as a curve point, a corner point and a tangent
point.
<P>
The isintersection bit is used internally to the SplineOverlap routines.
The flex value is for flex hints. It is read in from a type1 font and then
ignored. Someday I may use it.
<P>
Finally we have pointers to the two Splines than connect to this point.
<BLOCKQUOTE>
  <PRE>typedef struct linelist {
    IPoint here;
    struct linelist *next;
} <A NAME="LineList">LineList</A>;

typedef struct linearapprox {
    double scale;
    unsigned int oneline: 1;
    unsigned int onepoint: 1;
    struct linelist *lines;
    struct linearapprox *next;
} <A NAME="LinearApprox">LinearApprox</A>;
</PRE>
</BLOCKQUOTE>
<P>
These are the lines used to approximate a <A HREF="#Spline">Spline</A> when
drawing it. They are cached so they don't need to be regenerated each time.
There's a different set of lines for every scale (as there is a different
amount of visible detail). They get freed and regenerated if the Spline changes.
<BLOCKQUOTE>
  <PRE>typedef struct spline1d {
    double a, b, c, d;
} <A NAME="Spline1D">Spline1D</A>;

typedef struct spline {
    unsigned int islinear: 1;
    unsigned int isticked: 1;
    unsigned int isneeded: 1;
    unsigned int isunneeded: 1;
    unsigned int ishorvert: 1;
    unsigned int order2: 1;
    <A HREF="#SplinePoint">SplinePoint</A> *from, *to;
    <A HREF="#Spline1D">Spline1D</A> splines[2];		/* splines[0] is the x spline, splines[1] is y */
    <A HREF="#LinearApprox">struct linearapprox</A> *approx;
    /* Possible optimizations:
	Precalculate bounding box
	Precalculate points of inflection
    */
} <A NAME="Spline">Spline</A>;
</PRE>
</BLOCKQUOTE>
<P>
A spline runs from the <CODE>from</CODE>
<A HREF="#SplinePoint">SplinePoint</A> to the <CODE>to</CODE> SplinePoint.
If both control points of a Spline are degenerate, then the Spline is linear
(actually there are some other case that will lead to linear splines, sometimes
these will be detected and turned into the canonical case, other times they
will not be). The remaining bits are used when processing Splines in various
functions. Most are used in the SplineOverlap routines, but some are used
in other places too.
<P>
The Spline1D structures give the equations for the x and y coordinates
respectively (splines[0] is for x, splines[1] is for y).
<BLOCKQUOTE>
  <PRE>typedef struct splinepointlist {
    <A HREF="#SplinePoint">SplinePoint</A> *first, *last;
    struct splinepointlist *next;
} <A NAME="SplinePointList">SplinePointList</A>, <A NAME="SplineSet">SplineSet</A>;
</PRE>
</BLOCKQUOTE>
<P>
A SplinePointList (or a SplineSet) is a collection of
<A HREF="#Spline">Spline</A>s and <A HREF="#SplinePoint">SplinePoint</A>s.
Every SplinePoint can connect to two Splines (next and prev). Every Spline
connects to two SplinePoints (from and to). A SplinePointList is a connected
path. There are three cases:
<UL>
  <LI>
    <CODE>first != last</CODE> which means that we have an open path. Here
    first-&gt;prev==NULL and last-&gt;next==NULL.
  <LI>
    <CODE>first == last</CODE> and <CODE>first-&gt;prev==NULL</CODE> which means
    we have a degenerate path consisting of a single point, and
    last-&gt;next==NULL as well
  <LI>
    <CODE>first == last</CODE> and <CODE>first-&gt;prev!=NULL</CODE> which means
    we have a closed path. This should be the most common case.
</UL>
<P>
Generally a series of paths will make up a character, and they are linked
together on the next field.
<BLOCKQUOTE>
  <PRE>typedef struct refchar {
    int16 adobe_enc, orig_pos
    int unicode_enc;		/* used by paste */
    double transform[6];	/* transformation matrix (first 2 rows of a 3x3 matrix, missing row is 0,0,1) */
    <A HREF="#SplinePointList">SplinePointList</A> *splines;
    struct refchar *next;
    unsigned int checked: 1;
    unsigned int selected: 1;
    <A HREF="#DBounds">DBounds</A> bb;
    <A HREF="#SplineChar">struct splinechar</A> *sc;
} <A NAME="RefChar">RefChar</A>;
</PRE>
</BLOCKQUOTE>
<P>
A <A HREF="#SplineChar">SplineChar</A> may contain a reference to another
character. For instance "Agrave" might contain a reference to an "A" and
a "grave". There are three different encoding values, of which orig_pos is
not always up to date. Adobe_enc gives the location in the Adobe Standard
Encoding which is used by the seac command in type1 fonts. If this is -1
then the character isn't in the adobe encoding and it won't be possible to
put a reference to it into a Type1 font (truetype doesn't have this restriction,
it has other ones). The transformation matrix is a standard postscript
transformation matrix (3 rows of 2 columns. First 2 rows provide standard
rotation/scaling/flipping/skewing/... transformations, last row provides
for translations. (Both postscript and truetype have restrictions on what
kinds of transformations are acceptable). The splines field provides a quick
way of drawing the referred character, it is the result of applying the
transformation matrix on all splines in the refered character. There may
be several referred characters and they are linked together on the next field.
The checked field is used to insure that we don't have any loops (ie. on
characters which refer to themselves). The selected field indicates that
the reference is selected. The bb field provides a transformed bounding box.
And the sc field points to the SplineChar we are referring to.
<BLOCKQUOTE>
  <PRE>typedef struct kernpair {
    struct splinechar *sc;
    int off;
    struct kernpair *next;
} <A NAME="KernPair">KernPair</A>;
</PRE>
</BLOCKQUOTE>
<P>
If a character should be kerned with another, then this structure provides
that info. Every SplineChar has a linked list of KernPairs attached to it.
In that list the sc field indicates the other character in the pair, and
off defines the offset between them (or rather the difference from what their
respective left and right bearings would lead you to believe it should be).
Next points to the next kernpair.
<BLOCKQUOTE>
  <PRE>typedef struct hints {
    double base, width;
    double b1, b2, e1, e2;
    double ab, ae;
    unsigned int adjustb: 1;
    unsigned int adjuste: 1;
    struct hints *next;
} <A NAME="Hints">Hints</A>;
</PRE>
</BLOCKQUOTE>
<P>
The only important fields here are base, width and next. The others are used
temporarily by the SplineFill routines. Base gives the location (in either
x or y space) of where the stem starts, and width is how long it is. Width
may be negative (in which case base is where the stem ends). Next points
to the next hint for the character.
<BLOCKQUOTE>
  <PRE>typedef struct imagelist {
    struct gimage *image;
    double xoff, yoff;		/* position in character space of upper left corner of image */
    double xscale, yscale;	/* scale to convert one pixel of image to one unit of character space */
    <A HREF="#DBounds">DBounds</A> bb;
    struct imagelist *next;
    unsigned int selected: 1;
} <A NAME="ImageList">ImageList</A>;
</PRE>
</BLOCKQUOTE>
<P>
SplineChars may have images in their backgrounds (or foregrounds for multilayer
characters). This structure contains a pointer to the image to be displayed,
an indication of where it should be positioned, and how it should be scaled
(I do not support any other transformations on images). The bounding box
is after the transformations have been applied. The next field points to
the next image, and selected indicates whether this one is selected or not.
<BLOCKQUOTE>
  <PRE>typedef struct splinechar {
    char *name;
    int enc, unicodeenc;
    int width;
    int16 lsidebearing;		/* only used when reading in a type1 font */
    int16 ttf_glyph;		/* only used when writing out a ttf font */
    <A HREF="#SplinePointList">SplinePointList</A> *splines;
    <A HREF="#Hints">Hints</A> *hstem;		/* hstem hints have a vertical offset but run horizontally */
    <A HREF="#Hints">Hints</A> *vstem;		/* vstem hints have a horizontal offset but run vertically */
    <A HREF="#RefChar">RefChar</A> *refs;
    <A HREF="views.html#CharView">struct charview</A> *views;	/* All CharViews that look at us */
    <A HREF="#SplineFont">struct splinefont</A> *parent;
    unsigned int changed: 1;
    unsigned int changedsincelasthhinted: 1;
    unsigned int changedsincelastvhinted: 1;
    unsigned int manualhints: 1;
    unsigned int ticked: 1;	/* For reference character processing */
    unsigned int changed_since_autosave: 1;
    unsigned int widthset: 1;	/* needed so an emspace char doesn't disappear */
    struct splinecharlist { struct splinechar *sc; struct splinecharlist *next;} *dependents;
	    /* The dependents list is a list of all characters which reference*/
	    /*  the current character directly */
    <A HREF="#SplinePointList">SplinePointList</A> *backgroundsplines;
    <A HREF="#ImageList">ImageList</A> *backimages;
    <A HREF="#Undoes">Undoes</A> *undoes[2];
    <A HREF="#Undoes">Undoes</A> *redoes[2];
    <A HREF="#KernPair">KernPair</A> *kerns;
    uint8 *origtype1;		/* The original type1 (unencoded) character string */
    int origlen;		/*  its length. These get freed once the user has changed */
				/*  the character. Until then the preserve things like */
				/*  hint substitution which we wouldn't otherwise understand */
} <A NAME="SplineChar">SplineChar</A>;
</PRE>
</BLOCKQUOTE>
<P>
Every character has a name (sometimes it is ".notdef" but it's there). A
location (encoding) in the current font, a unicode code point (which may
be -1 if not in unicode). Every character has a width. The next two fields
are only meaningful when loading or saving a font in the appropriate format.
lbearing is needed to handle seac commands, and the ttf_glyph is needed for
just about everything when writing a ttf font. The splines field gives all
the foreground paths (<A HREF="#SplinePointList">SplinePointLists</A>). Hints
for horizontal and vertical stems. A set of other characters referenced in
this one, again only in the foreground. Then a linked list of all
<A HREF="views.html#CharView">CharViews</A> displaying this SplineChar (if
this guy changes, all must be updated to reflect the change). A pointer to
the <A HREF="#SplineFont">SplineFont</A> that contains us. A set of bits:
changed means the character has changed since the last save to disk,
changedsincelasthhinted means that we need to run autohint on the horizontal
stems, changedsincelastvhinted for vertical stems. Manual hints means the
user has taken control of providing hints, and we should only run autohint
if explicitly asked to. Ticked is a temporary field usually to avoid infinite
loops of refered characters. changed_since_autosave indicates that the next
time we update our autosave database we should write this character to it.
Widthset means the user has changed the width. If we didn't have this bit
we might think that an em space had nothing in it (instead of having an em-space
in it).
<P>
If a SplineChar is refered to in another character, then when we change the
original we must also update anything that refers to it (if we change A,
we must also redisplay Agrave).
<P>
Then backgroundsplines represent the SplinePointLists in the background layer,
and backimages represent the images in the background layers.
<P>
Undoes[0] contains undoes for the foreground and undoes[1] contains undoes
for the background. Same for redoes.
<P>
Finally kerns provides a list of kerning data for any special characters
that follow this one. For instance the combination "VA" might need kerning,
then the SplineChar representing "V" would have a pointer to a
<A HREF="#KernPair">KernPair</A> with data on "A".
<BLOCKQUOTE>
  <PRE>typedef struct splinefont {
    char *fontname, *fullname, *familyname, *weight;
    char *copyright;
    char *filename;
    char *version;
    double italicangle, upos, uwidth;
    int ascent, descent;
    int glyphcnt;
    <A HREF="#SplineChar">SplineChar</A> **glyphs;
    unsigned int changed: 1;
    unsigned int changed_since_autosave: 1;
    unsigned int display_antialias: 1;
    unsigned int dotlesswarn: 1;		/* User warned that font doesn't have a dotless i character */
    /*unsigned int wasbinary: 1;*/
    <A HREF="views.html#FontView">struct fontview</A> *fv;
    enum charset encoding_name;
    <A HREF="#SplinePointList">SplinePointList</A> *gridsplines;
    <A HREF="#Undoes">Undoes</A> *gundoes, *gredoes;
    <A HREF="#BDFFont">BDFFont</A> *bitmaps;
    char *origname;		/* filename of font file (ie. if not an sfd) */
    char *autosavename;
    int display_size;
} <A NAME="SplineFont">SplineFont</A>;
</PRE>
</BLOCKQUOTE>
<P>
The first four names are taken straight out of PostScript, as are copyright,
version, italicangle, underlinepos, underlineweight. Ascent and descent together
sum to make the em-square. Normally this will be 1000, but you can change
that if you want.
<P>
Charcnt says how big the chars array will be. There may be holes (ie. NULL
values) in the array.
<P>
Changed indicates that some character, bitmap, metric, something has changed
since we last saved the file. changed_since_autosave means that something
has changed since autosave last happened (so we should actually process this
font the next time autosave rolls around).
<P>
Display_antialias means we are displaying an antialias bytemap font in the
<A HREF="views.html#FontView">FontView</A>, rather than a bitmap font. These
look better but are slower.
<P>
Dotlesswarn means that we've warned the user when s/he attempted to create
an accented character based on i or j and a dotless version of those characters
was not present in the font (there's no point in warning him again. The operation
proceeded with a dotted version).
<P>
There is only one <A HREF="views.html#FontView">FontView</A> associated with
a font (other data structures allowed for multiple views, but the font does
not).
<P>
The font has a characterset and an encoding.
<P>
Gridsplines contains the <A HREF="#SplinePointList">SplinePointLists</A>
for all the splines displayed as background grids for characters. And gundoes
and gredoes are the un/redoes associated with them.
<P>
Bitmaps contains all the bitmaps that have been generated for this SplineFont.
<P>
Origname contains the name of the file we read in to get this one. Filename
above contains the name of an .sfd file associated with this font, but origname
can also contain random postscript or truetype fonts.
<P>
Autosavename indicates the name currently being used to save crash recovery
stuff to disk.
<P>
Display_size indicates how big we'd like the FontView to display our font.
<H2>
  Function declarations
</H2>
<P>
<BLOCKQUOTE>
  <PRE>struct fontdict;		/* the next four data structures are in psfont.h */
struct chars;
struct findsel;
struct charprocs;
enum charset;			/* in charset.h */

extern SplineFont *SplineFontFromPSFont(struct fontdict *fd);
extern int SFOneWidth(SplineFont *sf);
extern struct chars *SplineFont2Chrs(SplineFont *sf, int round);
enum fontformat { ff_pfa, ff_pfb, ff_ptype3, ff_ptype0, ff_ttf, ff_none };
extern int WritePSFont(char *fontname,SplineFont *sf,enum fontformat format);
extern int WriteTTFFont(char *fontname,SplineFont *sf);
int SFReencodeFont(SplineFont *sf,enum charset new_map);

extern int DoubleNear(double a,double b);
extern int DoubleNearish(double a,double b);

extern void LineListFree(LineList *ll);
extern void LinearApproxFree(LinearApprox *la);
extern void SplineFree(Spline *spline);
extern void SplinePointFree(SplinePoint *sp);
extern void SplinePointListFree(SplinePointList *spl);
extern void SplinePointListsFree(SplinePointList *head);
extern void RefCharFree(RefChar *ref);
extern void RefCharsFree(RefChar *ref);
extern void UndoesFree(Undoes *undo);
extern void HintsFree(Hints *h);
extern Hints *HintsCopy(Hints *h);
extern SplineChar *SplineCharCopy(SplineChar *sc);
extern BDFChar *BDFCharCopy(BDFChar *bc);
extern void ImageListsFree(ImageList *imgs);
extern void SplineCharFree(SplineChar *sc);
extern void SplineFontFree(SplineFont *sf);
extern void SplineRefigure(Spline *spline);
extern Spline *SplineMake(SplinePoint *from, SplinePoint *to);
extern LinearApprox *SplineApproximate(Spline *spline, double scale);
extern int SplinePointListIsClockwise(SplineSet *spl);
extern void SplineSetFindBounds(SplinePointList *spl, DBounds *bounds);
extern void SplineCharFindBounds(SplineChar *sc,DBounds *bounds);
extern void SplineFontFindBounds(SplineFont *sf,DBounds *bounds);
extern void SplinePointCatagorize(SplinePoint *sp);
extern void SCCatagorizePoints(SplineChar *sc);
extern SplinePointList *SplinePointListCopy(SplinePointList *base);
extern SplinePointList *SplinePointListCopySelected(SplinePointList *base);
extern SplinePointList *SplinePointListTransform(SplinePointList *base, double transform[6], int allpoints );
extern SplinePointList *SplinePointListShift(SplinePointList *base, double xoff, int allpoints );
extern SplinePointList *SplinePointListRemoveSelected(SplinePointList *base);
extern void SplinePointListSet(SplinePointList *tobase, SplinePointList *frombase);
extern void SplinePointListSelect(SplinePointList *spl,int sel);
extern void SCRefToSplines(SplineChar *sc,RefChar *rf);
extern void SCReinstanciateRefChar(SplineChar *sc,RefChar *rf);
extern void SCReinstanciateRef(SplineChar *sc,SplineChar *rsc);
extern void SCRemoveDependent(SplineChar *dependent,RefChar *rf);
extern void SCRemoveDependents(SplineChar *dependent);
extern RefChar *SCCanonicalRefs(SplineChar *sc, int isps);
extern void BCCompressBitmap(BDFChar *bdfc);
extern void BCRegularizeBitmap(BDFChar *bdfc);
extern void BCPasteInto(BDFChar *bc,BDFChar *rbc,int ixoff,int iyoff, int invert);
extern BDFChar *SplineCharRasterize(SplineChar *sc, int pixelsize);
extern BDFFont *SplineFontRasterize(SplineFont *sf, int pixelsize);
extern BDFChar *SplineCharAntiAlias(SplineChar *sc, int pixelsize,int linear_scale);
extern BDFFont *SplineFontAntiAlias(SplineFont *sf, int pixelsize,int linear_scale);
extern void BDFCharFree(BDFChar *bdfc);
extern void BDFFontFree(BDFFont *bdf);
extern void BDFFontDump(char *filename,BDFFont *font, char *encodingname);
extern double SplineSolve(Spline1D *sp, double tmin, double tmax, double sought_y, double err);
extern void SplineFindInflections(Spline1D *sp, double *_t1, double *_t2 );
extern int NearSpline(struct findsel *fs, Spline *spline);
extern double SplineNearPoint(Spline *spline, BasePoint *bp, double fudge);
extern void SCMakeDependent(SplineChar *dependent,SplineChar *base);
extern SplinePoint *SplineBisect(Spline *spline, double t);
extern Spline *ApproximateSplineFromPoints(SplinePoint *from, SplinePoint *to,
	TPoint *mid, int cnt);
extern int SplineIsLinear(Spline *spline);
extern int SplineInSplineSet(Spline *spline, SplineSet *spl);
extern void SplineCharMerge(SplineSet **head);
extern void SplineCharSimplify(SplineSet *head);
extern void SplineCharRemoveTiny(SplineSet *head);
extern SplineFont *SplineFontNew(void);
extern SplineFont *SplineFontBlank(int enc,int charcnt);
extern SplineSet *SplineSetReverse(SplineSet *spl);
extern SplineSet *SplineSetsExtractOpen(SplineSet **tbase);
extern SplineSet *SplineSetsCorrect(SplineSet *base);
extern void SPAverageCps(SplinePoint *sp);
extern void SplineCharDefaultPrevCP(SplinePoint *base, SplinePoint *prev);
extern void SplineCharDefaultNextCP(SplinePoint *base, SplinePoint *next);
extern void SplineCharTangentNextCP(SplinePoint *sp);
extern void SplineCharTangentPrevCP(SplinePoint *sp);
extern int PointListIsSelected(SplinePointList *spl);
extern void SplineSetsUntick(SplineSet *spl);
extern void SFOrderBitmapList(SplineFont *sf);

extern SplineSet *SplineSetStroke(SplineSet *spl,StrokeInfo *si);
extern SplineSet *SplineSetRemoveOverlap(SplineSet *base);

extern void FindBlues( SplineFont *sf, double blues[14], double otherblues[10]);
extern void FindHStems( SplineFont *sf, double snaps[12], double cnt[12]);
extern void FindVStems( SplineFont *sf, double snaps[12], double cnt[12]);
extern void SplineCharAutoHint( SplineChar *sc);
extern void SplineFontAutoHint( SplineFont *sf);
extern int AfmSplineFont(FILE *afm, SplineFont *sf,int type0);
extern char *EncodingName(int map);

extern int SFDWrite(char *filename,SplineFont *sf);
extern int SFDWriteBak(SplineFont *sf);
extern SplineFont *SFDRead(char *filename);
extern SplineFont *SFReadTTF(char *filename);
extern SplineFont *LoadSplineFont(char *filename);
extern SplineFont *ReadSplineFont(char *filename);	/* Don't use this, use LoadSF instead */

extern SplineChar *SCBuildDummy(SplineChar *dummy,SplineFont *sf,int i);
extern SplineChar *SFMakeChar(SplineFont *sf,int i);
extern BDFChar *BDFMakeChar(BDFFont *bdf,int i);

extern void SCUndoSetLBearingChange(SplineChar *sc,int lb);
extern Undoes *SCPreserveState(SplineChar *sc);
extern Undoes *SCPreserveWidth(SplineChar *sc);
extern Undoes *BCPreserveState(BDFChar *bc);
extern void BCDoRedo(BDFChar *bc,struct fontview *fv);
extern void BCDoUndo(BDFChar *bc,struct fontview *fv);

extern int SFIsCompositBuildable(SplineFont *sf,int unicodeenc);
extern void SCBuildComposit(SplineFont *sf, SplineChar *sc, int copybmp,
	struct fontview *fv);

extern void BDFFontDump(char *filename,BDFFont *font, char *encodingname);
extern int getAdobeEnc(char *name);

extern SplinePointList *SplinePointListInterpretPS(FILE *ps);
extern void PSFontInterpretPS(FILE *ps,struct charprocs *cp);

extern int SFFindChar(SplineFont *sf, int unienc, char *name );

extern char *getFontForgeDir(char *buffer);
extern void DoAutoSaves(void);
extern int DoAutoRecovery(void);
extern SplineFont *SFRecoverFile(char *autosavename);
extern void SFAutoSave(SplineFont *sf);
extern void SFClearAutoSave(SplineFont *sf);
#endif
</PRE>
</BLOCKQUOTE>
</DIV>
</BODY></HTML>