1 /* -*- coding: utf-8 -*- */
2 /* Copyright (C) 2000-2012 by George Williams */
3 /*
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6 
7  * Redistributions of source code must retain the above copyright notice, this
8  * list of conditions and the following disclaimer.
9 
10  * Redistributions in binary form must reproduce the above copyright notice,
11  * this list of conditions and the following disclaimer in the documentation
12  * and/or other materials provided with the distribution.
13 
14  * The name of the author may not be used to endorse or promote products
15  * derived from this software without specific prior written permission.
16 
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 #include <fontforge-config.h>
30 
31 #include "autowidth.h"
32 #include "bitmapchar.h"
33 #include "chardata.h"
34 #include "dumppfa.h"
35 #include "encoding.h"
36 #include "featurefile.h"
37 #include "fontforgeui.h"
38 #include "gkeysym.h"
39 #include "gutils.h"
40 #include "lookups.h"
41 #include "namelist.h"
42 #include "ofl.h"
43 #include "parsepfa.h"
44 #include "parsettf.h"
45 #include "psread.h"
46 #include "sfd.h"
47 #include "sfundo.h"
48 #include "splineorder2.h"
49 #include "splinesaveafm.h"
50 #include "splineutil.h"
51 #include "splineutil2.h"
52 #include "tottf.h"
53 #include "unicoderange.h"
54 #include "ustring.h"
55 #include "utype.h"
56 
57 #include <locale.h>
58 #include <math.h>
59 #include <time.h>
60 #include <unistd.h>
61 
62 extern int _GScrollBar_Width;
63 extern GBox _ggadget_Default_Box;
64 #define ACTIVE_BORDER   (_ggadget_Default_Box.active_border)
65 #define MAIN_FOREGROUND (_ggadget_Default_Box.main_foreground)
66 
67 static int last_aspect=0;
68 
69 GTextInfo emsizes[] = {
70     { (unichar_t *) "1000", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
71     { (unichar_t *) "1024", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
72     { (unichar_t *) "2048", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
73     { (unichar_t *) "4096", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
74     GTEXTINFO_EMPTY
75 };
76 
77 /* Note that we are storing integer data in a pointer field, hence the casts. They are not to be dereferenced. */
78 GTextInfo interpretations[] = {
79 /* GT: See the long comment at "Property|New" */
80 /* GT: The msgstr should contain a translation of "None", ignore "Interpretation|" */
81 /* GT: In french this could be "Aucun" or "Aucune" depending on the gender */
82 /* GT:  of "Interpretation" */
83     { (unichar_t *) N_("Interpretation|None"), NULL, 0, 0, (void *) ui_none, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
84 /*  { (unichar_t *) N_("Adobe Public Use Defs."), NULL, 0, 0, (void *) ui_adobe, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'}, */
85 /*  { (unichar_t *) N_("Greek"), NULL, 0, 0, (void *) ui_greek, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'}, */
86     { (unichar_t *) N_("Japanese"), NULL, 0, 0, (void *) ui_japanese, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
87     { (unichar_t *) N_("Traditional Chinese"), NULL, 0, 0, (void *) ui_trad_chinese, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
88     { (unichar_t *) N_("Simplified Chinese"), NULL, 0, 0, (void *) ui_simp_chinese, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
89     { (unichar_t *) N_("Korean"), NULL, 0, 0, (void *) ui_korean, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
90 /*  { (unichar_t *) N_("AMS Public Use"), NULL, 0, 0, (void *) ui_ams, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'}, */
91     GTEXTINFO_EMPTY
92 };
93 GTextInfo macstyles[] = {
94     { (unichar_t *) N_("MacStyles|Bold"), NULL, 0, 0, (void *) sf_bold, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
95     { (unichar_t *) N_("MacStyles|Italic"), NULL, 0, 0, (void *) sf_italic, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
96     { (unichar_t *) N_("MacStyles|Condense"), NULL, 0, 0, (void *) sf_condense, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
97     { (unichar_t *) N_("MacStyles|Expand"), NULL, 0, 0, (void *) sf_extend, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
98     { (unichar_t *) N_("MacStyles|Underline"), NULL, 0, 0, (void *) sf_underline, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
99     { (unichar_t *) N_("MacStyles|Outline"), NULL, 0, 0, (void *) sf_outline, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
100     { (unichar_t *) N_("MacStyles|Shadow"), NULL, 0, 0, (void *) sf_shadow, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
101     GTEXTINFO_EMPTY
102 };
103 static GTextInfo widthclass[] = {
104     { (unichar_t *) N_("Ultra-Condensed (50%)"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
105     { (unichar_t *) N_("Extra-Condensed (62.5%)"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
106     { (unichar_t *) N_("Condensed (75%)"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
107     { (unichar_t *) N_("Semi-Condensed (87.5%)"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
108     { (unichar_t *) N_("Medium (100%)"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
109     { (unichar_t *) N_("Semi-Expanded (112.5%)"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
110     { (unichar_t *) N_("Expanded (125%)"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
111     { (unichar_t *) N_("Extra-Expanded (150%)"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
112     { (unichar_t *) N_("Ultra-Expanded (200%)"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
113     GTEXTINFO_EMPTY
114 };
115 static GTextInfo weightclass[] = {
116     { (unichar_t *) N_("100 Thin"), NULL, 0, 0, (void *) 100, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
117     { (unichar_t *) N_("200 Extra-Light"), NULL, 0, 0, (void *) 200, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
118     { (unichar_t *) N_("300 Light"), NULL, 0, 0, (void *) 300, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
119     { (unichar_t *) N_("400 Regular"), NULL, 0, 0, (void *) 400, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
120     { (unichar_t *) N_("500 Medium"), NULL, 0, 0, (void *) 500, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
121     { (unichar_t *) N_("600 Semi-Bold"), NULL, 0, 0, (void *) 600, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
122     { (unichar_t *) N_("700 Bold"), NULL, 0, 0, (void *) 700, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
123     { (unichar_t *) N_("800 Extra-Bold"), NULL, 0, 0, (void *) 800, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
124     { (unichar_t *) N_("900 Black"), NULL, 0, 0, (void *) 900, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
125     GTEXTINFO_EMPTY
126 };
127 static GTextInfo fstype[] = {
128     { (unichar_t *) N_("Never Embed/No Editing"), NULL, 0, 0, (void *) 0x02, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
129     { (unichar_t *) N_("Printable Document"), NULL, 0, 0, (void *) 0x04, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
130     { (unichar_t *) N_("Editable Document"), NULL, 0, 0, (void *) 0x08, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
131     { (unichar_t *) N_("Installable Font"), NULL, 0, 0, (void *) 0x00, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
132     GTEXTINFO_EMPTY
133 };
134 static GTextInfo pfmfamily[] = {
135     { (unichar_t *) N_("Serif"), NULL, 0, 0, (void *) 0x11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
136     { (unichar_t *) N_("Sans-Serif"), NULL, 0, 0, (void *) 0x21, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
137     { (unichar_t *) N_("Monospace"), NULL, 0, 0, (void *) 0x31, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
138 /* GT: See the long comment at "Property|New" */
139 /* GT: The msgstr should contain a translation of "Script", ignore "cursive|" */
140 /* GT: English uses "script" to me a general writing style (latin, greek, kanji) */
141 /* GT: and the cursive handwriting style. Here we mean cursive handwriting. */
142     { (unichar_t *) N_("cursive|Script"), NULL, 0, 0, (void *) 0x41, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
143     { (unichar_t *) N_("Decorative"), NULL, 0, 0, (void *) 0x51, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
144     GTEXTINFO_EMPTY
145 };
146 static GTextInfo ibmfamily[] = {
147     { (unichar_t *) N_("No Classification"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
148     { (unichar_t *) N_("Old Style Serifs"), NULL, 0, 0, (void *) 0x100, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
149     { (unichar_t *) N_("OSS Rounded Legibility"), NULL, 0, 0, (void *) 0x101, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
150     { (unichar_t *) N_("OSS Geralde"), NULL, 0, 0, (void *) 0x102, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
151     { (unichar_t *) N_("OSS Venetian"), NULL, 0, 0, (void *) 0x103, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
152     { (unichar_t *) N_("OSS Modified Venetian"), NULL, 0, 0, (void *) 0x104, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
153     { (unichar_t *) N_("OSS Dutch Modern"), NULL, 0, 0, (void *) 0x105, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
154     { (unichar_t *) N_("OSS Dutch Trad"), NULL, 0, 0, (void *) 0x106, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
155     { (unichar_t *) N_("OSS Contemporary"), NULL, 0, 0, (void *) 0x107, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
156     { (unichar_t *) N_("OSS Calligraphic"), NULL, 0, 0, (void *) 0x108, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
157     { (unichar_t *) N_("OSS Miscellaneous"), NULL, 0, 0, (void *) 0x10f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
158     { (unichar_t *) N_("Transitional Serifs"), NULL, 0, 0, (void *) 0x200, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
159     { (unichar_t *) N_("TS Direct Line"), NULL, 0, 0, (void *) 0x201, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
160     { (unichar_t *) N_("TS Script"), NULL, 0, 0, (void *) 0x202, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
161     { (unichar_t *) N_("TS Miscellaneous"), NULL, 0, 0, (void *) 0x20f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
162     { (unichar_t *) N_("Modern Serifs"), NULL, 0, 0, (void *) 0x300, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
163     { (unichar_t *) N_("MS Italian"), NULL, 0, 0, (void *) 0x301, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
164     { (unichar_t *) N_("MS Script"), NULL, 0, 0, (void *) 0x302, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
165     { (unichar_t *) N_("MS Miscellaneous"), NULL, 0, 0, (void *) 0x30f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
166     { (unichar_t *) N_("Clarendon Serifs"), NULL, 0, 0, (void *) 0x400, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
167     { (unichar_t *) N_("CS Clarendon"), NULL, 0, 0, (void *) 0x401, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
168     { (unichar_t *) N_("CS Modern"), NULL, 0, 0, (void *) 0x402, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
169     { (unichar_t *) N_("CS Traditional"), NULL, 0, 0, (void *) 0x403, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
170     { (unichar_t *) N_("CS Newspaper"), NULL, 0, 0, (void *) 0x404, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
171     { (unichar_t *) N_("CS Stub Serif"), NULL, 0, 0, (void *) 0x405, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
172     { (unichar_t *) N_("CS Monotone"), NULL, 0, 0, (void *) 0x406, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
173     { (unichar_t *) N_("CS Typewriter"), NULL, 0, 0, (void *) 0x407, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
174     { (unichar_t *) N_("CS Miscellaneous"), NULL, 0, 0, (void *) 0x40f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
175     { (unichar_t *) N_("Slab Serifs"), NULL, 0, 0, (void *) 0x500, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
176     { (unichar_t *) N_("Slab Serifs|SS Monotone"), NULL, 0, 0, (void *) 0x501, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
177     { (unichar_t *) N_("Slab Serifs|SS Humanist"), NULL, 0, 0, (void *) 0x502, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
178     { (unichar_t *) N_("Slab Serifs|SS Geometric"), NULL, 0, 0, (void *) 0x503, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
179     { (unichar_t *) N_("Slab Serifs|SS Swiss"), NULL, 0, 0, (void *) 0x504, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
180     { (unichar_t *) N_("Slab Serifs|SS Typewriter"), NULL, 0, 0, (void *) 0x505, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
181     { (unichar_t *) N_("Slab Serifs|SS Miscellaneous"), NULL, 0, 0, (void *) 0x50f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
182     { (unichar_t *) N_("Freeform Serifs"), NULL, 0, 0, (void *) 0x700, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
183     { (unichar_t *) N_("FS Modern"), NULL, 0, 0, (void *) 0x701, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
184     { (unichar_t *) N_("FS Miscellaneous"), NULL, 0, 0, (void *) 0x70f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
185     { (unichar_t *) N_("Sans-Serif"), NULL, 0, 0, (void *) 0x800, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
186     { (unichar_t *) N_("Sans-Serif|SS IBM NeoGrotesque Gothic"), NULL, 0, 0, (void *) 0x801, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
187     { (unichar_t *) N_("Sans-Serif|SS Humanist"), NULL, 0, 0, (void *) 0x802, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
188     { (unichar_t *) N_("Sans-Serif|SS Low-x Round Geometric"), NULL, 0, 0, (void *) 0x803, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
189     { (unichar_t *) N_("Sans-Serif|SS High-x Round Geometric"), NULL, 0, 0, (void *) 0x804, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
190     { (unichar_t *) N_("Sans-Serif|SS NeoGrotesque Gothic"), NULL, 0, 0, (void *) 0x805, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
191     { (unichar_t *) N_("Sans-Serif|SS Modified Grotesque Gothic"), NULL, 0, 0, (void *) 0x806, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
192     { (unichar_t *) N_("Sans-Serif|SS Typewriter Gothic"), NULL, 0, 0, (void *) 0x809, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
193     { (unichar_t *) N_("Sans-Serif|SS Matrix"), NULL, 0, 0, (void *) 0x80a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
194     { (unichar_t *) N_("Sans-Serif|SS Miscellaneous"), NULL, 0, 0, (void *) 0x80f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
195     { (unichar_t *) N_("Ornamentals"), NULL, 0, 0, (void *) 0x900, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
196     { (unichar_t *) N_("O Engraver"), NULL, 0, 0, (void *) 0x901, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
197     { (unichar_t *) N_("O Black Letter"), NULL, 0, 0, (void *) 0x902, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
198     { (unichar_t *) N_("O Decorative"), NULL, 0, 0, (void *) 0x903, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
199     { (unichar_t *) N_("O Three Dimensional"), NULL, 0, 0, (void *) 0x904, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
200     { (unichar_t *) N_("O Miscellaneous"), NULL, 0, 0, (void *) 0x90f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
201     { (unichar_t *) N_("Scripts"), NULL, 0, 0, (void *) 0xa00, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
202     { (unichar_t *) N_("S Uncial"), NULL, 0, 0, (void *) 0xa01, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
203     { (unichar_t *) N_("S Brush Joined"), NULL, 0, 0, (void *) 0xa02, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
204     { (unichar_t *) N_("S Formal Joined"), NULL, 0, 0, (void *) 0xa03, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
205     { (unichar_t *) N_("S Monotone Joined"), NULL, 0, 0, (void *) 0xa04, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
206     { (unichar_t *) N_("S Calligraphic"), NULL, 0, 0, (void *) 0xa05, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
207     { (unichar_t *) N_("S Brush Unjoined"), NULL, 0, 0, (void *) 0xa06, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
208     { (unichar_t *) N_("S Formal Unjoined"), NULL, 0, 0, (void *) 0xa07, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
209     { (unichar_t *) N_("S Monotone Unjoined"), NULL, 0, 0, (void *) 0xa08, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
210     { (unichar_t *) N_("S Miscellaneous"), NULL, 0, 0, (void *) 0xa0f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
211     { (unichar_t *) N_("Symbolic"), NULL, 0, 0, (void *) 0xc00, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
212     { (unichar_t *) N_("Sy Mixed Serif"), NULL, 0, 0, (void *) 0xc03, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
213     { (unichar_t *) N_("Sy Old Style Serif"), NULL, 0, 0, (void *) 0xc06, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
214     { (unichar_t *) N_("Sy Neo-grotesque Sans Serif"), NULL, 0, 0, (void *) 0xc07, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
215     { (unichar_t *) N_("Sy Miscellaneous"), NULL, 0, 0, (void *) 0xc0f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
216     GTEXTINFO_EMPTY
217 };
218 static GTextInfo stylemap[] = {
219     { (unichar_t *) N_("Automatic"), NULL, 0, 0, (void *) -1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
220     { (unichar_t *) N_("None"), NULL, 0, 0, (void *) 0x00, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
221     { (unichar_t *) N_("Regular"), NULL, 0, 0, (void *) 0x40, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
222     { (unichar_t *) N_("Italic"), NULL, 0, 0, (void *) 0x01, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
223     { (unichar_t *) N_("Bold"), NULL, 0, 0, (void *) 0x20, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
224     { (unichar_t *) N_("Bold Italic"), NULL, 0, 0, (void *) 0x21, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
225     GTEXTINFO_EMPTY
226 };
227 static GTextInfo os2versions[] = {
228     { (unichar_t *) N_("OS2Version|Automatic"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
229     { (unichar_t *) N_("1"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
230     { (unichar_t *) N_("2"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
231     { (unichar_t *) N_("3"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
232     { (unichar_t *) N_("4"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
233     GTEXTINFO_EMPTY
234 };
235 static GTextInfo gaspversions[] = {
236     { (unichar_t *) N_("0"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
237     { (unichar_t *) N_("1"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
238     GTEXTINFO_EMPTY
239 };
240 static GTextInfo panfamily[] = {
241     { (unichar_t *) N_("PanoseFamily|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
242     { (unichar_t *) N_("PanoseFamily|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
243     { (unichar_t *) N_("Latin: Text and Display"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
244 /* GT: See the long comment at "Property|New" */
245 /* GT: The msgstr should contain a translation of "Script", ignore "cursive|" */
246 /* GT: English uses "script" to me a general writing style (latin, greek, kanji) */
247 /* GT: and the cursive handwriting style. Here we mean cursive handwriting. */
248     { (unichar_t *) N_("cursive|Latin: Handwritten"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
249     { (unichar_t *) N_("Latin: Decorative"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
250     { (unichar_t *) N_("Latin: Pictorial and Symbol"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
251     { (unichar_t *) "6", NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
252     { (unichar_t *) "7", NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
253     { (unichar_t *) "8", NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
254     { (unichar_t *) "9", NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
255     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
256     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
257     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
258     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
259     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
260     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
261     GTEXTINFO_EMPTY
262 };
263 static GTextInfo panunknown[] = {
264     { (unichar_t *) "Any", NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
265     { (unichar_t *) "No Fit", NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
266     { (unichar_t *) "2", NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
267     { (unichar_t *) "3", NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
268     { (unichar_t *) "4", NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
269     { (unichar_t *) "5", NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
270     { (unichar_t *) "6", NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
271     { (unichar_t *) "7", NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
272     { (unichar_t *) "8", NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
273     { (unichar_t *) "9", NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
274     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
275     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
276     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
277     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
278     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
279     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
280     GTEXTINFO_EMPTY
281 };
282 static GTextInfo panserifs[] = {
283     { (unichar_t *) N_("PanoseSerifs|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
284     { (unichar_t *) N_("PanoseSerifs|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
285     { (unichar_t *) N_("Cove"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
286     { (unichar_t *) N_("Obtuse Cove"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
287     { (unichar_t *) N_("Square Cove"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
288     { (unichar_t *) N_("Obtuse Square Cove"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
289     { (unichar_t *) N_("PanoseSerivfs|Square"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
290     { (unichar_t *) N_("PanoseSerifs|Thin"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
291     { (unichar_t *) N_("Bone"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
292     { (unichar_t *) N_("Exaggerated"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
293     { (unichar_t *) N_("Triangle"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
294     { (unichar_t *) N_("Normal Sans"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
295     { (unichar_t *) N_("Obtuse Sans"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
296     { (unichar_t *) N_("Perpendicular Sans"), NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
297     { (unichar_t *) N_("Flared"), NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
298     { (unichar_t *) N_("PanoseSerivfs|Rounded"), NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
299     GTEXTINFO_EMPTY
300 };
301 static GTextInfo panweight[] = {
302     { (unichar_t *) N_("PanoseWeight|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
303     { (unichar_t *) N_("PanoseWeight|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
304     { (unichar_t *) N_("Very Light"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
305     { (unichar_t *) N_("Light"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
306     { (unichar_t *) N_("PanoseWeight|Thin"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
307     { (unichar_t *) N_("Book"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
308     { (unichar_t *) N_("Medium"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
309     { (unichar_t *) N_("Demi"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
310     { (unichar_t *) N_("Bold"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
311     { (unichar_t *) N_("Heavy"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
312     { (unichar_t *) N_("Black"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
313     { (unichar_t *) N_("Extra Black (Nord)"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
314     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
315     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
316     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
317     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
318     GTEXTINFO_EMPTY
319 };
320 static GTextInfo panprop[] = {
321     { (unichar_t *) N_("PanoseProportion|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
322     { (unichar_t *) N_("PanoseProportion|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
323     { (unichar_t *) N_("Old Style"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
324     { (unichar_t *) N_("Modern"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
325     { (unichar_t *) N_("Even Width"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
326     { (unichar_t *) N_("Expanded"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
327     { (unichar_t *) N_("Condensed"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
328     { (unichar_t *) N_("Very Expanded"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
329     { (unichar_t *) N_("Very Condensed"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
330     { (unichar_t *) N_("Monospaced"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
331     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
332     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
333     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
334     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
335     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
336     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
337     GTEXTINFO_EMPTY
338 };
339 static GTextInfo pancontrast[] = {
340     { (unichar_t *) N_("PanoseContrast|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
341     { (unichar_t *) N_("PanoseContrast|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
342     { (unichar_t *) N_("PanoseContrast|None"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
343     { (unichar_t *) N_("PanoseContrast|Very Low"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
344     { (unichar_t *) N_("PanoseContrast|Low"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
345     { (unichar_t *) N_("PanoseContrast|Medium Low"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
346     { (unichar_t *) N_("PanoseContrast|Medium"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
347     { (unichar_t *) N_("PanoseContrast|Medium High"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
348     { (unichar_t *) N_("PanoseContrast|High"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
349     { (unichar_t *) N_("PanoseContrast|Very High"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
350     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
351     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
352     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
353     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
354     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
355     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
356     GTEXTINFO_EMPTY
357 };
358 static GTextInfo panstrokevar[] = {
359     { (unichar_t *) N_("PanoseStrokeVariation|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
360     { (unichar_t *) N_("PanoseStrokeVariation|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
361     { (unichar_t *) N_("No Variation"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
362     { (unichar_t *) N_("Gradual/Diagonal"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
363     { (unichar_t *) N_("Gradual/Transitional"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
364     { (unichar_t *) N_("Gradual/Vertical"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
365     { (unichar_t *) N_("Gradual/Horizontal"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
366     { (unichar_t *) N_("Rapid/Vertical"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
367     { (unichar_t *) N_("Rapid/Horizontal"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
368     { (unichar_t *) N_("Instant/Vertical"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
369     { (unichar_t *) N_("Instant/Horizontal"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
370     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
371     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
372     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
373     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
374     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
375     GTEXTINFO_EMPTY
376 };
377 static GTextInfo panarmstyle[] = {
378     { (unichar_t *) N_("PanoseArmStyle|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
379     { (unichar_t *) N_("PanoseArmStyle|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
380     { (unichar_t *) N_("Straight Arms/Horizontal"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
381     { (unichar_t *) N_("Straight Arms/Wedge"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
382     { (unichar_t *) N_("Straight Arms/Vertical"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
383     { (unichar_t *) N_("Straight Arms/Single Serif"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
384     { (unichar_t *) N_("Straight Arms/Double Serif"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
385     { (unichar_t *) N_("Non-Straight Arms/Horizontal"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
386     { (unichar_t *) N_("Non-Straight Arms/Wedge"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
387     { (unichar_t *) N_("Non-Straight Arms/Vertical"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
388     { (unichar_t *) N_("Non-Straight Arms/Single Serif"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
389     { (unichar_t *) N_("Non-Straight Arms/Double Serif"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
390     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
391     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
392     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
393     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
394     GTEXTINFO_EMPTY
395 };
396 static GTextInfo panletterform[] = {
397     { (unichar_t *) N_("PanoseLetterform|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
398     { (unichar_t *) N_("PanoseLetterform|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
399     { (unichar_t *) N_("Normal/Contact"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
400     { (unichar_t *) N_("Normal/Weighted"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
401     { (unichar_t *) N_("Normal/Boxed"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
402     { (unichar_t *) N_("Normal/Flattened"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
403     { (unichar_t *) N_("Normal/Rounded"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
404     { (unichar_t *) N_("Normal/Off-Center"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
405     { (unichar_t *) N_("Normal/Square"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
406     { (unichar_t *) N_("Oblique/Contact"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
407     { (unichar_t *) N_("Oblique/Weighted"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
408     { (unichar_t *) N_("Oblique/Boxed"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
409     { (unichar_t *) N_("Oblique/Flattened"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
410     { (unichar_t *) N_("Oblique/Rounded"), NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
411     { (unichar_t *) N_("Oblique/Off-Center"), NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
412     { (unichar_t *) N_("Oblique/Square"), NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
413     GTEXTINFO_EMPTY
414 };
415 static GTextInfo panmidline[] = {
416     { (unichar_t *) N_("PanoseMidline|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
417     { (unichar_t *) N_("PanoseMidline|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
418     { (unichar_t *) N_("PanoseMidline|Standard/Trimmed"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
419     { (unichar_t *) N_("PanoseMidline|Standard/Pointed"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
420     { (unichar_t *) N_("PanoseMidline|Standard/Serifed"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
421     { (unichar_t *) N_("PanoseMidline|High/Trimmed"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
422     { (unichar_t *) N_("PanoseMidline|High/Pointed"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
423     { (unichar_t *) N_("PanoseMidline|High/Serifed"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
424     { (unichar_t *) N_("PanoseMidline|Constant/Trimmed"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
425     { (unichar_t *) N_("PanoseMidline|Constant/Pointed"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
426     { (unichar_t *) N_("PanoseMidline|Constant/Serifed"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
427     { (unichar_t *) N_("PanoseMidline|Low/Trimmed"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
428     { (unichar_t *) N_("PanoseMidline|Low/Pointed"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
429     { (unichar_t *) N_("PanoseMidline|Low/Serifed"), NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
430     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
431     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
432     GTEXTINFO_EMPTY
433 };
434 static GTextInfo panxheight[] = {
435     { (unichar_t *) N_("PanoseXHeight|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
436     { (unichar_t *) N_("PanoseXHeight|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
437     { (unichar_t *) N_("PanoseXHeight|Constant/Small"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
438     { (unichar_t *) N_("PanoseXHeight|Constant/Standard"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
439     { (unichar_t *) N_("PanoseXHeight|Constant/Large"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
440     { (unichar_t *) N_("PanoseXHeight|Ducking/Small"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
441     { (unichar_t *) N_("PanoseXHeight|Ducking/Standard"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
442     { (unichar_t *) N_("PanoseXHeight|Ducking/Large"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
443     { (unichar_t *) "8", NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
444     { (unichar_t *) "9", NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
445     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
446     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
447     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
448     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
449     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
450     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
451     GTEXTINFO_EMPTY
452 };
453 /* Latin: Hand written */
454 static GTextInfo pantool[] = {
455     { (unichar_t *) N_("PanoseTool|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
456     { (unichar_t *) N_("PanoseTool|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
457     { (unichar_t *) N_("Flat Nib"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
458     { (unichar_t *) N_("Pressure Point"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
459     { (unichar_t *) N_("Engraved"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
460     { (unichar_t *) N_("Ball (Round Cap)"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
461     { (unichar_t *) N_("Brush"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
462     { (unichar_t *) N_("Rough"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
463     { (unichar_t *) N_("Felt Pen or Brush Tip"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
464     { (unichar_t *) N_("Wild Brush - Drips a lot"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
465     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
466     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
467     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
468     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
469     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
470     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
471     GTEXTINFO_EMPTY
472 };
473 static GTextInfo panspacing[] = {
474     { (unichar_t *) N_("PanoseSpacing|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
475     { (unichar_t *) N_("PanoseSpacing|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
476     { (unichar_t *) N_("Proportional Spaced"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
477     { (unichar_t *) N_("Monospaced"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
478     { (unichar_t *) "4", NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
479     { (unichar_t *) "5", NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
480     { (unichar_t *) "6", NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
481     { (unichar_t *) "7", NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
482     { (unichar_t *) "8", NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
483     { (unichar_t *) "9", NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
484     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
485     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
486     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
487     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
488     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
489     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
490     GTEXTINFO_EMPTY
491 };
492 static GTextInfo panasprat[] = {
493     { (unichar_t *) N_("PanoseAspectRatio|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
494     { (unichar_t *) N_("PanoseAspectRatio|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
495     { (unichar_t *) N_("Very Condensed"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
496     { (unichar_t *) N_("Condensed"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
497     { (unichar_t *) N_("Normal"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
498     { (unichar_t *) N_("Expanded"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
499     { (unichar_t *) N_("Very Expanded"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
500     { (unichar_t *) "7", NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
501     { (unichar_t *) "8", NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
502     { (unichar_t *) "9", NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
503     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
504     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
505     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
506     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
507     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
508     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
509     GTEXTINFO_EMPTY
510 };
511 static GTextInfo pancontrast2[] = {
512     { (unichar_t *) N_("PanoseContrast|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
513     { (unichar_t *) N_("PanoseContrast|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
514     { (unichar_t *) N_("PanoseContrast|None"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
515     { (unichar_t *) N_("Very Low"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
516     { (unichar_t *) N_("Low"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
517     { (unichar_t *) N_("Medium Low"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
518     { (unichar_t *) N_("Medium"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
519     { (unichar_t *) N_("Medium High"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
520     { (unichar_t *) N_("High"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
521     { (unichar_t *) N_("Very High"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
522     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
523     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
524     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
525     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
526     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
527     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
528     GTEXTINFO_EMPTY
529 };
530 static GTextInfo pantopology[] = {
531     { (unichar_t *) N_("PanoseTopology|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
532     { (unichar_t *) N_("PanoseTopology|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
533     { (unichar_t *) N_("Roman Disconnected"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
534     { (unichar_t *) N_("Roman Trailing"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
535     { (unichar_t *) N_("Roman Connected"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
536     { (unichar_t *) N_("Cursive Disconnected"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
537     { (unichar_t *) N_("Cursive Trailing"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
538     { (unichar_t *) N_("Cursive Connected"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
539     { (unichar_t *) N_("Blackletter Disconnected"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
540     { (unichar_t *) N_("Blackletter Trailing"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
541     { (unichar_t *) N_("Blackletter Connected"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
542     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
543     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
544     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
545     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
546     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
547     GTEXTINFO_EMPTY
548 };
549 static GTextInfo panform[] = {
550     { (unichar_t *) N_("PanoseForm|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
551     { (unichar_t *) N_("PanoseForm|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
552     { (unichar_t *) N_("Upright/No Wrapping"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
553     { (unichar_t *) N_("Upright/Some Wrapping"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
554     { (unichar_t *) N_("Upright/More Wrapping"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
555     { (unichar_t *) N_("Upright/Extreme Wrapping"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
556     { (unichar_t *) N_("Oblique/No Wrapping"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
557     { (unichar_t *) N_("Oblique/Some Wrapping"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
558     { (unichar_t *) N_("Oblique/More Wrapping"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
559     { (unichar_t *) N_("Oblique/Extreme Wrapping"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
560     { (unichar_t *) N_("Exaggerated/No Wrapping"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
561     { (unichar_t *) N_("Exaggerated/Some Wrapping"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
562     { (unichar_t *) N_("Exaggerated/More Wrapping"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
563     { (unichar_t *) N_("Exaggerated/Extreme Wrapping"), NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
564     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
565     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
566     GTEXTINFO_EMPTY
567 };
568 static GTextInfo panfinials[] = {
569     { (unichar_t *) N_("PanoseFinials|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
570     { (unichar_t *) N_("PanoseFinials|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
571     { (unichar_t *) N_("None/No Loops"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
572     { (unichar_t *) N_("None/Closed Loops"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
573     { (unichar_t *) N_("None/Open Loops"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
574     { (unichar_t *) N_("Sharp/No Loops"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
575     { (unichar_t *) N_("Sharp/Closed Loops"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
576     { (unichar_t *) N_("Sharp/Open Loops"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
577     { (unichar_t *) N_("Tapered/No Loops"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
578     { (unichar_t *) N_("Tapered/Closed Loops"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
579     { (unichar_t *) N_("Tapered/Open Loops"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
580     { (unichar_t *) N_("Round/No Loops"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
581     { (unichar_t *) N_("Round/Closed Loops"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
582     { (unichar_t *) N_("Round/Open Loops"), NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
583     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
584     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
585     GTEXTINFO_EMPTY
586 };
587 static GTextInfo panxascent[] = {
588     { (unichar_t *) N_("PanoseXAscent|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
589     { (unichar_t *) N_("PanoseXAscent|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
590     { (unichar_t *) N_("PanoseXAscent|Very Low"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
591     { (unichar_t *) N_("PanoseXAscent|Low"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
592     { (unichar_t *) N_("PanoseXAscent|Medium"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
593     { (unichar_t *) N_("PanoseXAscent|High"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
594     { (unichar_t *) N_("PanoseXAscent|Very High"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
595     { (unichar_t *) "7", NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
596     { (unichar_t *) "8", NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
597     { (unichar_t *) "9", NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
598     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
599     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
600     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
601     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
602     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
603     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
604     GTEXTINFO_EMPTY
605 };
606 /* Latin: Decorative */
607 static GTextInfo panclass[] = {
608     { (unichar_t *) N_("PanoseClass|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
609     { (unichar_t *) N_("PanoseClass|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
610     { (unichar_t *) N_("Derivative"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
611     { (unichar_t *) N_("Non-standard Topology"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
612     { (unichar_t *) N_("Non-standard Elements"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
613     { (unichar_t *) N_("Non-standard Aspect"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
614     { (unichar_t *) N_("Initials"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
615     { (unichar_t *) N_("Cartoon"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
616     { (unichar_t *) N_("Picture Stems"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
617     { (unichar_t *) N_("Ornamented"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
618     { (unichar_t *) N_("Text and Background"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
619     { (unichar_t *) N_("Collage"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
620     { (unichar_t *) N_("Montage"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
621     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
622     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
623     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
624     GTEXTINFO_EMPTY
625 };
626 static GTextInfo panaspect[] = {
627     { (unichar_t *) N_("PanoseAspect|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
628     { (unichar_t *) N_("PanoseAspect|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
629     { (unichar_t *) N_("Super Condensed"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
630     { (unichar_t *) N_("Very Condensed"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
631     { (unichar_t *) N_("Condensed"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
632     { (unichar_t *) N_("Normal"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
633     { (unichar_t *) N_("Extended"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
634     { (unichar_t *) N_("Very Extended"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
635     { (unichar_t *) N_("Super Extended"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
636     { (unichar_t *) N_("Monospaced"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
637     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
638     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
639     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
640     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
641     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
642     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
643     GTEXTINFO_EMPTY
644 };
645 static GTextInfo pancontrast3[] = {
646     { (unichar_t *) N_("PanoseContrast|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
647     { (unichar_t *) N_("PanoseContrast|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
648     { (unichar_t *) N_("PanoseContrast|None"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
649     { (unichar_t *) N_("Very Low"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
650     { (unichar_t *) N_("Low"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
651     { (unichar_t *) N_("Medium Low"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
652     { (unichar_t *) N_("Medium"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
653     { (unichar_t *) N_("Medium High"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
654     { (unichar_t *) N_("High"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
655     { (unichar_t *) N_("Very High"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
656     { (unichar_t *) N_("Horizontal Low"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
657     { (unichar_t *) N_("Horizontal Medium"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
658     { (unichar_t *) N_("Horizontal High"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
659     { (unichar_t *) N_("Broken"), NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
660     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
661     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
662     GTEXTINFO_EMPTY
663 };
664 static GTextInfo panserifvar[] = {
665     { (unichar_t *) N_("PanoseSerifVariant|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
666     { (unichar_t *) N_("PanoseSerifVariant|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
667     { (unichar_t *) N_("Cove"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
668     { (unichar_t *) N_("Obtuse Cove"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
669     { (unichar_t *) N_("Square Cove"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
670     { (unichar_t *) N_("Obtuse Square Cove"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
671     { (unichar_t *) N_("PanoseSerivfs|Square"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
672     { (unichar_t *) N_("PanoseSerifs|Thin"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
673 /*!*/{ (unichar_t *) N_("Oval"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
674     { (unichar_t *) N_("Exaggerated"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
675     { (unichar_t *) N_("Triangle"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
676     { (unichar_t *) N_("Normal Sans"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
677     { (unichar_t *) N_("Obtuse Sans"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
678     { (unichar_t *) N_("Perpendicular Sans"), NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
679     { (unichar_t *) N_("Flared"), NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
680     { (unichar_t *) N_("PanoseSerivfs|Rounded"), NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
681 /* Um, these guys are only supposed to go up to 15, so why does this have a 16? */
682 /*!*/{ (unichar_t *) N_("PanoseSerivfs|Script"), NULL, 0, 0, (void *) 16, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
683     GTEXTINFO_EMPTY
684 };
685 static GTextInfo pantreatment[] = {
686     { (unichar_t *) N_("PanoseTreatment|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
687     { (unichar_t *) N_("PanoseTreatment|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
688     { (unichar_t *) N_("Standard Solid Fill"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
689     { (unichar_t *) N_("No Fill"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
690     { (unichar_t *) N_("Patterned Fill"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
691     { (unichar_t *) N_("Complex Fill"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
692     { (unichar_t *) N_("Shaped Fill"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
693     { (unichar_t *) N_("Drawn or Distressed"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
694     { (unichar_t *) "8", NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
695     { (unichar_t *) "9", NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
696     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
697     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
698     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
699     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
700     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
701     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
702     GTEXTINFO_EMPTY
703 };
704 static GTextInfo panlining[] = {
705     { (unichar_t *) N_("PanoseLining|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
706     { (unichar_t *) N_("PanoseLining|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
707     { (unichar_t *) N_("PanoseLining|None"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
708     { (unichar_t *) N_("PanoseLining|Inline"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
709     { (unichar_t *) N_("PanoseLining|Outline"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
710     { (unichar_t *) N_("PanoseLining|Engraved (Multiple Lines)"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
711     { (unichar_t *) N_("PanoseLining|Shadow"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
712     { (unichar_t *) N_("PanoseLining|Relief"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
713     { (unichar_t *) N_("PanoseLining|Backdrop"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
714     { (unichar_t *) "9", NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
715     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
716     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
717     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
718     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
719     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
720     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
721     GTEXTINFO_EMPTY
722 };
723 static GTextInfo pantopology2[] = {
724     { (unichar_t *) N_("PanoseTopology|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
725     { (unichar_t *) N_("PanoseTopology|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
726     { (unichar_t *) N_("Standard"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
727     { (unichar_t *) N_("Square"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
728     { (unichar_t *) N_("Multiple Segment"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
729     { (unichar_t *) N_("Deco (E,M,S) Waco Midline"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
730     { (unichar_t *) N_("Uneven Weighting"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
731     { (unichar_t *) N_("Diverse Arms"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
732     { (unichar_t *) N_("Diverse Forms"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
733     { (unichar_t *) N_("Lombardic Forms"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
734     { (unichar_t *) N_("Upper Case in Lower Case"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
735     { (unichar_t *) N_("Implied Topology"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
736     { (unichar_t *) N_("Horseshoe E and A"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
737     { (unichar_t *) N_("Cursive"), NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
738     { (unichar_t *) N_("Blackletter"), NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
739     { (unichar_t *) N_("Swash Variance"), NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
740     GTEXTINFO_EMPTY
741 };
742 static GTextInfo pancharrange[] = {
743     { (unichar_t *) N_("PanoseCharRange|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
744     { (unichar_t *) N_("PanoseCharRange|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
745     { (unichar_t *) N_("Extended Collection"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
746     { (unichar_t *) N_("Literals"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
747     { (unichar_t *) N_("No Lower Case"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
748     { (unichar_t *) N_("Small Caps"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
749     { (unichar_t *) "6", NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
750     { (unichar_t *) "7", NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
751     { (unichar_t *) "8", NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
752     { (unichar_t *) "9", NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
753     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
754     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
755     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
756     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
757     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
758     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
759     GTEXTINFO_EMPTY
760 };
761 /* Latin: Symbol */
762 static GTextInfo pankind[] = {
763     { (unichar_t *) N_("PanoseKind|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
764     { (unichar_t *) N_("PanoseKind|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
765     { (unichar_t *) N_("Montages"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
766     { (unichar_t *) N_("Pictures"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
767     { (unichar_t *) N_("Shapes"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
768     { (unichar_t *) N_("Scientific"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
769     { (unichar_t *) N_("Music"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
770     { (unichar_t *) N_("Expert"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
771     { (unichar_t *) N_("Patterns"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
772     { (unichar_t *) N_("Borders"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
773     { (unichar_t *) N_("Icons"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
774     { (unichar_t *) N_("Logos"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
775     { (unichar_t *) N_("Industry Specific"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
776     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
777     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
778     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
779     GTEXTINFO_EMPTY
780 };
781 static GTextInfo panasprat2[] = {
782     { (unichar_t *) N_("PanoseAspect|Any"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
783     { (unichar_t *) N_("PanoseAspect|No Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
784     { (unichar_t *) N_("No Width"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
785     { (unichar_t *) N_("Exceptionally Wide"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
786     { (unichar_t *) N_("Super Wide"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
787     { (unichar_t *) N_("Very Wide"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
788     { (unichar_t *) N_("Wide"), NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
789     { (unichar_t *) N_("Normal"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
790     { (unichar_t *) N_("Narrow"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
791     { (unichar_t *) N_("Very Narrow"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
792     { (unichar_t *) "10", NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
793     { (unichar_t *) "11", NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
794     { (unichar_t *) "12", NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
795     { (unichar_t *) "13", NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
796     { (unichar_t *) "14", NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
797     { (unichar_t *) "15", NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
798     GTEXTINFO_EMPTY
799 };
800 
801 static struct titlelist { char *name; GTextInfo *variants; } panoses[][9] = {
802     /*Any*/    {{ N_("Class2"), panunknown }, { N_("Class3"), panunknown }, { N_("Class4"), panunknown }, { N_("Class5"), panunknown }, { N_("Class6"), panunknown }, { N_("Class7"), panunknown }, { N_("Class8"), panunknown }, { N_("Class9"), panunknown }, { N_("Class10"), panunknown }},
803     /*NoFit*/  {{ N_("Class2"), panunknown }, { N_("Class3"), panunknown }, { N_("Class4"), panunknown }, { N_("Class5"), panunknown }, { N_("Class6"), panunknown }, { N_("Class7"), panunknown }, { N_("Class8"), panunknown }, { N_("Class9"), panunknown }, { N_("Class10"), panunknown }},
804     /*LtnTxt*/ {{ N_("_Serifs"), panserifs }, { N_("Panose|_Weight"), panweight }, { N_("_Proportion"), panprop }, { N_("_Contrast"), pancontrast }, { N_("Stroke _Variation"), panstrokevar }, { N_("_Arm Style"), panarmstyle }, { N_("_Letterform"), panletterform }, { N_("_Midline"), panmidline }, { N_("_X-Height"), panxheight }},
805     /*LtnHnd*/ {{ N_("_Tool"), pantool }, { N_("Panose|_Weight"), panweight }, { N_("_Spacing"), panspacing }, { N_("_Aspect Ratio"), panasprat }, { N_("_Contrast"), pancontrast2 }, { N_("_Topology"), pantopology }, { N_("F_orm"), panform }, { N_("F_inials"), panfinials }, { N_("_X-Ascent"), panxascent }},
806     /*LtnDcr*/ {{ N_("_Class"), panclass }, { N_("Panose|_Weight"), panweight }, { N_("_Aspect"), panaspect }, { N_("C_ontrast"), pancontrast3 }, { N_("_Serif Variant"), panserifvar }, { N_("T_reatment"), pantreatment }, { N_("_Lining"), panlining }, { N_("_Topology"), pantopology2 }, { N_("Char. _Range"), pancharrange }},
807 					    /* Yup, really should be "unknown", no weights permitted, nor aspect ratios */
808     /*LtnSym*/ {{ N_("_Kind"), pankind }, { N_("Panose|_Weight"), panunknown }, { N_("_Spacing"), panspacing }, { N_("_Aspect Ratio"), panunknown }, { N_("AR: Char 94"), panasprat2 }, { N_("AR: Char 119"), panasprat2 }, { N_("AR: Char 157"), panasprat2 }, { N_("AR: Char 163"), panasprat2 }, { N_("AR: Char 211"), panasprat2 }},
809     /* 6 */    {{ N_("Class2"), panunknown }, { N_("Class3"), panunknown }, { N_("Class4"), panunknown }, { N_("Class5"), panunknown }, { N_("Class6"), panunknown }, { N_("Class7"), panunknown }, { N_("Class8"), panunknown }, { N_("Class9"), panunknown }, { N_("Class10"), panunknown }},
810     {{NULL, NULL}}
811 };
812 
813 /* There is a similar list at the end of python.c, untranslated strings for */
814 /*  scripting use */
815 static GTextInfo mslanguages[] = {
816     { (unichar_t *) N_("Afrikaans"), NULL, 0, 0, (void *) 0x436, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
817     { (unichar_t *) N_("Albanian"), NULL, 0, 0, (void *) 0x41c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
818 /* GT: See the long comment at "Property|New" */
819 /* GT: The msgstr should contain a translation of "Malayalam", ignore "Lang|" */
820     { (unichar_t *) N_("Lang|Amharic"), NULL, 0, 0, (void *) 0x45e, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
821     { (unichar_t *) N_("Arabic (Saudi Arabia)"), NULL, 0, 0, (void *) 0x401, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
822     { (unichar_t *) N_("Arabic (Iraq)"), NULL, 0, 0, (void *) 0x801, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
823     { (unichar_t *) N_("Arabic (Egypt)"), NULL, 0, 0, (void *) 0xc01, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
824     { (unichar_t *) N_("Arabic (Libya)"), NULL, 0, 0, (void *) 0x1001, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
825     { (unichar_t *) N_("Arabic (Algeria)"), NULL, 0, 0, (void *) 0x1401, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
826     { (unichar_t *) N_("Arabic (Morocco)"), NULL, 0, 0, (void *) 0x1801, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
827     { (unichar_t *) N_("Arabic (Tunisia)"), NULL, 0, 0, (void *) 0x1C01, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
828     { (unichar_t *) N_("Arabic (Oman)"), NULL, 0, 0, (void *) 0x2001, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
829     { (unichar_t *) N_("Arabic (Yemen)"), NULL, 0, 0, (void *) 0x2401, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
830     { (unichar_t *) N_("Arabic (Syria)"), NULL, 0, 0, (void *) 0x2801, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
831     { (unichar_t *) N_("Arabic (Jordan)"), NULL, 0, 0, (void *) 0x2c01, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
832     { (unichar_t *) N_("Arabic (Lebanon)"), NULL, 0, 0, (void *) 0x3001, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
833     { (unichar_t *) N_("Arabic (Kuwait)"), NULL, 0, 0, (void *) 0x3401, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
834     { (unichar_t *) N_("Arabic (U.A.E.)"), NULL, 0, 0, (void *) 0x3801, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
835     { (unichar_t *) N_("Arabic (Bahrain)"), NULL, 0, 0, (void *) 0x3c01, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
836     { (unichar_t *) N_("Arabic (Qatar)"), NULL, 0, 0, (void *) 0x4001, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
837     { (unichar_t *) N_("Lang|Armenian"), NULL, 0, 0, (void *) 0x42b, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
838     { (unichar_t *) N_("Assamese"), NULL, 0, 0, (void *) 0x44d, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
839     { (unichar_t *) N_("Azeri (Latin)"), NULL, 0, 0, (void *) 0x42c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
840     { (unichar_t *) N_("Azeri (Cyrillic)"), NULL, 0, 0, (void *) 0x82c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
841     { (unichar_t *) N_("Basque"), NULL, 0, 0, (void *) 0x42d, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
842     { (unichar_t *) N_("Byelorussian"), NULL, 0, 0, (void *) 0x423, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
843     { (unichar_t *) N_("Lang|Bengali"), NULL, 0, 0, (void *) 0x445, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
844     { (unichar_t *) N_("Bengali Bangladesh"), NULL, 0, 0, (void *) 0x845, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
845     { (unichar_t *) N_("Bulgarian"), NULL, 0, 0, (void *) 0x402, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
846     { (unichar_t *) N_("Burmese"), NULL, 0, 0, (void *) 0x455, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
847     { (unichar_t *) N_("Catalan"), NULL, 0, 0, (void *) 0x403, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
848     { (unichar_t *) N_("Cambodian"), NULL, 0, 0, (void *) 0x453, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
849     { (unichar_t *) N_("Lang|Cherokee"), NULL, 0, 0, (void *) 0x45c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
850     { (unichar_t *) N_("Chinese (Taiwan)"), NULL, 0, 0, (void *) 0x404, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
851     { (unichar_t *) N_("Chinese (PRC)"), NULL, 0, 0, (void *) 0x804, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
852     { (unichar_t *) N_("Chinese (Hong Kong)"), NULL, 0, 0, (void *) 0xc04, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
853     { (unichar_t *) N_("Chinese (Singapore)"), NULL, 0, 0, (void *) 0x1004, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
854     { (unichar_t *) N_("Chinese (Macau)"), NULL, 0, 0, (void *) 0x1404, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
855     { (unichar_t *) N_("Croatian"), NULL, 0, 0, (void *) 0x41a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
856     { (unichar_t *) N_("Croatian Bosnia/Herzegovina"), NULL, 0, 0, (void *) 0x101a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
857     { (unichar_t *) N_("Czech"), NULL, 0, 0, (void *) 0x405, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
858     { (unichar_t *) N_("Danish"), NULL, 0, 0, (void *) 0x406, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
859     { (unichar_t *) N_("Divehi"), NULL, 0, 0, (void *) 0x465, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
860     { (unichar_t *) N_("Dutch"), NULL, 0, 0, (void *) 0x413, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
861     { (unichar_t *) N_("Flemish (Belgian Dutch)"), NULL, 0, 0, (void *) 0x813, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
862     { (unichar_t *) N_("Edo"), NULL, 0, 0, (void *) 0x466, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
863     { (unichar_t *) N_("English (British)"), NULL, 0, 0, (void *) 0x809, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
864     { (unichar_t *) N_("English (US)"), NULL, 0, 0, (void *) 0x409, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
865     { (unichar_t *) N_("English (Canada)"), NULL, 0, 0, (void *) 0x1009, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
866     { (unichar_t *) N_("English (Australian)"), NULL, 0, 0, (void *) 0xc09, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
867     { (unichar_t *) N_("English (New Zealand)"), NULL, 0, 0, (void *) 0x1409, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
868     { (unichar_t *) N_("English (Irish)"), NULL, 0, 0, (void *) 0x1809, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
869     { (unichar_t *) N_("English (South Africa)"), NULL, 0, 0, (void *) 0x1c09, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
870     { (unichar_t *) N_("English (Jamaica)"), NULL, 0, 0, (void *) 0x2009, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
871     { (unichar_t *) N_("English (Caribbean)"), NULL, 0, 0, (void *) 0x2409, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
872     { (unichar_t *) N_("English (Belize)"), NULL, 0, 0, (void *) 0x2809, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
873     { (unichar_t *) N_("English (Trinidad)"), NULL, 0, 0, (void *) 0x2c09, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
874     { (unichar_t *) N_("English (Zimbabwe)"), NULL, 0, 0, (void *) 0x3009, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
875     { (unichar_t *) N_("English (Philippines)"), NULL, 0, 0, (void *) 0x3409, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
876     { (unichar_t *) N_("English (Indonesia)"), NULL, 0, 0, (void *) 0x3809, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
877     { (unichar_t *) N_("English (Hong Kong)"), NULL, 0, 0, (void *) 0x3c09, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
878     { (unichar_t *) N_("English (India)"), NULL, 0, 0, (void *) 0x4009, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
879     { (unichar_t *) N_("English (Malaysia)"), NULL, 0, 0, (void *) 0x4409, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
880     { (unichar_t *) N_("Estonian"), NULL, 0, 0, (void *) 0x425, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
881     { (unichar_t *) N_("Faeroese"), NULL, 0, 0, (void *) 0x438, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
882     { (unichar_t *) N_("Lang|Farsi"), NULL, 0, 0, (void *) 0x429, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
883     { (unichar_t *) N_("Filipino"), NULL, 0, 0, (void *) 0x464, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
884     { (unichar_t *) N_("Finnish"), NULL, 0, 0, (void *) 0x40b, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
885     { (unichar_t *) N_("French French"), NULL, 0, 0, (void *) 0x40c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
886     { (unichar_t *) N_("French Belgium"), NULL, 0, 0, (void *) 0x80c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
887     { (unichar_t *) N_("French Canadian"), NULL, 0, 0, (void *) 0xc0c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
888     { (unichar_t *) N_("French Swiss"), NULL, 0, 0, (void *) 0x100c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
889     { (unichar_t *) N_("French Luxembourg"), NULL, 0, 0, (void *) 0x140c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
890     { (unichar_t *) N_("French Monaco"), NULL, 0, 0, (void *) 0x180c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
891     { (unichar_t *) N_("French West Indies"), NULL, 0, 0, (void *) 0x1c0c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
892     { (unichar_t *) NU_("French Réunion"), NULL, 0, 0, (void *) 0x200c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
893     { (unichar_t *) N_("French D.R. Congo"), NULL, 0, 0, (void *) 0x240c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
894     { (unichar_t *) N_("French Senegal"), NULL, 0, 0, (void *) 0x280c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
895     { (unichar_t *) N_("French Camaroon"), NULL, 0, 0, (void *) 0x2c0c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
896     { (unichar_t *) NU_("French Côte d'Ivoire"), NULL, 0, 0, (void *) 0x300c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
897     { (unichar_t *) N_("French Mali"), NULL, 0, 0, (void *) 0x340c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
898     { (unichar_t *) N_("French Morocco"), NULL, 0, 0, (void *) 0x380c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
899     { (unichar_t *) N_("French Haiti"), NULL, 0, 0, (void *) 0x3c0c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
900     { (unichar_t *) N_("French North Africa"), NULL, 0, 0, (void *) 0xe40c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
901     { (unichar_t *) N_("Frisian"), NULL, 0, 0, (void *) 0x462, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
902     { (unichar_t *) N_("Fulfulde"), NULL, 0, 0, (void *) 0x467, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
903     { (unichar_t *) N_("Gaelic (Scottish)"), NULL, 0, 0, (void *) 0x43c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
904     { (unichar_t *) N_("Gaelic (Irish)"), NULL, 0, 0, (void *) 0x83c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
905     { (unichar_t *) N_("Galician"), NULL, 0, 0, (void *) 0x467, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
906     { (unichar_t *) N_("Lang|Georgian"), NULL, 0, 0, (void *) 0x437, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
907     { (unichar_t *) N_("German German"), NULL, 0, 0, (void *) 0x407, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
908     { (unichar_t *) N_("German Swiss"), NULL, 0, 0, (void *) 0x807, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
909     { (unichar_t *) N_("German Austrian"), NULL, 0, 0, (void *) 0xc07, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
910     { (unichar_t *) N_("German Luxembourg"), NULL, 0, 0, (void *) 0x1007, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
911     { (unichar_t *) N_("German Liechtenstein"), NULL, 0, 0, (void *) 0x1407, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
912     { (unichar_t *) N_("Lang|Greek"), NULL, 0, 0, (void *) 0x408, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
913     { (unichar_t *) N_("Guarani"), NULL, 0, 0, (void *) 0x474, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
914     { (unichar_t *) N_("Lang|Gujarati"), NULL, 0, 0, (void *) 0x447, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
915     { (unichar_t *) N_("Hausa"), NULL, 0, 0, (void *) 0x468, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
916     { (unichar_t *) N_("Hawaiian"), NULL, 0, 0, (void *) 0x475, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
917     { (unichar_t *) N_("Lang|Hebrew"), NULL, 0, 0, (void *) 0x40d, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
918     { (unichar_t *) N_("Hindi"), NULL, 0, 0, (void *) 0x439, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
919     { (unichar_t *) N_("Hungarian"), NULL, 0, 0, (void *) 0x40e, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
920     { (unichar_t *) N_("Ibibio"), NULL, 0, 0, (void *) 0x469, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
921     { (unichar_t *) N_("Icelandic"), NULL, 0, 0, (void *) 0x40f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
922     { (unichar_t *) N_("Igbo"), NULL, 0, 0, (void *) 0x470, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
923     { (unichar_t *) N_("Indonesian"), NULL, 0, 0, (void *) 0x421, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
924     { (unichar_t *) N_("Inuktitut"), NULL, 0, 0, (void *) 0x45d, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
925     { (unichar_t *) N_("Italian"), NULL, 0, 0, (void *) 0x410, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
926     { (unichar_t *) N_("Italian Swiss"), NULL, 0, 0, (void *) 0x810, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
927     { (unichar_t *) N_("Japanese"), NULL, 0, 0, (void *) 0x411, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
928     { (unichar_t *) N_("Lang|Kannada"), NULL, 0, 0, (void *) 0x44b, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
929     { (unichar_t *) N_("Kanuri"), NULL, 0, 0, (void *) 0x471, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
930     { (unichar_t *) N_("Kashmiri (India)"), NULL, 0, 0, (void *) 0x860, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
931     { (unichar_t *) N_("Kazakh"), NULL, 0, 0, (void *) 0x43f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
932     { (unichar_t *) N_("Lang|Khmer"), NULL, 0, 0, (void *) 0x453, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
933     { (unichar_t *) N_("Kirghiz"), NULL, 0, 0, (void *) 0x440, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
934     { (unichar_t *) N_("Konkani"), NULL, 0, 0, (void *) 0x457, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
935     { (unichar_t *) N_("Korean"), NULL, 0, 0, (void *) 0x412, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
936     { (unichar_t *) N_("Korean (Johab)"), NULL, 0, 0, (void *) 0x812, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
937     { (unichar_t *) N_("Lao"), NULL, 0, 0, (void *) 0x454, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
938     { (unichar_t *) N_("Latvian"), NULL, 0, 0, (void *) 0x426, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
939     { (unichar_t *) N_("Lang|Latin"), NULL, 0, 0, (void *) 0x476, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
940     { (unichar_t *) N_("Lithuanian"), NULL, 0, 0, (void *) 0x427, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
941     { (unichar_t *) N_("Lithuanian (Classic)"), NULL, 0, 0, (void *) 0x827, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
942     { (unichar_t *) N_("Macedonian"), NULL, 0, 0, (void *) 0x42f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
943     { (unichar_t *) N_("Malay"), NULL, 0, 0, (void *) 0x43e, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
944     { (unichar_t *) N_("Malay (Brunei)"), NULL, 0, 0, (void *) 0x83e, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
945     { (unichar_t *) N_("Lang|Malayalam"), NULL, 0, 0, (void *) 0x44c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
946     { (unichar_t *) N_("Maltese"), NULL, 0, 0, (void *) 0x43a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
947     { (unichar_t *) N_("Manipuri"), NULL, 0, 0, (void *) 0x458, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
948     { (unichar_t *) N_("Maori"), NULL, 0, 0, (void *) 0x481, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
949     { (unichar_t *) N_("Marathi"), NULL, 0, 0, (void *) 0x44e, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
950     { (unichar_t *) N_("Mongolian (Cyrillic)"), NULL, 0, 0, (void *) 0x450, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
951     { (unichar_t *) N_("Mongolian (Mongolian)"), NULL, 0, 0, (void *) 0x850, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
952     { (unichar_t *) N_("Nepali"), NULL, 0, 0, (void *) 0x461, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
953     { (unichar_t *) N_("Nepali (India)"), NULL, 0, 0, (void *) 0x861, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
954     { (unichar_t *) N_("Norwegian (Bokmal)"), NULL, 0, 0, (void *) 0x414, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
955     { (unichar_t *) N_("Norwegian (Nynorsk)"), NULL, 0, 0, (void *) 0x814, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
956     { (unichar_t *) N_("Lang|Oriya"), NULL, 0, 0, (void *) 0x448, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
957     { (unichar_t *) N_("Oromo"), NULL, 0, 0, (void *) 0x472, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
958     { (unichar_t *) N_("Papiamentu"), NULL, 0, 0, (void *) 0x479, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
959     { (unichar_t *) N_("Pashto"), NULL, 0, 0, (void *) 0x463, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
960     { (unichar_t *) N_("Polish"), NULL, 0, 0, (void *) 0x415, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
961     { (unichar_t *) N_("Portuguese (Portugal)"), NULL, 0, 0, (void *) 0x416, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
962     { (unichar_t *) N_("Portuguese (Brasil)"), NULL, 0, 0, (void *) 0x816, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
963     { (unichar_t *) N_("Punjabi (India)"), NULL, 0, 0, (void *) 0x446, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
964     { (unichar_t *) N_("Punjabi (Pakistan)"), NULL, 0, 0, (void *) 0x846, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
965     { (unichar_t *) N_("Quecha (Bolivia)"), NULL, 0, 0, (void *) 0x46b, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
966     { (unichar_t *) N_("Quecha (Ecuador)"), NULL, 0, 0, (void *) 0x86b, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
967     { (unichar_t *) N_("Quecha (Peru)"), NULL, 0, 0, (void *) 0xc6b, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
968     { (unichar_t *) N_("Rhaeto-Romanic"), NULL, 0, 0, (void *) 0x417, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
969     { (unichar_t *) N_("Romanian"), NULL, 0, 0, (void *) 0x418, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
970     { (unichar_t *) N_("Romanian (Moldova)"), NULL, 0, 0, (void *) 0x818, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
971     { (unichar_t *) N_("Russian"), NULL, 0, 0, (void *) 0x419, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
972     { (unichar_t *) N_("Russian (Moldova)"), NULL, 0, 0, (void *) 0x819, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
973     { (unichar_t *) N_("Sami (Lappish)"), NULL, 0, 0, (void *) 0x43b, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
974     { (unichar_t *) N_("Sanskrit"), NULL, 0, 0, (void *) 0x43b, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
975     { (unichar_t *) N_("Sepedi"), NULL, 0, 0, (void *) 0x46c, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
976     { (unichar_t *) N_("Serbian (Cyrillic)"), NULL, 0, 0, (void *) 0xc1a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
977     { (unichar_t *) N_("Serbian (Latin)"), NULL, 0, 0, (void *) 0x81a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
978     { (unichar_t *) N_("Sindhi India"), NULL, 0, 0, (void *) 0x459, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
979     { (unichar_t *) N_("Sindhi Pakistan"), NULL, 0, 0, (void *) 0x859, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
980     { (unichar_t *) N_("Lang|Sinhalese"), NULL, 0, 0, (void *) 0x45b, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
981     { (unichar_t *) N_("Slovak"), NULL, 0, 0, (void *) 0x41b, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
982     { (unichar_t *) N_("Slovenian"), NULL, 0, 0, (void *) 0x424, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
983     { (unichar_t *) N_("Sorbian"), NULL, 0, 0, (void *) 0x42e, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
984     { (unichar_t *) N_("Spanish (Traditional)"), NULL, 0, 0, (void *) 0x40a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
985     { (unichar_t *) N_("Spanish Mexico"), NULL, 0, 0, (void *) 0x80a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
986     { (unichar_t *) N_("Spanish (Modern)"), NULL, 0, 0, (void *) 0xc0a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
987     { (unichar_t *) N_("Spanish (Guatemala)"), NULL, 0, 0, (void *) 0x100a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
988     { (unichar_t *) N_("Spanish (Costa Rica)"), NULL, 0, 0, (void *) 0x140a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
989     { (unichar_t *) N_("Spanish (Panama)"), NULL, 0, 0, (void *) 0x180a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
990     { (unichar_t *) N_("Spanish (Dominican Republic)"), NULL, 0, 0, (void *) 0x1c0a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
991     { (unichar_t *) N_("Spanish (Venezuela)"), NULL, 0, 0, (void *) 0x200a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
992     { (unichar_t *) N_("Spanish (Colombia)"), NULL, 0, 0, (void *) 0x240a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
993     { (unichar_t *) N_("Spanish (Peru)"), NULL, 0, 0, (void *) 0x280a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
994     { (unichar_t *) N_("Spanish (Argentina)"), NULL, 0, 0, (void *) 0x2c0a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
995     { (unichar_t *) N_("Spanish (Ecuador)"), NULL, 0, 0, (void *) 0x300a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
996     { (unichar_t *) N_("Spanish (Chile)"), NULL, 0, 0, (void *) 0x340a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
997     { (unichar_t *) N_("Spanish (Uruguay)"), NULL, 0, 0, (void *) 0x380a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
998     { (unichar_t *) N_("Spanish (Paraguay)"), NULL, 0, 0, (void *) 0x3c0a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
999     { (unichar_t *) N_("Spanish (Bolivia)"), NULL, 0, 0, (void *) 0x400a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1000     { (unichar_t *) N_("Spanish (El Salvador)"), NULL, 0, 0, (void *) 0x440a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1001     { (unichar_t *) N_("Spanish (Honduras)"), NULL, 0, 0, (void *) 0x480a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1002     { (unichar_t *) N_("Spanish (Nicaragua)"), NULL, 0, 0, (void *) 0x4c0a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1003     { (unichar_t *) N_("Spanish (Puerto Rico)"), NULL, 0, 0, (void *) 0x500a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1004     { (unichar_t *) N_("Spanish (United States)"), NULL, 0, 0, (void *) 0x540a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1005     { (unichar_t *) N_("Spanish (Latin America)"), NULL, 0, 0, (void *) 0xe40a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1006     { (unichar_t *) N_("Sutu"), NULL, 0, 0, (void *) 0x430, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1007     { (unichar_t *) N_("Swahili (Kenyan)"), NULL, 0, 0, (void *) 0x441, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1008     { (unichar_t *) N_("Swedish (Sweden)"), NULL, 0, 0, (void *) 0x41d, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1009     { (unichar_t *) N_("Swedish (Finland)"), NULL, 0, 0, (void *) 0x81d, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1010     { (unichar_t *) N_("Lang|Syriac"), NULL, 0, 0, (void *) 0x45a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1011     { (unichar_t *) N_("Lang|Tagalog"), NULL, 0, 0, (void *) 0x464, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1012     { (unichar_t *) N_("Tajik"), NULL, 0, 0, (void *) 0x428, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1013     { (unichar_t *) N_("Tamazight (Arabic)"), NULL, 0, 0, (void *) 0x45f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1014     { (unichar_t *) N_("Tamazight (Latin)"), NULL, 0, 0, (void *) 0x85f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1015     { (unichar_t *) N_("Lang|Tamil"), NULL, 0, 0, (void *) 0x449, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1016     { (unichar_t *) N_("Tatar (Tatarstan)"), NULL, 0, 0, (void *) 0x444, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1017     { (unichar_t *) N_("Lang|Telugu"), NULL, 0, 0, (void *) 0x44a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1018     { (unichar_t *) N_("Lang|Thai"), NULL, 0, 0, (void *) 0x41e, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1019     { (unichar_t *) N_("Tibetan (PRC)"), NULL, 0, 0, (void *) 0x451, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1020     { (unichar_t *) N_("Tibetan Bhutan"), NULL, 0, 0, (void *) 0x851, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1021     { (unichar_t *) N_("Tigrinya Ethiopia"), NULL, 0, 0, (void *) 0x473, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1022     { (unichar_t *) N_("Tigrinyan Eritrea"), NULL, 0, 0, (void *) 0x873, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1023     { (unichar_t *) N_("Tsonga"), NULL, 0, 0, (void *) 0x431, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1024     { (unichar_t *) N_("Tswana"), NULL, 0, 0, (void *) 0x432, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1025     { (unichar_t *) N_("Turkish"), NULL, 0, 0, (void *) 0x41f, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1026     { (unichar_t *) N_("Turkmen"), NULL, 0, 0, (void *) 0x442, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1027     { (unichar_t *) N_("Lang|Uighur"), NULL, 0, 0, (void *) 0x480, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1028     { (unichar_t *) N_("Ukrainian"), NULL, 0, 0, (void *) 0x422, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1029     { (unichar_t *) N_("Urdu (Pakistan)"), NULL, 0, 0, (void *) 0x420, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1030     { (unichar_t *) N_("Urdu (India)"), NULL, 0, 0, (void *) 0x820, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1031     { (unichar_t *) N_("Uzbek (Latin)"), NULL, 0, 0, (void *) 0x443, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1032     { (unichar_t *) N_("Uzbek (Cyrillic)"), NULL, 0, 0, (void *) 0x843, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1033     { (unichar_t *) N_("Venda"), NULL, 0, 0, (void *) 0x433, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1034     { (unichar_t *) N_("Vietnamese"), NULL, 0, 0, (void *) 0x42a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1035     { (unichar_t *) N_("Welsh"), NULL, 0, 0, (void *) 0x452, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1036     { (unichar_t *) N_("Xhosa"), NULL, 0, 0, (void *) 0x434, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1037     { (unichar_t *) N_("Lang|Yi"), NULL, 0, 0, (void *) 0x478, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1038     { (unichar_t *) N_("Yiddish"), NULL, 0, 0, (void *) 0x43d, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1039     { (unichar_t *) N_("Yoruba"), NULL, 0, 0, (void *) 0x46a, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1040     { (unichar_t *) N_("Zulu"), NULL, 0, 0, (void *) 0x435, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1041     GTEXTINFO_EMPTY
1042 };
1043 /* There is a similar list at the end of python.c, untranslated strings for */
1044 /*  scripting use */
1045 static GTextInfo ttfnameids[] = {
1046 /* Put styles (docs call it subfamily) first because it is most likely to change */
1047     { (unichar_t *) N_("Styles (SubFamily)"), NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1048     { (unichar_t *) N_("Copyright"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1049     { (unichar_t *) N_("Family"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1050     { (unichar_t *) N_("Fullname"), NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1051     { (unichar_t *) N_("UniqueID"), NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1052     { (unichar_t *) N_("Version"), NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1053 /* Don't give user access to PostScriptName, we set that elsewhere */
1054     { (unichar_t *) N_("Trademark"), NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1055     { (unichar_t *) N_("Manufacturer"), NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1056     { (unichar_t *) N_("Designer"), NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1057     { (unichar_t *) N_("Descriptor"), NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1058     { (unichar_t *) N_("Vendor URL"), NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1059     { (unichar_t *) N_("Designer URL"), NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1060     { (unichar_t *) N_("License"), NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1061     { (unichar_t *) N_("License URL"), NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1062 /* slot 15 is reserved */
1063     { (unichar_t *) N_("Preferred Family"), NULL, 0, 0, (void *) 16, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1064     { (unichar_t *) N_("Preferred Styles"), NULL, 0, 0, (void *) 17, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1065     { (unichar_t *) N_("Compatible Full"), NULL, 0, 0, (void *) 18, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1066     { (unichar_t *) N_("Sample Text"), NULL, 0, 0, (void *) 19, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1067     { (unichar_t *) N_("CID findfont Name"), NULL, 0, 0, (void *) 20, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1068     { (unichar_t *) N_("WWS Family"), NULL, 0, 0, (void *) 21, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1069     { (unichar_t *) N_("WWS Subfamily"), NULL, 0, 0, (void *) 22, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1070     GTEXTINFO_EMPTY
1071 };
1072 static GTextInfo otfssfeattags[] = {
1073 /* These should not be translated. They are tags */
1074     { (unichar_t *) "ss01", NULL, 0, 0, (void *) (intpt) CHR('s','s','0','1'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1075     { (unichar_t *) "ss02", NULL, 0, 0, (void *) (intpt) CHR('s','s','0','2'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1076     { (unichar_t *) "ss03", NULL, 0, 0, (void *) (intpt) CHR('s','s','0','3'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1077     { (unichar_t *) "ss04", NULL, 0, 0, (void *) (intpt) CHR('s','s','0','4'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1078     { (unichar_t *) "ss05", NULL, 0, 0, (void *) (intpt) CHR('s','s','0','5'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1079     { (unichar_t *) "ss06", NULL, 0, 0, (void *) (intpt) CHR('s','s','0','6'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1080     { (unichar_t *) "ss07", NULL, 0, 0, (void *) (intpt) CHR('s','s','0','7'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1081     { (unichar_t *) "ss08", NULL, 0, 0, (void *) (intpt) CHR('s','s','0','8'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1082     { (unichar_t *) "ss09", NULL, 0, 0, (void *) (intpt) CHR('s','s','0','9'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1083     { (unichar_t *) "ss10", NULL, 0, 0, (void *) (intpt) CHR('s','s','1','0'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1084     { (unichar_t *) "ss11", NULL, 0, 0, (void *) (intpt) CHR('s','s','1','1'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1085     { (unichar_t *) "ss12", NULL, 0, 0, (void *) (intpt) CHR('s','s','1','2'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1086     { (unichar_t *) "ss13", NULL, 0, 0, (void *) (intpt) CHR('s','s','1','3'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1087     { (unichar_t *) "ss14", NULL, 0, 0, (void *) (intpt) CHR('s','s','1','4'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1088     { (unichar_t *) "ss15", NULL, 0, 0, (void *) (intpt) CHR('s','s','1','5'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1089     { (unichar_t *) "ss16", NULL, 0, 0, (void *) (intpt) CHR('s','s','1','6'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1090     { (unichar_t *) "ss17", NULL, 0, 0, (void *) (intpt) CHR('s','s','1','7'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1091     { (unichar_t *) "ss18", NULL, 0, 0, (void *) (intpt) CHR('s','s','1','8'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1092     { (unichar_t *) "ss19", NULL, 0, 0, (void *) (intpt) CHR('s','s','1','9'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1093     { (unichar_t *) "ss20", NULL, 0, 0, (void *) (intpt) CHR('s','s','2','0'), NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1094     GTEXTINFO_EMPTY
1095 };
1096 /* Put styles (docs call it subfamily) first because it is most likely to change */
1097 static GTextInfo unicoderangenames[] = {
1098     { (unichar_t *) N_("Basic Latin"),				NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1099     { (unichar_t *) N_("Latin-1 Supplement"),			NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1100     { (unichar_t *) N_("Latin Extended-A"),			NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1101     { (unichar_t *) N_("Latin Extended-B"),			NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1102     { (unichar_t *) N_("IPA Ext & Phonetic Ext (& Supplement)"),NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1103     { (unichar_t *) N_("Modifier Letters & Modifier Tone Letters"),
1104 								NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1105     { (unichar_t *) N_("Combining Diacritical Marks (& Supplement)"),
1106 								NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1107     { (unichar_t *) N_("Greek and Coptic"),			NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1108     { (unichar_t *) N_("Coptic"),				NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1109     { (unichar_t *) N_("Cyrillic (& Supplement & Ext A/B)"),	NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1110     { (unichar_t *) N_("Armenian"),				NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1111     { (unichar_t *) N_("Hebrew"),				NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1112     { (unichar_t *) N_("Vai"),					NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1113     { (unichar_t *) N_("Arabic (& Supplement)"),		NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1114     { (unichar_t *) N_("NKo"),					NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1115     { (unichar_t *) N_("Devanagari"),				NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1116     { (unichar_t *) N_("Bengali"),				NULL, 0, 0, (void *) 16, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1117     { (unichar_t *) N_("Gurmukhi"),				NULL, 0, 0, (void *) 17, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1118     { (unichar_t *) N_("Gujarati"),				NULL, 0, 0, (void *) 18, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1119     { (unichar_t *) N_("Oriya"),				NULL, 0, 0, (void *) 19, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1120     { (unichar_t *) N_("Tamil"),				NULL, 0, 0, (void *) 20, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1121     { (unichar_t *) N_("Telugu"),				NULL, 0, 0, (void *) 21, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1122     { (unichar_t *) N_("Kannada"),				NULL, 0, 0, (void *) 22, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1123     { (unichar_t *) N_("Malayalam"),				NULL, 0, 0, (void *) 23, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1124     { (unichar_t *) N_("Thai"),					NULL, 0, 0, (void *) 24, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1125     { (unichar_t *) N_("Lao"),					NULL, 0, 0, (void *) 25, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1126     { (unichar_t *) N_("Georgian (& Supplement)"),		NULL, 0, 0, (void *) 26, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1127     { (unichar_t *) N_("Balinese"),				NULL, 0, 0, (void *) 27, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1128     { (unichar_t *) N_("Hangul Jamo"),				NULL, 0, 0, (void *) 28, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1129     { (unichar_t *) N_("Latin Extended Additional/C/D"),	NULL, 0, 0, (void *) 29, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1130     { (unichar_t *) N_("Greek Extended"),			NULL, 0, 0, (void *) 30, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1131     { (unichar_t *) N_("General/Supplemental Punctuation"),	NULL, 0, 0, (void *) 31, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1132     { (unichar_t *) N_("Subscripts and Superscripts"),		NULL, 0, 0, (void *) 32, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1133     { (unichar_t *) N_("Currency Symbols"),			NULL, 0, 0, (void *) 33, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1134     { (unichar_t *) N_("Combining Diacritical Marks for Symbols"), NULL, 0, 0, (void *) 34, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1135     { (unichar_t *) N_("Letterlike Symbols"),			NULL, 0, 0, (void *) 35, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1136     { (unichar_t *) N_("Numeric Forms"),			NULL, 0, 0, (void *) 36, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1137     { (unichar_t *) N_("Arrows & Sup Arrows A/B & Misc Arrows"),NULL, 0, 0, (void *) 37, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1138     { (unichar_t *) N_("Math Operators & Sup Math Operators & Misc Math Symbols A/B"),
1139 								NULL, 0, 0, (void *) 38, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1140     { (unichar_t *) N_("Miscellaneous Technical"),		NULL, 0, 0, (void *) 39, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1141     { (unichar_t *) N_("Control Pictures"),			NULL, 0, 0, (void *) 40, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1142     { (unichar_t *) N_("Optical Character Recognition"),	NULL, 0, 0, (void *) 41, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1143     { (unichar_t *) N_("Enclosed Alphanumerics"),		NULL, 0, 0, (void *) 42, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1144     { (unichar_t *) N_("Box Drawing"),				NULL, 0, 0, (void *) 43, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1145     { (unichar_t *) N_("Block Elements"),			NULL, 0, 0, (void *) 44, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1146     { (unichar_t *) N_("Geometric Shapes"),			NULL, 0, 0, (void *) 45, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1147     { (unichar_t *) N_("Miscellaneous Symbols"),		NULL, 0, 0, (void *) 46, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1148     { (unichar_t *) N_("Dingbats"),				NULL, 0, 0, (void *) 47, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1149     { (unichar_t *) N_("CJK Symbols and Punctuation"),		NULL, 0, 0, (void *) 48, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1150     { (unichar_t *) N_("Hiragana"),				NULL, 0, 0, (void *) 49, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1151     { (unichar_t *) N_("Katakana (& Phonetic Extensions)"),	NULL, 0, 0, (void *) 50, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1152     { (unichar_t *) N_("Bopomofo (& Extended)"),		NULL, 0, 0, (void *) 51, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1153     { (unichar_t *) N_("Hangul Compatibility Jamo"),		NULL, 0, 0, (void *) 52, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1154     { (unichar_t *) N_("Phags-pa"),				NULL, 0, 0, (void *) 53, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1155     { (unichar_t *) N_("Enclosed CJK Letters and Months"),	NULL, 0, 0, (void *) 54, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1156     { (unichar_t *) N_("CJK Compatibility"),			NULL, 0, 0, (void *) 55, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1157     { (unichar_t *) N_("Hangul Syllables"),			NULL, 0, 0, (void *) 56, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1158     { (unichar_t *) N_("Non-Basic Multilingual Plane"),		NULL, 0, 0, (void *) 57, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1159     { (unichar_t *) N_("Phoenician"),				NULL, 0, 0, (void *) 58, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1160     { (unichar_t *) N_("CJK (& Ext A/B) & CJK Radicals Sup & Kangxi & IDC & Kanbun"),
1161 								NULL, 0, 0, (void *) 59, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1162     { (unichar_t *) N_("Private Use Area"),			NULL, 0, 0, (void *) 60, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1163     { (unichar_t *) N_("CJK Strokes & CJK Compat Ideographs (& Sup)"),
1164 								NULL, 0, 0, (void *) 61, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1165     { (unichar_t *) N_("Alphabetic Presentation Forms"),	NULL, 0, 0, (void *) 62, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1166     { (unichar_t *) N_("Arabic Presentation Forms-A"),		NULL, 0, 0, (void *) 63, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1167     { (unichar_t *) N_("Combining Half Marks"),			NULL, 0, 0, (void *) 64, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1168     { (unichar_t *) N_("Vertical Forms & CJK Compatibility Forms"),
1169 								NULL, 0, 0, (void *) 65, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1170     { (unichar_t *) N_("Small Form Variants"),			NULL, 0, 0, (void *) 66, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1171     { (unichar_t *) N_("Arabic Presentation Forms-B"),		NULL, 0, 0, (void *) 67, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1172     { (unichar_t *) N_("Halfwidth and Fullwidth Forms"),	NULL, 0, 0, (void *) 68, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1173     { (unichar_t *) N_("Specials"),				NULL, 0, 0, (void *) 69, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1174     { (unichar_t *) N_("Tibetan"),				NULL, 0, 0, (void *) 70, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1175     { (unichar_t *) N_("Syriac"),				NULL, 0, 0, (void *) 71, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1176     { (unichar_t *) N_("Thaana"),				NULL, 0, 0, (void *) 72, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1177     { (unichar_t *) N_("Sinhala"),				NULL, 0, 0, (void *) 73, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1178     { (unichar_t *) N_("Myanmar"),				NULL, 0, 0, (void *) 74, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1179     { (unichar_t *) N_("Ethiopic (& Supplement/Extended)"), 	NULL, 0, 0, (void *) 75, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1180     { (unichar_t *) N_("Cherokee"),				NULL, 0, 0, (void *) 76, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1181     { (unichar_t *) N_("Unified Canadian Aboriginal Syllabics"),NULL, 0, 0, (void *) 77, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1182     { (unichar_t *) N_("Ogham"),				NULL, 0, 0, (void *) 78, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1183     { (unichar_t *) N_("Runic"),				NULL, 0, 0, (void *) 79, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1184     { (unichar_t *) N_("Khmer & Khmer Symbols"),		NULL, 0, 0, (void *) 80, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1185     { (unichar_t *) N_("Mongolian"),				NULL, 0, 0, (void *) 81, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1186     { (unichar_t *) N_("Braille Patterns"),			NULL, 0, 0, (void *) 82, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1187     { (unichar_t *) N_("Yi Syllables/Radicals"),		NULL, 0, 0, (void *) 83, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1188     { (unichar_t *) N_("Tagalog/Hanunoo/Buhid/Tagbanwa"),	NULL, 0, 0, (void *) 84, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1189     { (unichar_t *) N_("Old Italic"),				NULL, 0, 0, (void *) 85, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1190     { (unichar_t *) N_("Gothic"),				NULL, 0, 0, (void *) 86, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1191     { (unichar_t *) N_("Deseret"),				NULL, 0, 0, (void *) 87, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1192     { (unichar_t *) N_("Byzantine Music & Music & Ancient Greek Music"),
1193 								NULL, 0, 0, (void *) 88, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1194     { (unichar_t *) N_("Mathematical Alphanumeric Symbols"),	NULL, 0, 0, (void *) 89, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1195     { (unichar_t *) N_("Supplementary Private Use Area A/B"),	NULL, 0, 0, (void *) 90, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1196     { (unichar_t *) N_("Variation Selectors (& Supplement)"), 	NULL, 0, 0, (void *) 91, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1197     { (unichar_t *) N_("Tags"),					NULL, 0, 0, (void *) 92, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1198     { (unichar_t *) N_("Limbu"),				NULL, 0, 0, (void *) 93, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1199     { (unichar_t *) N_("Tai Le"),				NULL, 0, 0, (void *) 94, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1200     { (unichar_t *) N_("New Tai Lue"),				NULL, 0, 0, (void *) 95, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1201     { (unichar_t *) N_("Buginese"),				NULL, 0, 0, (void *) 96, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1202     { (unichar_t *) N_("Glagolitic"),				NULL, 0, 0, (void *) 97, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1203     { (unichar_t *) N_("Tifinagh"),				NULL, 0, 0, (void *) 98, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1204     { (unichar_t *) N_("Yijing Hexagram Symbols"),		NULL, 0, 0, (void *) 99, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1205     { (unichar_t *) N_("Syloti Nagri"),				NULL, 0, 0, (void *) 100, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1206     { (unichar_t *) N_("Linear B Syllabary/Ideograms & Aegean Numbers"),
1207 								NULL, 0, 0, (void *) 101, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1208     { (unichar_t *) N_("Ancient Greek Numbers"),		NULL, 0, 0, (void *) 102, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1209     { (unichar_t *) N_("Ugaritic"),				NULL, 0, 0, (void *) 103, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1210     { (unichar_t *) N_("Old Persian"),				NULL, 0, 0, (void *) 104, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1211     { (unichar_t *) N_("Shavian"),				NULL, 0, 0, (void *) 105, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1212     { (unichar_t *) N_("Osmanya"),				NULL, 0, 0, (void *) 106, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1213     { (unichar_t *) N_("Cypriot Syllabary"),			NULL, 0, 0, (void *) 107, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1214     { (unichar_t *) N_("Kharoshthi"),				NULL, 0, 0, (void *) 108, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1215     { (unichar_t *) N_("Tai Xuan Jing Symbols"),		NULL, 0, 0, (void *) 109, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1216     { (unichar_t *) N_("Cuneiform (& Numbers and Punctuation)"),NULL, 0, 0, (void *) 110, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1217     { (unichar_t *) N_("Counting Rod Numerals"),		NULL, 0, 0, (void *) 111, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1218     { (unichar_t *) N_("Sundanese"),				NULL, 0, 0, (void *) 112, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1219     { (unichar_t *) N_("Lepcha"),				NULL, 0, 0, (void *) 113, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1220     { (unichar_t *) N_("Ol Chiki"),				NULL, 0, 0, (void *) 114, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1221     { (unichar_t *) N_("Saurashtra"),				NULL, 0, 0, (void *) 115, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1222     { (unichar_t *) N_("Kayah Li"),				NULL, 0, 0, (void *) 116, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1223     { (unichar_t *) N_("Rejang"),				NULL, 0, 0, (void *) 117, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1224     { (unichar_t *) N_("Cham"),					NULL, 0, 0, (void *) 118, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1225     { (unichar_t *) N_("Ancient Symbols"),			NULL, 0, 0, (void *) 119, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1226     { (unichar_t *) N_("Phaistos Disc"),			NULL, 0, 0, (void *) 120, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1227     { (unichar_t *) N_("Lycian/Carian/Lydian"),			NULL, 0, 0, (void *) 121, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1228     { (unichar_t *) N_("Mahjong/Domino Tiles"),			NULL, 0, 0, (void *) 122, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1229     { (unichar_t *) N_("Unassigned Bit 123"),			NULL, 0, 0, (void *) 123, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1230     { (unichar_t *) N_("Unassigned Bit 124"),			NULL, 0, 0, (void *) 124, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1231     { (unichar_t *) N_("Unassigned Bit 125"),			NULL, 0, 0, (void *) 125, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1232     { (unichar_t *) N_("Unassigned Bit 126"),			NULL, 0, 0, (void *) 126, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1233     { (unichar_t *) N_("Unassigned Bit 127"),			NULL, 0, 0, (void *) 127, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1234     GTEXTINFO_EMPTY
1235 };
1236 static GTextInfo codepagenames[] = {
1237     { (unichar_t *) N_("1252, Latin-1"),			NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1238     { (unichar_t *) N_("1250, Latin-2 (Eastern Europe)"),	NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1239     { (unichar_t *) N_("1251, Cyrillic"),			NULL, 0, 0, (void *) 2, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1240     { (unichar_t *) N_("1253, Greek"),				NULL, 0, 0, (void *) 3, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1241     { (unichar_t *) N_("1254, Turkish"),			NULL, 0, 0, (void *) 4, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1242     { (unichar_t *) N_("1255, Hebrew"),				NULL, 0, 0, (void *) 5, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1243     { (unichar_t *) N_("1256, Arabic"),				NULL, 0, 0, (void *) 6, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1244     { (unichar_t *) N_("1257, Windows Baltic"),			NULL, 0, 0, (void *) 7, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1245     { (unichar_t *) N_("1258, Vietnamese"),			NULL, 0, 0, (void *) 8, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1246     { (unichar_t *) N_("Reserved Bit 9"),			NULL, 0, 0, (void *) 9, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1247     { (unichar_t *) N_("Reserved Bit 10"),			NULL, 0, 0, (void *) 10, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1248     { (unichar_t *) N_("Reserved Bit 11"),			NULL, 0, 0, (void *) 11, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1249     { (unichar_t *) N_("Reserved Bit 12"),			NULL, 0, 0, (void *) 12, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1250     { (unichar_t *) N_("Reserved Bit 13"),			NULL, 0, 0, (void *) 13, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1251     { (unichar_t *) N_("Reserved Bit 14"),			NULL, 0, 0, (void *) 14, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1252     { (unichar_t *) N_("Reserved Bit 15"),			NULL, 0, 0, (void *) 15, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1253     { (unichar_t *) N_("874, Thai"),				NULL, 0, 0, (void *) 16, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1254     { (unichar_t *) N_("932, JIS/Japan"),			NULL, 0, 0, (void *) 17, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1255     { (unichar_t *) N_("936, Simplified Chinese"),		NULL, 0, 0, (void *) 18, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1256     { (unichar_t *) N_("949, Korean Wansung"),			NULL, 0, 0, (void *) 19, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1257     { (unichar_t *) N_("950, Traditional Chinese"),		NULL, 0, 0, (void *) 20, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1258     { (unichar_t *) N_("1361, Korean Johab"),			NULL, 0, 0, (void *) 21, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1259     { (unichar_t *) N_("Reserved Bit 22"),			NULL, 0, 0, (void *) 22, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1260     { (unichar_t *) N_("Reserved Bit 23"),			NULL, 0, 0, (void *) 23, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1261     { (unichar_t *) N_("Reserved Bit 24"),			NULL, 0, 0, (void *) 24, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1262     { (unichar_t *) N_("Reserved Bit 25"),			NULL, 0, 0, (void *) 25, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1263     { (unichar_t *) N_("Reserved Bit 26"),			NULL, 0, 0, (void *) 26, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1264     { (unichar_t *) N_("Reserved Bit 27"),			NULL, 0, 0, (void *) 27, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1265     { (unichar_t *) N_("Reserved Bit 28"),			NULL, 0, 0, (void *) 28, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1266     { (unichar_t *) N_("Mac Roman"),				NULL, 0, 0, (void *) 29, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1267     { (unichar_t *) N_("OEM Charset"),				NULL, 0, 0, (void *) 30, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1268     { (unichar_t *) N_("Symbol Charset"),			NULL, 0, 0, (void *) 31, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1269     { (unichar_t *) N_("Reserved Bit 32"),			NULL, 0, 0, (void *) 32, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1270     { (unichar_t *) N_("Reserved Bit 33"),			NULL, 0, 0, (void *) 33, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1271     { (unichar_t *) N_("Reserved Bit 34"), 			NULL, 0, 0, (void *) 34, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1272     { (unichar_t *) N_("Reserved Bit 35"),			NULL, 0, 0, (void *) 35, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1273     { (unichar_t *) N_("Reserved Bit 36"),			NULL, 0, 0, (void *) 36, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1274     { (unichar_t *) N_("Reserved Bit 37"),			NULL, 0, 0, (void *) 37, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1275     { (unichar_t *) N_("Reserved Bit 38"), 			NULL, 0, 0, (void *) 38, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1276     { (unichar_t *) N_("Reserved Bit 39"),			NULL, 0, 0, (void *) 39, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1277     { (unichar_t *) N_("Reserved Bit 40"),			NULL, 0, 0, (void *) 40, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1278     { (unichar_t *) N_("Reserved Bit 41"),			NULL, 0, 0, (void *) 41, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1279     { (unichar_t *) N_("Reserved Bit 42"),			NULL, 0, 0, (void *) 42, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1280     { (unichar_t *) N_("Reserved Bit 43"),			NULL, 0, 0, (void *) 43, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1281     { (unichar_t *) N_("Reserved Bit 44"),			NULL, 0, 0, (void *) 44, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1282     { (unichar_t *) N_("Reserved Bit 45"),			NULL, 0, 0, (void *) 45, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1283     { (unichar_t *) N_("Reserved Bit 46"),			NULL, 0, 0, (void *) 46, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1284     { (unichar_t *) N_("Reserved Bit 47"),			NULL, 0, 0, (void *) 47, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1285     { (unichar_t *) N_("869, IBM Greek"),			NULL, 0, 0, (void *) 48, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1286     { (unichar_t *) N_("866, MS-DOS Russian"),			NULL, 0, 0, (void *) 49, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1287     { (unichar_t *) N_("865, MS_DOS Nordic"),			NULL, 0, 0, (void *) 50, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1288     { (unichar_t *) N_("864, Arabic"),				NULL, 0, 0, (void *) 51, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1289     { (unichar_t *) N_("863, MS-DOS Canadian French"),		NULL, 0, 0, (void *) 52, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1290     { (unichar_t *) N_("862, Hebrew"),				NULL, 0, 0, (void *) 53, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1291     { (unichar_t *) N_("861, MS-DOS Icelandic"),		NULL, 0, 0, (void *) 54, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1292     { (unichar_t *) N_("860, MS-DOS Portuguese"),		NULL, 0, 0, (void *) 55, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1293     { (unichar_t *) N_("857, IBM Turkish"),			NULL, 0, 0, (void *) 56, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1294     { (unichar_t *) N_("855, IBM Cyrillic; primarily Russian"),	NULL, 0, 0, (void *) 57, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1295     { (unichar_t *) N_("852, Latin 2"),				NULL, 0, 0, (void *) 58, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1296     { (unichar_t *) N_("775, MS-DOS Baltic"),			NULL, 0, 0, (void *) 59, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1297     { (unichar_t *) N_("737, Greek; former 437 G"),		NULL, 0, 0, (void *) 60, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1298     { (unichar_t *) N_("708, Arabic ASMO 708"),			NULL, 0, 0, (void *) 61, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1299     { (unichar_t *) N_("850, WE/Latin 1"),			NULL, 0, 0, (void *) 62, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1300     { (unichar_t *) N_("437, US"),				NULL, 0, 0, (void *) 63, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1301     GTEXTINFO_EMPTY
1302 };
1303 static char *TN_DefaultName(GGadget *g, int r, int c);
1304 static void TN_StrIDEnable(GGadget *g,GMenuItem *mi, int r, int c);
1305 static void TN_LangEnable(GGadget *g,GMenuItem *mi, int r, int c);
1306 static struct col_init ci[] = {
1307     { me_enum, NULL, mslanguages, TN_LangEnable, N_("Language") },
1308     { me_enum, NULL, ttfnameids, TN_StrIDEnable, N_("String ID") },
1309     { me_func, TN_DefaultName, NULL, NULL, N_("String") }
1310 };
1311 static struct col_init ssci[] = {
1312     { me_enum, NULL, mslanguages, NULL, N_("Language") },
1313     { me_enum, NULL, otfssfeattags, NULL, N_("Feature Tags") },
1314     { me_string, NULL, NULL, NULL, N_("Friendly Name") }
1315 };
1316 static struct col_init sizeci[] = {
1317     { me_enum, NULL, mslanguages, NULL, N_("Language") },
1318     { me_string, NULL, NULL, NULL, N_("Name") }
1319 };
1320 static GTextInfo gridfit[] = {
1321     { (unichar_t *) N_("No Grid Fit"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1322     { (unichar_t *) N_("Grid Fit"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1323     GTEXTINFO_EMPTY
1324 };
1325 static GTextInfo antialias[] = {
1326     { (unichar_t *) N_("No Anti-Alias"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1327     { (unichar_t *) N_("Anti-Alias"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1328     GTEXTINFO_EMPTY
1329 };
1330 static GTextInfo symsmooth[] = {
1331     { (unichar_t *) N_("No Symmetric-Smooth"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1332     { (unichar_t *) N_("Symmetric-Smoothing"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1333     GTEXTINFO_EMPTY
1334 };
1335 static GTextInfo gfsymsmooth[] = {
1336     { (unichar_t *) N_("No Grid Fit w/ Sym-Smooth"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1337     { (unichar_t *) N_("Grid Fit w/ Sym-Smooth"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1338     GTEXTINFO_EMPTY
1339 };
1340 static struct col_init gaspci[] = {
1341     { me_int , NULL, NULL, NULL, N_("Gasp|For Pixels Per EM <= Value") },
1342     { me_enum, NULL, gridfit, NULL, N_("Gasp|Grid Fit") },			/* 1 */
1343     { me_enum, NULL, antialias, NULL, N_("Gasp|Anti-Alias") },			/* 2 */
1344     { me_enum, NULL, symsmooth, NULL, N_("Gasp|Symmetric Smoothing") },		/* 8 */
1345     { me_enum, NULL, gfsymsmooth, NULL, N_("Gasp|Grid Fit w/ Sym Smooth") }	/* 4 */
1346 };
1347 static GTextInfo splineorder[] = {
1348     { (unichar_t *) N_("Cubic"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1349     { (unichar_t *) N_("Quadratic"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1350     GTEXTINFO_EMPTY
1351 };
1352 static GTextInfo layertype[] = {
1353     { (unichar_t *) N_("Layer|Foreground"), NULL, 0, 0, (void *) 0, NULL, 0, 0, 0, 0, 1, 0, 1, 0, 0, '\0'},
1354     { (unichar_t *) N_("Layer|Background"), NULL, 0, 0, (void *) 1, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1355     GTEXTINFO_EMPTY
1356 };
1357 static void Layers_BackgroundEnable(GGadget *g,GMenuItem *mi, int r, int c);
1358 static struct col_init layersci[] = {
1359     { me_string, NULL, NULL, NULL, N_("Layer Name") },
1360     { me_enum  , NULL, splineorder, NULL, N_("Curve Type") },
1361     { me_enum  , NULL, layertype, Layers_BackgroundEnable, N_("Type") },
1362     { me_int   , NULL, NULL, NULL, N_("Orig layer") }
1363 };
1364 static char *GFI_Mark_PickGlyphsForClass(GGadget *g,int r, int c);
1365 static struct col_init marks_ci[] = {
1366     { me_string, NULL, NULL, NULL, N_("Set Name") },
1367     { me_funcedit, GFI_Mark_PickGlyphsForClass, NULL, NULL, N_("Glyphs in the set") },
1368 };
1369 static struct col_init markc_ci[] = {
1370     { me_string, NULL, NULL, NULL, N_("Class Name") },
1371     { me_funcedit, GFI_Mark_PickGlyphsForClass, NULL, NULL, N_("Glyphs in the class") },
1372 };
1373 
1374 struct langstyle { int lang; const char *str; };
1375 #define LANGSTYLE_EMPTY { 0, NULL }
1376 
1377 static const char regulareng[] = "Regular";
1378 static const char demiboldeng[] = "DemiBold";
1379 static const char demiboldeng3[] = "Demi";
1380 static const char demiboldeng5[] = "SemiBold";
1381 static const char boldeng[] = "Bold";
1382 static const char thineng[] = "Thin";
1383 static const char lighteng[] = "Light";
1384 static const char extralighteng[] = "ExtraLight";
1385 static const char extralighteng2[] = "VeryLight";
1386 static const char mediumeng[] = "Medium";
1387 static const char bookeng[] = "Book";
1388 static const char heavyeng[] = "Heavy";
1389 static const char blackeng[] = "Black";
1390 static const char italiceng[] = "Italic";
1391 static const char obliqueeng[] = "Oblique";
1392 static const char condensedeng[] = "Condensed";
1393 static const char expandedeng[] = "Expanded";
1394 static const char outlineeng[] = "Outline";
1395 
1396 static const char regularfren[] = "Normal";
1397 static const char boldfren[] = "Gras";
1398 static const char demiboldfren[] = "DemiGras";
1399 static const char demiboldfren2[] = "Demi";
1400 static const char mediumfren[] = "Normal";
1401 static const char lightfren[] = "Maigre";
1402 static const char blackfren[] = "ExtraGras";
1403 static const char italicfren[] = "Italique";
1404 static const char obliquefren[] = "Oblique";
1405 static const char condensedfren[] = "Etroite";
1406 static const char expandedfren[] = "Elargi";
1407 static const char outlinefren[] = "Contour";
1408 
1409 static const char regulargerm[] = "Standard";
1410 static const char demiboldgerm[] = "Halbfett";
1411 static const char demiboldgerm2[] = "Schmallfett";
1412 static const char boldgerm[] = "Fett";
1413 static const char boldgerm2[] = "Dick";
1414 static const char blackgerm[] = "Schwarz";
1415 static const char lightgerm[] = "Mager";
1416 static const char mediumgerm[] = "Mittel";
1417 static const char bookgerm[] = "Buchschrift";
1418 static const char italicgerm[] = "Kursiv";
1419 static const char obliquegerm[] = "Schräg";
1420 static const char condensedgerm[] = "Schmal";
1421 static const char expandedgerm[] = "Breit";
1422 static const char outlinegerm[] = "Konturert";
1423 
1424 static const char regularspan[] = "Normal";
1425 static const char boldspan[] = "Negrita";
1426 static const char lightspan[] = "Fina";
1427 static const char blackspan[] = "Supernegra";
1428 static const char italicspan[] = "Cursiva";
1429 static const char condensedspan[] = "Condensada";
1430 static const char expandedspan[] = "Amplida";
1431 
1432 static const char regulardutch[] = "Normaal";
1433 static const char mediumdutch[] = "Gemiddeld";
1434 static const char bookdutch[] = "Boek";
1435 static const char bolddutch[] = "Vet";
1436 static const char demibolddutch[] = "Dik";
1437 /*static const char demibolddutch[] = "Halfvet";*/
1438 static const char lightdutch[] = "Licht";
1439 /*static const char lightdutch[] = "Licht mager";*/
1440 static const char blackdutch[] = "Extra vet";
1441 static const char italicdutch[] = "Cursief";
1442 static const char italicdutch2[] = "italiek";
1443 static const char obliquedutch2[] = "oblique";
1444 static const char obliquedutch[] = "Schuin";
1445 static const char condenseddutch[] = "Smal";
1446 static const char expandeddutch[] = "Breed";
1447 static const char outlinedutch[] = "Uitlijning";
1448 /*static const char outlinedutch[] = "Contour";*/
1449 
1450 static const char regularswed[] = "Mager";
1451 static const char boldswed[] = "Fet";
1452 static const char lightswed[] = "Extrafin";
1453 static const char blackswed[] = "Extrafet";
1454 static const char italicswed[] = "Kursiv";
1455 static const char condensedswed[] = "Smal";
1456 static const char expandedswed[] = "Bred";
1457 
1458 static const char regulardanish[] = "Normal";
1459 static const char bolddanish[] = "Fed";
1460 static const char demibolddanish[] = "Halvfed";
1461 static const char lightdanish[] = "Fin";
1462 static const char mediumdanish[] = "Medium";
1463 static const char blackdanish[] = "Extrafed";
1464 static const char italicdanish[] = "Kursiv";
1465 static const char condenseddanish[] = "Smal";
1466 static const char expandeddanish[] = "Bred";
1467 static const char outlinedanish[] = "Kontour";
1468 
1469 static const char regularnor[] = "Vanlig";
1470 static const char boldnor[] = "Halvfet";
1471 static const char lightnor[] = "Mager";
1472 static const char blacknor[] = "Fet";
1473 static const char italicnor[] = "Kursiv";
1474 static const char condensednor[] = "Smal";
1475 static const char expandednor[] = "Sperret";
1476 
1477 static const char regularital[] = "Normale";
1478 static const char demiboldital[] = "Nerretto";
1479 static const char boldital[] = "Nero";
1480 static const char thinital[] = "Fine";
1481 static const char lightital[] = "Chiaro";
1482 static const char mediumital[] = "Medio";
1483 static const char bookital[] = "Libro";
1484 static const char heavyital[] = "Nerissimo";
1485 static const char blackital[] = "ExtraNero";
1486 static const char italicital[] = "Cursivo";
1487 static const char obliqueital[] = "Obliquo";
1488 static const char condensedital[] = "Condensato";
1489 static const char expandedital[] = "Allargato";
1490 
1491 static const char regularru[] = "Обычный";
1492 static const char demiboldru[] = "Полужирный";
1493 static const char boldru[] = "Обычный";
1494 static const char heavyru[] = "Сверхжирный";
1495 static const char blackru[] = "Чёрный";
1496 static const char thinru[] = "Тонкий";
1497 static const char lightru[] = "Светлый";
1498 static const char italicru[] = "Курсив";
1499 static const char obliqueru[] = "Наклон";
1500 static const char condensedru[] = "Узкий";
1501 static const char expandedru[] = "Широкий";
1502 
1503 static const char regularhu[] = "Normál";
1504 static const char demiboldhu[] = "Negyedkövér";
1505 static const char demiboldhu2[] = "Félkövér";
1506 static const char boldhu[] = "Félkövér";
1507 static const char boldhu2[] = "Háromnegyedkövér";
1508 static const char thinhu[] = "Sovány";
1509 static const char lighthu[] = "Világos";
1510 static const char mediumhu[] = "Közepes";
1511 static const char bookhu[] = "Halvány";
1512 static const char bookhu2[] = "Könyv";
1513 static const char heavyhu[] = "Kövér";
1514 static const char heavyhu2[] = "Extrakövér";
1515 static const char blackhu[] = "Fekete";
1516 static const char blackhu2[] = "Sötét";
1517 static const char italichu[] = "Dőlt";
1518 static const char obliquehu[] = "Döntött";
1519 static const char obliquehu2[] = "Ferde";
1520 static const char condensedhu[] = "Keskeny";
1521 static const char expandedhu[] = "Széles";
1522 static const char outlinehu[] = "Kontúros";
1523 
1524 static const char regularpl[] = "podstawowa";
1525 static const char demiboldpl[] = "półgruba";
1526 static const char boldpl[] = "pogrubiona";
1527 static const char thinpl[] = "cienka";
1528 static const char lightpl[] = "bardzo cienka";
1529 static const char heavypl[] = "bardzo gruba";
1530 static const char italicpl[] = "pochyła";
1531 static const char obliquepl[] = "pochyła";
1532 static const char condensedpl[] = "wąska";
1533 static const char expandedpl[] = "szeroka";
1534 static const char outlinepl[] = "konturowa";
1535 static const char mediumpl[] = "zwykła";
1536 static const char bookpl[] = "zwykła";
1537 
1538 static struct langstyle regs[] = { {0x409, regulareng}, { 0x40c, regularfren }, { 0x410, regularital }, { 0x407, regulargerm }, { 0x40a, regularspan }, { 0x419, regularru }, { 0x40e, regularhu },
1539 	{ 0x413, regulardutch}, { 0x41d, regularswed }, { 0x414, regularnor },
1540 	{ 0x406, regulardanish}, {0x415, regularpl }, { 0x804, "正常"},
1541 	{ 0x408, "κανονική"}, { 0x42a, "Chuẩn"}, { 0x418, "Normal"}, LANGSTYLE_EMPTY};
1542 static struct langstyle meds[] = { {0x409, mediumeng}, { 0x410, mediumital },
1543 	{ 0x40c, mediumfren }, { 0x407, mediumgerm }, { 0x40e, mediumhu },
1544 	{ 0x406, mediumdanish}, {0x415, mediumpl }, { 0x804, "中等"},
1545 	{ 0x408, "µεσαία"}, { 0x42a, "Vừa"}, { 0x413, mediumdutch},
1546         { 0x418, "Mediu"}, LANGSTYLE_EMPTY};
1547 static struct langstyle books[] = { {0x409, bookeng}, { 0x410, bookital },
1548 	{ 0x407, bookgerm }, { 0x40e, bookhu }, { 0x40e, bookhu2 },
1549 	{ 0x415, bookpl}, { 0x804, "书体"}, { 0x408, "ßιßλίου"},
1550 	{ 0x42a, "Sách"}, { 0x413, bookdutch}, { 0x418, "Carte"}, LANGSTYLE_EMPTY};
1551 static struct langstyle bolds[] = { {0x409, boldeng}, { 0x410, boldital }, { 0x40c, boldfren }, { 0x407, boldgerm }, { 0x407, boldgerm2 }, { 0x40a, boldspan}, { 0x419, boldru }, { 0x40e, boldhu }, { 0x40e, boldhu2 },
1552 	{ 0x413, bolddutch}, { 0x41d, boldswed }, { 0x414, boldnor },
1553 	{ 0x406, bolddanish}, { 0x415, boldpl}, { 0x804, "粗体"},
1554 	{ 0x408, "έντονη"}, { 0x42a, "Đậm"}, {0x418,"Aldin"}, LANGSTYLE_EMPTY};
1555 static struct langstyle italics[] = { {0x409, italiceng}, { 0x410, italicital }, { 0x40c, italicfren }, { 0x407, italicgerm }, { 0x40a, italicspan}, { 0x419, italicru }, { 0x40e, italichu },
1556 	{ 0x413, italicdutch}, { 0x413, italicdutch2}, { 0x41d, italicswed }, { 0x414, italicnor },
1557 	{ 0x406, italicdanish}, { 0x415, italicpl}, { 0x804, "斜体"},
1558 	{ 0x408, "Λειψίας"}, { 0x42a, "Nghiêng" }, { 0x418, "Cursiv"},  LANGSTYLE_EMPTY};
1559 static struct langstyle obliques[] = { {0x409, obliqueeng}, { 0x410, obliqueital },
1560 	{ 0x40c, obliquefren }, { 0x407, obliquegerm }, { 0x419, obliqueru },
1561 	{ 0x40e, obliquehu }, { 0x40e, obliquehu2 }, {0x415, obliquepl},
1562 	{ 0x804, "斜体"}, { 0x408, "πλάγια"},
1563 	{ 0x42a, "Xiên" }, { 0x413, obliquedutch}, { 0x413, obliquedutch2},
1564         { 0x418, "Înclinat"}, LANGSTYLE_EMPTY};
1565 static struct langstyle demibolds[] = { {0x409, demiboldeng}, {0x409, demiboldeng3}, {0x409, demiboldeng5},
1566 	{ 0x410, demiboldital }, { 0x40c, demiboldfren }, { 0x40c, demiboldfren2 }, { 0x407, demiboldgerm }, { 0x407, demiboldgerm2 },
1567 	{ 0x419, demiboldru }, { 0x40e, demiboldhu }, { 0x40e, demiboldhu2 },
1568 	{ 0x406, demibolddanish}, { 0x415, demiboldpl },
1569 	{ 0x804, "略粗"}, { 0x408, "ηµιέντονη"},
1570 	{ 0x42a, "Nửa đậm"}, { 0x413, demibolddutch},
1571         {0x418, "Semialdin"}, LANGSTYLE_EMPTY};
1572 static struct langstyle heavys[] = { {0x409, heavyeng}, { 0x410, heavyital },
1573 	{ 0x419, heavyru }, { 0x40e, heavyhu }, { 0x40e, heavyhu2 },
1574 	{ 0x415, heavypl }, { 0x804, "粗"}, LANGSTYLE_EMPTY};
1575 static struct langstyle blacks[] = { {0x409, blackeng}, { 0x410, blackital }, { 0x40c, blackfren }, { 0x407, blackgerm }, { 0x419, blackru }, { 0x40e, blackhu }, { 0x40e, blackhu2 }, { 0x40a, blackspan },
1576 	{ 0x413, blackdutch}, { 0x41d, blackswed }, { 0x414, blacknor }, { 0x406, blackdanish},
1577 	{ 0x415, heavypl }, { 0x804, "黑"},  { 0x408, "µαύρα"},
1578 	{ 0x42a, "Đen"}, { 0x418, "Negru"}, LANGSTYLE_EMPTY };
1579 static struct langstyle thins[] = { {0x409, thineng}, { 0x410, thinital },
1580 	{ 0x419, thinru }, { 0x40e, thinhu }, { 0x415, thinpl},
1581 	{ 0x804, "细"}, LANGSTYLE_EMPTY};
1582 static struct langstyle extralights[] = { {0x409, extralighteng}, {0x409, extralighteng2},
1583 	{ 0x804, "极细"}, LANGSTYLE_EMPTY};
1584 static struct langstyle lights[] = { {0x409, lighteng}, {0x410, lightital}, {0x40c, lightfren}, {0x407, lightgerm}, { 0x419, lightru }, { 0x40e, lighthu }, { 0x40a, lightspan },
1585 	{ 0x413, lightdutch}, { 0x41d, lightswed }, { 0x414, lightnor },
1586 	{ 0x406, lightdanish}, { 0x415, lightpl}, { 0x804, "细"},
1587 	{ 0x408, "λεπτή"}, { 0x42a, "Nhẹ" }, { 0x418, "Subțire"}, LANGSTYLE_EMPTY};
1588 static struct langstyle condenseds[] = { {0x409, condensedeng}, {0x410, condensedital}, {0x40c, condensedfren}, {0x407, condensedgerm}, { 0x419, condensedru }, { 0x40e, condensedhu }, { 0x40a, condensedspan },
1589 	{ 0x413, condenseddutch}, { 0x41d, condensedswed },
1590 	{ 0x414, condensednor }, { 0x406, condenseddanish},
1591 	{ 0x415, condensedpl }, { 0x804, "压缩"},
1592 	{ 0x408, "πυκνή"}, { 0x42a, "Hẹp" }, { 0x418, "Îngust"}, LANGSTYLE_EMPTY};
1593 static struct langstyle expandeds[] = { {0x409, expandedeng}, {0x410, expandedital}, {0x40c, expandedfren}, {0x407, expandedgerm}, { 0x419, expandedru }, { 0x40e, expandedhu }, { 0x40a, expandedspan },
1594 	{ 0x413, expandeddutch}, { 0x41d, expandedswed }, { 0x414, expandednor },
1595 	{ 0x406, expandeddanish}, { 0x415, expandedpl }, { 0x804, "加宽"},
1596 	{ 0x408, "αραιή"}, { 0x42a, "Rộng" }, { 0x418, "Expandat"}, LANGSTYLE_EMPTY};
1597 static struct langstyle outlines[] = { {0x409, outlineeng}, {0x40c, outlinefren},
1598 	{0x407, outlinegerm}, {0x40e, outlinehu}, { 0x406, outlinedanish},
1599 	{0x415, outlinepl}, { 0x804, "轮廓"}, { 0x408, "περιγράμματος"},
1600 	{0x42a, "Nét ngoài" }, { 0x413, outlinedutch}, {0x418, "Contur"}, LANGSTYLE_EMPTY};
1601 static struct langstyle *stylelist[] = {regs, meds, books, demibolds, bolds, heavys, blacks,
1602 	extralights, lights, thins, italics, obliques, condenseds, expandeds, outlines, NULL };
1603 
1604 #define CID_Features	101		/* Mac stuff */
1605 #define CID_FeatureDel	103
1606 #define CID_FeatureEdit	105
1607 
1608 #define CID_Family	1002
1609 #define CID_Weight	1003
1610 #define CID_ItalicAngle	1004
1611 #define CID_UPos	1005
1612 #define CID_UWidth	1006
1613 #define CID_Ascent	1007
1614 #define CID_Descent	1008
1615 #define CID_Notice	1010
1616 #define CID_Version	1011
1617 #define CID_UniqueID	1012
1618 #define CID_HasVerticalMetrics	1013
1619 #define CID_Fontname	1016
1620 #define CID_Em		1017
1621 #define CID_Scale	1018
1622 #define CID_Interpretation	1021
1623 #define CID_Namelist	1024
1624 #define CID_Revision	1025
1625 
1626 #define CID_WoffMajor	1050
1627 #define CID_WoffMinor	1051
1628 #define CID_WoffMetadata	1052
1629 
1630 #define CID_XUID	1113
1631 #define CID_Human	1114
1632 #define CID_SameAsFontname	1115
1633 #define CID_HasDefBase	1116
1634 #define CID_DefBaseName	1117
1635 #define CID_UseXUID	1118
1636 #define CID_UseUniqueID	1119
1637 
1638 #define CID_GuideOrder2		1200
1639 #define CID_IsMixed		1217
1640 #define CID_IsOrder3		1218
1641 #define CID_IsOrder2		1219
1642 #define CID_IsMultiLayer	1220
1643 #define CID_IsStrokedFont	1222
1644 #define CID_StrokeWidth		1223
1645 #define CID_Backgrounds		1226
1646 
1647 #define CID_Private		2001
1648 #define CID_Guess		2004
1649 #define CID_Hist		2006
1650 
1651 #define CID_TTFTabs		3000
1652 #define CID_WeightClass		3001
1653 #define CID_WidthClass		3002
1654 #define CID_PFMFamily		3003
1655 #define CID_FSType		3004
1656 #define CID_NoSubsetting	3005
1657 #define CID_OnlyBitmaps		3006
1658 #define CID_LineGap		3007
1659 #define CID_VLineGap		3008
1660 #define CID_VLineGapLab		3009
1661 #define CID_WinAscent		3010
1662 #define CID_WinAscentLab	3011
1663 #define CID_WinAscentIsOff	3012
1664 #define CID_WinDescent		3013
1665 #define CID_WinDescentLab	3014
1666 #define CID_WinDescentIsOff	3015
1667 #define CID_TypoAscent		3016
1668 #define CID_TypoAscentLab	3017
1669 #define CID_TypoAscentIsOff	3018
1670 #define CID_TypoDescent		3019
1671 #define CID_TypoDescentLab	3020
1672 #define CID_TypoDescentIsOff	3021
1673 #define CID_TypoLineGap		3022
1674 #define CID_HHeadAscent		3023
1675 #define CID_HHeadAscentLab	3024
1676 #define CID_HHeadAscentIsOff	3025
1677 #define CID_HHeadDescent	3026
1678 #define CID_HHeadDescentLab	3027
1679 #define CID_HHeadDescentIsOff	3028
1680 #define CID_Vendor		3029
1681 #define CID_IBMFamily		3030
1682 #define CID_OS2Version		3031
1683 #define CID_UseTypoMetrics	3032
1684 #define CID_WeightWidthSlopeOnly	3033
1685 // Maybe we could insert these above and change the numbering.
1686 #define CID_CapHeight		3034
1687 #define CID_CapHeightLab		3035
1688 #define CID_XHeight		3036
1689 #define CID_XHeightLab		3037
1690 #define CID_StyleMap		3038
1691 
1692 #define CID_SubSuperDefault	3100
1693 #define CID_SubXSize		3101
1694 #define CID_SubYSize		3102
1695 #define CID_SubXOffset		3103
1696 #define CID_SubYOffset		3104
1697 #define CID_SuperXSize		3105
1698 #define CID_SuperYSize		3106
1699 #define CID_SuperXOffset	3107
1700 #define CID_SuperYOffset	3108
1701 #define CID_StrikeoutSize	3109
1702 #define CID_StrikeoutPos	3110
1703 
1704 #define CID_PanFamily		4001
1705 #define CID_PanSerifs		4002
1706 #define CID_PanWeight		4003
1707 #define CID_PanProp		4004
1708 #define CID_PanContrast		4005
1709 #define CID_PanStrokeVar	4006
1710 #define CID_PanArmStyle		4007
1711 #define CID_PanLetterform	4008
1712 #define CID_PanMidLine		4009
1713 #define CID_PanXHeight		4010
1714 #define CID_PanDefault		4011
1715 #define CID_PanFamilyLab	4021
1716 #define CID_PanSerifsLab	4022
1717 #define CID_PanWeightLab	4023
1718 #define CID_PanPropLab		4024
1719 #define CID_PanContrastLab	4025
1720 #define CID_PanStrokeVarLab	4026
1721 #define CID_PanArmStyleLab	4027
1722 #define CID_PanLetterformLab	4028
1723 #define CID_PanMidLineLab	4029
1724 #define CID_PanXHeightLab	4030
1725 
1726 #define CID_TNLangSort		5001
1727 #define CID_TNStringSort	5002
1728 #define CID_TNVScroll		5003
1729 #define CID_TNHScroll		5004
1730 #define CID_TNames		5005
1731 
1732 #define CID_Language		5006	/* Used by AskForLangNames */
1733 
1734 #define CID_SSNames		5050
1735 
1736 #define CID_Gasp		5100
1737 #define CID_GaspVersion		5101
1738 #define CID_HeadClearType	5102
1739 
1740 #define CID_Comment		6001
1741 #define CID_FontLog		6002
1742 
1743 #define CID_MarkClasses		7101
1744 
1745 #define CID_MarkSets		7201
1746 
1747 #define CID_TeXText		8001
1748 #define CID_TeXMathSym		8002
1749 #define CID_TeXMathExt		8003
1750 #define CID_MoreParams		8005
1751 #define CID_TeXExtraSpLabel	8006
1752 #define CID_TeX			8007	/* through 8014 */
1753 #define CID_TeXBox		8030
1754 
1755 #define CID_DesignSize		8301
1756 #define CID_DesignBottom	8302
1757 #define CID_DesignTop		8303
1758 #define CID_StyleID		8304
1759 #define CID_StyleName		8305
1760 
1761 #define CID_Tabs		10001
1762 #define CID_OK			10002
1763 #define CID_Cancel		10003
1764 #define CID_MainGroup		10004
1765 #define CID_TopBox		10005
1766 
1767 #define CID_Lookups		11000
1768 #define CID_LookupTop		11001
1769 #define CID_LookupUp		11002
1770 #define CID_LookupDown		11003
1771 #define CID_LookupBottom	11004
1772 #define CID_AddLookup		11005
1773 #define CID_AddSubtable		11006
1774 #define CID_EditMetadata	11007
1775 #define CID_EditSubtable	11008
1776 #define CID_DeleteLookup	11009
1777 #define CID_MergeLookup		11010
1778 #define CID_RevertLookups	11011
1779 #define CID_LookupSort		11012
1780 #define CID_ImportLookups	11013
1781 #define CID_LookupWin		11020		/* (GSUB, add 1 for GPOS) */
1782 #define CID_LookupVSB		11022		/* (GSUB, add 1 for GPOS) */
1783 #define CID_LookupHSB		11024		/* (GSUB, add 1 for GPOS) */
1784 #define CID_SaveLookup		11026
1785 #define CID_SaveFeat		11027
1786 #define CID_AddAllAlternates	11028
1787 #define CID_AddDFLT		11029
1788 #define CID_AddLanguage		11030
1789 #define CID_RmLanguage		11031
1790 
1791 #define CID_MacAutomatic	16000
1792 #define CID_MacStyles		16001
1793 #define CID_MacFOND		16002
1794 
1795 #define CID_Unicode		16100
1796 #define CID_UnicodeEmpties	16101
1797 #define CID_UnicodeTab		16102
1798 #define CID_URangesDefault	16110
1799 #define CID_UnicodeRanges	16111
1800 #define CID_UnicodeList		16112
1801 #define CID_CPageDefault	16120
1802 #define CID_CodePageRanges	16121
1803 #define CID_CodePageList	16122
1804 
UI_TTFNameIds(int id)1805 const char *UI_TTFNameIds(int id) {
1806     int i;
1807 
1808     FontInfoInit();
1809     for ( i=0; ttfnameids[i].text!=NULL; ++i )
1810 	if ( ttfnameids[i].userdata == (void *) (intpt) id )
1811 return( (char *) ttfnameids[i].text );
1812 
1813     if ( id==6 )
1814 return( "PostScript" );
1815 
1816 return( _("Unknown") );
1817 }
1818 
UI_MSLangString(int language)1819 const char *UI_MSLangString(int language) {
1820     int i;
1821 
1822     FontInfoInit();
1823     for ( i=0; mslanguages[i].text!=NULL; ++i )
1824 	if ( mslanguages[i].userdata == (void *) (intpt) language )
1825 return( (char *) mslanguages[i].text );
1826 
1827     language &= 0xff;
1828     for ( i=0; mslanguages[i].text!=NULL; ++i )
1829 	if ( ((intpt) mslanguages[i].userdata & 0xff) == language )
1830 return( (char *) mslanguages[i].text );
1831 
1832 return( _("Unknown") );
1833 }
1834 
1835 /* These are PostScript names, and as such should not be translated */
1836 enum { pt_number, pt_boolean, pt_array, pt_code };
1837 static struct { const char *name; short type, arr_size, present; } KnownPrivates[] = {
1838     { "BlueValues", pt_array, 14, 0 },
1839     { "OtherBlues", pt_array, 10, 0 },
1840     { "BlueFuzz", pt_number, 0, 0 },
1841     { "FamilyBlues", pt_array, 14, 0 },
1842     { "FamilyOtherBlues", pt_array, 10, 0 },
1843     { "BlueScale", pt_number, 0, 0 },
1844     { "BlueShift", pt_number, 0, 0 },
1845     { "StdHW", pt_array, 1, 0 },
1846     { "StdVW", pt_array, 1, 0 },
1847     { "StemSnapH", pt_array, 12, 0 },
1848     { "StemSnapV", pt_array, 12, 0 },
1849     { "ForceBold", pt_boolean, 0, 0 },
1850     { "LanguageGroup", pt_number, 0, 0 },
1851     { "RndStemUp", pt_number, 0, 0 },
1852     { "lenIV", pt_number, 0, 0 },
1853     { "ExpansionFactor", pt_number, 0, 0 },
1854     { "Erode", pt_code, 0, 0 },
1855 /* I am deliberately not including Subrs and OtherSubrs */
1856 /* The first could not be entered (because it's a set of binary strings) */
1857 /* And the second has special meaning to us and must be handled with care */
1858     { NULL, 0, 0, 0 }
1859 };
1860 
1861 static GTextInfo psprivate_nameids[] = {
1862 /* Don't translate these here either */
1863     { (unichar_t *) "BlueValues", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1864     { (unichar_t *) "OtherBlues", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1865     { (unichar_t *) "BlueFuzz", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1866     { (unichar_t *) "FamilyBlues", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1867     { (unichar_t *) "FamilyOtherBlues", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1868     { (unichar_t *) "BlueScale", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1869     { (unichar_t *) "BlueShift", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1870     { (unichar_t *) "StdHW", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1871     { (unichar_t *) "StdVW", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1872     { (unichar_t *) "StemSnapH", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1873     { (unichar_t *) "StemSnapV", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1874     { (unichar_t *) "ForceBold", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1875     { (unichar_t *) "LanguageGroup", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1876     { (unichar_t *) "RndStemUp", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1877     { (unichar_t *) "lenIV", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1878     { (unichar_t *) "ExpansionFactor", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1879     { (unichar_t *) "Erode", NULL, 0, 0, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 0, 0, '\0'},
1880     GTEXTINFO_EMPTY
1881 };
1882 
PI_KeyEnable(GGadget * g,GMenuItem * mi,int r,int c)1883 static void PI_KeyEnable(GGadget *g,GMenuItem *mi, int r, int c) {
1884     int i,j, rows;
1885     struct matrix_data *strings = _GMatrixEditGet(g, &rows);
1886     int cols = GMatrixEditGetColCnt(g);
1887     int found;
1888 
1889     for ( i=0; mi[i].ti.text!=NULL; ++i ) {
1890 	found = 0;
1891 	for ( j=0; j<rows; ++j ) {
1892 	    if ( strcmp((char *) mi[i].ti.text,strings[j*cols+0].u.md_str)==0 ) {
1893 		found=1;
1894 	break;
1895 	    }
1896 	}
1897 	if ( j==r && found ) {
1898 	    mi[i].ti.disabled = false;
1899 	    mi[i].ti.selected = true;
1900 	} else {
1901 	    mi[i].ti.disabled = found;
1902 	    mi[i].ti.selected = false;
1903 	}
1904     }
1905 }
1906 
1907 static struct col_init psprivate_ci[] = {
1908     { me_stringchoice, NULL, psprivate_nameids, PI_KeyEnable, N_("Key") },
1909     { me_string, NULL, NULL, NULL, N_("Value") }
1910     };
1911 
rpldecimal(const char * orig,const char * decimal_point,locale_t tmplocale)1912 static char *rpldecimal(const char *orig,const char *decimal_point, locale_t tmplocale) {
1913     char *end;
1914     char *new, *npt; const char *pt;
1915     int dlen;
1916     double dval;
1917     char buffer[40];
1918     locale_t oldlocale;
1919 
1920     /* if the current locale uses a "." for a decimal point the we don't need */
1921     /*  to translate the number, just check that it is valid */
1922     if ( strcmp(decimal_point,".")==0 ) {
1923 	strtod(orig,&end);
1924 	while ( isspace(*end)) ++end;
1925 	if ( *end!='\0' )
1926 return( NULL );
1927 return( copy(orig));
1928     }
1929 
1930     npt = new = malloc(2*strlen(orig)+10);
1931     dlen = strlen(decimal_point);
1932     /* now I want to change the number as little as possible. So if they use */
1933     /*  arabic numerals we can get by with just switching the decimal point */
1934     /*  If they use some other number convention, then parse in the old locale*/
1935     /*  and sprintf in the PostScript ("C") locale. This might lose some */
1936     /*  precision but the basic idea will get across */
1937     for ( pt=orig; *pt; ) {
1938 	if ( strncmp(pt,decimal_point,dlen)==0 ) {
1939 	    pt += dlen;
1940 	    *npt++ = '.';
1941 	} else
1942 	    *npt++ = *pt++;
1943     }
1944     *npt = '\0';
1945 
1946     oldlocale = uselocale_hack(tmplocale);
1947     strtod(new,&end);
1948     uselocale_hack(oldlocale);
1949     while ( isspace(*end)) ++end;
1950     if ( *end=='\0' ) {
1951 	char *ret = copy(new);
1952 	free(new);
1953 return( ret );
1954     }
1955 
1956     /* OK, can we parse the number in the original local? */
1957     dval = strtod(new,&end);
1958     while ( isspace(*end)) ++end;
1959     if ( *end!='\0' ) {
1960 	free(new);
1961 return( NULL );
1962     }
1963     free(new);
1964     oldlocale = uselocale_hack(tmplocale);
1965     sprintf( buffer, "%g", dval );
1966     uselocale_hack(oldlocale);
1967 return( copy(buffer));
1968 }
1969 
rplarraydecimal(const char * orig,const char * decimal_point,locale_t tmplocale)1970 static char *rplarraydecimal(const char *orig,const char *decimal_point, locale_t tmplocale) {
1971     char *new, *npt, *rpl;
1972     int nlen;
1973     const char *start, *pt; int ch;
1974 
1975     nlen = 2*strlen(orig)+10;
1976     npt = new = calloc(1,nlen+1);
1977     *npt++ = '[';
1978 
1979     for ( pt=orig; isspace(*pt) || *pt=='['; ++pt );
1980     while ( *pt!=']' && *pt!='\0' ) {
1981 	start=pt;
1982 	while ( *pt!=']' && *pt!=' ' && *pt!='\0' ) ++pt;
1983 	ch = *pt; *(char *) pt = '\0';
1984 	rpl = rpldecimal(start,decimal_point,tmplocale);
1985 	*(char *) pt = ch;
1986 	if ( rpl==NULL ) {
1987 	    gwwv_post_notice(_("Bad type"),_("Expected array of numbers.\nFailed to parse \"%.*s\" as a number."),
1988 		    pt-start, start);
1989 	    free(new);
1990 return( NULL );
1991 	}
1992 	if ( npt-new + strlen(rpl) + 2 >nlen ) {
1993 	    int noff = npt-new;
1994 	    new = realloc(new,nlen += strlen(rpl)+100);
1995 	    npt = new+noff;
1996 	}
1997 	if ( npt[-1]!='[' )
1998 	    *npt++ = ' ';
1999 	strcpy(npt,rpl);
2000 	free(rpl);
2001 	npt += strlen(npt);
2002 	while ( isspace(*pt)) ++pt;
2003     }
2004     *npt++ =']';
2005     *npt = '\0';
2006     rpl = copy(new);
2007     free(new);
2008 return( rpl );
2009 }
2010 
PSPrivate_FinishEdit(GGadget * g,int r,int c,int wasnew)2011 static void PSPrivate_FinishEdit(GGadget *g,int r, int c, int wasnew) {
2012     int rows, cols = GMatrixEditGetColCnt(g);
2013     struct matrix_data *strings = _GMatrixEditGet(g, &rows);
2014     struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
2015     char *key = strings[r*cols+0].u.md_str;
2016     char *val = strings[r*cols+1].u.md_str;
2017     char *pt, *ept, *newval;
2018     locale_t tmplocale;
2019     struct psdict *tempdict;
2020 
2021     if ( key==NULL )
2022 return;
2023 
2024     if ( c==0 && (wasnew || val==NULL || *val=='\0')) {
2025 	tempdict = calloc(1,sizeof(*tempdict));
2026 	SFPrivateGuess(d->sf,ly_fore,tempdict,key,true);
2027 	strings[r*cols+1].u.md_str = copy(PSDictHasEntry(tempdict,key));
2028 	PSDictFree(tempdict);
2029     } else if ( c==1 && val!=NULL ) {
2030 	struct lconv *loc = localeconv();
2031 	int i;
2032 	for ( i=0; KnownPrivates[i].name!=NULL; ++i )
2033 	    if ( strcmp(KnownPrivates[i].name,key)==0 )
2034 	break;
2035 	if ( KnownPrivates[i].name==NULL )	/* If we don't recognize it, leave it be */
2036 return;
2037 
2038 	tmplocale = newlocale_hack(LC_NUMERIC_MASK, "C", NULL);
2039 	if (tmplocale == NULL) fprintf(stderr, "Locale error.\n");
2040 
2041 	for ( pt=val; isspace(*pt); ++pt );
2042 	for ( ept = val+strlen(val-1); ept>pt && isspace(*ept); --ept );
2043 	if ( KnownPrivates[i].type==pt_boolean ) {
2044 	    if ( strcasecmp(val,"true")==0 || strcasecmp(val,"t")==0 || strtol(val,NULL,10)!=0 ) {
2045 		/* If they make a mistake about case, correct it */
2046 		strings[r*cols+1].u.md_str = copy("true");
2047 		free(val);
2048 		GGadgetRedraw(g);
2049 	    } else if ( strcasecmp(val,"false")==0 || strcasecmp(val,"f")==0 || (*val=='0' && strtol(val,NULL,10)==0) ) {
2050 		strings[r*cols+1].u.md_str = copy("false");
2051 		free(val);
2052 		GGadgetRedraw(g);
2053 	    } else
2054 /* GT: The words "true" and "false" should be left untranslated. We are restricted */
2055 /* GT: here by what PostScript understands, and it only understands the English */
2056 /* GT: words. You may, of course, change it to something like ("true" (vrai) ou "false" (faux)) */
2057 		gwwv_post_notice(_("Bad type"),_("Expected boolean value.\n(\"true\" or \"false\")"));
2058 	} else if ( KnownPrivates[i].type==pt_code ) {
2059 	    if ( *pt!='\0' && (*pt!='{' || (ept>=pt && *ept!='}')) )
2060 		gwwv_post_notice(_("Bad type"),_("Expected PostScript code.\nWhich usually begins with a \"{\" and ends with a \"}\"."));
2061 	} else if ( KnownPrivates[i].type==pt_number ) {
2062 	    newval = rpldecimal(val,loc->decimal_point,tmplocale);
2063 	    if ( newval==NULL )
2064 		gwwv_post_notice(_("Bad type"),_("Expected number."));
2065 	    else if ( strcmp(newval,val)==0 )
2066 		free(newval);		/* No change */
2067 	    else {
2068 		strings[r*cols+1].u.md_str = newval;
2069 		free(val);
2070 		GGadgetRedraw(g);
2071 	    }
2072 	} else if ( KnownPrivates[i].type==pt_array ) {
2073 	    newval = rplarraydecimal(val,loc->decimal_point,tmplocale);
2074 	    if ( newval==NULL )
2075 		gwwv_post_notice(_("Bad type"),_("Expected number."));
2076 	    else if ( strcmp(newval,val)==0 )
2077 		free(newval);		/* No change */
2078 	    else {
2079 		strings[r*cols+1].u.md_str = newval;
2080 		free(val);
2081 		GGadgetRedraw(g);
2082 	    }
2083 	}
2084 	if (tmplocale != NULL) { freelocale_hack(tmplocale); tmplocale = NULL; }
2085     }
2086 }
2087 
PSPrivate_MatrixInit(struct matrixinit * mi,struct gfi_data * d)2088 static void PSPrivate_MatrixInit(struct matrixinit *mi,struct gfi_data *d) {
2089     SplineFont *sf = d->sf;
2090     int i,j;
2091     struct matrix_data *md;
2092 
2093     memset(mi,0,sizeof(*mi));
2094     mi->col_cnt = 2;
2095     mi->col_init = psprivate_ci;
2096 
2097     mi->initial_row_cnt = sf->private==NULL?0:sf->private->next;
2098     md = calloc(2*(mi->initial_row_cnt+1),sizeof(struct matrix_data));
2099     if ( sf->private!=NULL ) {
2100 	for ( i=j=0; i<sf->private->next; ++i ) {
2101 	    md[2*j  ].u.md_str = copy(sf->private->keys[i]);
2102 	    md[2*j+1].u.md_str = copy(sf->private->values[i]);
2103 	    ++j;
2104 	}
2105     }
2106     mi->matrix_data = md;
2107 
2108     mi->finishedit = PSPrivate_FinishEdit;
2109 }
2110 
GFI_ParsePrivate(struct gfi_data * d)2111 static struct psdict *GFI_ParsePrivate(struct gfi_data *d) {
2112     struct psdict *ret = calloc(1,sizeof(struct psdict));
2113     GGadget *private = GWidgetGetControl(d->gw,CID_Private);
2114     int rows, cols = GMatrixEditGetColCnt(private);
2115     struct matrix_data *strings = GMatrixEditGet(private, &rows);
2116     int i,j;
2117 
2118     ret->cnt = rows;
2119     ret->keys = malloc(rows*sizeof(char *));
2120     ret->values = malloc(rows*sizeof(char *));
2121     for ( i=j=0; i<rows; ++i ) {
2122 	if ( strings[i*cols+0].u.md_str!=NULL && strings[i*cols+1].u.md_str!=NULL ) {
2123 	    ret->keys[j] = copy(strings[i*cols+0].u.md_str);
2124 	    ret->values[j++] = copy(strings[i*cols+1].u.md_str);
2125 	}
2126     }
2127     ret->next = j;
2128 return( ret );
2129 }
2130 
PSPrivate_EnableButtons(GGadget * g,int r,int c)2131 static void PSPrivate_EnableButtons(GGadget *g, int r, int c) {
2132     int rows, cols = GMatrixEditGetColCnt(g);
2133     struct matrix_data *strings = _GMatrixEditGet(g, &rows);
2134     struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
2135     char *key = r>=0 && r<rows ? strings[r*cols+0].u.md_str : NULL;
2136     int has_hist = key!=NULL && (
2137 		    strcmp(key,"BlueValues")==0 ||
2138 		    strcmp(key,"OtherBlues")==0 ||
2139 		    strcmp(key,"StdHW")==0 ||
2140 		    strcmp(key,"StemSnapH")==0 ||
2141 		    strcmp(key,"StdVW")==0 ||
2142 		    strcmp(key,"StemSnapV")==0);
2143     int has_guess = key!=NULL && (has_hist ||
2144 		    strcmp(key,"BlueScale")==0 ||
2145 		    strcmp(key,"BlueShift")==0 ||
2146 		    strcmp(key,"BlueFuzz")==0 ||
2147 		    strcmp(key,"ForceBold")==0 ||
2148 		    strcmp(key,"LanguageGroup")==0 ||
2149 		    strcmp(key,"ExpansionFactor")==0);
2150     GGadgetSetEnabled(GWidgetGetControl(d->gw,CID_Guess), has_guess);
2151     GGadgetSetEnabled(GWidgetGetControl(d->gw,CID_Hist ), has_hist );
2152 }
2153 
PI_Guess(GGadget * g,GEvent * e)2154 static int PI_Guess(GGadget *g, GEvent *e) {
2155     GWindow gw;
2156     struct gfi_data *d;
2157     GGadget *private;
2158     struct psdict *tempdict;
2159     struct matrix_data *strings;
2160     int rows, cols, r;
2161     char *key, *ret;
2162 
2163     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
2164 	gw = GGadgetGetWindow(g);
2165 	d = GDrawGetUserData(gw);
2166 	private = GWidgetGetControl(gw,CID_Private);
2167 	strings = GMatrixEditGet(private, &rows);	/* Commit any changes made thus far */
2168 	cols = GMatrixEditGetColCnt(private);
2169 	r = GMatrixEditGetActiveRow(private);
2170 	key = strings[r*cols+0].u.md_str;
2171 	tempdict = calloc(1,sizeof(*tempdict));
2172 	SFPrivateGuess(d->sf,ly_fore,tempdict,key,true);
2173 	ret = copy(PSDictHasEntry(tempdict,key));
2174 	if ( ret!=NULL ) {
2175 	    free(strings[r*cols+1].u.md_str);
2176 	    strings[r*cols+1].u.md_str = ret;
2177 	    GGadgetRedraw(private);
2178 	}
2179 	PSDictFree(tempdict);
2180     }
2181 return( true );
2182 }
2183 
PI_Hist(GGadget * g,GEvent * e)2184 static int PI_Hist(GGadget *g, GEvent *e) {
2185     GWindow gw;
2186     struct gfi_data *d;
2187     GGadget *private;
2188     struct psdict *tempdict;
2189     enum hist_type h;
2190     struct matrix_data *strings;
2191     int rows, cols, r;
2192     char *key, *ret;
2193 
2194     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
2195 	gw = GGadgetGetWindow(g);
2196 	d = GDrawGetUserData(gw);
2197 	private = GWidgetGetControl(gw,CID_Private);
2198 	strings = _GMatrixEditGet(private, &rows);
2199 	cols = GMatrixEditGetColCnt(private);
2200 	r = GMatrixEditGetActiveRow(private);
2201 	key = strings[r*cols+0].u.md_str;
2202 	if ( strcmp(key,"BlueValues")==0 ||
2203 		strcmp(key,"OtherBlues")==0 )
2204 	    h = hist_blues;
2205 	else if ( strcmp(key,"StdHW")==0 ||
2206 		strcmp(key,"StemSnapH")==0 )
2207 	    h = hist_hstem;
2208 	else if ( strcmp(key,"StdVW")==0 ||
2209 		strcmp(key,"StemSnapV")==0 )
2210 	    h = hist_vstem;
2211 	else
2212 return( true );		/* can't happen */
2213 	tempdict = GFI_ParsePrivate(d);
2214 	SFHistogram(d->sf,ly_fore,tempdict,NULL,NULL,h);
2215 	ret = copy(PSDictHasEntry(tempdict,key));
2216 	if ( ret!=NULL ) {
2217 	    free(strings[r*cols+1].u.md_str);
2218 	    strings[r*cols+1].u.md_str = ret;
2219 	    GGadgetRedraw(private);
2220 	}
2221 	PSDictFree(tempdict);
2222     }
2223 return( true );
2224 }
2225 
GFI_NameChange(GGadget * g,GEvent * e)2226 static int GFI_NameChange(GGadget *g, GEvent *e) {
2227     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
2228 	GWindow gw = GGadgetGetWindow(g);
2229 	struct gfi_data *gfi = GDrawGetUserData(gw);
2230 	const unichar_t *uname = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Fontname));
2231 	unichar_t ubuf[50];
2232 	int i,j;
2233 	for ( j=0; noticeweights[j]!=NULL; ++j ) {
2234 	    for ( i=0; noticeweights[j][i]!=NULL; ++i ) {
2235 		if ( uc_strstrmatch(uname,noticeweights[j][i])!=NULL ) {
2236 		    uc_strcpy(ubuf, noticeweights[j]==knownweights ?
2237 			    realweights[i] : noticeweights[j][i]);
2238 		    GGadgetSetTitle(GWidgetGetControl(gw,CID_Weight),ubuf);
2239 	    break;
2240 		}
2241 	    }
2242 	    if ( noticeweights[j][i]!=NULL )
2243 	break;
2244 	}
2245 
2246 	/* If the user didn't set the full name yet, we guess it from the
2247 	 * postrscript name */
2248 	if ( gfi->human_untitled ) {
2249 	    unichar_t *cp = u_copy(uname);
2250 	    int i=0;
2251 	    /* replace the last hyphen with space */
2252 	    for( i=u_strlen(cp); i>=0; i-- ) {
2253 		if( cp[i] == '-' ) {
2254 		    cp[i] = ' ';
2255 		    break;
2256 		}
2257 	    }
2258 	    /* If the postscript name ends with "Regular" it is recommended not
2259 	     * to include it in the full name */
2260 	    if(u_endswith(cp,c_to_u(" Regular")) || u_endswith(cp,c_to_u(" regular"))) {
2261 		cp[u_strlen(cp) - strlen(" Regular")] ='\0';
2262 	    }
2263 	    GGadgetSetTitle(GWidgetGetControl(gw,CID_Human),cp);
2264 	    free(cp);
2265 	}
2266 	if ( gfi->family_untitled ) {
2267 	    const unichar_t *ept = uname+u_strlen(uname); unichar_t *temp;
2268 	    for ( i=0; knownweights[i]!=NULL; ++i ) {
2269 		if (( temp = uc_strstrmatch(uname,knownweights[i]))!=NULL && temp<ept && temp!=uname )
2270 		    ept = temp;
2271 	    }
2272 	    if (( temp = uc_strstrmatch(uname,"ital"))!=NULL && temp<ept && temp!=uname )
2273 		ept = temp;
2274 	    if (( temp = uc_strstrmatch(uname,"obli"))!=NULL && temp<ept && temp!=uname )
2275 		ept = temp;
2276 	    if (( temp = uc_strstrmatch(uname,"kurs"))!=NULL && temp<ept && temp!=uname )
2277 		ept = temp;
2278 	    if (( temp = uc_strstrmatch(uname,"slanted"))!=NULL && temp<ept && temp!=uname )
2279 		ept = temp;
2280 	    if (( temp = u_strchr(uname,'-'))!=NULL && temp!=uname )
2281 		ept = temp;
2282 	    temp = u_copyn(uname,ept-uname);
2283 	    GGadgetSetTitle(GWidgetGetControl(gw,CID_Family),temp);
2284 	}
2285     }
2286 return( true );
2287 }
2288 
GFI_FamilyChange(GGadget * g,GEvent * e)2289 static int GFI_FamilyChange(GGadget *g, GEvent *e) {
2290     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
2291 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
2292 	gfi->family_untitled = false;
2293     }
2294 return( true );
2295 }
2296 
GFI_DefBaseChange(GGadget * g,GEvent * e)2297 static int GFI_DefBaseChange(GGadget *g, GEvent *e) {
2298     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
2299 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
2300 	GGadgetSetChecked(GWidgetGetControl(gfi->gw,*_GGadgetGetTitle(g)!='\0'?CID_HasDefBase:CID_SameAsFontname),
2301 		true);
2302     }
2303 return( true );
2304 }
2305 
GFI_HumanChange(GGadget * g,GEvent * e)2306 static int GFI_HumanChange(GGadget *g, GEvent *e) {
2307     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
2308 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
2309 	gfi->human_untitled = false;
2310     }
2311 return( true );
2312 }
2313 
GFI_VMetricsCheck(GGadget * g,GEvent * e)2314 static int GFI_VMetricsCheck(GGadget *g, GEvent *e) {
2315     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
2316 	GWindow gw = GGadgetGetWindow(g);
2317 	int checked = GGadgetIsChecked(g);
2318 	GGadgetSetEnabled(GWidgetGetControl(GDrawGetParentWindow(gw),CID_VLineGap),checked);
2319 	GGadgetSetEnabled(GWidgetGetControl(GDrawGetParentWindow(gw),CID_VLineGapLab),checked);
2320     }
2321 return( true );
2322 }
2323 
GFI_EmChanged(GGadget * g,GEvent * e)2324 static int GFI_EmChanged(GGadget *g, GEvent *e) {
2325     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
2326 	char buf[20]; unichar_t ubuf[20];
2327 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
2328 	const unichar_t *ret = _GGadgetGetTitle(g); unichar_t *end;
2329 	int val = u_strtol(ret,&end,10), ascent, descent;
2330 	if ( *end )
2331 return( true );
2332 	switch ( GGadgetGetCid(g)) {
2333 	  case CID_Em:
2334 	    ascent = rint( ((double) val)*d->sf->ascent/(d->sf->ascent+d->sf->descent) );
2335 	    descent = val - ascent;
2336 	  break;
2337 	  case CID_Ascent:
2338 	    ascent = val;
2339 	    ret = _GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Descent));
2340 	    descent = u_strtol(ret,&end,10);
2341 	    if ( *end )
2342 return( true );
2343 	  break;
2344 	  case CID_Descent:
2345 	    descent = val;
2346 	    ret = _GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Ascent));
2347 	    ascent = u_strtol(ret,&end,10);
2348 	    if ( *end )
2349 return( true );
2350 	  break;
2351 	}
2352 	sprintf( buf, "%d", ascent ); if ( ascent==0 ) buf[0]='\0'; uc_strcpy(ubuf,buf);
2353 	GGadgetSetTitle(GWidgetGetControl(d->gw,CID_Ascent),ubuf);
2354 	sprintf( buf, "%d", descent ); if ( descent==0 ) buf[0]='\0'; uc_strcpy(ubuf,buf);
2355 	GGadgetSetTitle(GWidgetGetControl(d->gw,CID_Descent),ubuf);
2356 	sprintf( buf, "%d", ascent+descent ); if ( ascent+descent==0 ) buf[0]='\0'; uc_strcpy(ubuf,buf);
2357 	GGadgetSetTitle(GWidgetGetControl(d->gw,CID_Em),ubuf);
2358     }
2359 return( true );
2360 }
2361 
GFI_GuessItalic(GGadget * g,GEvent * e)2362 static int GFI_GuessItalic(GGadget *g, GEvent *e) {
2363     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
2364 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
2365 	double val = SFGuessItalicAngle(d->sf);
2366 	char buf[30]; unichar_t ubuf[30];
2367 	sprintf( buf, "%.1f", val);
2368 	uc_strcpy(ubuf,buf);
2369 	GGadgetSetTitle(GWidgetGetControl(d->gw,CID_ItalicAngle),ubuf);
2370     }
2371 return( true );
2372 }
2373 
GFI_Close(struct gfi_data * d)2374 static void GFI_Close(struct gfi_data *d) {
2375 
2376     GDrawDestroyWindow(d->gw);
2377     if ( d->sf->fontinfo == d )
2378 	d->sf->fontinfo = NULL;
2379     FVRefreshAll(d->sf);
2380     d->done = true;
2381     /* d will be freed by destroy event */;
2382 }
2383 
GFI_Mark_FinishEdit(GGadget * g,int r,int c,int wasnew)2384 static void GFI_Mark_FinishEdit(GGadget *g,int r, int c, int wasnew) {
2385     struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
2386     int is_markclass = GGadgetGetCid(g) == CID_MarkClasses;
2387 
2388     if ( c==0 ) {
2389 	/* Name can't be null. No spaces. No duplicates */
2390 	int rows, cols = GMatrixEditGetColCnt(g);
2391 	struct matrix_data *classes = _GMatrixEditGet(g,&rows);
2392 	char *pt;
2393 	int i;
2394 
2395 	if ( classes[r*cols+c].u.md_str==NULL || *classes[r*cols+c].u.md_str=='\0' ) {
2396 	    ff_post_error(_("No Name"), _("Please specify a name for this mark class or set"));
2397 return;
2398 	}
2399 	for ( pt = classes[r*cols+c].u.md_str; *pt!='\0'; ++pt ) {
2400 	    if ( *pt==' ' ) {
2401 		ff_post_error(_("Bad Name"), _("Mark class/set names should not contain spaces."));
2402 return;
2403 	    }
2404 	}
2405 	for ( i=0; i<rows; ++i ) if ( i!=r ) {
2406 	    if ( strcmp(classes[r*cols+c].u.md_str,classes[i*cols+c].u.md_str)==0 ) {
2407 		ff_post_error(_("Duplicate Name"), _("This name was previously used to identify mark class/set #%d."), i+1);
2408 return;
2409 	    }
2410 	}
2411     } else {
2412 	if ( is_markclass )
2413 	    ME_ClassCheckUnique(g, r, c, d->sf);
2414 	else
2415 	    ME_SetCheckUnique(g, r, c, d->sf);
2416     }
2417 }
2418 
GFI_Mark_PickGlyphsForClass(GGadget * g,int r,int c)2419 static char *GFI_Mark_PickGlyphsForClass(GGadget *g,int r, int c) {
2420     struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
2421     int rows, cols = GMatrixEditGetColCnt(g);
2422     struct matrix_data *classes = _GMatrixEditGet(g,&rows);
2423     char *new = GlyphSetFromSelection(d->sf,d->def_layer,classes[r*cols+c].u.md_str);
2424 return( new );
2425 }
2426 
GFI_Mark_DeleteClass(GGadget * g,int whichclass)2427 static void GFI_Mark_DeleteClass(GGadget *g,int whichclass) {
2428     struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
2429     int rows/*, cols = GMatrixEditGetColCnt(g)*/;
2430     struct matrix_data *classes = _GMatrixEditGet(g,&rows);
2431     int is_markclass = GGadgetGetCid(g) == CID_MarkClasses;
2432     SplineFont *sf = d->sf;
2433     OTLookup *otl;
2434     int isgpos;
2435 
2436     whichclass += is_markclass;		/* Classes begin at 1, Sets begin at 0 */
2437     for ( isgpos=0; isgpos<2; ++isgpos ) {
2438 	for ( otl = isgpos ? sf->gpos_lookups : sf->gsub_lookups; otl!=NULL; otl=otl->next ) {
2439 	    if ( is_markclass ) {
2440 		int old = (otl->lookup_flags & pst_markclass)>>8;
2441 		if ( old==whichclass ) {
2442 		    ff_post_notice(_("Mark Class was in use"),_("This mark class (%s) was used in lookup %s"),
2443 			    classes[2*whichclass-2].u.md_str,otl->lookup_name);
2444 		    otl->lookup_flags &= ~ pst_markclass;
2445 		} else if ( old>whichclass ) {
2446 		    otl->lookup_flags &= ~ pst_markclass;
2447 		    otl->lookup_flags |= (old-1)<<8;
2448 		}
2449 	    } else if ( otl->lookup_flags&pst_usemarkfilteringset ) {
2450 		int old = (otl->lookup_flags & pst_markset)>>16;
2451 		if ( old==whichclass ) {
2452 		    ff_post_notice(_("Mark Set was in use"),_("This mark set (%s) was used in lookup %s"),
2453 			    classes[2*whichclass+0].u.md_str,otl->lookup_name);
2454 		    otl->lookup_flags &= ~ pst_markset;
2455 		    otl->lookup_flags &= ~pst_usemarkfilteringset;
2456 		} else if ( old>whichclass ) {
2457 		    otl->lookup_flags &= ~ pst_markset;
2458 		    otl->lookup_flags |= (old-1)<<16;
2459 		}
2460 	    }
2461 	}
2462     }
2463 }
2464 
GFI_GlyphListCompletion(GGadget * t,int from_tab)2465 static unichar_t **GFI_GlyphListCompletion(GGadget *t,int from_tab) {
2466     struct gfi_data *d = GDrawGetUserData(GDrawGetParentWindow(GGadgetGetWindow(t)));
2467     SplineFont *sf = d->sf;
2468 
2469 return( SFGlyphNameCompletion(sf,t,from_tab,true));
2470 }
2471 
GFI_CancelClose(struct gfi_data * d)2472 static void GFI_CancelClose(struct gfi_data *d) {
2473     int isgpos,i,j;
2474 
2475     MacFeatListFree(GGadgetGetUserData((GWidgetGetControl(
2476 	    d->gw,CID_Features))));
2477     for ( isgpos=0; isgpos<2; ++isgpos ) {
2478 	struct lkdata *lk = &d->tables[isgpos];
2479 	for ( i=0; i<lk->cnt; ++i ) {
2480 	    if ( lk->all[i].new )
2481 		SFRemoveLookup(d->sf,lk->all[i].lookup,0);
2482 	    else for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
2483 		if ( lk->all[i].subtables[j].new )
2484 		    SFRemoveLookupSubTable(d->sf,lk->all[i].subtables[j].subtable,0);
2485 	    }
2486 	    free(lk->all[i].subtables);
2487 	}
2488 	free(lk->all);
2489     }
2490     GFI_Close(d);
2491 }
2492 
OtfNameFromStyleNames(GGadget * me)2493 static struct otfname *OtfNameFromStyleNames(GGadget *me) {
2494     int i;
2495     int rows;
2496     struct matrix_data *strings = GMatrixEditGet(me, &rows);
2497     struct otfname *head=NULL, *last, *cur;
2498 
2499     for ( i=0; i<rows; ++i ) {
2500 	cur = chunkalloc(sizeof(struct otfname));
2501 	cur->lang = strings[2*i  ].u.md_ival;
2502 	cur->name = copy(strings[2*i+1].u.md_str);
2503 	if ( head==NULL )
2504 	    head = cur;
2505 	else
2506 	    last->next = cur;
2507 	last = cur;
2508     }
2509 return( head );
2510 }
2511 
GListMoveSelected(GGadget * list,int offset)2512 void GListMoveSelected(GGadget *list,int offset) {
2513     int32 len; int i,j;
2514     GTextInfo **old, **new;
2515 
2516     old = GGadgetGetList(list,&len);
2517     new = calloc(len+1,sizeof(GTextInfo *));
2518     j = (offset<0 ) ? 0 : len-1;
2519     for ( i=0; i<len; ++i ) if ( old[i]->selected ) {
2520 	if ( offset==0x80000000 || offset==0x7fffffff )
2521 	    /* Do Nothing */;
2522 	else if ( offset<0 ) {
2523 	    if ( (j= i+offset)<0 ) j=0;
2524 	    while ( new[j] ) ++j;
2525 	} else {
2526 	    if ( (j= i+offset)>=len ) j=len-1;
2527 	    while ( new[j] ) --j;
2528 	}
2529 	new[j] = malloc(sizeof(GTextInfo));
2530 	*new[j] = *old[i];
2531 	new[j]->text = u_copy(new[j]->text);
2532 	if ( offset<0 ) ++j; else --j;
2533     }
2534     for ( i=j=0; i<len; ++i ) if ( !old[i]->selected ) {
2535 	while ( new[j] ) ++j;
2536 	new[j] = malloc(sizeof(GTextInfo));
2537 	*new[j] = *old[i];
2538 	new[j]->text = u_copy(new[j]->text);
2539 	++j;
2540     }
2541     new[len] = calloc(1,sizeof(GTextInfo));
2542     GGadgetSetList(list,new,false);
2543 }
2544 
GListDelSelected(GGadget * list)2545 void GListDelSelected(GGadget *list) {
2546     int32 len; int i,j;
2547     GTextInfo **old, **new;
2548 
2549     old = GGadgetGetList(list,&len);
2550     new = calloc(len+1,sizeof(GTextInfo *));
2551     for ( i=j=0; i<len; ++i ) if ( !old[i]->selected ) {
2552 	new[j] = malloc(sizeof(GTextInfo));
2553 	*new[j] = *old[i];
2554 	new[j]->text = u_copy(new[j]->text);
2555 	++j;
2556     }
2557     new[j] = calloc(1,sizeof(GTextInfo));
2558     GGadgetSetList(list,new,false);
2559 }
2560 
GListChangeLine(GGadget * list,int pos,const unichar_t * line)2561 GTextInfo *GListChangeLine(GGadget *list,int pos, const unichar_t *line) {
2562     GTextInfo **old, **new;
2563     int32 i,len;
2564 
2565     old = GGadgetGetList(list,&len);
2566     new = calloc(len+1,sizeof(GTextInfo *));
2567     for ( i=0; i<len; ++i ) {
2568 	new[i] = malloc(sizeof(GTextInfo));
2569 	*new[i] = *old[i];
2570 	if ( i!=pos )
2571 	    new[i]->text = u_copy(new[i]->text);
2572 	else
2573 	    new[i]->text = u_copy(line);
2574     }
2575     new[i] = calloc(1,sizeof(GTextInfo));
2576     GGadgetSetList(list,new,false);
2577     GGadgetScrollListToPos(list,pos);
2578 return( new[pos]);
2579 }
2580 
GListAppendLine(GGadget * list,const unichar_t * line,int select)2581 GTextInfo *GListAppendLine(GGadget *list,const unichar_t *line,int select) {
2582     GTextInfo **old, **new;
2583     int32 i,len;
2584 
2585     old = GGadgetGetList(list,&len);
2586     new = calloc(len+2,sizeof(GTextInfo *));
2587     for ( i=0; i<len; ++i ) {
2588 	new[i] = malloc(sizeof(GTextInfo));
2589 	*new[i] = *old[i];
2590 	new[i]->text = u_copy(new[i]->text);
2591 	if ( select ) new[i]->selected = false;
2592     }
2593     new[i] = calloc(1,sizeof(GTextInfo));
2594     new[i]->fg = new[i]->bg = COLOR_DEFAULT;
2595     new[i]->userdata = NULL;
2596     new[i]->text = u_copy(line);
2597     new[i]->selected = select;
2598     new[i+1] = calloc(1,sizeof(GTextInfo));
2599     GGadgetSetList(list,new,false);
2600     GGadgetScrollListToPos(list,i);
2601 return( new[i]);
2602 }
2603 
GListChangeLine8(GGadget * list,int pos,const char * line)2604 GTextInfo *GListChangeLine8(GGadget *list,int pos, const char *line) {
2605     GTextInfo **old, **new;
2606     int32 i,len;
2607 
2608     old = GGadgetGetList(list,&len);
2609     new = calloc(len+1,sizeof(GTextInfo *));
2610     for ( i=0; i<len; ++i ) {
2611 	new[i] = malloc(sizeof(GTextInfo));
2612 	*new[i] = *old[i];
2613 	if ( i!=pos )
2614 	    new[i]->text = u_copy(new[i]->text);
2615 	else
2616 	    new[i]->text = utf82u_copy(line);
2617     }
2618     new[i] = calloc(1,sizeof(GTextInfo));
2619     GGadgetSetList(list,new,false);
2620     GGadgetScrollListToPos(list,pos);
2621 return( new[pos]);
2622 }
2623 
GListAppendLine8(GGadget * list,const char * line,int select)2624 GTextInfo *GListAppendLine8(GGadget *list,const char *line,int select) {
2625     GTextInfo **old, **new;
2626     int32 i,len;
2627 
2628     old = GGadgetGetList(list,&len);
2629     new = calloc(len+2,sizeof(GTextInfo *));
2630     for ( i=0; i<len; ++i ) {
2631 	new[i] = malloc(sizeof(GTextInfo));
2632 	*new[i] = *old[i];
2633 	new[i]->text = u_copy(new[i]->text);
2634 	if ( select ) new[i]->selected = false;
2635     }
2636     new[i] = calloc(1,sizeof(GTextInfo));
2637     new[i]->fg = new[i]->bg = COLOR_DEFAULT;
2638     new[i]->userdata = NULL;
2639     new[i]->text = utf82u_copy(line);
2640     new[i]->selected = select;
2641     new[i+1] = calloc(1,sizeof(GTextInfo));
2642     GGadgetSetList(list,new,false);
2643     GGadgetScrollListToPos(list,i);
2644 return( new[i]);
2645 }
2646 
GFI_Cancel(GGadget * g,GEvent * e)2647 static int GFI_Cancel(GGadget *g, GEvent *e) {
2648     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
2649 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
2650 	GFI_CancelClose(d);
2651     }
2652 return( true );
2653 }
2654 
BadFamily()2655 static void BadFamily() {
2656     ff_post_error(_("Bad Family Name"),_("Bad Family Name, must begin with an alphabetic character."));
2657 }
2658 
SetFontName(GWindow gw,SplineFont * sf)2659 static int SetFontName(GWindow gw, SplineFont *sf) {
2660     const unichar_t *ufamily = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Family));
2661     const unichar_t *ufont = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Fontname));
2662     const unichar_t *uweight = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Weight));
2663     const unichar_t *uhum = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Human));
2664     int diff = uc_strcmp(ufont,sf->fontname)!=0;
2665 
2666     free(sf->familyname);
2667     free(sf->fontname);
2668     free(sf->weight);
2669     free(sf->fullname);
2670     sf->familyname = cu_copy(ufamily);
2671     sf->fontname = cu_copy(ufont);
2672     sf->weight = cu_copy(uweight);
2673     sf->fullname = cu_copy(uhum);
2674 return( diff );
2675 }
2676 
CheckNames(struct gfi_data * d)2677 static int CheckNames(struct gfi_data *d) {
2678     const unichar_t *ufamily = _GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Family));
2679     const unichar_t *ufont = _GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Fontname));
2680     unichar_t *end; const unichar_t *pt;
2681     char *buts[3];
2682     buts[0] = _("_OK"); buts[1] = _("_Cancel"); buts[2]=NULL;
2683 
2684     if ( u_strlen(ufont)>63 ) {
2685 	ff_post_error(_("Bad Font Name"),_("A PostScript name should be ASCII\nand must not contain (){}[]<>%%/ or space\nand must be shorter than 63 characters"));
2686 return( false );
2687     }
2688 
2689     if ( *ufamily=='\0' ) {
2690 	ff_post_error(_("A Font Family name is required"),_("A Font Family name is required"));
2691 return( false );
2692     }
2693     /* A postscript name cannot be a number. There are two ways it can be a */
2694     /*  number, it can be a real (which we can check for with strtod) or */
2695     /*  it can be a "radix number" which is <intval>'#'<intval>. I'll only */
2696     /*  do a cursory test for that */
2697     u_strtod(ufamily,&end);
2698     if ( *end=='\0' || (isdigit(ufamily[0]) && u_strchr(ufamily,'#')!=NULL) ) {
2699 	ff_post_error(_("Bad Font Family Name"),_("A PostScript name may not be a number"));
2700 return( false );
2701     }
2702     if ( u_strlen(ufamily)>31 ) {
2703 	if ( gwwv_ask(_("Bad Font Family Name"),(const char **) buts,0,1,_("Some versions of Windows will refuse to install postscript fonts if the familyname is longer than 31 characters. Do you want to continue anyway?"))==1 )
2704 return( false );
2705     } else {
2706 	if ( u_strlen(ufont)>31 ) {
2707 	    if ( gwwv_ask(_("Bad Font Name"),(const char **) buts,0,1,_("Some versions of Windows will refuse to install postscript fonts if the fontname is longer than 31 characters. Do you want to continue anyway?"))==1 )
2708 return( false );
2709 	} else if ( u_strlen(ufont)>29 ) {
2710 	    if ( gwwv_ask(_("Bad Font Name"),(const char **) buts,0,1,_("Adobe's fontname spec (5088.FontNames.pdf) says that fontnames should not be longer than 29 characters. Do you want to continue anyway?"))==1 )
2711 return( false );
2712 	}
2713     }
2714     while ( *ufamily ) {
2715 	if ( *ufamily<' ' || *ufamily>=0x7f ) {
2716 	    ff_post_error(_("Bad Font Family Name"),_("A PostScript name should be ASCII\nand must not contain (){}[]<>%%/ or space"));
2717 return( false );
2718 	}
2719 	++ufamily;
2720     }
2721 
2722     u_strtod(ufont,&end);
2723     if ( (*end=='\0' || (isdigit(ufont[0]) && u_strchr(ufont,'#')!=NULL)) &&
2724 	    *ufont!='\0' ) {
2725 	ff_post_error(_("Bad Font Name"),_("A PostScript name may not be a number"));
2726 return( false );
2727     }
2728     for ( pt=ufont; *pt; ++pt ) {
2729 	if ( *pt<=' ' || *pt>=0x7f ||
2730 		*pt=='(' || *pt=='[' || *pt=='{' || *pt=='<' ||
2731 		*pt==')' || *pt==']' || *pt=='}' || *pt=='>' ||
2732 		*pt=='%' || *pt=='/' ) {
2733 	    ff_post_error(_("Bad Font Name"),_("A PostScript name should be ASCII\nand must not contain (){}[]<>%%/ or space"));
2734 return( false );
2735 	}
2736     }
2737 return( true );
2738 }
2739 
2740 static int ttfspecials[] = { ttf_copyright, ttf_family, ttf_fullname,
2741 	ttf_subfamily, ttf_version, -1 };
2742 
tn_recalculatedef(struct gfi_data * d,int cur_id)2743 static char *tn_recalculatedef(struct gfi_data *d,int cur_id) {
2744     char versionbuf[40], *v;
2745 
2746     switch ( cur_id ) {
2747       case ttf_copyright:
2748 return( GGadgetGetTitle8(GWidgetGetControl(d->gw,CID_Notice)));
2749       case ttf_family:
2750 return( GGadgetGetTitle8(GWidgetGetControl(d->gw,CID_Family)));
2751       case ttf_fullname:
2752 return( GGadgetGetTitle8(GWidgetGetControl(d->gw,CID_Human)));
2753       case ttf_subfamily:
2754 return( u2utf8_copy(_uGetModifiers(
2755 		_GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Fontname)),
2756 		_GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Family)),
2757 		_GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Weight)))));
2758       case ttf_version:
2759 	sprintf(versionbuf,_("Version %.20s"),
2760 		v=GGadgetGetTitle8(GWidgetGetControl(d->gw,CID_Version)));
2761 	free(v);
2762 return( copy(versionbuf));
2763       default:
2764 return( NULL );
2765     }
2766 }
2767 
TN_DefaultName(GGadget * g,int r,int c)2768 static char *TN_DefaultName(GGadget *g, int r, int c) {
2769     struct gfi_data *d = GGadgetGetUserData(g);
2770     int rows;
2771     struct matrix_data *strings = GMatrixEditGet(g, &rows);
2772 
2773     if ( strings==NULL || !strings[3*r+2].user_bits )
2774 return( NULL );
2775 
2776 return( tn_recalculatedef(d,strings[3*r+1].u.md_ival ));
2777 }
2778 
langname(int lang,char * buffer)2779 static const char *langname(int lang,char *buffer) {
2780     int i;
2781     for ( i=0; mslanguages[i].text!=NULL; ++i )
2782 	if ( mslanguages[i].userdata == (void *) (intpt) lang )
2783 return( (char *) mslanguages[i].text );
2784 
2785     sprintf( buffer, "%04X", lang );
2786 return( buffer );
2787 }
2788 
strid_sorter(const void * pt1,const void * pt2)2789 static int strid_sorter(const void *pt1, const void *pt2) {
2790     const struct matrix_data *n1 = pt1, *n2 = pt2;
2791     char buf1[20], buf2[20];
2792     const char *l1, *l2;
2793 
2794     if ( n1[1].u.md_ival!=n2[1].u.md_ival )
2795 return( n1[1].u.md_ival - n2[1].u.md_ival );
2796 
2797     l1 = langname(n1[0].u.md_ival,buf1);
2798     l2 = langname(n2[0].u.md_ival,buf2);
2799 return( strcoll(l1,l2));
2800 }
2801 
lang_sorter(const void * pt1,const void * pt2)2802 static int lang_sorter(const void *pt1, const void *pt2) {
2803     const struct matrix_data *n1 = pt1, *n2 = pt2;
2804     char buf1[20], buf2[20];
2805     const char *l1, *l2;
2806 
2807     if ( n1[0].u.md_ival==n2[0].u.md_ival )
2808 return( n1[1].u.md_ival - n2[1].u.md_ival );
2809 
2810     l1 = langname(n1[0].u.md_ival,buf1);
2811     l2 = langname(n2[0].u.md_ival,buf2);
2812 return( strcoll(l1,l2));
2813 }
2814 
2815 static int ms_thislocale = 0;
specialvals(const struct matrix_data * n)2816 static int specialvals(const struct matrix_data *n) {
2817     if ( n[0].u.md_ival == ms_thislocale )
2818 return( -10000000 );
2819     else if ( (n[0].u.md_ival&0x3ff) == (ms_thislocale&0x3ff) )
2820 return( -10000000 + (n[0].u.md_ival&~0x3ff) );
2821     if ( n[0].u.md_ival == 0x409 )	/* English */
2822 return( -1000000 );
2823     else if ( (n[0].u.md_ival&0x3ff) == 9 )
2824 return( -1000000 + (n[0].u.md_ival&~0x3ff) );
2825 
2826 return( 1 );
2827 }
2828 
speciallang_sorter(const void * pt1,const void * pt2)2829 static int speciallang_sorter(const void *pt1, const void *pt2) {
2830     const struct matrix_data *n1 = pt1, *n2 = pt2;
2831     char buf1[20], buf2[20];
2832     const char *l1, *l2;
2833     int pos1=1, pos2=1;
2834 
2835     /* sort so that entries for the current language are first, then English */
2836     /*  then alphabetical order */
2837     if ( n1[0].u.md_ival==n2[0].u.md_ival )
2838 return( n1[1].u.md_ival - n2[1].u.md_ival );
2839 
2840     pos1 = specialvals(n1); pos2 = specialvals(n2);
2841     if ( pos1<0 || pos2<0 )
2842 return( pos1-pos2 );
2843     l1 = langname(n1[0].u.md_ival,buf1);
2844     l2 = langname(n2[0].u.md_ival,buf2);
2845 return( strcoll(l1,l2));
2846 }
2847 
TTFNames_Resort(struct gfi_data * d)2848 static void TTFNames_Resort(struct gfi_data *d) {
2849     int(*compar)(const void *, const void *);
2850     GGadget *edit = GWidgetGetControl(d->gw,CID_TNames);
2851     int rows;
2852     struct matrix_data *strings = GMatrixEditGet(edit, &rows);
2853 
2854     if ( strings==NULL )
2855 return;
2856 
2857     if ( GGadgetIsChecked(GWidgetGetControl(d->gw,CID_TNLangSort)) )
2858 	compar = lang_sorter;
2859     else if ( GGadgetIsChecked(GWidgetGetControl(d->gw,CID_TNStringSort)) )
2860 	compar = strid_sorter;
2861     else
2862 	compar = speciallang_sorter;
2863     ms_thislocale = d->langlocalecode;
2864     qsort(strings,rows,3*sizeof(struct matrix_data),compar);
2865 }
2866 
GFI_Char(struct gfi_data * d,GEvent * event)2867 static int GFI_Char(struct gfi_data *d,GEvent *event) {
2868     if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
2869 	help("ui/dialogs/fontinfo.html", NULL);
2870 return( true );
2871     } else if ( GMenuIsCommand(event,H_("Save All|Alt+Ctl+S") )) {
2872 	MenuSaveAll(NULL,NULL,NULL);
2873 return( true );
2874     } else if ( GMenuIsCommand(event,H_("Quit|Ctl+Q") )) {
2875 	MenuExit(NULL,NULL,NULL);
2876 return( true );
2877     } else if ( GMenuIsCommand(event,H_("Close|Ctl+Shft+Q") )) {
2878 	GFI_CancelClose(d);
2879 return( true );
2880     }
2881 return( false );
2882 }
2883 
CheckActiveStyleTranslation(struct gfi_data * d,struct matrix_data * strings,int r,int rows,int iswws)2884 static int CheckActiveStyleTranslation(struct gfi_data *d,
2885 	struct matrix_data *strings,int r, int rows, int iswws ) {
2886     int i,j, eng_pos, other_pos;
2887     char *english, *new=NULL, *temp, *pt;
2888     int other_lang = strings[3*r].u.md_ival;
2889     int changed = false;
2890     int search_sid = iswws ? ttf_wwssubfamily : ttf_subfamily;
2891 
2892     for ( i=rows-1; i>=0 ; --i )
2893 	if ( strings[3*i+1].u.md_ival==search_sid &&
2894 		strings[3*i].u.md_ival == 0x409 )
2895     break;
2896     if ( i<0 && iswws ) {
2897 	for ( i=rows-1; i>=0; --i )
2898 	    if ( strings[3*i+1].u.md_ival==ttf_subfamily &&
2899 		    strings[3*i].u.md_ival == other_lang ) {
2900 		new = copy(strings[3*i+2].u.md_str);
2901 		changed = true;
2902 	break;
2903 	    }
2904     } else {
2905 	if ( i<0 || (english = strings[3*i+2].u.md_str)==NULL )
2906 	    new = tn_recalculatedef(d,ttf_subfamily);
2907 	else
2908 	    new = copy(english);
2909 	for ( i=0; stylelist[i]!=NULL; ++i ) {
2910 	    eng_pos = other_pos = -1;
2911 	    for ( j=0; stylelist[i][j].str!=NULL; ++j ) {
2912 		if ( stylelist[i][j].lang == other_lang ) {
2913 		    other_pos = j;
2914 	    break;
2915 		}
2916 	    }
2917 	    if ( other_pos==-1 )
2918 	continue;
2919 	    for ( j=0; stylelist[i][j].str!=NULL; ++j ) {
2920 		if ( stylelist[i][j].lang == 0x409 &&
2921 			(pt = strstrmatch(new,stylelist[i][j].str))!=NULL ) {
2922 		    if ( pt==new && strlen(stylelist[i][j].str)==strlen(new) ) {
2923 			free(new);
2924 			free(strings[3*r+2].u.md_str);
2925 			if ( other_lang==0x415 ) {
2926 			    /* polish needs a word before the translation */
2927 			    strings[3*r+2].u.md_str = malloc(strlen("odmiana ")+strlen(stylelist[i][other_pos].str)+1);
2928 			    strcpy(strings[3*r+2].u.md_str,"odmiana ");
2929 			    strcat(strings[3*r+2].u.md_str,stylelist[i][other_pos].str);
2930 			} else
2931 			    strings[3*r+2].u.md_str = copy(stylelist[i][other_pos].str);
2932     return( true );
2933 		    }
2934 		    temp = malloc((strlen(new)
2935 			    + strlen(stylelist[i][other_pos].str)
2936 			    - strlen(stylelist[i][j].str)
2937 			    +1));
2938 		    strncpy(temp,new,pt-new);
2939 		    strcpy(temp+(pt-new),stylelist[i][other_pos].str);
2940 		    strcat(temp+(pt-new),pt+strlen(stylelist[i][j].str));
2941 		    free(new);
2942 		    new = temp;
2943 		    changed = true;
2944 	    continue;
2945 		}
2946 	    }
2947 	}
2948     }
2949     if ( changed ) {
2950 	free(strings[3*r+2].u.md_str);
2951 	if ( other_lang==0x415 ) {
2952 	    /* polish needs a word before the translation */
2953 	    strings[3*r+2].u.md_str = malloc(strlen("odmiana ")+strlen(new)+1);
2954 	    strcpy(strings[3*r+2].u.md_str,"odmiana ");
2955 	    strcat(strings[3*r+2].u.md_str,new);
2956 	    free(new);
2957 	} else
2958 	    strings[3*r+2].u.md_str = new;
2959     } else
2960 	free(new);
2961 return( changed );
2962 }
2963 
2964 #define MID_ToggleBase	1
2965 #define MID_MultiEdit	2
2966 #define MID_Delete	3
2967 
TN_StrPopupDispatch(GWindow gw,GMenuItem * mi,GEvent * e)2968 static void TN_StrPopupDispatch(GWindow gw, GMenuItem *mi, GEvent *e) {
2969     struct gfi_data *d = GDrawGetUserData(GDrawGetParentWindow(gw));
2970     GGadget *g = GWidgetGetControl(d->gw,CID_TNames);
2971 
2972     switch ( mi->mid ) {
2973       case MID_ToggleBase: {
2974 	int rows;
2975 	struct matrix_data *strings = GMatrixEditGet(g, &rows);
2976 	strings[3*d->tn_active+2].frozen = !strings[3*d->tn_active+2].frozen;
2977 	if ( strings[3*d->tn_active+2].frozen ) {
2978 	    free( strings[3*d->tn_active+2].u.md_str );
2979 	    strings[3*d->tn_active+2].u.md_str = NULL;
2980 	} else {
2981 	    strings[3*d->tn_active+2].u.md_str = tn_recalculatedef(d,strings[3*d->tn_active+1].u.md_ival);
2982 	}
2983 	GGadgetRedraw(g);
2984       } break;
2985       case MID_MultiEdit:
2986 	GMatrixEditStringDlg(g,d->tn_active,2);
2987       break;
2988       case MID_Delete:
2989 	GMatrixEditDeleteRow(g,d->tn_active);
2990       break;
2991     }
2992 }
2993 
menusort(const void * m1,const void * m2)2994 static int menusort(const void *m1, const void *m2) {
2995     const GMenuItem *mi1 = m1, *mi2 = m2;
2996 
2997     /* Should do a strcoll here, but I never wrote one */
2998     if ( mi1->ti.text_is_1byte && mi2->ti.text_is_1byte )
2999 return( strcoll( (char *) (mi1->ti.text), (char *) (mi2->ti.text)) );
3000     else
3001 return( u_strcmp(mi1->ti.text,mi2->ti.text));
3002 }
3003 
TN_StrIDEnable(GGadget * g,GMenuItem * mi,int r,int c)3004 static void TN_StrIDEnable(GGadget *g,GMenuItem *mi, int r, int c) {
3005     int rows, i, j;
3006     struct matrix_data *strings = GMatrixEditGet(g, &rows);
3007 
3008     for ( i=0; mi[i].ti.text!=NULL; ++i ) {
3009 	int strid = (intpt) mi[i].ti.userdata;
3010 	for ( j=0; j<rows; ++j ) if ( j!=r )
3011 	    if ( strings[3*j].u.md_ival == strings[3*r].u.md_ival &&
3012 		    strings[3*j+1].u.md_ival == strid ) {
3013 		mi[i].ti.disabled = true;
3014 	break;
3015 	    }
3016     }
3017     qsort(mi,i,sizeof(mi[0]),menusort);
3018 }
3019 
TN_LangEnable(GGadget * g,GMenuItem * mi,int r,int c)3020 static void TN_LangEnable(GGadget *g,GMenuItem *mi, int r, int c) {
3021     int i;
3022 
3023     for ( i=0; mi[i].ti.text!=NULL; ++i );
3024     qsort(mi,i,sizeof(mi[0]),menusort);
3025 }
3026 
TN_NewName(GGadget * g,int row)3027 static void TN_NewName(GGadget *g,int row) {
3028     int rows;
3029     struct matrix_data *strings = GMatrixEditGet(g, &rows);
3030 
3031     strings[3*row+1].u.md_ival = ttf_subfamily;
3032 }
3033 
TN_FinishEdit(GGadget * g,int row,int col,int wasnew)3034 static void TN_FinishEdit(GGadget *g,int row,int col,int wasnew) {
3035     int i,rows;
3036     struct matrix_data *strings = GMatrixEditGet(g, &rows);
3037     uint8 found[ttf_namemax];
3038     struct gfi_data *d = (struct gfi_data *) GGadgetGetUserData(g);
3039     int ret = false;
3040 
3041     if ( col==2 ) {
3042 	if ( strings[3*row+2].u.md_str==NULL || *strings[3*row+2].u.md_str=='\0' ) {
3043 	    GMatrixEditDeleteRow(g,row);
3044 	    ret = true;
3045 	}
3046     } else {
3047 	if ( col==0 ) {
3048 	    memset(found,0,sizeof(found));
3049 	    found[ttf_idontknow] = true;	/* reserved name id */
3050 	    for ( i=0; i<rows; ++i ) if ( i!=row ) {
3051 		if ( strings[3*i].u.md_ival == strings[3*row].u.md_ival )	/* Same language */
3052 		    found[strings[3*i+1].u.md_ival] = true;
3053 	    }
3054 	    if ( found[ strings[3*row+1].u.md_ival ] ) {
3055 		/* This language already has an entry for this strid */
3056 		/* pick another */
3057 		if ( !found[ttf_subfamily] ) {
3058 		    strings[3*row+1].u.md_ival = ttf_subfamily;
3059 		    ret = true;
3060 		} else {
3061 		    for ( i=0; i<ttf_namemax; ++i )
3062 			if ( !found[i] ) {
3063 			    strings[3*row+1].u.md_ival = i;
3064 			    ret = true;
3065 		    break;
3066 			}
3067 		}
3068 	    }
3069 	}
3070 	if ( (strings[3*row+2].u.md_str==NULL || *strings[3*row+2].u.md_str=='\0') ) {
3071 	    for ( i=0; i<rows; ++i ) if ( i!=row ) {
3072 		if ( strings[3*row+1].u.md_ival == strings[3*i+1].u.md_ival &&
3073 			(strings[3*row].u.md_ival&0xff) == (strings[3*i].u.md_ival&0xff)) {
3074 		    /* Same string, same language, different locale */
3075 		    /* first guess is the same as the other string. */
3076 		    if ( strings[3*i+2].u.md_str==NULL )
3077 			strings[3*row+2].u.md_str = tn_recalculatedef(d,strings[3*row+1].u.md_ival );
3078 		    else
3079 			strings[3*row+2].u.md_str = copy(strings[3*i+2].u.md_str);
3080 		    ret = true;
3081 	    break;
3082 		}
3083 	    }
3084 	    if ( i==rows ) {
3085 	    /* If we didn't find anything above, and if we've got a style */
3086 	    /*  (subfamily) see if we can guess a translation from the english */
3087 		if ( strings[3*row+1].u.md_ival == ttf_subfamily )
3088 		    ret |= CheckActiveStyleTranslation(d,strings,row,rows,false);
3089 		else if ( strings[3*row+1].u.md_ival == ttf_wwssubfamily ) {
3090 		    /* First see if there is a wwssubfamily we can translate */
3091 		    /* then see if there is a subfamily we can copy */
3092 		    ret |= CheckActiveStyleTranslation(d,strings,row,rows,true);
3093 		} else if ( strings[3*row+1].u.md_ival == ttf_wwsfamily ) {
3094 		    /* Copy the normal family */
3095 		    for ( i=rows-1; i>=0; --i )
3096 			if ( strings[3*i+1].u.md_ival==ttf_family &&
3097 				strings[3*i].u.md_ival == strings[3*row].u.md_ival ) {
3098 			    strings[3*row+2].u.md_str = copy(strings[3*i+2].u.md_str);
3099 			    ret = true;
3100 		    break;
3101 			}
3102 		    if ( (i<0 || strings[3*i+2].u.md_str==NULL) &&
3103 			    strings[3*row].u.md_ival == 0x409 ) {
3104 			strings[3*row+2].u.md_str = tn_recalculatedef(d,ttf_family);
3105 			ret = true;
3106 		    }
3107 		}
3108 	    }
3109 	}
3110     }
3111     if ( ret )
3112 	GGadgetRedraw(g);
3113 }
3114 
TN_CanDelete(GGadget * g,int row)3115 static int TN_CanDelete(GGadget *g,int row) {
3116     int rows;
3117     struct matrix_data *strings = GMatrixEditGet(g, &rows);
3118     if ( strings==NULL )
3119 return( false );
3120 
3121 return( !strings[3*row+2].user_bits );
3122 }
3123 
TN_PopupMenu(GGadget * g,GEvent * event,int r,int c)3124 static void TN_PopupMenu(GGadget *g,GEvent *event,int r,int c) {
3125     struct gfi_data *d = (struct gfi_data *) GGadgetGetUserData(g);
3126     int rows;
3127     struct matrix_data *strings = GMatrixEditGet(g, &rows);
3128     GMenuItem mi[5];
3129     int i;
3130 
3131     if ( strings==NULL )
3132 return;
3133 
3134     d->tn_active = r;
3135 
3136     memset(mi,'\0',sizeof(mi));
3137     for ( i=0; i<3; ++i ) {
3138 	mi[i].ti.fg = COLOR_DEFAULT;
3139 	mi[i].ti.bg = COLOR_DEFAULT;
3140 	mi[i].mid = i+1;
3141 	mi[i].invoke = TN_StrPopupDispatch;
3142 	mi[i].ti.text_is_1byte = true;
3143     }
3144     mi[MID_Delete-1].ti.disabled = strings[3*r+2].user_bits;
3145     mi[MID_ToggleBase-1].ti.disabled = !strings[3*r+2].user_bits;
3146     if ( strings[3*r+2].frozen ) {
3147 	mi[MID_MultiEdit-1].ti.disabled = true;
3148 	mi[MID_ToggleBase-1].ti.text = (unichar_t *) _("Detach from PostScript Names");
3149     } else {
3150 	char *temp;
3151 	mi[MID_ToggleBase-1].ti.text = (unichar_t *) _("Same as PostScript Names");
3152 	temp = tn_recalculatedef(d,strings[3*r+1].u.md_ival);
3153 	mi[MID_ToggleBase-1].ti.disabled = (temp==NULL);
3154 	free(temp);
3155     }
3156     if ( c!=2 )
3157 	mi[MID_MultiEdit-1].ti.disabled = true;
3158     mi[MID_MultiEdit-1].ti.text = (unichar_t *) _("Multi-line edit");
3159     mi[MID_Delete-1].ti.text = (unichar_t *) _("Delete");
3160     GMenuCreatePopupMenu(event->w,event, mi);
3161 }
3162 
TN_PassChar(GGadget * g,GEvent * e)3163 static int TN_PassChar(GGadget *g,GEvent *e) {
3164 return( GFI_Char(GGadgetGetUserData(g),e));
3165 }
3166 
TN_BigEditTitle(GGadget * g,int r,int c)3167 static char *TN_BigEditTitle(GGadget *g,int r, int c) {
3168     char buf[100], buf2[20];
3169     const char *lang;
3170     int k;
3171     int rows;
3172     struct matrix_data *strings = GMatrixEditGet(g, &rows);
3173 
3174     lang = langname(strings[3*r].u.md_ival,buf2);
3175     for ( k=0; ttfnameids[k].text!=NULL && ttfnameids[k].userdata!=(void *) (intpt) strings[3*r+1].u.md_ival;
3176 	    ++k );
3177     snprintf(buf,sizeof(buf),_("%1$.30s string for %2$.30s"),
3178 	    lang, (char *) ttfnameids[k].text );
3179 return( copy( buf ));
3180 }
3181 
TNMatrixInit(struct matrixinit * mi,struct gfi_data * d)3182 static void TNMatrixInit(struct matrixinit *mi,struct gfi_data *d) {
3183     SplineFont *sf = d->sf;
3184     int i,j,k,cnt;
3185     uint8 sawEnglishUS[ttf_namemax];
3186     struct ttflangname *tln;
3187     struct matrix_data *md;
3188 
3189     d->langlocalecode = MSLanguageFromLocale();
3190 
3191     memset(mi,0,sizeof(*mi));
3192     mi->col_cnt = 3;
3193     mi->col_init = ci;
3194 
3195     md = NULL;
3196     for ( k=0; k<2; ++k ) {
3197 	memset(sawEnglishUS,0,sizeof(sawEnglishUS));
3198 	cnt = 0;
3199 	for ( tln = sf->names; tln!=NULL; tln = tln->next ) {
3200 	    for ( i=0; i<ttf_namemax; ++i ) if ( i!=ttf_postscriptname && tln->names[i]!=NULL ) {
3201 		if ( md!=NULL ) {
3202 		    md[3*cnt  ].u.md_ival = tln->lang;
3203 		    md[3*cnt+1].u.md_ival = i;
3204 		    md[3*cnt+2].u.md_str = copy(tln->names[i]);
3205 		}
3206 		++cnt;
3207 		if ( tln->lang==0x409 )
3208 		    sawEnglishUS[i] = true;
3209 	    }
3210 	}
3211 	for ( i=0; ttfspecials[i]!=-1; ++i ) if ( !sawEnglishUS[ttfspecials[i]] ) {
3212 	    if ( md!=NULL ) {
3213 		md[3*cnt  ].u.md_ival = 0x409;
3214 		md[3*cnt+1].u.md_ival = ttfspecials[i];
3215 		md[3*cnt+2].u.md_str = NULL;
3216 /* if frozen is set then can't remove or edit. (old basedon bit) */
3217 		md[3*cnt].frozen = md[3*cnt+1].frozen = md[3*cnt+2].frozen = true;
3218 /* if user_bits is set then can't remove. (old cantremove bit) */
3219 		md[3*cnt].user_bits = md[3*cnt+1].user_bits = md[3*cnt+2].user_bits = true;
3220 	    }
3221 	    ++cnt;
3222 	}
3223 	if ( md==NULL )
3224 	    md = calloc(3*(cnt+10),sizeof(struct matrix_data));
3225     }
3226     for ( i=0; i<cnt; ++i ) if ( md[3*cnt].u.md_ival==0x409 ) {
3227 	for ( j=0; ttfspecials[j]!=-1 && ttfspecials[j]!=md[3*cnt+1].u.md_ival; ++j );
3228 	md[3*i].user_bits = md[3*i+1].user_bits = md[3*i+2].user_bits =
3229 		( ttfspecials[j]!=-1 );
3230     }
3231     mi->matrix_data = md;
3232     mi->initial_row_cnt = cnt;
3233 
3234     mi->initrow = TN_NewName;
3235     mi->finishedit = TN_FinishEdit;
3236     mi->candelete = TN_CanDelete;
3237     mi->popupmenu = TN_PopupMenu;
3238     mi->handle_key = TN_PassChar;
3239     mi->bigedittitle = TN_BigEditTitle;
3240 }
3241 
GFI_SortBy(GGadget * g,GEvent * e)3242 static int GFI_SortBy(GGadget *g, GEvent *e) {
3243     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
3244 	struct gfi_data *d = (struct gfi_data *) GDrawGetUserData(GGadgetGetWindow(g));
3245 	TTFNames_Resort(d);
3246 	GGadgetRedraw(GWidgetGetControl(d->gw,CID_TNames));
3247     }
3248 return( true );
3249 }
3250 
GFI_HelpOFL(GGadget * g,GEvent * e)3251 static int GFI_HelpOFL(GGadget *g, GEvent *e) {
3252 /* F1 Help to open a browser to sil.org Open Source License and FAQ */
3253     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
3254 	help("http://scripts.sil.org/OFL", NULL);
3255     }
3256 return( true );
3257 }
3258 
GFI_AddOFL(GGadget * g,GEvent * e)3259 static int GFI_AddOFL(GGadget *g, GEvent *e) {
3260 /* Add sil.org Open Source License (see ofl.c), and modify with current date */
3261 /* Author, and Font Family Name for rows[0,1] of the license. You can access */
3262 /* this routine from GUI at Element->Font_Info->TTF_Names. info at PS_Names. */
3263     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
3264 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
3265 	GGadget *tng = GWidgetGetControl(GGadgetGetWindow(g),CID_TNames);
3266 	int rows;
3267 	struct matrix_data *tns, *newtns;
3268 	int i,j,k,l,m, extras, len;
3269 	char *all, *pt, **data;
3270 	char buffer[1024], *bpt;
3271 	const char *author = GetAuthor();
3272 	char *reservedname, *fallback;
3273 	time_t now;
3274 	struct tm *tm;
3275 
3276 	now = GetTime();
3277 	tm = localtime(&now);
3278 
3279 	tns = GMatrixEditGet(tng, &rows); newtns = NULL;
3280 	for ( k=0; k<2; ++k ) {
3281 	    extras = 0;
3282 	    for ( i=0; ofl_str_lang_data[i].data!=NULL; ++i ) {
3283 		for ( j=rows-1; j>=0; --j ) {
3284 		    if ( tns[j*3+1].u.md_ival==ofl_str_lang_data[i].strid &&
3285 			    tns[j*3+0].u.md_ival==ofl_str_lang_data[i].lang ) {
3286 			if ( k ) {
3287 			    free(newtns[j*3+2].u.md_str);
3288 			    newtns[j*3+2].u.md_str = NULL;
3289 			}
3290 		break;
3291 		    }
3292 		}
3293 		if ( j<0 )
3294 		    j = rows + extras++;
3295 		if ( k ) {
3296 		    newtns[j*3+1].u.md_ival = ofl_str_lang_data[i].strid;
3297 		    newtns[j*3+0].u.md_ival = ofl_str_lang_data[i].lang;
3298 		    data = ofl_str_lang_data[i].data;
3299 		    reservedname = fallback = NULL;
3300 		    for ( m=0; m<rows; ++m ) {
3301 			if ( newtns[j*3+1].u.md_ival==ttf_family ) {
3302 			    if ( newtns[j*3+0].u.md_ival==0x409 )
3303 				fallback = newtns[3*j+2].u.md_str;
3304 			    else if ( newtns[j*3+0].u.md_ival==ofl_str_lang_data[i].lang )
3305 				reservedname = newtns[3*j+2].u.md_str;
3306 			}
3307 		    }
3308 		    if ( reservedname==NULL )
3309 			reservedname = fallback;
3310 		    if ( reservedname==NULL )
3311 			reservedname = d->sf->familyname;
3312 		    for ( m=0; m<2; ++m ) {
3313 			len = 0;
3314 			for ( l=0; data[l]!=NULL; ++l ) {
3315 			    if ( l==0 ) {
3316 				sprintf( buffer, data[l], tm->tm_year+1900, author );
3317 			        bpt = buffer;
3318 			    } else if ( l==1 ) {
3319 				sprintf( buffer, data[l], reservedname );
3320 			        bpt = buffer;
3321 			    } else
3322 				bpt = data[l];
3323 			    if ( m ) {
3324 				strcpy( pt, bpt );
3325 			        pt += strlen( bpt );
3326 			        *pt++ = '\n';
3327 			    } else
3328 				len += strlen( bpt ) + 1;		/* for a new line */
3329 			}
3330 			if ( !m )
3331 			    newtns[j*3+2].u.md_str = all = pt = malloc(len+2);
3332 		    }
3333 		    if ( pt>all ) pt[-1] = '\0';
3334 		    else *pt = '\0';
3335 		}
3336 	    }
3337 	    if ( !k ) {
3338 		newtns = calloc((rows+extras)*3,sizeof(struct matrix_data));
3339 		memcpy(newtns,tns,rows*3*sizeof(struct matrix_data));
3340 		for ( i=0; i<rows; ++i )
3341 		    newtns[3*i+2].u.md_str = copy(newtns[3*i+2].u.md_str);
3342 	    }
3343 	}
3344 	GMatrixEditSet(tng, newtns, rows+extras, false);
3345 	ff_post_notice(_("Using the OFL for your open fonts"),_(
3346 	    "The OFL is a community-approved software license designed for libre/open font projects. \n"
3347 	    "Fonts under the OFL can be used, studied, copied, modified, embedded, merged and redistributed while giving authors enough control and artistic integrity. For more details including an FAQ see http://scripts.sil.org/OFL. \n\n"
3348 	    "This font metadata will help users, designers and distribution channels to know who you are, how to contact you and what rights you are granting. \n"
3349         "When releasing modified versions, remember to add your additional notice, including any extra Reserved Font Name(s). \n\n"
3350 	    "Have fun designing open fonts!" ));
3351     }
3352 return( true );
3353 }
3354 
ss_cmp(const void * _md1,const void * _md2)3355 static int ss_cmp(const void *_md1, const void *_md2) {
3356     const struct matrix_data *md1 = _md1, *md2 = _md2;
3357 
3358     char buf1[20], buf2[20];
3359     const char *l1, *l2;
3360 
3361     if ( md1[1].u.md_ival == md2[1].u.md_ival ) {
3362        l1 = langname(md1[0].u.md_ival,buf1);
3363        l2 = langname(md2[0].u.md_ival,buf2);
3364 return( strcoll(l1,l2));
3365     }
3366 return( md1[1].u.md_ival - md2[1].u.md_ival );
3367 }
3368 
SSMatrixInit(struct matrixinit * mi,struct gfi_data * d)3369 static void SSMatrixInit(struct matrixinit *mi,struct gfi_data *d) {
3370     SplineFont *sf = d->sf;
3371     struct matrix_data *md;
3372     struct otffeatname *fn;
3373     struct otfname *on;
3374     int cnt;
3375 
3376     memset(mi,0,sizeof(*mi));
3377     mi->col_cnt = 3;
3378     mi->col_init = ssci;
3379 
3380     for ( cnt=0, fn=sf->feat_names; fn!=NULL; fn=fn->next ) {
3381 	for ( on=fn->names; on!=NULL; on=on->next, ++cnt );
3382     }
3383     md = calloc(3*(cnt+10),sizeof(struct matrix_data));
3384     for ( cnt=0, fn=sf->feat_names; fn!=NULL; fn=fn->next ) {
3385 	for ( on=fn->names; on!=NULL; on=on->next, ++cnt ) {
3386 	    md[3*cnt  ].u.md_ival = on->lang;
3387 	    md[3*cnt+1].u.md_ival = fn->tag;
3388 	    md[3*cnt+2].u.md_str = copy(on->name);
3389 	}
3390     }
3391     qsort( md, cnt, 3*sizeof(struct matrix_data), ss_cmp );
3392     mi->matrix_data = md;
3393     mi->initial_row_cnt = cnt;
3394 }
3395 
size_cmp(const void * _md1,const void * _md2)3396 static int size_cmp(const void *_md1, const void *_md2) {
3397     const struct matrix_data *md1 = _md1, *md2 = _md2;
3398 
3399     char buf1[20], buf2[20];
3400     const char *l1, *l2;
3401 
3402    l1 = langname(md1[0].u.md_ival,buf1);
3403    l2 = langname(md2[0].u.md_ival,buf2);
3404 return( strcoll(l1,l2));
3405 }
3406 
SizeMatrixInit(struct matrixinit * mi,struct gfi_data * d)3407 static void SizeMatrixInit(struct matrixinit *mi,struct gfi_data *d) {
3408     SplineFont *sf = d->sf;
3409     struct matrix_data *md;
3410     struct otfname *on;
3411     int cnt;
3412 
3413     memset(mi,0,sizeof(*mi));
3414     mi->col_cnt = 2;
3415     mi->col_init = sizeci;
3416 
3417     for ( cnt=0, on=sf->fontstyle_name; on!=NULL; on=on->next )
3418 	++cnt;
3419     md = calloc(2*(cnt+10),sizeof(struct matrix_data));
3420     for ( cnt=0, on=sf->fontstyle_name; on!=NULL; on=on->next, ++cnt ) {
3421 	md[2*cnt  ].u.md_ival = on->lang;
3422 	md[2*cnt+1].u.md_str = copy(on->name);
3423     }
3424     qsort( md, cnt, 2*sizeof(struct matrix_data), size_cmp );
3425     mi->matrix_data = md;
3426     mi->initial_row_cnt = cnt;
3427 }
3428 
Gasp_Default(GGadget * g,GEvent * e)3429 static int Gasp_Default(GGadget *g, GEvent *e) {
3430     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
3431 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
3432 	GGadget *gg = GWidgetGetControl(GGadgetGetWindow(g),CID_Gasp);
3433 	int rows;
3434 	struct matrix_data *gasp;
3435 
3436 	if ( !SFHasInstructions(d->sf)) {
3437 	    rows = 1;
3438 	    gasp = calloc(rows*5,sizeof(struct matrix_data));
3439 	    gasp[0].u.md_ival = 65535;
3440 	    gasp[1].u.md_ival = 0;	/* no grid fit (we have no instructions, we can't grid fit) */
3441 	    gasp[2].u.md_ival = 1;	/* do anti-alias */
3442 	    gasp[3].u.md_ival = 0;	/* do symmetric smoothing */
3443 	    gasp[4].u.md_ival = 0;	/* do no grid fit w/ sym smooth */
3444 	} else {
3445 	    rows = 3;
3446 	    gasp = calloc(rows*5,sizeof(struct matrix_data));
3447 	    gasp[0].u.md_ival = 8;     gasp[1].u.md_ival = 0; gasp[2].u.md_ival = 1;
3448 		    gasp[3].u.md_ival = 0; gasp[4].u.md_ival = 0;
3449 	    gasp[5].u.md_ival = 16;    gasp[6].u.md_ival = 1; gasp[7].u.md_ival = 0;
3450 		    gasp[8].u.md_ival = 0; gasp[9].u.md_ival = 0;
3451 	    gasp[10].u.md_ival = 65535; gasp[11].u.md_ival = 1; gasp[12].u.md_ival = 1;
3452 		    gasp[13].u.md_ival = 0; gasp[14].u.md_ival = 0;
3453 	}
3454 	GMatrixEditSet(gg,gasp,rows,false);
3455     }
3456 return( true );
3457 }
3458 
Gasp_CanDelete(GGadget * g,int row)3459 static int Gasp_CanDelete(GGadget *g,int row) {
3460     int rows;
3461     struct matrix_data *gasp = GMatrixEditGet(g, &rows);
3462     if ( gasp==NULL )
3463 return( false );
3464 
3465     /* Only allow them to delete the sentinal entry if that would give us an */
3466     /* empty gasp table */
3467 return( gasp[5*row].u.md_ival!=0xffff || rows==1 );
3468 }
3469 
gasp_comp(const void * _md1,const void * _md2)3470 static int gasp_comp(const void *_md1, const void *_md2) {
3471     const struct matrix_data *md1 = _md1, *md2 = _md2;
3472 return( md1->u.md_ival - md2->u.md_ival );
3473 }
3474 
Gasp_FinishEdit(GGadget * g,int row,int col,int wasnew)3475 static void Gasp_FinishEdit(GGadget *g,int row,int col,int wasnew) {
3476     int rows;
3477     struct matrix_data *gasp = GMatrixEditGet(g, &rows);
3478 
3479     if ( col==0 ) {
3480 	qsort(gasp,rows,5*sizeof(struct matrix_data),gasp_comp);
3481 	GGadgetRedraw(g);
3482     }
3483 }
3484 
GaspMatrixInit(struct matrixinit * mi,struct gfi_data * d)3485 static void GaspMatrixInit(struct matrixinit *mi,struct gfi_data *d) {
3486     SplineFont *sf = d->sf;
3487     int i;
3488     struct matrix_data *md;
3489 
3490     memset(mi,0,sizeof(*mi));
3491     mi->col_cnt = 5;
3492     mi->col_init = gaspci;
3493 
3494     if ( sf->gasp_cnt==0 ) {
3495 	md = calloc(5,sizeof(struct matrix_data));
3496 	mi->initial_row_cnt = 0;
3497     } else {
3498 	md = calloc(5*sf->gasp_cnt,sizeof(struct matrix_data));
3499 	for ( i=0; i<sf->gasp_cnt; ++i ) {
3500 	    md[5*i  ].u.md_ival = sf->gasp[i].ppem;
3501 	    md[5*i+1].u.md_ival = (sf->gasp[i].flags&1)?1:0;
3502 	    md[5*i+2].u.md_ival = (sf->gasp[i].flags&2)?1:0;
3503 	    md[5*i+3].u.md_ival = (sf->gasp[i].flags&8)?1:0;
3504 	    md[5*i+4].u.md_ival = (sf->gasp[i].flags&4)?1:0;
3505 	}
3506 	mi->initial_row_cnt = sf->gasp_cnt;
3507     }
3508     mi->matrix_data = md;
3509 
3510     mi->finishedit = Gasp_FinishEdit;
3511     mi->candelete = Gasp_CanDelete;
3512     mi->handle_key = TN_PassChar;
3513 }
3514 
GFI_GaspVersion(GGadget * g,GEvent * e)3515 static int GFI_GaspVersion(GGadget *g, GEvent *e) {
3516     if ( e->u.control.subtype == et_listselected ) {
3517 	int version = GGadgetGetFirstListSelectedItem(g);
3518 	GGadget *gasp = GWidgetGetControl(GGadgetGetWindow(g),CID_Gasp);
3519 	if ( version == 0 ) {
3520 	    GMatrixEditShowColumn(gasp,3,false);
3521 	    GMatrixEditShowColumn(gasp,4,false);
3522 	} else {
3523 	    GMatrixEditShowColumn(gasp,3,true);
3524 	    GMatrixEditShowColumn(gasp,4,true);
3525 	}
3526 	GGadgetRedraw(gasp);
3527     }
3528 return( true );
3529 }
3530 
Layers_BackgroundEnable(GGadget * g,GMenuItem * mi,int r,int c)3531 static void Layers_BackgroundEnable(GGadget *g,GMenuItem *mi, int r, int c) {
3532     int disable = r<=ly_fore;
3533     mi[0].ti.disabled = disable;
3534     mi[1].ti.disabled = disable;
3535 }
3536 
Layers_CanDelete(GGadget * g,int row)3537 static int Layers_CanDelete(GGadget *g,int row) {
3538 return( row>ly_fore );
3539 }
3540 
Layers_InitRow(GGadget * g,int row)3541 static void Layers_InitRow(GGadget *g,int row) {
3542     int rows, cols = GMatrixEditGetColCnt(g);
3543     struct matrix_data *layers = GMatrixEditGet(g, &rows);
3544     int isquadratic = GGadgetIsChecked(GWidgetGetControl(GGadgetGetWindow(g),CID_IsOrder2));
3545 
3546     layers[row*cols+1].u.md_ival = isquadratic;
3547 }
3548 
LayersMatrixInit(struct matrixinit * mi,struct gfi_data * d)3549 static void LayersMatrixInit(struct matrixinit *mi,struct gfi_data *d) {
3550     SplineFont *sf = d->sf;
3551     int i,j;
3552     struct matrix_data *md;
3553 
3554     memset(mi,0,sizeof(*mi));
3555     mi->col_cnt = 4;
3556     mi->col_init = layersci;
3557 
3558     md = calloc(4*(sf->layer_cnt+1),sizeof(struct matrix_data));
3559     for ( i=j=0; i<sf->layer_cnt; ++i ) {
3560 	md[4*j  ].u.md_str  = copy(sf->layers[i].name);
3561 	md[4*j+1].u.md_ival = sf->layers[i].order2;
3562 	md[4*j+2].u.md_ival = sf->layers[i].background;
3563 	md[4*j+3].u.md_ival = i+1;
3564 	++j;
3565     }
3566     mi->initial_row_cnt = sf->layer_cnt;
3567     mi->matrix_data = md;
3568 
3569     mi->initrow   = Layers_InitRow;
3570     mi->candelete = Layers_CanDelete;
3571 }
3572 
GFI_Type3Change(GGadget * g,GEvent * e)3573 static int GFI_Type3Change(GGadget *g, GEvent *e) {
3574     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
3575 	GWindow gw = GGadgetGetWindow(g);
3576 	int type3 = GGadgetIsChecked(GWidgetGetControl(gw,CID_IsMultiLayer));
3577 	int mixed = GGadgetIsChecked(GWidgetGetControl(gw,CID_IsMixed));
3578 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_IsMixed), !type3);
3579 	if ( type3 )
3580 	    GGadgetSetChecked(GWidgetGetControl(gw,CID_IsMixed), false );
3581 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_IsOrder2), !type3);
3582 	if ( type3 )
3583 	    GGadgetSetChecked(GWidgetGetControl(gw,CID_IsOrder2), false );
3584 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_IsOrder3), !type3);
3585 	if ( type3 )
3586 	    GGadgetSetChecked(GWidgetGetControl(gw,CID_IsOrder3), true );
3587 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_GuideOrder2), !type3 && mixed);
3588 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_Backgrounds), !type3);
3589     }
3590 return( true );
3591 }
3592 
GFI_OrderChange(GGadget * g,GEvent * e)3593 static int GFI_OrderChange(GGadget *g, GEvent *e) {
3594     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
3595 	GWindow gw = GGadgetGetWindow(g);
3596 	GGadget *backs = GWidgetGetControl(gw,CID_Backgrounds);
3597 	int mixed = GGadgetIsChecked(GWidgetGetControl(gw,CID_IsMixed));
3598 	int cubic = GGadgetIsChecked(GWidgetGetControl(gw,CID_IsOrder3));
3599 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_IsMultiLayer), cubic);
3600 	GGadgetSetEnabled(GWidgetGetControl(gw,CID_GuideOrder2), mixed);
3601 	if ( !mixed ) {
3602 	    GGadgetSetChecked(GWidgetGetControl(gw,CID_GuideOrder2), !cubic );
3603 	}
3604 	GGadgetSetEnabled(backs, true);
3605 	GMatrixEditEnableColumn(backs, 1, mixed);
3606 	if ( !mixed ) {
3607 	    int col = GMatrixEditGetColCnt(backs), rows, i;
3608 	    struct matrix_data *md = GMatrixEditGet(backs, &rows);
3609 	    for ( i=0; i<rows; ++i )
3610 		md[i*col+1].u.md_ival = !cubic;
3611 	}
3612 	GGadgetRedraw(backs);
3613     }
3614 return( true );
3615 }
3616 
BDFsSetAsDs(SplineFont * sf)3617 static void BDFsSetAsDs(SplineFont *sf) {
3618     BDFFont *bdf;
3619     real scale;
3620 
3621     for ( bdf=sf->bitmaps; bdf!=NULL; bdf=bdf->next ) {
3622 	scale = bdf->pixelsize / (real) (sf->ascent+sf->descent);
3623 	bdf->ascent = rint(sf->ascent*scale);
3624 	bdf->descent = bdf->pixelsize-bdf->ascent;
3625     }
3626 }
3627 
3628 static char *texparams[] = { N_("Slant:"), N_("Space:"), N_("Stretch:"),
3629 	N_("Shrink:"), N_("XHeight:"), N_("Quad:"),
3630 /* GT: Extra Space, see below for a full comment */
3631 	N_("Extra Sp:"), NULL };
3632 static char *texpopups[] = { N_("In an italic font the horizontal change per unit vertical change"),
3633     N_("The amount of space between words when using this font"),
3634     N_("The amount of stretchable space between words when using this font"),
3635     N_("The amount the space between words may shrink when using this font"),
3636     N_("The height of the lower case letters with flat tops"),
3637     N_("The width of one em"),
3638     N_("Either:\nThe amount of extra space to be added after a sentence\nOr the space to be used within math formulae"),
3639     NULL};
3640 
ParseTeX(struct gfi_data * d)3641 static int ParseTeX(struct gfi_data *d) {
3642     int i, err=false;
3643     double em = (d->sf->ascent+d->sf->descent), val;
3644 
3645     for ( i=0; texparams[i]!=0 ; ++i ) {
3646 	val = GetReal8(d->gw,CID_TeX+i,texparams[i],&err);
3647 	d->texdata.params[i] = rint( val/em * (1<<20) );
3648     }
3649     if ( GGadgetIsChecked(GWidgetGetControl(d->gw,CID_TeXText)) )
3650 	d->texdata.type = tex_text;
3651     else if ( GGadgetIsChecked(GWidgetGetControl(d->gw,CID_TeXMathSym)) )
3652 	d->texdata.type = tex_math;
3653     else
3654 	d->texdata.type = tex_mathext;
3655 return( !err );
3656 }
3657 
ttfmultuniqueids(SplineFont * sf,struct gfi_data * d)3658 static int ttfmultuniqueids(SplineFont *sf,struct gfi_data *d) {
3659     struct ttflangname *tln;
3660     int found = false;
3661     int i;
3662 
3663     if ( d->names_set ) {
3664 	GGadget *edit = GWidgetGetControl(d->gw,CID_TNames);
3665 	int rows;
3666 	struct matrix_data *strings = GMatrixEditGet(edit, &rows);
3667 	for ( i=0; i<rows; ++i )
3668 	    if ( strings[3*i+1].u.md_ival==ttf_uniqueid ) {
3669 		if ( found )
3670 return( true );
3671 		found = true;
3672 	    }
3673     } else {
3674 	for ( tln = sf->names; tln!=NULL; tln=tln->next )
3675 	    if ( tln->names[ttf_uniqueid]!=NULL ) {
3676 		if ( found )
3677 return( true );
3678 		found = true;
3679 	    }
3680     }
3681 return( false );
3682 }
3683 
ttfuniqueidmatch(SplineFont * sf,struct gfi_data * d)3684 static int ttfuniqueidmatch(SplineFont *sf,struct gfi_data *d) {
3685     struct ttflangname *tln;
3686     int i;
3687 
3688     if ( sf->names==NULL )
3689 return( false );
3690 
3691     if ( !d->names_set ) {
3692 	for ( tln = sf->names; tln!=NULL; tln=tln->next )
3693 	    if ( tln->names[ttf_uniqueid]!=NULL )
3694 return( true );
3695     } else {
3696 	GGadget *edit = GWidgetGetControl(d->gw,CID_TNames);
3697 	int rows;
3698 	struct matrix_data *strings = GMatrixEditGet(edit, &rows);
3699 
3700 	for ( tln = sf->names; tln!=NULL; tln=tln->next ) {
3701 	    if ( tln->names[ttf_uniqueid]==NULL )
3702 	continue;		/* Not set, so if it has been given a new value */
3703 				/*  that's a change, and if it hasn't that's ok */
3704 	    for ( i=0; i<rows; ++i )
3705 		if ( strings[3*i+1].u.md_ival==ttf_uniqueid && strings[3*i].u.md_ival==tln->lang )
3706 	    break;
3707 	    if ( i==rows )
3708 	continue;		/* removed. That's a change */
3709 	    if ( strcmp(tln->names[ttf_uniqueid],strings[3*i+2].u.md_str )==0 )
3710 return( true );		/* name unchanged */
3711 	}
3712     }
3713 return( false );
3714 }
3715 
ttfuniqueidfixup(SplineFont * sf,struct gfi_data * d)3716 static void ttfuniqueidfixup(SplineFont *sf,struct gfi_data *d) {
3717     struct ttflangname *tln;
3718     char *changed = NULL;
3719     int i;
3720 
3721     if ( sf->names==NULL )
3722 return;
3723 
3724     if ( !d->names_set ) {
3725 	for ( tln = sf->names; tln!=NULL; tln=tln->next ) {
3726 	    free( tln->names[ttf_uniqueid]);
3727 	    tln->names[ttf_uniqueid] = NULL;
3728 	}
3729     } else {
3730 	GGadget *edit = GWidgetGetControl(d->gw,CID_TNames);
3731 	int rows;
3732 	struct matrix_data *strings = GMatrixEditGet(edit, &rows);
3733 
3734 	/* see if any instances of the name have changed */
3735 	for ( tln = sf->names; tln!=NULL; tln=tln->next ) {
3736 	    if ( tln->names[ttf_uniqueid]==NULL )
3737 	continue;
3738 	    for ( i=0; i<rows; ++i )
3739 		if ( strings[3*i+1].u.md_ival==ttf_uniqueid && strings[3*i].u.md_ival==tln->lang )
3740 	    break;
3741 	    if ( i==rows )
3742 	continue;
3743 	    if ( strcmp(tln->names[ttf_uniqueid],strings[3*i+2].u.md_str )!=0 )
3744 		changed = copy(strings[3*i+2].u.md_str );
3745 	break;
3746 	}
3747 	/* All unique ids should be the same, if any changed set the unchanged */
3748 	/*  ones to the one that did (or the first of many if several changed) */
3749 	for ( tln = sf->names; tln!=NULL; tln=tln->next ) {
3750 	    if ( tln->names[ttf_uniqueid]==NULL )
3751 	continue;
3752 	    for ( i=0; i<rows; ++i )
3753 		if ( strings[3*i+1].u.md_ival==ttf_uniqueid && strings[3*i].u.md_ival==tln->lang )
3754 	    break;
3755 	    if ( i==rows )
3756 	continue;
3757 	    if ( strcmp(tln->names[ttf_uniqueid],strings[3*i+2].u.md_str)==0 ) {
3758 		free(strings[3*i+2].u.md_str);
3759 		strings[3*i+2].u.md_str = changed!=NULL
3760 			? copy( changed )
3761 			: NULL;
3762 	    }
3763 	}
3764     }
3765 }
3766 
StoreTTFNames(struct gfi_data * d)3767 static void StoreTTFNames(struct gfi_data *d) {
3768     struct ttflangname *tln;
3769     SplineFont *sf = d->sf;
3770     int i;
3771     GGadget *edit = GWidgetGetControl(d->gw,CID_TNames);
3772     int rows;
3773     struct matrix_data *strings = GMatrixEditGet(edit, &rows);
3774 
3775     TTFLangNamesFree(sf->names); sf->names = NULL;
3776 
3777     for ( i=0; i<rows; ++i ) {
3778 	for ( tln=sf->names; tln!=NULL && tln->lang!=strings[3*i].u.md_ival; tln=tln->next );
3779 	if ( tln==NULL ) {
3780 	    tln = chunkalloc(sizeof(struct ttflangname));
3781 	    tln->lang = strings[3*i].u.md_ival;
3782 	    tln->next = sf->names;
3783 	    sf->names = tln;
3784 	}
3785 	tln->names[strings[3*i+1].u.md_ival] = copy(strings[3*i+2].u.md_str );
3786     }
3787 
3788     TTF_PSDupsDefault(sf);
3789 }
3790 
SSNameValidate(struct gfi_data * d)3791 static int SSNameValidate(struct gfi_data *d) {
3792     GGadget *edit = GWidgetGetControl(d->gw,CID_SSNames);
3793     int rows;
3794     struct matrix_data *strings = GMatrixEditGet(edit, &rows);
3795     int i, j, k;
3796 
3797     for ( i=0; i<rows; ++i ) {
3798 	if ( strings[3*i+2].u.md_str == NULL )
3799     continue;
3800 	for ( j=i+1; j<rows; ++j ) {
3801 	    if ( strings[3*j+2].u.md_str == NULL )
3802 	continue;
3803 	    if ( strings[3*i  ].u.md_ival == strings[3*j  ].u.md_ival &&
3804 		    strings[3*i+1].u.md_ival == strings[3*j+1].u.md_ival ) {
3805 		uint32 tag = strings[3*i+1].u.md_ival;
3806 		for ( k=0; mslanguages[k].text!=NULL &&
3807 			((intpt) mslanguages[k].userdata)!=strings[3*i].u.md_ival; ++k );
3808 		if ( mslanguages[k].text==NULL ) k=0;
3809 		ff_post_error(_("Duplicate StyleSet Name"),_("The feature '%c%c%c%c' is named twice in language %s\n%.80s\n%.80s"),
3810 			tag>>24, tag>>16, tag>>8, tag,
3811 			mslanguages[k].text,
3812 			strings[3*i+2].u.md_str,
3813 			strings[3*j+2].u.md_str
3814 			);
3815 return( false );
3816 	    }
3817 	}
3818     }
3819 return( true );
3820 }
3821 
StoreSSNames(struct gfi_data * d)3822 static void StoreSSNames(struct gfi_data *d) {
3823     GGadget *edit = GWidgetGetControl(d->gw,CID_SSNames);
3824     int rows;
3825     struct matrix_data *strings = GMatrixEditGet(edit, &rows);
3826     int i;
3827     uint32 tag, lang;
3828     struct otffeatname *fn;
3829     struct otfname *on;
3830     SplineFont *sf = d->sf;
3831 
3832     OtfFeatNameListFree(sf->feat_names);
3833     sf->feat_names = NULL;
3834 
3835     qsort( strings, rows, 3*sizeof(struct matrix_data), ss_cmp );
3836     for ( i=rows-1; i>=0; --i ) {
3837 	if ( strings[3*i+2].u.md_str == NULL )
3838     continue;
3839 	tag = strings[3*i+1].u.md_ival;
3840 	lang = strings[3*i].u.md_ival;
3841 	for ( fn=sf->feat_names; fn!=NULL && fn->tag!=tag; fn=fn->next );
3842 	if ( fn==NULL ) {
3843 	    fn = chunkalloc(sizeof(*fn));
3844 	    fn->tag = tag;
3845 	    fn->next = sf->feat_names;
3846 	    sf->feat_names = fn;
3847 	}
3848 	on = chunkalloc(sizeof(*on));
3849 	on->next = fn->names;
3850 	fn->names = on;
3851 	on->lang = lang;
3852 	on->name = copy(strings[3*i+2].u.md_str );
3853     }
3854 }
3855 
GFI_ApplyLookupChanges(struct gfi_data * gfi)3856 static void GFI_ApplyLookupChanges(struct gfi_data *gfi) {
3857     int i,j, isgpos;
3858     OTLookup *last;
3859     SplineFont *sf = gfi->sf;
3860     struct lookup_subtable *sublast;
3861 
3862     for ( isgpos=0; isgpos<2; ++isgpos ) {
3863 	struct lkdata *lk = &gfi->tables[isgpos];
3864 	for ( i=0; i<lk->cnt; ++i ) {
3865 	    if ( lk->all[i].deleted )
3866 		SFRemoveLookup(gfi->sf,lk->all[i].lookup,0);
3867 	    else for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
3868 		if ( lk->all[i].subtables[j].deleted )
3869 		    SFRemoveLookupSubTable(gfi->sf,lk->all[i].subtables[j].subtable,0);
3870 	    }
3871 	}
3872 	last = NULL;
3873 	for ( i=0; i<lk->cnt; ++i ) {
3874 	    if ( !lk->all[i].deleted ) {
3875 		if ( last!=NULL )
3876 		    last->next = lk->all[i].lookup;
3877 		else if ( isgpos )
3878 		    sf->gpos_lookups = lk->all[i].lookup;
3879 		else
3880 		    sf->gsub_lookups = lk->all[i].lookup;
3881 		last = lk->all[i].lookup;
3882 		sublast = NULL;
3883 		for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
3884 		    if ( !lk->all[i].subtables[j].deleted ) {
3885 			if ( sublast!=NULL )
3886 			    sublast->next = lk->all[i].subtables[j].subtable;
3887 			else
3888 			    last->subtables = lk->all[i].subtables[j].subtable;
3889 			sublast = lk->all[i].subtables[j].subtable;
3890 			sublast->lookup = last;
3891 		    }
3892 		}
3893 		if ( sublast!=NULL )
3894 		    sublast->next = NULL;
3895 		else
3896 		    last->subtables = NULL;
3897 	    }
3898 	    free(lk->all[i].subtables);
3899 	}
3900 	if ( last!=NULL )
3901 	    last->next = NULL;
3902 	else if ( isgpos )
3903 	    sf->gpos_lookups = NULL;
3904 	else
3905 	    sf->gsub_lookups = NULL;
3906 	free(lk->all);
3907     }
3908 }
3909 
hexparse(GWindow gw,int cid,char * name,uint32 * data,int len,int * err)3910 static void hexparse(GWindow gw, int cid, char *name, uint32 *data, int len, int *err) {
3911     int i;
3912     const unichar_t *ret;
3913     unichar_t *end;
3914 
3915     ret = _GGadgetGetTitle(GWidgetGetControl(gw,cid));
3916     end = (unichar_t *) ret;
3917     for ( i=0; i<len; ++i ) {
3918 	if ( i!=0 ) {
3919 	    if ( *end=='.' )
3920 		++end;
3921 	    else {
3922 		*err = true;
3923 		ff_post_error(_("Bad hex number"), _("Bad hex number in %s"), name);
3924 return;
3925 	    }
3926 	}
3927 	data[len-1-i] = u_strtoul(end,&end,16);
3928     }
3929     if ( *end!='\0' ) {
3930 	*err = true;
3931 	ff_post_error(_("Bad hex number"), _("Bad hex number in %s"), name);
3932 return;
3933     }
3934 }
3935 
GFI_AnyLayersRemoved(struct gfi_data * d)3936 static int GFI_AnyLayersRemoved(struct gfi_data *d) {
3937     GGadget *backs = GWidgetGetControl(d->gw,CID_Backgrounds);
3938     int rows, cols = GMatrixEditGetColCnt(backs), r, origr, l;
3939     struct matrix_data *layers = GMatrixEditGet(backs, &rows);
3940     SplineFont *sf = d->sf;
3941     int anytrue_before, anytrue_after;
3942 
3943     for ( l=0; l<sf->layer_cnt; ++l )
3944 	sf->layers[l].ticked = false;
3945 
3946     anytrue_before = anytrue_after = false;
3947     for ( r=ly_fore; r<sf->layer_cnt; ++r ) {
3948 	if ( sf->layers[r].order2 )
3949 	    anytrue_before = true;
3950     }
3951     for ( r=0; r<rows; ++r ) if ( (origr = layers[r*cols+3].u.md_ival)!=0 ) {
3952 	--origr;
3953 	sf->layers[origr].ticked = true;
3954 	if ( origr>=ly_fore && layers[r*cols+1].u.md_ival )
3955 	    anytrue_after = true;
3956     }
3957 
3958     for ( l=sf->layer_cnt-1; l>ly_fore; --l ) if ( !sf->layers[l].ticked )
3959 return( 1 | (anytrue_before && !anytrue_after? 2 : 0) );
3960 
3961 return( 0 | (anytrue_before && !anytrue_after? 2 : 0) );
3962 }
3963 
GFI_SetLayers(struct gfi_data * d)3964 static int GFI_SetLayers(struct gfi_data *d) {
3965     GGadget *backs = GWidgetGetControl(d->gw,CID_Backgrounds);
3966     int rows, cols = GMatrixEditGetColCnt(backs), r, origr, l;
3967     struct matrix_data *layers = GMatrixEditGet(backs, &rows);
3968     SplineFont *sf = d->sf;
3969     int changed = false;
3970 
3971     for ( l=0; l<sf->layer_cnt; ++l )
3972 	sf->layers[l].ticked = false;
3973 
3974     for ( r=0; r<rows; ++r ) if ( (origr = layers[r*cols+3].u.md_ival)!=0 ) {
3975 	/* It's an old layer. Do we need to change anything? */
3976 	--origr;
3977 	sf->layers[origr].ticked = true;
3978 	if ( sf->layers[origr].order2 != layers[r*cols+1].u.md_ival ) {
3979 	    if ( layers[r*cols+1].u.md_ival )
3980 		SFConvertLayerToOrder2(sf,origr);
3981 	    else
3982 		SFConvertLayerToOrder3(sf,origr);
3983 	    changed = true;
3984 	}
3985 	if ( sf->layers[origr].background != layers[r*cols+2].u.md_ival ) {
3986 	    SFLayerSetBackground(sf,origr,layers[r*cols+2].u.md_ival);
3987 	    changed = true;
3988 	}
3989 	if ( layers[r*cols+0].u.md_str!=NULL && *layers[r*cols+0].u.md_str!='\0' &&
3990 		strcmp( sf->layers[origr].name, layers[r*cols+0].u.md_str)!=0 ) {
3991 	    free( sf->layers[origr].name );
3992 	    sf->layers[origr].name = copy( layers[r*cols+0].u.md_str );
3993 	    changed = true;
3994 	}
3995     }
3996 
3997     for ( l=sf->layer_cnt-1; l>ly_fore; --l ) if ( !sf->layers[l].ticked ) {
3998 	SFRemoveLayer(sf,l);
3999 	changed = true;
4000     }
4001 
4002     l = 0;
4003     for ( r=0; r<rows; ++r ) if ( layers[r*cols+3].u.md_ival==0 ) {
4004 	SFAddLayer(sf,layers[r*cols+0].u.md_str,layers[r*cols+1].u.md_ival, layers[r*cols+2].u.md_ival);
4005 	changed = true;
4006     }
4007     if ( changed )
4008 	CVLayerPaletteCheck(sf);
4009 return( changed );
4010 }
4011 
4012 
DumpSplineFontMetadata(SplineFont * sf)4013 char* DumpSplineFontMetadata(SplineFont *sf) {
4014     FILE *sfd;
4015     if ( (sfd=MakeTemporaryFile()) ) {
4016 	SFD_DumpSplineFontMetadata( sfd, sf );
4017 	char *str = FileToAllocatedString( sfd );
4018 	fclose(sfd);
4019 	return( str );
4020     }
4021     return( 0 );
4022 }
4023 
GFI_OK(GGadget * g,GEvent * e)4024 static int GFI_OK(GGadget *g, GEvent *e) {
4025     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate )
4026     {
4027 	GWindow gw = GGadgetGetWindow(g);
4028 	struct gfi_data *d = GDrawGetUserData(gw);
4029 	SplineFont *sf = d->sf, *_sf;
4030 
4031 //	printf("at top of GFI_OK\n");
4032 
4033 	char* sfdfrag  = DumpSplineFontMetadata( sf );
4034 	SFUndoes* undo = SFUndoCreateSFD( sfut_fontinfo,
4035 					  _("Font Information Dialog"),
4036 					  sfdfrag );
4037 	SFUndoPushFront( &sf->undoes, undo );
4038 
4039 
4040 
4041 	int interp;
4042 	int reformat_fv=0, retitle_fv=false;
4043 	int upos, uwid, as, des, err = false, weight=0;
4044 	int uniqueid, linegap=0, vlinegap=0, winascent=0, windescent=0;
4045 	int tlinegap=0, tascent=0, tdescent=0, hascent=0, hdescent=0;
4046 	int capheight=0, xheight=0;
4047 	int winaoff=true, windoff=true;
4048 	int taoff=true, tdoff=true, haoff = true, hdoff = true;
4049 	real ia, cidversion;
4050 	const unichar_t *txt, *fond; unichar_t *end;
4051 	int i,j, mcs;
4052 	int vmetrics, namechange, guideorder2;
4053 	int xuidchanged = false, usexuid, useuniqueid;
4054 	GTextInfo *pfmfam, *ibmfam, *fstype, *nlitem, *stylemap;
4055 	int32 len;
4056 	GTextInfo **ti;
4057 	int subs[4], super[4], strike[2];
4058 	struct otfname *fontstyle_name;
4059 	int design_size, size_top, size_bottom, styleid;
4060 	int strokedfont = false;
4061 	real strokewidth;
4062 	int multilayer = false;
4063 	char os2_vendor[4];
4064 	NameList *nl;
4065 	extern int allow_utf8_glyphnames;
4066 	int os2version;
4067 	int rows, gasprows, mc_rows, ms_rows;
4068 	struct matrix_data *strings     = GMatrixEditGet(GWidgetGetControl(d->gw,CID_TNames), &rows);
4069 	struct matrix_data *gasp        = GMatrixEditGet(GWidgetGetControl(d->gw,CID_Gasp), &gasprows);
4070 	struct matrix_data *markclasses = GMatrixEditGet(GWidgetGetControl(d->gw,CID_MarkClasses), &mc_rows);
4071 	struct matrix_data *marksets    = GMatrixEditGet(GWidgetGetControl(d->gw,CID_MarkSets), &ms_rows);
4072 	int was_ml = sf->multilayer, was_stroke = sf->strokedfont;
4073 	uint32 codepages[2], uranges[4];
4074 	int layer_cnt;
4075 	struct matrix_data *layers = GMatrixEditGet(GWidgetGetControl(d->gw,CID_Backgrounds), &layer_cnt);
4076 	int layer_flags;
4077 	int sfntRevision=sfntRevisionUnset, woffMajor=woffUnset, woffMinor=woffUnset;
4078 
4079 	if ( strings==NULL || gasp==NULL || layers==NULL )
4080 return( true );
4081 	if ( gasprows>0 && gasp[5*gasprows-5].u.md_ival!=65535 ) {
4082 	    ff_post_error(_("Bad Grid Fitting table"),_("The 'gasp' (Grid Fit) table must end with a pixel entry of 65535"));
4083 return( true );
4084 	}
4085 	{
4086 	    int i;
4087 	    static struct {
4088 		int cid;
4089 		char *tit, *msg;
4090 	    } msgs[] = {
4091 		{ CID_Notice, N_("Bad Copyright"), NU_("Copyright text (in the Names pane) must be entirely ASCII. So, use (c) instead of ©.")},
4092 		{ CID_Human, N_("Bad Human Fontname"), N_("The human-readable fontname text (in the Names pane) must be entirely ASCII.")},
4093 		{ CID_Weight, N_("Bad Weight"), N_("The weight text (in the Names pane) must be entirely ASCII.")},
4094 		{ CID_Version, N_("Bad Version"), N_("The version text (in the Names pane) must be entirely ASCII.")},
4095 		{ 0, NULL, NULL }
4096 	    };
4097 	    for ( i = 0; msgs[i].cid!=0 ; ++i )
4098 		    if ( !uAllAscii(_GGadgetGetTitle(GWidgetGetControl(d->gw,msgs[i].cid))) ) {
4099 		ff_post_error(_(msgs[i].tit),_(msgs[i].msg));
4100 return( true );
4101 	    }
4102 	}
4103 	if ( (layer_flags = GFI_AnyLayersRemoved(d))!=0 ) {
4104 	    char *buts[3];
4105 	    buts[0] = _("_OK"); buts[1] = _("_Cancel"); buts[2]=NULL;
4106 	    if ( layer_flags & 1 ) {
4107 		if ( gwwv_ask(_("Deleting a layer cannot be UNDONE!"),(const char **) buts,0,1,_(
4108 			"You are about to delete a layer.\n"
4109 			"This will lose all contours in that layer.\n"
4110 			"If this is the last quadratic layer it will\n"
4111 			"lose all truetype instructions.\n\n"
4112 			"Deleting a layer cannot be undone.\n\n"
4113 			"Is this really your intent?"))==1 )
4114 return( true );
4115 	    } else if ( layer_flags & 2 ) {
4116 		if ( gwwv_ask(_("Removing instructions cannot be UNDONE!"),(const char **) buts,0,1,_(
4117 			"You are about to change the last quadratic\n"
4118 			"layer to cubic. When this happens FontForge\n"
4119 			"will remove all truetype instructions.\n\n"
4120 			"This cannot be undone.\n\n"
4121 			"Is this really your intent?"))==1 )
4122 return( true );
4123 	    }
4124 	}
4125 	if ( layer_cnt>=BACK_LAYER_MAX-2 ) {
4126 	    ff_post_error(_("Too many layers"),_("FontForge supports at most %d layers"),BACK_LAYER_MAX-2);
4127 return( true );
4128 	}
4129 	if ( !CheckNames(d))
4130 return( true );
4131 
4132 	if ( ttfmultuniqueids(sf,d)) {
4133 	    char *buts[3];
4134 	    buts[0] = _("_OK"); buts[1] = _("_Cancel"); buts[2]=NULL;
4135 	    if ( gwwv_ask(_("Too many Unique Font IDs"),(const char **) buts,0,1,_("You should only specify the TrueType Unique Font Identification string in one language. This font has more. Do you want to continue anyway?"))==1 )
4136 return( true );
4137 	}
4138 	txt = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Family));
4139 	if ( !isalpha(*txt)) {
4140 	    BadFamily();
4141 return( true );
4142 	}
4143 	txt = _GGadgetGetTitle(GWidgetGetControl(gw,CID_ItalicAngle));
4144 	ia = u_strtod(txt,&end);
4145 	if ( *end!='\0' ) {
4146 	    GGadgetProtest8(_("_Italic Angle:"));
4147 return(true);
4148 	}
4149 	guideorder2 = GGadgetIsChecked(GWidgetGetControl(gw,CID_GuideOrder2));
4150 	strokedfont = GGadgetIsChecked(GWidgetGetControl(gw,CID_IsStrokedFont));
4151 	strokewidth = GetReal8(gw,CID_StrokeWidth,_("Stroke _Width:"),&err);
4152 	multilayer = GGadgetIsChecked(GWidgetGetControl(gw,CID_IsMultiLayer));
4153 	vmetrics = GGadgetIsChecked(GWidgetGetControl(gw,CID_HasVerticalMetrics));
4154 	upos = GetReal8(gw,CID_UPos, _("Underline _Position:"),&err);
4155 	uwid = GetReal8(gw,CID_UWidth,S_("Underline|_Height:"),&err);
4156 	GetInt8(gw,CID_Em,_("_Em Size:"),&err);	/* just check for errors. redundant info */
4157 	as = GetInt8(gw,CID_Ascent,_("_Ascent:"),&err);
4158 	des = GetInt8(gw,CID_Descent,_("_Descent:"),&err);
4159 	uniqueid = GetInt8(gw,CID_UniqueID,_("UniqueID"),&err);
4160 	design_size = rint(10*GetReal8(gw,CID_DesignSize,_("De_sign Size:"),&err));
4161 	size_bottom = rint(10*GetReal8(gw,CID_DesignBottom,_("_Bottom"),&err));
4162 	size_top = rint(10*GetReal8(gw,CID_DesignTop,_("_Top"),&err));
4163 	styleid = GetInt8(gw,CID_StyleID,_("Style _ID:"),&err);
4164 	fontstyle_name = OtfNameFromStyleNames(GWidgetGetControl(gw,CID_StyleName));
4165 	OtfNameListFree(fontstyle_name);
4166 	if ( design_size==0 && ( size_bottom!=0 || size_top!=0 || styleid!=0 || fontstyle_name!=NULL )) {
4167 	    ff_post_error(_("Bad Design Size Info"),_("If the design size is 0, then all other fields on that pane must be zero (or unspecified) too."));
4168 return( true );
4169 	} else if ( styleid!=0 && fontstyle_name==NULL ) {
4170 	    ff_post_error(_("Bad Design Size Info"),_("If you specify a style id for the design size, then you must specify a style name"));
4171 return( true );
4172 	} else if ( fontstyle_name!=NULL && styleid==0 ) {
4173 	    ff_post_error(_("Bad Design Size Info"),_("If you specify a style name for the design size, then you must specify a style id"));
4174 return( true );
4175 	} else if ( design_size<0 ) {
4176 	    ff_post_error(_("Bad Design Size Info"),_("If you specify a design size, it must be positive"));
4177 return( true );
4178 	} else if ( size_bottom!=0 && size_bottom>design_size ) {
4179 	    ff_post_error(_("Bad Design Size Info"),_("In the design size range, the bottom field must be less than the design size."));
4180 return( true );
4181 	} else if ( size_top!=0 && size_top<design_size ) {
4182 	    ff_post_error(_("Bad Design Size Info"),_("In the design size range, the bottom top must be more than the design size."));
4183 return( true );
4184 	} else if ( styleid!=0 && size_top==0 ) {
4185 	    ff_post_error(_("Bad Design Size Info"),_("If you specify a style id for the design size, then you must specify a size range"));
4186 return( true );
4187 	} else if ( size_top!=0 && styleid==0 ) {
4188 	    ff_post_notice(_("Bad Design Size Info"),_("If you specify a design size range, then you are supposed to specify a style id and style name too. FontForge will allow you to leave those fields blank, but other applications may not."));
4189 	    /* no return, this is just a warning */
4190 	}
4191 
4192 	if ( *_GGadgetGetTitle(GWidgetGetControl(gw,CID_Revision))!='\0' )
4193 	    sfntRevision = rint(65536.*GetReal8(gw,CID_Revision,_("sfnt Revision:"),&err));
4194 	if ( *_GGadgetGetTitle(GWidgetGetControl(gw,CID_WoffMajor))!='\0' ) {
4195 	    woffMajor = GetInt8(gw,CID_WoffMajor,_("Woff Major Version:"),&err);
4196 	    woffMinor = 0;
4197 	    if ( *_GGadgetGetTitle(GWidgetGetControl(gw,CID_WoffMinor))!='\0' )
4198 		woffMinor = GetInt8(gw,CID_WoffMinor,_("Woff Minor Version:"),&err);
4199 	}
4200 	if ( err )
4201 return(true);
4202 
4203 	memset(codepages,0,sizeof(codepages));
4204 	memset(uranges,0,sizeof(uranges));
4205 	if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_CPageDefault)) )
4206 	    hexparse(gw,CID_CodePageRanges,_("MS Code Pages"),codepages,2,&err );
4207 	if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_URangesDefault)) )
4208 	    hexparse(gw,CID_UnicodeRanges,_("Unicode Ranges"),uranges,4,&err );
4209 	if ( err )
4210 return( true );
4211 
4212 	if ( sf->subfontcnt!=0 ) {
4213 	    cidversion = GetReal8(gw,CID_Version,_("_Version"),&err);
4214 	    if ( err )
4215 return(true);
4216 	}
4217 	os2version = sf->os2_version;
4218 	if ( d->ttf_set ) {
4219 	    char *os2v = GGadgetGetTitle8(GWidgetGetControl(gw,CID_OS2Version));
4220 	    if ( strcasecmp(os2v,(char *) os2versions[0].text )== 0 )
4221 		os2version = 0;
4222 	    else
4223 		os2version = GetInt8(gw,CID_OS2Version,_("Weight, Width, Slope Only"),&err);
4224 	    free(os2v);
4225 	    /* Only use the normal routine if we get no value, because */
4226 	    /*  "400 Book" is a reasonable setting, but would cause GetInt */
4227 	    /*  to complain */
4228 	    weight = u_strtol(_GGadgetGetTitle(GWidgetGetControl(gw,CID_WeightClass)),NULL,10);
4229 	    if ( weight == 0 ) {
4230 		int i;
4231 		char *wc = GGadgetGetTitle8(GWidgetGetControl(gw,CID_WeightClass));
4232 		for ( i=0; widthclass[i].text!=NULL; ++i ) {
4233 		    if ( strcmp(wc,(char *) widthclass[i].text)==0 ) {
4234 			weight = (intpt) widthclass[i].userdata;
4235 		break;
4236 		    }
4237 		}
4238 		free(wc);
4239 	    }
4240 	    if ( weight == 0 )
4241 		weight = GetInt8(gw,CID_WeightClass,_("_Weight Class"),&err);
4242 	    linegap = GetInt8(gw,CID_LineGap,_("HHead _Line Gap:"),&err);
4243 	    tlinegap = GetInt8(gw,CID_TypoLineGap,_("Typo Line _Gap:"),&err);
4244 	    if ( vmetrics )
4245 		vlinegap = GetInt8(gw,CID_VLineGap,_("VHead _Column Spacing:"),&err);
4246 	    winaoff = GGadgetIsChecked(GWidgetGetControl(gw,CID_WinAscentIsOff));
4247 	    windoff = GGadgetIsChecked(GWidgetGetControl(gw,CID_WinDescentIsOff));
4248 	    winascent  = GetInt8(gw,CID_WinAscent,winaoff ? _("Win _Ascent Offset:") : _("Win Ascent:"),&err);
4249 	    windescent = GetInt8(gw,CID_WinDescent,windoff ? _("Win _Descent Offset:") : _("Win Descent:"),&err);
4250 	    taoff = GGadgetIsChecked(GWidgetGetControl(gw,CID_TypoAscentIsOff));
4251 	    tdoff = GGadgetIsChecked(GWidgetGetControl(gw,CID_TypoDescentIsOff));
4252 	    tascent  = GetInt8(gw,CID_TypoAscent,taoff ? _("_Typo Ascent Offset:") : _("Typo Ascent:"),&err);
4253 	    tdescent = GetInt8(gw,CID_TypoDescent,tdoff ? _("T_ypo Descent Offset:") : _("Typo Descent:"),&err);
4254 	    haoff = GGadgetIsChecked(GWidgetGetControl(gw,CID_HHeadAscentIsOff));
4255 	    hdoff = GGadgetIsChecked(GWidgetGetControl(gw,CID_HHeadDescentIsOff));
4256 	    hascent  = GetInt8(gw,CID_HHeadAscent,haoff ? _("_HHead Ascent Offset:") : _("HHead Ascent:"),&err);
4257 	    hdescent = GetInt8(gw,CID_HHeadDescent,hdoff ? _("HHead De_scent Offset:") : _("HHead Descent:"),&err);
4258 	    capheight = GetInt8(gw,CID_CapHeight, _("Ca_pital Height:"),&err);
4259 	    xheight = GetInt8(gw,CID_XHeight, _("_X Height:"),&err);
4260 	    if ( err )
4261 return(true);
4262 
4263 	    if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_SubSuperDefault)) ) {
4264 		for ( i=0; i<4; ++i )
4265 		    subs[i] = GetInt8(gw,CID_SubXSize+i,_("Subscript"),&err);
4266 		for ( i=0; i<4; ++i )
4267 		    super[i] = GetInt8(gw,CID_SuperXSize+i,_("Superscript"),&err);
4268 		for ( i=0; i<2; ++i )
4269 		    strike[i] = GetInt8(gw,CID_StrikeoutSize+i,_("Strikeout"),&err);
4270 	    }
4271 	    txt = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Vendor));
4272 	    if ( u_strlen(txt)>4 || txt[0]>0x7e || (txt[0]!='\0' && (txt[1]>0x7e ||
4273 		    (txt[1]!='\0' && (txt[2]>0x7e || (txt[2]!='\0' && txt[3]>0x7e))))) ) {
4274 		if ( u_strlen(txt)>4 )
4275 		    ff_post_error(_("Bad IBM Family"),_("Tag must be 4 characters long"));
4276 		else
4277 		    ff_post_error(_("Bad IBM Family"),_("A tag must be 4 ASCII characters"));
4278 return( true );
4279 	    }
4280 	    os2_vendor[0] = txt[0]==0 ? ' ' : txt[0];
4281 	    os2_vendor[1] = txt[0]==0 || txt[1]=='\0' ? ' ' : txt[1];
4282 	    os2_vendor[2] = txt[0]==0 || txt[1]=='\0' || txt[2]=='\0' ? ' ' : txt[2];
4283 	    os2_vendor[3] = txt[0]==0 || txt[1]=='\0' || txt[2]=='\0' || txt[3]=='\0' ? ' ' : txt[3];
4284 	}
4285 	if ( err )
4286 return(true);
4287 	if ( d->tex_set ) {
4288 	    if ( !ParseTeX(d))
4289 return( true );
4290 	}
4291 	if ( as+des>16384 || des<0 || as<0 ) {
4292 	    ff_post_error(_("Bad Ascent/Descent"),_("Ascent and Descent must be positive and their sum less than 16384"));
4293 return( true );
4294 	}
4295 	mcs = -1;
4296 	if ( !GGadgetIsChecked(GWidgetGetControl(d->gw,CID_MacAutomatic)) ) {
4297 	    mcs = 0;
4298 	    ti = GGadgetGetList(GWidgetGetControl(d->gw,CID_MacStyles),&len);
4299 	    for ( i=0; i<len; ++i )
4300 		if ( ti[i]->selected )
4301 		    mcs |= (int) (intpt) ti[i]->userdata;
4302 	    if ( (mcs&sf_condense) && (mcs&sf_extend)) {
4303 		ff_post_error(_("Bad Style"),_("A style may not have both condense and extend set (it makes no sense)"));
4304 return( true );
4305 	    }
4306 	}
4307 
4308 	nlitem = GGadgetGetListItemSelected(GWidgetGetControl(gw,CID_Namelist));
4309 	if ( nlitem==NULL )
4310 	    nl = DefaultNameListForNewFonts();
4311 	else {
4312 	    char *name = u2utf8_copy(nlitem->text);
4313 	    nl = NameListByName(name);
4314 	    free(name);
4315 	}
4316 	if ( nl->uses_unicode && !allow_utf8_glyphnames ) {
4317 	    ff_post_error(_("Namelist contains non-ASCII names"),_("Glyph names should be limited to characters in the ASCII character set,\nbut there are names in this namelist which use characters outside\nthat range."));
4318 return(true);
4319 	}
4320 	if ( !SSNameValidate(d))
4321 return( true );
4322 	if ( strokedfont!=sf->strokedfont || multilayer!=sf->multilayer ) {
4323 	    if ( sf->strokedfont && multilayer )
4324 		SFSetLayerWidthsStroked(sf,sf->strokewidth);
4325 	    else if ( sf->multilayer )
4326 		SFSplinesFromLayers(sf,strokedfont);
4327 	    SFReinstanciateRefs(sf);
4328 	    if ( multilayer!=sf->multilayer ) {
4329 		sf->multilayer = multilayer;
4330 		SFLayerChange(sf);
4331 	    }
4332 	    for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL )
4333 		sf->glyphs[i]->changedsincelasthinted = !strokedfont && !multilayer;
4334 	}
4335 	sf->strokedfont = strokedfont;
4336 	sf->strokewidth = strokewidth;
4337 	GDrawSetCursor(gw,ct_watch);
4338 	namechange = SetFontName(gw,sf);
4339 	if ( namechange ) retitle_fv = true;
4340 	usexuid = GGadgetIsChecked(GWidgetGetControl(gw,CID_UseXUID));
4341 	useuniqueid = GGadgetIsChecked(GWidgetGetControl(gw,CID_UseUniqueID));
4342 	txt = _GGadgetGetTitle(GWidgetGetControl(gw,CID_XUID));
4343 	xuidchanged = (sf->xuid==NULL && *txt!='\0') ||
4344 			(sf->xuid!=NULL && uc_strcmp(txt,sf->xuid)==0);
4345 	if ( namechange &&
4346 		((uniqueid!=0 && uniqueid==sf->uniqueid && useuniqueid) ||
4347 		 (sf->xuid!=NULL && uc_strcmp(txt,sf->xuid)==0 && usexuid) ||
4348 		 ttfuniqueidmatch(sf,d)) ) {
4349 	    char *buts[4];
4350 	    int ans;
4351 	    buts[0] = _("Change");
4352 	    buts[1] = _("Retain");
4353 	    buts[2] = _("_Cancel");
4354 	    buts[3] = NULL;
4355 	    ans = gwwv_ask(_("Change UniqueID?"),(const char **) buts,0,2,_("You have changed this font's name without changing the UniqueID (or XUID).\nThis is probably not a good idea, would you like me to\ngenerate a random new value?"));
4356 	    if ( ans==2 ) {
4357 		GDrawSetCursor(gw,ct_pointer);
4358 return(true);
4359 	    }
4360 	    if ( ans==0 ) {
4361 		if ( uniqueid!=0 && uniqueid==sf->uniqueid )
4362 		    uniqueid = 4000000 + (rand()&0x3ffff);
4363 		if ( sf->xuid!=NULL && uc_strcmp(txt,sf->xuid)==0 ) {
4364 		    SFRandomChangeXUID(sf);
4365 		    xuidchanged = true;
4366 		}
4367 	    }
4368 	    if ( ttfuniqueidmatch(sf,d))
4369 		ttfuniqueidfixup(sf,d);
4370 	} else {
4371 	    free(sf->xuid);
4372 	    sf->xuid = *txt=='\0'?NULL:cu_copy(txt);
4373 	}
4374 	sf->use_xuid = usexuid;
4375 	sf->use_uniqueid = useuniqueid;
4376 
4377 	sf->sfntRevision = sfntRevision;
4378 
4379 	free(sf->woffMetadata);
4380 	sf->woffMetadata = NULL;
4381 	if ( *_GGadgetGetTitle(GWidgetGetControl(gw,CID_WoffMetadata))!='\0' )
4382 	    sf->woffMetadata = GGadgetGetTitle8(GWidgetGetControl(gw,CID_WoffMetadata));
4383 	sf->woffMajor = woffMajor;
4384 	sf->woffMinor = woffMinor;
4385 
4386 	free(sf->gasp);
4387 	sf->gasp_cnt = gasprows;
4388 	if ( gasprows==0 )
4389 	    sf->gasp = NULL;
4390 	else {
4391 	    sf->gasp = malloc(gasprows*sizeof(struct gasp));
4392 	    sf->gasp_version = GGadgetGetFirstListSelectedItem(GWidgetGetControl(gw,CID_GaspVersion));
4393 	    for ( i=0; i<gasprows; ++i ) {
4394 		sf->gasp[i].ppem = gasp[5*i].u.md_ival;
4395 		if ( sf->gasp_version==0 )
4396 		    sf->gasp[i].flags = gasp[5*i+1].u.md_ival |
4397 			    (gasp[5*i+2].u.md_ival<<1);
4398 		else
4399 		    sf->gasp[i].flags = gasp[5*i+1].u.md_ival |
4400 			    (gasp[5*i+2].u.md_ival<<1) |
4401 			    (gasp[5*i+4].u.md_ival<<2) |
4402 			    (gasp[5*i+3].u.md_ival<<3);
4403 	    }
4404 	}
4405 	sf->head_optimized_for_cleartype = GGadgetIsChecked(GWidgetGetControl(gw,CID_HeadClearType));
4406 
4407 	OtfNameListFree(sf->fontstyle_name);
4408 	sf->fontstyle_name = OtfNameFromStyleNames(GWidgetGetControl(gw,CID_StyleName));
4409 	sf->design_size = design_size;
4410 	sf->design_range_bottom = size_bottom;
4411 	sf->design_range_top = size_top;
4412 	sf->fontstyle_id = styleid;
4413 
4414 	txt = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Notice));
4415 	free(sf->copyright); sf->copyright = cu_copy(txt);
4416 	txt = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Comment));
4417 	free(sf->comments); sf->comments = u2utf8_copy(*txt?txt:NULL);
4418 	txt = _GGadgetGetTitle(GWidgetGetControl(gw,CID_FontLog));
4419 	free(sf->fontlog); sf->fontlog = u2utf8_copy(*txt?txt:NULL);
4420 	txt = _GGadgetGetTitle(GWidgetGetControl(gw,CID_DefBaseName));
4421 	if ( *txt=='\0' || GGadgetIsChecked(GWidgetGetControl(gw,CID_SameAsFontname)) )
4422 	    txt = NULL;
4423 	free(sf->defbasefilename); sf->defbasefilename = u2utf8_copy(txt);
4424 	if ( sf->subfontcnt!=0 ) {
4425 	    sf->cidversion = cidversion;
4426 	} else {
4427 	    txt = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Version));
4428 	    free(sf->version); sf->version = cu_copy(txt);
4429 	}
4430 	fond = _GGadgetGetTitle(GWidgetGetControl(gw,CID_MacFOND));
4431 	free(sf->fondname); sf->fondname = NULL;
4432 	if ( *fond )
4433 	    sf->fondname = cu_copy(fond);
4434 	sf->macstyle = mcs;
4435 	sf->italicangle = ia;
4436 	sf->upos = upos;
4437 	sf->uwidth = uwid;
4438 	sf->uniqueid = uniqueid;
4439 	sf->texdata = d->texdata;
4440 	if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_CPageDefault)) ) {
4441 	    memcpy(sf->pfminfo.codepages,codepages,sizeof(codepages));
4442 	    sf->pfminfo.hascodepages = true;
4443 	} else
4444 	    sf->pfminfo.hascodepages = false;
4445 	if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_URangesDefault)) ) {
4446 	    memcpy(sf->pfminfo.unicoderanges,uranges,sizeof(uranges));
4447 	    sf->pfminfo.hasunicoderanges = true;
4448 	} else
4449 	    sf->pfminfo.hasunicoderanges = false;
4450 
4451 	interp = GGadgetGetFirstListSelectedItem(GWidgetGetControl(gw,CID_Interpretation));
4452 	if ( interp==-1 ) sf->uni_interp = ui_none;
4453 	else sf->uni_interp = (intpt) interpretations[interp].userdata;
4454 
4455 	sf->for_new_glyphs = nl;
4456 
4457 	if ( sf->hasvmetrics!=vmetrics )
4458 	    CVPaletteDeactivate();		/* Force a refresh later */
4459 	_sf = sf->cidmaster?sf->cidmaster:sf;
4460 	_sf->hasvmetrics = vmetrics;
4461 	for ( j=0; j<_sf->subfontcnt; ++j )
4462 	    _sf->subfonts[j]->hasvmetrics = vmetrics;
4463 
4464 	PSDictFree(sf->private);
4465 	sf->private = GFI_ParsePrivate(d);
4466 
4467 	if ( d->names_set )
4468 	    StoreTTFNames(d);
4469 	StoreSSNames(d);
4470 	if ( d->ttf_set ) {
4471 	    sf->os2_version = os2version;
4472 	    sf->use_typo_metrics = GGadgetIsChecked(GWidgetGetControl(gw,CID_UseTypoMetrics));
4473 	    sf->weight_width_slope_only = GGadgetIsChecked(GWidgetGetControl(gw,CID_WeightWidthSlopeOnly));
4474 	    sf->pfminfo.weight = weight;
4475 	    sf->pfminfo.width = GGadgetGetFirstListSelectedItem(GWidgetGetControl(gw,CID_WidthClass))+1;
4476 	    pfmfam = GGadgetGetListItemSelected(GWidgetGetControl(gw,CID_PFMFamily));
4477 	    if ( pfmfam!=NULL )
4478 		sf->pfminfo.pfmfamily = (intpt) (pfmfam->userdata);
4479 	    else
4480 		sf->pfminfo.pfmfamily = 0x11;
4481 	    ibmfam = GGadgetGetListItemSelected(GWidgetGetControl(gw,CID_IBMFamily));
4482 	    if ( ibmfam!=NULL )
4483 		sf->pfminfo.os2_family_class = (intpt) (ibmfam->userdata);
4484 	    else
4485 		sf->pfminfo.os2_family_class = 0x00;
4486         stylemap = GGadgetGetListItemSelected(GWidgetGetControl(gw,CID_StyleMap));
4487         if ( stylemap!=NULL )
4488         sf->pfminfo.stylemap = (intpt) (stylemap->userdata);
4489         else
4490         sf->pfminfo.stylemap = -1;
4491 	    memcpy(sf->pfminfo.os2_vendor,os2_vendor,sizeof(os2_vendor));
4492 	    fstype = GGadgetGetListItemSelected(GWidgetGetControl(gw,CID_FSType));
4493 	    if ( fstype!=NULL )
4494 		sf->pfminfo.fstype = (intpt) (fstype->userdata);
4495 	    else
4496 		sf->pfminfo.fstype = 0xc;
4497 	    if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_NoSubsetting)))
4498 		sf->pfminfo.fstype |=0x100;
4499 	    if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_OnlyBitmaps)))
4500 		sf->pfminfo.fstype |=0x200;
4501 	    for ( i=0; i<10; ++i )
4502 		sf->pfminfo.panose[i] = (intpt) (GGadgetGetListItemSelected(GWidgetGetControl(gw,CID_PanFamily+i))->userdata);
4503 	    sf->pfminfo.panose_set = !GGadgetIsChecked(GWidgetGetControl(gw,CID_PanDefault));
4504 	    sf->pfminfo.os2_typolinegap = tlinegap;
4505 	    sf->pfminfo.linegap = linegap;
4506 	    if ( vmetrics )
4507 		sf->pfminfo.vlinegap = vlinegap;
4508 	    sf->pfminfo.os2_winascent = winascent;
4509 	    sf->pfminfo.os2_windescent = windescent;
4510 	    sf->pfminfo.winascent_add = winaoff;
4511 	    sf->pfminfo.windescent_add = windoff;
4512 	    sf->pfminfo.os2_typoascent = tascent;
4513 	    sf->pfminfo.os2_typodescent = tdescent;
4514 	    sf->pfminfo.typoascent_add = taoff;
4515 	    sf->pfminfo.typodescent_add = tdoff;
4516 	    sf->pfminfo.hhead_ascent = hascent;
4517 	    sf->pfminfo.hhead_descent = hdescent;
4518 	    sf->pfminfo.hheadascent_add = haoff;
4519 	    sf->pfminfo.hheaddescent_add = hdoff;
4520 	    sf->pfminfo.os2_capheight = capheight;
4521 	    sf->pfminfo.os2_xheight = xheight;
4522 	    sf->pfminfo.pfmset = true;
4523 
4524 	    sf->pfminfo.subsuper_set = !GGadgetIsChecked(GWidgetGetControl(gw,CID_SubSuperDefault));
4525 	    if ( sf->pfminfo.subsuper_set ) {
4526 		sf->pfminfo.os2_subxsize = subs[0];
4527 		sf->pfminfo.os2_subysize = subs[1];
4528 		sf->pfminfo.os2_subxoff = subs[2];
4529 		sf->pfminfo.os2_subyoff = subs[3];
4530 		sf->pfminfo.os2_supxsize = super[0];
4531 		sf->pfminfo.os2_supysize = super[1];
4532 		sf->pfminfo.os2_supxoff = super[2];
4533 		sf->pfminfo.os2_supyoff = super[3];
4534 		sf->pfminfo.os2_strikeysize = strike[0];
4535 		sf->pfminfo.os2_strikeypos = strike[1];
4536 	    }
4537 	}
4538 	/* must come after all scaleable fields (linegap, etc.) */
4539 	if ( as!=sf->ascent || des!=sf->descent ) {
4540 	    if ( as+des != sf->ascent+sf->descent && GGadgetIsChecked(GWidgetGetControl(gw,CID_Scale)) )
4541 		SFScaleToEm(sf,as,des);
4542 	    else {
4543 		sf->ascent = as;
4544 		sf->descent = des;
4545 	    }
4546 	    BDFsSetAsDs(sf);
4547 	    reformat_fv = true;
4548 	    CIDMasterAsDes(sf);
4549 	}
4550 	GFI_SetLayers(d);
4551 	if ( guideorder2!=sf->grid.order2 ) {
4552 	    if ( guideorder2 )
4553 		SFConvertGridToOrder2(sf);
4554 	    else
4555 		SFConvertGridToOrder3(sf);
4556 	}
4557 	GFI_ApplyLookupChanges(d);
4558 	if ( retitle_fv )
4559 	    FVSetTitles(sf);
4560 	if ( reformat_fv || was_ml!=sf->multilayer || was_stroke!=sf->strokedfont )
4561 	    FontViewReformatAll(sf);
4562 	sf->changed = true;
4563 	SFSetModTime(sf);
4564 	sf->changed_since_autosave = true;
4565 	sf->changed_since_xuidchanged = !xuidchanged;
4566 	/* Just in case they changed the blue values and we are showing blues */
4567 	/*  in outline views... */
4568 	for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL ) {
4569 	    CharView *cv;
4570 	    for ( cv = (CharView *) (sf->glyphs[i]->views); cv!=NULL; cv=(CharView *) (cv->b.next) ) {
4571 		cv->back_img_out_of_date = true;
4572 		GDrawRequestExpose(cv->v,NULL,false);
4573 	    }
4574 	}
4575 	MacFeatListFree(sf->features);
4576 	sf->features = GGadgetGetUserData(GWidgetGetControl(d->gw,CID_Features));
4577 	last_aspect = d->old_aspect;
4578 
4579 	/* Class 0 is unused */
4580 	MarkClassFree(sf->mark_class_cnt,sf->mark_classes,sf->mark_class_names);
4581 	sf->mark_class_cnt = mc_rows + 1;
4582 	sf->mark_classes     = malloc((mc_rows+1)*sizeof(char *));
4583 	sf->mark_class_names = malloc((mc_rows+1)*sizeof(char *));
4584 	sf->mark_classes[0] = sf->mark_class_names[0] = NULL;
4585 	for ( i=0; i<mc_rows; ++i ) {
4586 	    sf->mark_class_names[i+1] = copy(markclasses[2*i+0].u.md_str);
4587 	    sf->mark_classes[i+1]     = GlyphNameListDeUnicode(markclasses[2*i+1].u.md_str);
4588 	}
4589 
4590 	/* Set 0 is used */
4591 	MarkSetFree(sf->mark_set_cnt,sf->mark_sets,sf->mark_set_names);
4592 	sf->mark_set_cnt = ms_rows;
4593 	sf->mark_sets      = malloc((ms_rows)*sizeof(char *));
4594 	sf->mark_set_names = malloc((ms_rows)*sizeof(char *));
4595 	for ( i=0; i<ms_rows; ++i ) {
4596 	    sf->mark_set_names[i] = copy(marksets[2*i+0].u.md_str);
4597 	    sf->mark_sets[i]      = GlyphNameListDeUnicode(marksets[2*i+1].u.md_str);
4598 	}
4599 
4600 	GFI_Close(d);
4601 
4602 	SFReplaceFontnameBDFProps(sf);
4603 	MVReFeatureAll(sf);
4604 	MVReKernAll(sf);
4605     }
4606 return( true );
4607 }
4608 
GFI_AsDsLab(struct gfi_data * d,int cid,int onlylabel)4609 static void GFI_AsDsLab(struct gfi_data *d, int cid, int onlylabel) {
4610     int isoffset = GGadgetIsChecked(GWidgetGetControl(d->gw,cid));
4611     DBounds b;
4612     int ocid, labcid;
4613     double val;
4614     char buf[40];
4615     char *offt, *baret;
4616     int ismax=0;
4617     unichar_t *end;
4618 
4619     switch ( cid ) {
4620       case CID_WinAscentIsOff:
4621 	offt = _("Win Ascent Offset:"); baret = _("Win Ascent:");
4622 	ocid = CID_WinAscent; labcid = CID_WinAscentLab;
4623 	ismax = true;
4624       break;
4625       case CID_WinDescentIsOff:
4626 	offt = _("Win Descent Offset:"); baret = _("Win Descent:");
4627 	ocid = CID_WinDescent; labcid = CID_WinDescentLab;
4628       break;
4629       case CID_TypoAscentIsOff:
4630 	offt = _("Typo Ascent Offset:"); baret = _("Typo Ascent:");
4631 	ocid = CID_TypoAscent; labcid = CID_TypoAscentLab;
4632 	ismax = true;
4633       break;
4634       case CID_TypoDescentIsOff:
4635 	offt = _("Typo Descent Offset:"); baret = _("Typo Descent:");
4636 	ocid = CID_TypoDescent; labcid = CID_TypoDescentLab;
4637       break;
4638       case CID_HHeadAscentIsOff:
4639 	offt = _("HHead Ascent Offset:"); baret = _("HHead Ascent:");
4640 	ocid = CID_HHeadAscent; labcid = CID_HHeadAscentLab;
4641 	ismax = true;
4642       break;
4643       case CID_HHeadDescentIsOff:
4644 	offt = _("HHead Descent Offset:"); baret = _("HHead Descent:");
4645 	ocid = CID_HHeadDescent; labcid = CID_HHeadDescentLab;
4646       break;
4647       default:
4648 return;
4649     }
4650 
4651     GGadgetSetTitle8(GWidgetGetControl(d->gw,labcid),
4652 	    isoffset?offt:baret);
4653     if ( onlylabel )
4654 return;
4655 
4656     if ( cid == CID_TypoAscentIsOff ) {
4657 	const unichar_t *as = _GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Ascent));
4658 	double av=u_strtod(as,&end);
4659 	b.maxy = *end=='\0' ? av : d->sf->ascent;
4660     } else if ( cid == CID_TypoDescentIsOff ) {
4661 	const unichar_t *ds = _GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Descent));
4662 	double dv=u_strtod(ds,&end);
4663 	b.miny = *end=='\0' ? -dv : -d->sf->descent;
4664     } else {
4665 	CIDLayerFindBounds(d->sf,ly_fore,&b);
4666 	if ( cid == CID_WinDescentIsOff ) b.miny = -b.miny;
4667     }
4668 
4669     val = u_strtod(_GGadgetGetTitle(GWidgetGetControl(d->gw,ocid)),NULL);
4670     if ( isoffset )
4671 	sprintf( buf,"%g",rint( val-(ismax ? b.maxy : b.miny)) );
4672     else
4673 	sprintf( buf,"%g",rint( val+(ismax ? b.maxy : b.miny)) );
4674     GGadgetSetTitle8(GWidgetGetControl(d->gw,ocid),buf);
4675 }
4676 
GFI_AsDesIsOff(GGadget * g,GEvent * e)4677 static int GFI_AsDesIsOff(GGadget *g, GEvent *e) {
4678     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
4679 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
4680 	GFI_AsDsLab(d,GGadgetGetCid(g),false);
4681     }
4682 return( true );
4683 }
4684 
_GFI_PanoseDefault(struct gfi_data * d)4685 static void _GFI_PanoseDefault(struct gfi_data *d) {
4686     int i;
4687     int isdefault = GGadgetIsChecked(GWidgetGetControl(d->gw,CID_PanDefault));
4688 
4689     for ( i=0; i<10; ++i ) {
4690 	GGadgetSetEnabled(GWidgetGetControl(d->gw,CID_PanFamily+i),!isdefault);
4691 	GGadgetSetEnabled(GWidgetGetControl(d->gw,CID_PanFamilyLab+i),!isdefault);
4692     }
4693     if ( isdefault ) {
4694 	char *n = cu_copy(_GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Fontname)));
4695 	struct pfminfo info;
4696 	int old1, old2;
4697 	memset(&info,0,sizeof(info));
4698 	old1 = d->sf->pfminfo.pfmset; old2 = d->sf->pfminfo.panose_set;
4699 	d->sf->pfminfo.pfmset = false; d->sf->pfminfo.panose_set = false;
4700 	SFDefaultOS2Info(&info,d->sf,n);
4701 	d->sf->pfminfo.pfmset = old1; d->sf->pfminfo.panose_set = old2;
4702 	free(n);
4703 	for ( i=0; i<10; ++i )
4704 	    GGadgetSelectOneListItem(GWidgetGetControl(d->gw,CID_PanFamily+i),info.panose[i]);
4705     }
4706 }
4707 
GFI_PanoseDefault(GGadget * g,GEvent * e)4708 static int GFI_PanoseDefault(GGadget *g, GEvent *e) {
4709     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
4710 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
4711 	_GFI_PanoseDefault(d);
4712     }
4713 return( true );
4714 }
4715 
GFI_ShowPanoseDocs(GGadget * g,GEvent * e)4716 static int GFI_ShowPanoseDocs(GGadget *g, GEvent *e) {
4717     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
4718 	help("http://panose.com/", NULL);
4719     }
4720 return( true );
4721 }
4722 
GFI_SetPanoseLists(struct gfi_data * d)4723 static void GFI_SetPanoseLists(struct gfi_data *d) {
4724     int kind = GGadgetGetFirstListSelectedItem(GWidgetGetControl(d->gw,CID_PanFamily));
4725     int i;
4726 
4727     if ( kind>=0 && kind!=d->last_panose_family ) {
4728 	if ( kind>6 ) kind=6;	/* No data for any kinds beyond 5, so anything bigger is just undefined, and that's 6 */
4729 	for ( i=1; i<10; ++i ) {
4730 	    GGadget *lab = GWidgetGetControl(d->gw,CID_PanFamilyLab+i);
4731 	    GGadget *list = GWidgetGetControl(d->gw,CID_PanFamily+i);
4732 	    int temp = GGadgetGetFirstListSelectedItem(list);
4733 	    if ( kind==5 && i==2 ) temp=1;
4734 	    if ( temp>=16 && (kind!=4 || i!=5)) temp=15;
4735 	    else if ( temp>16 ) temp=16;	/* Decorative.serifvar has 17 elements */
4736 	    GGadgetSetTitle8WithMn(lab,panoses[kind][i-1].name);
4737 	    GGadgetSetList(list,GTextInfoArrayFromList(panoses[kind][i-1].variants,NULL),false);
4738 	    GGadgetSelectOneListItem(list,temp);
4739 	}
4740     }
4741 }
4742 
GFI_ChangePanoseFamily(GGadget * g,GEvent * e)4743 static int GFI_ChangePanoseFamily(GGadget *g, GEvent *e) {
4744     if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
4745 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
4746 	GFI_SetPanoseLists(d);
4747     }
4748 return( true );
4749 }
4750 
GFI_SubSuperSet(struct gfi_data * d,struct pfminfo * info)4751 static void GFI_SubSuperSet(struct gfi_data *d, struct pfminfo *info) {
4752     char buffer[40];
4753     unichar_t ubuf[40];
4754 
4755     sprintf( buffer, "%d", info->os2_subxsize );
4756     uc_strcpy(ubuf,buffer);
4757     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_SubXSize),ubuf);
4758 
4759     sprintf( buffer, "%d", info->os2_subysize );
4760     uc_strcpy(ubuf,buffer);
4761     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_SubYSize),ubuf);
4762 
4763     sprintf( buffer, "%d", info->os2_subxoff );
4764     uc_strcpy(ubuf,buffer);
4765     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_SubXOffset),ubuf);
4766 
4767     sprintf( buffer, "%d", info->os2_subyoff );
4768     uc_strcpy(ubuf,buffer);
4769     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_SubYOffset),ubuf);
4770 
4771 
4772     sprintf( buffer, "%d", info->os2_supxsize );
4773     uc_strcpy(ubuf,buffer);
4774     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_SuperXSize),ubuf);
4775 
4776     sprintf( buffer, "%d", info->os2_supysize );
4777     uc_strcpy(ubuf,buffer);
4778     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_SuperYSize),ubuf);
4779 
4780     sprintf( buffer, "%d", info->os2_supxoff );
4781     uc_strcpy(ubuf,buffer);
4782     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_SuperXOffset),ubuf);
4783 
4784     sprintf( buffer, "%d", info->os2_supyoff );
4785     uc_strcpy(ubuf,buffer);
4786     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_SuperYOffset),ubuf);
4787 
4788 
4789     sprintf( buffer, "%d", info->os2_strikeysize );
4790     uc_strcpy(ubuf,buffer);
4791     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_StrikeoutSize),ubuf);
4792 
4793     sprintf( buffer, "%d", info->os2_strikeypos );
4794     uc_strcpy(ubuf,buffer);
4795     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_StrikeoutPos),ubuf);
4796 }
4797 
_GFI_SubSuperDefault(struct gfi_data * d)4798 static void _GFI_SubSuperDefault(struct gfi_data *d) {
4799     int i;
4800     int isdefault = GGadgetIsChecked(GWidgetGetControl(d->gw,CID_SubSuperDefault));
4801 
4802     for ( i=0; i<10; ++i )
4803 	GGadgetSetEnabled(GWidgetGetControl(d->gw,CID_SubXSize+i),!isdefault);
4804     if ( isdefault ) {
4805 	const unichar_t *as = _GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Ascent));
4806 	const unichar_t *ds = _GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Descent));
4807 	const unichar_t *ia = _GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Descent));
4808 	unichar_t *aend, *dend, *iend;
4809 	double av=u_strtod(as,&aend),dv=u_strtod(ds,&dend),iav=u_strtod(ia,&iend);
4810 	struct pfminfo info;
4811 	if ( *aend!='\0' ) av = d->sf->ascent;
4812 	if ( *dend!='\0' ) dv = d->sf->descent;
4813 	if ( *iend!='\0' ) iav = d->sf->italicangle;
4814 	memset(&info,0,sizeof(info));
4815 	SFDefaultOS2SubSuper(&info,(int) (dv+av), iav);
4816 	GFI_SubSuperSet(d,&info);
4817     }
4818 }
4819 
GFI_SubSuperDefault(GGadget * g,GEvent * e)4820 static int GFI_SubSuperDefault(GGadget *g, GEvent *e) {
4821     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
4822 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
4823 	_GFI_SubSuperDefault(d);
4824     }
4825 return( true );
4826 }
4827 
TTFSetup(struct gfi_data * d)4828 static void TTFSetup(struct gfi_data *d) {
4829     struct pfminfo info;
4830     char buffer[10]; unichar_t ubuf[10];
4831     int i, lg, vlg, tlg;
4832     const unichar_t *as = _GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Ascent));
4833     const unichar_t *ds = _GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Descent));
4834     unichar_t *aend, *dend;
4835     double av=u_strtod(as,&aend),dv=u_strtod(ds,&dend);
4836 
4837     info = d->sf->pfminfo;
4838     if ( !info.pfmset ) {
4839 	/* Base this stuff on the CURRENT name */
4840 	/* if the user just created a font, and named it *Bold, then the sf */
4841 	/*  won't yet have Bold in its name, and basing the weight on it would*/
4842 	/*  give the wrong answer. That's why we don't do this init until we */
4843 	/*  get to one of the ttf aspects, it gives the user time to set the */
4844 	/*  name properly */
4845 	/* And on CURRENT values of ascent and descent */
4846 	char *n = cu_copy(_GGadgetGetTitle(GWidgetGetControl(d->gw,CID_Fontname)));
4847 	if ( *aend=='\0' && *dend=='\0' ) {
4848 	    if ( info.linegap==0 )
4849 		info.linegap = rint(.09*(av+dv));
4850 	    if ( info.vlinegap==0 )
4851 		info.vlinegap = info.linegap;
4852 	    if ( info.os2_typolinegap==0 )
4853 		info.os2_typolinegap = info.linegap;
4854 	}
4855 	lg = info.linegap; vlg = info.vlinegap; tlg = info.os2_typolinegap;
4856 	SFDefaultOS2Info(&info,d->sf,n);
4857 	if ( lg != 0 )
4858 	    info.linegap = lg;
4859 	if ( vlg!= 0 )
4860 	    info.vlinegap = vlg;
4861 	if ( tlg!=0 )
4862 	    info.os2_typolinegap = tlg;
4863 	free(n);
4864     }
4865 
4866     if ( info.weight>0 && info.weight<=900 && info.weight%100==0 )
4867 	GGadgetSetTitle8(GWidgetGetControl(d->gw,CID_WeightClass),
4868 		(char *) weightclass[info.weight/100-1].text);
4869     else {
4870 	sprintf( buffer, "%d", info.weight );
4871 	GGadgetSetTitle8(GWidgetGetControl(d->gw,CID_WeightClass),buffer);
4872     }
4873     GGadgetSelectOneListItem(GWidgetGetControl(d->gw,CID_WidthClass),info.width-1);
4874     for ( i=0; pfmfamily[i].text!=NULL; ++i )
4875 	if ( (intpt) (pfmfamily[i].userdata)==info.pfmfamily ) {
4876 	    GGadgetSelectOneListItem(GWidgetGetControl(d->gw,CID_PFMFamily),i);
4877     break;
4878 	}
4879 
4880     if ( d->sf->os2_version>=0 && d->sf->os2_version<=4 )
4881 	GGadgetSelectOneListItem(GWidgetGetControl(d->gw,CID_OS2Version),d->sf->os2_version);
4882     else {
4883 	sprintf( buffer,"%d", d->sf->os2_version );
4884 	GGadgetSetTitle8(GWidgetGetControl(d->gw,CID_OS2Version),buffer);
4885     }
4886     GGadgetSetChecked(GWidgetGetControl(d->gw,CID_UseTypoMetrics),d->sf->use_typo_metrics);
4887     GGadgetSetChecked(GWidgetGetControl(d->gw,CID_WeightWidthSlopeOnly),d->sf->weight_width_slope_only);
4888 
4889     for ( i=0; ibmfamily[i].text!=NULL; ++i )
4890 	if ( (intpt) (ibmfamily[i].userdata)==info.os2_family_class ) {
4891 	    GGadgetSelectOneListItem(GWidgetGetControl(d->gw,CID_IBMFamily),i);
4892     break;
4893 	}
4894     if ( info.os2_vendor[0]!='\0' ) {
4895 	ubuf[0] = info.os2_vendor[0];
4896 	ubuf[1] = info.os2_vendor[1];
4897 	ubuf[2] = info.os2_vendor[2];
4898 	ubuf[3] = info.os2_vendor[3];
4899 	ubuf[4] = 0;
4900     } else if ( TTFFoundry!=NULL )
4901 	uc_strncpy(ubuf,TTFFoundry,4);
4902     else
4903 	uc_strcpy(ubuf,"PfEd");
4904     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_Vendor),ubuf);
4905 
4906     GGadgetSetChecked(GWidgetGetControl(d->gw,CID_PanDefault),!info.panose_set);
4907     _GFI_PanoseDefault(d);
4908     if ( info.panose_set ) {
4909 	for ( i=0; i<10; ++i ) {
4910 	    int v = info.panose[i];
4911 	    if ( v>=16 && (info.panose[0]!=4 || i!=5 )) v=15;
4912 	    else if ( v>16 ) v=16;	/* Sigh Decorative.SerifVar has 17 elements */
4913 	    GGadgetSelectOneListItem(GWidgetGetControl(d->gw,CID_PanFamily+i),v);
4914 	    if ( i==0 )
4915 		GFI_SetPanoseLists(d);
4916 	}
4917     }
4918 
4919     GGadgetSetChecked(GWidgetGetControl(d->gw,CID_SubSuperDefault),!info.subsuper_set);
4920     if ( info.subsuper_set )
4921 	GFI_SubSuperSet(d,&info);
4922     _GFI_SubSuperDefault(d);
4923 
4924     d->ttf_set = true;
4925     /* FSType is already set */
4926     sprintf( buffer, "%d", info.linegap );
4927     uc_strcpy(ubuf,buffer);
4928     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_LineGap),ubuf);
4929     sprintf( buffer, "%d", info.vlinegap );
4930     uc_strcpy(ubuf,buffer);
4931     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_VLineGap),ubuf);
4932     sprintf( buffer, "%d", info.os2_typolinegap );
4933     uc_strcpy(ubuf,buffer);
4934     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_TypoLineGap),ubuf);
4935 
4936     GGadgetSetChecked(GWidgetGetControl(d->gw,CID_WinAscentIsOff),info.winascent_add);
4937     GFI_AsDsLab(d,CID_WinAscentIsOff,true);
4938     sprintf( buffer, "%d", info.os2_winascent );
4939     uc_strcpy(ubuf,buffer);
4940     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_WinAscent),ubuf);
4941     GGadgetSetChecked(GWidgetGetControl(d->gw,CID_WinDescentIsOff),info.windescent_add);
4942     GFI_AsDsLab(d,CID_WinDescentIsOff,true);
4943     sprintf( buffer, "%d", info.os2_windescent );
4944     uc_strcpy(ubuf,buffer);
4945     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_WinDescent),ubuf);
4946 
4947     GGadgetSetChecked(GWidgetGetControl(d->gw,CID_TypoAscentIsOff),info.typoascent_add);
4948     GFI_AsDsLab(d,CID_TypoAscentIsOff,true);
4949     sprintf( buffer, "%d", info.os2_typoascent );
4950     uc_strcpy(ubuf,buffer);
4951     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_TypoAscent),ubuf);
4952     GGadgetSetChecked(GWidgetGetControl(d->gw,CID_TypoDescentIsOff),info.typodescent_add);
4953     GFI_AsDsLab(d,CID_TypoDescentIsOff,true);
4954     sprintf( buffer, "%d", info.os2_typodescent );
4955     uc_strcpy(ubuf,buffer);
4956     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_TypoDescent),ubuf);
4957 
4958     sprintf( buffer, "%d", info.os2_capheight );
4959     uc_strcpy(ubuf,buffer);
4960     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_CapHeight),ubuf);
4961     sprintf( buffer, "%d", info.os2_xheight );
4962     uc_strcpy(ubuf,buffer);
4963     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_XHeight),ubuf);
4964 
4965     GGadgetSetChecked(GWidgetGetControl(d->gw,CID_HHeadAscentIsOff),info.hheadascent_add);
4966     GFI_AsDsLab(d,CID_HHeadAscentIsOff,true);
4967     sprintf( buffer, "%d", info.hhead_ascent );
4968     uc_strcpy(ubuf,buffer);
4969     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_HHeadAscent),ubuf);
4970     GGadgetSetChecked(GWidgetGetControl(d->gw,CID_HHeadDescentIsOff),info.hheaddescent_add);
4971     GFI_AsDsLab(d,CID_HHeadDescentIsOff,true);
4972     sprintf( buffer, "%d", info.hhead_descent );
4973     uc_strcpy(ubuf,buffer);
4974     GGadgetSetTitle(GWidgetGetControl(d->gw,CID_HHeadDescent),ubuf);
4975 }
4976 
4977 static char *mathparams[] = {
4978 /* GT: TeX parameters for math fonts. "Num" means numerator, "Denom" */
4979 /* GT: means denominator, "Sup" means superscript, "Sub" means subscript */
4980     N_("Num1:"),
4981     N_("Num2:"),  N_("Num3:"), N_("Denom1:"),
4982     N_("Denom2:"), N_("Sup1:"), N_("Sup2:"), N_("Sup3:"), N_("Sub1:"), N_("Sub2:"),
4983     N_("SupDrop:"), N_("SubDrop:"), N_("Delim1:"), N_("Delim2:"), N_("Axis Ht:"),
4984     0 };
4985 static char *mathpopups[] = { N_("Amount to raise baseline for numerators in display styles"),
4986     N_("Amount to raise baseline for numerators in non-display styles"),
4987     N_("Amount to raise baseline for numerators in non-display atop styles"),
4988     N_("Amount to lower baseline for denominators in display styles"),
4989     N_("Amount to lower baseline for denominators in non-display styles"),
4990     N_("Amount to raise baseline for superscripts in display styles"),
4991     N_("Amount to raise baseline for superscripts in non-display styles"),
4992     N_("Amount to raise baseline for superscripts in modified styles"),
4993     N_("Amount to lower baseline for subscripts in display styles"),
4994     N_("Amount to lower baseline for subscripts in non-display styles"),
4995     N_("Amount above top of large box to place baseline of superscripts"),
4996     N_("Amount below bottom of large box to place baseline of subscripts"),
4997     N_("Size of comb delimiters in display styles"),
4998     N_("Size of comb delimiters in non-display styles"),
4999     N_("Height of fraction bar above base line"),
5000     0 };
5001 /* GT: Default Rule Thickness. A rule being a typographic term for a straight */
5002 /* GT: black line on a printed page. */
5003 static char *extparams[] = { N_("Def Rule Thick:"),
5004 /* GT: I don't really understand these "Big Op Space" things. They have */
5005 /* GT: something to do with TeX and are roughly defined a few strings down */
5006 	N_("Big Op Space1:"),
5007 	N_("Big Op Space2:"),
5008 	N_("Big Op Space3:"),
5009 	N_("Big Op Space4:"),
5010 	N_("Big Op Space5:"), 0 };
5011 static char *extpopups[] = { N_("Default thickness of over and overline bars"),
5012 	N_("The minimum glue space above a large displayed operator"),
5013 	N_("The minimum glue space below a large displayed operator"),
5014 	N_("The minimum distance between a limit's baseline and a large displayed\noperator when the limit is above the operator"),
5015 	N_("The minimum distance between a limit's baseline and a large displayed\noperator when the limit is below the operator"),
5016 	N_("The extra glue place above and below displayed limits"),
5017 	0 };
5018 
mp_e_h(GWindow gw,GEvent * event)5019 static int mp_e_h(GWindow gw, GEvent *event) {
5020     int i;
5021 
5022     if ( event->type==et_close ) {
5023 	struct gfi_data *d = GDrawGetUserData(gw);
5024 	d->mpdone = true;
5025     } else if ( event->type == et_char ) {
5026 return( false );
5027     } else if ( event->type==et_controlevent && event->u.control.subtype == et_buttonactivate ) {
5028 	struct gfi_data *d = GDrawGetUserData(gw);
5029 	if ( GGadgetGetCid(event->u.control.g)) {
5030 	    int err=false;
5031 	    double em = (d->sf->ascent+d->sf->descent), val;
5032 	    char **params;
5033 	    if ( GGadgetIsChecked(GWidgetGetControl(d->gw,CID_TeXMathSym)) )
5034 		params = mathparams;
5035 	    else
5036 		params = extparams;
5037 	    for ( i=0; params[i]!=0 && !err; ++i ) {
5038 		val = GetReal8(gw,CID_TeX+i,params[i],&err);
5039 		if ( !err )
5040 		    d->texdata.params[i+7] = rint( val/em * (1<<20) );
5041 	    }
5042 	    if ( !err )
5043 		d->mpdone = true;
5044 	} else
5045 	    d->mpdone = true;
5046     }
5047 return( true );
5048 }
5049 
GFI_MoreParams(GGadget * g,GEvent * e)5050 static int GFI_MoreParams(GGadget *g, GEvent *e) {
5051     int tot;
5052     GRect pos;
5053     GWindow gw;
5054     GWindowAttrs wattrs;
5055     GGadgetCreateData txgcd[35], boxes[3], *txarray[18][3], *barray[9];
5056     GTextInfo txlabel[35];
5057     int i,y,k,j;
5058     char **params, **popups;
5059     char values[20][20];
5060 
5061     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
5062 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
5063 	if ( GGadgetIsChecked(GWidgetGetControl(d->gw,CID_TeXText)) )
5064 return( true );
5065 	else if ( GGadgetIsChecked(GWidgetGetControl(d->gw,CID_TeXMathSym)) ) {
5066 	    tot = 22-7;
5067 	    params = mathparams;
5068 	    popups = mathpopups;
5069 	} else {
5070 	    tot = 13-7;
5071 	    params = extparams;
5072 	    popups = extpopups;
5073 	}
5074 
5075 	memset(&wattrs,0,sizeof(wattrs));
5076 	wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
5077 	wattrs.event_masks = ~(1<<et_charup);
5078 	wattrs.is_dlg = true;
5079 	wattrs.restrict_input_to_me = 1;
5080 	wattrs.undercursor = 1;
5081 	wattrs.cursor = ct_pointer;
5082 /* GT: More Parameters */
5083 	wattrs.utf8_window_title = _("More Params");
5084 	pos.x = pos.y = 0;
5085 	pos.width =GDrawPointsToPixels(NULL,GGadgetScale(180));
5086 	pos.height = GDrawPointsToPixels(NULL,tot*26+60);
5087 	gw = GDrawCreateTopWindow(NULL,&pos,mp_e_h,d,&wattrs);
5088 
5089 	memset(&txlabel,0,sizeof(txlabel));
5090 	memset(&txgcd,0,sizeof(txgcd));
5091 
5092 	k=j=0; y = 10;
5093 	for ( i=0; params[i]!=0; ++i ) {
5094 	    txlabel[k].text = (unichar_t *) params[i];
5095 	    txlabel[k].text_is_1byte = true;
5096 	    txgcd[k].gd.label = &txlabel[k];
5097 	    txgcd[k].gd.pos.x = 10; txgcd[k].gd.pos.y = y+4;
5098 	    txgcd[k].gd.flags = gg_visible | gg_enabled;
5099 	    txgcd[k].gd.popup_msg = popups[i];
5100 	    txgcd[k++].creator = GLabelCreate;
5101 	    txarray[j][0] = &txgcd[k-1];
5102 
5103 	    sprintf( values[i], "%g", d->texdata.params[i+7]*(double) (d->sf->ascent+d->sf->descent)/(double) (1<<20));
5104 	    txlabel[k].text = (unichar_t *) values[i];
5105 	    txlabel[k].text_is_1byte = true;
5106 	    txgcd[k].gd.label = &txlabel[k];
5107 	    txgcd[k].gd.pos.x = 85; txgcd[k].gd.pos.y = y;
5108 	    txgcd[k].gd.pos.width = 75;
5109 	    txgcd[k].gd.flags = gg_visible | gg_enabled;
5110 	    txgcd[k].gd.cid = CID_TeX + i;
5111 	    txgcd[k++].creator = GTextFieldCreate;
5112 	    txarray[j][1] = &txgcd[k-1]; txarray[j++][2] = NULL;
5113 	    y += 26;
5114 	}
5115 	txarray[j][0] = GCD_Glue; txarray[j][1] = GCD_Glue; txarray[j++][2] = NULL;
5116 
5117 	txgcd[k].gd.pos.x = 30-3; txgcd[k].gd.pos.y = GDrawPixelsToPoints(NULL,pos.height)-35-3;
5118 	txgcd[k].gd.pos.width = -1; txgcd[k].gd.pos.height = 0;
5119 	txgcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
5120 	txlabel[k].text = (unichar_t *) _("_OK");
5121 	txlabel[k].text_is_1byte = true;
5122 	txlabel[k].text_in_resource = true;
5123 	txgcd[k].gd.label = &txlabel[k];
5124 	txgcd[k].gd.cid = true;
5125 	txgcd[k++].creator = GButtonCreate;
5126 
5127 	txgcd[k].gd.pos.x = -30; txgcd[k].gd.pos.y = txgcd[k-1].gd.pos.y+3;
5128 	txgcd[k].gd.pos.width = -1; txgcd[k].gd.pos.height = 0;
5129 	txgcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
5130 	txlabel[k].text = (unichar_t *) _("_Cancel");
5131 	txlabel[k].text_is_1byte = true;
5132 	txlabel[k].text_in_resource = true;
5133 	txgcd[k].gd.label = &txlabel[k];
5134 	txgcd[k].gd.cid = false;
5135 	txgcd[k++].creator = GButtonCreate;
5136 
5137 	barray[0] = barray[2] = barray[3] = barray[4] = barray[6] = GCD_Glue; barray[7] = NULL;
5138 	barray[1] = &txgcd[k-2]; barray[5] = &txgcd[k-1];
5139 	txarray[j][0] = &boxes[2]; txarray[j][1] = GCD_ColSpan; txarray[j++][2] = NULL;
5140 	txarray[j][0] = NULL;
5141 
5142 	memset(boxes,0,sizeof(boxes));
5143 	boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
5144 	boxes[0].gd.flags = gg_enabled|gg_visible;
5145 	boxes[0].gd.u.boxelements = txarray[0];
5146 	boxes[0].creator = GHVGroupCreate;
5147 
5148 	boxes[2].gd.flags = gg_enabled|gg_visible;
5149 	boxes[2].gd.u.boxelements = barray;
5150 	boxes[2].creator = GHBoxCreate;
5151 
5152 	GGadgetsCreate(gw,boxes);
5153 	GHVBoxSetExpandableCol(boxes[2].ret,gb_expandgluesame);
5154 	GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
5155 	GHVBoxFitWindow(boxes[0].ret);
5156 	d->mpdone = false;
5157 	GDrawSetVisible(gw,true);
5158 
5159 	while ( !d->mpdone )
5160 	    GDrawProcessOneEvent(NULL);
5161 	GDrawDestroyWindow(gw);
5162     }
5163 return( true );
5164 }
5165 
GFI_TeXChanged(GGadget * g,GEvent * e)5166 static int GFI_TeXChanged(GGadget *g, GEvent *e) {
5167     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
5168 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
5169 	GGadget *extrasp = GWidgetGetControl(d->gw,CID_TeXExtraSpLabel);
5170 
5171 	if ( GGadgetGetCid(g)==CID_TeXText ) {
5172 	    GGadgetSetTitle8(extrasp,
5173 /* GT: Extra Space */
5174 		    _("Extra Sp:"));
5175 	    GGadgetSetEnabled(GWidgetGetControl(d->gw,CID_MoreParams),false);
5176 	} else {
5177 	    GGadgetSetTitle8(extrasp, _("Math Sp:"));
5178 	    GGadgetSetEnabled(GWidgetGetControl(d->gw,CID_MoreParams),true);
5179 	}
5180 	/* In Polish we need to reflow the text after changing the label */
5181 	GHVBoxReflow(GWidgetGetControl(d->gw,CID_TeXBox));
5182     }
5183 return( true );
5184 }
5185 
DefaultTeX(struct gfi_data * d)5186 static void DefaultTeX(struct gfi_data *d) {
5187     char buffer[20];
5188     int i;
5189     SplineFont *sf = d->sf;
5190 
5191     d->tex_set = true;
5192 
5193     if ( sf->texdata.type==tex_unset ) {
5194 	TeXDefaultParams(sf);
5195 	d->texdata = sf->texdata;
5196     }
5197 
5198     for ( i=0; i<7; ++i ) {
5199 	sprintf( buffer,"%g", d->texdata.params[i]*(sf->ascent+sf->descent)/(double) (1<<20));
5200 	GGadgetSetTitle8(GWidgetGetControl(d->gw,CID_TeX+i),buffer);
5201     }
5202     if ( sf->texdata.type==tex_math )
5203 	GGadgetSetChecked(GWidgetGetControl(d->gw,CID_TeXMathSym), true);
5204     else if ( sf->texdata.type == tex_mathext )
5205 	GGadgetSetChecked(GWidgetGetControl(d->gw,CID_TeXMathExt), true);
5206     else {
5207 	GGadgetSetChecked(GWidgetGetControl(d->gw,CID_TeXText), true);
5208 	GGadgetSetTitle8(GWidgetGetControl(d->gw,CID_TeXExtraSpLabel),
5209 /* GT: Extra Space */
5210 		_("Extra Sp:"));
5211 	GGadgetSetEnabled(GWidgetGetControl(d->gw,CID_MoreParams),false);
5212     }
5213 }
5214 
GFI_MacAutomatic(GGadget * g,GEvent * e)5215 static int GFI_MacAutomatic(GGadget *g, GEvent *e) {
5216     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
5217 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
5218 	int autom = GGadgetIsChecked(GWidgetGetControl(d->gw,CID_MacAutomatic));
5219 	GGadgetSetEnabled(GWidgetGetControl(d->gw,CID_MacStyles),!autom);
5220     }
5221 return( true );
5222 }
5223 
FigureUnicode(struct gfi_data * d)5224 static void FigureUnicode(struct gfi_data *d) {
5225     int includeempties = GGadgetIsChecked(GWidgetGetControl(d->gw,CID_UnicodeEmpties));
5226     GGadget *list = GWidgetGetControl(d->gw,CID_Unicode);
5227     struct rangeinfo *ri;
5228     int cnt, i;
5229     GTextInfo **ti;
5230     char buffer[200];
5231 
5232     GGadgetClearList(list);
5233     ri = SFUnicodeRanges(d->sf,(includeempties?ur_includeempty:0)|ur_sortbyunicode);
5234     if ( ri==NULL ) cnt=0;
5235     else
5236 	for ( cnt=0; ri[cnt].range!=NULL; ++cnt );
5237 
5238     ti = malloc((cnt+1) * sizeof( GTextInfo * ));
5239     for ( i=0; i<cnt; ++i ) {
5240 	if ( ri[i].range->first==-1 )
5241 	    snprintf( buffer, sizeof(buffer),
5242 		    "%s  %d/0", _(ri[i].range->name), ri[i].cnt);
5243 	else
5244 	    snprintf( buffer, sizeof(buffer),
5245 		    "%s  U+%04X-U+%04X %d/%d",
5246 		    _(ri[i].range->name),
5247 		    (int) ri[i].range->first, (int) ri[i].range->last,
5248 		    ri[i].cnt, ri[i].range->actual );
5249 	ti[i] = calloc(1,sizeof(GTextInfo));
5250 	ti[i]->fg = ti[i]->bg = COLOR_DEFAULT;
5251 	ti[i]->text = utf82u_copy(buffer);
5252 	ti[i]->userdata = ri[i].range;
5253     }
5254     ti[i] = calloc(1,sizeof(GTextInfo));
5255     GGadgetSetList(list,ti,false);
5256     free(ri);
5257 }
5258 
GFI_UnicodeRangeChange(GGadget * g,GEvent * e)5259 static int GFI_UnicodeRangeChange(GGadget *g, GEvent *e) {
5260     struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
5261     GTextInfo *ti = GGadgetGetListItemSelected(g);
5262     struct unicoderange *r;
5263     int gid, first=-1;
5264     SplineFont *sf = d->sf;
5265     FontView *fv = (FontView *) (sf->fv);
5266     EncMap *map = fv->b.map;
5267     int i, enc;
5268 
5269     if ( ti==NULL )
5270 return( true );
5271     if ( e->type!=et_controlevent ||
5272 	    (e->u.control.subtype != et_listselected &&e->u.control.subtype != et_listdoubleclick))
5273 return( true );
5274 
5275     r = ti->userdata;
5276 
5277     for ( i=0; i<map->enccount; ++i )
5278 	fv->b.selected[i] = 0;
5279 
5280     if ( e->u.control.subtype == et_listselected ) {
5281 	for ( gid=0; gid<sf->glyphcnt; ++gid ) if ( sf->glyphs[gid]!=NULL ) {
5282 	    enc = map->backmap[gid];
5283 	    if ( sf->glyphs[gid]->unicodeenc>=r->first && sf->glyphs[gid]->unicodeenc<=r->last &&
5284 		    enc!=-1 ) {
5285 		if ( first==-1 || enc<first ) first = enc;
5286 		fv->b.selected[enc] = true;
5287 	    }
5288 	}
5289     } else if ( e->u.control.subtype == et_listdoubleclick && !r->unassigned ) {
5290 	char *found = calloc(r->last-r->first+1,1);
5291 	for ( gid=0; gid<sf->glyphcnt; ++gid ) if ( sf->glyphs[gid]!=NULL ) {
5292 	    int u = sf->glyphs[gid]->unicodeenc;
5293 	    if ( u>=r->first && u<=r->last ) {
5294 		found[u-r->first] = true;
5295 	    }
5296 	}
5297 	for ( i=0; i<=r->last-r->first; ++i ) {
5298 	    if ( isunicodepointassigned(i+r->first) && !found[i] ) {
5299 		enc = EncFromUni(i+r->first,map->enc);
5300 		if ( enc!=-1 ) {
5301 		    if ( first==-1 || enc<first ) first = enc;
5302 		    fv->b.selected[enc] = true;
5303 		}
5304 	    }
5305 	}
5306 	free(found);
5307     }
5308     if ( first==-1 ) {
5309 	GDrawBeep(NULL);
5310     } else {
5311 	FVScrollToChar(fv,first);
5312     }
5313     GDrawRequestExpose(fv->v,NULL,false);
5314 return( true );
5315 }
5316 
GFI_UnicodeEmptiesChange(GGadget * g,GEvent * e)5317 static int GFI_UnicodeEmptiesChange(GGadget *g, GEvent *e) {
5318     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
5319 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
5320 	FigureUnicode(d);
5321     }
5322 return( true );
5323 }
5324 
GFI_AspectChange(GGadget * g,GEvent * e)5325 static int GFI_AspectChange(GGadget *g, GEvent *e) {
5326     if ( e==NULL || (e->type==et_controlevent && e->u.control.subtype == et_radiochanged )) {
5327 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
5328 	int new_aspect = GTabSetGetSel(g);
5329 	int rows;
5330 
5331 	if ( d->old_aspect == d->tn_aspect )
5332 	    GMatrixEditGet(GWidgetGetControl(d->gw,CID_TNames), &rows);
5333 	if ( !d->ttf_set && new_aspect == d->ttfv_aspect )
5334 	    TTFSetup(d);
5335 	else if ( !d->names_set && new_aspect == d->tn_aspect ) {
5336 	    TTFNames_Resort(d);
5337 	    d->names_set = true;
5338 	} else if ( !d->tex_set && new_aspect == d->tx_aspect )
5339 	    DefaultTeX(d);
5340 	else if ( new_aspect == d->unicode_aspect )
5341 	    FigureUnicode(d);
5342 	d->old_aspect = new_aspect;
5343     }
5344 return( true );
5345 }
5346 
GFI_URangeAspectChange(GGadget * g,GEvent * e)5347 static int GFI_URangeAspectChange(GGadget *g, GEvent *e) {
5348     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
5349 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
5350 	GTabSetSetSel(GWidgetGetControl(d->gw,CID_Tabs),d->ttfv_aspect);
5351 	GFI_AspectChange(GWidgetGetControl(d->gw,CID_Tabs),NULL);
5352 	GTabSetSetSel(GWidgetGetControl(d->gw,CID_TTFTabs),4);
5353     }
5354 return( true );
5355 }
5356 
e_h(GWindow gw,GEvent * event)5357 static int e_h(GWindow gw, GEvent *event) {
5358     if ( event->type==et_close ) {
5359 	struct gfi_data *d = GDrawGetUserData(gw);
5360 	GFI_CancelClose(d);
5361     } else if ( event->type==et_destroy ) {
5362 	struct gfi_data *d = GDrawGetUserData(gw);
5363 	free(d);
5364     } else if ( event->type==et_char ) {
5365 return( GFI_Char(GDrawGetUserData(gw),event));
5366     }
5367 return( true );
5368 }
5369 
OS2_UnicodeChange(GGadget * g,GEvent * e)5370 static int OS2_UnicodeChange(GGadget *g, GEvent *e) {
5371     int32 flags[4];
5372     int len,i,bit,set;
5373 
5374     if ( e==NULL || (e->type==et_controlevent && e->u.control.subtype == et_textchanged )) {
5375 	const unichar_t *ret;
5376 	unichar_t *end;
5377 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
5378 	GWindow gw = d->gw;
5379 	GGadget *list;
5380 
5381 	ret = _GGadgetGetTitle(g);
5382 	flags[3] = u_strtoul(ret,&end,16);
5383 	while ( !ishexdigit(*end) && *end!='\0' ) ++end;
5384 	flags[2] = u_strtoul(end,&end,16);
5385 	while ( !ishexdigit(*end) && *end!='\0' ) ++end;
5386 	flags[1] = u_strtoul(end,&end,16);
5387 	while ( !ishexdigit(*end) && *end!='\0' ) ++end;
5388 	flags[0] = u_strtoul(end,&end,16);
5389 
5390 	list = GWidgetGetControl(gw,CID_UnicodeList);
5391 
5392 	for ( i=0; unicoderangenames[i].text!=NULL; ++i ) {
5393 	    bit = (intpt) (unicoderangenames[i].userdata);
5394 	    set = (flags[bit>>5]&(1<<(bit&31)))?1 : 0;
5395 	    GGadgetSelectListItem(list,i,set);
5396 	}
5397     } else if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
5398 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
5399 	GWindow gw = d->gw;
5400 	char ranges[40];
5401 	GTextInfo **list = GGadgetGetList(g,&len);
5402 	GGadget *field = GWidgetGetControl(gw,CID_UnicodeRanges);
5403 
5404 	flags[0] = flags[1] = flags[2] = flags[3] = 0;
5405 	for ( i=0; i<len; ++i )
5406 	    if ( list[i]->selected ) {
5407 		bit = ((intpt) (list[i]->userdata));
5408 		flags[bit>>5] |= (1<<(bit&31));
5409 	    }
5410 
5411 	sprintf( ranges, "%08x.%08x.%08x.%08x", flags[3], flags[2], flags[1], flags[0]);
5412 	GGadgetSetTitle8(field,ranges);
5413     }
5414 return( true );
5415 }
5416 
OS2_URangesDefault(GGadget * g,GEvent * e)5417 static int OS2_URangesDefault(GGadget *g, GEvent *e) {
5418 
5419     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
5420 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
5421 	int def = GGadgetIsChecked(g);
5422 	GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_UnicodeRanges),!def);
5423 	GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_UnicodeList),!def);
5424 	if ( def ) {
5425 	    SplineFont *sf = gfi->sf;
5426 	    char ranges[40];
5427 	    OS2FigureUnicodeRanges(sf,sf->pfminfo.unicoderanges);
5428 	    sprintf( ranges, "%08x.%08x.%08x.%08x",
5429 		    sf->pfminfo.unicoderanges[3], sf->pfminfo.unicoderanges[2],
5430 		    sf->pfminfo.unicoderanges[1], sf->pfminfo.unicoderanges[0]);
5431 	    GGadgetSetTitle8(GWidgetGetControl(gfi->gw,CID_UnicodeRanges),ranges);
5432 	    OS2_UnicodeChange(GWidgetGetControl(gfi->gw,CID_UnicodeRanges),NULL);
5433 	}
5434     }
5435 return( true );
5436 }
5437 
OS2_CodePageChange(GGadget * g,GEvent * e)5438 static int OS2_CodePageChange(GGadget *g, GEvent *e) {
5439     int32 flags[2];
5440     int len,i,bit,set;
5441 
5442     if ( e==NULL || (e->type==et_controlevent && e->u.control.subtype == et_textchanged )) {
5443 	const unichar_t *ret;
5444 	unichar_t *end;
5445 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
5446 	GWindow gw = d->gw;
5447 	GGadget *list;
5448 
5449 	ret = _GGadgetGetTitle(g);
5450 	flags[1] = u_strtoul(ret,&end,16);
5451 	while ( !ishexdigit(*end) && *end!='\0' ) ++end;
5452 	flags[0] = u_strtoul(end,&end,16);
5453 
5454 	list = GWidgetGetControl(gw,CID_CodePageList);
5455 
5456 	for ( i=0; codepagenames[i].text!=NULL; ++i ) {
5457 	    bit = (intpt) (codepagenames[i].userdata);
5458 	    set = (flags[bit>>5]&(1<<(bit&31)))?1 : 0;
5459 	    GGadgetSelectListItem(list,i,set);
5460 	}
5461     } else if ( e->type==et_controlevent && e->u.control.subtype == et_listselected ) {
5462 	struct gfi_data *d = GDrawGetUserData(GGadgetGetWindow(g));
5463 	GWindow gw = d->gw;
5464 	char ranges[40];
5465 	GTextInfo **list = GGadgetGetList(g,&len);
5466 	GGadget *field = GWidgetGetControl(gw,CID_CodePageRanges);
5467 
5468 	flags[0] = flags[1] = 0;
5469 	for ( i=0; i<len; ++i )
5470 	    if ( list[i]->selected ) {
5471 		bit = ((intpt) (list[i]->userdata));
5472 		flags[bit>>5] |= (1<<(bit&31));
5473 	    }
5474 
5475 	sprintf( ranges, "%08x.%08x", flags[1], flags[0]);
5476 	GGadgetSetTitle8(field,ranges);
5477     }
5478 return( true );
5479 }
5480 
OS2_CPageDefault(GGadget * g,GEvent * e)5481 static int OS2_CPageDefault(GGadget *g, GEvent *e) {
5482 
5483     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
5484 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
5485 	int def = GGadgetIsChecked(g);
5486 	GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_CodePageRanges),!def);
5487 	GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_CodePageList),!def);
5488 	if ( def ) {
5489 	    SplineFont *sf = gfi->sf;
5490 	    char codepages[40];
5491 	    OS2FigureCodePages(sf,sf->pfminfo.codepages);
5492 	    sprintf( codepages, "%08x.%08x",
5493 		    sf->pfminfo.codepages[1], sf->pfminfo.codepages[0]);
5494 	    GGadgetSetTitle8(GWidgetGetControl(gfi->gw,CID_CodePageRanges),codepages);
5495 	    OS2_CodePageChange(GWidgetGetControl(gfi->gw,CID_CodePageRanges),NULL);
5496 	}
5497     }
5498 return( true );
5499 }
5500 
GFI_UseUniqueIDChanged(GGadget * g,GEvent * e)5501 static int GFI_UseUniqueIDChanged(GGadget *g, GEvent *e) {
5502 
5503     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
5504 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
5505 	GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_UniqueID),
5506 		GGadgetIsChecked(g));
5507     }
5508 return( true );
5509 }
5510 
GFI_UseXUIDChanged(GGadget * g,GEvent * e)5511 static int GFI_UseXUIDChanged(GGadget *g, GEvent *e) {
5512 
5513     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
5514 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
5515 	GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_XUID),
5516 		GGadgetIsChecked(g));
5517     }
5518 return( true );
5519 }
5520 
LookupSetup(struct lkdata * lk,OTLookup * lookups)5521 static void LookupSetup(struct lkdata *lk,OTLookup *lookups) {
5522     int cnt, subcnt;
5523     OTLookup *otl;
5524     struct lookup_subtable *sub;
5525 
5526     for ( cnt=0, otl=lookups; otl!=NULL; ++cnt, otl=otl->next );
5527     lk->cnt = cnt; lk->max = cnt+10;
5528     lk->all = calloc(lk->max,sizeof(struct lkinfo));
5529     for ( cnt=0, otl=lookups; otl!=NULL; ++cnt, otl=otl->next ) {
5530 	lk->all[cnt].lookup = otl;
5531 	for ( subcnt=0, sub=otl->subtables; sub!=NULL; ++subcnt, sub=sub->next );
5532 	lk->all[cnt].subtable_cnt = subcnt; lk->all[cnt].subtable_max = subcnt+10;
5533 	lk->all[cnt].subtables = calloc(lk->all[cnt].subtable_max,sizeof(struct lksubinfo));
5534 	for ( subcnt=0, sub=otl->subtables; sub!=NULL; ++subcnt, sub=sub->next )
5535 	    lk->all[cnt].subtables[subcnt].subtable = sub;
5536     }
5537 }
5538 
LookupInfoFree(struct lkdata * lk)5539 static void LookupInfoFree(struct lkdata *lk) {
5540     int cnt;
5541 
5542     for ( cnt=0; cnt<lk->cnt; ++cnt )
5543 	free(lk->all[cnt].subtables);
5544     free(lk->all);
5545 }
5546 
5547 #define LK_MARGIN 2
5548 
5549 struct selection_bits {
5550     int lookup_cnt, sub_cnt;	/* Number of selected lookups, and selected sub tables */
5551     int a_lookup, a_sub;	/* The index of one of those lookups, or subtables */
5552     int a_sub_lookup;		/*  the index of the lookup containing a_sub */
5553     int any_first, any_last;	/* Whether any of the selected items is first or last in its catagory */
5554     int sub_table_mergeable;	/* Can we merge the selected subtables? */
5555     int lookup_mergeable;	/* Can we merge the selected lookups? */
5556 };
5557 
LookupParseSelection(struct lkdata * lk,struct selection_bits * sel)5558 static void LookupParseSelection(struct lkdata *lk, struct selection_bits *sel) {
5559     int lookup_cnt, sub_cnt, any_first, any_last, all_one_lookup;
5560     int a_lookup, a_sub, a_sub_lookup;
5561     int sub_mergeable, lookup_mergeable;
5562     int i,j;
5563 
5564     lookup_cnt = sub_cnt = any_first = any_last = 0;
5565     all_one_lookup = a_lookup = a_sub = a_sub_lookup = -1;
5566     sub_mergeable = lookup_mergeable = true;
5567     for ( i=0; i<lk->cnt; ++i ) {
5568 	if ( lk->all[i].deleted )
5569     continue;
5570 	if ( lk->all[i].selected ) {
5571 	    ++lookup_cnt;
5572 	    if ( a_lookup==-1 )
5573 		a_lookup = i;
5574 	    else if ( lk->all[i].lookup->lookup_type!=lk->all[a_lookup].lookup->lookup_type ||
5575 		    lk->all[i].lookup->lookup_flags!=lk->all[a_lookup].lookup->lookup_flags )
5576 		lookup_mergeable = false;
5577 	    if ( i==0 ) any_first=true;
5578 	    if ( i==lk->cnt-1 ) any_last=true;
5579 	}
5580 	if ( lk->all[i].open ) {
5581 	    for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
5582 		if ( lk->all[i].subtables[j].deleted )
5583 	    continue;
5584 		if ( lk->all[i].subtables[j].selected ) {
5585 		    ++sub_cnt;
5586 		    if ( a_sub==-1 ) {
5587 			a_sub = j; a_sub_lookup = i;
5588 		    }
5589 		    if ( j==0 ) any_first = true;
5590 		    if ( j==lk->all[i].subtable_cnt-1 ) any_last = true;
5591 		    if ( lk->all[i].subtables[j].subtable->kc!=NULL ||
5592 			    lk->all[i].subtables[j].subtable->fpst!=NULL ||
5593 			    lk->all[i].subtables[j].subtable->sm!=NULL )
5594 			sub_mergeable = false;
5595 		    if ( all_one_lookup==-1 )
5596 			all_one_lookup = i;
5597 		    else if ( all_one_lookup!=i )
5598 			all_one_lookup = -2;
5599 		}
5600 	    }
5601 	}
5602     }
5603 
5604     sel->lookup_cnt = lookup_cnt;
5605     sel->sub_cnt = sub_cnt;
5606     sel->a_lookup = a_lookup;
5607     sel->a_sub = a_sub;
5608     sel->a_sub_lookup = a_sub_lookup;
5609     sel->any_first = any_first;
5610     sel->any_last = any_last;
5611     sel->sub_table_mergeable = sub_mergeable && all_one_lookup>=0 && sub_cnt>=2 && lookup_cnt==0;
5612     sel->lookup_mergeable = lookup_mergeable && lookup_cnt>=2 && sub_cnt==0;
5613 }
5614 
LookupsImportable(SplineFont * sf,int isgpos)5615 static int LookupsImportable(SplineFont *sf,int isgpos) {
5616     FontView *ofv;
5617 
5618     for ( ofv=fv_list; ofv!=NULL; ofv = (FontView *) (ofv->b.next) ) {
5619 	SplineFont *osf = ofv->b.sf;
5620 	if ( osf->cidmaster ) osf = osf->cidmaster;
5621 	if ( osf==sf || sf->cidmaster==osf )
5622     continue;
5623 	if ( (isgpos && osf->gpos_lookups!=NULL) || (!isgpos && osf->gsub_lookups!=NULL) )
5624     break;
5625     }
5626 return( ofv!=NULL );
5627 }
5628 
GFI_LookupEnableButtons(struct gfi_data * gfi,int isgpos)5629 void GFI_LookupEnableButtons(struct gfi_data *gfi, int isgpos) {
5630     struct lkdata *lk = &gfi->tables[isgpos];
5631     struct selection_bits sel;
5632 
5633     LookupParseSelection(lk,&sel);
5634 
5635     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_LookupTop),!sel.any_first &&
5636 	    sel.lookup_cnt+sel.sub_cnt==1);
5637     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_LookupUp),!sel.any_first &&
5638 	    sel.lookup_cnt+sel.sub_cnt!=0);
5639     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_LookupDown),!sel.any_last &&
5640 	    sel.lookup_cnt+sel.sub_cnt!=0);
5641     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_LookupBottom),!sel.any_last &&
5642 	    sel.lookup_cnt+sel.sub_cnt==1);
5643     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_AddLookup),
5644 	    (sel.lookup_cnt+sel.sub_cnt<=1));
5645     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_AddSubtable),
5646 	    (sel.lookup_cnt==1 && sel.sub_cnt<=1) || (sel.lookup_cnt==0 && sel.sub_cnt==1));
5647     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_EditMetadata),
5648 	    (sel.lookup_cnt==1 && sel.sub_cnt==0) ||
5649 	    (sel.lookup_cnt==0 && sel.sub_cnt==1));
5650     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_EditSubtable),sel.lookup_cnt==0 &&
5651 	    sel.sub_cnt==1);
5652     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_DeleteLookup),sel.lookup_cnt!=0 ||
5653 	    sel.sub_cnt!=0);
5654     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_MergeLookup),
5655 	    (sel.lookup_cnt>=2 && sel.sub_cnt==0 && sel.lookup_mergeable) ||
5656 	    (sel.lookup_cnt==0 && sel.sub_cnt>=2 && sel.sub_table_mergeable));
5657     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_RevertLookups),true);
5658     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_LookupSort),lk->cnt>1 );
5659 
5660     GGadgetSetEnabled(GWidgetGetControl(gfi->gw,CID_ImportLookups),
5661 	    LookupsImportable(gfi->sf,isgpos));
5662 }
5663 
GFI_LookupScrollbars(struct gfi_data * gfi,int isgpos,int refresh)5664 void GFI_LookupScrollbars(struct gfi_data *gfi, int isgpos, int refresh) {
5665     int lcnt, i,j;
5666     int width=0, wmax;
5667     GWindow gw = GDrawableGetWindow(GWidgetGetControl(gfi->gw,CID_LookupWin+isgpos));
5668     struct lkdata *lk = &gfi->tables[isgpos];
5669     GGadget *vsb = GWidgetGetControl(gfi->gw,CID_LookupVSB+isgpos);
5670     GGadget *hsb = GWidgetGetControl(gfi->gw,CID_LookupHSB+isgpos);
5671     int off_top, off_left;
5672 
5673     GDrawSetFont(gw,gfi->font);
5674     lcnt = 0;
5675     for ( i=0; i<lk->cnt; ++i ) {
5676 	if ( lk->all[i].deleted )
5677     continue;
5678 	++lcnt;
5679 	wmax = GDrawGetText8Width(gw,lk->all[i].lookup->lookup_name,-1);
5680 	if ( wmax > width ) width = wmax;
5681 	if ( lk->all[i].open ) {
5682 	    for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
5683 		if ( lk->all[i].subtables[j].deleted )
5684 	    continue;
5685 		++lcnt;
5686 		wmax = gfi->fh+GDrawGetText8Width(gw,lk->all[i].subtables[j].subtable->subtable_name,-1);
5687 		if ( wmax > width ) width = wmax;
5688 	    }
5689 	}
5690     }
5691     width += gfi->fh;
5692     GScrollBarSetBounds(vsb,0,lcnt,(gfi->lkheight-2*LK_MARGIN)/gfi->fh);
5693     GScrollBarSetBounds(hsb,0,width,gfi->lkwidth-2*LK_MARGIN);
5694     off_top = lk->off_top;
5695     if ( off_top+((gfi->lkheight-2*LK_MARGIN)/gfi->fh) > lcnt )
5696 	off_top = lcnt - (gfi->lkheight-2*LK_MARGIN)/gfi->fh;
5697     if ( off_top<0 )
5698 	off_top  = 0;
5699     off_left = lk->off_left;
5700     if ( off_left+gfi->lkwidth-2*LK_MARGIN > width )
5701 	off_left = width-(gfi->lkwidth-2*LK_MARGIN);
5702     if ( off_left<0 )
5703 	off_left  = 0;
5704     if ( off_top!=lk->off_top || off_left!=lk->off_left ) {
5705 	lk->off_top = off_top; lk->off_left = off_left;
5706 	GScrollBarSetPos(vsb,off_top);
5707 	GScrollBarSetPos(hsb,off_left);
5708 	refresh = true;
5709     }
5710     if ( refresh )
5711 	GDrawRequestExpose(gw,NULL,false);
5712 }
5713 
LookupsHScroll(GGadget * g,GEvent * event)5714 static int LookupsHScroll(GGadget *g,GEvent *event) {
5715     struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
5716     int isgpos = GGadgetGetCid(g)-CID_LookupHSB;
5717     struct lkdata *lk = &gfi->tables[isgpos];
5718     int newpos = lk->off_left;
5719     int32 sb_min, sb_max, sb_pagesize;
5720 
5721     if ( event->type!=et_controlevent || event->u.control.subtype != et_scrollbarchange )
5722 return( true );
5723 
5724     GScrollBarGetBounds(event->u.control.g,&sb_min,&sb_max,&sb_pagesize);
5725     switch( event->u.control.u.sb.type ) {
5726       case et_sb_top:
5727         newpos = 0;
5728       break;
5729       case et_sb_uppage:
5730         newpos -= 9*sb_pagesize/10;
5731       break;
5732       case et_sb_up:
5733         newpos -= sb_pagesize/15;
5734       break;
5735       case et_sb_down:
5736         newpos += sb_pagesize/15;
5737       break;
5738       case et_sb_downpage:
5739         newpos += 9*sb_pagesize/10;
5740       break;
5741       case et_sb_bottom:
5742         newpos = sb_max-sb_pagesize;
5743       break;
5744       case et_sb_thumb:
5745       case et_sb_thumbrelease:
5746         newpos = event->u.control.u.sb.pos;
5747       break;
5748       case et_sb_halfup:
5749         newpos -= sb_pagesize/30;
5750       break;
5751       case et_sb_halfdown:
5752         newpos += sb_pagesize/30;
5753       break;
5754     }
5755     if ( newpos>sb_max-sb_pagesize )
5756         newpos = sb_max-sb_pagesize;
5757     if ( newpos<0 ) newpos = 0;
5758     if ( newpos!=lk->off_left ) {
5759 	lk->off_left = newpos;
5760 	GScrollBarSetPos(event->u.control.g,newpos);
5761 	GDrawRequestExpose(GDrawableGetWindow(GWidgetGetControl(gfi->gw,CID_LookupWin+isgpos)),NULL,false);
5762     }
5763 return( true );
5764 }
5765 
LookupsVScroll(GGadget * g,GEvent * event)5766 static int LookupsVScroll(GGadget *g,GEvent *event) {
5767     struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
5768     int isgpos = GGadgetGetCid(g)-CID_LookupVSB;
5769     struct lkdata *lk = &gfi->tables[isgpos];
5770     int newpos = lk->off_top;
5771     int32 sb_min, sb_max, sb_pagesize;
5772 
5773     if ( event->type!=et_controlevent || event->u.control.subtype != et_scrollbarchange )
5774 return( true );
5775 
5776     GScrollBarGetBounds(event->u.control.g,&sb_min,&sb_max,&sb_pagesize);
5777     switch( event->u.control.u.sb.type ) {
5778       case et_sb_top:
5779         newpos = 0;
5780       break;
5781       case et_sb_uppage:
5782         newpos -= 9*sb_pagesize/10;
5783       break;
5784       case et_sb_up:
5785         --newpos;
5786       break;
5787       case et_sb_down:
5788         ++newpos;
5789       break;
5790       case et_sb_downpage:
5791         newpos += 9*sb_pagesize/10;
5792       break;
5793       case et_sb_bottom:
5794         newpos = (sb_max-sb_pagesize);
5795       break;
5796       case et_sb_thumb:
5797       case et_sb_thumbrelease:
5798         newpos = event->u.control.u.sb.pos;
5799       break;
5800     }
5801     if ( newpos>(sb_max-sb_pagesize) )
5802         newpos = (sb_max-sb_pagesize);
5803     if ( newpos<0 ) newpos = 0;
5804     if ( newpos!=lk->off_top ) {
5805 	/*int diff = newpos-lk->off_top;*/
5806 	lk->off_top = newpos;
5807 	GScrollBarSetPos(event->u.control.g,newpos);
5808 	/*GDrawScroll(GDrawableGetWindow(GWidgetGetControl(gfi->gw,CID_LookupWin+isgpos)),NULL,0,diff*gfi->fh);*/
5809 	GDrawRequestExpose(GDrawableGetWindow(GWidgetGetControl(gfi->gw,CID_LookupWin+isgpos)),NULL,false);
5810     }
5811 return( true );
5812 }
5813 
GFI_LookupOrder(GGadget * g,GEvent * e)5814 static int GFI_LookupOrder(GGadget *g, GEvent *e) {
5815 
5816     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
5817 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
5818 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
5819 	struct lkdata *lk = &gfi->tables[isgpos];
5820 	int i,j,k;
5821 	struct lkinfo temp;
5822 	struct lksubinfo temp2;
5823 	int cid = GGadgetGetCid(g);
5824 	GWindow gw = GDrawableGetWindow(GWidgetGetControl(gfi->gw,CID_LookupWin+isgpos));
5825 
5826 	if ( cid==CID_LookupTop ) {
5827 	    for ( i=0; i<lk->cnt; ++i ) {
5828 		if ( lk->all[i].deleted )
5829 	    continue;
5830 		if ( lk->all[i].selected ) {
5831 		    temp = lk->all[i];
5832 		    for ( k=i-1; k>=0; --k )
5833 			lk->all[k+1] = lk->all[k];
5834 		    lk->all[0] = temp;
5835     goto done;
5836 		}
5837 		if ( lk->all[i].open ) {
5838 		    for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
5839 			if ( lk->all[i].subtables[j].deleted )
5840 		    continue;
5841 			if ( lk->all[i].subtables[j].selected ) {
5842 			    temp2 = lk->all[i].subtables[j];
5843 			    for ( k=j-1; k>=0; --k )
5844 				lk->all[i].subtables[k+1] = lk->all[i].subtables[k];
5845 			    lk->all[i].subtables[0] = temp2;
5846     goto done;
5847 			}
5848 		    }
5849 		}
5850 	    }
5851 	} else if ( cid==CID_LookupBottom ) {
5852 	    for ( i=0; i<lk->cnt; ++i ) {
5853 		if ( lk->all[i].deleted )
5854 	    continue;
5855 		if ( lk->all[i].selected ) {
5856 		    temp = lk->all[i];
5857 		    for ( k=i; k<lk->cnt-1; ++k )
5858 			lk->all[k] = lk->all[k+1];
5859 		    lk->all[lk->cnt-1] = temp;
5860     goto done;
5861 		}
5862 		if ( lk->all[i].open ) {
5863 		    for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
5864 			if ( lk->all[i].subtables[j].deleted )
5865 		    continue;
5866 			if ( lk->all[i].subtables[j].selected ) {
5867 			    temp2 = lk->all[i].subtables[j];
5868 			    for ( k=j; k<lk->all[i].subtable_cnt-1; ++k )
5869 				lk->all[i].subtables[k] = lk->all[i].subtables[k+1];
5870 			    lk->all[i].subtables[lk->all[i].subtable_cnt-1] = temp2;
5871     goto done;
5872 			}
5873 		    }
5874 		}
5875 	    }
5876 	} else if ( cid==CID_LookupUp ) {
5877 	    for ( i=0; i<lk->cnt; ++i ) {
5878 		if ( lk->all[i].deleted )
5879 	    continue;
5880 		if ( lk->all[i].selected && i!=0 ) {
5881 		    temp = lk->all[i];
5882 		    lk->all[i] = lk->all[i-1];
5883 		    lk->all[i-1] = temp;
5884 		}
5885 		if ( lk->all[i].open ) {
5886 		    for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
5887 			if ( lk->all[i].subtables[j].deleted )
5888 		    continue;
5889 			if ( lk->all[i].subtables[j].selected && j!=0 ) {
5890 			    temp2 = lk->all[i].subtables[j];
5891 			    lk->all[i].subtables[j] = lk->all[i].subtables[j-1];
5892 			    lk->all[i].subtables[j-1] = temp2;
5893 			}
5894 		    }
5895 		}
5896 	    }
5897 	} else if ( cid==CID_LookupDown ) {
5898 	    for ( i=lk->cnt-1; i>=0; --i ) {
5899 		if ( lk->all[i].deleted )
5900 	    continue;
5901 		if ( lk->all[i].selected && i!=lk->cnt-1 ) {
5902 		    temp = lk->all[i];
5903 		    lk->all[i] = lk->all[i+1];
5904 		    lk->all[i+1] = temp;
5905 		}
5906 		if ( lk->all[i].open ) {
5907 		    for ( j=lk->all[i].subtable_cnt-1; j>=0; --j ) {
5908 			if ( lk->all[i].subtables[j].deleted )
5909 		    continue;
5910 			if ( lk->all[i].subtables[j].selected && j!=lk->all[i].subtable_cnt-1 ) {
5911 			    temp2 = lk->all[i].subtables[j];
5912 			    lk->all[i].subtables[j] = lk->all[i].subtables[j+1];
5913 			    lk->all[i].subtables[j+1] = temp2;
5914 			}
5915 		    }
5916 		}
5917 	    }
5918 	}
5919     done:
5920 	GFI_LookupEnableButtons(gfi,isgpos);
5921 	GDrawRequestExpose(gw,NULL,false);
5922     }
5923 return( true );
5924 }
5925 
GFI_LookupSort(GGadget * g,GEvent * e)5926 static int GFI_LookupSort(GGadget *g, GEvent *e) {
5927 
5928     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
5929 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
5930 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
5931 	struct lkdata *lk = &gfi->tables[isgpos];
5932 	struct lkinfo temp;
5933 	int i,j;
5934 
5935 	for ( i=0; i<lk->cnt; ++i ) {
5936 	    int order = FeatureOrderId(isgpos,lk->all[i].lookup->features);
5937 	    for ( j=i+1; j<lk->cnt; ++j ) {
5938 		int jorder = FeatureOrderId(isgpos,lk->all[j].lookup->features);
5939 		if ( order>jorder) {
5940 		    temp = lk->all[i];
5941 		    lk->all[i] = lk->all[j];
5942 		    lk->all[j] = temp;
5943 		    order = jorder;
5944 		}
5945 	    }
5946 	}
5947 	GDrawRequestExpose(GDrawableGetWindow(GWidgetGetControl(gfi->gw,CID_LookupWin+isgpos)),NULL,false);
5948 	GFI_LookupEnableButtons(gfi,isgpos);
5949     }
5950 return( true );
5951 }
5952 
5953 /* ??? *//* How about a series of buttons to show only by lookup_type, feat-tag, script-tag */
5954 
GFI_FinishContextNew(struct gfi_data * d,FPST * fpst,int success)5955 void GFI_FinishContextNew(struct gfi_data *d,FPST *fpst, int success) {
5956     OTLookup *otl;
5957     struct lookup_subtable *sub, *prev;
5958     FPST *ftest, *fprev;
5959 
5960     if ( !success ) {
5961 	/* We can't allow incomplete FPSTs to float around */
5962 	/* If they didn't fill it in, delete it */
5963 	otl = fpst->subtable->lookup;
5964 	prev = NULL;
5965 	for ( sub=otl->subtables; sub!=NULL && sub!=fpst->subtable; prev = sub, sub=sub->next );
5966 	if ( sub!=NULL ) {
5967 	    if ( prev==NULL )
5968 		otl->subtables = sub->next;
5969 	    else
5970 		prev->next = sub->next;
5971 	    free(sub->subtable_name);
5972 	    chunkfree(sub,sizeof(struct lookup_subtable));
5973 	}
5974 	fprev = NULL;
5975 	for ( ftest=d->sf->possub; ftest!=NULL && ftest!=fpst; fprev = ftest, ftest=ftest->next );
5976 	if ( ftest!=NULL ) {
5977 	    if ( fprev==NULL )
5978 		d->sf->possub = fpst->next;
5979 	    else
5980 		fprev->next = fpst->next;
5981 	}
5982 
5983 	chunkfree(fpst,sizeof(FPST));
5984     }
5985 }
5986 
GFI_FinishSMNew(struct gfi_data * d,ASM * sm,int success,int isnew)5987 void GFI_FinishSMNew(struct gfi_data *d,ASM *sm, int success, int isnew) {
5988     OTLookup *otl;
5989     struct lookup_subtable *sub, *prev;
5990     ASM *smtest, *smprev;
5991 
5992     if ( !success && isnew ) {
5993 	/* We can't allow incomplete state machines floating around */
5994 	/* If they didn't fill it in, delete it */
5995 	otl = sm->subtable->lookup;
5996 	prev = NULL;
5997 	for ( sub=otl->subtables; sub!=NULL && sub!=sm->subtable; prev = sub, sub=sub->next );
5998 	if ( sub!=NULL ) {
5999 	    if ( prev==NULL )
6000 		otl->subtables = sub->next;
6001 	    else
6002 		prev->next = sub->next;
6003 	    free(sub->subtable_name);
6004 	    chunkfree(sub,sizeof(struct lookup_subtable));
6005 	}
6006 	smprev = NULL;
6007 	for ( smtest=d->sf->sm; smtest!=NULL && smtest!=sm; smprev = smtest, smtest=smtest->next );
6008 	if ( smtest!=NULL ) {
6009 	    if ( smprev==NULL )
6010 		d->sf->sm = sm->next;
6011 	    else
6012 		smprev->next = sm->next;
6013 	}
6014 	chunkfree(sm,sizeof(ASM));
6015     }
6016 }
6017 
LookupSubtableContents(struct gfi_data * gfi,int isgpos)6018 static void LookupSubtableContents(struct gfi_data *gfi,int isgpos) {
6019     struct lkdata *lk = &gfi->tables[isgpos];
6020     int i,j;
6021 
6022     for ( i=0; i<lk->cnt; ++i ) {
6023 	if ( lk->all[i].deleted )
6024     continue;
6025 	if ( lk->all[i].open ) {
6026 	    for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
6027 		if ( lk->all[i].subtables[j].deleted )
6028 	    continue;
6029 		if ( lk->all[i].subtables[j].selected ) {
6030 		    _LookupSubtableContents(gfi->sf,lk->all[i].subtables[j].subtable,NULL,gfi->def_layer);
6031 return;
6032 		}
6033 	    }
6034 	}
6035     }
6036 }
6037 
GFI_LookupEditSubtableContents(GGadget * g,GEvent * e)6038 static int GFI_LookupEditSubtableContents(GGadget *g, GEvent *e) {
6039 
6040     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
6041 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
6042 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6043 	LookupSubtableContents(gfi,isgpos);
6044     }
6045 return( true );
6046 }
6047 
GFI_LookupAddLookup(GGadget * g,GEvent * e)6048 static int GFI_LookupAddLookup(GGadget *g, GEvent *e) {
6049 
6050     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
6051 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
6052 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6053 	struct lkdata *lk = &gfi->tables[isgpos];
6054 	int i,j,k,lcnt;
6055 	OTLookup *otl = chunkalloc(sizeof(OTLookup)), *test;
6056 
6057 	k = 0;
6058 	for ( test = isgpos ? gfi->sf->gpos_lookups : gfi->sf->gsub_lookups;
6059 		test!=NULL; test = test->next )
6060 	    ++k;
6061 	otl->lookup_index = k;
6062 
6063 	if ( !EditLookup(otl,isgpos,gfi->sf)) {
6064 	    chunkfree(otl,sizeof(OTLookup));
6065 return( true );
6066 	}
6067 	for ( i=lk->cnt-1; i>=0; --i ) {
6068 	    if ( !lk->all[i].deleted && lk->all[i].selected ) {
6069 		lk->all[i].selected = false;
6070 	break;
6071 	    }
6072 	    if ( !lk->all[i].deleted && lk->all[i].open ) {
6073 		for ( j=0; j<lk->all[i].subtable_cnt; ++j )
6074 		    if ( !lk->all[i].subtables[j].deleted &&
6075 			    lk->all[i].subtables[j].selected ) {
6076 			lk->all[i].subtables[j].selected = false;
6077 		break;
6078 		    }
6079 		if ( j<lk->all[i].subtable_cnt )
6080 	break;
6081 	    }
6082 	}
6083 	if ( lk->cnt>=lk->max )
6084 	    lk->all = realloc(lk->all,(lk->max+=10)*sizeof(struct lkinfo));
6085 	for ( k=lk->cnt; k>i+1; --k )
6086 	    lk->all[k] = lk->all[k-1];
6087 	memset(&lk->all[k],0,sizeof(struct lkinfo));
6088 	lk->all[k].lookup = otl;
6089 	lk->all[k].new = true;
6090 	lk->all[k].selected = true;
6091 	++lk->cnt;
6092 	if ( isgpos ) {
6093 	    otl->next = gfi->sf->gpos_lookups;
6094 	    gfi->sf->gpos_lookups = otl;
6095 	} else {
6096 	    otl->next = gfi->sf->gsub_lookups;
6097 	    gfi->sf->gsub_lookups = otl;
6098 	}
6099 
6100 	/* Make sure the window is scrolled to display the new lookup */
6101 	lcnt=0;
6102 	for ( i=0; i<lk->cnt; ++i ) {
6103 	    if ( lk->all[i].deleted )
6104 	continue;
6105 	    if ( i==k )
6106 	break;
6107 	    ++lcnt;
6108 	    for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
6109 		if ( lk->all[i].subtables[j].deleted )
6110 	    continue;
6111 		++lcnt;
6112 	    }
6113 	}
6114 	if ( lcnt<lk->off_top || lcnt>=lk->off_top+(gfi->lkheight-2*LK_MARGIN)/gfi->fh )
6115 	    lk->off_top = lcnt;
6116 
6117 	GFI_LookupScrollbars(gfi,isgpos, true);
6118 	GFI_LookupEnableButtons(gfi,isgpos);
6119     }
6120 return( true );
6121 }
6122 
GFI_LookupAddSubtable(GGadget * g,GEvent * e)6123 static int GFI_LookupAddSubtable(GGadget *g, GEvent *e) {
6124 
6125     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
6126 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
6127 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6128 	struct lkdata *lk = &gfi->tables[isgpos];
6129 	int i,j,k,lcnt;
6130 	struct lookup_subtable *sub;
6131 
6132 	lcnt = 0;
6133 	for ( i=0; i<lk->cnt; ++i ) {
6134 	    if ( lk->all[i].deleted )
6135 	continue;
6136 	    j = -1;
6137 	    ++lcnt;
6138 	    if ( lk->all[i].selected )
6139 	break;
6140 	    for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
6141 		if ( lk->all[i].subtables[j].deleted )
6142 	    continue;
6143 		++lcnt;
6144 		if ( lk->all[i].subtables[j].selected )
6145 	goto break_2_loops;
6146 	    }
6147 	}
6148 	break_2_loops:
6149 	if ( i==lk->cnt )
6150 return( true );
6151 
6152 	sub = chunkalloc(sizeof(struct lookup_subtable));
6153 	sub->lookup = lk->all[i].lookup;
6154 	if ( !EditSubtable(sub,isgpos,gfi->sf,NULL,gfi->def_layer)) {
6155 	    chunkfree(sub,sizeof(struct lookup_subtable));
6156 return( true );
6157 	}
6158 	if ( lk->all[i].subtable_cnt>=lk->all[i].subtable_max )
6159 	    lk->all[i].subtables = realloc(lk->all[i].subtables,(lk->all[i].subtable_max+=10)*sizeof(struct lksubinfo));
6160 	for ( k=lk->all[i].subtable_cnt; k>j+1; --k )
6161 	    lk->all[i].subtables[k] = lk->all[i].subtables[k-1];
6162 	memset(&lk->all[i].subtables[k],0,sizeof(struct lksubinfo));
6163 	lk->all[i].subtables[k].subtable = sub;
6164 	lk->all[i].subtables[k].new = true;
6165 	sub->next = lk->all[i].lookup->subtables;
6166 	lk->all[i].lookup->subtables = sub;
6167 	++lk->all[i].subtable_cnt;
6168 
6169 	/* Make sure the window is scrolled to display the new subtable */
6170 	if ( lcnt<lk->off_top || lcnt>=lk->off_top+(gfi->lkheight-2*LK_MARGIN)/gfi->fh )
6171 	    lk->off_top = lcnt;
6172 
6173 	GFI_LookupScrollbars(gfi,isgpos, true);
6174 	GFI_LookupEnableButtons(gfi,isgpos);
6175     }
6176 return( true );
6177 }
6178 
GFI_LookupEditMetadata(GGadget * g,GEvent * e)6179 static int GFI_LookupEditMetadata(GGadget *g, GEvent *e) {
6180 
6181     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
6182 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
6183 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6184 	struct lkdata *lk = &gfi->tables[isgpos];
6185 	int i,j;
6186 
6187 	for ( i=0; i<lk->cnt; ++i ) {
6188 	    if ( lk->all[i].deleted )
6189 	continue;
6190 	    if ( lk->all[i].selected ) {
6191 		EditLookup(lk->all[i].lookup,isgpos,gfi->sf);
6192 		GDrawRequestExpose(GDrawableGetWindow(GWidgetGetControl(gfi->gw,CID_LookupWin+isgpos)),NULL,false);
6193 return( true );
6194 	    } else if ( lk->all[i].open ) {
6195 		for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
6196 		    if ( lk->all[i].subtables[j].deleted )
6197 		continue;
6198 		    if ( lk->all[i].subtables[j].selected ) {
6199 			EditSubtable(lk->all[i].subtables[j].subtable,isgpos,gfi->sf,NULL,gfi->def_layer);
6200 			GDrawRequestExpose(GDrawableGetWindow(GWidgetGetControl(gfi->gw,CID_LookupWin+isgpos)),NULL,false);
6201 return( true );
6202 		    }
6203 		}
6204 	    }
6205 	}
6206     }
6207 return( true );
6208 }
6209 
GFI_LookupMergeLookup(GGadget * g,GEvent * e)6210 static int GFI_LookupMergeLookup(GGadget *g, GEvent *e) {
6211 
6212     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
6213 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
6214 	char *buts[3];
6215 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6216 	struct lkdata *lk = &gfi->tables[isgpos];
6217 	struct selection_bits sel;
6218 	int i,j;
6219 	struct lkinfo *lkfirst;
6220 	struct lksubinfo *sbfirst;
6221 	struct lookup_subtable *sub;
6222 
6223 	LookupParseSelection(lk,&sel);
6224 	if ( !sel.sub_table_mergeable && !sel.lookup_mergeable )
6225 return( true );
6226 
6227 	buts[0] = _("Do it");
6228 	buts[1] = _("_Cancel");
6229 	buts[2] = NULL;
6230 	if ( gwwv_ask(_("Cannot be Undone"),(const char **) buts,0,1,_("The Merge operation cannot be reverted.\nDo it anyway?"))==1 )
6231 return( true );
6232 	if ( sel.lookup_mergeable ) {
6233 	    lkfirst = NULL;
6234 	    for ( i=0; i<lk->cnt; ++i ) {
6235 		if ( lk->all[i].selected && !lk->all[i].deleted ) {
6236 		    if ( lkfirst==NULL )
6237 			lkfirst = &lk->all[i];
6238 		    else {
6239 			FLMerge(lkfirst->lookup,lk->all[i].lookup);
6240 			if ( lkfirst->subtable_cnt+lk->all[i].subtable_cnt >= lkfirst->subtable_max )
6241 			    lkfirst->subtables = realloc(lkfirst->subtables,(lkfirst->subtable_max+=lk->all[i].subtable_cnt)*sizeof(struct lksubinfo));
6242 			memcpy(lkfirst->subtables+lkfirst->subtable_cnt,
6243 				lk->all[i].subtables,lk->all[i].subtable_cnt*sizeof(struct lksubinfo));
6244 			lkfirst->subtable_cnt += lk->all[i].subtable_cnt;
6245 			for ( j=0; j<lk->all[i].subtable_cnt; ++j )
6246 			    lk->all[i].subtables[j].subtable->lookup = lkfirst->lookup;
6247 			if ( lk->all[i].lookup->subtables!=NULL ) {
6248 			    for ( sub = lk->all[i].lookup->subtables; sub->next!=NULL; sub = sub->next );
6249 			    sub->next = lkfirst->lookup->subtables;
6250 			    lkfirst->lookup->subtables = lk->all[i].lookup->subtables;
6251 			    lk->all[i].lookup->subtables = NULL;
6252 			}
6253 			lk->all[i].subtable_cnt = 0;
6254 			lk->all[i].deleted = true;
6255 			lk->all[i].open = false;
6256 			lk->all[i].selected = false;
6257 		    }
6258 		}
6259 	    }
6260 	} else if ( sel.sub_table_mergeable ) {
6261 	    sbfirst = NULL;
6262 	    for ( i=0; i<lk->cnt; ++i ) if ( !lk->all[i].deleted && lk->all[i].open ) {
6263 		for ( j=0; j<lk->all[i].subtable_cnt; ++j ) if ( !lk->all[i].subtables[j].deleted ) {
6264 		    if ( lk->all[i].subtables[j].selected ) {
6265 			if ( sbfirst == NULL )
6266 			    sbfirst = &lk->all[i].subtables[j];
6267 			else {
6268 			    SFSubTablesMerge(gfi->sf,sbfirst->subtable,lk->all[i].subtables[j].subtable);
6269 			    lk->all[i].subtables[j].deleted = true;
6270 			    lk->all[i].subtables[j].selected = false;
6271 			}
6272 		    }
6273 		}
6274 		if ( sbfirst!=NULL )	/* Can only merge subtables within a lookup, so if we found anything, in a lookup that's everything */
6275 	    break;
6276 	    }
6277 	}
6278 	GFI_LookupScrollbars(gfi,isgpos, true);
6279 	GFI_LookupEnableButtons(gfi,isgpos);
6280     }
6281 return( true );
6282 }
6283 
GFI_LookupDeleteLookup(GGadget * g,GEvent * e)6284 static int GFI_LookupDeleteLookup(GGadget *g, GEvent *e) {
6285 
6286     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
6287 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
6288 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6289 	struct lkdata *lk = &gfi->tables[isgpos];
6290 	int i,j;
6291 
6292 	for ( i=0; i<lk->cnt; ++i ) {
6293 	    if ( lk->all[i].deleted )
6294 	continue;
6295 	    if ( lk->all[i].selected )
6296 		lk->all[i].deleted = true;
6297 	    else if ( lk->all[i].open ) {
6298 		for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
6299 		    if ( lk->all[i].subtables[j].deleted )
6300 		continue;
6301 		    if ( lk->all[i].subtables[j].selected )
6302 			lk->all[i].subtables[j].deleted = true;
6303 		}
6304 	    }
6305 	}
6306 
6307 	GFI_LookupScrollbars(gfi,isgpos, true);
6308 	GFI_LookupEnableButtons(gfi,isgpos);
6309     }
6310 
6311 return( true );
6312 }
6313 
GFI_LookupRevertLookup(GGadget * g,GEvent * e)6314 static int GFI_LookupRevertLookup(GGadget *g, GEvent *e) {
6315 
6316     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
6317 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
6318 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6319 	struct lkdata *lk = &gfi->tables[isgpos];
6320 	int i,j;
6321 
6322 	/* First remove any new lookups, subtables */
6323 	for ( i=0; i<lk->cnt; ++i ) {
6324 	    if ( lk->all[i].new )
6325 		SFRemoveLookup(gfi->sf,lk->all[i].lookup,0);
6326 	    else {
6327 		for ( j=0; j<lk->all[i].subtable_cnt; ++j )
6328 		    if ( lk->all[i].subtables[j].new )
6329 			SFRemoveLookupSubTable(gfi->sf,lk->all[i].subtables[j].subtable,0);
6330 	    }
6331 	}
6332 
6333 	/* Now since we didn't actually delete anything we don't need to do */
6334 	/*  anything to resurrect them */
6335 
6336 	/* Finally we need to restore the original order. */
6337 	/* But that just means regenerating the lk structure. So free it and */
6338 	/*  regenerate it */
6339 
6340 	LookupInfoFree(lk);
6341 	LookupSetup(lk,isgpos?gfi->sf->gpos_lookups:gfi->sf->gsub_lookups);
6342 
6343 	GFI_LookupScrollbars(gfi,isgpos, true);
6344 	GFI_LookupEnableButtons(gfi,isgpos);
6345     }
6346 return( true );
6347 }
6348 
import_e_h(GWindow gw,GEvent * event)6349 static int import_e_h(GWindow gw, GEvent *event) {
6350     int *done = GDrawGetUserData(gw);
6351 
6352     if ( event->type==et_close ) {
6353 	*done = true;
6354     } else if ( event->type==et_char ) {
6355 	if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
6356 	    help("ui/dialogs/fontinfo.html", "#fontinfo-lookups");
6357 return( true );
6358 	}
6359 return( false );
6360     } else if ( event->type==et_controlevent ) {
6361 	if ( event->u.control.subtype == et_buttonactivate ) {
6362 	    switch ( GGadgetGetCid(event->u.control.g)) {
6363 	      case CID_OK:
6364 		*done = 2;
6365 	      break;
6366 	      case CID_Cancel:
6367 		*done = true;
6368 	      break;
6369 	    }
6370 	} else if ( event->u.control.subtype == et_listdoubleclick )
6371 	    *done = 2;
6372     }
6373 return( true );
6374 }
6375 
GFI_LookupImportLookup(GGadget * g,GEvent * e)6376 static int GFI_LookupImportLookup(GGadget *g, GEvent *e) {
6377 
6378     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
6379 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
6380 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6381 	FontView *ofv;
6382 	SplineFont *osf;
6383 	OTLookup *otl;
6384 	int i, j, cnt;
6385 	GTextInfo *ti;
6386 	GGadgetCreateData gcd[7], *varray[8], *harray[7];
6387 	GTextInfo label[7];
6388 	GWindowAttrs wattrs;
6389 	GRect pos;
6390 	GWindow gw;
6391 	int done = 0;
6392 
6393 	/* Figure out what lookups can be imported from which (open) fonts */
6394 	ti = NULL;
6395 	for ( j=0; j<2; ++j ) {
6396 	    for ( ofv=fv_list; ofv!=NULL; ofv=(FontView *) (ofv->b.next) ) {
6397 		osf = ofv->b.sf;
6398 		if ( osf->cidmaster ) osf = osf->cidmaster;
6399 		osf->ticked = false;
6400 	    }
6401 	    cnt = 0;
6402 	    for ( ofv=fv_list; ofv!=NULL; ofv=(FontView *) (ofv->b.next) ) {
6403 		osf = ofv->b.sf;
6404 		if ( osf->cidmaster ) osf = osf->cidmaster;
6405 		if ( osf->ticked || osf==gfi->sf || osf==gfi->sf->cidmaster ||
6406 			( isgpos && osf->gpos_lookups==NULL) ||
6407 			(!isgpos && osf->gsub_lookups==NULL) )
6408 	    continue;
6409 		osf->ticked = true;
6410 		if ( cnt!=0 ) {
6411 		    if ( ti )
6412 			ti[cnt].line = true;
6413 		    ++cnt;
6414 		}
6415 		if ( ti ) {
6416 		    ti[cnt].text = (unichar_t *) copy( osf->fontname );
6417 		    ti[cnt].text_is_1byte = true;
6418 		    ti[cnt].disabled = true;
6419 		    ti[cnt].userdata = osf;
6420 		}
6421 		++cnt;
6422 		for ( otl = isgpos ? osf->gpos_lookups : osf->gsub_lookups; otl!=NULL; otl=otl->next ) {
6423 		    if ( ti ) {
6424 			ti[cnt].text = (unichar_t *) strconcat( " ", otl->lookup_name );
6425 			ti[cnt].text_is_1byte = true;
6426 			ti[cnt].userdata = otl;
6427 		    }
6428 		    ++cnt;
6429 		}
6430 	    }
6431 	    if ( ti==NULL )
6432 		ti = calloc((cnt+1),sizeof(GTextInfo));
6433 	}
6434 
6435 	memset(gcd,0,sizeof(gcd));
6436 	memset(label,0,sizeof(label));
6437 
6438 	i = 0;
6439 	label[i].text = (unichar_t *) _("Select lookups from other fonts");
6440 	label[i].text_is_1byte = true;
6441 	label[i].text_in_resource = true;
6442 	gcd[i].gd.label = &label[i];
6443 	gcd[i].gd.pos.x = 12; gcd[i].gd.pos.y = 6+6;
6444 	gcd[i].gd.flags = gg_visible | gg_enabled;
6445 	gcd[i].creator = GLabelCreate;
6446 	varray[0] = &gcd[i++]; varray[1] = NULL;
6447 
6448 	gcd[i].gd.pos.height = 12*12+6;
6449 	gcd[i].gd.flags = gg_enabled|gg_visible|gg_list_multiplesel;
6450 	gcd[i].gd.u.list = ti;
6451 	gcd[i].creator = GListCreate;
6452 	varray[2] = &gcd[i++]; varray[3] = NULL;
6453 
6454 	gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_default;
6455 	label[i].text = (unichar_t *) _("_Import");
6456 	label[i].text_is_1byte = true;
6457 	label[i].text_in_resource = true;
6458 	gcd[i].gd.label = &label[i];
6459 	gcd[i].gd.cid = CID_OK;
6460 	harray[0] = GCD_Glue; harray[1] = &gcd[i]; harray[2] = GCD_Glue;
6461 	gcd[i++].creator = GButtonCreate;
6462 
6463 	gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
6464 	label[i].text = (unichar_t *) _("_Cancel");
6465 	label[i].text_is_1byte = true;
6466 	label[i].text_in_resource = true;
6467 	gcd[i].gd.label = &label[i];
6468 	gcd[i].gd.cid = CID_Cancel;
6469 	harray[3] = GCD_Glue; harray[4] = &gcd[i]; harray[5] = GCD_Glue; harray[6] = NULL;
6470 	gcd[i++].creator = GButtonCreate;
6471 
6472 	gcd[i].gd.flags = gg_enabled|gg_visible;
6473 	gcd[i].gd.u.boxelements = harray;
6474 	gcd[i].creator = GHBoxCreate;
6475 	varray[4] = &gcd[i++]; varray[5] = NULL; varray[6] = NULL;
6476 
6477 	gcd[i].gd.pos.x = gcd[i].gd.pos.y = 2;
6478 	gcd[i].gd.flags = gg_enabled|gg_visible;
6479 	gcd[i].gd.u.boxelements = varray;
6480 	gcd[i].creator = GHVGroupCreate;
6481 
6482 	memset(&wattrs,0,sizeof(wattrs));
6483 	wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
6484 	wattrs.event_masks = ~(1<<et_charup);
6485 	wattrs.restrict_input_to_me = 1;
6486 	wattrs.undercursor = 1;
6487 	wattrs.cursor = ct_pointer;
6488 	wattrs.utf8_window_title =  _("Import Lookup");
6489 	wattrs.is_dlg = true;
6490 	pos.x = pos.y = 0;
6491 	pos.width = GGadgetScale(GDrawPointsToPixels(NULL,150));
6492 	pos.height = GDrawPointsToPixels(NULL,193);
6493 	gw = GDrawCreateTopWindow(NULL,&pos,import_e_h,&done,&wattrs);
6494 
6495 	GGadgetsCreate(gw,&gcd[i]);
6496 	GHVBoxSetExpandableRow(gcd[i].ret,1);
6497 	GHVBoxSetExpandableCol(gcd[i-1].ret,gb_expandgluesame);
6498 	GHVBoxFitWindow(gcd[i].ret);
6499 	GTextInfoListFree(ti);
6500 	GDrawSetVisible(gw,true);
6501 
6502 	while ( !done )
6503 	    GDrawProcessOneEvent(NULL);
6504 	if ( done==2 ) {
6505 	    int32 len;
6506 	    GTextInfo **ti = GGadgetGetList(gcd[1].ret,&len);
6507 	    OTLookup **list = malloc((len+1)*sizeof(OTLookup*));
6508 	    struct lkdata *lk = &gfi->tables[isgpos];
6509 	    OTLookup *before = NULL;
6510 
6511 	    for ( i=0; i<lk->cnt; ++i ) {
6512 		if ( lk->all[i].deleted )
6513 	    continue;
6514 		if ( lk->all[i].selected ) {
6515 		    before = lk->all[i].lookup;
6516 	    break;
6517 		}
6518 	    }
6519 	    osf = NULL;
6520 	    for ( i=0; i<len; ++i ) {
6521 		if ( ti[i]->disabled )
6522 		    osf = ti[i]->userdata;
6523 		else if ( ti[i]->selected && ti[i]->text!=NULL ) {
6524 		    for ( j=0; i+j<len && !ti[i+j]->disabled &&
6525 			    ti[i+j]->selected && ti[i+j]->text; ++j )
6526 			list[j] = (OTLookup *) ti[i+j]->userdata;
6527 		    list[j] = NULL;
6528 		    OTLookupsCopyInto(gfi->sf,osf,list,before);
6529 		    i += j-1;
6530 		}
6531 	    }
6532 	    free(list);
6533 	}
6534 	GDrawDestroyWindow(gw);
6535 
6536 	GFI_LookupScrollbars(gfi,isgpos, true);
6537 	GFI_LookupEnableButtons(gfi,isgpos);
6538     }
6539 return( true );
6540 }
6541 
GFI_LookupAspectChange(GGadget * g,GEvent * e)6542 static int GFI_LookupAspectChange(GGadget *g, GEvent *e) {
6543 
6544     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
6545 	struct gfi_data *gfi = GDrawGetUserData(GGadgetGetWindow(g));
6546 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6547 	GFI_LookupEnableButtons(gfi,isgpos);
6548     }
6549 return( true );
6550 }
6551 
LookupExpose(GWindow pixmap,struct gfi_data * gfi,int isgpos)6552 static void LookupExpose(GWindow pixmap, struct gfi_data *gfi, int isgpos) {
6553     int lcnt, i,j;
6554     struct lkdata *lk = &gfi->tables[isgpos];
6555     GRect r, old;
6556     extern GBox _ggadget_Default_Box;
6557 
6558     r.x = LK_MARGIN; r.width = gfi->lkwidth-2*LK_MARGIN;
6559     r.y = LK_MARGIN; r.height = gfi->lkheight-2*LK_MARGIN;
6560     GDrawPushClip(pixmap,&r,&old);
6561     GDrawSetFont(pixmap,gfi->font);
6562 
6563     lcnt = 0;
6564     for ( i=0; i<lk->cnt; ++i ) {
6565 	if ( lk->all[i].deleted )
6566     continue;
6567 	if ( lcnt>=lk->off_top ) {
6568 	    if ( lk->all[i].selected ) {
6569 		r.x = LK_MARGIN; r.width = gfi->lkwidth-2*LK_MARGIN;
6570 		r.y = (lcnt-lk->off_top)*gfi->fh; r.height = gfi->fh;
6571 		GDrawFillRect(pixmap,&r,ACTIVE_BORDER);
6572 	    }
6573 	    r.x = LK_MARGIN-lk->off_left; r.width = (gfi->as&~1);
6574 	    r.y = LK_MARGIN+(lcnt-lk->off_top)*gfi->fh; r.height = r.width;
6575 	    GDrawDrawRect(pixmap,&r,0x000000);
6576 	    GDrawDrawLine(pixmap,r.x+2,r.y+(r.height/2), r.x+r.width-2,r.y+(r.height/2), 0x000000);
6577 	    if ( !lk->all[i].open )
6578 		GDrawDrawLine(pixmap,r.x+(r.width/2),r.y+2, r.x+(r.width/2),r.y+r.height-2, 0x000000);
6579 	    GDrawDrawText8(pixmap,r.x+gfi->fh, r.y+gfi->as,
6580 		    lk->all[i].lookup->lookup_name,-1,MAIN_FOREGROUND);
6581 	}
6582 	++lcnt;
6583 	if ( lk->all[i].open ) {
6584 	    for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
6585 		if ( lk->all[i].subtables[j].deleted )
6586 	    continue;
6587 		if ( lcnt>=lk->off_top ) {
6588 		    if ( lk->all[i].subtables[j].selected ) {
6589 			r.x = LK_MARGIN; r.width = gfi->lkwidth-2*LK_MARGIN;
6590 			r.y = LK_MARGIN+(lcnt-lk->off_top)*gfi->fh; r.height = gfi->fh;
6591 			GDrawFillRect(pixmap,&r,ACTIVE_BORDER);
6592 		    }
6593 		    r.x = LK_MARGIN+2*gfi->fh-lk->off_left;
6594 		    r.y = LK_MARGIN+(lcnt-lk->off_top)*gfi->fh;
6595 		    GDrawDrawText8(pixmap,r.x, r.y+gfi->as,
6596 			    lk->all[i].subtables[j].subtable->subtable_name,-1,MAIN_FOREGROUND);
6597 		}
6598 		++lcnt;
6599 	    }
6600 	}
6601     }
6602     GDrawPopClip(pixmap,&old);
6603 }
6604 
LookupDeselect(struct lkdata * lk)6605 static void LookupDeselect(struct lkdata *lk) {
6606     int i,j;
6607 
6608     for ( i=0; i<lk->cnt; ++i ) {
6609 	lk->all[i].selected = false;
6610 	for ( j=0; j<lk->all[i].subtable_cnt; ++j )
6611 	    lk->all[i].subtables[j].selected = false;
6612     }
6613 }
6614 
LookupPopup(GWindow gw,OTLookup * otl,struct lookup_subtable * sub,struct lkdata * lk)6615 static void LookupPopup(GWindow gw,OTLookup *otl,struct lookup_subtable *sub,
6616 	struct lkdata *lk) {
6617     static char popup_msg[600];
6618     int pos;
6619     char *lookuptype;
6620     FeatureScriptLangList *fl;
6621     struct scriptlanglist *sl;
6622     int l;
6623 
6624     if ( (otl->lookup_type&0xff)>= 0xf0 ) {
6625 	if ( otl->lookup_type==kern_statemachine )
6626 	    lookuptype = _("Kerning State Machine");
6627 	else if ( otl->lookup_type==morx_indic )
6628 	    lookuptype = _("Indic State Machine");
6629 	else if ( otl->lookup_type==morx_context )
6630 	    lookuptype = _("Contextual State Machine");
6631 	else
6632 	    lookuptype = _("Contextual State Machine");
6633     } else if ( (otl->lookup_type>>8)<2 && (otl->lookup_type&0xff)<10 )
6634 	lookuptype = _(lookup_type_names[otl->lookup_type>>8][otl->lookup_type&0xff]);
6635     else
6636 	lookuptype = S_("LookupType|Unknown");
6637     snprintf(popup_msg,sizeof(popup_msg), "%s\n", lookuptype);
6638     pos = strlen(popup_msg);
6639 
6640     if ( sub!=NULL && otl->lookup_type==gpos_pair && sub->kc!=NULL ) {
6641 	snprintf(popup_msg+pos,sizeof(popup_msg)-pos,"%s",_("(kerning class)\n") );
6642 	pos += strlen( popup_msg+pos );
6643     }
6644 
6645     if ( otl->features==NULL )
6646 	snprintf(popup_msg+pos,sizeof(popup_msg)-pos,"%s",_("Not attached to a feature"));
6647     else {
6648 	for ( fl=otl->features; fl!=NULL && pos<sizeof(popup_msg)-2; fl=fl->next ) {
6649 	    snprintf(popup_msg+pos,sizeof(popup_msg)-pos,"%c%c%c%c: ",
6650 		    fl->featuretag>>24, fl->featuretag>>16,
6651 		    fl->featuretag>>8, fl->featuretag&0xff );
6652 	    pos += strlen( popup_msg+pos );
6653 	    for ( sl=fl->scripts; sl!=NULL; sl=sl->next ) {
6654 		snprintf(popup_msg+pos,sizeof(popup_msg)-pos,"%c%c%c%c{",
6655 			sl->script>>24, sl->script>>16,
6656 			sl->script>>8, sl->script&0xff );
6657 		pos += strlen( popup_msg+pos );
6658 		for ( l=0; l<sl->lang_cnt; ++l ) {
6659 		    uint32 lang = l<MAX_LANG ? sl->langs[l] : sl->morelangs[l-MAX_LANG];
6660 		    snprintf(popup_msg+pos,sizeof(popup_msg)-pos,"%c%c%c%c,",
6661 			    lang>>24, lang>>16,
6662 			    lang>>8, lang&0xff );
6663 		    pos += strlen( popup_msg+pos );
6664 		}
6665 		if ( popup_msg[pos-1]==',' )
6666 		    popup_msg[pos-1] = '}';
6667 		else if ( pos<sizeof(popup_msg)-2 )
6668 		    popup_msg[pos++] = '}';
6669 		if ( pos<sizeof(popup_msg)-2 )
6670 		    popup_msg[pos++] = ' ';
6671 	    }
6672 	    if ( pos<sizeof(popup_msg)-2 )
6673 		popup_msg[pos++] = '\n';
6674 	}
6675     }
6676 
6677     /* Find out if any other lookups invoke it (ie. a context lookup invokes */
6678     /*  does it invoke ME?) */
6679     for ( l=0; l<lk->cnt; ++l ) {
6680 	int j, r, used = false;
6681 	if ( lk->all[l].deleted )
6682     continue;
6683 	for ( j=0; j<lk->all[l].subtable_cnt && !used; ++j ) {
6684 	    struct lookup_subtable *sub = lk->all[l].subtables[j].subtable;
6685 	    if ( lk->all[l].subtables[j].deleted )
6686     continue;
6687 	    if ( sub->fpst!=NULL ) {
6688 		for ( r=0; r<sub->fpst->rule_cnt && !used; ++r ) {
6689 		    struct fpst_rule *rule = &sub->fpst->rules[r];
6690 		    int ls;
6691 		    for ( ls = 0; ls<rule->lookup_cnt; ++ls ) {
6692 			if ( rule->lookups[ls].lookup == otl ) {
6693 			    used = true;
6694 		    break;
6695 			}
6696 		    }
6697 		}
6698 	    }
6699 	}
6700 	if ( used ) {
6701 	    snprintf(popup_msg+pos,sizeof(popup_msg)-pos,_(" Used in %s\n"),
6702 		    lk->all[l].lookup->lookup_name );
6703 	    pos += strlen( popup_msg+pos );
6704 	}
6705     }
6706 
6707     if ( pos>=sizeof(popup_msg) )
6708 	pos = sizeof(popup_msg)-1;
6709     popup_msg[pos]='\0';
6710     GGadgetPreparePopup8(gw,popup_msg);
6711 }
6712 
AddDFLT(OTLookup * otl)6713 static void AddDFLT(OTLookup *otl) {
6714     FeatureScriptLangList *fl;
6715     struct scriptlanglist *sl;
6716     int l;
6717 
6718     for ( fl = otl->features; fl!=NULL; fl=fl->next ) {
6719 	int hasDFLT = false, hasdflt=false;
6720 	for ( sl=fl->scripts; sl!=NULL; sl=sl->next ) {
6721 	    if ( sl->script == DEFAULT_SCRIPT )
6722 		hasDFLT = true;
6723 	    for ( l=0; l<sl->lang_cnt; ++l ) {
6724 		uint32 lang = l<MAX_LANG ? sl->langs[l] : sl->morelangs[l-MAX_LANG];
6725 		if ( lang==DEFAULT_LANG ) {
6726 		    hasdflt = true;
6727 	    break;
6728 		}
6729 	    }
6730 	    if ( hasdflt && hasDFLT )
6731 	break;
6732 	}
6733 	if ( hasDFLT	/* Already there */ ||
6734 		!hasdflt /* Shouldn't add it */ )
6735     continue;
6736 	sl = chunkalloc(sizeof(struct scriptlanglist));
6737 	sl->script = DEFAULT_SCRIPT;
6738 	sl->lang_cnt = 1;
6739 	sl->langs[0] = DEFAULT_LANG;
6740 	sl->next = fl->scripts;
6741 	fl->scripts = sl;
6742     }
6743 }
6744 
AALTRemoveOld(SplineFont * sf,struct lkdata * lk)6745 static void AALTRemoveOld(SplineFont *sf,struct lkdata *lk) {
6746     int i;
6747     FeatureScriptLangList *fl, *prev;
6748 
6749     for ( i=0; i<lk->cnt; ++i ) {
6750 	if ( lk->all[i].deleted )
6751     continue;
6752 	prev = NULL;
6753 	for ( fl = lk->all[i].lookup->features; fl!=NULL; prev=fl, fl=fl->next ) {
6754 	    if ( fl->featuretag==CHR('a','a','l','t') ) {
6755 		if ( fl==lk->all[i].lookup->features && fl->next==NULL && !LookupUsedNested(sf,lk->all[i].lookup) )
6756 		    lk->all[i].deleted = true;
6757 		else {
6758 		    if ( prev==NULL )
6759 			lk->all[i].lookup->features = fl->next;
6760 		    else
6761 			prev->next = fl->next;
6762 		    fl->next = NULL;
6763 		    FeatureScriptLangListFree(fl);
6764 		}
6765 	break;
6766 	    }
6767 	}
6768     }
6769 }
6770 
AALTCreateNew(SplineFont * sf,struct lkdata * lk)6771 static void AALTCreateNew(SplineFont *sf, struct lkdata *lk) {
6772     /* different script/lang combinations may need different 'aalt' lookups */
6773     /*  well, let's just say different script combinations */
6774     /* for each script/lang combo find all single/alternate subs for each */
6775     /*  glyph. Merge those choices and create new lookup with that info */
6776     struct sllk *sllk = NULL;
6777     int sllk_cnt=0, sllk_max = 0;
6778     int i,k;
6779     OTLookup *otl;
6780 
6781     /* Find all scripts, and all the single/alternate lookups for each */
6782     /*  and all the languages used for these in each script */
6783     for ( i=0; i<lk->cnt; ++i ) {
6784 	if ( lk->all[i].deleted )
6785     continue;
6786 	sllk = AddOTLToSllks( lk->all[i].lookup, sllk, &sllk_cnt, &sllk_max );
6787     }
6788     /* Each of these gets its own gsub_alternate lookup which gets inserted */
6789     /*  at the head of the lookup list. Each lookup has one subtable */
6790     for ( i=0; i<sllk_cnt; ++i ) {
6791 	if ( sllk[i].cnt==0 )		/* Script used, but provides no alternates */
6792     continue;
6793 	otl = NewAALTLookup(sf,sllk,sllk_cnt,i);
6794 	if ( lk->cnt>=lk->max )
6795 	    lk->all = realloc(lk->all,(lk->max+=10)*sizeof(struct lkinfo));
6796 	for ( k=lk->cnt; k>0; --k )
6797 	    lk->all[k] = lk->all[k-1];
6798 	memset(&lk->all[0],0,sizeof(struct lkinfo));
6799 	lk->all[0].lookup = otl;
6800 	lk->all[0].new = true;
6801 	++lk->cnt;
6802 
6803 	/* Now add the new subtable */
6804 	lk->all[0].subtables = calloc(1,sizeof(struct lksubinfo));
6805 	lk->all[0].subtable_cnt = lk->all[0].subtable_max = 1;
6806 	lk->all[0].subtables[0].subtable = otl->subtables;
6807 	lk->all[0].subtables[0].new = true;
6808     }
6809 
6810     SllkFree(sllk,sllk_cnt);
6811 }
6812 
lookupmenu_dispatch(GWindow v,GMenuItem * mi,GEvent * e)6813 static void lookupmenu_dispatch(GWindow v, GMenuItem *mi, GEvent *e) {
6814     GEvent dummy;
6815     struct gfi_data *gfi = GDrawGetUserData(v);
6816     int i;
6817     char *buts[4];
6818 
6819     if ( mi->mid==CID_SaveFeat || mi->mid==CID_SaveLookup ) {
6820 	char *filename, *defname;
6821 	FILE *out;
6822 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6823 	struct lkdata *lk = &gfi->tables[isgpos];
6824 	OTLookup *otl = NULL;
6825 
6826 	if ( mi->mid==CID_SaveLookup ) {
6827 	    for ( i=0; i<lk->cnt && (!lk->all[i].selected || lk->all[i].deleted); ++i );
6828 	    if ( i==lk->cnt )
6829 return;
6830 	    otl = lk->all[i].lookup;
6831 	    SFFindUnusedLookups(gfi->sf);
6832 	    if ( otl->unused ) {
6833 		ff_post_error(_("No data"), _("This lookup contains no data"));
6834 return;
6835 	    }
6836 	}
6837 	defname = strconcat(gfi->sf->fontname,".fea");
6838 	filename = gwwv_save_filename(_("Feature file?"),defname,"*.fea");
6839 	free(defname);
6840 	if ( filename==NULL )
6841 return;
6842 	/* Convert to def encoding !!! */
6843 	out = fopen(filename,"w");
6844 	if ( out==NULL ) {
6845 	    ff_post_error(_("Cannot open file"),_("Cannot open %s"), filename );
6846 	    free(filename);
6847 return;
6848 	}
6849 	if ( otl!=NULL )
6850 	    FeatDumpOneLookup( out,gfi->sf,otl );
6851 	else
6852 	    FeatDumpFontLookups( out,gfi->sf );
6853 	if ( ferror(out)) {
6854 	    ff_post_error(_("Output error"),_("An error occurred writing %s"), filename );
6855 	    free(filename);
6856 	    fclose(out);
6857 return;
6858 	}
6859 	free(filename);
6860 	fclose(out);
6861     } else if ( mi->mid==CID_AddAllAlternates ) {
6862 	/* First we want to remove any old aalt-only lookups */
6863 	/*  (and remove the 'aalt' tag from any lookups with multiple features) */
6864 	/* Then add the new ones */
6865 	struct lkdata *lk = &gfi->tables[0];		/* GSUB */
6866 	int has_aalt_only=false, has_aalt_mixed = false;
6867 	int i, ret;
6868 	FeatureScriptLangList *fl;
6869 
6870 	for ( i=0; i<lk->cnt; ++i ) {
6871 	    if ( lk->all[i].deleted )
6872 	continue;
6873 	    for ( fl = lk->all[i].lookup->features; fl!=NULL; fl=fl->next ) {
6874 		if ( fl->featuretag==CHR('a','a','l','t') ) {
6875 		    if ( fl==lk->all[i].lookup->features && fl->next==NULL )
6876 			has_aalt_only = true;
6877 		    else
6878 			has_aalt_mixed = true;
6879 	    break;
6880 		}
6881 	    }
6882 	}
6883 	if ( has_aalt_only || has_aalt_mixed ) {
6884 	    buts[0] = _("_OK"); buts[1] = _("_Cancel"); buts[2] = NULL;
6885 	    ret = gwwv_ask(has_aalt_only?_("Lookups will be removed"):_("Feature tags will be removed"),
6886 		    (const char **) buts,0,1,
6887 		    !has_aalt_mixed ?
6888 		    _("Warning: There are already some 'aalt' lookups in\n"
6889 		      "the font. If you proceed with this command those\n"
6890 		      "lookups will be removed and new lookups will be\n"
6891 		      "generated. The old information will be LOST.\n"
6892 		      " Is that what you want?") :
6893 		    !has_aalt_only ?
6894 		    _("Warning: There are already some 'aalt' lookups in\n"
6895 		      "the font but there are other feature tags associated\n"
6896 		      "with these lookups. If you proceed with this command\n"
6897 		      "the 'aalt' tag will be removed from those lookups,\n"
6898 		      "and new lookups will be generate which will NOT be\n"
6899 		      "associated with the other feature tag(s).\n"
6900 		      " Is that what you want?") :
6901 		    _("Warning: There are already some 'aalt' lookups in\n"
6902 		      "the font, some have no other feature tags associated\n"
6903 		      "with them and these will be removed, others have other\n"
6904 		      "tags associated and these will remain while the 'aalt'\n"
6905 		      "tag will be removed from the lookup -- a new lookup\n"
6906 		      "will be generated which is not associated with any\n"
6907 		      "other feature tags.\n"
6908 		      " Is that what you want?") );
6909 	    if ( ret==1 )
6910 return;
6911 	    AALTRemoveOld(gfi->sf,lk);
6912 	}
6913 	AALTCreateNew(gfi->sf,lk);
6914 	GDrawRequestExpose(GDrawableGetWindow(GWidgetGetControl(gfi->gw,CID_LookupWin+0)),NULL,false);
6915     } else if ( mi->mid==CID_AddDFLT ) {
6916 	struct selection_bits sel;
6917 	int toall, ret, i;
6918 	char *buts[4];
6919 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6920 	struct lkdata *lk = &gfi->tables[isgpos];
6921 
6922 	LookupParseSelection(lk,&sel);
6923 	if ( sel.lookup_cnt==0 ) {
6924 	    buts[0] = _("_Apply to All"); buts[1] = _("_Cancel"); buts[2]=NULL;
6925 	} else {
6926 	    buts[0] = _("_Apply to All"); buts[1] = _("_Apply to Selection"); buts[2] = _("_Cancel"); buts[3]=NULL;
6927 	}
6928 	ret = gwwv_ask(_("Apply to:"),(const char **) buts,0,sel.lookup_cnt==0?1:2,_("Apply change to which lookups?"));
6929 	toall = false;
6930 	if ( ret==0 )
6931 	    toall = true;
6932 	else if ( (ret==1 && sel.lookup_cnt==0) || (ret==2 && sel.lookup_cnt!=0))
6933 return;
6934 	for ( i=0; i<lk->cnt; ++i ) {
6935 	    if ( lk->all[i].deleted )
6936 	continue;
6937 	    if ( lk->all[i].selected || toall ) {
6938 		AddDFLT(lk->all[i].lookup);
6939 	    }
6940 	}
6941     } else if ( mi->mid==CID_AddLanguage || mi->mid==CID_RmLanguage ) {
6942 	int isgpos = GTabSetGetSel(GWidgetGetControl(gfi->gw,CID_Lookups));
6943 	struct lkdata *lk = &gfi->tables[isgpos];
6944 
6945 	AddRmLang(gfi->sf,lk,mi->mid==CID_AddLanguage);
6946     } else {
6947 	memset(&dummy,0,sizeof(dummy));
6948 	dummy.type = et_controlevent;
6949 	dummy.u.control.subtype = et_buttonactivate;
6950 	dummy.u.control.g = GWidgetGetControl(gfi->gw,mi->mid);
6951 	dummy.w = GGadgetGetWindow(dummy.u.control.g);
6952 	dummy.u.control.u.button.button = e->u.mouse.button;
6953 	GGadgetDispatchEvent(dummy.u.control.g,&dummy);
6954     }
6955 }
6956 
6957 static GMenuItem lookuppopupmenu[] = {
6958     { { (unichar_t *) N_("_Top"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 't' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_LookupTop },
6959     { { (unichar_t *) N_("_Up"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'C' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_LookupUp },
6960     { { (unichar_t *) N_("_Down"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_LookupDown },
6961     { { (unichar_t *) N_("_Bottom"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_LookupBottom },
6962     { { (unichar_t *) N_("_Sort"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_LookupSort },
6963     { { NULL, NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 1, 0, 0, 0, '\0' }, '\0', 0, NULL, NULL, NULL, 0 }, /* line */
6964     { { (unichar_t *) N_("Add _Lookup"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_AddLookup },
6965     { { (unichar_t *) N_("Add Sub_table"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_AddSubtable },
6966     { { (unichar_t *) N_("Edit _Metadata"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_EditMetadata },
6967     { { (unichar_t *) N_("_Edit Data"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_EditSubtable },
6968     { { (unichar_t *) N_("De_lete"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_DeleteLookup },
6969     { { (unichar_t *) N_("_Merge"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_MergeLookup },
6970     { { (unichar_t *) N_("Sa_ve Lookup..."), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_SaveLookup },
6971     { { NULL, NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 1, 0, 0, 0, '\0' }, '\0', 0, NULL, NULL, NULL, 0 }, /* line */
6972     { { (unichar_t *) N_("Add Language to Script..."), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_AddLanguage },
6973     { { (unichar_t *) N_("Remove Language from Script..."), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_RmLanguage },
6974     { { NULL, NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 1, 0, 0, 0, '\0' }, '\0', 0, NULL, NULL, NULL, 0 }, /* line */
6975     { { (unichar_t *) N_("_Add 'aalt' features"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_AddAllAlternates },
6976     { { (unichar_t *) N_("Add 'D_FLT' script"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_AddDFLT },
6977     { { NULL, NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 1, 0, 0, 0, '\0' }, '\0', 0, NULL, NULL, NULL, 0 }, /* line */
6978     { { (unichar_t *) N_("_Revert All"), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_RevertLookups },
6979     { { (unichar_t *) N_("_Import..."), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_ImportLookups },
6980     { { (unichar_t *) N_("S_ave Feature File..."), NULL, COLOR_DEFAULT, COLOR_DEFAULT, NULL, NULL, 0, 0, 0, 0, 0, 0, 1, 1, 0, 'o' }, '\0', ksm_control, NULL, NULL, lookupmenu_dispatch, CID_SaveFeat },
6981     GMENUITEM_EMPTY
6982 };
6983 
LookupMenu(struct gfi_data * gfi,struct lkdata * lk,int isgpos,GEvent * event)6984 static void LookupMenu(struct gfi_data *gfi,struct lkdata *lk,int isgpos, GEvent *event) {
6985     struct selection_bits sel;
6986     int i,j;
6987     static int initted = false;
6988 
6989     if ( !initted ) {
6990         int i;
6991         initted = true;
6992 
6993         for ( i=0; lookuppopupmenu[i].ti.text!=NULL || lookuppopupmenu[i].ti.line; ++i )
6994             if ( lookuppopupmenu[i].ti.text!=NULL )
6995                 lookuppopupmenu[i].ti.text = (unichar_t *) _( (char *)lookuppopupmenu[i].ti.text);
6996     }
6997 
6998     GGadgetEndPopup();
6999 
7000     LookupParseSelection(lk,&sel);
7001     for ( i=0; lookuppopupmenu[i].ti.text!=NULL || lookuppopupmenu[i].ti.line; ++i ) {
7002 	switch ( lookuppopupmenu[i].mid ) {
7003 	  case 0:
7004 	    /* Lines */;
7005 	  break;
7006 	  case CID_LookupTop:
7007 	    lookuppopupmenu[i].ti.disabled = sel.any_first || sel.lookup_cnt+sel.sub_cnt!=1;
7008 	  break;
7009 	  case CID_LookupUp:
7010 	    lookuppopupmenu[i].ti.disabled = sel.any_first || sel.lookup_cnt+sel.sub_cnt==0;
7011 	  break;
7012 	  case CID_LookupDown:
7013 	    lookuppopupmenu[i].ti.disabled = sel.any_last || sel.lookup_cnt+sel.sub_cnt==0;
7014 	  break;
7015 	  case CID_LookupBottom:
7016 	    lookuppopupmenu[i].ti.disabled = sel.any_last || sel.lookup_cnt+sel.sub_cnt!=1;
7017 	  break;
7018 	  case CID_LookupSort:
7019 	    lookuppopupmenu[i].ti.disabled = lk->cnt<=1;
7020 	  break;
7021 	  case CID_AddLookup:
7022 	    lookuppopupmenu[i].ti.disabled = sel.lookup_cnt+sel.sub_cnt>1;
7023 	  break;
7024 	  case CID_AddSubtable:
7025 	    lookuppopupmenu[i].ti.disabled = (sel.lookup_cnt!=1 || sel.sub_cnt>1) && (sel.lookup_cnt!=0 || sel.sub_cnt!=1);
7026 	  break;
7027 	  case CID_EditMetadata:
7028 	    lookuppopupmenu[i].ti.disabled = (sel.lookup_cnt!=1 || sel.sub_cnt!=0) &&
7029 			(sel.lookup_cnt!=0 || sel.sub_cnt!=1);
7030 	  break;
7031 	  case CID_EditSubtable:
7032 	    lookuppopupmenu[i].ti.disabled = sel.lookup_cnt!=0 || sel.sub_cnt!=1;
7033 	  break;
7034 	  case CID_DeleteLookup:
7035 	    lookuppopupmenu[i].ti.disabled = sel.lookup_cnt==0 && sel.sub_cnt==0;
7036 	  break;
7037 	  case CID_MergeLookup:
7038 	    lookuppopupmenu[i].ti.disabled = !(
7039 		    (sel.lookup_cnt>=2 && sel.sub_cnt==0 && sel.lookup_mergeable) ||
7040 		    (sel.lookup_cnt==0 && sel.sub_cnt>=2 && sel.sub_table_mergeable)  );
7041 	  break;
7042 	  case CID_ImportLookups:
7043 	    lookuppopupmenu[i].ti.disabled = !LookupsImportable(gfi->sf,isgpos);
7044 	  break;
7045 	  case CID_RevertLookups:
7046 	    lookuppopupmenu[i].ti.disabled = false;
7047 	  break;
7048 	  case CID_SaveLookup:
7049 	    lookuppopupmenu[i].ti.disabled = sel.lookup_cnt!=1 || sel.sub_cnt!=0;
7050 	    for ( j=0; j<lk->cnt; ++j ) if ( lk->all[j].selected ) {
7051 		int type = lk->all[j].lookup->lookup_type;
7052 		if ( type==kern_statemachine || type==morx_indic ||
7053 			type==morx_context || type==morx_insert )
7054 		    lookuppopupmenu[i].ti.disabled = true;
7055 	    break;
7056 	    }
7057 	  break;
7058 	  case CID_AddDFLT:
7059 	    lookuppopupmenu[i].ti.disabled = lk->cnt==0;
7060 	  break;
7061 	  case CID_AddAllAlternates:
7062 	    lookuppopupmenu[i].ti.disabled = lk->cnt==0 || lk==&gfi->tables[1]/*Only applies to GSUB*/;
7063 	  break;
7064 	  case CID_SaveFeat:
7065 	    lookuppopupmenu[i].ti.disabled = lk->cnt<=0;
7066 	  break;
7067 	}
7068     }
7069     GMenuCreatePopupMenu(event->w,event, lookuppopupmenu);
7070 }
7071 
7072 
LookupIndex(struct gfi_data * othergfi,int isgpos,GWindow gw,GWindow othergw,GEvent * event,int * subindex)7073 static int LookupIndex(struct gfi_data *othergfi, int isgpos, GWindow gw,
7074 	GWindow othergw, GEvent *event, int *subindex) {
7075     GPoint pt;
7076     struct lkdata *otherlk = &othergfi->tables[isgpos];
7077     int l,i,j, lcnt;
7078 
7079     pt.x = event->u.mouse.x; pt.y = event->u.mouse.y;
7080     if ( gw!=othergw )
7081 	GDrawTranslateCoordinates(gw,othergw,&pt);
7082     l = (pt.y-LK_MARGIN)/othergfi->fh + otherlk->off_top;
7083 
7084     if ( l<0 ) {
7085 	*subindex = -1;
7086 return( -1 );
7087     }
7088 
7089     lcnt = 0;
7090     for ( i=0; i<otherlk->cnt; ++i ) {
7091 	if ( otherlk->all[i].deleted )
7092     continue;
7093 	if ( l==lcnt ) {
7094 	    *subindex = -1;
7095 return( i );
7096 	}
7097 	++lcnt;
7098 	if ( otherlk->all[i].open ) {
7099 	    for ( j=0; j<otherlk->all[i].subtable_cnt; ++j ) {
7100 		if ( otherlk->all[i].subtables[j].deleted )
7101 	    continue;
7102 		if ( l==lcnt ) {
7103 		    *subindex = j;
7104 return( i );
7105 		}
7106 		++lcnt;
7107 	    }
7108 	}
7109     }
7110     /* drop after last lookup */
7111     *subindex = -1;
7112 return( i );
7113 }
7114 
LookupsDropable(struct gfi_data * gfi,struct gfi_data * othergfi,int isgpos,GWindow gw,GWindow othergw,GEvent * event)7115 static int LookupsDropable(struct gfi_data *gfi, struct gfi_data *othergfi,
7116 	int isgpos, GWindow gw, GWindow othergw, GEvent *event) {
7117     int lookup, subtable;
7118     struct lkdata *lk = &gfi->tables[isgpos];
7119     struct lkdata *otherlk = &othergfi->tables[isgpos];
7120 
7121     if ( gfi->first_sel_subtable==-1 )
7122 return( true );			/* Lookups can be dropped anywhere */
7123 
7124     lookup = LookupIndex(othergfi,isgpos,gw,othergw,event,&subtable);
7125     if ( lookup<0 || lookup>=lk->cnt )
7126 return( false );		/* Subtables must be dropped in a lookup */
7127 
7128     if ( gfi!=othergfi /* || lookup!=gfi->first_sel_lookup*/ )
7129 return( false );		/* Can't merge subtables from one lookup to another */
7130 
7131     /* Subtables can only be dropped in a lookup with the same type */
7132     /* At the moment we don't need this test, as we only allow subtables to be dropped within their original lookup */
7133 return( otherlk->all[lookup].lookup->lookup_type ==
7134 		lk->all[gfi->first_sel_lookup].lookup->lookup_type );
7135 }
7136 
LookupDragDrop(struct gfi_data * gfi,int isgpos,GEvent * event)7137 static void LookupDragDrop(struct gfi_data *gfi, int isgpos, GEvent *event) {
7138     FontViewBase *fv;
7139     struct gfi_data *othergfi=NULL;
7140     GWindow gw = GDrawableGetWindow(GWidgetGetControl(gfi->gw,CID_LookupWin+isgpos));
7141     GWindow othergw = NULL;
7142     int i,j;
7143 
7144     othergw = GDrawGetPointerWindow(gfi->gw);
7145 
7146     for ( fv = (FontViewBase *) fv_list; fv!=NULL; fv=fv->next ) if ( fv->sf->fontinfo!=NULL ) {
7147 	int otherisgpos;
7148 
7149 	othergfi = fv->sf->fontinfo;
7150 	otherisgpos = GTabSetGetSel(GWidgetGetControl(othergfi->gw,CID_Lookups));
7151 	if ( otherisgpos!=isgpos )
7152     continue;
7153 	if ( othergw == GDrawableGetWindow(GWidgetGetControl(othergfi->gw,CID_LookupWin+otherisgpos)))
7154     break;
7155     }
7156     if ( fv==NULL )
7157 	othergw = NULL;
7158 
7159     if ( fv==NULL || !LookupsDropable(gfi,othergfi,isgpos,gw,othergw,event)) {
7160 	if ( event->type==et_mouseup ) {
7161 	    GDrawSetCursor(gw,ct_mypointer);
7162 	    gfi->lk_drag_and_drop = gfi->lk_dropablecursor = false;
7163 return;
7164 	} else {
7165 	    if ( gfi->lk_dropablecursor ) {
7166 		gfi->lk_dropablecursor = false;
7167 		GDrawSetCursor(gw,ct_prohibition);
7168 	    }
7169 return;
7170 	}
7171     } else {
7172 	if ( event->type==et_mousemove ) {
7173 	    if ( !gfi->lk_dropablecursor ) {
7174 		gfi->lk_dropablecursor = true;
7175 		GDrawSetCursor(gw,ct_features);
7176 	    }
7177 return;
7178 	} else {
7179 	    struct lkdata *otherlk = &othergfi->tables[isgpos];
7180 	    struct lkdata *lk = &gfi->tables[isgpos];
7181 	    struct lkinfo temp;
7182 	    struct lksubinfo subtemp;
7183 	    int lookup, subtable;
7184 
7185 	    lookup = LookupIndex(othergfi,isgpos,gw,othergw,event,&subtable);
7186 
7187 	    if ( gfi==othergfi ) {
7188 		/* dropping in the same window just moves things around */
7189 		if ( gfi->first_sel_subtable == -1 ) {
7190 		    /* Moving lookups */
7191 		    if ( lookup<0 ) lookup=0;
7192 		    else if ( lookup>=lk->cnt ) lookup=lk->cnt;
7193 		    if ( lookup==gfi->first_sel_lookup )
7194   goto done_drop;
7195 		    for ( i=0; i<lk->cnt; ++i )
7196 			lk->all[i].moved = false;
7197 		    for ( i=gfi->first_sel_lookup; i<lk->cnt; ++i ) {
7198 			if ( lk->all[i].deleted || !lk->all[i].selected ||
7199 				lk->all[i].moved || i==lookup )
7200 		    continue;
7201 			temp = lk->all[i];
7202 			temp.moved = true;
7203 			if ( i<lookup ) {
7204 			    for ( j=i+1; j<lookup; ++j )
7205 				lk->all[j-1] = lk->all[j];
7206 			    lk->all[j-1] = temp;
7207 			} else {
7208 			    for ( j=i; j>lookup; --j )
7209 				lk->all[j] = lk->all[j-1];
7210 			    lk->all[j] = temp;
7211 			}
7212 			--i;
7213 		    }
7214 		} else if ( lookup==gfi->first_sel_lookup ) {
7215 		    if ( subtable< 0 ) subtable=0;
7216 		    if ( subtable==gfi->first_sel_subtable )
7217   goto done_drop;
7218 		    for ( i=0; i<lk->cnt; ++i )
7219 			lk->all[lookup].subtables[i].moved = false;
7220 		    for ( i=gfi->first_sel_subtable; i<lk->all[lookup].subtable_cnt; ++i ) {
7221 			if ( lk->all[lookup].subtables[i].deleted || !lk->all[lookup].subtables[i].selected ||
7222 				lk->all[lookup].subtables[i].moved || i==subtable )
7223 		    continue;
7224 			subtemp = lk->all[lookup].subtables[i];
7225 			subtemp.moved = true;
7226 			if ( i<subtable ) {
7227 			    for ( j=i+1; j<subtable; ++j )
7228 				lk->all[lookup].subtables[j-1] = lk->all[lookup].subtables[j];
7229 			    lk->all[lookup].subtables[j-1] = subtemp;
7230 			} else {
7231 			    for ( j=i; j>subtable; --j )
7232 				lk->all[lookup].subtables[j] = lk->all[lookup].subtables[j-1];
7233 			    lk->all[lookup].subtables[j] = subtemp;
7234 			}
7235 			--i;
7236 		    }
7237 		} else {
7238 		    int old_lk = gfi->first_sel_lookup;
7239 		    int sel_cnt=0, k;
7240 		    if ( subtable<0 ) /* dropped into lookup */
7241 			subtable = 0;
7242 		    for ( i=gfi->first_sel_subtable; i<lk->all[old_lk].subtable_cnt; ++i )
7243 			if ( !lk->all[old_lk].subtables[i].deleted && lk->all[old_lk].subtables[i].selected )
7244 			    ++sel_cnt;
7245 		    if ( lk->all[lookup].subtable_cnt+sel_cnt >= lk->all[lookup].subtable_max )
7246 			lk->all[lookup].subtables = realloc(lk->all[lookup].subtables,
7247 				(lk->all[lookup].subtable_max += sel_cnt+3)*sizeof(struct lksubinfo));
7248 		    for ( i= lk->all[lookup].subtable_cnt+sel_cnt-1; i>=subtable; --i )
7249 			lk->all[lookup].subtables[i] = lk->all[lookup].subtables[i-sel_cnt];
7250 		    k=0;
7251 		    for ( i=gfi->first_sel_subtable; i<lk->all[old_lk].subtable_cnt; ++i ) {
7252 			if ( !lk->all[old_lk].subtables[i].deleted && lk->all[old_lk].subtables[i].selected )
7253 			    lk->all[lookup].subtables[subtable+k++] = lk->all[old_lk].subtables[i];
7254 		    }
7255 		    lk->all[lookup].subtable_cnt += k;
7256 		    k=0;
7257 		    for ( i=gfi->first_sel_subtable; i<lk->all[old_lk].subtable_cnt; ++i ) {
7258 			if ( !lk->all[old_lk].subtables[i].deleted && lk->all[old_lk].subtables[i].selected )
7259 			    ++k;
7260 			else if ( k!=0 )
7261 			    lk->all[old_lk].subtables[i-k] = lk->all[old_lk].subtables[i];
7262 		    }
7263 		    lk->all[old_lk].subtable_cnt -= k;
7264 		}
7265 	    } else {
7266 		if ( gfi->first_sel_subtable == -1 ) {
7267 		    /* Import lookups from one font to another */
7268 		    OTLookup **list, *before;
7269 		    int cnt=0;
7270 		    for ( i=0; i<lk->cnt; ++i ) {
7271 			if ( lk->all[i].deleted )
7272 		    continue;
7273 			if ( lk->all[i].selected )
7274 			    ++cnt;
7275 		    }
7276 		    list = malloc((cnt+1)*sizeof(OTLookup *));
7277 		    cnt=0;
7278 		    for ( i=0; i<lk->cnt; ++i ) {
7279 			if ( lk->all[i].deleted )
7280 		    continue;
7281 			if ( lk->all[i].selected )
7282 			    list[cnt++] = lk->all[i].lookup;
7283 		    }
7284 		    list[cnt] = NULL;
7285 		    if ( lookup<0 ) lookup=0;
7286 		    before = lookup>=otherlk->cnt ? NULL : otherlk->all[lookup].lookup;
7287 		    OTLookupsCopyInto(othergfi->sf,gfi->sf,list,before);
7288 		    free( list );
7289 		} else
7290 		    IError("Attempt to merge subtables across fonts not permitted" );
7291 		GDrawRequestExpose(othergw,NULL,false);
7292 	    }
7293   done_drop:
7294 	    GDrawSetCursor(gw,ct_mypointer);
7295 	    GDrawRequestExpose(gw,NULL,false);
7296 	    gfi->lk_drag_and_drop = gfi->lk_dropablecursor = false;
7297 return;
7298 	}
7299     }
7300 }
7301 
LookupDragDropable(struct gfi_data * gfi,struct lkdata * lk)7302 static int LookupDragDropable(struct gfi_data *gfi, struct lkdata *lk) {
7303     int i,j;
7304     int first_l= -1, first_s= -1;
7305 
7306     for ( i=0; i<lk->cnt; ++i ) {
7307 	if ( lk->all[i].deleted )
7308     continue;
7309 	if ( lk->all[i].selected ) {
7310 	    if ( first_s!=-1 )
7311 return( false );		/* Can't have mixed lookups and subtables */
7312 	    if ( first_l==-1 )
7313 		first_l = i;
7314 	}
7315 	if ( lk->all[i].open ) {
7316 	    for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
7317 		if ( lk->all[i].subtables[j].deleted )
7318 	    continue;
7319 		if ( lk->all[i].subtables[j].selected ) {
7320 		    if ( first_l==i || first_l==-1 )
7321 			first_l = i;
7322 		    else
7323 return( false );		/* Mixed lookups and subtables */
7324 		    if ( first_s==-1 )
7325 			first_s = j;
7326 		}
7327 	    }
7328 	}
7329     }
7330     gfi->first_sel_lookup   = first_l;
7331     gfi->first_sel_subtable = first_s;
7332 return( true );
7333 }
7334 
LookupMouse(struct gfi_data * gfi,int isgpos,GEvent * event)7335 static void LookupMouse(struct gfi_data *gfi, int isgpos, GEvent *event) {
7336     struct lkdata *lk = &gfi->tables[isgpos];
7337     int l = (event->u.mouse.y-LK_MARGIN)/gfi->fh + lk->off_top;
7338     int inbox = event->u.mouse.x>=LK_MARGIN &&
7339 	    event->u.mouse.x>=LK_MARGIN-lk->off_left &&
7340 	    event->u.mouse.x<=LK_MARGIN-lk->off_left+gfi->as+1;
7341     GWindow gw = GDrawableGetWindow(GWidgetGetControl(gfi->gw,CID_LookupWin+isgpos));
7342     int i,j,lcnt;
7343 
7344     if ( event->type!=et_mousedown && gfi->lk_drag_and_drop ) {
7345 	LookupDragDrop(gfi,isgpos,event);
7346 return;
7347     }
7348 
7349     if ( l<0 || event->u.mouse.y>=(gfi->lkheight-2*LK_MARGIN) )
7350 return;
7351 
7352     lcnt = 0;
7353     for ( i=0; i<lk->cnt; ++i ) {
7354 	if ( lk->all[i].deleted )
7355     continue;
7356 	if ( l==lcnt ) {
7357 	    if ( event->type==et_mouseup )
7358 return;
7359 	    else if ( event->type==et_mousemove ) {
7360 		LookupPopup(gw,lk->all[i].lookup,NULL,lk);
7361 return;
7362 	    } else {
7363 		if ( gfi->lk_drag_and_drop ) {
7364 		    GDrawSetCursor(gw,ct_mypointer);
7365 		    gfi->lk_drag_and_drop = gfi->lk_dropablecursor = false;
7366 		}
7367 		if ( inbox || event->u.mouse.clicks>1 ) {
7368 		    lk->all[i].open = !lk->all[i].open;
7369 		    GFI_LookupScrollbars(gfi, isgpos, true);
7370 return;
7371 		}
7372 		if ( !(event->u.mouse.state&(ksm_shift|ksm_control)) ) {
7373 		    /* If line is selected, and we're going to pop up a menu */
7374 		    /*  then don't clear other selected lines */
7375 		    if ( !lk->all[i].selected ||
7376 			    (event->u.mouse.button!=3 && !LookupDragDropable(gfi,lk)))
7377 			LookupDeselect(lk);
7378 		    else if ( event->u.mouse.button!=3 ) {
7379 			gfi->lk_drag_and_drop = gfi->lk_dropablecursor = true;
7380 			GDrawSetCursor(gw,ct_features);
7381 		    }
7382 		    lk->all[i].selected = true;
7383 		} else if ( event->u.mouse.state&ksm_control ) {
7384 		    lk->all[i].selected = !lk->all[i].selected;
7385 		} else if ( lk->all[i].selected ) {
7386 		    lk->all[i].selected = false;
7387 		} else {
7388 		    for ( j=0; j<lk->cnt; ++j )
7389 			if ( !lk->all[j].deleted  && lk->all[j].selected )
7390 		    break;
7391 		    if ( j==lk->cnt )
7392 			lk->all[i].selected = true;
7393 		    else if ( j<i ) {
7394 			for ( ; j<=i ; ++j )
7395 			    if ( !lk->all[j].deleted )
7396 				lk->all[j].selected = true;
7397 		    } else {
7398 			for ( ; j>=i ; --j )
7399 			    if ( !lk->all[j].deleted )
7400 				lk->all[j].selected = true;
7401 		    }
7402 		}
7403 		GFI_LookupEnableButtons(gfi,isgpos);
7404 		GDrawRequestExpose(gw,NULL,false);
7405 		if ( event->u.mouse.button==3 )
7406 		    LookupMenu(gfi,lk,isgpos,event);
7407 return;
7408 	    }
7409 	}
7410 	++lcnt;
7411 	if ( lk->all[i].open ) {
7412 	    for ( j=0; j<lk->all[i].subtable_cnt; ++j ) {
7413 		if ( lk->all[i].subtables[j].deleted )
7414 	    continue;
7415 		if ( l==lcnt ) {
7416 		    if ( event->type==et_mouseup )
7417 return;
7418 		    else if ( event->type==et_mousemove ) {
7419 			LookupPopup(gw,lk->all[i].lookup,lk->all[i].subtables[j].subtable,lk);
7420 return;
7421 		    } else {
7422 			if ( inbox )
7423 return;		/* Can't open this guy */
7424 			if ( event->u.mouse.clicks>1 )
7425 			    LookupSubtableContents(gfi,isgpos);
7426 			else {
7427 			    if ( !(event->u.mouse.state&(ksm_shift|ksm_control)) ) {
7428 				/* If line is selected, and we're going to pop up a menu */
7429 				/*  then don't clear other selected lines */
7430 				if ( !lk->all[i].subtables[j].selected ||
7431 					(event->u.mouse.button!=3 && !LookupDragDropable(gfi,lk)))
7432 				    LookupDeselect(lk);
7433 				else if ( event->u.mouse.button!=3 ) {
7434 				    gfi->lk_drag_and_drop = gfi->lk_dropablecursor = true;
7435 				    GDrawSetCursor(gw,ct_features);
7436 				}
7437 				lk->all[i].subtables[j].selected = true;
7438 			    } else
7439 				lk->all[i].subtables[j].selected = !lk->all[i].subtables[j].selected;
7440 			    GFI_LookupEnableButtons(gfi,isgpos);
7441 			    GDrawRequestExpose(gw,NULL,false);
7442 			    if ( event->u.mouse.button==3 )
7443 				LookupMenu(gfi,lk,isgpos,event);
7444 			}
7445 return;
7446 		    }
7447 		}
7448 		++lcnt;
7449 	    }
7450 	}
7451     }
7452 }
7453 
lookups_e_h(GWindow gw,GEvent * event,int isgpos)7454 static int lookups_e_h(GWindow gw, GEvent *event, int isgpos) {
7455     struct gfi_data *gfi = GDrawGetUserData(gw);
7456 
7457     if (( event->type==et_mouseup || event->type==et_mousedown ) &&
7458 	    (event->u.mouse.button>=4 && event->u.mouse.button<=7) ) {
7459 return( GGadgetDispatchEvent(GWidgetGetControl(gw,CID_LookupVSB+isgpos),event));
7460     }
7461 
7462     switch ( event->type ) {
7463       case et_char:
7464 return( GFI_Char(gfi,event) );
7465       case et_expose:
7466 	LookupExpose(gw,gfi,isgpos);
7467       break;
7468       case et_mousedown: case et_mousemove: case et_mouseup:
7469 	LookupMouse(gfi,isgpos,event);
7470       break;
7471       case et_resize: {
7472 	GRect r;
7473 	GDrawGetSize(gw,&r);
7474 	gfi->lkheight = r.height; gfi->lkwidth = r.width;
7475 	GFI_LookupScrollbars(gfi,false,false);
7476 	GFI_LookupScrollbars(gfi,true,false);
7477       }
7478       break;
7479     }
7480 return( true );
7481 }
7482 
gposlookups_e_h(GWindow gw,GEvent * event)7483 static int gposlookups_e_h(GWindow gw, GEvent *event) {
7484 return( lookups_e_h(gw,event,true));
7485 }
7486 
gsublookups_e_h(GWindow gw,GEvent * event)7487 static int gsublookups_e_h(GWindow gw, GEvent *event) {
7488 return( lookups_e_h(gw,event,false));
7489 }
7490 
FontInfo(SplineFont * sf,int deflayer,int defaspect,int sync)7491 void FontInfo(SplineFont *sf,int deflayer,int defaspect,int sync) {
7492     // This opens the Font Info box to the tab specified by defaspect,
7493     // which indexes the array aspects, populated below.
7494     GRect pos;
7495     GWindow gw;
7496     GWindowAttrs wattrs;
7497     GTabInfo aspects[26], vaspects[6], lkaspects[3];
7498     GGadgetCreateData mgcd[10], ngcd[19], psgcd[30], tngcd[8],
7499 	pgcd[12], vgcd[21], pangcd[23], comgcd[4], txgcd[23], floggcd[4],
7500 	mfgcd[8], mcgcd[8], szgcd[19], mkgcd[7], metgcd[33], vagcd[3], ssgcd[23],
7501 	xugcd[8], dgcd[6], ugcd[6], gaspgcd[5], gaspgcd_def[2], lksubgcd[2][4],
7502 	lkgcd[2], lkbuttonsgcd[15], cgcd[12], lgcd[20], msgcd[7], ssngcd[8],
7503 	woffgcd[8], privategcd_def[4];
7504     GGadgetCreateData mb[2], mb2, nb[2], nb2, nb3, xub[2], psb[2], psb2[3], ppbox[4],
7505 	    vbox[4], metbox[2], ssbox[2], panbox[2], combox[2], mkbox[3],
7506 	    txbox[5], ubox[3], dbox[2], flogbox[2],
7507 	    mcbox[3], mfbox[3], szbox[6], tnboxes[4], gaspboxes[3],
7508 	    lkbox[7], cbox[6], lbox[8], msbox[3], ssboxes[4], woffbox[2];
7509     GGadgetCreateData *marray[7], *marray2[9], *narray[29], *narray2[7], *narray3[3],
7510 	*xuarray[20], *psarray[10], *psarray2[21], *psarray4[10],
7511 	*pparray[6], *vradio[5], *varray[41], *metarray[53],
7512 	*ssarray[58], *panarray[40], *comarray[3], *flogarray[3],
7513 	*mkarray[6], *msarray[6],
7514 	*txarray[5], *txarray2[30],
7515 	*txarray3[6], *txarray4[6], *uarray[5], *darray[10],
7516 	*mcarray[13], *mcarray2[7],
7517 	*mfarray[14], *szarray[7], *szarray2[5], *szarray3[7],
7518 	*szarray4[4], *tnvarray[4], *tnharray[6], *tnharray2[5], *gaspharray[6],
7519 	*gaspvarray[3], *lkarray[2][7], *lkbuttonsarray[17], *lkharray[3],
7520 	*charray1[4], *charray2[4], *charray3[4], *cvarray[9], *cvarray2[4],
7521 	*larray[16], *larray2[25], *larray3[6], *larray4[5], *uharray[4],
7522 	*ssvarray[4], *woffarray[16];
7523     GTextInfo mlabel[10], nlabel[18], pslabel[30], tnlabel[7],
7524 	plabel[12], vlabel[21], panlabel[22], comlabel[3], txlabel[23],
7525 	mflabel[8], mclabel[8], szlabel[17], mklabel[7], metlabel[32],
7526 	sslabel[23], xulabel[8], dlabel[5], ulabel[3], gasplabel[5],
7527 	lkbuttonslabel[14], clabel[11], floglabel[3], llabel[20], mslabel[7],
7528 	ssnlabel[7], wofflabel[8], privatelabel_def[3];
7529     GTextInfo *namelistnames;
7530     struct gfi_data *d;
7531     char iabuf[20], upbuf[20], uwbuf[20], asbuf[20], dsbuf[20],
7532 	    vbuf[20], uibuf[12], embuf[20];
7533     char dszbuf[20], dsbbuf[20], dstbuf[21], sibuf[20], swbuf[20], sfntrbuf[20];
7534     char ranges[40], codepages[40];
7535     char woffmajorbuf[20], woffminorbuf[20];
7536     int i,j,k,g, psrow;
7537     int mcs;
7538     char title[130];
7539     FontRequest rq;
7540     int as, ds, ld;
7541     char **nlnames;
7542     char createtime[200], modtime[200];
7543     unichar_t *tmpcreatetime, *tmpmodtime;
7544     time_t t;
7545     const struct tm *tm;
7546     struct matrixinit mi, gaspmi, layersmi, ssmi, sizemi, marks_mi, markc_mi, private_mi;
7547     struct matrix_data *marks_md, *markc_md;
7548     int ltype;
7549     static GBox small_blue_box;
7550     extern GBox _GGadget_button_box;
7551     static GFont *fi_font=NULL;
7552     char *copied_copyright;
7553 
7554     FontInfoInit();
7555 
7556     if ( sf->fontinfo!=NULL ) {
7557 	GDrawSetVisible(((struct gfi_data *) (sf->fontinfo))->gw,true);
7558 	GDrawRaise( ((struct gfi_data *) (sf->fontinfo))->gw );
7559 return;
7560     }
7561     if ( defaspect==-1 )
7562 	defaspect = last_aspect;
7563 
7564     d = calloc(1,sizeof(struct gfi_data));
7565     sf->fontinfo = d;
7566 
7567     memset(&wattrs,0,sizeof(wattrs));
7568     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg;
7569     wattrs.event_masks = ~(1<<et_charup);
7570     wattrs.is_dlg = true;
7571     if ( sync ) {
7572 	wattrs.mask |= wam_restrict;
7573 	wattrs.restrict_input_to_me = 1;
7574     }
7575     wattrs.undercursor = 1;
7576     wattrs.cursor = ct_pointer;
7577     snprintf(title,sizeof(title),_("Font Information for %.90s"),
7578 	    sf->fontname);
7579     wattrs.utf8_window_title = title;
7580     pos.x = pos.y = 0;
7581     pos.width =GDrawPointsToPixels(NULL,GGadgetScale(268+85));
7582     pos.height = GDrawPointsToPixels(NULL,375);
7583     gw = GDrawCreateTopWindow(NULL,&pos,e_h,d,&wattrs);
7584 
7585     d->sf = sf;
7586     d->def_layer = deflayer;
7587     d->gw = gw;
7588     d->old_sel = -2;
7589     d->texdata = sf->texdata;
7590 
7591     memset(&nlabel,0,sizeof(nlabel));
7592     memset(&ngcd,0,sizeof(ngcd));
7593 
7594     nlabel[0].text = (unichar_t *) _("Fo_ntname:");
7595     nlabel[0].text_is_1byte = true;
7596     nlabel[0].text_in_resource = true;
7597     ngcd[0].gd.label = &nlabel[0];
7598     ngcd[0].gd.pos.x = 12; ngcd[0].gd.pos.y = 6+6;
7599     ngcd[0].gd.flags = gg_visible | gg_enabled;
7600     ngcd[0].creator = GLabelCreate;
7601 
7602     ngcd[1].gd.pos.x = 115; ngcd[1].gd.pos.y = ngcd[0].gd.pos.y-6; ngcd[1].gd.pos.width = 137;
7603     ngcd[1].gd.flags = gg_visible | gg_enabled;
7604     nlabel[1].text = (unichar_t *) sf->fontname;
7605     nlabel[1].text_is_1byte = true;
7606     ngcd[1].gd.label = &nlabel[1];
7607     ngcd[1].gd.cid = CID_Fontname;
7608     ngcd[1].gd.handle_controlevent = GFI_NameChange;
7609     ngcd[1].creator = GTextFieldCreate;
7610 
7611     nlabel[2].text = (unichar_t *) _("_Family Name:");
7612     nlabel[2].text_is_1byte = true;
7613     nlabel[2].text_in_resource = true;
7614     ngcd[2].gd.label = &nlabel[2];
7615     ngcd[2].gd.pos.x = 12; ngcd[2].gd.pos.y = ngcd[0].gd.pos.y+26;
7616     ngcd[2].gd.flags = gg_visible | gg_enabled;
7617     ngcd[2].creator = GLabelCreate;
7618 
7619     ngcd[3].gd.pos.x = ngcd[1].gd.pos.x; ngcd[3].gd.pos.y = ngcd[2].gd.pos.y-6; ngcd[3].gd.pos.width = 137;
7620     ngcd[3].gd.flags = gg_visible | gg_enabled;
7621     nlabel[3].text = (unichar_t *) (sf->familyname?sf->familyname:sf->fontname);
7622     nlabel[3].text_is_1byte = true;
7623     ngcd[3].gd.label = &nlabel[3];
7624     ngcd[3].gd.cid = CID_Family;
7625     ngcd[3].gd.handle_controlevent = GFI_FamilyChange;
7626     ngcd[3].creator = GTextFieldCreate;
7627     if ( sf->familyname==NULL || strstr(sf->familyname,"Untitled")==sf->familyname )
7628 	d->family_untitled = true;
7629 
7630     ngcd[4].gd.pos.x = 12; ngcd[4].gd.pos.y = ngcd[3].gd.pos.y+26+6;
7631     nlabel[4].text = (unichar_t *) _("Name For Human_s:");
7632     nlabel[4].text_is_1byte = true;
7633     nlabel[4].text_in_resource = true;
7634     ngcd[4].gd.label = &nlabel[4];
7635     ngcd[4].gd.flags = gg_visible | gg_enabled;
7636     ngcd[4].creator = GLabelCreate;
7637 
7638     ngcd[5].gd.pos.x = 115; ngcd[5].gd.pos.y = ngcd[4].gd.pos.y-6; ngcd[5].gd.pos.width = 137;
7639     ngcd[5].gd.flags = gg_visible | gg_enabled;
7640     nlabel[5].text = (unichar_t *) (sf->fullname?sf->fullname:sf->fontname);
7641     nlabel[5].text_is_1byte = true;
7642     ngcd[5].gd.label = &nlabel[5];
7643     ngcd[5].gd.cid = CID_Human;
7644     ngcd[5].gd.handle_controlevent = GFI_HumanChange;
7645     ngcd[5].creator = GTextFieldCreate;
7646     if ( sf->fullname==NULL || strstr(sf->fullname,"Untitled")==sf->fullname )
7647 	d->human_untitled = true;
7648 
7649     nlabel[6].text = (unichar_t *) _("_Weight");
7650     nlabel[6].text_is_1byte = true;
7651     nlabel[6].text_in_resource = true;
7652     ngcd[6].gd.label = &nlabel[6];
7653     ngcd[6].gd.pos.x = ngcd[4].gd.pos.x; ngcd[6].gd.pos.y = ngcd[4].gd.pos.y+26;
7654     ngcd[6].gd.flags = gg_visible | gg_enabled;
7655     ngcd[6].creator = GLabelCreate;
7656 
7657     ngcd[7].gd.pos.x = ngcd[1].gd.pos.x; ngcd[7].gd.pos.y = ngcd[6].gd.pos.y-6; ngcd[7].gd.pos.width = 137;
7658     ngcd[7].gd.flags = gg_visible | gg_enabled;
7659     nlabel[7].text = (unichar_t *) (sf->weight?sf->weight:"Regular");
7660     nlabel[7].text_is_1byte = true;
7661     ngcd[7].gd.label = &nlabel[7];
7662     ngcd[7].gd.cid = CID_Weight;
7663     ngcd[7].creator = GTextFieldCreate;
7664 
7665     ngcd[8].gd.pos.x = 12; ngcd[8].gd.pos.y = ngcd[6].gd.pos.y+26;
7666     nlabel[8].text = (unichar_t *) _("_Version:");
7667     nlabel[8].text_is_1byte = true;
7668     nlabel[8].text_in_resource = true;
7669     ngcd[8].gd.label = &nlabel[8];
7670     ngcd[8].gd.flags = gg_visible | gg_enabled;
7671     ngcd[8].creator = GLabelCreate;
7672 
7673     ngcd[9].gd.pos.x = 115; ngcd[9].gd.pos.y = ngcd[8].gd.pos.y-6; ngcd[9].gd.pos.width = 137;
7674     ngcd[9].gd.flags = gg_visible | gg_enabled;
7675     nlabel[9].text = (unichar_t *) (sf->version?sf->version:"");
7676     nlabel[9].text_is_1byte = true;
7677     if ( sf->subfontcnt!=0 ) {
7678 	sprintf( vbuf,"%g", sf->cidversion );
7679 	nlabel[9].text = (unichar_t *) vbuf;
7680     }
7681     ngcd[9].gd.label = &nlabel[9];
7682     ngcd[9].gd.cid = CID_Version;
7683     ngcd[9].creator = GTextFieldCreate;
7684 
7685     nlabel[10].text = (unichar_t *) _("sfnt _Revision:");
7686     nlabel[10].text_is_1byte = true;
7687     nlabel[10].text_in_resource = true;
7688     ngcd[10].gd.label = &nlabel[10];
7689     ngcd[10].gd.flags = gg_visible | gg_enabled;
7690     ngcd[10].gd.popup_msg = _("If you leave this field blank FontForge will use a default based on\neither the version string above, or one in the 'name' table." );
7691     ngcd[10].creator = GLabelCreate;
7692 
7693     sfntrbuf[0]='\0';
7694     if ( sf->sfntRevision!=sfntRevisionUnset )
7695 	sprintf( sfntrbuf, "%g", sf->sfntRevision/65536.0 );
7696     ngcd[11].gd.flags = gg_visible | gg_enabled;
7697     nlabel[11].text = (unichar_t *) sfntrbuf;
7698     nlabel[11].text_is_1byte = true;
7699     ngcd[11].gd.label = &nlabel[11];
7700     ngcd[11].gd.cid = CID_Revision;
7701     ngcd[11].gd.popup_msg = _("If you leave this field blank FontForge will use a default based on\neither the version string above, or one in the 'name' table." );
7702     ngcd[11].creator = GTextFieldCreate;
7703 
7704     nlabel[12].text = (unichar_t *) _("_Base Filename:");
7705     nlabel[12].text_is_1byte = true;
7706     nlabel[12].text_in_resource = true;
7707     ngcd[12].gd.label = &nlabel[12];
7708     ngcd[12].gd.popup_msg = _("Use this as the default base for the filename\nwhen generating a font." );
7709     ngcd[12].gd.flags = gg_visible | gg_enabled;
7710     ngcd[12].creator = GLabelCreate;
7711 
7712 /* GT: The space in front of "Same" makes things line up better */
7713     nlabel[13].text = (unichar_t *) _(" Same as Fontname");
7714     nlabel[13].text_is_1byte = true;
7715     ngcd[13].gd.label = &nlabel[13];
7716     ngcd[13].gd.flags = sf->defbasefilename==NULL ? (gg_visible | gg_enabled | gg_cb_on ) : (gg_visible | gg_enabled);
7717     ngcd[13].gd.cid = CID_SameAsFontname;
7718     ngcd[13].creator = GRadioCreate;
7719 
7720     nlabel[14].text = (unichar_t *) "";
7721     nlabel[14].text_is_1byte = true;
7722     ngcd[14].gd.label = &nlabel[14];
7723     ngcd[14].gd.flags = sf->defbasefilename!=NULL ?
7724 		(gg_visible | gg_enabled | gg_cb_on | gg_rad_continueold ) :
7725 		(gg_visible | gg_enabled | gg_rad_continueold);
7726     ngcd[14].gd.cid = CID_HasDefBase;
7727     ngcd[14].creator = GRadioCreate;
7728 
7729     ngcd[15].gd.flags = gg_visible | gg_enabled|gg_text_xim;
7730     nlabel[15].text = (unichar_t *) (sf->defbasefilename?sf->defbasefilename:"");
7731     nlabel[15].text_is_1byte = true;
7732     ngcd[15].gd.label = &nlabel[15];
7733     ngcd[15].gd.cid = CID_DefBaseName;
7734     ngcd[15].gd.handle_controlevent = GFI_DefBaseChange;
7735     ngcd[15].creator = GTextFieldCreate;
7736 
7737     ngcd[16].gd.flags = gg_visible | gg_enabled;
7738     nlabel[16].text = (unichar_t *) _("Copy_right:");
7739     nlabel[16].text_is_1byte = true;
7740     nlabel[16].text_in_resource = true;
7741     ngcd[16].gd.label = &nlabel[16];
7742     ngcd[16].creator = GLabelCreate;
7743 
7744     ngcd[17].gd.pos.width = ngcd[5].gd.pos.x+ngcd[5].gd.pos.width-26;
7745     ngcd[17].gd.flags = gg_visible | gg_enabled | gg_textarea_wrap;
7746     copied_copyright = NULL;
7747     if ( sf->copyright!=NULL ) {
7748 	if ( !AllAscii(sf->copyright))
7749 	    nlabel[17].text = (unichar_t *) (copied_copyright = StripToASCII(sf->copyright));
7750 	else
7751 	    nlabel[17].text = (unichar_t *) sf->copyright;
7752 	nlabel[17].text_is_1byte = true;
7753 	ngcd[17].gd.label = &nlabel[17];
7754     }
7755     ngcd[17].gd.cid = CID_Notice;
7756     ngcd[17].gd.popup_msg = _("This must be ASCII, so you may not use the copyright symbol (use (c) instead).");
7757     ngcd[17].creator = GTextAreaCreate;
7758 
7759     memset(&nb,0,sizeof(nb)); memset(&nb2,0,sizeof(nb2)); memset(&nb3,0,sizeof(nb3));
7760 
7761     narray3[0] = &ngcd[14]; narray3[1] = &ngcd[15]; narray3[2] = NULL;
7762 
7763     narray2[0] = &ngcd[12]; narray2[1] = &ngcd[13]; narray2[2] = NULL;
7764     narray2[3] = GCD_RowSpan; narray2[4] = &nb3; narray2[5] = NULL;
7765     narray2[6] = NULL;
7766 
7767     narray[0] = &ngcd[0]; narray[1] = &ngcd[1]; narray[2] = NULL;
7768     narray[3] = &ngcd[2]; narray[4] = &ngcd[3]; narray[5] = NULL;
7769     narray[6] = &ngcd[4]; narray[7] = &ngcd[5]; narray[8] = NULL;
7770     narray[9] = &ngcd[6]; narray[10] = &ngcd[7]; narray[11] = NULL;
7771     narray[12] = &ngcd[8]; narray[13] = &ngcd[9]; narray[14] = NULL;
7772     narray[15] = &ngcd[10]; narray[16] = &ngcd[11]; narray[17] = NULL;
7773     narray[18] = &nb2; narray[19] = GCD_ColSpan; narray[20] = NULL;
7774     narray[21] = &ngcd[16]; narray[22] = GCD_ColSpan; narray[23] = NULL;
7775     narray[24] = &ngcd[17]; narray[25] = GCD_ColSpan; narray[26] = NULL;
7776     narray[27] = NULL;
7777 
7778     nb3.gd.flags = gg_enabled|gg_visible;
7779     nb3.gd.u.boxelements = narray3;
7780     nb3.creator = GHBoxCreate;
7781 
7782     nb2.gd.flags = gg_enabled|gg_visible;
7783     nb2.gd.u.boxelements = narray2;
7784     nb2.creator = GHVBoxCreate;
7785 
7786     nb[0].gd.flags = gg_enabled|gg_visible;
7787     nb[0].gd.u.boxelements = narray;
7788     nb[0].creator = GHVBoxCreate;
7789 
7790 /******************************************************************************/
7791     memset(&xulabel,0,sizeof(xulabel));
7792     memset(&xugcd,0,sizeof(xugcd));
7793 
7794     xulabel[0].text = (unichar_t *) _("(Adobe now considers XUID/UniqueID unnecessary)");
7795     xulabel[0].text_is_1byte = true;
7796     xulabel[0].text_in_resource = true;
7797     xugcd[0].gd.label = &xulabel[0];
7798     xugcd[0].gd.flags = gg_visible | gg_enabled;
7799     xugcd[0].creator = GLabelCreate;
7800 
7801     xulabel[1].text = (unichar_t *) _("Use XUID");
7802     xulabel[1].text_is_1byte = true;
7803     xulabel[1].text_in_resource = true;
7804     xugcd[1].gd.label = &xulabel[1];
7805     xugcd[1].gd.flags = gg_visible | gg_enabled;
7806     if ( sf->use_xuid ) xugcd[1].gd.flags = gg_visible | gg_enabled | gg_cb_on;
7807     xugcd[1].gd.cid = CID_UseXUID;
7808     xugcd[1].gd.handle_controlevent = GFI_UseXUIDChanged;
7809     xugcd[1].creator = GCheckBoxCreate;
7810 
7811     xugcd[2].gd.pos.x = 12; xugcd[2].gd.pos.y = 10+6;
7812     xugcd[2].gd.flags = gg_visible | gg_enabled;
7813     xulabel[2].text = (unichar_t *) _("_XUID:");
7814     xulabel[2].text_is_1byte = true;
7815     xulabel[2].text_in_resource = true;
7816     xugcd[2].gd.label = &xulabel[2];
7817     xugcd[2].creator = GLabelCreate;
7818 
7819     xugcd[3].gd.flags = gg_visible;
7820     if ( sf->use_xuid ) xugcd[3].gd.flags = gg_visible | gg_enabled;
7821     if ( sf->xuid!=NULL ) {
7822 	xulabel[3].text = (unichar_t *) sf->xuid;
7823 	xulabel[3].text_is_1byte = true;
7824 	xugcd[3].gd.label = &xulabel[3];
7825     }
7826     xugcd[3].gd.cid = CID_XUID;
7827     xugcd[3].creator = GTextFieldCreate;
7828 
7829     xulabel[4].text = (unichar_t *) _("Use UniqueID");
7830     xulabel[4].text_is_1byte = true;
7831     xulabel[4].text_in_resource = true;
7832     xugcd[4].gd.label = &xulabel[4];
7833     xugcd[4].gd.flags = gg_visible | gg_enabled;
7834     if ( sf->use_uniqueid ) xugcd[4].gd.flags = gg_visible | gg_enabled | gg_cb_on;
7835     xugcd[4].gd.cid = CID_UseUniqueID;
7836     xugcd[4].gd.handle_controlevent = GFI_UseUniqueIDChanged;
7837     xugcd[4].creator = GCheckBoxCreate;
7838 
7839     xulabel[5].text = (unichar_t *) _("_UniqueID:");
7840     xulabel[5].text_is_1byte = true;
7841     xulabel[5].text_in_resource = true;
7842     xugcd[5].gd.label = &xulabel[5];
7843     xugcd[5].gd.flags = gg_visible | gg_enabled;
7844     xugcd[5].creator = GLabelCreate;
7845 
7846     xugcd[6].gd.flags = gg_visible;
7847     if ( sf->use_uniqueid ) xugcd[6].gd.flags = gg_visible | gg_enabled;
7848     xulabel[6].text = (unichar_t *) "";
7849     xulabel[6].text_is_1byte = true;
7850     if ( sf->uniqueid!=0 ) {
7851 	sprintf( uibuf, "%d", sf->uniqueid );
7852 	xulabel[6].text = (unichar_t *) uibuf;
7853     }
7854     xugcd[6].gd.label = &xulabel[6];
7855     xugcd[6].gd.cid = CID_UniqueID;
7856     xugcd[6].creator = GTextFieldCreate;
7857 
7858     xuarray[0] = &xugcd[0]; xuarray[1] = GCD_ColSpan; xuarray[2] = NULL;
7859     xuarray[3] = &xugcd[1]; xuarray[4] = GCD_ColSpan; xuarray[5] = NULL;
7860     xuarray[6] = &xugcd[2]; xuarray[7] = &xugcd[3]; xuarray[8] = NULL;
7861     xuarray[9] = &xugcd[4]; xuarray[10] = GCD_ColSpan; xuarray[11] = NULL;
7862     xuarray[12] = &xugcd[5]; xuarray[13] = &xugcd[6]; xuarray[14] = NULL;
7863     xuarray[15] = GCD_Glue; xuarray[16] = GCD_Glue; xuarray[17] = NULL;
7864     xuarray[18] = NULL;
7865 
7866     memset(xub,0,sizeof(xub));
7867     xub[0].gd.flags = gg_enabled|gg_visible;
7868     xub[0].gd.u.boxelements = xuarray;
7869     xub[0].creator = GHVBoxCreate;
7870 
7871 /******************************************************************************/
7872     memset(&pslabel,0,sizeof(pslabel));
7873     memset(&psgcd,0,sizeof(psgcd));
7874 
7875     psgcd[0].gd.pos.x = 12; psgcd[0].gd.pos.y = 12;
7876     psgcd[0].gd.flags = gg_visible | gg_enabled;
7877     pslabel[0].text = (unichar_t *) _("_Ascent:");
7878     pslabel[0].text_is_1byte = true;
7879     pslabel[0].text_in_resource = true;
7880     psgcd[0].gd.label = &pslabel[0];
7881     psgcd[0].creator = GLabelCreate;
7882 
7883     psgcd[1].gd.pos.x = 103; psgcd[1].gd.pos.y = psgcd[0].gd.pos.y-6; psgcd[1].gd.pos.width = 47;
7884     psgcd[1].gd.flags = gg_visible | gg_enabled;
7885     sprintf( asbuf, "%d", sf->ascent );
7886     pslabel[1].text = (unichar_t *) asbuf;
7887     pslabel[1].text_is_1byte = true;
7888     psgcd[1].gd.label = &pslabel[1];
7889     psgcd[1].gd.cid = CID_Ascent;
7890     psgcd[1].gd.handle_controlevent = GFI_EmChanged;
7891     psgcd[1].creator = GTextFieldCreate;
7892 
7893     psgcd[2].gd.pos.x = 155; psgcd[2].gd.pos.y = psgcd[0].gd.pos.y;
7894     psgcd[2].gd.flags = gg_visible | gg_enabled;
7895     pslabel[2].text = (unichar_t *) _("_Descent:");
7896     pslabel[2].text_is_1byte = true;
7897     pslabel[2].text_in_resource = true;
7898     psgcd[2].gd.label = &pslabel[2];
7899     psgcd[2].creator = GLabelCreate;
7900 
7901     psgcd[3].gd.pos.x = 200; psgcd[3].gd.pos.y = psgcd[1].gd.pos.y; psgcd[3].gd.pos.width = 47;
7902     psgcd[3].gd.flags = gg_visible | gg_enabled;
7903     sprintf( dsbuf, "%d", sf->descent );
7904     pslabel[3].text = (unichar_t *) dsbuf;
7905     pslabel[3].text_is_1byte = true;
7906     psgcd[3].gd.label = &pslabel[3];
7907     psgcd[3].gd.cid = CID_Descent;
7908     psgcd[3].gd.handle_controlevent = GFI_EmChanged;
7909     psgcd[3].creator = GTextFieldCreate;
7910 
7911     psgcd[4].gd.pos.x = psgcd[0].gd.pos.x+5; psgcd[4].gd.pos.y = psgcd[0].gd.pos.y+24;
7912     psgcd[4].gd.flags = gg_visible | gg_enabled;
7913     pslabel[4].text = (unichar_t *) _(" _Em Size:");
7914     pslabel[4].text_is_1byte = true;
7915     pslabel[4].text_in_resource = true;
7916     psgcd[4].gd.label = &pslabel[4];
7917     psgcd[4].creator = GLabelCreate;
7918 
7919     psgcd[5].gd.pos.x = psgcd[1].gd.pos.x-20; psgcd[5].gd.pos.y = psgcd[1].gd.pos.y+24; psgcd[5].gd.pos.width = 67;
7920     psgcd[5].gd.flags = gg_visible | gg_enabled;
7921     sprintf( embuf, "%d", sf->descent+sf->ascent );
7922     pslabel[5].text = (unichar_t *) embuf;
7923     pslabel[5].text_is_1byte = true;
7924     psgcd[5].gd.label = &pslabel[5];
7925     psgcd[5].gd.cid = CID_Em;
7926     psgcd[5].gd.u.list = emsizes;
7927     psgcd[5].gd.handle_controlevent = GFI_EmChanged;
7928     psgcd[5].creator = GListFieldCreate;
7929 
7930     psgcd[6].gd.pos.x = psgcd[2].gd.pos.x; psgcd[6].gd.pos.y = psgcd[4].gd.pos.y-4;
7931     psgcd[6].gd.flags = gg_visible | gg_enabled | gg_cb_on;
7932     pslabel[6].text = (unichar_t *) _("_Scale Outlines");
7933     pslabel[6].text_is_1byte = true;
7934     pslabel[6].text_in_resource = true;
7935     psgcd[6].gd.label = &pslabel[6];
7936     psgcd[6].gd.cid = CID_Scale;
7937     psgcd[6].creator = GCheckBoxCreate;
7938 
7939 /* I've reversed the label, text field order in the gcd here because */
7940 /*  that way the text field will be displayed on top of the label rather */
7941 /*  than the reverse, and in Russian that's important translation of */
7942 /*  "Italic Angle" is too long. Oops, no it's the next one, might as well leave in here though */
7943     psgcd[8].gd.pos.x = 12; psgcd[8].gd.pos.y = psgcd[5].gd.pos.y+26+6;
7944     psgcd[8].gd.flags = gg_visible | gg_enabled;
7945     pslabel[8].text = (unichar_t *) _("_Italic Angle:");
7946     pslabel[8].text_is_1byte = true;
7947     pslabel[8].text_in_resource = true;
7948     psgcd[8].gd.label = &pslabel[8];
7949     psgcd[8].creator = GLabelCreate;
7950 
7951     psgcd[7].gd.pos.x = 103; psgcd[7].gd.pos.y = psgcd[8].gd.pos.y-6;
7952     psgcd[7].gd.pos.width = 47;
7953     psgcd[7].gd.flags = gg_visible | gg_enabled;
7954     sprintf( iabuf, "%g", (double) sf->italicangle );
7955     pslabel[7].text = (unichar_t *) iabuf;
7956     pslabel[7].text_is_1byte = true;
7957     psgcd[7].gd.label = &pslabel[7];
7958     psgcd[7].gd.cid = CID_ItalicAngle;
7959     psgcd[7].creator = GTextFieldCreate;
7960 
7961     psgcd[9].gd.pos.y = psgcd[7].gd.pos.y;
7962     psgcd[9].gd.pos.width = -1; psgcd[9].gd.pos.height = 0;
7963     psgcd[9].gd.pos.x = psgcd[3].gd.pos.x+psgcd[3].gd.pos.width-
7964 	    GIntGetResource(_NUM_Buttonsize)*100/GIntGetResource(_NUM_ScaleFactor);
7965     /*if ( strstrmatch(sf->fontname,"Italic")!=NULL ||strstrmatch(sf->fontname,"Oblique")!=NULL )*/
7966 	psgcd[9].gd.flags = gg_visible | gg_enabled;
7967     pslabel[9].text = (unichar_t *) _("_Guess");
7968     pslabel[9].text_is_1byte = true;
7969     pslabel[9].text_in_resource = true;
7970     psgcd[9].gd.label = &pslabel[9];
7971     psgcd[9].gd.handle_controlevent = GFI_GuessItalic;
7972     psgcd[9].creator = GButtonCreate;
7973 
7974 /* I've reversed the label, text field order in the gcd here because */
7975 /*  that way the text field will be displayed on top of the label rather */
7976 /*  than the reverse, and in Russian that's important translation of */
7977 /*  "Underline position" is too long. */
7978     psgcd[11].gd.pos.x = 12; psgcd[11].gd.pos.y = psgcd[7].gd.pos.y+26+6;
7979     psgcd[11].gd.flags = gg_visible | gg_enabled;
7980     pslabel[11].text = (unichar_t *) _("Underline _Position:");
7981     pslabel[11].text_is_1byte = true;
7982     pslabel[11].text_in_resource = true;
7983     psgcd[11].gd.label = &pslabel[11];
7984     psgcd[11].creator = GLabelCreate;
7985 
7986     psgcd[10].gd.pos.x = 103; psgcd[10].gd.pos.y = psgcd[11].gd.pos.y-6; psgcd[10].gd.pos.width = 47;
7987     psgcd[10].gd.flags = gg_visible | gg_enabled;
7988     sprintf( upbuf, "%g", (double) sf->upos );
7989     pslabel[10].text = (unichar_t *) upbuf;
7990     pslabel[10].text_is_1byte = true;
7991     psgcd[10].gd.label = &pslabel[10];
7992     psgcd[10].gd.cid = CID_UPos;
7993     psgcd[10].creator = GTextFieldCreate;
7994 
7995     psgcd[12].gd.pos.x = 155; psgcd[12].gd.pos.y = psgcd[11].gd.pos.y;
7996     psgcd[12].gd.flags = gg_visible | gg_enabled;
7997     pslabel[12].text = (unichar_t *) S_("Underline|_Height:");
7998     pslabel[12].text_is_1byte = true;
7999     pslabel[12].text_in_resource = true;
8000     psgcd[12].gd.label = &pslabel[12];
8001     psgcd[12].creator = GLabelCreate;
8002 
8003     psgcd[13].gd.pos.x = 200; psgcd[13].gd.pos.y = psgcd[10].gd.pos.y; psgcd[13].gd.pos.width = 47;
8004     psgcd[13].gd.flags = gg_visible | gg_enabled;
8005     sprintf( uwbuf, "%g", (double) sf->uwidth );
8006     pslabel[13].text = (unichar_t *) uwbuf;
8007     pslabel[13].text_is_1byte = true;
8008     psgcd[13].gd.label = &pslabel[13];
8009     psgcd[13].gd.cid = CID_UWidth;
8010     psgcd[13].creator = GTextFieldCreate;
8011 
8012     psgcd[14].gd.pos.x = 12; psgcd[14].gd.pos.y = psgcd[13].gd.pos.y+26;
8013     pslabel[14].text = (unichar_t *) _("Has _Vertical Metrics");
8014     pslabel[14].text_is_1byte = true;
8015     pslabel[14].text_in_resource = true;
8016     psgcd[14].gd.label = &pslabel[14];
8017     psgcd[14].gd.cid = CID_HasVerticalMetrics;
8018     psgcd[14].gd.flags = gg_visible | gg_enabled;
8019     if ( sf->hasvmetrics )
8020 	psgcd[14].gd.flags |= gg_cb_on;
8021     psgcd[14].gd.handle_controlevent = GFI_VMetricsCheck;
8022     psgcd[14].creator = GCheckBoxCreate;
8023     k = 15;
8024 
8025     psgcd[k].gd.pos.x = psgcd[k-2].gd.pos.x; psgcd[k].gd.pos.y = psgcd[k-1].gd.pos.y+32;
8026     psgcd[k].gd.flags = gg_visible | gg_enabled;
8027     pslabel[k].text = (unichar_t *) _("Interpretation:");
8028     pslabel[k].text_is_1byte = true;
8029     pslabel[k].text_in_resource = true;
8030     psgcd[k].gd.label = &pslabel[k];
8031     psgcd[k++].creator = GLabelCreate;
8032 
8033     psgcd[k].gd.pos.x = psgcd[k-2].gd.pos.x; psgcd[k].gd.pos.y = psgcd[k-1].gd.pos.y-6;
8034     psgcd[k].gd.flags = gg_visible | gg_enabled;
8035     psgcd[k].gd.u.list = interpretations;
8036     psgcd[k].gd.cid = CID_Interpretation;
8037     psgcd[k].creator = GListButtonCreate;
8038     for ( i=0; interpretations[i].text!=NULL || interpretations[i].line; ++i ) {
8039 	if ( (void *) (sf->uni_interp)==interpretations[i].userdata &&
8040 		interpretations[i].text!=NULL ) {
8041 	    interpretations[i].selected = true;
8042 	    psgcd[k].gd.label = &interpretations[i];
8043 	} else
8044 	    interpretations[i].selected = false;
8045     }
8046     ++k;
8047 
8048     psgcd[k].gd.pos.x = psgcd[k-2].gd.pos.x; psgcd[k].gd.pos.y = psgcd[k-1].gd.pos.y+32;
8049     psgcd[k].gd.flags = gg_visible | gg_enabled;
8050     pslabel[k].text = (unichar_t *) _("Name List:");
8051     pslabel[k].text_is_1byte = true;
8052     pslabel[k].text_in_resource = true;
8053     psgcd[k].gd.label = &pslabel[k];
8054     psgcd[k++].creator = GLabelCreate;
8055 
8056     psgcd[k].gd.pos.x = psgcd[k-2].gd.pos.x; psgcd[k].gd.pos.y = psgcd[k-1].gd.pos.y-6;
8057     psgcd[k].gd.flags = gg_visible | gg_enabled;
8058     psgcd[k].gd.cid = CID_Namelist;
8059     psgcd[k].creator = GListButtonCreate;
8060     nlnames = AllNamelistNames();
8061     for ( i=0; nlnames[i]!=NULL; ++i);
8062     namelistnames = calloc(i+1,sizeof(GTextInfo));
8063     for ( i=0; nlnames[i]!=NULL; ++i) {
8064 	namelistnames[i].text = (unichar_t *) nlnames[i];
8065 	namelistnames[i].text_is_1byte = true;
8066 	if ( strcmp(_(sf->for_new_glyphs->title),nlnames[i])==0 ) {
8067 	    namelistnames[i].selected = true;
8068 	    psgcd[k].gd.label = &namelistnames[i];
8069 	}
8070     }
8071     psgcd[k++].gd.u.list = namelistnames;
8072     free(nlnames);
8073 
8074 
8075     if ( sf->subfontcnt!=0 ) {
8076 	for ( i=0; i<=13; ++i )
8077 	    psgcd[i].gd.flags &= ~gg_enabled;
8078     } else if ( sf->cidmaster!=NULL ) {
8079 	for ( i=14; i<=16; ++i )
8080 	    psgcd[i].gd.flags &= ~gg_enabled;
8081     }
8082 
8083     psarray[0] = &psb2[0];
8084     psarray[1] = &psgcd[14];
8085     j=2;
8086     psarray[j++] = &psb2[1];
8087     psrow = j;
8088     psarray[j++] = GCD_Glue;
8089     psarray[j++] = NULL;
8090 
8091     psarray2[0] = &psgcd[0]; psarray2[1] = &psgcd[1]; psarray2[2] = &psgcd[2]; psarray2[3] = &psgcd[3]; psarray2[4] = NULL;
8092     psarray2[5] = &psgcd[4]; psarray2[6] = &psgcd[5]; psarray2[7] = &psgcd[6]; psarray2[8] = GCD_ColSpan; psarray2[9] = NULL;
8093     psarray2[10] = &psgcd[8]; psarray2[11] = &psgcd[7]; psarray2[12] = &psgcd[9]; psarray2[13] = GCD_ColSpan; psarray2[14] = NULL;
8094     psarray2[15] = &psgcd[11]; psarray2[16] = &psgcd[10]; psarray2[17] = &psgcd[12]; psarray2[18] = &psgcd[13]; psarray2[19] = NULL;
8095     psarray2[20] = NULL;
8096 
8097     psarray4[0] = &psgcd[k-4]; psarray4[1] = &psgcd[k-3]; psarray4[2] = NULL;
8098     psarray4[3] = &psgcd[k-2]; psarray4[4] = &psgcd[k-1]; psarray4[5] = NULL;
8099     psarray4[6] = NULL;
8100 
8101     memset(psb,0,sizeof(psb));
8102     psb[0].gd.flags = gg_enabled|gg_visible;
8103     psb[0].gd.u.boxelements = psarray;
8104     psb[0].creator = GVBoxCreate;
8105 
8106     memset(psb2,0,sizeof(psb2));
8107     psb2[0].gd.flags = gg_enabled|gg_visible;
8108     psb2[0].gd.u.boxelements = psarray2;
8109     psb2[0].creator = GHVBoxCreate;
8110 
8111     psb2[1].gd.flags = gg_enabled|gg_visible;
8112     psb2[1].gd.u.boxelements = psarray4;
8113     psb2[1].creator = GHVBoxCreate;
8114 /******************************************************************************/
8115 
8116     memset(&llabel,0,sizeof(llabel));
8117     memset(&lgcd,0,sizeof(lgcd));
8118     memset(&lbox,0,sizeof(lbox));
8119 
8120     ltype = -1;
8121     for ( j=0; j<sf->layer_cnt; ++j ) {
8122 	if ( ltype==-1 )
8123 	    ltype = sf->layers[j].order2;
8124 	else if ( ltype!=sf->layers[j].order2 )
8125 	    ltype = -2;
8126     }
8127 
8128     k = j = 0;
8129 
8130     lgcd[k].gd.pos.x = 12; lgcd[k].gd.pos.y = 0;
8131     llabel[k].text = (unichar_t *) _("Font Type:");
8132     llabel[k].text_is_1byte = true;
8133     llabel[k].text_in_resource = true;
8134     lgcd[k].gd.label = &llabel[k];
8135     lgcd[k].gd.flags = (gg_visible | gg_enabled);
8136     lgcd[k++].creator = GLabelCreate;
8137     larray2[j++] = &lgcd[k-1]; larray2[j++] = GCD_ColSpan; larray2[j++] = GCD_Glue; larray2[j++] = GCD_Glue; larray2[j++] = NULL;
8138 
8139     lgcd[k].gd.pos.x = 12; lgcd[k].gd.pos.y = lgcd[k-1].gd.pos.y+k;
8140     llabel[k].text = (unichar_t *) _("_Outline Font");
8141     llabel[k].text_is_1byte = true;
8142     llabel[k].text_in_resource = true;
8143     lgcd[k].gd.label = &llabel[k];
8144     lgcd[k].gd.flags = (!sf->strokedfont && !sf->multilayer)?
8145 	    (gg_visible | gg_enabled | gg_cb_on) : (gg_visible | gg_enabled);
8146     lgcd[k].gd.handle_controlevent = GFI_Type3Change;
8147     lgcd[k++].creator = GRadioCreate;
8148     larray2[j++] = GCD_HPad10; larray2[j++] = &lgcd[k-1]; larray2[j++] = GCD_Glue; larray2[j++] = GCD_Glue; larray2[j++] = NULL;
8149 
8150     lgcd[k].gd.pos.x = 12; lgcd[k].gd.pos.y = lgcd[k-1].gd.pos.y+14;
8151     llabel[k].text = (unichar_t *) _("_Type3 Multi Layered Font");
8152     llabel[k].text_is_1byte = true;
8153     llabel[k].text_in_resource = true;
8154     lgcd[k].gd.label = &llabel[k];
8155     lgcd[k].gd.flags = ltype!=0 ? (gg_visible| gg_rad_continueold) :
8156 	sf->multilayer ? (gg_visible | gg_enabled| gg_cb_on | gg_rad_continueold) :
8157 	(gg_visible | gg_enabled| gg_rad_continueold);
8158     lgcd[k].gd.cid = CID_IsMultiLayer;
8159     lgcd[k].gd.handle_controlevent = GFI_Type3Change;
8160     lgcd[k].creator = GRadioCreate;
8161     lgcd[k++].gd.popup_msg = _("Allow editing of multiple colors and shades, fills and strokes.\nMulti layered fonts can only be output as type3 or svg fonts.");
8162     larray2[j++] = GCD_HPad10; larray2[j++] = &lgcd[k-1]; larray2[j++] = GCD_ColSpan; larray2[j++] = GCD_Glue; larray2[j++] = NULL;
8163 
8164     lgcd[k].gd.pos.x = 12; lgcd[k].gd.pos.y = lgcd[k-1].gd.pos.y+14;
8165     llabel[k].text = (unichar_t *) _("_Stroked Font");
8166     llabel[k].text_is_1byte = true;
8167     llabel[k].text_in_resource = true;
8168     lgcd[k].gd.label = &llabel[k];
8169     lgcd[k].gd.flags = sf->strokedfont ? (gg_visible | gg_enabled| gg_cb_on) : (gg_visible | gg_enabled);
8170     lgcd[k].gd.cid = CID_IsStrokedFont;
8171     lgcd[k].gd.handle_controlevent = GFI_Type3Change;
8172     lgcd[k].creator = GRadioCreate;
8173     lgcd[k++].gd.popup_msg = _("Glyphs will be composed of stroked lines rather than filled outlines.\nAll glyphs are stroked at the following width");
8174     larray2[j++] = GCD_HPad10; larray2[j++] = &lgcd[k-1];
8175 
8176     lgcd[k].gd.pos.x = 12; lgcd[k].gd.pos.y = lgcd[k-1].gd.pos.y+20;
8177     llabel[k].text = (unichar_t *) _("  Stroke _Width:");
8178     llabel[k].text_is_1byte = true;
8179     llabel[k].text_in_resource = true;
8180     lgcd[k].gd.label = &llabel[k];
8181     lgcd[k].gd.flags = gg_visible | gg_enabled;
8182     lgcd[k++].creator = GLabelCreate;
8183     larray2[j++] = &lgcd[k-1];
8184 
8185     sprintf( swbuf,"%g", (double) sf->strokewidth );
8186     lgcd[k].gd.pos.x = 115; lgcd[k].gd.pos.y = lgcd[k-1].gd.pos.y-6; lgcd[k].gd.pos.width = 137;
8187     lgcd[k].gd.flags = gg_visible | gg_enabled;
8188     llabel[k].text = (unichar_t *) swbuf;
8189     llabel[k].text_is_1byte = true;
8190     lgcd[k].gd.label = &llabel[k];
8191     lgcd[k].gd.cid = CID_StrokeWidth;
8192     lgcd[k++].creator = GTextFieldCreate;
8193     larray2[j++] = &lgcd[k-1]; larray2[j++] = NULL; larray2[j++] = NULL;
8194 
8195     lbox[2].gd.flags = gg_enabled|gg_visible;
8196     lbox[2].gd.u.boxelements = larray2;
8197     lbox[2].creator = GHVBoxCreate;
8198     larray[0] = &lbox[2]; larray[1] = NULL;
8199 
8200     llabel[k].text = (unichar_t *) _("All layers _cubic");
8201     llabel[k].text_is_1byte = true;
8202     llabel[k].text_in_resource = true;
8203     lgcd[k].gd.label = &llabel[k];
8204     lgcd[k].gd.flags = ltype==0 || sf->multilayer ?
8205 	(gg_visible | gg_enabled | gg_cb_on) :
8206 	(gg_visible | gg_enabled);
8207     lgcd[k].gd.cid = CID_IsOrder3;
8208     lgcd[k].gd.handle_controlevent = GFI_OrderChange;
8209     lgcd[k].creator = GRadioCreate;
8210     lgcd[k++].gd.popup_msg = _(
8211 	"Use cubic (that is postscript) splines to hold the outlines of all\n"
8212 	"layers of this font. Cubic splines are generally easier to edit\n"
8213 	"than quadratic (and you may still generate a truetype font from them).");
8214 
8215     llabel[k].text = (unichar_t *) _("All layers _quadratic");
8216     llabel[k].text_is_1byte = true;
8217     llabel[k].text_in_resource = true;
8218     lgcd[k].gd.label = &llabel[k];
8219     lgcd[k].gd.flags = sf->multilayer ? (gg_visible) :
8220 	    ltype==1 ? (gg_visible | gg_enabled | gg_cb_on) :
8221 		(gg_visible | gg_enabled);
8222     lgcd[k].gd.cid = CID_IsOrder2;
8223     lgcd[k].gd.handle_controlevent = GFI_OrderChange;
8224     lgcd[k].creator = GRadioCreate;
8225     lgcd[k++].gd.popup_msg = _(
8226 	"Use quadratic (that is truetype) splines to hold the outlines of all\n"
8227 	"layers of this font rather than cubic (postscript) splines.");
8228 
8229     llabel[k].text = (unichar_t *) _("_Mixed");
8230     llabel[k].text_is_1byte = true;
8231     llabel[k].text_in_resource = true;
8232     lgcd[k].gd.label = &llabel[k];
8233     lgcd[k].gd.flags = sf->multilayer ? (gg_visible) :
8234 	    ltype<0 ? (gg_visible | gg_enabled | gg_cb_on) :
8235 		(gg_visible | gg_enabled);
8236     lgcd[k].gd.handle_controlevent = GFI_OrderChange;
8237     lgcd[k].gd.cid = CID_IsMixed;
8238     lgcd[k].creator = GRadioCreate;
8239     lgcd[k++].gd.popup_msg = _(
8240 	"The order of each layer of the font can be controlled\n"
8241 	"individually. This might be useful if you wished to\n"
8242 	"retain both quadratic and cubic versions of a font.");
8243     larray3[0] = &lgcd[k-3]; larray3[1] = &lgcd[k-2]; larray3[2] = &lgcd[k-1]; larray3[3] = GCD_Glue; larray3[4] = NULL;
8244 
8245     lbox[3].gd.flags = gg_enabled|gg_visible;
8246     lbox[3].gd.u.boxelements = larray3;
8247     lbox[3].creator = GHBoxCreate;
8248     larray[2] = GCD_HPad10; larray[3] = NULL;
8249     larray[4] = &lbox[3]; larray[5] = NULL;
8250 
8251     lgcd[k].gd.pos.x = 12; lgcd[k].gd.pos.y = 0;
8252     llabel[k].text = (unichar_t *) _("Guidelines:");
8253     llabel[k].text_is_1byte = true;
8254     llabel[k].text_in_resource = true;
8255     lgcd[k].gd.label = &llabel[k];
8256     lgcd[k].gd.flags = (gg_visible | gg_enabled);
8257     lgcd[k++].creator = GLabelCreate;
8258     larray4[0] = &lgcd[k-1];
8259 
8260     llabel[k].text = (unichar_t *) _("Quadratic");
8261     llabel[k].text_is_1byte = true;
8262     llabel[k].text_in_resource = true;
8263     lgcd[k].gd.label = &llabel[k];
8264     lgcd[k].gd.flags = sf->multilayer || ltype>=0 ? (gg_visible) :
8265 	    (gg_visible | gg_enabled);
8266     if ( sf->grid.order2 )
8267 	lgcd[k].gd.flags |= gg_cb_on;
8268     lgcd[k].gd.cid = CID_GuideOrder2;
8269     lgcd[k].creator = GCheckBoxCreate;
8270     lgcd[k++].gd.popup_msg = _(
8271 	"Use quadratic splines for the guidelines layer of the font");
8272     larray4[1] = &lgcd[k-1]; larray4[2] = GCD_Glue; larray4[3] = NULL;
8273 
8274     lbox[4].gd.flags = gg_enabled|gg_visible;
8275     lbox[4].gd.u.boxelements = larray4;
8276     lbox[4].creator = GHBoxCreate;
8277     larray[6] = &lbox[4]; larray[7] = NULL;
8278 
8279     lgcd[k].gd.pos.x = 12; lgcd[k].gd.pos.y = 0;
8280     llabel[k].text = (unichar_t *) _("\nLayers:");
8281     llabel[k].text_is_1byte = true;
8282     llabel[k].text_in_resource = true;
8283     lgcd[k].gd.label = &llabel[k];
8284     lgcd[k].gd.flags = (gg_visible | gg_enabled);
8285     lgcd[k++].creator = GLabelCreate;
8286     larray[8] = &lgcd[k-1]; larray[9] = NULL;
8287 
8288     LayersMatrixInit(&layersmi,d);
8289 
8290     lgcd[k].gd.pos.width = 300; lgcd[k].gd.pos.height = 180;
8291     lgcd[k].gd.flags = sf->multilayer ? gg_visible : (gg_enabled | gg_visible);
8292     lgcd[k].gd.cid = CID_Backgrounds;
8293     lgcd[k].gd.u.matrix = &layersmi;
8294     lgcd[k].data = d;
8295     lgcd[k++].creator = GMatrixEditCreate;
8296     larray[10] = &lgcd[k-1]; larray[11] = NULL; larray[12] = NULL;
8297 
8298     lbox[0].gd.flags = gg_enabled|gg_visible;
8299     lbox[0].gd.u.boxelements = larray;
8300     lbox[0].creator = GHVGroupCreate;
8301 
8302 /******************************************************************************/
8303 
8304     memset(&plabel,0,sizeof(plabel));
8305     memset(&pgcd,0,sizeof(pgcd));
8306 
8307     PSPrivate_MatrixInit(&private_mi,d);
8308 
8309     i=0;
8310     pgcd[i].gd.pos.width = 300; pgcd[i].gd.pos.height = 200;
8311     pgcd[i].gd.flags = gg_enabled | gg_visible;
8312     pgcd[i].gd.cid = CID_Private;
8313     pgcd[i].gd.u.matrix = &private_mi;
8314     pgcd[i].gd.popup_msg = _(
8315 	"The PostScript 'Private' dictionary gives you control over\n"
8316 	"several font-wide versions of hinting.\n"
8317 	"The 'Private' dictionary only applies to PostScript fonts.");
8318     pgcd[i].data = d;
8319     pgcd[i++].creator = GMatrixEditCreate;
8320     pparray[0] = &pgcd[0]; pparray[1] = NULL;
8321 
8322     memset(ppbox,0,sizeof(ppbox));
8323     ppbox[0].gd.flags = gg_enabled|gg_visible;
8324     ppbox[0].gd.u.boxelements = pparray;
8325     ppbox[0].creator = GVBoxCreate;
8326 
8327 
8328     memset(&privatelabel_def,0,sizeof(privatelabel_def));
8329     memset(&privategcd_def,0,sizeof(privategcd_def));
8330     privategcd_def[0].gd.flags = gg_visible ;
8331     privatelabel_def[0].text = (unichar_t *) _("_Guess");
8332     privatelabel_def[0].text_is_1byte = true;
8333     privatelabel_def[0].text_in_resource = true;
8334     privategcd_def[0].gd.label = &privatelabel_def[0];
8335     privategcd_def[0].gd.handle_controlevent = PI_Guess;
8336     privategcd_def[0].gd.cid = CID_Guess;
8337     privategcd_def[0].creator = GButtonCreate;
8338 
8339     privategcd_def[1].gd.flags = gg_visible;
8340     privatelabel_def[1].text = (unichar_t *) _("_Histogram");
8341     privatelabel_def[1].text_is_1byte = true;
8342     privatelabel_def[1].text_in_resource = true;
8343     privategcd_def[1].gd.label = &privatelabel_def[1];
8344     privategcd_def[1].gd.handle_controlevent = PI_Hist;
8345     privategcd_def[1].gd.cid = CID_Hist;
8346     privategcd_def[1].gd.popup_msg = _("Histogram Dialog");
8347     privategcd_def[1].creator = GButtonCreate;
8348 
8349 /******************************************************************************/
8350     memset(&vlabel,0,sizeof(vlabel));
8351     memset(&vgcd,0,sizeof(vgcd));
8352 
8353     vgcd[0].gd.pos.x = 10; vgcd[0].gd.pos.y = 12;
8354     vlabel[0].text = (unichar_t *) _("_Weight Class");
8355     vlabel[0].text_is_1byte = true;
8356     vlabel[0].text_in_resource = true;
8357     vgcd[0].gd.label = &vlabel[0];
8358     vgcd[0].gd.flags = gg_visible | gg_enabled;
8359     vgcd[0].creator = GLabelCreate;
8360 
8361     vgcd[1].gd.pos.x = 90; vgcd[1].gd.pos.y = vgcd[0].gd.pos.y-6; vgcd[1].gd.pos.width = 140;
8362     vgcd[1].gd.flags = gg_visible | gg_enabled;
8363     vgcd[1].gd.cid = CID_WeightClass;
8364     vgcd[1].gd.u.list = weightclass;
8365     vgcd[1].creator = GListFieldCreate;
8366 
8367     vgcd[2].gd.pos.x = 10; vgcd[2].gd.pos.y = vgcd[1].gd.pos.y+26+6;
8368     vlabel[2].text = (unichar_t *) _("Width _Class");
8369     vlabel[2].text_is_1byte = true;
8370     vlabel[2].text_in_resource = true;
8371     vgcd[2].gd.label = &vlabel[2];
8372     vgcd[2].gd.flags = gg_visible | gg_enabled;
8373     vgcd[2].creator = GLabelCreate;
8374 
8375     vgcd[3].gd.pos.x = 90; vgcd[3].gd.pos.y = vgcd[2].gd.pos.y-6;
8376     vgcd[3].gd.flags = gg_visible | gg_enabled;
8377     vgcd[3].gd.cid = CID_WidthClass;
8378     vgcd[3].gd.u.list = widthclass;
8379     vgcd[3].creator = GListButtonCreate;
8380 
8381     vgcd[4].gd.pos.x = 10; vgcd[4].gd.pos.y = vgcd[3].gd.pos.y+26+6;
8382     vlabel[4].text = (unichar_t *) _("P_FM Family");
8383     vlabel[4].text_is_1byte = true;
8384     vlabel[4].text_in_resource = true;
8385     vgcd[4].gd.label = &vlabel[4];
8386     vgcd[4].gd.flags = gg_visible | gg_enabled;
8387     vgcd[4].creator = GLabelCreate;
8388 
8389     vgcd[5].gd.pos.x = 90; vgcd[5].gd.pos.y = vgcd[4].gd.pos.y-6; vgcd[5].gd.pos.width = 140;
8390     vgcd[5].gd.flags = gg_visible | gg_enabled;
8391     vgcd[5].gd.cid = CID_PFMFamily;
8392     vgcd[5].gd.u.list = pfmfamily;
8393     vgcd[5].creator = GListButtonCreate;
8394 
8395     vgcd[6].gd.pos.x = 10; vgcd[6].gd.pos.y = vgcd[5].gd.pos.y+26+6;
8396     vlabel[6].text = (unichar_t *) _("_Embeddable");
8397     vlabel[6].text_is_1byte = true;
8398     vlabel[6].text_in_resource = true;
8399     vgcd[6].gd.label = &vlabel[6];
8400     vgcd[6].gd.flags = gg_visible | gg_enabled;
8401     vgcd[6].gd.popup_msg = _("Can this font be embedded in a downloadable (pdf)\ndocument, and if so, what behaviors are permitted on\nboth the document and the font.");
8402     vgcd[6].creator = GLabelCreate;
8403 
8404     vgcd[7].gd.pos.x = 90; vgcd[7].gd.pos.y = vgcd[6].gd.pos.y-6;
8405     vgcd[7].gd.pos.width = 140;
8406     vgcd[7].gd.flags = gg_visible | gg_enabled;
8407     vgcd[7].gd.cid = CID_FSType;
8408     vgcd[7].gd.u.list = fstype;
8409     vgcd[7].gd.popup_msg = vgcd[6].gd.popup_msg;
8410     vgcd[7].creator = GListButtonCreate;
8411     fstype[0].selected = fstype[1].selected =
8412 	    fstype[2].selected = fstype[3].selected = false;
8413     if ( sf->pfminfo.fstype == -1 )
8414 	i = 3;
8415     else if ( sf->pfminfo.fstype&0x8 )
8416 	i = 2;
8417     else if ( sf->pfminfo.fstype&0x4 )
8418 	i = 1;
8419     else if ( sf->pfminfo.fstype&0x2 )
8420 	i = 0;
8421     else
8422 	i = 3;
8423     fstype[i].selected = true;
8424     vgcd[7].gd.label = &fstype[i];
8425 
8426     vgcd[8].gd.pos.x = 20; vgcd[8].gd.pos.y = vgcd[7].gd.pos.y+26;
8427     vlabel[8].text = (unichar_t *) _("No Subsetting");
8428     vlabel[8].text_is_1byte = true;
8429     vgcd[8].gd.label = &vlabel[8];
8430     vgcd[8].gd.flags = gg_visible | gg_enabled;
8431     if ( sf->pfminfo.fstype!=-1 && (sf->pfminfo.fstype&0x100) )
8432 	vgcd[8].gd.flags |= gg_cb_on;
8433     vgcd[8].gd.popup_msg = _("If set then the entire font must be\nembedded in a document when any character is.\nOtherwise the document creator need\nonly include the characters it uses.");
8434     vgcd[8].gd.cid = CID_NoSubsetting;
8435     vgcd[8].creator = GCheckBoxCreate;
8436 
8437     vgcd[9].gd.pos.x = 110; vgcd[9].gd.pos.y = vgcd[8].gd.pos.y;
8438     vlabel[9].text = (unichar_t *) _("Only Embed Bitmaps");
8439     vlabel[9].text_is_1byte = true;
8440     vgcd[9].gd.label = &vlabel[9];
8441     vgcd[9].gd.flags = gg_visible | gg_enabled;
8442     if ( sf->pfminfo.fstype!=-1 && ( sf->pfminfo.fstype&0x200 ))
8443 	vgcd[9].gd.flags |= gg_cb_on;
8444     vgcd[9].gd.popup_msg = _("Only Bitmaps may be embedded.\nOutline descriptions may not be\n(if font file contains no bitmaps\nthen nothing may be embedded).");
8445     vgcd[9].gd.cid = CID_OnlyBitmaps;
8446     vgcd[9].creator = GCheckBoxCreate;
8447 
8448     vgcd[10].gd.pos.x = 10; vgcd[10].gd.pos.y = vgcd[9].gd.pos.y+24;
8449     vlabel[10].text = (unichar_t *) _("Vendor ID:");
8450     vlabel[10].text_is_1byte = true;
8451     vgcd[10].gd.label = &vlabel[10];
8452     vgcd[10].gd.flags = gg_visible | gg_enabled;
8453     vgcd[10].creator = GLabelCreate;
8454 
8455     vgcd[11].gd.pos.x = 90; vgcd[11].gd.pos.y = vgcd[11-1].gd.pos.y-4;
8456     vgcd[11].gd.pos.width = 50;
8457     vgcd[11].gd.flags = gg_visible | gg_enabled;
8458 	/* value set later */
8459     vgcd[11].gd.cid = CID_Vendor;
8460     vgcd[11].creator = GTextFieldCreate;
8461 
8462     vgcd[12].gd.pos.x = 10; vgcd[12].gd.pos.y = vgcd[11].gd.pos.y+24+6;
8463     vlabel[12].text = (unichar_t *) _("_IBM Family:");
8464     vlabel[12].text_is_1byte = true;
8465     vlabel[12].text_in_resource = true;
8466     vgcd[12].gd.label = &vlabel[12];
8467     vgcd[12].gd.flags = gg_visible | gg_enabled;
8468     vgcd[12].creator = GLabelCreate;
8469 
8470     vgcd[13].gd.pos.x = 90; vgcd[13].gd.pos.y = vgcd[12].gd.pos.y-4; vgcd[13].gd.pos.width = vgcd[7].gd.pos.width;
8471     vgcd[13].gd.flags = gg_visible | gg_enabled;
8472     vgcd[13].gd.cid = CID_IBMFamily;
8473     vgcd[13].gd.u.list = ibmfamily;
8474     vgcd[13].creator = GListButtonCreate;
8475 
8476     vgcd[15].gd.pos.x = 10; vgcd[15].gd.pos.y = vgcd[11].gd.pos.y+24+6;
8477     vlabel[15].text = (unichar_t *) _("_OS/2 Version");
8478     vlabel[15].text_is_1byte = true;
8479     vlabel[15].text_in_resource = true;
8480     vgcd[15].gd.label = &vlabel[15];
8481     vgcd[15].gd.popup_msg = _("The 'OS/2' table has changed slightly over the years.\nGenerally fields have been added, but occasionally their\nmeanings have been redefined." );
8482     vgcd[15].gd.flags = gg_visible | gg_enabled;
8483     vgcd[15].creator = GLabelCreate;
8484 
8485     vgcd[16].gd.pos.x = 90; vgcd[16].gd.pos.y = vgcd[15].gd.pos.y-4; vgcd[16].gd.pos.width = vgcd[7].gd.pos.width;
8486     vgcd[16].gd.flags = gg_visible | gg_enabled;
8487     vgcd[16].gd.cid = CID_OS2Version;
8488     vgcd[16].gd.u.list = os2versions;
8489     vgcd[16].creator = GListFieldCreate;
8490 
8491     vgcd[17].gd.pos.x = 10; vgcd[17].gd.pos.y = vgcd[13].gd.pos.y+26+6;
8492     vlabel[17].text = (unichar_t *) _("Style Map:");
8493     vlabel[17].text_is_1byte = true;
8494     vlabel[17].text_in_resource = true;
8495     vgcd[17].gd.label = &vlabel[17];
8496     vgcd[17].gd.flags = gg_visible | gg_enabled;
8497     vgcd[17].creator = GLabelCreate;
8498 
8499     vgcd[18].gd.pos.x = 90; vgcd[18].gd.pos.y = vgcd[17].gd.pos.y-6; vgcd[18].gd.pos.width = vgcd[7].gd.pos.width;
8500     vgcd[18].gd.flags = gg_visible | gg_enabled;
8501     vgcd[18].gd.cid = CID_StyleMap;
8502     vgcd[18].gd.u.list = stylemap;
8503     vgcd[18].creator = GListButtonCreate;
8504     stylemap[0].selected = stylemap[1].selected =
8505 	    stylemap[2].selected = stylemap[3].selected =
8506         stylemap[4].selected = stylemap[5].selected = false;
8507     if ( sf->pfminfo.stylemap == 0x00 )
8508 	i = 1;
8509     else if ( sf->pfminfo.stylemap == 0x40 )
8510 	i = 2;
8511     else if ( sf->pfminfo.stylemap == 0x01 )
8512 	i = 3;
8513     else if ( sf->pfminfo.stylemap == 0x20 )
8514 	i = 4;
8515     else if ( sf->pfminfo.stylemap == 0x21 )
8516 	i = 5;
8517     else
8518 	i = 0;
8519     stylemap[i].selected = true;
8520     vgcd[18].gd.label = &stylemap[i];
8521 
8522     vgcd[14].gd.pos.x = 10; vgcd[14].gd.pos.y = vgcd[18].gd.pos.y+24+6;
8523     vlabel[14].text = (unichar_t *) _("Weight, Width, Slope Only");
8524     vlabel[14].text_is_1byte = true;
8525     vlabel[14].text_in_resource = true;
8526     vgcd[14].gd.label = &vlabel[14];
8527     vgcd[14].gd.cid = CID_WeightWidthSlopeOnly;
8528     vgcd[14].gd.popup_msg = _("MS needs to know whether a font family's members differ\nonly in weight, width and slope (and not in other variables\nlike optical size)." );
8529     vgcd[14].gd.flags = gg_visible | gg_enabled;
8530     vgcd[14].creator = GCheckBoxCreate;
8531 
8532     vradio[0] = GCD_Glue; vradio[1] = &vgcd[8]; vradio[2] = &vgcd[9]; vradio[3] = GCD_Glue; vradio[4] = NULL;
8533 
8534     varray[0] = &vgcd[15]; varray[1] = &vgcd[16]; varray[2] = NULL;
8535     varray[3] = &vgcd[0]; varray[4] = &vgcd[1]; varray[5] = NULL;
8536     varray[6] = &vgcd[2]; varray[7] = &vgcd[3]; varray[8] = NULL;
8537     varray[9] = &vgcd[4]; varray[10] = &vgcd[5]; varray[11] = NULL;
8538     varray[12] = &vgcd[6]; varray[13] = &vgcd[7]; varray[14] = NULL;
8539     varray[15] = &vbox[2]; varray[16] = GCD_ColSpan; varray[17] = NULL;
8540     varray[18] = &vgcd[10]; varray[19] = &vgcd[11]; varray[20] = NULL;
8541     varray[21] = &vgcd[12]; varray[22] = &vgcd[13]; varray[23] = NULL;
8542     varray[24] = &vgcd[17]; varray[25] = &vgcd[18]; varray[26] = NULL;
8543     varray[27] = &vgcd[14]; varray[28] = GCD_ColSpan; varray[29] = NULL;
8544     varray[30] = GCD_Glue; varray[31] = GCD_Glue; varray[32] = NULL;
8545     varray[33] = GCD_Glue; varray[34] = GCD_Glue; varray[35] = NULL;
8546     varray[36] = varray[40] = NULL;
8547 
8548     memset(vbox,0,sizeof(vbox));
8549     vbox[0].gd.flags = gg_enabled|gg_visible;
8550     vbox[0].gd.u.boxelements = varray;
8551     vbox[0].creator = GHVBoxCreate;
8552 
8553     vbox[2].gd.flags = gg_enabled|gg_visible;
8554     vbox[2].gd.u.boxelements = vradio;
8555     vbox[2].creator = GHBoxCreate;
8556 
8557 /******************************************************************************/
8558 
8559     memset(&metgcd,0,sizeof(metgcd));
8560     memset(&metlabel,'\0',sizeof(metlabel));
8561     memset(&metarray,'\0',sizeof(metarray));
8562 
8563     i = j = 0;
8564 
8565     metgcd[i].gd.pos.x = 10; metgcd[i].gd.pos.y = 9;
8566     metlabel[i].text = (unichar_t *) _("Win _Ascent Offset:");
8567     metlabel[i].text_is_1byte = true;
8568     metlabel[i].text_in_resource = true;
8569     metgcd[i].gd.label = &metlabel[i];
8570     metgcd[i].gd.flags = gg_visible | gg_enabled;
8571     metgcd[i].gd.popup_msg = _("Anything outside the OS/2 WinAscent &\nWinDescent fields will be clipped by windows.\nThis includes marks, etc. that have been repositioned by GPOS.\n(The descent field is usually positive.)\nIf the \"[] Is Offset\" checkbox is clear then\nany number you enter will be the value used in OS/2.\nIf set then any number you enter will be added to the\nfont's bounds. You should leave this\nfield 0 and check \"[*] Is Offset\" in most cases.\n\nNote: WinDescent is a POSITIVE number for\nthings below the baseline");
8572     metgcd[i].gd.cid = CID_WinAscentLab;
8573     metarray[j++] = &metgcd[i];
8574     metgcd[i++].creator = GLabelCreate;
8575 
8576     metgcd[i].gd.pos.x = 125; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y-4;
8577     metgcd[i].gd.pos.width = 50;
8578     metgcd[i].gd.flags = gg_visible | gg_enabled;
8579 	/* value set later */
8580     metgcd[i].gd.cid = CID_WinAscent;
8581     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8582     metarray[j++] = &metgcd[i];
8583     metgcd[i++].creator = GTextFieldCreate;
8584 
8585     metgcd[i].gd.pos.x = 178; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y;
8586     metlabel[i].text = (unichar_t *) _("Is Offset");
8587     metlabel[i].text_is_1byte = true;
8588     metgcd[i].gd.label = &metlabel[i];
8589     metgcd[i].gd.flags = gg_visible | gg_enabled;
8590 	/* value set later */
8591     metgcd[i].gd.cid = CID_WinAscentIsOff;
8592     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8593     metgcd[i].gd.handle_controlevent = GFI_AsDesIsOff;
8594     metarray[j++] = &metgcd[i];
8595     metgcd[i++].creator = GCheckBoxCreate;
8596     metarray[j++] = NULL;
8597 
8598     metgcd[i].gd.pos.x = 10; metgcd[i].gd.pos.y = metgcd[i-2].gd.pos.y+26+4;
8599     metlabel[i].text = (unichar_t *) _("Win _Descent Offset:");
8600     metlabel[i].text_is_1byte = true;
8601     metlabel[i].text_in_resource = true;
8602     metgcd[i].gd.label = &metlabel[i];
8603     metgcd[i].gd.flags = gg_visible | gg_enabled;
8604     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8605     metgcd[i].gd.cid = CID_WinDescentLab;
8606     metarray[j++] = &metgcd[i];
8607     metgcd[i++].creator = GLabelCreate;
8608 
8609     metgcd[i].gd.pos.x = 125; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y-4;
8610     metgcd[i].gd.pos.width = 50;
8611     metgcd[i].gd.flags = gg_visible | gg_enabled;
8612 	/* value set later */
8613     metgcd[i].gd.cid = CID_WinDescent;
8614     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8615     metarray[j++] = &metgcd[i];
8616     metgcd[i++].creator = GTextFieldCreate;
8617 
8618     metgcd[i].gd.pos.x = 178; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y;
8619     metlabel[i].text = (unichar_t *) _("Is Offset");
8620     metlabel[i].text_is_1byte = true;
8621     metgcd[i].gd.label = &metlabel[i];
8622     metgcd[i].gd.flags = gg_visible | gg_enabled;
8623 	/* value set later */
8624     metgcd[i].gd.cid = CID_WinDescentIsOff;
8625     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8626     metgcd[i].gd.handle_controlevent = GFI_AsDesIsOff;
8627     metarray[j++] = &metgcd[i];
8628     metgcd[i++].creator = GCheckBoxCreate;
8629     metarray[j++] = NULL;
8630 
8631     metgcd[i].gd.pos.x = 5; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y;
8632     metlabel[i].text = (unichar_t *) _("Really use Typo metrics");
8633     metlabel[i].text_is_1byte = true;
8634     metgcd[i].gd.label = &metlabel[i];
8635     metgcd[i].gd.flags = gg_visible | gg_enabled;
8636 	/* value set later */
8637     metgcd[i].gd.cid = CID_UseTypoMetrics;
8638     metgcd[i].gd.popup_msg = _("The specification already says that the typo metrics should be\nused to determine line spacing. But so many\nprograms fail to follow the spec. that MS decided an additional\nbit was needed to remind them to do so.");
8639     metarray[j++] = &metgcd[i]; metarray[j++] = GCD_ColSpan; metarray[j++] = GCD_Glue;
8640     metgcd[i++].creator = GCheckBoxCreate;
8641     metarray[j++] = NULL;
8642 
8643     metgcd[i].gd.pos.x = 10; metgcd[i].gd.pos.y = metgcd[i-2].gd.pos.y+26+4;
8644     metlabel[i].text = (unichar_t *) _("_Typo Ascent Offset:");
8645     metlabel[i].text_is_1byte = true;
8646     metlabel[i].text_in_resource = true;
8647     metgcd[i].gd.label = &metlabel[i];
8648     metgcd[i].gd.flags = gg_visible | gg_enabled;
8649     metgcd[i].gd.popup_msg = _("The typo ascent&descent fields are>supposed<\nto specify the line spacing on windows.\nIn fact usually the win ascent/descent fields do.\n(The descent field is usually negative.)\nIf the \"[] Is Offset\" checkbox is clear then\nany number you enter will be the value used in OS/2.\nIf set then any number you enter will be added to the\nEm-size. You should leave this\nfield 0 and check \"[*] Is Offset\" in most cases.\n\nNOTE: Typo Descent is a NEGATIVE number for\nthings below the baseline");
8650     metgcd[i].gd.cid = CID_TypoAscentLab;
8651     metarray[j++] = &metgcd[i];
8652     metgcd[i++].creator = GLabelCreate;
8653 
8654     metgcd[i].gd.pos.x = 125; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y-4;
8655     metgcd[i].gd.pos.width = 50;
8656     metgcd[i].gd.flags = gg_visible | gg_enabled;
8657 	/* value set later */
8658     metgcd[i].gd.cid = CID_TypoAscent;
8659     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8660     metarray[j++] = &metgcd[i];
8661     metgcd[i++].creator = GTextFieldCreate;
8662 
8663     metgcd[i].gd.pos.x = 178; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y;
8664     metlabel[i].text = (unichar_t *) _("Is Offset");
8665     metlabel[i].text_is_1byte = true;
8666     metgcd[i].gd.label = &metlabel[i];
8667     metgcd[i].gd.flags = gg_visible | gg_enabled;
8668 	/* value set later */
8669     metgcd[i].gd.cid = CID_TypoAscentIsOff;
8670     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8671     metgcd[i].gd.handle_controlevent = GFI_AsDesIsOff;
8672     metarray[j++] = &metgcd[i];
8673     metgcd[i++].creator = GCheckBoxCreate;
8674     metarray[j++] = NULL;
8675 
8676     metgcd[i].gd.pos.x = 10; metgcd[i].gd.pos.y = metgcd[i-2].gd.pos.y+26+4;
8677     metlabel[i].text = (unichar_t *) _("T_ypo Descent Offset:");
8678     metlabel[i].text_is_1byte = true;
8679     metlabel[i].text_in_resource = true;
8680     metgcd[i].gd.label = &metlabel[i];
8681     metgcd[i].gd.flags = gg_visible | gg_enabled;
8682     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8683     metgcd[i].gd.cid = CID_TypoDescentLab;
8684     metarray[j++] = &metgcd[i];
8685     metgcd[i++].creator = GLabelCreate;
8686 
8687     metgcd[i].gd.pos.x = 125; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y-4;
8688     metgcd[i].gd.pos.width = 50;
8689     metgcd[i].gd.flags = gg_visible | gg_enabled;
8690 	/* value set later */
8691     metgcd[i].gd.cid = CID_TypoDescent;
8692     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8693     metarray[j++] = &metgcd[i];
8694     metgcd[i++].creator = GTextFieldCreate;
8695 
8696     metgcd[i].gd.pos.x = 178; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y;
8697     metlabel[i].text = (unichar_t *) _("Is Offset");
8698     metlabel[i].text_is_1byte = true;
8699     metgcd[i].gd.label = &metlabel[i];
8700     metgcd[i].gd.flags = gg_visible | gg_enabled;
8701 	/* value set later */
8702     metgcd[i].gd.cid = CID_TypoDescentIsOff;
8703     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8704     metgcd[i].gd.handle_controlevent = GFI_AsDesIsOff;
8705     metarray[j++] = &metgcd[i];
8706     metgcd[i++].creator = GCheckBoxCreate;
8707     metarray[j++] = NULL;
8708 
8709     metgcd[i].gd.pos.x = 10; metgcd[i].gd.pos.y = metgcd[i-2].gd.pos.y+26+4;
8710     metlabel[i].text = (unichar_t *) _("Typo Line _Gap:");
8711     metlabel[i].text_is_1byte = true;
8712     metlabel[i].text_in_resource = true;
8713     metgcd[i].gd.label = &metlabel[i];
8714     metgcd[i].gd.flags = gg_visible | gg_enabled;
8715     metgcd[i].gd.popup_msg = _("Sets the TypoLinegap field in the OS/2 table, used on MS Windows");
8716     metarray[j++] = &metgcd[i];
8717     metgcd[i++].creator = GLabelCreate;
8718 
8719     metgcd[i].gd.pos.x = 125; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y-4;
8720     metgcd[i].gd.pos.width = 50;
8721     metgcd[i].gd.flags = gg_visible | gg_enabled;
8722 	/* Line gap value set later */
8723     metgcd[i].gd.cid = CID_TypoLineGap;
8724     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8725     metarray[j++] = &metgcd[i];
8726     metgcd[i++].creator = GTextFieldCreate;
8727     metarray[j++] = GCD_Glue;
8728     metarray[j++] = NULL;
8729 
8730     metgcd[i].gd.pos.x = 10; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y+26+4;
8731     metlabel[i].text = (unichar_t *) _("_HHead Ascent Offset:");
8732     metlabel[i].text_is_1byte = true;
8733     metlabel[i].text_in_resource = true;
8734     metgcd[i].gd.label = &metlabel[i];
8735     metgcd[i].gd.flags = gg_visible | gg_enabled;
8736     metgcd[i].gd.popup_msg = _("This specifies the line spacing on the mac.\n(The descent field is usually negative.)\nIf the \"[] Is Offset\" checkbox is clear then\nany number you enter will be the value used in hhea.\nIf set then any number you enter will be added to the\nfont's bounds. You should leave this\nfield 0 and check \"[*] Is Offset\" in most cases.\n\nNOTE: hhea Descent is a NEGATIVE value for things\nbelow the baseline");
8737     metgcd[i].gd.cid = CID_HHeadAscentLab;
8738     metarray[j++] = &metgcd[i];
8739     metgcd[i++].creator = GLabelCreate;
8740 
8741     metgcd[i].gd.pos.x = 125; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y-4;
8742     metgcd[i].gd.pos.width = 50;
8743     metgcd[i].gd.flags = gg_visible | gg_enabled;
8744 	/* value set later */
8745     metgcd[i].gd.cid = CID_HHeadAscent;
8746     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8747     metarray[j++] = &metgcd[i];
8748     metgcd[i++].creator = GTextFieldCreate;
8749 
8750     metgcd[i].gd.pos.x = 178; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y;
8751     metlabel[i].text = (unichar_t *) _("Is Offset");
8752     metlabel[i].text_is_1byte = true;
8753     metgcd[i].gd.label = &metlabel[i];
8754     metgcd[i].gd.flags = gg_visible | gg_enabled;
8755 	/* value set later */
8756     metgcd[i].gd.cid = CID_HHeadAscentIsOff;
8757     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8758     metgcd[i].gd.handle_controlevent = GFI_AsDesIsOff;
8759     metarray[j++] = &metgcd[i];
8760     metgcd[i++].creator = GCheckBoxCreate;
8761     metarray[j++] = NULL;
8762 
8763     metgcd[i].gd.pos.x = 10; metgcd[i].gd.pos.y = metgcd[i-2].gd.pos.y+26+4;
8764     metlabel[i].text = (unichar_t *) _("HHead De_scent Offset:");
8765     metlabel[i].text_in_resource = true;
8766     metlabel[i].text_is_1byte = true;
8767     metgcd[i].gd.label = &metlabel[i];
8768     metgcd[i].gd.flags = gg_visible | gg_enabled;
8769     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8770     metgcd[i].gd.cid = CID_HHeadDescentLab;
8771     metarray[j++] = &metgcd[i];
8772     metgcd[i++].creator = GLabelCreate;
8773 
8774     metgcd[i].gd.pos.x = 125; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y-4;
8775     metgcd[i].gd.pos.width = 50;
8776     metgcd[i].gd.flags = gg_visible | gg_enabled;
8777 	/* value set later */
8778     metgcd[i].gd.cid = CID_HHeadDescent;
8779     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8780     metarray[j++] = &metgcd[i];
8781     metgcd[i++].creator = GTextFieldCreate;
8782 
8783     metgcd[i].gd.pos.x = 178; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y;
8784     metlabel[i].text = (unichar_t *) _("Is Offset");
8785     metlabel[i].text_is_1byte = true;
8786     metgcd[i].gd.label = &metlabel[i];
8787     metgcd[i].gd.flags = gg_visible | gg_enabled;
8788 	/* value set later */
8789     metgcd[i].gd.cid = CID_HHeadDescentIsOff;
8790     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8791     metgcd[i].gd.handle_controlevent = GFI_AsDesIsOff;
8792     metarray[j++] = &metgcd[i];
8793     metgcd[i++].creator = GCheckBoxCreate;
8794     metarray[j++] = NULL;
8795 
8796     metgcd[i].gd.pos.x = 10; metgcd[i].gd.pos.y = metgcd[i-2].gd.pos.y+26+4;
8797     metlabel[i].text = (unichar_t *) _("HHead _Line Gap:");
8798     metlabel[i].text_is_1byte = true;
8799     metlabel[i].text_in_resource = true;
8800     metgcd[i].gd.label = &metlabel[i];
8801     metgcd[i].gd.flags = gg_visible | gg_enabled;
8802     metgcd[i].gd.popup_msg = _("Sets the linegap field in the hhea table, used on the mac");
8803     metarray[j++] = &metgcd[i];
8804     metgcd[i++].creator = GLabelCreate;
8805 
8806     metgcd[i].gd.pos.x = 125; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y-4;
8807     metgcd[i].gd.pos.width = 50;
8808     metgcd[i].gd.flags = gg_visible | gg_enabled;
8809 	/* Line gap value set later */
8810     metgcd[i].gd.cid = CID_LineGap;
8811     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8812     metarray[j++] = &metgcd[i];
8813     metgcd[i++].creator = GTextFieldCreate;
8814     metarray[j++] = GCD_Glue;
8815     metarray[j++] = NULL;
8816 
8817     metgcd[i].gd.pos.x = 10; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y+26+6;
8818     metlabel[i].text = (unichar_t *) _("VHead _Column Spacing:");
8819     metlabel[i].text_is_1byte = true;
8820     metlabel[i].text_in_resource = true;
8821     metgcd[i].gd.label = &metlabel[i];
8822     metgcd[i].gd.flags = sf->hasvmetrics ? (gg_visible | gg_enabled) : (gg_visible);
8823     metgcd[i].gd.popup_msg = _("Sets the linegap field in the vhea table.\nThis is the horizontal spacing between rows\nof vertically set text.");
8824     metgcd[i].gd.cid = CID_VLineGapLab;
8825     metarray[j++] = &metgcd[i];
8826     metgcd[i++].creator = GLabelCreate;
8827 
8828     metgcd[i].gd.pos.x = 125; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y-6;
8829     metgcd[i].gd.pos.width = 50;
8830     metgcd[i].gd.flags = sf->hasvmetrics ? (gg_visible | gg_enabled) : (gg_visible);
8831 	/* V Line gap value set later */
8832     metgcd[i].gd.cid = CID_VLineGap;
8833     metgcd[i].gd.popup_msg = metgcd[17].gd.popup_msg;
8834     metarray[j++] = &metgcd[i];
8835     metgcd[i++].creator = GTextFieldCreate;
8836     metarray[j++] = GCD_Glue;
8837     metarray[j++] = NULL;
8838 
8839     metgcd[i].gd.pos.x = 10; metgcd[i].gd.pos.y = metgcd[i-2].gd.pos.y+26+6;
8840     metlabel[i].text = (unichar_t *) _("Ca_pital Height:");
8841     metlabel[i].text_is_1byte = true;
8842     metlabel[i].text_in_resource = true;
8843     metgcd[i].gd.label = &metlabel[i];
8844     metgcd[i].gd.flags = gg_visible | gg_enabled;
8845     metgcd[i].gd.popup_msg = _("This denotes the height of X.");
8846     metgcd[i].gd.cid = CID_CapHeightLab;
8847     metarray[j++] = &metgcd[i];
8848     metgcd[i++].creator = GLabelCreate;
8849 
8850     metgcd[i].gd.pos.x = 125; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y-4;
8851     metgcd[i].gd.pos.width = 50;
8852     metgcd[i].gd.flags = gg_visible | gg_enabled;
8853 	/* value set later */
8854     metgcd[i].gd.cid = CID_CapHeight;
8855     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8856     metarray[j++] = &metgcd[i];
8857     metgcd[i++].creator = GTextFieldCreate;
8858     metarray[j++] = GCD_Glue;
8859     metarray[j++] = NULL;
8860 
8861     metgcd[i].gd.pos.x = 10; metgcd[i].gd.pos.y = metgcd[i-2].gd.pos.y+26+6;
8862     metlabel[i].text = (unichar_t *) _("_X Height:");
8863     metlabel[i].text_is_1byte = true;
8864     metlabel[i].text_in_resource = true;
8865     metgcd[i].gd.label = &metlabel[i];
8866     metgcd[i].gd.flags = gg_visible | gg_enabled;
8867     metgcd[i].gd.popup_msg = _("This denotes the height of x.");
8868     metgcd[i].gd.cid = CID_XHeightLab;
8869     metarray[j++] = &metgcd[i];
8870     metgcd[i++].creator = GLabelCreate;
8871 
8872     metgcd[i].gd.pos.x = 125; metgcd[i].gd.pos.y = metgcd[i-1].gd.pos.y-4;
8873     metgcd[i].gd.pos.width = 50;
8874     metgcd[i].gd.flags = gg_visible | gg_enabled;
8875 	/* value set later */
8876     metgcd[i].gd.cid = CID_XHeight;
8877     metgcd[i].gd.popup_msg = metgcd[i-1].gd.popup_msg;
8878     metarray[j++] = &metgcd[i];
8879     metgcd[i++].creator = GTextFieldCreate;
8880     metarray[j++] = GCD_Glue;
8881     metarray[j++] = NULL;
8882 
8883     metarray[j++] = GCD_Glue; metarray[j++] = GCD_Glue; metarray[j++] = GCD_Glue;
8884 
8885     metarray[j++] = NULL; metarray[j++] = NULL;
8886 
8887     memset(metbox,0,sizeof(metbox));
8888     metbox[0].gd.flags = gg_enabled|gg_visible;
8889     metbox[0].gd.u.boxelements = metarray;
8890     metbox[0].creator = GHVBoxCreate;
8891 /******************************************************************************/
8892 
8893     memset(&ssgcd,0,sizeof(ssgcd));
8894     memset(&sslabel,'\0',sizeof(sslabel));
8895 
8896     i = j = 0;
8897 
8898     ssgcd[i].gd.pos.x = 5; ssgcd[i].gd.pos.y = 5;
8899     sslabel[i].text = (unichar_t *) S_("SubscriptSuperUse|Default");
8900     sslabel[i].text_is_1byte = true;
8901     ssgcd[i].gd.label = &sslabel[i];
8902     ssgcd[i].gd.flags = gg_visible | gg_enabled;
8903 	/* value set later */
8904     ssgcd[i].gd.cid = CID_SubSuperDefault;
8905     ssgcd[i].gd.handle_controlevent = GFI_SubSuperDefault;
8906     ssarray[j++] = &ssgcd[i];
8907     ssgcd[i++].creator = GCheckBoxCreate;
8908     ssarray[j++] = GCD_Glue; ssarray[j++] = GCD_Glue; ssarray[j++] = GCD_Glue;
8909     ssarray[j++] = NULL;
8910 
8911     ssgcd[i].gd.pos.x = 5; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y+16;
8912     sslabel[i].text = (unichar_t *) _("Subscript");
8913     sslabel[i].text_is_1byte = true;
8914     ssgcd[i].gd.label = &sslabel[i];
8915     ssgcd[i].gd.flags = gg_visible | gg_enabled;
8916     ssarray[j++] = &ssgcd[i];
8917     ssgcd[i++].creator = GLabelCreate;
8918 
8919     ssgcd[i].gd.pos.x = 120; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y-4;
8920 /* GT: X is a coordinate, the leading spaces help to align it */
8921     sslabel[i].text = (unichar_t *) _("  X");
8922     sslabel[i].text_is_1byte = true;
8923     ssgcd[i].gd.label = &sslabel[i];
8924     ssgcd[i].gd.flags = gg_visible | gg_enabled;
8925     ssarray[j++] = &ssgcd[i];
8926     ssgcd[i++].creator = GLabelCreate;
8927 
8928     ssgcd[i].gd.pos.x = 180; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y;
8929 /* GT: Y is a coordinate, the leading spaces help to align it */
8930     sslabel[i].text = (unichar_t *) _("Y");
8931     sslabel[i].text_is_1byte = true;
8932     ssgcd[i].gd.label = &sslabel[i];
8933     ssgcd[i].gd.flags = gg_visible | gg_enabled;
8934     ssarray[j++] = &ssgcd[i];
8935     ssgcd[i++].creator = GLabelCreate;
8936     ssarray[j++] = GCD_Glue; ssarray[j++] = NULL;
8937 
8938     ssgcd[i].gd.pos.x = 10; ssgcd[i].gd.pos.y = ssgcd[i-3].gd.pos.y+14+4;
8939     sslabel[i].text = (unichar_t *) _("Size");
8940     sslabel[i].text_is_1byte = true;
8941     ssgcd[i].gd.label = &sslabel[i];
8942     ssgcd[i].gd.flags = gg_visible | gg_enabled;
8943     ssarray[j++] = &ssgcd[i];
8944     ssgcd[i++].creator = GLabelCreate;
8945 
8946     ssgcd[i].gd.pos.x = 100; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y-6;
8947     ssgcd[i].gd.pos.width = 50;
8948     ssgcd[i].gd.flags = gg_visible | gg_enabled;
8949 	/* set later */
8950     ssgcd[i].gd.cid = CID_SubXSize;
8951     ssarray[j++] = &ssgcd[i];
8952     ssgcd[i++].creator = GTextFieldCreate;
8953 
8954     ssgcd[i].gd.pos.x = 160; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y;
8955     ssgcd[i].gd.pos.width = 50;
8956     ssgcd[i].gd.flags = gg_visible | gg_enabled;
8957 	/* set later */
8958     ssgcd[i].gd.cid = CID_SubYSize;
8959     ssarray[j++] = &ssgcd[i];
8960     ssgcd[i++].creator = GTextFieldCreate;
8961     ssarray[j++] = GCD_Glue; ssarray[j++] = NULL;
8962 
8963     ssgcd[i].gd.pos.x = 10; ssgcd[i].gd.pos.y = ssgcd[i-3].gd.pos.y+26;
8964     sslabel[i].text = (unichar_t *) _("Offset");
8965     sslabel[i].text_is_1byte = true;
8966     ssgcd[i].gd.label = &sslabel[i];
8967     ssgcd[i].gd.flags = gg_visible | gg_enabled;
8968     ssarray[j++] = &ssgcd[i];
8969     ssgcd[i++].creator = GLabelCreate;
8970 
8971     ssgcd[i].gd.pos.x = 100; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y-6;
8972     ssgcd[i].gd.pos.width = 50;
8973     ssgcd[i].gd.flags = gg_visible | gg_enabled;
8974 	/* set later */
8975     ssgcd[i].gd.cid = CID_SubXOffset;
8976     ssarray[j++] = &ssgcd[i];
8977     ssgcd[i++].creator = GTextFieldCreate;
8978 
8979     ssgcd[i].gd.pos.x = 160; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y;
8980     ssgcd[i].gd.pos.width = 50;
8981     ssgcd[i].gd.flags = gg_visible | gg_enabled;
8982 	/* set later */
8983     ssgcd[i].gd.cid = CID_SubYOffset;
8984     ssarray[j++] = &ssgcd[i];
8985     ssgcd[i++].creator = GTextFieldCreate;
8986     ssarray[j++] = GCD_Glue; ssarray[j++] = NULL;
8987 
8988 
8989     ssgcd[i].gd.pos.x = 5; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y+30;
8990     sslabel[i].text = (unichar_t *) _("Superscript");
8991     sslabel[i].text_is_1byte = true;
8992     ssgcd[i].gd.label = &sslabel[i];
8993     ssgcd[i].gd.flags = gg_visible | gg_enabled;
8994     ssarray[j++] = &ssgcd[i];
8995     ssgcd[i++].creator = GLabelCreate;
8996     ssarray[j++] = GCD_Glue; ssarray[j++] = GCD_Glue; ssarray[j++] = GCD_Glue;
8997     ssarray[j++] = NULL;
8998 
8999     ssgcd[i].gd.pos.x = 10; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y+14+4;
9000     sslabel[i].text = (unichar_t *) _("Size");
9001     sslabel[i].text_is_1byte = true;
9002     ssgcd[i].gd.label = &sslabel[i];
9003     ssgcd[i].gd.flags = gg_visible | gg_enabled;
9004     ssarray[j++] = &ssgcd[i];
9005     ssgcd[i++].creator = GLabelCreate;
9006 
9007     ssgcd[i].gd.pos.x = 100; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y-6;
9008     ssgcd[i].gd.pos.width = 50;
9009     ssgcd[i].gd.flags = gg_visible | gg_enabled;
9010 	/* set later */
9011     ssgcd[i].gd.cid = CID_SuperXSize;
9012     ssarray[j++] = &ssgcd[i];
9013     ssgcd[i++].creator = GTextFieldCreate;
9014 
9015     ssgcd[i].gd.pos.x = 160; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y;
9016     ssgcd[i].gd.pos.width = 50;
9017     ssgcd[i].gd.flags = gg_visible | gg_enabled;
9018 	/* set later */
9019     ssgcd[i].gd.cid = CID_SuperYSize;
9020     ssarray[j++] = &ssgcd[i];
9021     ssgcd[i++].creator = GTextFieldCreate;
9022     ssarray[j++] = GCD_Glue; ssarray[j++] = NULL;
9023 
9024     ssgcd[i].gd.pos.x = 10; ssgcd[i].gd.pos.y = ssgcd[i-3].gd.pos.y+26;
9025     sslabel[i].text = (unichar_t *) _("Offset");
9026     sslabel[i].text_is_1byte = true;
9027     ssgcd[i].gd.label = &sslabel[i];
9028     ssgcd[i].gd.flags = gg_visible | gg_enabled;
9029     ssarray[j++] = &ssgcd[i];
9030     ssgcd[i++].creator = GLabelCreate;
9031 
9032     ssgcd[i].gd.pos.x = 100; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y-6;
9033     ssgcd[i].gd.pos.width = 50;
9034     ssgcd[i].gd.flags = gg_visible | gg_enabled;
9035 	/* set later */
9036     ssgcd[i].gd.cid = CID_SuperXOffset;
9037     ssarray[j++] = &ssgcd[i];
9038     ssgcd[i++].creator = GTextFieldCreate;
9039 
9040     ssgcd[i].gd.pos.x = 160; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y;
9041     ssgcd[i].gd.pos.width = 50;
9042     ssgcd[i].gd.flags = gg_visible | gg_enabled;
9043 	/* set later */
9044     ssgcd[i].gd.cid = CID_SuperYOffset;
9045     ssarray[j++] = &ssgcd[i];
9046     ssgcd[i++].creator = GTextFieldCreate;
9047     ssarray[j++] = GCD_Glue; ssarray[j++] = NULL;
9048 
9049 
9050     ssgcd[i].gd.pos.x = 5; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y+30;
9051     sslabel[i].text = (unichar_t *) _("Strikeout");
9052     sslabel[i].text_is_1byte = true;
9053     ssgcd[i].gd.label = &sslabel[i];
9054     ssgcd[i].gd.flags = gg_visible | gg_enabled;
9055     ssarray[j++] = &ssgcd[i];
9056     ssgcd[i++].creator = GLabelCreate;
9057     ssarray[j++] = GCD_Glue; ssarray[j++] = GCD_Glue; ssarray[j++] = GCD_Glue;
9058     ssarray[j++] = NULL;
9059 
9060     ssgcd[i].gd.pos.x = 10; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y+14+4;
9061     sslabel[i].text = (unichar_t *) _("Size");
9062     sslabel[i].text_is_1byte = true;
9063     ssgcd[i].gd.label = &sslabel[i];
9064     ssgcd[i].gd.flags = gg_visible | gg_enabled;
9065     ssarray[j++] = &ssgcd[i];
9066     ssgcd[i++].creator = GLabelCreate;
9067     ssarray[j++] = GCD_Glue;
9068 
9069     ssgcd[i].gd.pos.x = 160; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y-6;
9070     ssgcd[i].gd.pos.width = 50;
9071     ssgcd[i].gd.flags = gg_visible | gg_enabled;
9072 	/* set later */
9073     ssgcd[i].gd.cid = CID_StrikeoutSize;
9074     ssarray[j++] = &ssgcd[i];
9075     ssgcd[i++].creator = GTextFieldCreate;
9076     ssarray[j++] = GCD_Glue; ssarray[j++] = NULL;
9077 
9078     ssgcd[i].gd.pos.x = 10; ssgcd[i].gd.pos.y = ssgcd[i-2].gd.pos.y+26;
9079     sslabel[i].text = (unichar_t *) _("Pos");
9080     sslabel[i].text_is_1byte = true;
9081     ssgcd[i].gd.label = &sslabel[i];
9082     ssgcd[i].gd.flags = gg_visible | gg_enabled;
9083     ssarray[j++] = &ssgcd[i];
9084     ssgcd[i++].creator = GLabelCreate;
9085     ssarray[j++] = GCD_Glue;
9086 
9087     ssgcd[i].gd.pos.x = 160; ssgcd[i].gd.pos.y = ssgcd[i-1].gd.pos.y-6;
9088     ssgcd[i].gd.pos.width = 50;
9089     ssgcd[i].gd.flags = gg_visible | gg_enabled;
9090 	/* set later */
9091     ssgcd[i].gd.cid = CID_StrikeoutPos;
9092     ssarray[j++] = &ssgcd[i];
9093     ssgcd[i++].creator = GTextFieldCreate;
9094     ssarray[j++] = GCD_Glue; ssarray[j++] = NULL;
9095 
9096     ssarray[j++] = GCD_Glue; ssarray[j++] = GCD_Glue; ssarray[j++] = GCD_Glue; ssarray[j++] = GCD_Glue;
9097 
9098     ssarray[j++] = NULL; ssarray[j++] = NULL;
9099 
9100     memset(ssbox,0,sizeof(ssbox));
9101     ssbox[0].gd.flags = gg_enabled|gg_visible;
9102     ssbox[0].gd.u.boxelements = ssarray;
9103     ssbox[0].creator = GHVBoxCreate;
9104 /******************************************************************************/
9105     memset(&panlabel,0,sizeof(panlabel));
9106     memset(&pangcd,0,sizeof(pangcd));
9107 
9108     if ( small_blue_box.main_foreground==0 ) {
9109 	extern void _GButtonInit(void);
9110 	_GButtonInit();
9111 	small_blue_box = _GGadget_button_box;
9112 	small_blue_box.border_type = bt_box;
9113 	small_blue_box.border_shape = bs_rect;
9114 	small_blue_box.border_width = 1;
9115 	small_blue_box.flags = 0;
9116 	small_blue_box.padding = 0;
9117 	small_blue_box.main_foreground = 0x0000ff;
9118 	small_blue_box.border_darker = small_blue_box.main_foreground;
9119 	small_blue_box.border_darkest = small_blue_box.border_brighter =
9120 		small_blue_box.border_brightest =
9121 		small_blue_box.main_background = GDrawGetDefaultBackground(NULL);
9122     }
9123 
9124     i = j = 0;
9125 
9126     pangcd[i].gd.pos.x = 5; pangcd[i].gd.pos.y = 5;
9127     panlabel[i].text = (unichar_t *) S_("PanoseUse|Default");
9128     panlabel[i].text_is_1byte = true;
9129     pangcd[i].gd.label = &panlabel[i];
9130     pangcd[i].gd.flags = gg_visible | gg_enabled;
9131 	/* value set later */
9132     pangcd[i].gd.cid = CID_PanDefault;
9133     /*pangcd[i].gd.popup_msg = pangcd[i-1].gd.popup_msg;*/
9134     pangcd[i].gd.handle_controlevent = GFI_PanoseDefault;
9135     panarray[j++] = &pangcd[i];
9136     pangcd[i++].creator = GCheckBoxCreate;
9137 
9138     panlabel[i].text = (unichar_t *) _( "http://panose.com/");
9139     panlabel[i].text_is_1byte = true;
9140     pangcd[i].gd.label = &panlabel[i];
9141     pangcd[i].gd.pos.x = 12; ugcd[1].gd.pos.y = 10;
9142     pangcd[i].gd.flags = gg_visible | gg_enabled | gg_dontcopybox;
9143     pangcd[i].gd.box = &small_blue_box;
9144     pangcd[i].gd.handle_controlevent = GFI_ShowPanoseDocs;
9145     pangcd[i++].creator = GButtonCreate;
9146     panarray[j++] = &pangcd[i-1]; panarray[j++] = NULL;
9147 
9148     pangcd[i].gd.pos.x = 20; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y+14+4;
9149     panlabel[i].text = (unichar_t *) S_("Panose|_Family Kind");
9150     panlabel[i].text_is_1byte = true;
9151     panlabel[i].text_in_resource = true;
9152     pangcd[i].gd.label = &panlabel[i];
9153     pangcd[i].gd.cid = CID_PanFamilyLab;
9154     pangcd[i].gd.flags = gg_visible | gg_enabled;
9155     panarray[j++] = &pangcd[i];
9156     pangcd[i++].creator = GLabelCreate;
9157 
9158     pangcd[i].gd.pos.x = 100; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y-6; pangcd[i].gd.pos.width = 120;
9159     pangcd[i].gd.flags = gg_visible | gg_enabled;
9160     pangcd[i].gd.cid = CID_PanFamily;
9161     pangcd[i].gd.u.list = panfamily;
9162     panarray[j++] = &pangcd[i];
9163     pangcd[i].gd.handle_controlevent = GFI_ChangePanoseFamily;
9164     pangcd[i++].creator = GListButtonCreate;
9165     panarray[j++] = NULL;
9166 
9167     pangcd[i].gd.pos.x = 20; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y+26+5;
9168     panlabel[i].text = (unichar_t *) _("_Serifs");
9169     panlabel[i].text_is_1byte = true;
9170     panlabel[i].text_in_resource = true;
9171     pangcd[i].gd.label = &panlabel[i];
9172     pangcd[i].gd.cid = CID_PanSerifsLab;
9173     pangcd[i].gd.flags = gg_visible | gg_enabled;
9174     panarray[j++] = &pangcd[i];
9175     pangcd[i++].creator = GLabelCreate;
9176 
9177     pangcd[i].gd.pos.x = 100; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y-6; pangcd[i].gd.pos.width = 120;
9178     pangcd[i].gd.flags = gg_visible | gg_enabled;
9179     pangcd[i].gd.cid = CID_PanSerifs;
9180     pangcd[i].gd.u.list = panserifs;
9181     panarray[j++] = &pangcd[i];
9182     pangcd[i++].creator = GListButtonCreate;
9183     panarray[j++] = NULL;
9184 
9185     pangcd[i].gd.pos.x = 20; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y+26+5;
9186     panlabel[i].text = (unichar_t *) S_("Panose|_Weight");
9187     panlabel[i].text_is_1byte = true;
9188     panlabel[i].text_in_resource = true;
9189     pangcd[i].gd.label = &panlabel[i];
9190     pangcd[i].gd.cid = CID_PanWeightLab;
9191     pangcd[i].gd.flags = gg_visible | gg_enabled;
9192     panarray[j++] = &pangcd[i];
9193     pangcd[i++].creator = GLabelCreate;
9194 
9195     pangcd[i].gd.pos.x = 100; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y-6; pangcd[i].gd.pos.width = 120;
9196     pangcd[i].gd.flags = gg_visible | gg_enabled;
9197     pangcd[i].gd.cid = CID_PanWeight;
9198     pangcd[i].gd.u.list = panweight;
9199     panarray[j++] = &pangcd[i];
9200     pangcd[i++].creator = GListButtonCreate;
9201     panarray[j++] = NULL;
9202 
9203     pangcd[i].gd.pos.x = 20; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y+26+5;
9204     panlabel[i].text = (unichar_t *) _("_Proportion");
9205     panlabel[i].text_is_1byte = true;
9206     panlabel[i].text_in_resource = true;
9207     pangcd[i].gd.label = &panlabel[i];
9208     pangcd[i].gd.cid = CID_PanPropLab;
9209     pangcd[i].gd.flags = gg_visible | gg_enabled;
9210     panarray[j++] = &pangcd[i];
9211     pangcd[i++].creator = GLabelCreate;
9212 
9213     pangcd[i].gd.pos.x = 100; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y-6; pangcd[i].gd.pos.width = 120;
9214     pangcd[i].gd.flags = gg_visible | gg_enabled;
9215     pangcd[i].gd.cid = CID_PanProp;
9216     pangcd[i].gd.u.list = panprop;
9217     panarray[j++] = &pangcd[i];
9218     pangcd[i++].creator = GListButtonCreate;
9219     panarray[j++] = NULL;
9220 
9221     pangcd[i].gd.pos.x = 20; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y+26+5;
9222     panlabel[i].text = (unichar_t *) _("_Contrast");
9223     panlabel[i].text_is_1byte = true;
9224     panlabel[i].text_in_resource = true;
9225     pangcd[i].gd.label = &panlabel[i];
9226     pangcd[i].gd.cid = CID_PanContrastLab;
9227     pangcd[i].gd.flags = gg_visible | gg_enabled;
9228     panarray[j++] = &pangcd[i];
9229     pangcd[i++].creator = GLabelCreate;
9230 
9231     pangcd[i].gd.pos.x = 100; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y-6; pangcd[i].gd.pos.width = 120;
9232     pangcd[i].gd.flags = gg_visible | gg_enabled;
9233     pangcd[i].gd.cid = CID_PanContrast;
9234     pangcd[i].gd.u.list = pancontrast;
9235     panarray[j++] = &pangcd[i];
9236     pangcd[i++].creator = GListButtonCreate;
9237     panarray[j++] = NULL;
9238 
9239     pangcd[i].gd.pos.x = 20; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y+26+5;
9240     panlabel[i].text = (unichar_t *) _("Stroke _Variation");
9241     panlabel[i].text_is_1byte = true;
9242     panlabel[i].text_in_resource = true;
9243     pangcd[i].gd.label = &panlabel[i];
9244     pangcd[i].gd.cid = CID_PanStrokeVarLab;
9245     pangcd[i].gd.flags = gg_visible | gg_enabled;
9246     panarray[j++] = &pangcd[i];
9247     pangcd[i++].creator = GLabelCreate;
9248 
9249     pangcd[i].gd.pos.x = 100; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y-6; pangcd[i].gd.pos.width = 120;
9250     pangcd[i].gd.flags = gg_visible | gg_enabled;
9251     pangcd[i].gd.cid = CID_PanStrokeVar;
9252     pangcd[i].gd.u.list = panstrokevar;
9253     panarray[j++] = &pangcd[i];
9254     pangcd[i++].creator = GListButtonCreate;
9255     panarray[j++] = NULL;
9256 
9257     pangcd[i].gd.pos.x = 20; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y+26+5;
9258     panlabel[i].text = (unichar_t *) _("_Arm Style");
9259     panlabel[i].text_is_1byte = true;
9260     panlabel[i].text_in_resource = true;
9261     pangcd[i].gd.label = &panlabel[i];
9262     pangcd[i].gd.cid = CID_PanArmStyleLab;
9263     pangcd[i].gd.flags = gg_visible | gg_enabled;
9264     panarray[j++] = &pangcd[i];
9265     pangcd[i++].creator = GLabelCreate;
9266 
9267     pangcd[i].gd.pos.x = 100; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y-6; pangcd[i].gd.pos.width = 120;
9268     pangcd[i].gd.flags = gg_visible | gg_enabled;
9269     pangcd[i].gd.cid = CID_PanArmStyle;
9270     pangcd[i].gd.u.list = panarmstyle;
9271     panarray[j++] = &pangcd[i];
9272     pangcd[i++].creator = GListButtonCreate;
9273     panarray[j++] = NULL;
9274 
9275     pangcd[i].gd.pos.x = 20; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y+26+5;
9276     panlabel[i].text = (unichar_t *) _("_Letterform");
9277     panlabel[i].text_is_1byte = true;
9278     panlabel[i].text_in_resource = true;
9279     pangcd[i].gd.label = &panlabel[i];
9280     pangcd[i].gd.cid = CID_PanLetterformLab;
9281     pangcd[i].gd.flags = gg_visible | gg_enabled;
9282     panarray[j++] = &pangcd[i];
9283     pangcd[i++].creator = GLabelCreate;
9284 
9285     pangcd[i].gd.pos.x = 100; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y-6; pangcd[i].gd.pos.width = 120;
9286     pangcd[i].gd.flags = gg_visible | gg_enabled;
9287     pangcd[i].gd.cid = CID_PanLetterform;
9288     pangcd[i].gd.u.list = panletterform;
9289     panarray[j++] = &pangcd[i];
9290     pangcd[i++].creator = GListButtonCreate;
9291     panarray[j++] = NULL;
9292 
9293     pangcd[i].gd.pos.x = 20; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y+26+5;
9294     panlabel[i].text = (unichar_t *) _("_Midline");
9295     panlabel[i].text_is_1byte = true;
9296     panlabel[i].text_in_resource = true;
9297     pangcd[i].gd.label = &panlabel[i];
9298     pangcd[i].gd.cid = CID_PanMidLineLab;
9299     pangcd[i].gd.flags = gg_visible | gg_enabled;
9300     panarray[j++] = &pangcd[i];
9301     pangcd[i++].creator = GLabelCreate;
9302 
9303     pangcd[i].gd.pos.x = 100; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y-6; pangcd[i].gd.pos.width = 120;
9304     pangcd[i].gd.flags = gg_visible | gg_enabled;
9305     pangcd[i].gd.cid = CID_PanMidLine;
9306     pangcd[i].gd.u.list = panmidline;
9307     panarray[j++] = &pangcd[i];
9308     pangcd[i++].creator = GListButtonCreate;
9309     panarray[j++] = NULL;
9310 
9311     pangcd[i].gd.pos.x = 20; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y+26+5;
9312     panlabel[i].text = (unichar_t *) _("_X-Height");
9313     panlabel[i].text_is_1byte = true;
9314     panlabel[i].text_in_resource = true;
9315     pangcd[i].gd.label = &panlabel[i];
9316     pangcd[i].gd.cid = CID_PanXHeightLab;
9317     pangcd[i].gd.flags = gg_visible | gg_enabled;
9318     panarray[j++] = &pangcd[i];
9319     pangcd[i++].creator = GLabelCreate;
9320 
9321     pangcd[i].gd.pos.x = 100; pangcd[i].gd.pos.y = pangcd[i-1].gd.pos.y-6; pangcd[i].gd.pos.width = 120;
9322     pangcd[i].gd.flags = gg_visible | gg_enabled;
9323     pangcd[i].gd.cid = CID_PanXHeight;
9324     pangcd[i].gd.u.list = panxheight;
9325     panarray[j++] = &pangcd[i];
9326     pangcd[i++].creator = GListButtonCreate;
9327     panarray[j++] = NULL;
9328 
9329     panarray[j++] = GCD_Glue; panarray[j++] = GCD_Glue;
9330 
9331     panarray[j++] = NULL; panarray[j++] = NULL;
9332 
9333     memset(panbox,0,sizeof(panbox));
9334     panbox[0].gd.flags = gg_enabled|gg_visible;
9335     panbox[0].gd.u.boxelements = panarray;
9336     panbox[0].creator = GHVBoxCreate;
9337 /******************************************************************************/
9338     memset(cgcd,0,sizeof(cgcd));
9339     memset(clabel,0,sizeof(clabel));
9340     memset(cbox,0,sizeof(cbox));
9341 
9342     i = j = 0;
9343     clabel[i].text = (unichar_t *) _("Unicode Ranges:");
9344     clabel[i].text_is_1byte = true;
9345     cgcd[i].gd.label = &clabel[i];
9346     cgcd[i].gd.flags = gg_visible | gg_enabled;
9347     cgcd[i++].creator = GLabelCreate;
9348     charray1[0] = &cgcd[i-1];
9349 
9350     clabel[i].text = (unichar_t *) _("Default");
9351     clabel[i].text_is_1byte = true;
9352     cgcd[i].gd.label = &clabel[i];
9353     cgcd[i].gd.flags = gg_visible | gg_enabled;
9354     if ( !sf->pfminfo.hasunicoderanges ) {
9355 	cgcd[i].gd.flags = gg_visible | gg_enabled | gg_cb_on;
9356 	OS2FigureUnicodeRanges(sf,sf->pfminfo.unicoderanges);
9357     }
9358     cgcd[i].gd.cid = CID_URangesDefault;
9359     cgcd[i].gd.handle_controlevent = OS2_URangesDefault;
9360     cgcd[i++].creator = GCheckBoxCreate;
9361     charray1[1] = &cgcd[i-1]; charray1[2] = GCD_Glue; charray1[3] = NULL;
9362 
9363     cbox[2].gd.flags = gg_enabled|gg_visible;
9364     cbox[2].gd.u.boxelements = charray1;
9365     cbox[2].creator = GHBoxCreate;
9366     cvarray[j++] = &cbox[2];
9367 
9368     sprintf( ranges, "%08x.%08x.%08x.%08x",
9369 	    sf->pfminfo.unicoderanges[3], sf->pfminfo.unicoderanges[2],
9370 	    sf->pfminfo.unicoderanges[1], sf->pfminfo.unicoderanges[0]);
9371     clabel[i].text = (unichar_t *) ranges;
9372     clabel[i].text_is_1byte = true;
9373     cgcd[i].gd.label = &clabel[i];
9374     cgcd[i].gd.pos.width = 270;
9375     cgcd[i].gd.flags = /* gg_visible |*/ gg_enabled;
9376     if ( !sf->pfminfo.hasunicoderanges )
9377 	cgcd[i].gd.flags = /* gg_visible*/ 0;
9378     cgcd[i].gd.cid = CID_UnicodeRanges;
9379     cgcd[i].gd.handle_controlevent = OS2_UnicodeChange;
9380     cgcd[i++].creator = GTextFieldCreate;
9381     cvarray[j++] = &cgcd[i-1];
9382 
9383     cgcd[i].gd.pos.width = 220; cgcd[i].gd.pos.height = 6*12+10;
9384     cgcd[i].gd.flags = gg_visible | gg_enabled | gg_list_multiplesel;
9385     if ( !sf->pfminfo.hasunicoderanges )
9386 	cgcd[i].gd.flags = gg_visible | gg_list_multiplesel;
9387     cgcd[i].gd.cid = CID_UnicodeList;
9388     cgcd[i].gd.u.list = unicoderangenames;
9389     cgcd[i].gd.handle_controlevent = OS2_UnicodeChange;
9390     cgcd[i++].creator = GListCreate;
9391     cvarray[j++] = &cgcd[i-1];
9392 
9393     cgcd[i].gd.flags = gg_visible | gg_enabled ;
9394     cgcd[i++].creator = GLineCreate;
9395     cvarray[j++] = &cgcd[i-1];
9396 
9397     clabel[i].text = (unichar_t *) _("MS Code Pages:");
9398     clabel[i].text_is_1byte = true;
9399     cgcd[i].gd.label = &clabel[i];
9400     cgcd[i].gd.flags = gg_visible | gg_enabled;
9401     cgcd[i++].creator = GLabelCreate;
9402     charray2[0] = &cgcd[i-1];
9403 
9404     clabel[i].text = (unichar_t *) _("Default");
9405     clabel[i].text_is_1byte = true;
9406     cgcd[i].gd.label = &clabel[i];
9407     cgcd[i].gd.flags = gg_visible | gg_enabled;
9408     if ( !sf->pfminfo.hascodepages ) {
9409 	cgcd[i].gd.flags = gg_visible | gg_enabled | gg_cb_on;
9410 	OS2FigureCodePages(sf,sf->pfminfo.codepages);
9411     }
9412     cgcd[i].gd.cid = CID_CPageDefault;
9413     cgcd[i].gd.handle_controlevent = OS2_CPageDefault;
9414     cgcd[i++].creator = GCheckBoxCreate;
9415     charray2[1] = &cgcd[i-1]; charray2[2] = GCD_Glue; charray2[3] = NULL;
9416 
9417     cbox[3].gd.flags = gg_enabled|gg_visible;
9418     cbox[3].gd.u.boxelements = charray2;
9419     cbox[3].creator = GHBoxCreate;
9420     cvarray[j++] = &cbox[3];
9421 
9422     sprintf( codepages, "%08x.%08x",
9423 	    sf->pfminfo.codepages[1], sf->pfminfo.codepages[0]);
9424     clabel[i].text = (unichar_t *) codepages;
9425     clabel[i].text_is_1byte = true;
9426     cgcd[i].gd.label = &clabel[i];
9427     cgcd[i].gd.pos.width = 140;
9428     cgcd[i].gd.flags = /*gg_visible |*/ gg_enabled;
9429     if ( !sf->pfminfo.hascodepages )
9430 	cgcd[i].gd.flags = /*gg_visible*/ 0;
9431     cgcd[i].gd.cid = CID_CodePageRanges;
9432     cgcd[i].gd.handle_controlevent = OS2_CodePageChange;
9433     cgcd[i++].creator = GTextFieldCreate;
9434     cvarray2[0] = &cgcd[i-1]; cvarray2[1] = GCD_Glue; cvarray2[2] = NULL;
9435 
9436     cbox[4].gd.flags = gg_enabled|gg_visible;
9437     cbox[4].gd.u.boxelements = cvarray2;
9438     cbox[4].creator = GVBoxCreate;
9439     charray3[0] = &cbox[4];
9440 
9441     cgcd[i].gd.pos.width = 200; cgcd[i].gd.pos.height = 6*12+10;
9442     cgcd[i].gd.flags = gg_visible | gg_enabled | gg_list_multiplesel;
9443     if ( !sf->pfminfo.hascodepages )
9444 	cgcd[i].gd.flags = gg_visible | gg_list_multiplesel;
9445     cgcd[i].gd.cid = CID_CodePageList;
9446     cgcd[i].gd.u.list = codepagenames;
9447     cgcd[i].gd.handle_controlevent = OS2_CodePageChange;
9448     cgcd[i++].creator = GListCreate;
9449     charray3[1] = &cgcd[i-1]; charray3[2] = NULL;
9450 
9451     cbox[5].gd.flags = gg_enabled|gg_visible;
9452     cbox[5].gd.u.boxelements = charray3;
9453     cbox[5].creator = GHBoxCreate;
9454     cvarray[j++] = &cbox[5]; cvarray[j++] = GCD_Glue; cvarray[j++] = NULL;
9455 
9456     cbox[0].gd.flags = gg_enabled|gg_visible;
9457     cbox[0].gd.u.boxelements = cvarray;
9458     cbox[0].creator = GVBoxCreate;
9459 
9460 /******************************************************************************/
9461 
9462     memset(&vagcd,0,sizeof(vagcd));
9463     memset(&vaspects,'\0',sizeof(vaspects));
9464 
9465     i = 0;
9466     vaspects[i].text = (unichar_t *) _("Misc.");
9467     vaspects[i].text_is_1byte = true;
9468     vaspects[i++].gcd = vbox;
9469 
9470     vaspects[i].text = (unichar_t *) _("Metrics");
9471     vaspects[i].text_is_1byte = true;
9472     vaspects[i++].gcd = metbox;
9473 
9474     vaspects[i].text = (unichar_t *) _("Sub/Super");
9475     vaspects[i].text_is_1byte = true;
9476     vaspects[i++].gcd = ssbox;
9477 
9478     vaspects[i].text = (unichar_t *) _("Panose");
9479     vaspects[i].text_is_1byte = true;
9480     vaspects[i++].gcd = panbox;
9481 
9482     vaspects[i].text = (unichar_t *) _("Charsets");
9483     vaspects[i].text_is_1byte = true;
9484     vaspects[i++].gcd = cbox;
9485 
9486     vagcd[0].gd.pos.x = 4; vagcd[0].gd.pos.y = 6;
9487     vagcd[0].gd.pos.width = 252;
9488     vagcd[0].gd.pos.height = 300;
9489     vagcd[0].gd.u.tabs = vaspects;
9490     vagcd[0].gd.flags = gg_visible | gg_enabled | gg_tabset_scroll;
9491     /*vagcd[0].gd.handle_controlevent = GFI_TTFAspectChange;*/
9492     vagcd[0].gd.cid = CID_TTFTabs;
9493     vagcd[0].creator = GTabSetCreate;
9494 
9495 /******************************************************************************/
9496     memset(&gaspboxes,0,sizeof(gaspboxes));
9497     memset(&gaspgcd,0,sizeof(gaspgcd));
9498     memset(&gasplabel,0,sizeof(gasplabel));
9499     memset(&gaspgcd_def,0,sizeof(gaspgcd_def));
9500 
9501     GaspMatrixInit(&gaspmi,d);
9502 
9503     i = j = 0;
9504 
9505     gasplabel[i].text = (unichar_t *) S_("Gasp|_Version");
9506     gasplabel[i].text_is_1byte = true;
9507     gasplabel[i].text_in_resource = true;
9508     gaspgcd[i].gd.label = &gasplabel[i];
9509     gaspgcd[i].gd.flags = gg_visible | gg_enabled;
9510     gaspharray[j++] = &gaspgcd[i];
9511     gaspgcd[i++].creator = GLabelCreate;
9512 
9513     for ( g=0; gaspversions[g].text!=NULL; ++g )
9514 	gaspversions[g].selected = false;
9515     g = ( sf->gasp_version>=0 && sf->gasp_version<g ) ? sf->gasp_version : 0;
9516 
9517     gaspversions[g].selected = true;
9518     gaspgcd[i].gd.flags = gg_visible | gg_enabled;
9519     gaspgcd[i].gd.cid = CID_GaspVersion;
9520     gaspgcd[i].gd.label = &gaspversions[g];
9521     gaspgcd[i].gd.u.list = gaspversions;
9522     gaspharray[j++] = &gaspgcd[i];
9523     gaspgcd[i].gd.handle_controlevent = GFI_GaspVersion;
9524     gaspgcd[i++].creator = GListButtonCreate;
9525     gaspharray[j++] = GCD_HPad10;
9526 
9527     gasplabel[i].text = (unichar_t *) _("Optimized For ClearType");
9528     gasplabel[i].text_is_1byte = true;
9529     gasplabel[i].text_in_resource = true;
9530     gaspgcd[i].gd.label = &gasplabel[i];
9531     gaspgcd[i].gd.flags = gg_visible | gg_enabled;
9532     gaspgcd[i].gd.cid = CID_HeadClearType;
9533     if ( sf->head_optimized_for_cleartype )
9534 	gaspgcd[i].gd.flags |= gg_cb_on;
9535     gaspgcd[i].gd.popup_msg = _("Actually a bit in the 'head' table.\nIf unset then certain East Asian fonts will not be hinted");
9536     gaspharray[j++] = &gaspgcd[i];
9537     gaspgcd[i++].creator = GCheckBoxCreate;
9538     gaspharray[j++] = NULL;
9539 
9540     gaspboxes[2].gd.flags = gg_enabled|gg_visible;
9541     gaspboxes[2].gd.u.boxelements = gaspharray;
9542     gaspboxes[2].creator = GHBoxCreate;
9543 
9544     gaspvarray[0] = &gaspboxes[2];
9545 
9546     gaspgcd[i].gd.pos.width = 300; gaspgcd[i].gd.pos.height = 200;
9547     gaspgcd[i].gd.flags = gg_enabled | gg_visible;
9548     gaspgcd[i].gd.cid = CID_Gasp;
9549     gaspgcd[i].gd.u.matrix = &gaspmi;
9550     gaspgcd[i].gd.popup_msg = _(
9551 	"The 'gasp' table gives you control over when grid-fitting and\n"
9552 	"anti-aliased rasterizing are done.\n"
9553 	"The table consists of an (ordered) list of pixel sizes each with\n"
9554 	"a set of flags. Those flags apply to all pixel sizes bigger than\n"
9555 	"the previous table entry but less than or equal to the current.\n"
9556 	"The list must be terminated with a pixel size of 65535.\n"
9557 	"Version 1 of the table contains two additional flags that\n"
9558 	"apply to MS's ClearType rasterizer.\n\n"
9559 	"The 'gasp' table only applies to truetype fonts.");
9560     gaspgcd[i].data = d;
9561     gaspgcd[i].creator = GMatrixEditCreate;
9562     gaspvarray[1] = &gaspgcd[i];
9563     gaspvarray[2] = NULL;
9564 
9565     gaspboxes[0].gd.flags = gg_enabled|gg_visible;
9566     gaspboxes[0].gd.u.boxelements = gaspvarray;
9567     gaspboxes[0].creator = GVBoxCreate;
9568 
9569     gaspgcd_def[0].gd.flags = gg_visible | gg_enabled;
9570     gasplabel[4].text = (unichar_t *) S_("Gasp|_Default");
9571     gasplabel[4].text_is_1byte = true;
9572     gasplabel[4].text_in_resource = true;
9573     gaspgcd_def[0].gd.label = &gasplabel[4];
9574     gaspgcd_def[0].gd.handle_controlevent = Gasp_Default;
9575     gaspgcd_def[0].creator = GButtonCreate;
9576 /******************************************************************************/
9577     memset(&tnlabel,0,sizeof(tnlabel));
9578     memset(&tngcd,0,sizeof(tngcd));
9579     memset(&tnboxes,0,sizeof(tnboxes));
9580 
9581     TNMatrixInit(&mi,d);
9582 
9583     tngcd[0].gd.pos.x = 5; tngcd[0].gd.pos.y = 6;
9584     tngcd[0].gd.flags = gg_visible | gg_enabled;
9585     tnlabel[0].text = (unichar_t *) _("Sort By:");
9586     tnlabel[0].text_is_1byte = true;
9587     tngcd[0].gd.label = &tnlabel[0];
9588     tngcd[0].creator = GLabelCreate;
9589     tnharray[0] = &tngcd[0];
9590 
9591     tngcd[1].gd.pos.x = 50; tngcd[1].gd.pos.y = tngcd[0].gd.pos.y-4;
9592     tngcd[1].gd.flags = gg_enabled | gg_visible;
9593     tngcd[1].gd.cid = CID_TNLangSort;
9594     tnlabel[1].text = (unichar_t *) _("_Language");
9595     tnlabel[1].text_is_1byte = true;
9596     tnlabel[1].text_in_resource = true;
9597     tngcd[1].gd.label = &tnlabel[1];
9598     tngcd[1].creator = GRadioCreate;
9599     tngcd[1].gd.handle_controlevent = GFI_SortBy;
9600     tnharray[1] = &tngcd[1];
9601 
9602     tngcd[2].gd.pos.x = 120; tngcd[2].gd.pos.y = tngcd[1].gd.pos.y;
9603     tngcd[2].gd.flags = gg_visible | gg_enabled | gg_rad_continueold;
9604     tngcd[2].gd.cid = CID_TNStringSort;
9605     tnlabel[2].text = (unichar_t *) _("_String Type");
9606     tnlabel[2].text_is_1byte = true;
9607     tnlabel[2].text_in_resource = true;
9608     tngcd[2].gd.label = &tnlabel[2];
9609     tngcd[2].creator = GRadioCreate;
9610     tngcd[2].gd.handle_controlevent = GFI_SortBy;
9611     tnharray[2] = &tngcd[2];
9612 
9613     tngcd[3].gd.pos.x = 195; tngcd[3].gd.pos.y = tngcd[1].gd.pos.y;
9614     tngcd[3].gd.flags = gg_visible | gg_enabled | gg_cb_on | gg_rad_continueold;
9615     tnlabel[3].text = (unichar_t *) S_("SortingScheme|Default");
9616     tnlabel[3].text_is_1byte = true;
9617     tngcd[3].gd.label = &tnlabel[3];
9618     tngcd[3].creator = GRadioCreate;
9619     tngcd[3].gd.handle_controlevent = GFI_SortBy;
9620     tnharray[3] = &tngcd[3]; tnharray[4] = GCD_Glue; tnharray[5] = NULL;
9621 
9622     tngcd[4].gd.pos.x = 10; tngcd[4].gd.pos.y = tngcd[1].gd.pos.y+14;
9623     tngcd[4].gd.pos.width = 300; tngcd[4].gd.pos.height = 200;
9624     tngcd[4].gd.flags = gg_enabled | gg_visible;
9625     tngcd[4].gd.cid = CID_TNames;
9626     tngcd[4].gd.u.matrix = &mi;
9627     tngcd[4].gd.popup_msg = _(
9628 	"To create a new name, left click on the <New> button, and select a locale.\n"
9629 	"To change the locale, left click on it.\n"
9630 	"To change the string type, left click on it.\n"
9631 	"To change the text, left click in it and then type.\n"
9632 	"To delete a name, right click on the name & select Delete from the menu.\n"
9633 	"To associate or disassociate a truetype name to its postscript equivalent\n"
9634 	"right click and select the appropriate menu item." );
9635     tngcd[4].data = d;
9636     tngcd[4].creator = GMatrixEditCreate;
9637 
9638     tngcd[5].gd.flags = gg_visible | gg_enabled;
9639 /* GT: when translating this please leave the "SIL Open Font License" in */
9640 /* GT: English (possibly translating it in parentheses). I believe there */
9641 /* GT: are legal reasons for this. */
9642 /* GT: So "Añadir SIL Open Font License (licencia de fuentes libres)" */
9643     tnlabel[5].text = (unichar_t *) S_("Add OFL");
9644     tnlabel[5].image_precedes = false;
9645     tnlabel[5].image = &OFL_logo;
9646     tnlabel[5].text_is_1byte = true;
9647     tnlabel[5].text_in_resource = true;
9648     tngcd[5].gd.label = &tnlabel[5];
9649     tngcd[5].gd.handle_controlevent = GFI_AddOFL;
9650     tngcd[5].gd.popup_msg = _(
9651 	"Click here to add the OFL metadata to your own font in the License and License URL fields. \n"
9652 	"Then click on the License field to fill in the placeholders in sync with OFL.txt. \n");
9653     tngcd[5].creator = GButtonCreate;
9654 
9655     tngcd[6].gd.flags = gg_visible | gg_enabled;
9656     tnlabel[6].text = (unichar_t *) S_("scripts.sil.org/OFL");
9657     tnlabel[6].text_is_1byte = true;
9658     tnlabel[6].text_in_resource = true;
9659     tngcd[6].gd.label = &tnlabel[6];
9660     tngcd[6].gd.handle_controlevent = GFI_HelpOFL;
9661     tngcd[6].gd.popup_msg = _(
9662 	"Click here for more information about the OFL (SIL Open Font License) \n"
9663 	"including the corresponding FAQ. \n");
9664     tngcd[6].creator = GButtonCreate;
9665     tnharray2[0] = &tngcd[5]; tnharray2[1] = &tngcd[6]; tnharray2[2] = GCD_Glue; tnharray2[3] = NULL;
9666     tnvarray[0] = &tnboxes[2]; tnvarray[1] = &tngcd[4]; tnvarray[2] = &tnboxes[3]; tnvarray[3] = NULL;
9667 
9668     tnboxes[0].gd.flags = gg_enabled|gg_visible;
9669     tnboxes[0].gd.u.boxelements = tnvarray;
9670     tnboxes[0].creator = GVBoxCreate;
9671 
9672     tnboxes[2].gd.flags = gg_enabled|gg_visible;
9673     tnboxes[2].gd.u.boxelements = tnharray;
9674     tnboxes[2].creator = GHBoxCreate;
9675 
9676     tnboxes[3].gd.flags = gg_enabled|gg_visible;
9677     tnboxes[3].gd.u.boxelements = tnharray2;
9678     tnboxes[3].creator = GHBoxCreate;
9679 /******************************************************************************/
9680     memset(&ssnlabel,0,sizeof(ssnlabel));
9681     memset(&ssngcd,0,sizeof(ssngcd));
9682     memset(&ssboxes,0,sizeof(ssboxes));
9683 
9684     SSMatrixInit(&ssmi,d);
9685 
9686     ssngcd[0].gd.flags = gg_visible | gg_enabled;
9687     ssnlabel[0].text = (unichar_t *) _("The OpenType Style Set features ('ss01'-'ss20') may\n"
9688 				      "be assigned human readable names here.");
9689     ssnlabel[0].text_is_1byte = true;
9690     ssngcd[0].gd.label = &ssnlabel[0];
9691     ssngcd[0].creator = GLabelCreate;
9692     ssvarray[0] = &ssngcd[0];
9693 
9694     ssngcd[1].gd.pos.width = 300; ssngcd[1].gd.pos.height = 200;
9695     ssngcd[1].gd.flags = gg_enabled | gg_visible;
9696     ssngcd[1].gd.cid = CID_SSNames;
9697     ssngcd[1].gd.u.matrix = &ssmi;
9698     ssngcd[1].gd.popup_msg = _(
9699 	"To create a new name, left click on the <New> button, and select a locale (language).\n"
9700 	"To change the locale, left click on it.\n"
9701 	"To change the feature, left click on it.\n"
9702 	"To change the text, left click in it and then type.\n"
9703 	);
9704     ssngcd[1].data = d;
9705     ssngcd[1].creator = GMatrixEditCreate;
9706     ssvarray[1] = &ssngcd[1]; ssvarray[2] = NULL;
9707 
9708     ssboxes[0].gd.flags = gg_enabled|gg_visible;
9709     ssboxes[0].gd.u.boxelements = ssvarray;
9710     ssboxes[0].creator = GVBoxCreate;
9711 /******************************************************************************/
9712     memset(&comlabel,0,sizeof(comlabel));
9713     memset(&comgcd,0,sizeof(comgcd));
9714 
9715     comgcd[0].gd.flags = gg_visible | gg_enabled;
9716     comlabel[0].text = (unichar_t *) _("The font comment can contain whatever you feel it should");
9717     comlabel[0].text_is_1byte = true;
9718     comgcd[0].gd.label = &comlabel[0];
9719     comgcd[0].creator = GLabelCreate;
9720 
9721     comgcd[1].gd.pos.x = 10; comgcd[1].gd.pos.y = 10;
9722     comgcd[1].gd.pos.width = ngcd[11].gd.pos.width; comgcd[1].gd.pos.height = 230;
9723     comgcd[1].gd.flags = gg_visible | gg_enabled | gg_textarea_wrap | gg_text_xim;
9724     comgcd[1].gd.cid = CID_Comment;
9725     comlabel[1].text = (unichar_t *) sf->comments;
9726     comlabel[1].text_is_1byte = true;
9727     if ( comlabel[1].text==NULL ) comlabel[1].text = (unichar_t *) "";
9728     comgcd[1].gd.label = &comlabel[1];
9729     comgcd[1].creator = GTextAreaCreate;
9730 
9731     comarray[0] = &comgcd[0]; comarray[1] = &comgcd[1]; comarray[2] = NULL;
9732     memset(combox,0,sizeof(combox));
9733     combox[0].gd.flags = gg_enabled|gg_visible;
9734     combox[0].gd.u.boxelements = comarray;
9735     combox[0].creator = GVBoxCreate;
9736 
9737 /******************************************************************************/
9738     memset(&floglabel,0,sizeof(floglabel));
9739     memset(&floggcd,0,sizeof(floggcd));
9740 
9741     floggcd[0].gd.flags = gg_visible | gg_enabled;
9742     floglabel[0].text = (unichar_t *) _("The FONTLOG contains some description of the \n font project, a detailed changelog, and a list of contributors");
9743     floglabel[0].text_is_1byte = true;
9744     floggcd[0].gd.label = &floglabel[0];
9745     floggcd[0].creator = GLabelCreate;
9746 
9747     floggcd[1].gd.flags = gg_visible | gg_enabled | gg_textarea_wrap | gg_text_xim;
9748     floggcd[1].gd.cid = CID_FontLog;
9749     floglabel[1].text = (unichar_t *) sf->fontlog;
9750     floglabel[1].text_is_1byte = true;
9751     if ( floglabel[1].text==NULL ) floglabel[1].text = (unichar_t *) "";
9752     floggcd[1].gd.label = &floglabel[1];
9753     floggcd[1].creator = GTextAreaCreate;
9754 
9755     flogarray[0] = &floggcd[0]; flogarray[1] = &floggcd[1]; flogarray[2] = NULL;
9756     memset(flogbox,0,sizeof(flogbox));
9757     flogbox[0].gd.flags = gg_enabled|gg_visible;
9758     flogbox[0].gd.u.boxelements = flogarray;
9759     flogbox[0].creator = GVBoxCreate;
9760 
9761 /******************************************************************************/
9762     memset(&mklabel,0,sizeof(mklabel));
9763     memset(&mkgcd,0,sizeof(mkgcd));
9764 
9765     mklabel[0].text = (unichar_t *) _(
9766 	"These are not Anchor Classes. For them see the \"Lookups\" pane.\n"
9767 	"(Mark Classes can control when lookups are active, they do NOT\n"
9768 	" position glyphs.)");
9769     mklabel[0].text_is_1byte = true;
9770     mkgcd[0].gd.label = &mklabel[0];
9771     mkgcd[0].gd.flags = gg_visible | gg_enabled;
9772     mkgcd[0].creator = GLabelCreate;
9773 
9774     memset(&markc_mi,0,sizeof(markc_mi));
9775     markc_mi.col_cnt = 2;
9776     markc_mi.col_init = markc_ci;
9777 
9778     /* Class 0 is unused */
9779     markc_md = calloc(sf->mark_class_cnt+1,2*sizeof(struct matrix_data));
9780     for ( i=1; i<sf->mark_class_cnt; ++i ) {
9781 	markc_md[2*(i-1)+0].u.md_str = copy(sf->mark_class_names[i]);
9782 	markc_md[2*(i-1)+1].u.md_str = SFNameList2NameUni(sf,sf->mark_classes[i]);
9783     }
9784     markc_mi.matrix_data = markc_md;
9785     markc_mi.initial_row_cnt = sf->mark_class_cnt>0?sf->mark_class_cnt-1:0;
9786     markc_mi.finishedit = GFI_Mark_FinishEdit;
9787 
9788     mkgcd[1].gd.pos.x = 10; mkgcd[1].gd.pos.y = 10;
9789     mkgcd[1].gd.pos.width = ngcd[15].gd.pos.width; mkgcd[1].gd.pos.height = 200;
9790     mkgcd[1].gd.flags = gg_visible | gg_enabled;
9791     mkgcd[1].gd.cid = CID_MarkClasses;
9792     mkgcd[1].gd.u.matrix = &markc_mi;
9793     mkgcd[1].creator = GMatrixEditCreate;
9794 
9795     mkgcd[2].gd.pos.x = 10; mkgcd[2].gd.pos.y = mkgcd[1].gd.pos.y+mkgcd[1].gd.pos.height+4;
9796     mkgcd[2].gd.pos.width = -1;
9797     mkgcd[2].gd.flags = gg_visible | gg_enabled;
9798 
9799     mkarray[0] = &mkgcd[0]; mkarray[1] = &mkgcd[1];
9800       mkarray[2] = NULL;
9801     memset(mkbox,0,sizeof(mkbox));
9802     mkbox[0].gd.flags = gg_enabled|gg_visible;
9803     mkbox[0].gd.u.boxelements = mkarray;
9804     mkbox[0].creator = GVBoxCreate;
9805 /******************************************************************************/
9806     memset(&mslabel,0,sizeof(mslabel));
9807     memset(&msgcd,0,sizeof(msgcd));
9808 
9809     mslabel[0].text = (unichar_t *) _(
9810 	"These are not Anchor Classes. For them see the \"Lookups\" pane.\n"
9811 	"(Mark Sets, like Mark Classes can control when lookups are active,\n"
9812 	" they do NOT position glyphs.)");
9813     mslabel[0].text_is_1byte = true;
9814     msgcd[0].gd.label = &mslabel[0];
9815     msgcd[0].gd.flags = gg_visible | gg_enabled;
9816     msgcd[0].creator = GLabelCreate;
9817 
9818     memset(&marks_mi,0,sizeof(marks_mi));
9819     marks_mi.col_cnt = 2;
9820     marks_mi.col_init = marks_ci;
9821 
9822     /* Set 0 is used */
9823     marks_md = calloc(sf->mark_set_cnt+1,2*sizeof(struct matrix_data));
9824     for ( i=0; i<sf->mark_set_cnt; ++i ) {
9825 	marks_md[2*i+0].u.md_str = copy(sf->mark_set_names[i]);
9826 	marks_md[2*i+1].u.md_str = SFNameList2NameUni(sf,sf->mark_sets[i]);
9827     }
9828     marks_mi.matrix_data = marks_md;
9829     marks_mi.initial_row_cnt = sf->mark_set_cnt;
9830     marks_mi.finishedit = GFI_Mark_FinishEdit;
9831 
9832     msgcd[1].gd.pos.x = 10; msgcd[1].gd.pos.y = 10;
9833     msgcd[1].gd.pos.width = ngcd[15].gd.pos.width; msgcd[1].gd.pos.height = 200;
9834     msgcd[1].gd.flags = gg_visible | gg_enabled;
9835     msgcd[1].gd.cid = CID_MarkSets;
9836     msgcd[1].gd.u.matrix = &marks_mi;
9837     msgcd[1].creator = GMatrixEditCreate;
9838 
9839     msarray[0] = &msgcd[0]; msarray[1] = &msgcd[1];
9840       msarray[2] = NULL;
9841     memset(msbox,0,sizeof(msbox));
9842     msbox[0].gd.flags = gg_enabled|gg_visible;
9843     msbox[0].gd.u.boxelements = msarray;
9844     msbox[0].creator = GVBoxCreate;
9845 /******************************************************************************/
9846     memset(&wofflabel,0,sizeof(wofflabel));
9847     memset(&woffgcd,0,sizeof(woffgcd));
9848 
9849     wofflabel[0].text = (unichar_t *) _("Version, Major:");
9850     wofflabel[0].text_is_1byte = true;
9851     woffgcd[0].gd.label = &wofflabel[0];
9852     woffgcd[0].gd.flags = gg_visible | gg_enabled;
9853     woffgcd[0].creator = GLabelCreate;
9854 
9855     woffmajorbuf[0]='\0';
9856     woffminorbuf[0]='\0';
9857     if ( sf->woffMajor!=woffUnset ) {
9858 	sprintf( woffmajorbuf, "%d", sf->woffMajor );
9859 	sprintf( woffminorbuf, "%d", sf->woffMinor );
9860     }
9861     woffgcd[1].gd.flags = gg_visible | gg_enabled;
9862     wofflabel[1].text = (unichar_t *) woffmajorbuf;
9863     wofflabel[1].text_is_1byte = true;
9864     woffgcd[1].gd.label = &wofflabel[1];
9865     woffgcd[1].gd.cid = CID_WoffMajor;
9866     woffgcd[1].gd.popup_msg = _("If you leave this field blank FontForge will use a default based on\neither the version string, or one in the 'name' table." );
9867     woffgcd[1].creator = GTextFieldCreate;
9868 
9869     wofflabel[2].text = (unichar_t *) _("Minor:");
9870     wofflabel[2].text_is_1byte = true;
9871     woffgcd[2].gd.label = &wofflabel[2];
9872     woffgcd[2].gd.flags = gg_visible | gg_enabled;
9873     woffgcd[2].creator = GLabelCreate;
9874 
9875     woffgcd[3].gd.flags = gg_visible | gg_enabled;
9876     wofflabel[3].text = (unichar_t *) woffminorbuf;
9877     wofflabel[3].text_is_1byte = true;
9878     woffgcd[3].gd.label = &wofflabel[3];
9879     woffgcd[3].gd.cid = CID_WoffMinor;
9880     woffgcd[3].gd.popup_msg = _("If you leave this field blank FontForge will use a default based on\neither the version string, or one in the 'name' table." );
9881     woffgcd[3].creator = GTextFieldCreate;
9882 
9883     woffarray[0] = &woffgcd[0];
9884     woffarray[1] = &woffgcd[1];
9885     woffarray[2] = &woffgcd[2];
9886     woffarray[3] = &woffgcd[3];
9887     woffarray[4] = NULL;
9888 
9889     wofflabel[4].text = (unichar_t *) _("Metadata (xml):");
9890     wofflabel[4].text_is_1byte = true;
9891     woffgcd[4].gd.label = &wofflabel[4];
9892     woffgcd[4].gd.flags = gg_visible | gg_enabled;
9893     woffgcd[4].creator = GLabelCreate;
9894 
9895     woffarray[5] = &woffgcd[4];
9896     woffarray[6] = GCD_ColSpan;
9897     woffarray[7] = GCD_ColSpan;
9898     woffarray[8] = GCD_ColSpan;
9899     woffarray[9] = NULL;
9900 
9901     woffgcd[5].gd.flags = gg_visible | gg_enabled | gg_textarea_wrap;
9902     if ( sf->woffMetadata!=NULL ) {
9903 	wofflabel[5].text = (unichar_t *) sf->woffMetadata;
9904 	wofflabel[5].text_is_1byte = true;
9905 	woffgcd[5].gd.label = &wofflabel[5];
9906     }
9907     woffgcd[5].gd.cid = CID_WoffMetadata;
9908     woffgcd[5].creator = GTextAreaCreate;
9909 
9910     woffarray[10] = &woffgcd[5];
9911     woffarray[11] = GCD_ColSpan;
9912     woffarray[12] = GCD_ColSpan;
9913     woffarray[13] = GCD_ColSpan;
9914     woffarray[14] = NULL;
9915     woffarray[15] = NULL;
9916 
9917     memset(woffbox,0,sizeof(woffbox));
9918     woffbox[0].gd.flags = gg_enabled|gg_visible;
9919     woffbox[0].gd.u.boxelements = woffarray;
9920     woffbox[0].creator = GHVBoxCreate;
9921 /******************************************************************************/
9922     memset(&txlabel,0,sizeof(txlabel));
9923     memset(&txgcd,0,sizeof(txgcd));
9924 
9925     k=0;
9926     txlabel[k].text = (unichar_t *) U_("ΤεΧ General");
9927     txlabel[k].text_is_1byte = true;
9928     txgcd[k].gd.label = &txlabel[k];
9929     txgcd[k].gd.pos.x = 10; txgcd[k].gd.pos.y = 10;
9930     txgcd[k].gd.flags = gg_visible | gg_enabled;
9931     txgcd[k].gd.cid = CID_TeXText;
9932     txgcd[k].gd.handle_controlevent = GFI_TeXChanged;
9933     txgcd[k++].creator = GRadioCreate;
9934 
9935     txlabel[k].text = (unichar_t *) U_("ΤεΧ Math Symbol");
9936     txlabel[k].text_is_1byte = true;
9937     txgcd[k].gd.label = &txlabel[k];
9938     txgcd[k].gd.pos.x = 80; txgcd[k].gd.pos.y = txgcd[k-1].gd.pos.y;
9939     txgcd[k].gd.flags = gg_visible | gg_enabled | gg_rad_continueold;
9940     txgcd[k].gd.cid = CID_TeXMathSym;
9941     txgcd[k].gd.handle_controlevent = GFI_TeXChanged;
9942     txgcd[k++].creator = GRadioCreate;
9943 
9944     txlabel[k].text = (unichar_t *) U_("ΤεΧ Math Extension");
9945     txlabel[k].text_is_1byte = true;
9946     txgcd[k].gd.label = &txlabel[k];
9947     txgcd[k].gd.pos.x = 155; txgcd[k].gd.pos.y = txgcd[k-1].gd.pos.y;
9948     txgcd[k].gd.flags = gg_visible | gg_enabled | gg_rad_continueold;
9949     txgcd[k].gd.cid = CID_TeXMathExt;
9950     txgcd[k].gd.handle_controlevent = GFI_TeXChanged;
9951     txgcd[k++].creator = GRadioCreate;
9952 
9953     for ( i=j=0; texparams[i]!=0; ++i ) {
9954 	txlabel[k].text = (unichar_t *) texparams[i];
9955 	txlabel[k].text_is_1byte = true;
9956 	txgcd[k].gd.label = &txlabel[k];
9957 	txgcd[k].gd.pos.x = 10; txgcd[k].gd.pos.y = txgcd[k-2].gd.pos.y+26;
9958 	txgcd[k].gd.flags = gg_visible | gg_enabled;
9959 	txgcd[k].gd.popup_msg = texpopups[i];
9960 	txarray2[j++] = &txgcd[k];
9961 	txgcd[k++].creator = GLabelCreate;
9962 
9963 	txgcd[k].gd.pos.x = 70; txgcd[k].gd.pos.y = txgcd[k-1].gd.pos.y-4;
9964 	txgcd[k].gd.flags = gg_visible | gg_enabled;
9965 	txgcd[k].gd.cid = CID_TeX + i;
9966 	txarray2[j++] = &txgcd[k];
9967 	txgcd[k++].creator = GTextFieldCreate;
9968 	txarray2[j++] = GCD_Glue;
9969 	txarray2[j++] = NULL;
9970     }
9971     txgcd[k-2].gd.cid = CID_TeXExtraSpLabel;
9972     txarray2[j++] = NULL;
9973 
9974 /* GT: More Parameters */
9975     txlabel[k].text = (unichar_t *) _("More Params");
9976     txlabel[k].text_is_1byte = true;
9977     txgcd[k].gd.label = &txlabel[k];
9978     txgcd[k].gd.pos.x = 20; txgcd[k].gd.pos.y = txgcd[k-1].gd.pos.y+26;
9979     txgcd[k].gd.flags = gg_visible | gg_enabled;
9980     txgcd[k].gd.handle_controlevent = GFI_MoreParams;
9981     txgcd[k].gd.cid = CID_MoreParams;
9982     txgcd[k++].creator = GButtonCreate;
9983 
9984     txarray[0] = &txbox[2]; txarray[1] = &txbox[3]; txarray[2] = &txbox[4]; txarray[3] = GCD_Glue; txarray[4] = NULL;
9985     txarray3[0] = &txgcd[0]; txarray3[1] = GCD_Glue; txarray3[2] = &txgcd[1];
9986      txarray3[3] = GCD_Glue; txarray3[4] = &txgcd[2]; txarray3[5] = NULL;
9987     txarray4[0] = GCD_Glue; txarray4[1] = &txgcd[k-1];
9988      txarray4[2] = txarray4[3] = txarray4[4] = GCD_Glue; txarray4[5] = NULL;
9989     memset(txbox,0,sizeof(txbox));
9990     txbox[0].gd.flags = gg_enabled|gg_visible;
9991     txbox[0].gd.u.boxelements = txarray;
9992     txbox[0].creator = GVBoxCreate;
9993 
9994     txbox[2].gd.flags = gg_enabled|gg_visible;
9995     txbox[2].gd.u.boxelements = txarray3;
9996     txbox[2].creator = GHBoxCreate;
9997 
9998     txbox[3].gd.flags = gg_enabled|gg_visible;
9999     txbox[3].gd.u.boxelements = txarray2;
10000     txbox[3].gd.cid = CID_TeXBox;
10001     txbox[3].creator = GHVBoxCreate;
10002 
10003     txbox[4].gd.flags = gg_enabled|gg_visible;
10004     txbox[4].gd.u.boxelements = txarray4;
10005     txbox[4].creator = GHBoxCreate;
10006 /******************************************************************************/
10007     memset(&szlabel,0,sizeof(szlabel));
10008     memset(&szgcd,0,sizeof(szgcd));
10009     SizeMatrixInit(&sizemi,d);
10010 
10011     k=0;
10012 
10013     szlabel[k].text = (unichar_t *) _("De_sign Size:");
10014     szlabel[k].text_is_1byte = true;
10015     szlabel[k].text_in_resource = true;
10016     szgcd[k].gd.label = &szlabel[k];
10017     szgcd[k].gd.pos.x = 10; szgcd[k].gd.pos.y = 9;
10018     szgcd[k].gd.flags = gg_visible | gg_enabled;
10019     szgcd[k].gd.popup_msg = _("The size (in points) for which this face was designed");
10020     szgcd[k++].creator = GLabelCreate;
10021 
10022     sprintf(dszbuf, "%.1f", sf->design_size/10.0);
10023     szlabel[k].text = (unichar_t *) dszbuf;
10024     szlabel[k].text_is_1byte = true;
10025     szgcd[k].gd.label = &szlabel[k];
10026     szgcd[k].gd.pos.x = 70; szgcd[k].gd.pos.y = szgcd[k-1].gd.pos.y-4;
10027     szgcd[k].gd.pos.width = 60;
10028     szgcd[k].gd.flags = gg_visible | gg_enabled;
10029     szgcd[k].gd.cid = CID_DesignSize;
10030     szgcd[k++].creator = GTextFieldCreate;
10031 
10032     szlabel[k].text = (unichar_t *) S_("Size|Points");
10033     szlabel[k].text_is_1byte = true;
10034     szgcd[k].gd.label = &szlabel[k];
10035     szgcd[k].gd.pos.x = 134; szgcd[k].gd.pos.y = szgcd[k-2].gd.pos.y;
10036     szgcd[k].gd.flags = gg_visible | gg_enabled;
10037     szgcd[k].gd.popup_msg = _("The size (in points) for which this face was designed");
10038     szgcd[k++].creator = GLabelCreate;
10039 
10040     szlabel[k].text = (unichar_t *) _("Design Range");
10041     szlabel[k].text_is_1byte = true;
10042     szgcd[k].gd.label = &szlabel[k];
10043     szgcd[k].gd.pos.x = 14; szgcd[k].gd.pos.y = szgcd[k-2].gd.pos.y+24;
10044     szgcd[k].gd.flags = gg_visible | gg_enabled;
10045     szgcd[k].gd.popup_msg = _("The range of sizes (in points) to which this face applies.\nLower bound is exclusive, upper bound is inclusive.");
10046     szgcd[k++].creator = GLabelCreate;
10047 
10048     szgcd[k].gd.pos.x = 8; szgcd[k].gd.pos.y = GDrawPointsToPixels(NULL,szgcd[k-1].gd.pos.y+6);
10049     szgcd[k].gd.pos.width = pos.width-32; szgcd[k].gd.pos.height = GDrawPointsToPixels(NULL,36);
10050     szgcd[k].gd.flags = gg_enabled | gg_visible | gg_pos_in_pixels;
10051     szgcd[k++].creator = GGroupCreate;
10052 
10053     szlabel[k].text = (unichar_t *) _("_Bottom:");
10054     szlabel[k].text_is_1byte = true;
10055     szlabel[k].text_in_resource = true;
10056     szgcd[k].gd.label = &szlabel[k];
10057     szgcd[k].gd.pos.x = 14; szgcd[k].gd.pos.y = szgcd[k-2].gd.pos.y+18;
10058     szgcd[k].gd.flags = gg_visible | gg_enabled;
10059     szgcd[k].gd.popup_msg = _("The range of sizes (in points) to which this face applies.\nLower bound is exclusive, upper bound is inclusive.");
10060     szgcd[k++].creator = GLabelCreate;
10061 
10062     sprintf(dsbbuf, "%.1f", sf->design_range_bottom/10.0);
10063     szlabel[k].text = (unichar_t *) dsbbuf;
10064     szlabel[k].text_is_1byte = true;
10065     szgcd[k].gd.label = &szlabel[k];
10066     szgcd[k].gd.pos.x = 70; szgcd[k].gd.pos.y = szgcd[k-1].gd.pos.y-4;
10067     szgcd[k].gd.pos.width = 60;
10068     szgcd[k].gd.flags = gg_visible | gg_enabled;
10069     szgcd[k].gd.cid = CID_DesignBottom;
10070     szgcd[k++].creator = GTextFieldCreate;
10071 
10072     szlabel[k].text = (unichar_t *) _("_Top:");
10073     szlabel[k].text_is_1byte = true;
10074     szlabel[k].text_in_resource = true;
10075     szgcd[k].gd.label = &szlabel[k];
10076     szgcd[k].gd.pos.x = 140; szgcd[k].gd.pos.y = szgcd[k-2].gd.pos.y;
10077     szgcd[k].gd.flags = gg_visible | gg_enabled;
10078     szgcd[k].gd.popup_msg = _("The range of sizes (in points) to which this face applies.\nLower bound is exclusive, upper bound is inclusive.");
10079     szgcd[k++].creator = GLabelCreate;
10080 
10081     sprintf(dstbuf, "%.1f", sf->design_range_top/10.0);
10082     szlabel[k].text = (unichar_t *) dstbuf;
10083     szlabel[k].text_is_1byte = true;
10084     szgcd[k].gd.label = &szlabel[k];
10085     szgcd[k].gd.pos.x = 180; szgcd[k].gd.pos.y = szgcd[k-1].gd.pos.y-4;
10086     szgcd[k].gd.pos.width = 60;
10087     szgcd[k].gd.flags = gg_visible | gg_enabled;
10088     szgcd[k].gd.cid = CID_DesignTop;
10089     szgcd[k++].creator = GTextFieldCreate;
10090 
10091     szlabel[k].text = (unichar_t *) _("Style _ID:");
10092     szlabel[k].text_is_1byte = true;
10093     szlabel[k].text_in_resource = true;
10094     szgcd[k].gd.label = &szlabel[k];
10095     szgcd[k].gd.pos.x = 14; szgcd[k].gd.pos.y = GDrawPixelsToPoints(NULL,szgcd[k-5].gd.pos.y+szgcd[k-5].gd.pos.height)+10;
10096     szgcd[k].gd.flags = gg_visible | gg_enabled;
10097     szgcd[k].gd.popup_msg = _("This is an identifying number shared by all members of\nthis font family with the same style (I.e. 10pt Bold and\n24pt Bold would have the same id, but 10pt Italic would not");
10098     szgcd[k++].creator = GLabelCreate;
10099 
10100     sprintf(sibuf, "%d", sf->fontstyle_id);
10101     szlabel[k].text = (unichar_t *) sibuf;
10102     szlabel[k].text_is_1byte = true;
10103     szgcd[k].gd.label = &szlabel[k];
10104     szgcd[k].gd.pos.x = 70; szgcd[k].gd.pos.y = szgcd[k-1].gd.pos.y-4;
10105     szgcd[k].gd.pos.width = 60;
10106     szgcd[k].gd.flags = gg_visible | gg_enabled;
10107     szgcd[k].gd.cid = CID_StyleID;
10108     szgcd[k++].creator = GTextFieldCreate;
10109 
10110     szlabel[k].text = (unichar_t *) _("Style Name:");
10111     szlabel[k].text_is_1byte = true;
10112     szgcd[k].gd.label = &szlabel[k];
10113     szgcd[k].gd.pos.x = 14; szgcd[k].gd.pos.y = szgcd[k-2].gd.pos.y+22;
10114     szgcd[k].gd.flags = gg_visible | gg_enabled;
10115     szgcd[k].gd.popup_msg = _("This provides a set of names used to identify the\nstyle of this font. Names may be translated into multiple\nlanguages (English is required, others are optional)\nAll fonts with the same Style ID should share this name.");
10116     szgcd[k++].creator = GLabelCreate;
10117 
10118     szgcd[k].gd.pos.width = 300; szgcd[k].gd.pos.height = 200;
10119     szgcd[k].gd.flags = gg_enabled | gg_visible;
10120     szgcd[k].gd.cid = CID_StyleName;
10121     szgcd[k].gd.u.matrix = &sizemi;
10122     szgcd[k].gd.popup_msg = _(
10123 	"To create a new name, left click on the <New> button, and select a locale (language).\n"
10124 	"To change the locale, left click on it.\n"
10125 	"To change the text, left click in it and then type.\n"
10126 	);
10127     szgcd[k].data = d;
10128     szgcd[k].creator = GMatrixEditCreate;
10129 
10130     szarray[0] = &szbox[2];
10131     szarray[1] = &szbox[3];
10132     szarray[2] = &szbox[4];
10133     szarray[3] = &szgcd[11];
10134     szarray[4] = &szgcd[12];
10135     szarray[5] = NULL;
10136 
10137     szarray2[0] = &szgcd[0]; szarray2[1] = &szgcd[1]; szarray2[2] = &szgcd[2]; szarray2[3] = GCD_Glue; szarray2[4] = NULL;
10138     szarray3[0] = &szgcd[5]; szarray3[1] = &szgcd[6]; szarray3[2] = &szgcd[7]; szarray3[3] = &szgcd[8]; szarray3[4] = GCD_Glue; szarray3[5] = NULL;
10139      szarray3[6] = NULL;
10140     szarray4[0] = &szgcd[9]; szarray4[1] = &szgcd[10]; szarray4[2] = GCD_Glue; szarray4[3] = NULL;
10141 
10142     memset(szbox,0,sizeof(szbox));
10143     szbox[0].gd.flags = gg_enabled|gg_visible;
10144     szbox[0].gd.u.boxelements = szarray;
10145     szbox[0].creator = GVBoxCreate;
10146 
10147     szbox[2].gd.flags = gg_enabled|gg_visible;
10148     szbox[2].gd.u.boxelements = szarray2;
10149     szbox[2].creator = GHBoxCreate;
10150 
10151     szbox[3].gd.flags = gg_enabled|gg_visible;
10152     szbox[3].gd.label = (GTextInfo *) &szgcd[3];
10153     szbox[3].gd.u.boxelements = szarray3;
10154     szbox[3].creator = GHVGroupCreate;
10155 
10156     szbox[4].gd.flags = gg_enabled|gg_visible;
10157     szbox[4].gd.u.boxelements = szarray4;
10158     szbox[4].creator = GHBoxCreate;
10159 
10160 /******************************************************************************/
10161     memset(&mcgcd,0,sizeof(mcgcd));
10162     memset(&mclabel,'\0',sizeof(mclabel));
10163 
10164     k=0;
10165     mclabel[k].text = (unichar_t *) _("Mac Style Set:");
10166     mclabel[k].text_is_1byte = true;
10167     mcgcd[k].gd.label = &mclabel[k];
10168     mcgcd[k].gd.pos.x = 10; mcgcd[k].gd.pos.y = 7;
10169     mcgcd[k].gd.flags = gg_visible | gg_enabled;
10170     mcgcd[k++].creator = GLabelCreate;
10171 
10172     mclabel[k].text = (unichar_t *) _("Automatic");
10173     mclabel[k].text_is_1byte = true;
10174     mcgcd[k].gd.label = &mclabel[k];
10175     mcgcd[k].gd.pos.x = 10; mcgcd[k].gd.pos.y = 20;
10176     mcgcd[k].gd.flags = (sf->macstyle==-1) ? (gg_visible | gg_enabled | gg_cb_on) : (gg_visible | gg_enabled);
10177     mcgcd[k].gd.cid = CID_MacAutomatic;
10178     mcgcd[k].gd.handle_controlevent = GFI_MacAutomatic;
10179     mcgcd[k++].creator = GRadioCreate;
10180 
10181     mcgcd[k].gd.pos.x = 90; mcgcd[k].gd.pos.y = 20;
10182     mcgcd[k].gd.flags = (sf->macstyle!=-1) ? (gg_visible | gg_enabled | gg_cb_on | gg_rad_continueold) : (gg_visible | gg_enabled | gg_rad_continueold);
10183     mcgcd[k].gd.handle_controlevent = GFI_MacAutomatic;
10184     mcgcd[k++].creator = GRadioCreate;
10185 
10186     mcgcd[k].gd.pos.x = 110; mcgcd[k].gd.pos.y = 20;
10187     mcgcd[k].gd.pos.width = 120; mcgcd[k].gd.pos.height = 7*12+10;
10188     mcgcd[k].gd.flags = (sf->macstyle==-1) ? (gg_visible | gg_list_multiplesel) : (gg_visible | gg_enabled | gg_list_multiplesel);
10189     mcgcd[k].gd.cid = CID_MacStyles;
10190     mcgcd[k].gd.u.list = macstyles;
10191     mcgcd[k++].creator = GListCreate;
10192 
10193     mclabel[k].text = (unichar_t *) _("FOND Name:");
10194     mclabel[k].text_is_1byte = true;
10195     mcgcd[k].gd.label = &mclabel[k];
10196     mcgcd[k].gd.pos.x = 10; mcgcd[k].gd.pos.y = mcgcd[k-1].gd.pos.y + mcgcd[k-1].gd.pos.height+8;
10197     mcgcd[k].gd.flags = gg_visible | gg_enabled;
10198     mcgcd[k++].creator = GLabelCreate;
10199 
10200     mclabel[k].text = (unichar_t *) sf->fondname;
10201     mclabel[k].text_is_1byte = true;
10202     mcgcd[k].gd.label = sf->fondname==NULL ? NULL : &mclabel[k];
10203     mcgcd[k].gd.pos.x = 90; mcgcd[k].gd.pos.y = mcgcd[k-1].gd.pos.y - 4;
10204     mcgcd[k].gd.flags = gg_visible | gg_enabled;
10205     mcgcd[k].gd.cid = CID_MacFOND;
10206     mcgcd[k++].creator = GTextFieldCreate;
10207 
10208 
10209     mcs = MacStyleCode(sf,NULL);
10210     for ( i=0; macstyles[i].text!=NULL; ++i )
10211 	macstyles[i].selected = (mcs&(int) (intpt) macstyles[i].userdata)? 1 : 0;
10212 
10213     mcarray[0] = &mcgcd[0]; mcarray[1] = GCD_Glue; mcarray[2] = NULL;
10214     mcarray[3] = &mcbox[2]; mcarray[4] = &mcgcd[3]; mcarray[5] = NULL;
10215     mcarray[6] = &mcgcd[4]; mcarray[7] = &mcgcd[5]; mcarray[8] = NULL;
10216     mcarray[9] = GCD_Glue; mcarray[10] = GCD_Glue; mcarray[11] = NULL;
10217     mcarray[12] = NULL;
10218     mcarray2[0] = &mcgcd[1]; mcarray2[1] = &mcgcd[2]; mcarray2[2] = NULL;
10219     mcarray2[3] = GCD_Glue; mcarray2[4] = GCD_Glue; mcarray2[5] = NULL;
10220     mcarray2[6] = NULL;
10221 
10222     memset(mcbox,0,sizeof(mcbox));
10223     mcbox[0].gd.flags = gg_enabled|gg_visible;
10224     mcbox[0].gd.u.boxelements = mcarray;
10225     mcbox[0].creator = GHVBoxCreate;
10226 
10227     mcbox[2].gd.flags = gg_enabled|gg_visible;
10228     mcbox[2].gd.u.boxelements = mcarray2;
10229     mcbox[2].creator = GHVBoxCreate;
10230 
10231 /******************************************************************************/
10232     memset(&lksubgcd,0,sizeof(lksubgcd));
10233     memset(&lkgcd,0,sizeof(lkgcd));
10234     memset(&lkaspects,'\0',sizeof(lkaspects));
10235     memset(&lkbox,'\0',sizeof(lkbox));
10236     memset(&lkbuttonsgcd,'\0',sizeof(lkbuttonsgcd));
10237     memset(&lkbuttonslabel,'\0',sizeof(lkbuttonslabel));
10238 
10239     LookupSetup(&d->tables[0],sf->gsub_lookups);
10240     LookupSetup(&d->tables[1],sf->gpos_lookups);
10241 
10242     i=0;
10243     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10244     lkbuttonsgcd[i].gd.flags = gg_visible;
10245     lkbuttonsgcd[i].gd.popup_msg = _("Moves the currently selected lookup to be first in the lookup ordering\nor moves the currently selected subtable to be first in its lookup.");
10246     lkbuttonslabel[i].text = (unichar_t *) _("_Top");
10247     lkbuttonslabel[i].text_is_1byte = true;
10248     lkbuttonslabel[i].text_in_resource = true;
10249     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10250     lkbuttonsgcd[i].gd.cid = CID_LookupTop;
10251     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupOrder;
10252     lkbuttonsgcd[i++].creator = GButtonCreate;
10253 
10254     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10255     lkbuttonsgcd[i].gd.flags = gg_visible;
10256     lkbuttonsgcd[i].gd.popup_msg = _("Moves the currently selected lookup before the previous lookup\nor moves the currently selected subtable before the previous subtable.");
10257     lkbuttonslabel[i].text = (unichar_t *) _("_Up");
10258     lkbuttonslabel[i].text_is_1byte = true;
10259     lkbuttonslabel[i].text_in_resource = true;
10260     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10261     lkbuttonsgcd[i].gd.cid = CID_LookupUp;
10262     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupOrder;
10263     lkbuttonsgcd[i++].creator = GButtonCreate;
10264 
10265     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10266     lkbuttonsgcd[i].gd.flags = gg_visible;
10267     lkbuttonsgcd[i].gd.popup_msg = _("Moves the currently selected lookup after the next lookup\nor moves the currently selected subtable after the next subtable.");
10268     lkbuttonslabel[i].text = (unichar_t *) _("_Down");
10269     lkbuttonslabel[i].text_is_1byte = true;
10270     lkbuttonslabel[i].text_in_resource = true;
10271     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10272     lkbuttonsgcd[i].gd.cid = CID_LookupDown;
10273     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupOrder;
10274     lkbuttonsgcd[i++].creator = GButtonCreate;
10275 
10276     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10277     lkbuttonsgcd[i].gd.flags = gg_visible;
10278     lkbuttonsgcd[i].gd.popup_msg = _("Moves the currently selected lookup to the end of the lookup chain\nor moves the currently selected subtable to be the last subtable in the lookup");
10279     lkbuttonslabel[i].text = (unichar_t *) _("_Bottom");
10280     lkbuttonslabel[i].text_is_1byte = true;
10281     lkbuttonslabel[i].text_in_resource = true;
10282     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10283     lkbuttonsgcd[i].gd.cid = CID_LookupBottom;
10284     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupOrder;
10285     lkbuttonsgcd[i++].creator = GButtonCreate;
10286 
10287     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10288     lkbuttonsgcd[i].gd.flags = gg_visible;
10289     lkbuttonsgcd[i].gd.popup_msg = _("Sorts the lookups in a default ordering based on feature tags");
10290     lkbuttonslabel[i].text = (unichar_t *) _("_Sort");
10291     lkbuttonslabel[i].text_is_1byte = true;
10292     lkbuttonslabel[i].text_in_resource = true;
10293     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10294     lkbuttonsgcd[i].gd.cid = CID_LookupSort;
10295     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupSort;
10296     lkbuttonsgcd[i++].creator = GButtonCreate;
10297 
10298     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10299     lkbuttonsgcd[i].gd.flags = gg_visible | gg_enabled ;
10300     lkbuttonsgcd[i++].creator = GLineCreate;
10301 
10302     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10303     lkbuttonsgcd[i].gd.flags = gg_visible | gg_enabled;
10304     lkbuttonsgcd[i].gd.popup_msg = _("Adds a new lookup after the selected lookup\nor at the start of the lookup list if nothing is selected.");
10305     lkbuttonslabel[i].text = (unichar_t *) _("Add _Lookup");
10306     lkbuttonslabel[i].text_is_1byte = true;
10307     lkbuttonslabel[i].text_in_resource = true;
10308     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10309     lkbuttonsgcd[i].gd.cid = CID_AddLookup;
10310     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupAddLookup;
10311     lkbuttonsgcd[i++].creator = GButtonCreate;
10312 
10313     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10314     lkbuttonsgcd[i].gd.flags = gg_visible;
10315     lkbuttonsgcd[i].gd.popup_msg = _("Adds a new lookup subtable after the selected subtable\nor at the start of the lookup if nothing is selected.");
10316     lkbuttonslabel[i].text = (unichar_t *) _("Add Sub_table");
10317     lkbuttonslabel[i].text_is_1byte = true;
10318     lkbuttonslabel[i].text_in_resource = true;
10319     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10320     lkbuttonsgcd[i].gd.cid = CID_AddSubtable;
10321     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupAddSubtable;
10322     lkbuttonsgcd[i++].creator = GButtonCreate;
10323 
10324     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10325     lkbuttonsgcd[i].gd.flags = gg_visible;
10326     lkbuttonsgcd[i].gd.popup_msg = _("Edits a lookup or lookup subtable.");
10327     lkbuttonslabel[i].text = (unichar_t *) _("Edit _Metadata");
10328     lkbuttonslabel[i].text_is_1byte = true;
10329     lkbuttonslabel[i].text_in_resource = true;
10330     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10331     lkbuttonsgcd[i].gd.cid = CID_EditMetadata;
10332     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupEditMetadata;
10333     lkbuttonsgcd[i++].creator = GButtonCreate;
10334 
10335     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10336     lkbuttonsgcd[i].gd.flags = gg_visible;
10337     lkbuttonsgcd[i].gd.popup_msg = _("Edits the transformations in a lookup subtable.");
10338     lkbuttonslabel[i].text = (unichar_t *) _("_Edit Data");
10339     lkbuttonslabel[i].text_is_1byte = true;
10340     lkbuttonslabel[i].text_in_resource = true;
10341     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10342     lkbuttonsgcd[i].gd.cid = CID_EditSubtable;
10343     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupEditSubtableContents;
10344     lkbuttonsgcd[i++].creator = GButtonCreate;
10345 
10346     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10347     lkbuttonsgcd[i].gd.flags = gg_visible;
10348     lkbuttonsgcd[i].gd.popup_msg = _("Deletes any selected lookups and their subtables, or deletes any selected subtables.\nThis will also delete any transformations associated with those subtables.");
10349     lkbuttonslabel[i].text = (unichar_t *) _("De_lete");
10350     lkbuttonslabel[i].text_is_1byte = true;
10351     lkbuttonslabel[i].text_in_resource = true;
10352     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10353     lkbuttonsgcd[i].gd.cid = CID_DeleteLookup;
10354     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupDeleteLookup;
10355     lkbuttonsgcd[i++].creator = GButtonCreate;
10356 
10357     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10358     lkbuttonsgcd[i].gd.flags = gg_visible;
10359     lkbuttonsgcd[i].gd.popup_msg = _("Merges two selected (and compatible) lookups into one,\nor merges two selected subtables of a lookup into one");
10360     lkbuttonslabel[i].text = (unichar_t *) _("_Merge");
10361     lkbuttonslabel[i].text_is_1byte = true;
10362     lkbuttonslabel[i].text_in_resource = true;
10363     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10364     lkbuttonsgcd[i].gd.cid = CID_MergeLookup;
10365     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupMergeLookup;
10366     lkbuttonsgcd[i++].creator = GButtonCreate;
10367 
10368     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10369     lkbuttonsgcd[i].gd.flags = gg_visible;
10370     lkbuttonsgcd[i].gd.popup_msg = _("Reverts the lookup list to its original condition.\nBut any changes to subtable data will remain.");
10371     lkbuttonslabel[i].text = (unichar_t *) _("_Revert");
10372     lkbuttonslabel[i].text_is_1byte = true;
10373     lkbuttonslabel[i].text_in_resource = true;
10374     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10375     lkbuttonsgcd[i].gd.cid = CID_RevertLookups;
10376     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupRevertLookup;
10377     lkbuttonsgcd[i++].creator = GButtonCreate;
10378 
10379     lkbuttonsarray[i] = &lkbuttonsgcd[i];
10380     lkbuttonsgcd[i].gd.flags = gg_visible;
10381     lkbuttonsgcd[i].gd.popup_msg = _("Imports a lookup (and all its subtables) from another font.");
10382     lkbuttonslabel[i].text = (unichar_t *) _("_Import");
10383     lkbuttonslabel[i].text_is_1byte = true;
10384     lkbuttonslabel[i].text_in_resource = true;
10385     lkbuttonsgcd[i].gd.label = &lkbuttonslabel[i];
10386     lkbuttonsgcd[i].gd.cid = CID_ImportLookups;
10387     lkbuttonsgcd[i].gd.handle_controlevent = GFI_LookupImportLookup;
10388     lkbuttonsgcd[i++].creator = GButtonCreate;
10389     lkbuttonsarray[i] = GCD_Glue;
10390     lkbuttonsarray[i+1] = NULL;
10391 
10392     for ( i=0; i<2; ++i ) {
10393 	lkaspects[i].text = (unichar_t *) (i?"GPOS":"GSUB");
10394 	lkaspects[i].text_is_1byte = true;
10395 	lkaspects[i].gcd = &lkbox[2*i];
10396 
10397 	lksubgcd[i][0].gd.pos.x = 10; lksubgcd[i][0].gd.pos.y = 10;
10398 	lksubgcd[i][0].gd.pos.width = ngcd[15].gd.pos.width;
10399 	lksubgcd[i][0].gd.pos.height = 150;
10400 	lksubgcd[i][0].gd.flags = gg_visible | gg_enabled;
10401 	lksubgcd[i][0].gd.u.drawable_e_h = i ? gposlookups_e_h : gsublookups_e_h;
10402 	lksubgcd[i][0].gd.cid = CID_LookupWin+i;
10403 	lksubgcd[i][0].creator = GDrawableCreate;
10404 
10405 	lksubgcd[i][1].gd.pos.x = 10; lksubgcd[i][1].gd.pos.y = 10;
10406 	lksubgcd[i][1].gd.pos.height = 150;
10407 	lksubgcd[i][1].gd.flags = gg_visible | gg_enabled | gg_sb_vert;
10408 	lksubgcd[i][1].gd.cid = CID_LookupVSB+i;
10409 	lksubgcd[i][1].gd.handle_controlevent = LookupsVScroll;
10410 	lksubgcd[i][1].creator = GScrollBarCreate;
10411 
10412 	lksubgcd[i][2].gd.pos.x = 10; lksubgcd[i][2].gd.pos.y = 10;
10413 	lksubgcd[i][2].gd.pos.width = 150;
10414 	lksubgcd[i][2].gd.flags = gg_visible | gg_enabled;
10415 	lksubgcd[i][2].gd.cid = CID_LookupHSB+i;
10416 	lksubgcd[i][2].gd.handle_controlevent = LookupsHScroll;
10417 	lksubgcd[i][2].creator = GScrollBarCreate;
10418 
10419 	lksubgcd[i][3].gd.pos.x = 10; lksubgcd[i][3].gd.pos.y = 10;
10420 	lksubgcd[i][3].gd.pos.width = lksubgcd[i][3].gd.pos.height = _GScrollBar_Width;
10421 	lksubgcd[i][3].gd.flags = gg_visible | gg_enabled | gg_tabset_nowindow;
10422 	lksubgcd[i][3].creator = GDrawableCreate;
10423 
10424 	lkarray[i][0] = &lksubgcd[i][0]; lkarray[i][1] = &lksubgcd[i][1]; lkarray[i][2] = NULL;
10425 	lkarray[i][3] = &lksubgcd[i][2]; lkarray[i][4] = &lksubgcd[i][3]; lkarray[i][5] = NULL;
10426 	lkarray[i][6] = NULL;
10427 
10428 	lkbox[2*i].gd.flags = gg_enabled|gg_visible;
10429 	lkbox[2*i].gd.u.boxelements = lkarray[i];
10430 	lkbox[2*i].creator = GHVBoxCreate;
10431     }
10432 
10433     lkaspects[0].selected = true;
10434 
10435     lkgcd[0].gd.pos.x = 4; lkgcd[0].gd.pos.y = 10;
10436     lkgcd[0].gd.pos.width = 250;
10437     lkgcd[0].gd.pos.height = 260;
10438     lkgcd[0].gd.u.tabs = lkaspects;
10439     lkgcd[0].gd.flags = gg_visible | gg_enabled;
10440     lkgcd[0].gd.cid = CID_Lookups;
10441     lkgcd[0].gd.handle_controlevent = GFI_LookupAspectChange;
10442     lkgcd[0].creator = GTabSetCreate;
10443 
10444     lkharray[0] = &lkgcd[0]; lkharray[1] = &lkbox[4]; lkharray[2] = NULL;
10445 
10446     lkbox[4].gd.flags = gg_enabled|gg_visible;
10447     lkbox[4].gd.u.boxelements = lkbuttonsarray;
10448     lkbox[4].creator = GVBoxCreate;
10449 
10450     lkbox[5].gd.flags = gg_enabled|gg_visible;
10451     lkbox[5].gd.u.boxelements = lkharray;
10452     lkbox[5].creator = GHBoxCreate;
10453 
10454 
10455 /******************************************************************************/
10456     memset(&mfgcd,0,sizeof(mfgcd));
10457     memset(&mflabel,'\0',sizeof(mflabel));
10458     memset(mfbox,0,sizeof(mfbox));
10459 
10460     GCDFillMacFeat(mfgcd,mflabel,250,sf->features, false, mfbox, mfarray);
10461 /******************************************************************************/
10462 
10463     memset(&dlabel,0,sizeof(dlabel));
10464     memset(&dgcd,0,sizeof(dgcd));
10465 
10466     dlabel[0].text = (unichar_t *) _("Creation Date:");
10467     dlabel[0].text_is_1byte = true;
10468     dlabel[0].text_in_resource = true;
10469     dgcd[0].gd.label = &dlabel[0];
10470     dgcd[0].gd.pos.x = 12; dgcd[0].gd.pos.y = 6+6;
10471     dgcd[0].gd.flags = gg_visible | gg_enabled;
10472     dgcd[0].creator = GLabelCreate;
10473 
10474     t = sf->creationtime;
10475     tm = localtime(&t);
10476     if(!tm) strcpy(createtime, "error");
10477     else    strftime(createtime,sizeof(createtime),"%c",tm);
10478     tmpcreatetime = def2u_copy(createtime);
10479     dgcd[1].gd.pos.x = 115; dgcd[1].gd.pos.y = dgcd[0].gd.pos.y;
10480     dgcd[1].gd.flags = gg_visible | gg_enabled;
10481     dlabel[1].text = tmpcreatetime;
10482     dgcd[1].gd.label = &dlabel[1];
10483     dgcd[1].creator = GLabelCreate;
10484 
10485     dlabel[2].text = (unichar_t *) _("Modification Date:");
10486     dlabel[2].text_is_1byte = true;
10487     dlabel[2].text_in_resource = true;
10488     dgcd[2].gd.label = &dlabel[2];
10489     dgcd[2].gd.pos.x = 12; dgcd[2].gd.pos.y = dgcd[0].gd.pos.y+14;
10490     dgcd[2].gd.flags = gg_visible | gg_enabled;
10491     dgcd[2].creator = GLabelCreate;
10492 
10493     t = sf->modificationtime;
10494     tm = localtime(&t);
10495     if(!tm) strcpy(modtime, "error");
10496     else    strftime(modtime,sizeof(modtime),"%c",tm);
10497     tmpmodtime = def2u_copy(modtime);
10498     dgcd[3].gd.pos.x = 115; dgcd[3].gd.pos.y = dgcd[2].gd.pos.y;
10499     dgcd[3].gd.flags = gg_visible | gg_enabled;
10500     dlabel[3].text = tmpmodtime;
10501     dgcd[3].gd.label = &dlabel[3];
10502     dgcd[3].creator = GLabelCreate;
10503 
10504     darray[0] = &dgcd[0]; darray[1] = &dgcd[1]; darray[2] = NULL;
10505     darray[3] = &dgcd[2]; darray[4] = &dgcd[3]; darray[5] = NULL;
10506     darray[6] = GCD_Glue; darray[7] = GCD_Glue; darray[8] = NULL;
10507     darray[9] = NULL;
10508 
10509     memset(dbox,0,sizeof(dbox));
10510     dbox[0].gd.flags = gg_enabled|gg_visible;
10511     dbox[0].gd.u.boxelements = darray;
10512     dbox[0].creator = GHVBoxCreate;
10513 /******************************************************************************/
10514 
10515     memset(&ulabel,0,sizeof(ulabel));
10516     memset(&ugcd,0,sizeof(ugcd));
10517     memset(ubox,0,sizeof(ubox));
10518 
10519     ulabel[0].text = (unichar_t *) _(
10520 	    "This pane is informative only and shows the characters\n"
10521 	    "actually in the font. If you wish to set the OS/2 Unicode\n"
10522 	    "Range field, change the pane to");
10523     ulabel[0].text_is_1byte = true;
10524     ugcd[0].gd.label = &ulabel[0];
10525     ugcd[0].gd.pos.x = 12; ugcd[0].gd.pos.y = 10;
10526     ugcd[0].gd.flags = gg_visible | gg_enabled;
10527     ugcd[0].creator = GLabelCreate;
10528 
10529     ulabel[1].text = (unichar_t *) _( "OS/2 -> Charsets");
10530     ulabel[1].text_is_1byte = true;
10531     ugcd[1].gd.label = &ulabel[1];
10532     ugcd[1].gd.pos.x = 12; ugcd[1].gd.pos.y = 10;
10533     ugcd[1].gd.flags = gg_visible | gg_enabled | gg_dontcopybox;
10534     ugcd[1].gd.box = &small_blue_box;
10535     ugcd[1].gd.handle_controlevent = GFI_URangeAspectChange;
10536     ugcd[1].creator = GButtonCreate;
10537     uharray[0] = GCD_Glue; uharray[1] = &ugcd[1]; uharray[2] = GCD_Glue; uharray[3] = NULL;
10538 
10539     ubox[2].gd.flags = gg_enabled|gg_visible;
10540     ubox[2].gd.u.boxelements = uharray;
10541     ubox[2].creator = GHBoxCreate;
10542 
10543     ulabel[2].text = (unichar_t *) _("Include Empty Blocks");
10544     ulabel[2].text_is_1byte = true;
10545     ulabel[2].text_in_resource = true;
10546     ugcd[2].gd.label = &ulabel[2];
10547     ugcd[2].gd.pos.x = 12; ugcd[2].gd.pos.y = 10;
10548     ugcd[2].gd.flags = gg_visible | gg_enabled;
10549     ugcd[2].gd.handle_controlevent = GFI_UnicodeEmptiesChange;
10550     ugcd[2].gd.cid = CID_UnicodeEmpties;
10551     ugcd[2].creator = GCheckBoxCreate;
10552 
10553     ugcd[3].gd.pos.x = 12; ugcd[3].gd.pos.y = 30;
10554     ugcd[3].gd.pos.width = ngcd[15].gd.pos.width;
10555     ugcd[3].gd.pos.height = 200;
10556     ugcd[3].gd.flags = gg_visible | gg_enabled;
10557     ugcd[3].gd.cid = CID_Unicode;
10558     ugcd[3].gd.handle_controlevent = GFI_UnicodeRangeChange;
10559     ugcd[3].gd.popup_msg = _("Click on a range to select characters in that range.\nDouble click on a range to see characters that should be\nin the range but aren't.");
10560     ugcd[3].creator = GListCreate;
10561 
10562     uarray[0] = &ugcd[0]; uarray[1] = &ubox[2]; uarray[2] = &ugcd[2]; uarray[3] = &ugcd[3]; uarray[4] = NULL;
10563 
10564     ubox[0].gd.flags = gg_enabled|gg_visible;
10565     ubox[0].gd.u.boxelements = uarray;
10566     ubox[0].creator = GVBoxCreate;
10567 
10568 /******************************************************************************/
10569 
10570     // This is where the indices for the different tabs get set as referenced by defaspect.
10571     // If you change something here, it's probably a good idea to grep for calls to FontInfo
10572     // in order to confirm/adjust the defaspect arguments.
10573 
10574     memset(&mlabel,0,sizeof(mlabel));
10575     memset(&mgcd,0,sizeof(mgcd));
10576     memset(&aspects,'\0',sizeof(aspects));
10577 
10578     i = 0;
10579 
10580     aspects[i].text = (unichar_t *) _("PS Names");
10581     d->old_aspect = 0;
10582     aspects[i].text_is_1byte = true;
10583     aspects[i++].gcd = nb;
10584 
10585     aspects[i].text = (unichar_t *) _("General");
10586     aspects[i].text_is_1byte = true;
10587     aspects[i++].gcd = psb;
10588 
10589     aspects[i].text = (unichar_t *) _("Layers");
10590     aspects[i].text_is_1byte = true;
10591     aspects[i++].gcd = lbox;
10592 
10593     aspects[i].text = (unichar_t *) _("PS UID");
10594     aspects[i].text_is_1byte = true;
10595     aspects[i++].gcd = xub;
10596 
10597     d->private_aspect = i;
10598     aspects[i].text = (unichar_t *) _("PS Private");
10599     aspects[i].text_is_1byte = true;
10600     aspects[i++].gcd = ppbox;
10601 
10602     d->ttfv_aspect = i;
10603     aspects[i].text = (unichar_t *) _("OS/2");
10604     if ( sf->cidmaster!=NULL ) aspects[i].disabled = true;
10605     aspects[i].text_is_1byte = true;
10606     aspects[i++].gcd = vagcd;
10607 
10608     d->tn_aspect = i;
10609     if ( sf->cidmaster!=NULL ) aspects[i].disabled = true;
10610     aspects[i].text = (unichar_t *) _("TTF Names");
10611     aspects[i].text_is_1byte = true;
10612     aspects[i++].gcd = tnboxes;
10613 
10614     if ( sf->cidmaster!=NULL ) aspects[i].disabled = true;
10615     aspects[i].text = (unichar_t *) _("StyleSet Names");
10616     aspects[i].text_is_1byte = true;
10617     aspects[i++].gcd = ssboxes;
10618 
10619     if ( sf->cidmaster!=NULL ) aspects[i].disabled = true;
10620     aspects[i].text = (unichar_t *) _("Grid Fitting");
10621     aspects[i].text_is_1byte = true;
10622     aspects[i++].gcd = gaspboxes;
10623 
10624     d->tx_aspect = i;
10625 /* xgettext won't use non-ASCII messages */
10626     aspects[i].text = (unichar_t *) U_("ΤεΧ");	/* Tau epsilon Chi, in greek */
10627     aspects[i].text_is_1byte = true;
10628     aspects[i++].gcd = txbox;
10629 
10630     if ( sf->cidmaster!=NULL ) aspects[i].disabled = true;
10631     aspects[i].text = (unichar_t *) _("Size");
10632     aspects[i].text_is_1byte = true;
10633     aspects[i++].gcd = szbox;
10634 
10635     aspects[i].text = (unichar_t *) _("Comment");
10636     aspects[i].text_is_1byte = true;
10637     aspects[i++].gcd = combox;
10638 
10639     aspects[i].text = (unichar_t *) _("FONTLOG");
10640     aspects[i].text_is_1byte = true;
10641     aspects[i++].gcd = flogbox;
10642 
10643     if ( sf->cidmaster!=NULL ) aspects[i].disabled = true;
10644     aspects[i].text = (unichar_t *) _("Mark Classes");
10645     aspects[i].text_is_1byte = true;
10646     aspects[i++].gcd = mkbox;
10647 
10648     if ( sf->cidmaster!=NULL ) aspects[i].disabled = true;
10649     aspects[i].text = (unichar_t *) _("Mark Sets");
10650     aspects[i].text_is_1byte = true;
10651     aspects[i++].gcd = msbox;
10652 
10653 /* GT: OpenType GPOS/GSUB lookups */
10654     if ( sf->cidmaster!=NULL ) aspects[i].disabled = true;
10655     aspects[i].text = (unichar_t *) S_("OpenType|Lookups");
10656     aspects[i].text_is_1byte = true;
10657     aspects[i++].gcd = &lkbox[5];
10658 /* On my system the "lookups line appears indented. That seems to be because */
10659 /*  the letter "L" has more of a left-side bearing than it should. It is not */
10660 /*  a bug in the nesting level. Remember this next time it bugs me */
10661 
10662     aspects[i].text = (unichar_t *) _("WOFF");
10663     aspects[i].text_is_1byte = true;
10664     aspects[i++].gcd = woffbox;
10665 
10666     aspects[i].text = (unichar_t *) _("Mac");
10667     aspects[i].text_is_1byte = true;
10668     aspects[i++].gcd = mcbox;
10669 
10670     aspects[i].text = (unichar_t *) _("Mac Features");
10671     aspects[i].text_is_1byte = true;
10672     aspects[i++].gcd = mfbox;
10673 
10674     aspects[i].text = (unichar_t *) _("Dates");
10675     aspects[i].text_is_1byte = true;
10676     aspects[i++].gcd = dbox;
10677 
10678     d->unicode_aspect = i;
10679     aspects[i].text = (unichar_t *) _("Unicode Ranges");
10680     aspects[i].text_is_1byte = true;
10681     aspects[i++].gcd = ubox;
10682 
10683     aspects[defaspect].selected = true;
10684 
10685     mgcd[0].gd.pos.x = 4; mgcd[0].gd.pos.y = 6;
10686     mgcd[0].gd.u.tabs = aspects;
10687     mgcd[0].gd.flags = gg_visible | gg_enabled | gg_tabset_vert;
10688     // We adjusted the following two values so as to make the GPOS and GSUB scrollbars visible.
10689     mgcd[0].gd.pos.width = 500; // 260+85;
10690     mgcd[0].gd.pos.height = 380; // 325;
10691     mgcd[0].gd.handle_controlevent = GFI_AspectChange;
10692     mgcd[0].gd.cid = CID_Tabs;
10693     mgcd[0].creator = GTabSetCreate;
10694 
10695     mgcd[1].gd.pos.x = 30-3; mgcd[1].gd.pos.y = GDrawPixelsToPoints(NULL,pos.height)-35-3;
10696     mgcd[1].gd.pos.width = -1; mgcd[1].gd.pos.height = 0;
10697     mgcd[1].gd.flags = gg_visible | gg_enabled | gg_but_default;
10698     mlabel[1].text = (unichar_t *) _("_OK");
10699     mlabel[1].text_is_1byte = true;
10700     mlabel[1].text_in_resource = true;
10701     mgcd[1].gd.label = &mlabel[1];
10702     mgcd[1].gd.handle_controlevent = GFI_OK;
10703     mgcd[1].gd.cid = CID_OK;
10704     mgcd[1].creator = GButtonCreate;
10705 
10706     mgcd[2].gd.pos.x = -30; mgcd[2].gd.pos.y = mgcd[1].gd.pos.y+3;
10707     mgcd[2].gd.pos.width = -1; mgcd[2].gd.pos.height = 0;
10708     mgcd[2].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
10709     mlabel[2].text = (unichar_t *) _("_Cancel");
10710     mlabel[2].text_is_1byte = true;
10711     mlabel[2].text_in_resource = true;
10712     mgcd[2].gd.label = &mlabel[2];
10713     mgcd[2].gd.handle_controlevent = GFI_Cancel;
10714     mgcd[2].gd.cid = CID_Cancel;
10715     mgcd[2].creator = GButtonCreate;
10716 
10717     mgcd[3].gd.pos.x = 2; mgcd[3].gd.pos.y = 2;
10718     mgcd[3].gd.pos.width = pos.width-4; mgcd[3].gd.pos.height = pos.height-4;
10719     mgcd[3].gd.flags = gg_enabled | gg_visible | gg_pos_in_pixels;
10720     mgcd[3].gd.cid = CID_MainGroup;
10721     mgcd[3].creator = GGroupCreate;
10722 
10723     marray2[0] = marray2[2] = marray2[3] = marray2[4] = marray2[6] = GCD_Glue; marray2[7] = NULL;
10724     marray2[1] = &mgcd[1]; marray2[5] = &mgcd[2];
10725 
10726     marray[0] = &mgcd[0]; marray[1] = NULL;
10727     marray[2] = &mb2; marray[3] = NULL;
10728     marray[4] = GCD_Glue; marray[5] = NULL;
10729     marray[6] = NULL;
10730 
10731     memset(mb,0,sizeof(mb));
10732     mb[0].gd.pos.x = mb[0].gd.pos.y = 2;
10733     mb[0].gd.flags = gg_enabled|gg_visible;
10734     mb[0].gd.u.boxelements = marray;
10735     mb[0].gd.cid = CID_TopBox;
10736     mb[0].creator = GHVGroupCreate;
10737 
10738     memset(&mb2,0,sizeof(mb2));
10739     mb2.gd.flags = gg_enabled|gg_visible;
10740     mb2.gd.u.boxelements = marray2;
10741     mb2.creator = GHBoxCreate;
10742 
10743     GGadgetsCreate(gw,mb);
10744     GMatrixEditSetNewText(tngcd[4].ret,S_("TrueTypeName|New"));
10745     GGadgetSelectOneListItem(gaspgcd[0].ret,sf->gasp_version);
10746     GMatrixEditSetNewText(gaspgcd[3].ret,S_("gaspTableEntry|New"));
10747     GMatrixEditAddButtons(gaspgcd[3].ret,gaspgcd_def);
10748     if ( sf->gasp_version==0 ) {
10749 	GMatrixEditShowColumn(gaspgcd[3].ret,3,false);
10750 	GMatrixEditShowColumn(gaspgcd[3].ret,4,false);
10751     }
10752     GHVBoxSetExpandableCol(gaspboxes[2].ret,2);
10753     GHVBoxSetExpandableRow(gaspboxes[0].ret,1);
10754 
10755     GMatrixEditAddButtons(pgcd[0].ret,privategcd_def);
10756     GMatrixEditSetUpDownVisible(pgcd[0].ret, true);
10757     GMatrixEditSetOtherButtonEnable(pgcd[0].ret, PSPrivate_EnableButtons);
10758     GMatrixEditSetNewText(pgcd[0].ret,S_("PSPrivateDictKey|New"));
10759 
10760     GHVBoxSetExpandableCol(lbox[2].ret,3);
10761     GHVBoxSetExpandableCol(lbox[3].ret,gb_expandglue);
10762     GHVBoxSetExpandableCol(lbox[4].ret,gb_expandglue);
10763     GHVBoxSetExpandableRow(lbox[0].ret,5);
10764     GMatrixEditEnableColumn(GWidgetGetControl(gw,CID_Backgrounds),1,ltype<0);
10765     GMatrixEditShowColumn(GWidgetGetControl(gw,CID_Backgrounds),3,false);
10766 	/* This column contains internal state information which the user */
10767 	/* should not see, ever */
10768 
10769     GHVBoxSetExpandableRow(combox[0].ret,1);
10770     GHVBoxSetExpandableRow(flogbox[0].ret,1);
10771 
10772     GHVBoxSetExpandableRow(mb[0].ret,0);
10773     GHVBoxSetExpandableCol(mb2.ret,gb_expandgluesame);
10774 
10775     GHVBoxSetExpandableCol(nb[0].ret,1);
10776     GHVBoxSetExpandableRow(nb[0].ret,8);
10777     GHVBoxSetExpandableCol(nb2.ret,1);
10778     GHVBoxSetExpandableCol(nb3.ret,1);
10779 
10780     GHVBoxSetExpandableCol(xub[0].ret,1);
10781     GHVBoxSetExpandableRow(xub[0].ret,5);
10782 
10783     GHVBoxSetExpandableRow(psb[0].ret,psrow);
10784     GHVBoxSetExpandableCol(psb2[0].ret,3);
10785     GHVBoxSetExpandableCol(psb2[1].ret,1);
10786 
10787     GHVBoxSetExpandableRow(vbox[0].ret,gb_expandglue);
10788     GHVBoxSetExpandableCol(vbox[0].ret,1);
10789     GHVBoxSetExpandableCol(vbox[2].ret,gb_expandglue);
10790 
10791     GHVBoxSetExpandableRow(metbox[0].ret,10);
10792     GHVBoxSetExpandableCol(metbox[0].ret,1);
10793 
10794     GHVBoxSetExpandableRow(ssbox[0].ret,gb_expandglue);
10795     GHVBoxSetExpandableCol(ssbox[0].ret,gb_expandglue);
10796 
10797     GHVBoxSetExpandableRow(panbox[0].ret,gb_expandglue);
10798     GHVBoxSetExpandableCol(panbox[0].ret,1);
10799 
10800     GHVBoxSetExpandableRow(cbox[0].ret,2);
10801     GHVBoxSetExpandableCol(cbox[2].ret,gb_expandglue);
10802     GHVBoxSetExpandableCol(cbox[3].ret,gb_expandglue);
10803     GHVBoxSetExpandableRow(cbox[4].ret,gb_expandglue);
10804 
10805     GHVBoxSetExpandableRow(woffbox[0].ret,2);
10806 
10807     GHVBoxSetExpandableRow(mkbox[0].ret,1);
10808     GMatrixEditSetBeforeDelete(mkgcd[1].ret, GFI_Mark_DeleteClass);
10809     GMatrixEditSetColumnCompletion(mkgcd[1].ret,1,GFI_GlyphListCompletion);
10810 
10811     GHVBoxSetExpandableRow(msbox[0].ret,1);
10812     GMatrixEditSetBeforeDelete(msgcd[1].ret, GFI_Mark_DeleteClass);
10813     GMatrixEditSetColumnCompletion(msgcd[1].ret,1,GFI_GlyphListCompletion);
10814 
10815     GHVBoxSetExpandableRow(txbox[0].ret,gb_expandglue);
10816     GHVBoxSetExpandableCol(txbox[2].ret,gb_expandglue);
10817     GHVBoxSetExpandableCol(txbox[3].ret,gb_expandglue);
10818     GHVBoxSetExpandableCol(txbox[4].ret,gb_expandglue);
10819 
10820     GHVBoxSetExpandableRow(szbox[0].ret,4);
10821     GHVBoxSetPadding(szbox[2].ret,6,2);
10822     GHVBoxSetExpandableCol(szbox[2].ret,gb_expandglue);
10823     GHVBoxSetPadding(szbox[3].ret,6,2);
10824     GHVBoxSetExpandableCol(szbox[3].ret,gb_expandglue);
10825     GHVBoxSetPadding(szbox[4].ret,6,2);
10826     GHVBoxSetExpandableCol(szbox[4].ret,gb_expandglue);
10827 
10828     GHVBoxSetExpandableRow(tnboxes[0].ret,1);
10829     GHVBoxSetExpandableCol(tnboxes[2].ret,gb_expandglue);
10830     GHVBoxSetExpandableCol(tnboxes[3].ret,gb_expandglue);
10831 
10832     GHVBoxSetExpandableRow(ssboxes[0].ret,1);
10833 
10834     GHVBoxSetExpandableRow(mcbox[0].ret,gb_expandglue);
10835     GHVBoxSetExpandableCol(mcbox[0].ret,1);
10836     GHVBoxSetExpandableRow(mcbox[2].ret,gb_expandglue);
10837 
10838     GHVBoxSetExpandableRow(mfbox[0].ret,0);
10839     GHVBoxSetExpandableRow(mfbox[2].ret,gb_expandglue);
10840 
10841     GHVBoxSetExpandableRow(dbox[0].ret,gb_expandglue);
10842     GHVBoxSetExpandableCol(dbox[0].ret,1);
10843 
10844     GHVBoxSetExpandableRow(ubox[0].ret,3);
10845     GHVBoxSetExpandableCol(ubox[2].ret,gb_expandglue);
10846 
10847     GHVBoxSetExpandableCol(lkbox[0].ret,0);
10848     GHVBoxSetExpandableRow(lkbox[0].ret,0);
10849     GHVBoxSetPadding(lkbox[0].ret,0,0);
10850     GHVBoxSetExpandableCol(lkbox[2].ret,0);
10851     GHVBoxSetExpandableRow(lkbox[2].ret,0);
10852     GHVBoxSetPadding(lkbox[2].ret,0,0);
10853     GHVBoxSetExpandableRow(lkbox[4].ret,gb_expandglue);
10854     GHVBoxSetExpandableCol(lkbox[5].ret,0);
10855 
10856     GFI_LookupEnableButtons(d,true);
10857     GFI_LookupEnableButtons(d,false);
10858 
10859     OS2_UnicodeChange(GWidgetGetControl(gw,CID_UnicodeRanges),NULL);
10860     OS2_CodePageChange(GWidgetGetControl(gw,CID_CodePageRanges),NULL);
10861 
10862     if ( fi_font==NULL ) {
10863 	memset(&rq,0,sizeof(rq));
10864 	rq.utf8_family_name = SANS_UI_FAMILIES;
10865 	rq.point_size = 12;
10866 	rq.weight = 400;
10867 	fi_font = GDrawInstanciateFont(gw,&rq);
10868 	fi_font = GResourceFindFont("FontInfo.Font",fi_font);
10869     }
10870     d->font = fi_font;
10871     GDrawWindowFontMetrics(gw,d->font,&as,&ds,&ld);
10872     d->as = as; d->fh = as+ds;
10873 
10874     GTextInfoListFree(namelistnames);
10875 
10876     for ( i=0; i<mi.initial_row_cnt; ++i )
10877 	free( mi.matrix_data[3*i+2].u.md_str );
10878     free( mi.matrix_data );
10879 
10880     free(tmpcreatetime);
10881     free(tmpmodtime);
10882 
10883     free(copied_copyright);
10884 
10885     GWidgetIndicateFocusGadget(ngcd[1].ret);
10886     PSPrivate_EnableButtons(GWidgetGetControl(d->gw,CID_Private),-1,-1);
10887     GFI_AspectChange(mgcd[0].ret,NULL);
10888 
10889     GHVBoxFitWindow(mb[0].ret);
10890 
10891     GWidgetHidePalettes();
10892     GDrawSetVisible(gw,true);
10893 
10894     if ( sync ) {
10895 	while ( !d->done )
10896 	    GDrawProcessOneEvent(NULL);
10897     }
10898 }
10899 
FontMenuFontInfo(void * _fv)10900 void FontMenuFontInfo(void *_fv) {
10901     FontInfo( ((FontViewBase *) _fv)->sf,((FontViewBase *) _fv)->active_layer,-1,false);
10902 }
10903 
FontInfoDestroy(SplineFont * sf)10904 void FontInfoDestroy(SplineFont *sf) {
10905     if ( sf->fontinfo )
10906 	GFI_CancelClose( (struct gfi_data *) (sf->fontinfo) );
10907 }
10908 
FontInfoInit(void)10909 void FontInfoInit(void) {
10910     static int done = false;
10911     int i, j, k;
10912     static GTextInfo *needswork[] = {
10913 	macstyles, widthclass, weightclass, fstype, pfmfamily, ibmfamily,
10914 	panfamily, panserifs, panweight, panprop, pancontrast, panstrokevar,
10915 	panarmstyle, panletterform, panmidline, panxheight,
10916 	pantool, panspacing, panasprat, pancontrast2, pantopology, panform,
10917 	panfinials, panxascent,
10918 	panclass, panaspect, panserifvar, pantreatment, panlining,
10919 	pantopology2, pancharrange, pancontrast3,
10920 	pankind, panasprat2,
10921 	mslanguages,
10922 	ttfnameids, interpretations, gridfit, antialias, os2versions,
10923 	codepagenames, unicoderangenames, symsmooth, gfsymsmooth, splineorder,
10924 	NULL
10925     };
10926     struct titlelist *tl;
10927     static char **needswork2[] = { texparams, texpopups,
10928 	mathparams, mathpopups, extparams, extpopups,
10929     NULL };
10930     static struct {
10931 	int size;
10932 	struct col_init *ci;
10933     } needswork3[] = {{ sizeof(ci)/sizeof(ci[0]), ci},
10934 			{ sizeof(gaspci)/sizeof(gaspci[0]), gaspci },
10935 			{ sizeof(layersci)/sizeof(layersci[0]), layersci },
10936 			{ sizeof(ssci)/sizeof(ssci[0]), ssci },
10937 			{ sizeof(sizeci)/sizeof(sizeci[0]), sizeci },
10938 			{ sizeof(marks_ci)/sizeof(marks_ci[0]), marks_ci },
10939 			{ sizeof(markc_ci)/sizeof(markc_ci[0]), markc_ci },
10940 			{ 0, NULL }};
10941 
10942     if ( done )
10943 return;
10944     done = true;
10945     for ( j=0; needswork[j]!=NULL; ++j ) {
10946 	for ( i=0; needswork[j][i].text!=NULL; ++i )
10947 	    needswork[j][i].text = (unichar_t *) S_((char *) needswork[j][i].text);
10948     }
10949     for ( j=0; needswork2[j]!=NULL; ++j ) {
10950 	for ( i=0; needswork2[j][i]!=NULL; ++i )
10951 	    needswork2[j][i] = S_(needswork2[j][i]);
10952     }
10953 
10954     for ( j=0; needswork3[j].ci!=NULL; ++j ) {
10955 	for ( i=0; i<needswork3[j].size; ++i ) {
10956 	    needswork3[j].ci[i].title = S_(needswork3[j].ci[i].title);
10957 	    if ( needswork3[j].ci[i].enum_vals!=NULL ) {
10958 		for ( k=0; needswork3[j].ci[i].enum_vals[k].text!=NULL; ++k )
10959 		    needswork3[j].ci[i].enum_vals[k].text = (unichar_t *) S_((char *) needswork3[j].ci[i].enum_vals[k].text);
10960 	    }
10961 	}
10962     }
10963 
10964     for ( tl=&panoses[0][0]; tl->name!=NULL; ++tl )
10965 	tl->name = S_(tl->name);
10966 
10967     LookupUIInit();
10968     LookupInit();
10969 }
10970