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

          Line data    Source code
       1             : /* Copyright (C) 2003-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             : #include "autohint.h"
      28             : #include "dumppfa.h"
      29             : #include "fontforgeui.h"
      30             : #include "psfont.h"
      31             : #include "splineutil.h"
      32             : #include <ustring.h>
      33             : #include <gkeysym.h>
      34             : #include <utype.h>
      35             : #include <math.h>
      36             : #include "psfont.h"
      37             : #include <ffglib.h>
      38             : #include <glib/gprintf.h>
      39             : #include "xvasprintf.h"
      40             : 
      41             : /* This operations are designed to work on a single font. NOT a CID collection*/
      42             : /*  A CID collection must be treated one sub-font at a time */
      43             : 
      44             : struct hentry {
      45             :     int cnt, sum;
      46             :     int char_cnt, max;
      47             :     SplineChar **chars;
      48             : };
      49             : 
      50             : typedef struct histdata {
      51             :     int low, high;
      52             :     struct hentry *hist;        /* array of high-low+1 elements */
      53             :     int tot, max;
      54             : } HistData;
      55             : 
      56           0 : static void HistDataFree(HistData *h) {
      57             :     int i;
      58             : 
      59           0 :     for ( i=h->low; i<=h->high; ++i )
      60           0 :         free(h->hist[i-h->low].chars);
      61           0 :     free(h->hist);
      62           0 :     free(h);
      63           0 : }
      64             : 
      65           0 : static HistData *HistFindBlues(SplineFont *sf,int layer, uint8 *selected, EncMap *map) {
      66             :     int i, gid, low,high, top,bottom;
      67             :     SplineChar *sc;
      68             :     DBounds b;
      69             :     HistData *hist;
      70             :     struct hentry *h;
      71             : 
      72           0 :     hist = calloc(1,sizeof(HistData));
      73           0 :     hist->hist = calloc(sf->ascent+sf->descent+1,sizeof(struct hentry));
      74           0 :     hist->low = sf->ascent; hist->high = -sf->descent;
      75           0 :     low = -sf->descent; high = sf->ascent;
      76             : 
      77           0 :     for ( i=0; i<(selected==NULL?sf->glyphcnt:map->enccount); ++i ) {
      78           0 :         gid = selected==NULL ? i : map->map[i];
      79           0 :         if ( gid!=-1 && (sc = sf->glyphs[gid])!=NULL &&
      80           0 :                 sc->layers[ly_fore].splines!=NULL &&
      81           0 :                 sc->layers[ly_fore].refs==NULL &&
      82           0 :                 (selected==NULL || selected[i])) {
      83           0 :             SplineCharLayerFindBounds(sc,layer,&b);
      84           0 :             bottom = rint(b.miny);
      85           0 :             top = rint(b.maxy);
      86           0 :             if ( top==bottom )
      87           0 :         continue;
      88           0 :             if ( top>hist->high ) {
      89           0 :                 hist->high = top;
      90           0 :                 if ( top>high ) {
      91           0 :                     hist->hist = realloc(hist->hist,(top+10-low)*sizeof(struct hentry));
      92           0 :                     memset(hist->hist + high-low+1,0,(top+10-high-1)*sizeof(struct hentry));
      93           0 :                     high = top+10 -1;
      94             :                 }
      95             :             }
      96           0 :             ++ hist->hist[top-low].cnt;
      97           0 :             if ( hist->hist[top-low].char_cnt >= hist->hist[top-low].max ) {
      98           0 :                 if ( hist->hist[top-low].max==0 )
      99           0 :                     hist->hist[top-low].chars = malloc(10*sizeof(SplineChar *));
     100             :                 else
     101           0 :                     hist->hist[top-low].chars = realloc(hist->hist[top-low].chars,(hist->hist[top-low].max+10)*sizeof(SplineChar *));
     102           0 :                 hist->hist[top-low].max += 10;
     103             :             }
     104           0 :             hist->hist[top-low].chars[hist->hist[top-low].char_cnt++] = sc;
     105             : 
     106           0 :             if ( bottom<hist->low ) {
     107           0 :                 hist->low = bottom;
     108           0 :                 if ( bottom<low ) {
     109           0 :                     h = calloc((high-bottom+10),sizeof( struct hentry ));
     110           0 :                     memcpy(h+low-(bottom-10+1),hist->hist,(high+1-low)*sizeof(struct hentry));
     111           0 :                     low = bottom-10+1;
     112           0 :                     free( hist->hist );
     113           0 :                     hist->hist = h;
     114             :                 }
     115             :             }
     116           0 :             ++ hist->hist[bottom-low].cnt;
     117           0 :             if ( hist->hist[bottom-low].char_cnt >= hist->hist[bottom-low].max ) {
     118           0 :                 if ( hist->hist[bottom-low].max==0 )
     119           0 :                     hist->hist[bottom-low].chars = malloc(10*sizeof(SplineChar *));
     120             :                 else
     121           0 :                     hist->hist[bottom-low].chars = realloc(hist->hist[bottom-low].chars,(hist->hist[bottom-low].max+10)*sizeof(SplineChar *));
     122           0 :                 hist->hist[bottom-low].max += 10;
     123             :             }
     124           0 :             hist->hist[bottom-low].chars[hist->hist[bottom-low].char_cnt++] = sc;
     125             :         }
     126           0 :         hist->tot += 2;
     127             :     }
     128           0 :     if ( hist->low>hist->high ) {              /* Found nothing */
     129           0 :         hist->low = hist->high = 0;
     130             :     }
     131           0 :     if ( low!=hist->low || high!=hist->high ) {
     132           0 :         h = malloc((hist->high-hist->low+1)*sizeof(struct hentry));
     133           0 :         memcpy(h,hist->hist + hist->low-low,(hist->high-hist->low+1)*sizeof(struct hentry));
     134           0 :         free(hist->hist);
     135           0 :         hist->hist = h;
     136             :     }
     137           0 : return( hist );
     138             : }
     139             : 
     140           0 : static HistData *HistFindStemWidths(SplineFont *sf,int layer, uint8 *selected,EncMap *map,int hor) {
     141             :     int i, gid, low,high, val;
     142             :     SplineChar *sc;
     143             :     HistData *hist;
     144             :     struct hentry *h;
     145             :     StemInfo *stem;
     146             : 
     147           0 :     hist = calloc(1,sizeof(HistData));
     148           0 :     hist->hist = calloc(sf->ascent+sf->descent+1,sizeof(struct hentry));
     149           0 :     hist->low = sf->ascent+sf->descent;
     150           0 :     low = 0; high = sf->ascent+sf->descent;
     151             : 
     152           0 :     for ( i=0; i<(selected==NULL?sf->glyphcnt:map->enccount); ++i ) {
     153           0 :         gid = selected==NULL ? i : map->map[i];
     154           0 :         if ( gid!=-1 && (sc = sf->glyphs[gid])!=NULL &&
     155           0 :                 sc->layers[ly_fore].splines!=NULL &&
     156           0 :                 sc->layers[ly_fore].refs==NULL &&
     157           0 :                 (selected==NULL || selected[i])) {
     158           0 :             if ( autohint_before_generate && sc->changedsincelasthinted && !sc->manualhints )
     159           0 :                 SplineCharAutoHint(sc,layer,NULL);
     160           0 :             for ( stem = hor ? sc->hstem : sc->vstem ; stem!=NULL; stem = stem->next ) {
     161           0 :                 if ( stem->ghost )
     162           0 :             continue;
     163           0 :                 val = rint(stem->width);
     164           0 :                 if ( val<=0 )
     165           0 :                     val = -val;
     166           0 :                 if ( val>hist->high ) {
     167           0 :                     hist->high = val;
     168           0 :                     if ( val>high ) {
     169           0 :                         hist->hist = realloc(hist->hist,(val+10-low)*sizeof(struct hentry));
     170           0 :                         memset(hist->hist + high-low+1,0,(val+10-high-1)*sizeof(struct hentry));
     171           0 :                         high = val+10 -1;
     172             :                     }
     173             :                 }
     174           0 :                 if ( val<hist->low )
     175           0 :                     hist->low = val;
     176           0 :                 ++ hist->hist[val-low].cnt;
     177           0 :                 if ( hist->hist[val-low].char_cnt==0 ||
     178           0 :                         hist->hist[val-low].chars[hist->hist[val-low].char_cnt-1]!=sc ) {
     179           0 :                     if ( hist->hist[val-low].char_cnt >= hist->hist[val-low].max ) {
     180           0 :                         if ( hist->hist[val-low].max==0 )
     181           0 :                             hist->hist[val-low].chars = malloc(10*sizeof(SplineChar *));
     182             :                         else
     183           0 :                             hist->hist[val-low].chars = realloc(hist->hist[val-low].chars,(hist->hist[val-low].max+10)*sizeof(SplineChar *));
     184           0 :                         hist->hist[val-low].max += 10;
     185             :                     }
     186           0 :                     hist->hist[val-low].chars[hist->hist[val-low].char_cnt++] = sc;
     187             :                 }
     188           0 :                 ++ hist->tot;
     189             :             }
     190             :         }
     191             :     }
     192           0 :     if ( hist->low>hist->high ) {              /* Found nothing */
     193           0 :         hist->low = hist->high = 0;
     194             :     }
     195           0 :     if ( low!=hist->low || high!=hist->high ) {
     196           0 :         h = malloc((hist->high-hist->low+1)*sizeof(struct hentry));
     197           0 :         memcpy(h,hist->hist + hist->low-low,(hist->high-hist->low+1)*sizeof(struct hentry));
     198           0 :         free(hist->hist);
     199           0 :         hist->hist = h;
     200             :     }
     201           0 : return( hist );
     202             : }
     203             : 
     204           0 : static HistData *HistFindHStemWidths(SplineFont *sf,int layer, uint8 *selected,EncMap *map) {
     205           0 : return( HistFindStemWidths(sf,layer,selected,map,true) );
     206             : }
     207             : 
     208           0 : static HistData *HistFindVStemWidths(SplineFont *sf,int layer, uint8 *selected,EncMap *map) {
     209           0 : return( HistFindStemWidths(sf,layer,selected,map,false) );
     210             : }
     211             : 
     212           0 : static void HistFindMax(HistData *h, int sum_around) {
     213           0 :     int i, j, m=1;
     214             :     int c;
     215             : 
     216           0 :     if ( sum_around<0 ) sum_around = 0;
     217           0 :     for ( i = h->low; i<=h->high; ++i ) {
     218           0 :         c = 0;
     219           0 :         for ( j=i-sum_around; j<=i+sum_around; ++j )
     220           0 :             if ( j>=h->low && j<=h->high )
     221           0 :                 c += h->hist[j-h->low].cnt;
     222           0 :         h->hist[i-h->low].sum = c;
     223           0 :         if ( c>m )
     224           0 :             m = c;
     225             :     }
     226           0 :     h->max = m;
     227           0 : }
     228             : 
     229             : #define CID_ScrollBar           1000
     230             : #define CID_MainVal             1001
     231             : #define CID_SecondaryVal        1002
     232             : 
     233             : #define CID_SumAround           1003
     234             : #define CID_BarWidth            1004
     235             : 
     236             : #define CID_MainValL            2001
     237             : #define CID_SecondaryValL       2002
     238             : #define CID_SumAroundL          2003
     239             : #define CID_BarWidthL           2004
     240             : #define CID_Group               2005
     241             : #define CID_BlueMsg             2006
     242             : 
     243             : #define CID_OK                  3001
     244             : #define CID_Cancel              3002
     245             : 
     246             : #define CID_LeftSide            4001
     247             : #define CID_Histogram           4002
     248             : #define CID_RightSide           4003
     249             : 
     250             : struct hist_dlg {
     251             :     enum hist_type which;
     252             :     SplineFont *sf;
     253             :     int layer;
     254             :     struct psdict *private;
     255             :     uint8 *selected;
     256             :     HistData *h;
     257             : 
     258             :     int pending_blue;
     259             :     int is_pending;
     260             : 
     261             :     int sum_around, barwidth;
     262             :     int hoff;
     263             : 
     264             :     int x,y;
     265             :     int hwidth, hheight;
     266             :     int yoff;
     267             : 
     268             :     GWindow gw;
     269             :     GFont *font;
     270             :     int fh, as;
     271             :     int done;
     272             : };
     273             : 
     274           0 : static void HistPopup(struct hist_dlg *hist,GEvent *e) {
     275           0 :     int x = e->u.mouse.x;
     276             :     struct hentry *h;
     277             :     static char buffer[300];
     278           0 :     char *end = buffer + sizeof(buffer)/sizeof(buffer[0]), *pt, *line;
     279             :     int i;
     280             : 
     281           0 :     x /= hist->barwidth;
     282           0 :     if ( x + hist->hoff > hist->h->high || x + hist->hoff - hist->h->low<0 )
     283           0 : return;
     284             : 
     285           0 :     h = &hist->h->hist[x + hist->hoff - hist->h->low];
     286           0 :     if ( hist->sum_around==0 ) {
     287           0 :         if ( hist->which == hist_blues )
     288           0 :             snprintf(buffer,end-buffer,
     289           0 :                     _("Position: %d\nCount: %d\n"),
     290           0 :                     x + hist->hoff,
     291             :                     h->sum);
     292             :         else
     293           0 :             snprintf(buffer,end-buffer,
     294           0 :                     _("Width: %d\nCount: %d\nPercentage of Max: %d%%\n"),
     295           0 :                     x + hist->hoff,
     296           0 :                     h->sum, (int) rint(h->sum*100.0/hist->h->max));
     297             :     } else {
     298           0 :         if ( hist->which == hist_blues )
     299           0 :             snprintf(buffer,end-buffer,
     300           0 :                     _("Position: %d-%d (%d)\nCount: %d (%d)\n"),
     301           0 :                     x+hist->hoff-hist->sum_around, x+hist->hoff+hist->sum_around, x + hist->hoff,
     302             :                     h->sum, h->cnt);
     303             :         else
     304           0 :             snprintf(buffer,end-buffer,
     305           0 :                     _("Width: %d-%d (%d)\nCount: %d (%d)\nPercentage of Max: %d%%\n"),
     306           0 :                     x+hist->hoff-hist->sum_around, x+hist->hoff+hist->sum_around, x + hist->hoff,
     307           0 :                     h->sum, h->cnt, (int) rint(h->sum*100.0/hist->h->max));
     308             :     }
     309           0 :     pt = buffer+strlen(buffer);
     310           0 :     line = pt;
     311           0 :     for ( i = 0; i<h->char_cnt; ++i ) {
     312           0 :         if ( pt+strlen(h->chars[i]->name)+4>end ) {
     313           0 :             strcpy(pt,"...");
     314           0 :     break;
     315             :         }
     316           0 :         strcpy(pt,h->chars[i]->name);
     317           0 :         pt += strlen(pt);
     318           0 :         if ( pt-line>70 ) {
     319           0 :             *pt++ = '\n';
     320           0 :             line = pt;
     321             :         } else
     322           0 :             *pt++ = ' ';
     323           0 :         *pt = '\0';
     324             :     }
     325           0 :     GGadgetPreparePopup8(hist->gw,buffer);
     326             : }
     327             : 
     328           0 : static char *ArrayOrder(char *old,int args,int val1,int val2) {
     329             :     char *end;
     330             :     double array[40];
     331             :     int i,j,k;
     332             :     GString *new;
     333             : 
     334           0 :     if ( *old=='[' ) ++old;
     335             : 
     336           0 :     for ( i=0; i<40 && *old!=']' && *old!='\0'; ++i ) {
     337           0 :         array[i] = strtod(old,&end);
     338           0 :         if ( old==end )
     339           0 :     break;
     340           0 :         old = end;
     341           0 :         while ( *old==' ' ) ++old;
     342             :     }
     343           0 :     if (i<40)
     344           0 :         array[i++] = val1;
     345           0 :     if (i<40) {
     346           0 :         if ( args==2 )
     347           0 :             array[i++] = val2;
     348             :     }
     349           0 :     for ( j=0; j<i; ++j ) for ( k=j+1; k<i; ++k ) if ( array[j]>array[k] ) {
     350           0 :         double temp = array[j];
     351           0 :         array[j] = array[k];
     352           0 :         array[k] = temp;
     353             :     }
     354             : 
     355           0 :     new = g_string_new( "[" );
     356           0 :     for ( k=0; k<i; ++k ) {
     357           0 :         if (k == i-1)
     358           0 :             g_string_append_printf( new, "%g]", array[k] );
     359             :         else
     360           0 :             g_string_append_printf( new, "%g ", array[k] );
     361             :     }
     362             : 
     363           0 : return( (char *) g_string_free( new, FALSE ) );
     364             : }
     365             : 
     366             : /* Handle clicks on histogram chart and update text fields below accordingly */
     367           0 : static void HistPress(struct hist_dlg *hist,GEvent *e) {
     368           0 :     char *old = NULL;
     369           0 :     char *new = NULL;
     370           0 :     int x = e->u.mouse.x;
     371             : 
     372           0 :     x /= hist->barwidth;
     373           0 :     x += hist->hoff;
     374           0 :     if ( x > hist->h->high || x<hist->h->low )
     375           0 : return;
     376             : 
     377           0 :     if ( hist->which==hist_blues ) {
     378           0 :         if ( hist->is_pending ) {
     379           0 :             if ( x<hist->pending_blue )
     380           0 :                 ff_post_error(_("Bad Value"),_("The smaller number must be selected first in a pair of bluevalues"));
     381           0 :             else if ( x<0 ) {        /* OtherBlues */
     382           0 :                 old = GGadgetGetTitle8( GWidgetGetControl( hist->gw, CID_SecondaryVal ));
     383           0 :                 new = ArrayOrder( old, 2, hist->pending_blue, x );
     384           0 :                 GGadgetSetTitle8( GWidgetGetControl( hist->gw, CID_SecondaryVal ), new );
     385             :             } else {
     386           0 :                 old = GGadgetGetTitle8( GWidgetGetControl( hist->gw, CID_MainVal ));
     387           0 :                 new = ArrayOrder( old, 2, hist->pending_blue, x );
     388           0 :                 GGadgetSetTitle8( GWidgetGetControl( hist->gw, CID_MainVal ), new );
     389             :             }
     390           0 :             GDrawSetCursor(hist->gw,ct_pointer);
     391           0 :             hist->is_pending = false;
     392             :         } else {
     393           0 :             hist->is_pending = true;
     394           0 :             hist->pending_blue = x;
     395           0 :             GDrawSetCursor(hist->gw,ct_eyedropper);
     396             :         }
     397           0 :         GGadgetSetVisible(GWidgetGetControl(hist->gw,CID_MainVal),!hist->is_pending);
     398           0 :         GGadgetSetVisible(GWidgetGetControl(hist->gw,CID_MainValL),!hist->is_pending);
     399           0 :         GGadgetSetVisible(GWidgetGetControl(hist->gw,CID_BlueMsg),hist->is_pending);
     400             :     } else { /* HStem and VStem */
     401           0 :         if ( !( e->u.mouse.state&ksm_shift )) {
     402           0 :             new = xasprintf( "[%d]", x );
     403           0 :             GGadgetSetTitle8( GWidgetGetControl( hist->gw, CID_MainVal ), new );
     404           0 :             GGadgetSetTitle8( GWidgetGetControl( hist->gw, CID_SecondaryVal ), new );
     405             :         } else {
     406           0 :             old = GGadgetGetTitle8( GWidgetGetControl( hist->gw, CID_SecondaryVal ));
     407           0 :             new = ArrayOrder( old, 1, x, 0 );
     408           0 :             GGadgetSetTitle8( GWidgetGetControl( hist->gw, CID_SecondaryVal ), new );
     409             :         }
     410             :     }
     411           0 :     free( old );
     412           0 :     free( new );
     413             : }
     414             : 
     415           0 : static void HistExpose(GWindow pixmap, struct hist_dlg *hist) {
     416             :     GRect r,old;
     417             :     int height;
     418             :     double yscale;
     419             :     int i;
     420             :     char buf[20];
     421             :     GRect size;
     422           0 :     GDrawGetSize(GDrawableGetWindow(GWidgetGetControl(hist->gw,CID_Histogram)),&size);
     423             : 
     424           0 :     height = size.height-hist->fh-2;
     425           0 :     yscale = (4*height/5.0)/(hist->h->max-0);
     426             : 
     427           0 :     GDrawSetLineWidth(pixmap,0);
     428           0 :     r.x = 0; r.y = 0;
     429           0 :     r.width = size.width-1; r.height = height-1;
     430           0 :     GDrawDrawRect(pixmap,&r,0x000000);
     431             : 
     432           0 :     ++r.x; r.width--;
     433           0 :     ++r.y; r.height--;
     434           0 :     GDrawPushClip(pixmap,&r,&old);
     435             : 
     436           0 :     for ( i=hist->hoff; (i-hist->hoff)*hist->barwidth<size.width-2 && i<=hist->h->high; ++i ) {
     437           0 :         r.x = (i-hist->hoff)*hist->barwidth+1; r.width = hist->barwidth;
     438           0 :         r.height = rint(hist->h->hist[i-hist->h->low].sum * yscale);
     439           0 :         if ( r.height>=0 ) {
     440           0 :             r.y = height - r.height;
     441           0 :             GDrawFillRect(pixmap,&r,0x2020ff);
     442             :         }
     443             :     }
     444             : 
     445           0 :     GDrawPopClip(pixmap,&old);
     446             : 
     447           0 :     GDrawSetFont(pixmap,hist->font);
     448           0 :     sprintf(buf,"%d",hist->hoff);
     449           0 :     GDrawDrawText8(pixmap,0,height+2+hist->as, buf,-1,0x000000);
     450           0 :     sprintf(buf,"%d",hist->hoff+hist->hwidth/hist->barwidth);
     451           0 :     GDrawDrawText8(pixmap,size.width-GDrawGetText8Width(pixmap,buf,-1),height+2+hist->as,
     452             :             buf,-1,0x000000);
     453           0 : }
     454             : 
     455           0 : static void HistRExpose(GWindow pixmap, struct hist_dlg *hist) {
     456             :     int height;
     457             :     double yscale;
     458             :     GRect size;
     459             :     char buf[20];
     460             : 
     461           0 :     GDrawGetSize(GDrawableGetWindow(GWidgetGetControl(hist->gw,CID_RightSide)),&size);
     462           0 :     height = size.height-hist->fh-2;
     463           0 :     yscale = (4*height/5.0)/(hist->h->max-0);
     464             : 
     465           0 :     sprintf(buf,"%d",hist->h->max);
     466           0 :     GDrawDrawText8(pixmap,1,height-rint(hist->h->max*yscale),
     467             :             buf,-1,0x000000);
     468           0 : }
     469             : 
     470           0 : static void HistLExpose(GWindow pixmap, struct hist_dlg *hist) {
     471             :     int height;
     472             :     double yscale;
     473             :     GRect size;
     474             :     char buf[20];
     475             : 
     476           0 :     GDrawGetSize(GDrawableGetWindow(GWidgetGetControl(hist->gw,CID_LeftSide)),&size);
     477           0 :     height = size.height-hist->fh-2;
     478           0 :     yscale = (4*height/5.0)/(hist->h->max-0);
     479             : 
     480           0 :     sprintf(buf,"%d",hist->h->max);
     481           0 :     GDrawDrawText8(pixmap,size.width-GDrawGetText8Width(pixmap,buf,-1)-1,height-rint(hist->h->max*yscale),
     482             :             buf,-1,0x000000);
     483           0 : }
     484             : 
     485           0 : static void HistScroll(struct hist_dlg *hist,struct sbevent *sb) {
     486           0 :     int newpos = hist->hoff;
     487             :     int cols;
     488             :     GRect size;
     489           0 :     GGadget *g = GWidgetGetControl(hist->gw,CID_ScrollBar);
     490             : 
     491           0 :     GGadgetGetSize(g,&size);
     492           0 :     cols = (size.width-2)/hist->barwidth;
     493             : 
     494           0 :     switch( sb->type ) {
     495             :       case et_sb_top:
     496           0 :         newpos = 0;
     497           0 :       break;
     498             :       case et_sb_uppage:
     499           0 :         newpos -= cols;
     500           0 :       break;
     501             :       case et_sb_up:
     502           0 :         --newpos;
     503           0 :       break;
     504             :       case et_sb_down:
     505           0 :         ++newpos;
     506           0 :       break;
     507             :       case et_sb_downpage:
     508           0 :         newpos += cols;
     509           0 :       break;
     510             :       case et_sb_bottom:
     511           0 :         newpos = (hist->h->high+1-hist->h->low)-cols;
     512           0 :       break;
     513             :       case et_sb_thumb:
     514             :       case et_sb_thumbrelease:
     515           0 :         newpos = sb->pos;
     516           0 :       break;
     517             :     }
     518           0 :     if ( newpos>(hist->h->high+1-hist->h->low)-cols + hist->h->low )
     519           0 :         newpos = (hist->h->high+1-hist->h->low)-cols + hist->h->low;
     520           0 :     if ( newpos<hist->h->low ) newpos = hist->h->low;
     521           0 :     if ( newpos!=hist->hoff ) {
     522             :         /*int diff = newpos-hist->hoff;*/
     523           0 :         hist->hoff = newpos;
     524           0 :         GScrollBarSetPos(g,hist->hoff);
     525           0 :         GDrawRequestExpose(GDrawableGetWindow(GWidgetGetControl(hist->gw,CID_Histogram)),NULL,false);
     526             :     }
     527           0 : }
     528             : 
     529           0 : static void HistRefigureSB(struct hist_dlg *hist) {
     530           0 :     GGadget *g = GWidgetGetControl(hist->gw,CID_ScrollBar);
     531             :     int width, hoff, cols;
     532             :     GRect size;
     533             : 
     534           0 :     GGadgetGetSize(g,&size);
     535           0 :     width = size.width-2;
     536           0 :     cols = width/hist->barwidth;
     537             : 
     538           0 :     GScrollBarSetBounds(g,hist->h->low,hist->h->high+1,cols);
     539           0 :     if ( hist->hoff+cols >hist->h->high ) {
     540           0 :         hoff = hist->h->high-cols;
     541           0 :         if ( hoff<0 ) hoff = 0;
     542           0 :         if ( hoff!=hist->hoff ) {
     543           0 :             hist->hoff = hoff;
     544           0 :             GScrollBarSetPos(g,hoff);
     545             :         }
     546             :     }
     547           0 : }
     548             : 
     549           0 : static void HistResize(struct hist_dlg *hist) {
     550             : 
     551           0 :     HistRefigureSB(hist);
     552           0 :     GDrawRequestExpose(hist->gw,NULL,false);
     553           0 : }
     554             :         
     555           0 : static void HistSet(struct hist_dlg *hist) {
     556             :     char *primary, *secondary;
     557             :     char *temp;
     558           0 :     struct psdict *p = hist->private ? hist->private : hist->sf->private;
     559             :     const unichar_t *ret1, *ret2;
     560             : 
     561           0 :     switch ( hist->which ) {
     562             :       case hist_hstem:
     563           0 :         primary = "StdHW"; secondary = "StemSnapH";
     564           0 :       break;
     565             :       case hist_vstem:
     566           0 :         primary = "StdVW"; secondary = "StemSnapV";
     567           0 :       break;
     568             :       case hist_blues:
     569           0 :         primary = "BlueValues"; secondary = "OtherBlues";
     570           0 :       break;
     571             :     }
     572           0 :     ret1 = GGadgetGetTitle(GWidgetGetControl(hist->gw,CID_MainVal));
     573           0 :     ret2 = GGadgetGetTitle(GWidgetGetControl(hist->gw,CID_SecondaryVal));
     574           0 :     hist->done = true;
     575           0 :     if ( (*ret1=='\0' || uc_strcmp(ret1,"[]")==0 ) &&
     576           0 :             (*ret2=='\0' || uc_strcmp(ret2,"[]")==0 ) && p==NULL )
     577           0 : return;
     578           0 :     if ( p==NULL ) {
     579           0 :         hist->sf->private = p = calloc(1,sizeof(struct psdict));
     580           0 :         p->cnt = 10;
     581           0 :         p->keys = calloc(10,sizeof(char *));
     582           0 :         p->values = calloc(10,sizeof(char *));
     583             :     }
     584           0 :     PSDictChangeEntry(p,primary,temp=cu_copy(ret1)); free(temp);
     585           0 :     PSDictChangeEntry(p,secondary,temp=cu_copy(ret2)); free(temp);
     586             : }
     587             : 
     588           0 : static int leftside_e_h(GWindow gw, GEvent *event) {
     589           0 :     struct hist_dlg *hist = GDrawGetUserData(gw);
     590             : 
     591           0 :     switch ( event->type ) {
     592             :       case et_char:
     593           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     594           0 :             help("histogram.html");
     595           0 : return( true );
     596             :         }
     597           0 : return( false );
     598             :       break;
     599             :       case et_expose:
     600           0 :         HistLExpose(gw,hist);
     601           0 :       break;
     602             :       case et_mousemove:
     603             :       case et_mousedown:
     604           0 :         GGadgetEndPopup();
     605           0 :       break;
     606             :     }
     607           0 : return( true );
     608             : }
     609             : 
     610           0 : static int rightside_e_h(GWindow gw, GEvent *event) {
     611           0 :     struct hist_dlg *hist = GDrawGetUserData(gw);
     612             : 
     613           0 :     switch ( event->type ) {
     614             :       case et_char:
     615           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     616           0 :             help("histogram.html");
     617           0 : return( true );
     618             :         }
     619           0 : return( false );
     620             :       break;
     621             :       case et_expose:
     622           0 :         HistRExpose(gw,hist);
     623           0 :       break;
     624             :       case et_mousemove:
     625             :       case et_mousedown:
     626           0 :         GGadgetEndPopup();
     627           0 :       break;
     628             :     }
     629           0 : return( true );
     630             : }
     631             : 
     632           0 : static int histogram_e_h(GWindow gw, GEvent *event) {
     633           0 :     struct hist_dlg *hist = GDrawGetUserData(gw);
     634             : 
     635           0 :     switch ( event->type ) {
     636             :       case et_char:
     637           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     638           0 :             help("histogram.html");
     639           0 : return( true );
     640             :         }
     641           0 : return( false );
     642             :       break;
     643             :       case et_expose:
     644           0 :         HistExpose(gw,hist);
     645           0 :       break;
     646             :       case et_mousemove:
     647           0 :         GGadgetEndPopup();
     648           0 :         HistPopup(hist,event);
     649           0 :       break;
     650             :       case et_mousedown:
     651           0 :         GGadgetEndPopup();
     652           0 :         HistPress(hist,event);
     653           0 :       break;
     654             :     }
     655           0 : return( true );
     656             : }
     657             : 
     658           0 : static int hist_e_h(GWindow gw, GEvent *event) {
     659           0 :     struct hist_dlg *hist = GDrawGetUserData(gw);
     660             :     int temp;
     661             :     const unichar_t *ret;
     662             :     unichar_t *end;
     663             : 
     664           0 :     if ( event->type==et_close ) {
     665           0 :         hist->done = true;
     666           0 :     } else if ( event->type==et_char ) {
     667           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     668           0 :             help("histogram.html");
     669           0 : return( true );
     670             :         }
     671           0 : return( false );
     672           0 :     } else if ( event->type==et_resize ) {
     673           0 :         HistResize(hist);;
     674           0 :     } else if ( event->type==et_mousemove ) {
     675           0 :         GGadgetEndPopup();
     676           0 :     } else if ( event->type==et_mousedown ) {
     677           0 :         GGadgetEndPopup();
     678           0 :     } else if ( event->type==et_controlevent ) {
     679           0 :         switch ( event->u.control.subtype ) {
     680             :           case et_scrollbarchange:
     681           0 :             HistScroll(hist,&event->u.control.u.sb);
     682           0 :           break;
     683             :           case et_textchanged:
     684           0 :             switch( GGadgetGetCid(event->u.control.g)) {
     685             :               case CID_SumAround: case CID_BarWidth:
     686           0 :                 ret = _GGadgetGetTitle(event->u.control.g);
     687           0 :                 temp = u_strtol(ret,&end,10);
     688           0 :                 if ( temp<0 || *end )
     689             :               break;
     690           0 :                 if ( GGadgetGetCid(event->u.control.g)==CID_SumAround ) {
     691           0 :                     hist->sum_around = temp;
     692           0 :                     HistFindMax(hist->h,temp);
     693           0 :                 } else if ( temp==0 )
     694           0 :               break;
     695             :                 else {
     696           0 :                     hist->barwidth = temp;
     697           0 :                     HistRefigureSB(hist);
     698             :                 }
     699           0 :                 GDrawRequestExpose(GDrawableGetWindow(GWidgetGetControl(gw,CID_Histogram)),NULL,false);
     700           0 :                 GDrawRequestExpose(GDrawableGetWindow(GWidgetGetControl(gw,CID_LeftSide)),NULL,false);
     701           0 :                 GDrawRequestExpose(GDrawableGetWindow(GWidgetGetControl(gw,CID_RightSide)),NULL,false);
     702           0 :               break;
     703             :             }
     704           0 :           break;
     705             :           case et_buttonactivate:
     706           0 :             if ( GGadgetGetCid(event->u.control.g)==CID_OK ) {
     707           0 :                 HistSet(hist);
     708             :             } else
     709           0 :                 hist->done = true;
     710           0 :           break;
     711             :         }
     712             :     }
     713           0 : return( true );
     714             : }
     715             : 
     716           0 : static void CheckSmallSelection(uint8 *selected,EncMap *map,SplineFont *sf) {
     717             :     int i, cnt, tot;
     718             : 
     719           0 :     for ( i=cnt=tot=0; i<map->enccount; ++i ) {
     720           0 :         int gid = map->map[i];
     721           0 :         if ( gid!=-1 && sf->glyphs[gid]!=NULL ) {
     722           0 :             ++tot;
     723           0 :             if ( selected[i] )
     724           0 :                 ++cnt;
     725             :         }
     726             :     }
     727           0 :     if ( (cnt==1 && tot>1) || (cnt<8 && tot>30) )
     728           0 :         ff_post_notice(_("Tiny Selection"),_("There are so few glyphs selected that it seems unlikely to me that you will get a representative sample of this aspect of your font. If you deselect everything the command will apply to all glyphs in the font"));
     729           0 : }
     730             : 
     731           0 : void SFHistogram(SplineFont *sf,int layer, struct psdict *private, uint8 *selected,
     732             :         EncMap *map,enum hist_type which) {
     733             :     struct hist_dlg hist;
     734             :     GWindow gw;
     735             :     GRect pos;
     736             :     GWindowAttrs wattrs;
     737             :     GGadgetCreateData gcd[17], boxes[6], *hv[4][2], *butarray[9], *hvctls[5][5], *hvbody[3][4];
     738             :     GTextInfo label[17];
     739             :     int i,j;
     740             :     char binsize[20], barwidth[20], *primary, *secondary;
     741             :     FontRequest rq;
     742             :     int as, ds, ld;
     743             :     static unichar_t n9999[] = { '9', '9', '9', '9', 0 };
     744             :     static GFont *font = NULL;
     745             : 
     746           0 :     memset(&hist,0,sizeof(hist));
     747           0 :     hist.sf = sf;
     748           0 :     hist.layer = layer;
     749           0 :     hist.private = private;
     750           0 :     if ( private==NULL ) private = sf->private;
     751           0 :     hist.selected = selected;
     752           0 :     hist.which = which;
     753           0 :     hist.barwidth = 6;
     754           0 :     hist.sum_around = 0;
     755           0 :     switch ( which ) {
     756             :       case hist_hstem:
     757           0 :         hist.h = HistFindHStemWidths(sf,layer,selected,map);
     758           0 :       break;
     759             :       case hist_vstem:
     760           0 :         hist.h = HistFindVStemWidths(sf,layer,selected,map);
     761           0 :       break;
     762             :       case hist_blues:
     763           0 :         hist.h = HistFindBlues(sf,layer,selected,map);
     764           0 :       break;
     765             :     }
     766           0 :     HistFindMax(hist.h,hist.sum_around);
     767             : 
     768           0 :     if ( selected!=NULL )
     769           0 :         CheckSmallSelection(selected,map,sf);
     770             : 
     771           0 :     memset(&wattrs,0,sizeof(wattrs));
     772           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
     773           0 :     wattrs.event_masks = ~(1<<et_charup);
     774           0 :     wattrs.restrict_input_to_me = 1;
     775           0 :     wattrs.undercursor = 1;
     776           0 :     wattrs.cursor = ct_pointer;
     777           0 :     wattrs.utf8_window_title =  which==hist_hstem?_("HStem") :
     778             :                                               which==hist_vstem?_("VStem"):
     779             :                                                           _("Blues");
     780           0 :     wattrs.is_dlg = true;
     781           0 :     pos.x = pos.y = 0;
     782           0 :     pos.width = GGadgetScale(GDrawPointsToPixels(NULL,210));
     783           0 :     hist.yoff = GDrawPointsToPixels(NULL,120);
     784           0 :     pos.height = pos.width + hist.yoff;
     785           0 :     hist.gw = gw = GDrawCreateTopWindow(NULL,&pos,hist_e_h,&hist,&wattrs);
     786             : 
     787           0 :     if ( font == NULL ) {
     788           0 :         memset(&rq,0,sizeof(rq));
     789           0 :         rq.utf8_family_name = SANS_UI_FAMILIES;
     790           0 :         rq.point_size = 10;
     791           0 :         rq.weight = 400;
     792           0 :         font = GDrawInstanciateFont(NULL,&rq);
     793           0 :         font = GResourceFindFont("Histogram.Font",font);
     794             :     }
     795           0 :     hist.font = font;
     796           0 :     GDrawWindowFontMetrics(gw,hist.font,&as,&ds,&ld);
     797           0 :     hist.fh = as+ds; hist.as = as;
     798             : 
     799           0 :     GDrawSetFont(gw,hist.font);
     800           0 :     hist.x = 10+GDrawGetTextWidth(gw,n9999,-1);
     801           0 :     hist.hwidth = pos.width - 2*hist.x;
     802           0 :     hist.y = 10; hist.hheight = pos.width-20;
     803             : 
     804           0 :     memset(&gcd,0,sizeof(gcd));
     805           0 :     memset(&label,0,sizeof(label));
     806           0 :     memset(&boxes,0,sizeof(boxes));
     807             : 
     808           0 :     i=0;
     809           0 :     gcd[i].gd.pos.width = hist.x; gcd[i].gd.pos.height = 200;
     810           0 :     gcd[i].gd.flags = gg_enabled|gg_visible|gg_pos_in_pixels;
     811           0 :     gcd[i].gd.cid = CID_LeftSide;
     812           0 :     gcd[i].gd.u.drawable_e_h = leftside_e_h;
     813           0 :     gcd[i++].creator = GDrawableCreate;
     814           0 :     hvbody[0][0] = &gcd[i-1];
     815             : 
     816           0 :     gcd[i].gd.pos.width = hist.hwidth+1; gcd[i].gd.pos.height = 200;
     817           0 :     gcd[i].gd.flags = gg_enabled|gg_visible|gg_pos_in_pixels;
     818           0 :     gcd[i].gd.cid = CID_Histogram;
     819           0 :     gcd[i].gd.u.drawable_e_h = histogram_e_h;
     820           0 :     gcd[i++].creator = GDrawableCreate;
     821           0 :     hvbody[0][1] = &gcd[i-1];
     822             : 
     823           0 :     gcd[i].gd.pos.width = hist.x; gcd[i].gd.pos.height = 200;
     824           0 :     gcd[i].gd.flags = gg_enabled|gg_visible|gg_pos_in_pixels;
     825           0 :     gcd[i].gd.cid = CID_RightSide;
     826           0 :     gcd[i].gd.u.drawable_e_h = rightside_e_h;
     827           0 :     gcd[i++].creator = GDrawableCreate;
     828           0 :     hvbody[0][2] = &gcd[i-1];
     829           0 :     hvbody[0][3] = NULL;
     830             : 
     831           0 :     hvbody[1][0] = GCD_Glue;
     832           0 :     gcd[i].gd.pos.width = hist.hwidth+1;
     833           0 :     gcd[i].gd.flags = gg_enabled|gg_visible|gg_pos_in_pixels;
     834           0 :     gcd[i].gd.cid = CID_ScrollBar;
     835           0 :     gcd[i++].creator = GScrollBarCreate;
     836           0 :     hvbody[1][1] = &gcd[i-1];
     837           0 :     hvbody[1][2] = GCD_Glue;
     838           0 :     hvbody[1][3] = NULL;
     839           0 :     hvbody[2][0] = NULL;
     840             : 
     841           0 :     boxes[2].gd.flags = gg_enabled|gg_visible;
     842           0 :     boxes[2].gd.u.boxelements = &hvbody[0][0];
     843           0 :     boxes[2].creator = GHVBoxCreate;
     844             : 
     845           0 :     label[i].text = (unichar_t *) _("Sum Around:");
     846           0 :     label[i].text_is_1byte = true;
     847           0 :     gcd[i].gd.label = &label[i];
     848           0 :     gcd[i].gd.flags = gg_enabled|gg_visible;
     849           0 :     gcd[i].gd.cid = CID_SumAroundL;
     850           0 :     gcd[i++].creator = GLabelCreate;
     851           0 :     hvctls[0][0] = &gcd[i-1];
     852             : 
     853           0 :     sprintf(binsize,"%d", hist.sum_around);
     854           0 :     label[i].text = (unichar_t *) binsize;
     855           0 :     label[i].text_is_1byte = true;
     856           0 :     gcd[i].gd.label = &label[i];
     857           0 :     gcd[i].gd.pos.width = 30;
     858           0 :     gcd[i].gd.flags = gg_enabled|gg_visible;
     859           0 :     gcd[i].gd.cid = CID_SumAround;
     860           0 :     gcd[i++].creator = GTextFieldCreate;
     861           0 :     hvctls[0][1] = &gcd[i-1];
     862             : 
     863           0 :     label[i].text = (unichar_t *) _("Bar Width:");
     864           0 :     label[i].text_is_1byte = true;
     865           0 :     gcd[i].gd.label = &label[i];
     866           0 :     gcd[i].gd.flags = gg_enabled|gg_visible;
     867           0 :     gcd[i].gd.cid = CID_BarWidthL;
     868           0 :     gcd[i++].creator = GLabelCreate;
     869           0 :     hvctls[0][2] = &gcd[i-1];
     870             : 
     871           0 :     sprintf(barwidth,"%d", hist.barwidth);
     872           0 :     label[i].text = (unichar_t *) barwidth;
     873           0 :     label[i].text_is_1byte = true;
     874           0 :     gcd[i].gd.label = &label[i];
     875           0 :     gcd[i].gd.pos.width = 30;
     876           0 :     gcd[i].gd.flags = gg_enabled|gg_visible;
     877           0 :     gcd[i].gd.cid = CID_BarWidth;
     878           0 :     gcd[i++].creator = GTextFieldCreate;
     879           0 :     hvctls[0][3] = &gcd[i-1];
     880           0 :     hvctls[0][4] = NULL;
     881             : 
     882           0 :     label[i].text = (unichar_t *) _("BlueValues come in pairs. Select another.");
     883           0 :     label[i].text_is_1byte = true;
     884           0 :     label[i].fg = 0xff0000;
     885           0 :     label[i].bg = GDrawGetDefaultBackground(NULL);
     886           0 :     gcd[i].gd.label = &label[i];
     887           0 :     gcd[i].gd.flags = gg_enabled;
     888           0 :     gcd[i].gd.cid = CID_BlueMsg;
     889           0 :     gcd[i++].creator = GLabelCreate;
     890           0 :     hvctls[1][0] = &gcd[i-1];
     891           0 :     hvctls[1][1] = hvctls[1][2] = hvctls[1][3] = GCD_ColSpan;
     892           0 :     hvctls[1][4] = NULL;
     893             : 
     894           0 :     switch ( which ) {
     895             :       case hist_hstem:
     896           0 :         label[i].text = (unichar_t *) "StdHW:";
     897           0 :         label[i+2].text = (unichar_t *) "StemSnapH:";
     898           0 :         primary = "StdHW"; secondary = "StemSnapH";
     899           0 :       break;
     900             :       case hist_vstem:
     901           0 :         label[i].text = (unichar_t *) "StdVW:";
     902           0 :         label[i+2].text = (unichar_t *) "StemSnapV:";
     903           0 :         primary = "StdVW"; secondary = "StemSnapV";
     904           0 :       break;
     905             :       case hist_blues:
     906           0 :         label[i].text = (unichar_t *) "BlueValues:";
     907           0 :         label[i+2].text = (unichar_t *) "OtherBlues:";
     908           0 :         primary = "BlueValues"; secondary = "OtherBlues";
     909           0 :       break;
     910             :     }
     911           0 :     label[i].text_is_1byte = true;
     912           0 :     gcd[i].gd.label = &label[i];
     913           0 :     gcd[i].gd.pos.x = 5; gcd[i].gd.pos.y = gcd[i-2].gd.pos.y+28; 
     914           0 :     gcd[i].gd.flags = gg_enabled|gg_visible;
     915           0 :     gcd[i].gd.cid = CID_MainValL;
     916           0 :     gcd[i++].creator = GLabelCreate;
     917           0 :     hvctls[2][0] = &gcd[i-1];
     918             : 
     919           0 :     if ( private!=NULL && (j=PSDictFindEntry(private,primary))!=-1 ) {
     920           0 :         label[i].text = (unichar_t *) private->values[j];
     921           0 :         label[i].text_is_1byte = true;
     922           0 :         gcd[i].gd.label = &label[i];
     923             :     }
     924           0 :     gcd[i].gd.pos.x = 64; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y-4;
     925           0 :     gcd[i].gd.pos.width = 140;
     926           0 :     gcd[i].gd.flags = gg_enabled|gg_visible;
     927           0 :     gcd[i].gd.cid = CID_MainVal;
     928           0 :     gcd[i++].creator = GTextFieldCreate;
     929           0 :     hvctls[2][1] = &gcd[i-1];
     930           0 :     hvctls[2][2] = hvctls[2][3] = GCD_ColSpan;
     931           0 :     hvctls[2][4] = NULL;
     932             : 
     933           0 :     label[i].text_is_1byte = true;
     934           0 :     gcd[i].gd.label = &label[i];
     935           0 :     gcd[i].gd.pos.x = 5; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y+28; 
     936           0 :     gcd[i].gd.flags = gg_enabled|gg_visible;
     937           0 :     gcd[i].gd.cid = CID_SecondaryValL;
     938           0 :     gcd[i++].creator = GLabelCreate;
     939           0 :     hvctls[3][0] = &gcd[i-1];
     940             : 
     941           0 :     if ( private!=NULL && (j=PSDictFindEntry(private,secondary))!=-1 ) {
     942           0 :         label[i].text = (unichar_t *) private->values[j];
     943           0 :         label[i].text_is_1byte = true;
     944           0 :         gcd[i].gd.label = &label[i];
     945             :     }
     946           0 :     gcd[i].gd.pos.x = 64; gcd[i].gd.pos.y = gcd[i-1].gd.pos.y-4;
     947           0 :     gcd[i].gd.pos.width = 140;
     948           0 :     gcd[i].gd.flags = gg_enabled|gg_visible;
     949           0 :     gcd[i].gd.cid = CID_SecondaryVal;
     950           0 :     gcd[i++].creator = GTextFieldCreate;
     951           0 :     hvctls[3][1] = &gcd[i-1];
     952           0 :     hvctls[3][2] = hvctls[3][3] = GCD_ColSpan;
     953           0 :     hvctls[3][4] = NULL;
     954           0 :     hvctls[4][0] = NULL;
     955             : 
     956           0 :     boxes[3].gd.flags = gg_enabled|gg_visible;
     957           0 :     boxes[3].gd.u.boxelements = &hvctls[0][0];
     958           0 :     boxes[3].creator = GHVBoxCreate;
     959             : 
     960           0 :     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_default;
     961           0 :     label[i].text = (unichar_t *) _("_OK");
     962           0 :     label[i].text_is_1byte = true;
     963           0 :     label[i].text_in_resource = true;
     964           0 :     gcd[i].gd.label = &label[i];
     965           0 :     gcd[i].gd.cid = CID_OK;
     966           0 :     gcd[i++].creator = GButtonCreate;
     967           0 :     butarray[0] = GCD_Glue; butarray[1] = &gcd[i-1]; butarray[2] = GCD_Glue; butarray[3] = GCD_Glue;
     968             : 
     969           0 :     gcd[i].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
     970           0 :     label[i].text = (unichar_t *) _("_Cancel");
     971           0 :     label[i].text_is_1byte = true;
     972           0 :     label[i].text_in_resource = true;
     973           0 :     gcd[i].gd.label = &label[i];
     974           0 :     gcd[i].gd.mnemonic = 'C';
     975           0 :     gcd[i].gd.cid = CID_Cancel;
     976           0 :     gcd[i++].creator = GButtonCreate;
     977           0 :     butarray[4] = GCD_Glue; butarray[5] = &gcd[i-1]; butarray[6] = GCD_Glue; butarray[7] = NULL;
     978             : 
     979           0 :     boxes[4].gd.flags = gg_enabled|gg_visible;
     980           0 :     boxes[4].gd.u.boxelements = &butarray[0];
     981           0 :     boxes[4].creator = GHBoxCreate;
     982             : 
     983           0 :     hv[0][0] = &boxes[2]; hv[0][1] = NULL;
     984           0 :     hv[1][0] = &boxes[3]; hv[1][1] = NULL;
     985           0 :     hv[2][0] = &boxes[4]; hv[2][1] = NULL; hv[3][0] = NULL;
     986             : 
     987           0 :     boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
     988           0 :     boxes[0].gd.flags = gg_enabled|gg_visible;
     989           0 :     boxes[0].gd.u.boxelements = &hv[0][0];
     990           0 :     boxes[0].creator = GHVGroupCreate;
     991             : 
     992           0 :     GGadgetsCreate(gw,boxes);
     993             : 
     994           0 :     GHVBoxSetExpandableRow(boxes[0].ret,0);
     995           0 :     GHVBoxSetExpandableCol(boxes[2].ret,1);
     996           0 :     GHVBoxSetExpandableRow(boxes[2].ret,0);
     997           0 :     GHVBoxSetExpandableCol(boxes[3].ret,1);
     998           0 :     GHVBoxSetExpandableCol(boxes[4].ret,gb_expandglue);
     999             : 
    1000           0 :     hist.hoff = 0;
    1001           0 :     if ( hist.h->low>0 )
    1002           0 :         hist.hoff = hist.h->low;
    1003           0 :     GScrollBarSetPos(GWidgetGetControl(hist.gw,CID_ScrollBar),hist.hoff);
    1004           0 :     HistRefigureSB(&hist);
    1005             : 
    1006           0 :     GHVBoxFitWindow(boxes[0].ret);
    1007           0 :     GDrawSetVisible(gw,true);
    1008           0 :     while ( !hist.done )
    1009           0 :         GDrawProcessOneEvent(NULL);
    1010           0 :     GDrawDestroyWindow(gw);
    1011             : 
    1012           0 :     HistDataFree(hist.h);
    1013           0 : }

Generated by: LCOV version 1.10