LCOV - code coverage report
Current view: top level - fontforgeexe - wordlistparser.c (source / functions) Hit Total Coverage
Test: FontForge coverage report 2017-08-04 01:21:11+02:00 (commit d35f7e4107a9e1db65cce47c468fcc914cecb8fd) Lines: 0 467 0.0 %
Date: 2017-08-04 Functions: 0 25 0.0 %

          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             : 

Generated by: LCOV version 1.10