Line data Source code
1 : /******************************************************************************
2 : *******************************************************************************
3 : *******************************************************************************
4 :
5 : Copyright (C) 2013 Ben Martin
6 : Copyright 2014-2015, the FontForge Project Developers.
7 :
8 : This file is part of FontForge.
9 :
10 : FontForge is free software: you can redistribute it and/or modify
11 : it under the terms of the GNU General Public License as published by
12 : the Free Software Foundation,either version 3 of the License, or
13 : (at your option) any later version.
14 :
15 : FontForge is distributed in the hope that it will be useful,
16 : but WITHOUT ANY WARRANTY; without even the implied warranty of
17 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 : GNU General Public License for more details.
19 :
20 : You should have received a copy of the GNU General Public License
21 : along with FontForge. If not, see <http://www.gnu.org/licenses/>.
22 :
23 : For more details see the COPYING.gplv3 file in the root directory of this
24 : distribution.
25 :
26 : *******************************************************************************
27 : *******************************************************************************
28 : ******************************************************************************/
29 : #include <fontforge-config.h>
30 :
31 : #include "fvfonts.h"
32 :
33 : #include <string.h>
34 : #include <ctype.h>
35 :
36 : #include "inc/ustring.h"
37 : #include "inc/ggadget.h"
38 : #include "inc/gwidget.h"
39 : #include "uiinterface.h"
40 : #include "wordlistparser.h"
41 :
42 :
43 0 : static void dump_ustr( char* msg, unichar_t* u )
44 : {
45 : char u8buf[1001];
46 0 : char* pt = u8buf;
47 0 : memset( u8buf, 0, 1000 );
48 0 : printf("%s\n", msg );
49 0 : unichar_t* p = u;
50 0 : unichar_t* e = u + u_strlen( u );
51 0 : for( ; p!=e; ++p )
52 : {
53 : unichar_t buf[5];
54 0 : buf[0] = *p;
55 0 : buf[1] = '\0';
56 0 : printf("walk %d %s\n", *p, u_to_c(buf));
57 :
58 0 : pt = utf8_idpb( pt, *p, 0);
59 : }
60 0 : printf("%s u8str:%s\n", msg, u8buf );
61 0 : }
62 :
63 :
64 0 : const char* Wordlist_getSCName( SplineChar* sc )
65 : {
66 : /* printf("Wordlist_getSCName() sc->name:%s\n", sc->name ); */
67 : /* printf("Wordlist_getSCName() sc->len :%zd\n", strlen(sc->name) ); */
68 : /* printf("Wordlist_getSCName() is three:%d\n", strcmp( sc->name, "three" ) ); */
69 :
70 : static char ret[ 1024 ];
71 0 : int simple = false;
72 : /* If the glyph is unencoded, we need to keep a slash before the name because
73 : it doesn't correspond to the codepoint. */
74 0 : if( sc->unicodeenc != -1 ) {
75 0 : if( strlen( sc->name ) == 1 )
76 : {
77 0 : char ch = sc->name[0];
78 :
79 0 : if( ch >= 'a' && ch <= 'z' )
80 0 : simple = true;
81 0 : else if( ch >= '0' && ch <= '9' )
82 0 : simple = true;
83 0 : if( ch >= 'A' && ch <= 'Z' )
84 0 : simple = true;
85 :
86 0 : if( simple )
87 : {
88 0 : strcpy( ret, sc->name );
89 0 : return ret;
90 : }
91 : }
92 :
93 0 : if( !strcmp( sc->name, "zero" ))
94 0 : return "0";
95 0 : if( !strcmp( sc->name, "one" ))
96 0 : return "1";
97 0 : if( !strcmp( sc->name, "two" ))
98 0 : return "2";
99 0 : if( !strcmp( sc->name, "three" ))
100 0 : return "3";
101 0 : if( !strcmp( sc->name, "four" ))
102 0 : return "4";
103 0 : if( !strcmp( sc->name, "five" ))
104 0 : return "5";
105 0 : if( !strcmp( sc->name, "six" ))
106 0 : return "6";
107 0 : if( !strcmp( sc->name, "seven" ))
108 0 : return "7";
109 0 : if( !strcmp( sc->name, "eight" ))
110 0 : return "8";
111 0 : if( !strcmp( sc->name, "nine" ))
112 0 : return "9";
113 : }
114 :
115 0 : snprintf( ret, 1024, "/%s", sc->name );
116 0 : return ret;
117 : }
118 :
119 :
120 :
121 : static SplineChar*
122 0 : WordlistEscapedInputStringToRealString_readGlyphName(
123 : SplineFont *sf, char* in, char* in_end,
124 : char** updated_in, char* glyphname )
125 : {
126 : // printf("WordlistEscapedInputStringToRealString_readGlyphName(top)\n");
127 :
128 0 : int startedWithBackSlash = (*in == '\\');
129 0 : if( *in != '/' && *in != '\\' )
130 0 : return 0;
131 : // move over the delimiter that we know we are on
132 0 : in++;
133 0 : char* startpos = in;
134 :
135 : // Get the largest possible 'glyphname' from the input stream.
136 0 : memset( glyphname, '\0', PATH_MAX );
137 0 : char* outname = glyphname;
138 0 : while( *in != '/' && *in != ' ' && *in != ']' && in != in_end )
139 : {
140 0 : *outname = *in;
141 0 : ++outname;
142 0 : in++;
143 : }
144 0 : bool FullMatchEndsOnSpace = 0;
145 0 : char* maxpos = in;
146 0 : char* endpos = maxpos-1;
147 : // printf("WordlistEscapedInputStringToRealString_readGlyphName(x1) -->:%s:<--\n", glyphname);
148 : // printf("WordlistEscapedInputStringToRealString_readGlyphName(x2) %c %p %p\n",*in,startpos,endpos);
149 :
150 0 : int loopCounter = 0;
151 0 : int firstLookup = 1;
152 0 : for( ; endpos >= startpos; endpos--, loopCounter++ )
153 : {
154 : // printf("WordlistEscapedInputStringToRealString_readGlyphName(trim loop top) gn:%s\n", glyphname );
155 0 : SplineChar* sc = 0;
156 0 : if( startedWithBackSlash )
157 : {
158 0 : if( glyphname[0] == 'u' )
159 0 : glyphname++;
160 :
161 0 : char* endptr = 0;
162 0 : long unicodepoint = strtoul( glyphname+1, &endptr, 16 );
163 : TRACE("AAA glyphname:%s\n", glyphname+1 );
164 : TRACE("AAA unicodepoint:%ld\n", unicodepoint );
165 0 : sc = SFGetChar( sf, unicodepoint, 0 );
166 0 : if( sc && endptr )
167 : {
168 0 : char* endofglyphname = glyphname + strlen(glyphname);
169 0 : for( ; endptr < endofglyphname; endptr++ )
170 0 : --endpos;
171 : }
172 0 : if( !sc )
173 : {
174 0 : printf("WordlistEscapedInputStringToRealString_readGlyphName() no char found for backslashed unicodepoint:%ld\n", unicodepoint );
175 0 : strcpy(glyphname,"backslash");
176 0 : sc = SFGetChar( sf, -1, glyphname );
177 0 : endpos = startpos;
178 : }
179 : }
180 : else
181 : {
182 0 : if( firstLookup && glyphname[0] == '#' )
183 : {
184 0 : char* endptr = 0;
185 0 : long unicodepoint = strtoul( glyphname+1, &endptr, 16 );
186 : // printf("WordlistEscapedInputStringToRealString_readGlyphName() unicodepoint:%ld\n", unicodepoint );
187 0 : sc = SFGetChar( sf, unicodepoint, 0 );
188 0 : if( sc && endptr )
189 : {
190 0 : char* endofglyphname = glyphname + strlen(glyphname);
191 : // printf("endptr:%p endofglyphname:%p\n", endptr, endofglyphname );
192 0 : for( ; endptr < endofglyphname; endptr++ )
193 0 : --endpos;
194 : }
195 : }
196 0 : if( !sc )
197 : {
198 : // printf("WordlistEscapedInputStringToRealString_readGlyphName(getchar) gn:%s\n", glyphname );
199 0 : sc = SFGetChar( sf, -1, glyphname );
200 : }
201 : }
202 :
203 0 : if( sc )
204 : {
205 : // printf("WordlistEscapedInputStringToRealString_readGlyphName(found!) gn:%s start:%p end:%p\n", glyphname, startpos, endpos );
206 0 : if( !loopCounter && FullMatchEndsOnSpace )
207 : {
208 0 : endpos++;
209 : }
210 0 : *updated_in = endpos;
211 0 : return sc;
212 : }
213 0 : if( glyphname[0] != '\0' )
214 0 : glyphname[ strlen(glyphname)-1 ] = '\0';
215 : }
216 :
217 :
218 0 : *updated_in = endpos;
219 :
220 : // printf("WordlistEscapedInputStringToRealString_readGlyphName(end) gn:%s\n", glyphname );
221 0 : return 0;
222 : }
223 :
224 :
225 : static SplineChar*
226 0 : u_WordlistEscapedInputStringToRealString_readGlyphName(
227 : SplineFont *sf, unichar_t* in, unichar_t* in_end,
228 : unichar_t** updated_in, unichar_t* glyphname )
229 : {
230 0 : int startedWithBackSlash = (*in == '\\');
231 0 : if( *in != '/' && *in != '\\' )
232 0 : return 0;
233 0 : bool startsWithBackSlash = *in == '\\';
234 : // move over the delimiter that we know we are on
235 0 : in++;
236 0 : unichar_t* startpos = in;
237 :
238 : // Get the largest possible 'glyphname' from the input stream.
239 0 : memset( glyphname, '\0', PATH_MAX );
240 0 : unichar_t* outname = glyphname;
241 0 : while( *in != '/'
242 0 : && ( !startsWithBackSlash || *in != '\\' )
243 0 : && *in != ' ' && *in != ']' && in != in_end )
244 : {
245 0 : *outname = *in;
246 0 : ++outname;
247 0 : in++;
248 : }
249 0 : bool FullMatchEndsOnSpace = 0;
250 0 : unichar_t* maxpos = in;
251 0 : unichar_t* endpos = maxpos-1;
252 : TRACE("WordlistEscapedInputStringToRealString_readGlyphName(x1) -->:%s:<--\n", u_to_c(glyphname));
253 :
254 0 : int loopCounter = 0;
255 0 : int firstLookup = 1;
256 0 : for( ; endpos >= startpos; endpos--, loopCounter++ )
257 : {
258 : // printf("WordlistEscapedInputStringToRealString_readGlyphName(trim loop top) gn:%s\n", u_to_c(glyphname) );
259 0 : SplineChar* sc = 0;
260 :
261 0 : if( startedWithBackSlash )
262 : {
263 0 : if( glyphname[0] == 'u' )
264 0 : glyphname++;
265 :
266 0 : unichar_t* endptr = 0;
267 0 : long unicodepoint = u_strtoul( glyphname+1, &endptr, 16 );
268 : TRACE("AAA glyphname:%s\n", u_to_c(glyphname+1) );
269 : TRACE("AAA unicodepoint:%ld\n", unicodepoint );
270 0 : sc = SFGetChar( sf, unicodepoint, 0 );
271 0 : if( sc && endptr )
272 : {
273 0 : unichar_t* endofglyphname = glyphname + u_strlen(glyphname);
274 : /* printf("glyphname:%p\n", glyphname ); */
275 : /* printf("endptr:%p endofglyphname:%p\n", endptr, endofglyphname ); */
276 0 : for( ; endptr < endofglyphname; endptr++ )
277 0 : --endpos;
278 : }
279 0 : if( !sc )
280 : {
281 0 : printf("WordlistEscapedInputStringToRealString_readGlyphName() no char found for backslashed unicodepoint:%ld\n", unicodepoint );
282 0 : uc_strcpy(glyphname,"backslash");
283 0 : sc = SFGetChar( sf, -1, u_to_c(glyphname) );
284 0 : endpos = startpos;
285 : }
286 : }
287 : else
288 : {
289 0 : if( uc_startswith( glyphname, "uni"))
290 : {
291 0 : unichar_t* endptr = 0;
292 0 : long unicodepoint = u_strtoul( glyphname+3, &endptr, 16 );
293 0 : SplineChar* tmp = 0;
294 : TRACE("uni prefix, codepoint: %ld\n", unicodepoint );
295 0 : sc = SFGetChar( sf, unicodepoint, 0 );
296 0 : if (tmp = SFGetChar( sf, -1, u_to_c(glyphname) )) {
297 : TRACE("have subst. char: %s\n", tmp->name );
298 0 : sc = tmp;
299 : } else {
300 0 : if( sc && endptr )
301 : {
302 0 : unichar_t* endofglyphname = glyphname + u_strlen(glyphname);
303 : // printf("endptr:%p endofglyphname:%p\n", endptr, endofglyphname );
304 0 : for( ; endptr < endofglyphname; endptr++ )
305 0 : --endpos;
306 : }
307 : }
308 : }
309 :
310 0 : if( firstLookup && glyphname[0] == '#' )
311 : {
312 0 : unichar_t* endptr = 0;
313 0 : long unicodepoint = u_strtoul( glyphname+1, &endptr, 16 );
314 : // printf("WordlistEscapedInputStringToRealString_readGlyphName() unicodepoint:%ld\n", unicodepoint );
315 0 : sc = SFGetChar( sf, unicodepoint, 0 );
316 0 : if( sc && endptr )
317 : {
318 0 : unichar_t* endofglyphname = glyphname + u_strlen(glyphname);
319 : // printf("endptr:%p endofglyphname:%p\n", endptr, endofglyphname );
320 0 : for( ; endptr < endofglyphname; endptr++ )
321 0 : --endpos;
322 : }
323 : }
324 0 : if( !sc )
325 : {
326 : // printf("WordlistEscapedInputStringToRealString_readGlyphName(getchar) gn:%s\n", glyphname );
327 0 : sc = SFGetChar( sf, -1, u_to_c(glyphname) );
328 : }
329 : }
330 :
331 0 : if( sc )
332 : {
333 : // printf("WordlistEscapedInputStringToRealString_readGlyphName(found!) gn:%s start:%p end:%p\n", glyphname, startpos, endpos );
334 0 : if( !loopCounter && FullMatchEndsOnSpace )
335 : {
336 0 : endpos++;
337 : }
338 0 : *updated_in = endpos;
339 0 : return sc;
340 : }
341 0 : if( glyphname[0] != '\0' )
342 0 : glyphname[ u_strlen(glyphname)-1 ] = '\0';
343 : }
344 :
345 :
346 0 : *updated_in = endpos;
347 :
348 : // printf("WordlistEscapedInputStringToRealString_readGlyphName(end) gn:%s\n", glyphname );
349 0 : return 0;
350 : }
351 :
352 :
353 0 : int WordlistEscapedInputStringToRealString_getFakeUnicodeAsScUnicodeEnc( SplineChar *sc, void* udata )
354 : {
355 0 : return( sc->unicodeenc );
356 : }
357 :
358 :
359 : //
360 : // If there is only one trailing slash, then remove it.
361 : //
362 0 : void WordlistTrimTrailingSingleSlash( unichar_t* txt )
363 : {
364 0 : int len = u_strlen(txt);
365 : // printf("text changed, len :%d -1:%c -2:%c\n", len, txt[ len-1 ], txt[ len-2 ] );
366 0 : if( len >= 1 )
367 : {
368 0 : if( len >= 2 && txt[ len-1 ]=='/' && txt[ len-2 ]=='/' )
369 : {
370 : // nothing
371 : }
372 : else
373 : {
374 0 : if( txt[ len-1 ]=='/' )
375 0 : txt[ len-1 ] = '\0';
376 : }
377 : }
378 0 : }
379 :
380 :
381 :
382 : /************************************************************/
383 : /************************************************************/
384 : /************************************************************/
385 :
386 : static int WordListLineSz = 1024;
387 :
388 0 : int WordListLine_countSelected( WordListLine wll )
389 : {
390 0 : int ret = 0;
391 0 : for( ; wll->sc; wll++ ) {
392 0 : ret += wll->isSelected;
393 : }
394 0 : return ret;
395 : }
396 :
397 0 : WordListLine WordListLine_end( WordListLine wll )
398 : {
399 0 : for( ; wll->sc; wll++ ) {
400 : }
401 0 : return wll;
402 : }
403 :
404 0 : int WordListLine_size( WordListLine wll )
405 : {
406 0 : int ret = 0;
407 0 : for( ; wll->sc; wll++ ) {
408 0 : ++ret;
409 : }
410 0 : return ret;
411 : }
412 :
413 :
414 0 : WordListLine WordlistEscapedInputStringToParsedDataComplex(
415 : SplineFont* sf,
416 : const unichar_t* input_const,
417 : WordlistEscapedInputStringToRealString_getFakeUnicodeOfScFunc getUnicodeFunc,
418 : void* udata )
419 : {
420 0 : unichar_t* input = u_copy( input_const );
421 0 : WordListChar* ret = calloc( WordListLineSz, sizeof(WordListChar));
422 0 : WordListChar* out = ret;
423 0 : unichar_t* in = input;
424 0 : unichar_t* in_end = input + u_strlen(input);
425 : // trim comment and beyond from input
426 : {
427 0 : unichar_t* p = input;
428 0 : while( p && p < in_end )
429 : {
430 0 : p = u_strchr( p, '#' );
431 0 : if( p > input && *(p-1) == '/' )
432 : {
433 0 : p++;
434 0 : continue;
435 : }
436 0 : if( p )
437 0 : *p = '\0';
438 0 : break;
439 : }
440 : }
441 0 : in_end = input + u_strlen(input);
442 :
443 0 : int addingGlyphsToSelected = 0;
444 0 : int currentGlyphIndex = -1;
445 0 : for ( ; in < in_end; in++ )
446 : {
447 0 : unichar_t ch = *in;
448 : TRACE("in:%p end:%p got char %d %c\n", in, in_end, ch, ch );
449 0 : if( ch == '[' )
450 : {
451 0 : addingGlyphsToSelected = 1;
452 0 : continue;
453 : }
454 0 : if( ch == ']' )
455 : {
456 0 : addingGlyphsToSelected = 0;
457 0 : continue;
458 : }
459 0 : int isSelected = addingGlyphsToSelected;
460 0 : currentGlyphIndex++;
461 :
462 0 : if( ch == '/' || ch == '\\' )
463 : {
464 : // start of a glyph name
465 : unichar_t glyphname[ PATH_MAX+1 ];
466 0 : unichar_t* updated_in = 0;
467 0 : SplineChar* sc = u_WordlistEscapedInputStringToRealString_readGlyphName( sf, in, in_end, &updated_in, glyphname );
468 0 : if( sc )
469 : {
470 0 : in = updated_in;
471 0 : int n = getUnicodeFunc( sc, udata );
472 0 : if( n == -1 )
473 : {
474 : /*
475 : * Okay, this probably means we've got an unencoded glyph (generally
476 : * used for OpenType substitutions).
477 : * Redeem the value from the SplineFont datamap instead of fetching from
478 : * the Unicode identifier.
479 : */
480 0 : n = sf->map->backmap[sc->orig_pos];
481 :
482 : /*
483 : * Unencoded glyphs have special mappings in the SplineFont that
484 : * start from 65536 (values beyond Unicode, 65535 being the reserved
485 : * "frontier" value).
486 : */
487 0 : if ( (sf->map->enc->is_unicodebmp || sf->map->enc->is_unicodefull) && n < 65536 ) {
488 : TRACE("ToRealString: backmapped position does not match Unicode encoding\n");
489 : TRACE("orig_pos: %d, backmap: %d, attached unicode enc: %d\n", sc->orig_pos, n, sc->unicodeenc );
490 : TRACE("ToRealString: INVALID CHAR POSITION, name: %s\n", sc->name );
491 : }
492 : }
493 :
494 0 : out->sc = sc;
495 0 : out->isSelected = isSelected;
496 0 : out->currentGlyphIndex = currentGlyphIndex;
497 0 : out->n = n;
498 0 : out++;
499 : /* out = utf8_idpb( out, n, 0 ); */
500 : /* if( !out ) */
501 : /* printf("ToRealString error on out\n"); */
502 0 : continue;
503 : }
504 : }
505 :
506 : /* If we reach this point, we're looking based on codepoint. */
507 0 : SplineChar* sc = SFGetOrMakeChar( sf, (int)ch, 0 );
508 0 : out->sc = sc;
509 0 : out->isSelected = isSelected;
510 0 : out->currentGlyphIndex = currentGlyphIndex;
511 0 : out++;
512 : }
513 :
514 0 : free(input);
515 0 : return(ret);
516 : }
517 :
518 0 : WordListLine WordlistEscapedInputStringToParsedData(
519 : SplineFont* sf,
520 : unichar_t* input_const )
521 : {
522 0 : WordListLine ret = WordlistEscapedInputStringToParsedDataComplex(
523 : sf, input_const,
524 : WordlistEscapedInputStringToRealString_getFakeUnicodeAsScUnicodeEnc, 0 );
525 0 : return ret;
526 : }
527 :
528 :
529 :
530 :
531 : /************************************************************/
532 : /************************************************************/
533 : /************************************************************/
534 :
535 0 : static bool WordlistLoadFileToGTextInfo_IsLineBreak( char ch )
536 : {
537 0 : return ch == '\n' || ch == '\r';
538 : }
539 0 : static bool WordlistLoadFileToGTextInfo_isLineAllWhiteSpace( char* buffer )
540 : {
541 0 : char* p = buffer;
542 0 : for( ; *p; ++p )
543 : {
544 0 : if( !isspace( *p ))
545 0 : return false;
546 : }
547 :
548 0 : return true;
549 : }
550 :
551 :
552 :
553 0 : GTextInfo** WordlistLoadFileToGTextInfoBasic( int words_max )
554 : {
555 0 : return WordlistLoadFileToGTextInfo( -1, words_max );
556 : }
557 :
558 :
559 0 : GTextInfo** WordlistLoadFileToGTextInfo( int type, int words_max )
560 : {
561 0 : GTextInfo **words = 0;
562 : int cnt;
563 : char buffer[PATH_MAX];
564 : char *filename, *temp;
565 :
566 0 : filename = gwwv_open_filename(type==-1 ? "File of Kerning Words":"File of glyphname lists",NULL,"*.txt",NULL);
567 0 : if ( !filename )
568 : {
569 0 : return 0;
570 : }
571 0 : temp = utf82def_copy(filename);
572 0 : GIOChannel* file = g_io_channel_new_file( temp, "r", 0 );
573 0 : free(temp);
574 0 : if ( !file )
575 : {
576 0 : ff_post_error("Could not open", "Could not open %s", filename );
577 0 : return 0;
578 : }
579 0 : free(filename);
580 :
581 0 : words = malloc( words_max * sizeof(GTextInfo *));
582 :
583 0 : cnt = 0;
584 0 : if ( type==-1 )
585 : {
586 : // Kerning words
587 : while( true )
588 : {
589 0 : gsize len = 0;
590 0 : gchar* buffer = 0;
591 0 : GIOStatus status = g_io_channel_read_line( file, &buffer, &len, 0, 0 );
592 :
593 : // printf("getline status:%d \n", status );
594 0 : if( status != G_IO_STATUS_NORMAL )
595 0 : break;
596 :
597 0 : chomp(buffer);
598 0 : if ( buffer[0]=='\0'
599 0 : || WordlistLoadFileToGTextInfo_IsLineBreak(buffer[0])
600 0 : || WordlistLoadFileToGTextInfo_isLineAllWhiteSpace( buffer ))
601 : {
602 0 : free(buffer);
603 0 : continue;
604 : }
605 :
606 0 : words[cnt] = calloc(1,sizeof(GTextInfo));
607 0 : words[cnt]->fg = words[cnt]->bg = COLOR_DEFAULT;
608 0 : words[cnt]->text = (unichar_t *) utf82def_copy( buffer );
609 0 : words[cnt++]->text_is_1byte = true;
610 0 : free(buffer);
611 0 : if( cnt >= words_max )
612 0 : break;
613 0 : }
614 : }
615 : else
616 : {
617 : // glyphname lists
618 0 : strcpy(buffer,""); /* Zero width space: 0x200b, I use as a flag */
619 0 : gsize bytes_read = 0;
620 0 : while( G_IO_STATUS_NORMAL == g_io_channel_read_chars( file,
621 : buffer+3,
622 : sizeof(buffer)-3,
623 : &bytes_read,
624 : 0 ))
625 : {
626 0 : if ( buffer[3]=='\n' || buffer[3]=='#' )
627 0 : continue;
628 0 : if ( cnt>1000-3 )
629 0 : break;
630 0 : if ( buffer[strlen(buffer)-1]=='\n' )
631 0 : buffer[strlen(buffer)-1] = '\0';
632 0 : words[cnt] = calloc(1,sizeof(GTextInfo));
633 0 : words[cnt]->fg = words[cnt]->bg = COLOR_DEFAULT;
634 0 : words[cnt]->text = (unichar_t *) copy( buffer );
635 0 : words[cnt++]->text_is_1byte = true;
636 : }
637 : }
638 :
639 0 : g_io_channel_shutdown( file, 1, 0 );
640 0 : g_io_channel_unref( file );
641 0 : if ( cnt!=0 )
642 : {
643 0 : words[cnt] = calloc(1,sizeof(GTextInfo));
644 0 : words[cnt]->fg = words[cnt]->bg = COLOR_DEFAULT;
645 0 : words[cnt++]->line = true;
646 0 : words[cnt] = calloc(1,sizeof(GTextInfo));
647 0 : words[cnt]->fg = words[cnt]->bg = COLOR_DEFAULT;
648 0 : words[cnt]->text = (unichar_t *) copy( _("Load Word List...") );
649 0 : words[cnt]->text_is_1byte = true;
650 0 : words[cnt++]->userdata = (void *) -1;
651 0 : words[cnt] = calloc(1,sizeof(GTextInfo));
652 0 : words[cnt]->fg = words[cnt]->bg = COLOR_DEFAULT;
653 0 : words[cnt]->text = (unichar_t *) copy( _("Load Glyph Name List...") );
654 0 : words[cnt]->text_is_1byte = true;
655 0 : words[cnt++]->userdata = (void *) -2;
656 0 : words[cnt] = calloc(1,sizeof(GTextInfo));
657 : }
658 : else
659 : {
660 0 : free(words);
661 0 : words = 0;
662 : }
663 0 : return words;
664 : }
665 :
666 :
667 0 : void Wordlist_MoveByOffset( GGadget* g, int* idx, int offset )
668 : {
669 0 : int cidx = *idx;
670 0 : if ( cidx!=-1 )
671 : {
672 : int32 len;
673 0 : GTextInfo **ti = GGadgetGetList(g,&len);
674 : /* We subtract 3 because: There are two lines saying "load * list" */
675 : /* and then a line with a rule on it which we don't want access to */
676 0 : if ( cidx+offset >=0 && cidx+offset<len-3 )
677 : {
678 0 : cidx += offset;
679 0 : *idx = cidx;
680 0 : GGadgetSelectOneListItem( g, cidx );
681 0 : ti = NULL;
682 : }
683 0 : Wordlist_touch( g );
684 : }
685 0 : }
686 :
687 0 : void Wordlist_touch( GGadget* g )
688 : {
689 : // Force any extra chars to be setup and drawn
690 : GEvent e;
691 0 : e.type=et_controlevent;
692 0 : e.u.control.subtype = et_textchanged;
693 0 : e.u.control.u.tf_changed.from_pulldown = GGadgetGetFirstListSelectedItem(g);
694 0 : GGadgetDispatchEvent( g, &e );
695 0 : }
696 :
697 :
698 0 : void WordlistLoadToGTextInfo( GGadget* g, int* idx )
699 : {
700 0 : int words_max = 1024*128;
701 0 : GTextInfo** words = WordlistLoadFileToGTextInfoBasic( words_max );
702 0 : if( !words )
703 : {
704 0 : GGadgetSetTitle8(g,"");
705 0 : return;
706 : }
707 :
708 0 : if( words[0] )
709 : {
710 0 : GGadgetSetList(g,words,true);
711 0 : GGadgetSetTitle8(g,(char *) (words[0]->text));
712 0 : GTextInfoArrayFree(words);
713 0 : *idx = 0;
714 0 : GGadgetSelectOneListItem( g, *idx );
715 0 : Wordlist_touch( g );
716 0 : return;
717 : }
718 0 : return;
719 : }
720 :
721 :
722 0 : static GArray* Wordlist_selectedToBitmapArray( GArray* a )
723 : {
724 0 : GArray* ret = g_array_new( 1, 1, sizeof(gint) );
725 0 : ret = g_array_set_size( ret, PATH_MAX+1 );
726 :
727 0 : int i = 0;
728 0 : for (i = 0; i < a->len; i++)
729 : {
730 0 : int v = g_array_index (a, gint, i);
731 0 : int one = 1;
732 0 : g_array_insert_val( ret, v, one );
733 : }
734 0 : return ret;
735 : }
736 :
737 :
738 0 : unichar_t* Wordlist_selectionClear( SplineFont* sf, EncMap *map, unichar_t* txtu )
739 : {
740 : static unichar_t ret[ PATH_MAX ];
741 0 : int limit = PATH_MAX;
742 0 : memset( ret, 0, sizeof(unichar_t) * PATH_MAX );
743 :
744 0 : unichar_t *dst = ret;
745 0 : const unichar_t *src_end = 0;
746 0 : const unichar_t *src = 0;
747 0 : src_end=txtu+u_strlen(txtu);
748 0 : for ( src=txtu; src < src_end; ++src )
749 : {
750 0 : if( *src != '[' && *src != ']' )
751 : {
752 0 : *dst = *src;
753 0 : dst++;
754 : }
755 : }
756 :
757 0 : return ret;
758 : }
759 :
760 0 : unichar_t* Wordlist_selectionAdd( SplineFont* sf, EncMap *map, unichar_t* txtu, int offset )
761 : {
762 0 : int i = 0;
763 : static unichar_t ret[ PATH_MAX ];
764 0 : memset( ret, 0, sizeof(unichar_t) * PATH_MAX );
765 :
766 0 : WordlistTrimTrailingSingleSlash( txtu );
767 0 : WordListLine wll = WordlistEscapedInputStringToParsedData( sf, txtu );
768 :
769 0 : for( i = 0; wll->sc; wll++, i++ )
770 : {
771 0 : SplineChar* sc = wll->sc;
772 0 : int element_selected = wll->isSelected;
773 :
774 0 : if( i == offset )
775 0 : element_selected = 1;
776 :
777 0 : if( element_selected )
778 : {
779 0 : int pos = map->backmap[ sc->orig_pos ];
780 : TRACE("pos1:%d\n", pos );
781 : TRACE("map:%d\n", map->map[ pos ] );
782 0 : int gid = pos < 0 || pos >= map->enccount ? -2 : map->map[pos];
783 0 : if( gid == -2 )
784 0 : continue;
785 0 : if( gid==-1 || !sf->glyphs[gid] )
786 0 : sc = SFMakeChar( sf, map, pos );
787 : else
788 0 : sc = sf->glyphs[gid];
789 : }
790 :
791 :
792 0 : if( element_selected )
793 0 : uc_strcat( ret, "[" );
794 :
795 : /* uc_strcat( ret, "/" ); */
796 : /* uc_strcat( ret, scarray[i]->name ); */
797 0 : uc_strcat( ret, Wordlist_getSCName( sc ));
798 :
799 0 : if( element_selected )
800 0 : uc_strcat( ret, "]" );
801 : }
802 :
803 0 : return ret;
804 : }
805 :
806 :
807 0 : unichar_t* Wordlist_advanceSelectedCharsBy( SplineFont* sf, EncMap *map, unichar_t* txtu, int offset )
808 : {
809 : unichar_t original_data[ PATH_MAX ];
810 : static unichar_t ret[ PATH_MAX ];
811 0 : int i = 0;
812 :
813 0 : u_strcpy( original_data, txtu );
814 : TRACE("Wordlist_advanceSelectedCharsBy(1) %s\n", u_to_c( txtu ));
815 0 : WordlistTrimTrailingSingleSlash( txtu );
816 0 : WordListLine wll = WordlistEscapedInputStringToParsedData( sf, txtu );
817 :
818 0 : int selectedCount = WordListLine_countSelected( wll );
819 0 : if( !selectedCount )
820 0 : wll->isSelected = 1;
821 :
822 0 : memset( ret, 0, sizeof(unichar_t) * PATH_MAX );
823 0 : for( i = 0; wll->sc; wll++, i++ )
824 : {
825 0 : SplineChar* sc = wll->sc;
826 0 : int element_selected = wll->isSelected;
827 :
828 0 : if( element_selected )
829 : {
830 0 : int pos = map->backmap[ sc->orig_pos ];
831 0 : pos += offset;
832 0 : int gid = pos < 0 || pos >= map->enccount ? -2 : map->map[pos];
833 0 : if( gid == -2 )
834 : {
835 : // we can't find a glyph at the desired position.
836 : // so instead of dropping it we just do not perform the operation
837 : // on this char.
838 0 : pos -= offset;
839 0 : gid = pos < 0 || pos >= map->enccount ? -2 : map->map[pos];
840 0 : if( gid == -2 )
841 : {
842 : // we can't go back manually!
843 0 : u_strcpy( ret, original_data );
844 0 : return ret;
845 : }
846 : }
847 0 : if( gid==-1 || !sf->glyphs[gid] )
848 0 : sc = SFMakeChar( sf, map, pos );
849 : else
850 0 : sc = sf->glyphs[gid];
851 : }
852 :
853 :
854 0 : if( element_selected )
855 0 : uc_strcat( ret, "[" );
856 :
857 : /* uc_strcat( ret, "/" ); */
858 : /* uc_strcat( ret, scarray[i]->name ); */
859 0 : uc_strcat( ret, Wordlist_getSCName( sc ));
860 :
861 0 : if( element_selected )
862 0 : uc_strcat( ret, "]" );
863 : }
864 :
865 0 : return ret;
866 : }
867 :
868 :
869 :
870 : /**
871 : * haveSelection is set to true iff there is 1+ selections i txtu
872 : */
873 0 : static unichar_t* Wordlist_selectionStringOnly( unichar_t* txtu, int* haveSelection )
874 : {
875 : static unichar_t ret[ PATH_MAX ];
876 0 : int limit = PATH_MAX;
877 0 : memset( ret, 0, sizeof(unichar_t) * PATH_MAX );
878 0 : *haveSelection = 0;
879 :
880 0 : int inSelection = 0;
881 0 : unichar_t *dst = ret;
882 0 : const unichar_t *src_end = 0;
883 0 : const unichar_t *src = 0;
884 0 : src_end=txtu+u_strlen(txtu);
885 0 : for ( src=txtu; src < src_end; ++src )
886 : {
887 0 : if( *src == '[' )
888 : {
889 0 : inSelection = 1;
890 0 : *haveSelection = 1;
891 0 : continue;
892 : }
893 0 : if( *src == ']' )
894 : {
895 0 : inSelection = 0;
896 0 : continue;
897 : }
898 :
899 0 : if( inSelection )
900 : {
901 0 : *dst = *src;
902 0 : dst++;
903 : }
904 : }
905 :
906 0 : return ret;
907 : }
908 :
909 :
910 0 : bool Wordlist_selectionsEqual( unichar_t* s1, unichar_t* s2 )
911 : {
912 : static unichar_t s1stripped[ PATH_MAX ];
913 : static unichar_t s2stripped[ PATH_MAX ];
914 0 : int s1HasSelection = 0;
915 0 : int s2HasSelection = 0;
916 :
917 0 : u_strcpy( s1stripped, Wordlist_selectionStringOnly( s1, &s1HasSelection ));
918 0 : u_strcpy( s2stripped, Wordlist_selectionStringOnly( s2, &s2HasSelection ));
919 :
920 0 : if( s1HasSelection && !s2HasSelection )
921 0 : return false;
922 0 : if( !s1HasSelection && s2HasSelection )
923 0 : return false;
924 :
925 0 : return !u_strcmp( s1stripped, s2stripped );
926 : }
927 :
928 :
929 0 : unichar_t* WordListLine_toustr( WordListLine wll )
930 : {
931 0 : unichar_t* ret = calloc( WordListLine_size(wll)+1, sizeof(unichar_t));
932 0 : unichar_t* p = ret;
933 0 : for( ; wll->sc; wll++, p++ ) {
934 0 : *p = wll->sc->unicodeenc;
935 0 : if (*p == -1) *p = wll->n;
936 : }
937 0 : return ret;
938 : }
939 :
940 :
941 :
942 :
943 :
|