Line data Source code
1 : /* Copyright (C) 2000-2012 by George Williams */
2 : /*
3 : * Redistribution and use in source and binary forms, with or without
4 : * modification, are permitted provided that the following conditions are met:
5 :
6 : * Redistributions of source code must retain the above copyright notice, this
7 : * list of conditions and the following disclaimer.
8 :
9 : * Redistributions in binary form must reproduce the above copyright notice,
10 : * this list of conditions and the following disclaimer in the documentation
11 : * and/or other materials provided with the distribution.
12 :
13 : * The name of the author may not be used to endorse or promote products
14 : * derived from this software without specific prior written permission.
15 :
16 : * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 : * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 : * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 : * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 : * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 : * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 : * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 : * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 : */
27 :
28 : #include "fontforgeui.h"
29 : #include "fvfonts.h"
30 : #include <utype.h>
31 : #include <ustring.h>
32 : #include "unicoderange.h"
33 :
34 0 : static int alpha(const void *_t1, const void *_t2) {
35 0 : const GTextInfo *t1 = _t1, *t2 = _t2;
36 :
37 0 : return( strcmp((char *) (t1->text),(char *) (t2->text)));
38 : }
39 :
40 0 : static GTextInfo *AvailableRanges(SplineFont *sf,EncMap *map) {
41 0 : GTextInfo *ret = calloc(unicoderange_cnt+3,sizeof(GTextInfo));
42 : int i, cnt, ch, pos;
43 :
44 0 : for ( i=cnt=0; unicoderange[i].name!=NULL; ++i ) {
45 0 : if ( unicoderange[i].display ) {
46 0 : ch = unicoderange[i].defined==-1 ? unicoderange[i].first : unicoderange[i].defined;
47 0 : pos = SFFindSlot(sf,map,ch,NULL);
48 0 : if ( pos!=-1 ) {
49 0 : ret[cnt].text = (unichar_t *) _(unicoderange[i].name);
50 0 : ret[cnt].text_is_1byte = true;
51 0 : ret[cnt++].userdata = (void *) (intpt) pos;
52 : }
53 : }
54 : }
55 0 : qsort(ret,cnt,sizeof(GTextInfo),alpha);
56 0 : return( ret );
57 : }
58 :
59 : typedef struct gotodata {
60 : SplineFont *sf;
61 : EncMap *map;
62 : GWindow gw;
63 : int ret, done;
64 : GTextInfo *ranges;
65 : } GotoData;
66 :
67 : #define CID_Name 1000
68 : #define CID_MergeWithSelection 1001
69 :
70 0 : static int Goto_Cancel(GGadget *g, GEvent *e) {
71 : GWindow gw;
72 : GotoData *d;
73 :
74 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
75 0 : gw = GGadgetGetWindow(g);
76 0 : d = GDrawGetUserData(gw);
77 0 : d->done = true;
78 : }
79 0 : return( true );
80 : }
81 :
82 0 : static int Goto_OK(GGadget *g, GEvent *e) {
83 : GWindow gw;
84 : GotoData *d;
85 : char *ret;
86 : int i;
87 :
88 0 : if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
89 0 : gw = GGadgetGetWindow(g);
90 0 : d = GDrawGetUserData(gw);
91 0 : ret = GGadgetGetTitle8(GWidgetGetControl(gw,CID_Name));
92 0 : if ( d->ranges!=NULL ) {
93 0 : for ( i=0; d->ranges[i].text!=NULL; ++i ) {
94 0 : if ( strcmp(ret,(char *) d->ranges[i].text)==0 ) {
95 0 : d->ret = (intpt) d->ranges[i].userdata;
96 0 : break;
97 : }
98 : }
99 : }
100 0 : if ( d->ret==-1 ) {
101 0 : d->ret = NameToEncoding(d->sf,d->map,ret);
102 0 : if ( d->ret<0 || (d->ret>=d->map->enccount && d->sf->cidmaster==NULL ))
103 0 : d->ret = -1;
104 0 : if ( d->ret==-1 ) {
105 0 : ff_post_notice(_("Goto"),_("Could not find the glyph: %.70s"),ret);
106 : } else
107 0 : d->done = true;
108 : } else
109 0 : d->done = true;
110 0 : free(ret);
111 : }
112 0 : return( true );
113 : }
114 :
115 0 : static int goto_e_h(GWindow gw, GEvent *event) {
116 0 : if ( event->type==et_close ) {
117 0 : GotoData *d = GDrawGetUserData(gw);
118 0 : d->done = true;
119 0 : } else if ( event->type == et_char ) {
120 0 : return( false );
121 : }
122 0 : return( true );
123 : }
124 :
125 0 : static unichar_t **GotoCompletion(GGadget *t,int from_tab) {
126 : unichar_t *pt, *spt; unichar_t **ret;
127 : int gid, cnt, doit, match_len;
128 : SplineChar *sc;
129 0 : GotoData *d = GDrawGetUserData(GGadgetGetWindow(t));
130 0 : SplineFont *sf = d->sf;
131 : int do_wildcards;
132 :
133 0 : pt = spt = (unichar_t *) _GGadgetGetTitle(t);
134 0 : if ( pt==NULL )
135 0 : return( NULL );
136 0 : while ( *pt && *pt!='*' && *pt!='?' && *pt!='[' && *pt!='{' )
137 0 : ++pt;
138 0 : do_wildcards = *pt!='\0';
139 0 : if ( do_wildcards && !from_tab )
140 0 : return( NULL );
141 0 : if ( do_wildcards ) {
142 0 : pt = spt;
143 0 : spt = malloc((u_strlen(spt)+2)*sizeof(unichar_t));
144 0 : u_strcpy(spt,pt);
145 0 : uc_strcat(spt,"*");
146 : }
147 :
148 0 : match_len = u_strlen(spt);
149 0 : ret = NULL;
150 0 : for ( doit=0; doit<2; ++doit ) {
151 0 : cnt=0;
152 0 : for ( gid=0; gid<sf->glyphcnt; ++gid ) if ( (sc=sf->glyphs[gid])!=NULL ) {
153 : int matched;
154 0 : if ( do_wildcards ) {
155 0 : unichar_t *temp = utf82u_copy(sc->name);
156 0 : matched = GGadgetWildMatch((unichar_t *) spt,temp,false);
157 0 : free(temp);
158 : } else
159 0 : matched = uc_strncmp(spt,sc->name,match_len)==0;
160 0 : if ( matched ) {
161 0 : if ( doit )
162 0 : ret[cnt] = utf82u_copy(sc->name);
163 0 : ++cnt;
164 : }
165 : }
166 0 : if ( doit )
167 0 : ret[cnt] = NULL;
168 0 : else if ( cnt==0 )
169 0 : break;
170 : else
171 0 : ret = malloc((cnt+1)*sizeof(unichar_t *));
172 : }
173 0 : if ( do_wildcards )
174 0 : free(spt);
175 0 : return( ret );
176 : }
177 :
178 0 : int GotoChar(SplineFont *sf,EncMap *map,int *merge_with_selection) {
179 : GRect pos;
180 : GWindow gw;
181 : GWindowAttrs wattrs;
182 : GGadgetCreateData gcd[9], boxes[3], *hvarray[6][2], *barray[10];
183 : GTextInfo label[9];
184 : static GotoData gd;
185 0 : GTextInfo *ranges = NULL;
186 : int k,j;
187 :
188 0 : if ( !map->enc->only_1byte )
189 0 : ranges = AvailableRanges(sf,map);
190 0 : memset(&gd,0,sizeof(gd));
191 0 : gd.sf = sf;
192 0 : gd.map = map;
193 0 : gd.ret = -1;
194 0 : gd.ranges = ranges;
195 :
196 0 : memset(&wattrs,0,sizeof(wattrs));
197 0 : wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
198 0 : wattrs.event_masks = ~(1<<et_charup);
199 0 : wattrs.restrict_input_to_me = 1;
200 0 : wattrs.undercursor = 1;
201 0 : wattrs.cursor = ct_pointer;
202 0 : wattrs.utf8_window_title = _("Goto");
203 0 : wattrs.is_dlg = true;
204 0 : pos.x = pos.y = 0;
205 0 : pos.width = GGadgetScale(GDrawPointsToPixels(NULL,170));
206 0 : pos.height = GDrawPointsToPixels(NULL,90);
207 0 : gd.gw = gw = GDrawCreateTopWindow(NULL,&pos,goto_e_h,&gd,&wattrs);
208 :
209 0 : memset(&label,0,sizeof(label));
210 0 : memset(&gcd,0,sizeof(gcd));
211 0 : memset(&boxes,0,sizeof(boxes));
212 :
213 0 : k=j=0;
214 0 : label[k].text = (unichar_t *) _("Enter the name of a glyph in the font");
215 0 : label[k].text_is_1byte = true;
216 0 : gcd[k].gd.label = &label[k];
217 0 : gcd[k].gd.flags = gg_enabled|gg_visible;
218 0 : gcd[k].creator = GLabelCreate;
219 0 : hvarray[j][0] = &gcd[k++]; hvarray[j++][1] = NULL;
220 :
221 0 : gcd[k].gd.flags = gg_enabled|gg_visible|gg_text_xim;
222 0 : gcd[k].gd.cid = CID_Name;
223 0 : if ( ranges==NULL )
224 0 : gcd[k].creator = GTextCompletionCreate;
225 : else {
226 0 : gcd[k].gd.u.list = ranges;
227 0 : gcd[k].creator = GListFieldCreate;
228 : }
229 0 : hvarray[j][0] = &gcd[k++]; hvarray[j++][1] = NULL;
230 :
231 0 : if ( merge_with_selection!=NULL ) {
232 0 : label[k].text = (unichar_t *) _("Merge into selection");
233 0 : label[k].text_is_1byte = true;
234 0 : gcd[k].gd.label = &label[k];
235 0 : gcd[k].gd.cid = CID_MergeWithSelection;
236 0 : gcd[k].gd.flags = *merge_with_selection ?
237 : gg_enabled|gg_visible|gg_cb_on :
238 : gg_enabled|gg_visible;
239 0 : gcd[k].creator = GCheckBoxCreate;
240 0 : hvarray[j][0] = &gcd[k++]; hvarray[j++][1] = NULL;
241 : }
242 0 : hvarray[j][0] = GCD_Glue; hvarray[j++][1] = NULL;
243 :
244 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_default;
245 0 : label[k].text = (unichar_t *) _("_OK");
246 0 : label[k].text_is_1byte = true;
247 0 : label[k].text_in_resource = true;
248 0 : gcd[k].gd.label = &label[k];
249 0 : gcd[k].gd.handle_controlevent = Goto_OK;
250 0 : gcd[k].creator = GButtonCreate;
251 0 : barray[0] = GCD_Glue; barray[1] = &gcd[k++]; barray[2] = GCD_Glue; barray[3] = GCD_Glue;
252 :
253 0 : gcd[k].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
254 0 : label[k].text = (unichar_t *) _("_Cancel");
255 0 : label[k].text_is_1byte = true;
256 0 : label[k].text_in_resource = true;
257 0 : gcd[k].gd.label = &label[k];
258 0 : gcd[k].gd.handle_controlevent = Goto_Cancel;
259 0 : gcd[k].creator = GButtonCreate;
260 0 : barray[4] = GCD_Glue; barray[5] = &gcd[k++]; barray[6] = GCD_Glue; barray[7] = NULL;
261 :
262 0 : boxes[2].gd.flags = gg_visible | gg_enabled;
263 0 : boxes[2].gd.u.boxelements = barray;
264 0 : boxes[2].creator = GHBoxCreate;
265 0 : hvarray[j][0] = &boxes[2]; hvarray[j++][1] = NULL;
266 0 : hvarray[j][0] = NULL;
267 :
268 0 : boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
269 0 : boxes[0].gd.flags = gg_visible | gg_enabled;
270 0 : boxes[0].gd.u.boxelements = hvarray[0];
271 0 : boxes[0].creator = GHVGroupCreate;
272 :
273 0 : GGadgetsCreate(gw,boxes);
274 0 : GCompletionFieldSetCompletion(gcd[1].ret,GotoCompletion);
275 0 : GCompletionFieldSetCompletionMode(gcd[1].ret,true);
276 0 : GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
277 0 : GHVBoxSetExpandableCol(boxes[2].ret,gb_expandgluesame);
278 0 : GHVBoxFitWindow(boxes[0].ret);
279 0 : GDrawSetVisible(gw,true);
280 0 : while ( !gd.done )
281 0 : GDrawProcessOneEvent(NULL);
282 0 : if ( merge_with_selection!=NULL )
283 0 : *merge_with_selection = GGadgetIsChecked(GWidgetGetControl(gw,CID_MergeWithSelection));
284 0 : GDrawDestroyWindow(gw);
285 0 : free(ranges);
286 0 : return( gd.ret );
287 : }
|