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

          Line data    Source code
       1             : /* Copyright (C) 2000-2012 by George Williams */
       2             : /*
       3             :  * Redistribution and use in source and binary forms, with or without
       4             :  * modification, are permitted provided that the following conditions are met:
       5             : 
       6             :  * Redistributions of source code must retain the above copyright notice, this
       7             :  * list of conditions and the following disclaimer.
       8             : 
       9             :  * Redistributions in binary form must reproduce the above copyright notice,
      10             :  * this list of conditions and the following disclaimer in the documentation
      11             :  * and/or other materials provided with the distribution.
      12             : 
      13             :  * The name of the author may not be used to endorse or promote products
      14             :  * derived from this software without specific prior written permission.
      15             : 
      16             :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
      17             :  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
      18             :  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
      19             :  * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
      20             :  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
      21             :  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
      22             :  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
      23             :  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      24             :  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
      25             :  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
      26             :  */
      27             : #include "cvundoes.h"
      28             : #include "fontforgeui.h"
      29             : #include "fvfonts.h"
      30             : #include "splinestroke.h"
      31             : #include "splineutil.h"
      32             : #include "splineutil2.h"
      33             : #include <ustring.h>
      34             : #include <utype.h>
      35             : #include <gkeysym.h>
      36             : #include <math.h>
      37             : #define PI      3.1415926535897932
      38             : 
      39             : extern GDevEventMask input_em[];
      40             : extern const int input_em_cnt;
      41             : 
      42             : #define CID_ButtCap     1001
      43             : #define CID_RoundCap    1002
      44             : #define CID_SquareCap   1003
      45             : #define CID_BevelJoin   1004
      46             : #define CID_RoundJoin   1005
      47             : #define CID_MiterJoin   1006
      48             : #define CID_Width       1007
      49             : #define CID_MinorAxis   1008
      50             : #define CID_PenAngle    1009
      51             : #define CID_Circle      1010
      52             : #define CID_Caligraphic 1011
      53             : #define CID_Polygon     1012
      54             : #define CID_LineCapTxt  1014
      55             : #define CID_LineJoinTxt 1015
      56             : #define CID_MinorAxisTxt 1016
      57             : #define CID_PenAngleTxt 1017
      58             :         /* For Kanou (& me) */
      59             : #define CID_RmInternal  1019
      60             : #define CID_RmExternal  1020
      61             : /* #define CID_CleanupSelfIntersect     1021 */
      62             : #define CID_Apply       1022
      63             : #define CID_Nib         1023
      64             : #define CID_WidthTxt    1024
      65             : #define CID_TopBox      1025
      66             : 
      67             :         /* For freehand */
      68             : #define CID_CenterLine  1031
      69             : 
      70           0 : static void CVStrokeIt(void *_cv, StrokeInfo *si, int justapply) {
      71           0 :     CharView *cv = _cv;
      72             :     int anypoints;
      73           0 :     SplineSet *spl, *prev, *head=NULL, *cur, *snext;
      74             : 
      75           0 :     if ( cv->b.layerheads[cv->b.drawmode]->undoes!=NULL &&
      76           0 :             cv->b.layerheads[cv->b.drawmode]->undoes->undotype==ut_tstate )
      77           0 :         CVDoUndo(&cv->b);
      78             : 
      79           0 :     if ( justapply )
      80           0 :         CVPreserveTState(cv);
      81             :     else
      82           0 :         CVPreserveState(&cv->b);
      83           0 :     if ( CVAnySel(cv,&anypoints,NULL,NULL,NULL) && anypoints ) {
      84           0 :         prev = NULL;
      85           0 :         for ( spl= cv->b.layerheads[cv->b.drawmode]->splines; spl!=NULL; spl = snext ) {
      86           0 :             snext = spl->next;
      87           0 :             if ( PointListIsSelected(spl)) {
      88           0 :                 spl->next = NULL;
      89           0 :                 cur = SplineSetStroke(spl,si,cv->b.layerheads[cv->b.drawmode]->order2);
      90           0 :                 if ( cur!=NULL ) {
      91           0 :                     if ( prev==NULL )
      92           0 :                         cv->b.layerheads[cv->b.drawmode]->splines=cur;
      93             :                     else
      94           0 :                         prev->next = cur;
      95           0 :                     while ( cur->next ) cur=cur->next;
      96           0 :                     cur->next = snext;
      97           0 :                     prev = cur;
      98             :                 } else {
      99           0 :                     if ( prev==NULL )
     100           0 :                         cv->b.layerheads[cv->b.drawmode]->splines=snext;
     101             :                     else
     102           0 :                         prev->next = snext;
     103             :                 }
     104           0 :                 spl->next = NULL;
     105           0 :                 SplinePointListMDFree(cv->b.sc,spl);
     106             :             } else
     107           0 :                 prev = spl;
     108             :         }
     109             :     } else {
     110           0 :         head = SplineSetStroke(cv->b.layerheads[cv->b.drawmode]->splines,si,
     111           0 :                 cv->b.layerheads[cv->b.drawmode]->order2);
     112           0 :         SplinePointListsFree( cv->b.layerheads[cv->b.drawmode]->splines );
     113           0 :         cv->b.layerheads[cv->b.drawmode]->splines = head;
     114             :     }
     115           0 :     CVCharChangedUpdate(&cv->b);
     116           0 : }
     117             : 
     118           0 : static int _Stroke_OK(StrokeDlg *sd,int isapply) {
     119             :     StrokeInfo *si, strokeinfo;
     120             :     int err;
     121           0 :     GWindow sw = sd->gw;
     122             :     char *msg;
     123             : 
     124           0 :     err = false;
     125           0 :     if ( (si = sd->si)==NULL ) {
     126           0 :         memset(&strokeinfo,'\0',sizeof(strokeinfo));
     127           0 :         si = &strokeinfo;
     128             :     }
     129           0 :     si->stroke_type = si_std;
     130           0 :     if ( GGadgetIsChecked( GWidgetGetControl(sw,CID_Caligraphic)) )
     131           0 :         si->stroke_type = si_caligraphic;
     132           0 :     else if ( GGadgetIsChecked( GWidgetGetControl(sw,CID_Polygon)) )
     133           0 :         si->stroke_type = si_poly;
     134           0 :     else if ( si!= &strokeinfo &&
     135           0 :             GGadgetIsChecked( GWidgetGetControl(sw,CID_CenterLine)) )
     136           0 :         si->stroke_type = si_centerline;
     137           0 :     if ( si->stroke_type == si_poly ) {
     138           0 :         si->poly = sd->sc_stroke.layers[ly_fore].splines;
     139           0 :         if ( sd->sc_stroke.layers[ly_fore].refs != NULL ) {
     140           0 :             ff_post_error(_("No References"),_("No references allowed in a pen."));
     141           0 :             err = true;
     142           0 :         } else if ( si->poly == NULL ) {
     143           0 :             ff_post_error(_("Nothing specified"),_("Please draw a convex polygon in the drawing area."));
     144           0 :             err = true;
     145             :         } else {
     146             :             SplineSet *ss;
     147             :             SplinePoint *sp;
     148             :             BasePoint pts[256];
     149             :             int cnt, selectall;
     150           0 :             for ( ss=si->poly ; ss!=NULL && !err; ss=ss->next ) {
     151           0 :                 for ( sp=ss->first;;) {
     152           0 :                     sp->selected = false;
     153           0 :                     if ( sp->next==NULL )
     154           0 :                 break;
     155           0 :                     sp = sp->next->to;
     156           0 :                     if ( sp==ss->first )
     157           0 :                 break;
     158           0 :                 }
     159             :             }
     160           0 :             msg = NULL;
     161           0 :             selectall = false;
     162           0 :             for ( ss=si->poly ; ss!=NULL && !err; ss=ss->next ) {
     163           0 :                 if ( ss->first->prev==NULL ) {
     164           0 :                     msg = _("The selected contour is open, but it must be a convex polygon.");
     165           0 :                     err = selectall = true;
     166             :                 } else {
     167           0 :                     for ( sp=ss->first, cnt=0; cnt<255; ++cnt ) {
     168           0 :                         pts[cnt] = sp->me;
     169           0 :                         if ( !sp->next->knownlinear ) {
     170           0 :                             sp->selected = true;
     171           0 :                             sp->next->to->selected = true;
     172           0 :                             err = true;
     173           0 :                             msg = _("The selected spline has curved edges, but it must be a convex polygon (with straight edges).");
     174           0 :                     break;
     175             :                         }
     176           0 :                         sp = sp->next->to;
     177           0 :                         if ( sp==ss->first ) {
     178           0 :                             ++cnt;
     179           0 :                     break;
     180             :                         }
     181             :                     }
     182           0 :                     if ( err )
     183             :                         /* Already handled */;
     184           0 :                     else if ( cnt==255 ) {
     185           0 :                         msg = _("There are too many vertices on this polygon.");
     186           0 :                         err = selectall = true;
     187             :                     } else {
     188             :                         enum PolyType pt;
     189             :                         int badindex;
     190           0 :                         pt = PolygonIsConvex(pts,cnt,&badindex);
     191           0 :                         if ( pt==Poly_Line ) {
     192           0 :                             msg = _("This is a line; it must enclose some area.");
     193           0 :                             err = selectall = true;
     194           0 :                         } else if ( pt==Poly_TooFewPoints ) {
     195           0 :                             msg = _("There aren't enough vertices to be a polygon.");
     196           0 :                             err = selectall = true;
     197           0 :                         } else if ( pt!=Poly_Convex ) {
     198           0 :                             err = true;
     199           0 :                             if ( pt==Poly_PointOnEdge )
     200           0 :                                 msg = _("There are at least 3 colinear vertices. Please remove (Edit->Merge) the selected point.");
     201             :                             else
     202           0 :                                 msg = _("The selected vertex makes this a concave polygon. Please remove (Edit->Merge) it.");
     203           0 :                             for ( sp=ss->first, cnt=0; cnt<255; ++cnt ) {
     204           0 :                                 if ( cnt==badindex ) {
     205           0 :                                     sp->selected = true;
     206           0 :                             break;
     207             :                                 }
     208           0 :                                 sp = sp->next->to;
     209           0 :                                 if ( sp==ss->first )
     210           0 :                             break;
     211             :                             }
     212             :                         }
     213             :                     }
     214             :                 }
     215           0 :                 if ( selectall ) {
     216           0 :                     for ( sp=ss->first;;) {
     217           0 :                         sp->selected = true;
     218           0 :                         if ( sp->next==NULL )
     219           0 :                     break;
     220           0 :                         sp = sp->next->to;
     221           0 :                         if ( sp==ss->first )
     222           0 :                     break;
     223           0 :                     }
     224             :                 }
     225           0 :                 if ( err ) {
     226           0 :                     GDrawRequestExpose(sd->cv_stroke.v,NULL,false);
     227           0 :                     ff_post_error(_("Not a convex polygon"),msg);
     228           0 :             break;
     229             :                 }
     230             :             }
     231             :         }
     232           0 :         GDrawRequestExpose(sd->cv_stroke.v,NULL,false);
     233           0 :     } else if ( si->stroke_type==si_std || si->stroke_type==si_caligraphic ) {
     234           0 :         si->cap = GGadgetIsChecked( GWidgetGetControl(sw,CID_ButtCap))?lc_butt:
     235           0 :                 GGadgetIsChecked( GWidgetGetControl(sw,CID_RoundCap))?lc_round:
     236             :                 lc_square;
     237           0 :         si->join = GGadgetIsChecked( GWidgetGetControl(sw,CID_BevelJoin))?lj_bevel:
     238           0 :                 GGadgetIsChecked( GWidgetGetControl(sw,CID_RoundJoin))?lj_round:
     239             :                 lj_miter;
     240           0 :         si->radius = GetReal8(sw,CID_Width,_("Stroke _Width:"),&err)/2;
     241           0 :     if (si->radius == 0) {
     242           0 :         ff_post_error(_("Bad Value"), _("Stroke width cannot be zero"));
     243           0 :         err = true;
     244             :     }
     245           0 :         if ( si->radius<0 ) si->radius = -si->radius;       /* Behavior is said to be very slow (but correct) for negative strokes */
     246           0 :         si->penangle = GetReal8(sw,CID_PenAngle,_("Pen _Angle:"),&err);
     247           0 :         if ( si->penangle>180 || si->penangle < -180 ) {
     248           0 :             si->penangle = fmod(si->penangle,360);
     249           0 :             if ( si->penangle>180 )
     250           0 :                 si->penangle -= 360;
     251           0 :             else if ( si->penangle<-180 )
     252           0 :                 si->penangle += 360;
     253             :         }
     254           0 :         si->penangle *= 3.1415926535897932/180;
     255           0 :         si->minorradius = GetReal8(sw,CID_MinorAxis,_("Minor A_xis:"),&err)/2;
     256             :     }
     257           0 :     si->removeinternal = GGadgetIsChecked( GWidgetGetControl(sw,CID_RmInternal));
     258           0 :     si->removeexternal = GGadgetIsChecked( GWidgetGetControl(sw,CID_RmExternal));
     259             : /*      si->removeoverlapifneeded = GGadgetIsChecked( GWidgetGetControl(sw,CID_CleanupSelfIntersect)); */
     260           0 :     if ( si->removeinternal && si->removeexternal ) {
     261           0 :         ff_post_error(_("Bad Value"),_("Removing both the internal and the external contours makes no sense"));
     262           0 :         err = true;
     263             :     }
     264           0 :     if ( err )
     265           0 : return( true );
     266           0 :     if ( sd->strokeit!=NULL )
     267           0 :         (sd->strokeit)(sd->cv,si,isapply);
     268           0 :     sd->done = !isapply;
     269           0 : return( true );
     270             : }
     271             : 
     272           0 : static int Stroke_OK(GGadget *g, GEvent *e) {
     273             : 
     274           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     275           0 :         GWindow sw = GGadgetGetWindow(g);
     276           0 :         StrokeDlg *sd = (StrokeDlg *) ((CharViewBase *) GDrawGetUserData(sw))->container;
     277           0 : return( _Stroke_OK(sd,GGadgetGetCid(g) == CID_Apply));
     278             :     }
     279           0 : return( true );
     280             : }
     281             : 
     282           0 : static void _Stroke_Cancel(StrokeDlg *sd ) {
     283           0 :     if ( sd->strokeit==CVStrokeIt && sd->cv->b.layerheads[sd->cv->b.drawmode]->undoes!=NULL &&
     284           0 :             sd->cv->b.layerheads[sd->cv->b.drawmode]->undoes->undotype==ut_tstate )
     285           0 :         CVDoUndo(&sd->cv->b);
     286           0 :     sd->done = true;
     287           0 : }
     288             : 
     289           0 : static int Stroke_Cancel(GGadget *g, GEvent *e) {
     290           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
     291           0 :         StrokeDlg *sd = (StrokeDlg *) ((CharViewBase *) GDrawGetUserData(GGadgetGetWindow(g)))->container;
     292           0 :         _Stroke_Cancel(sd);
     293             :     }
     294           0 : return( true );
     295             : }
     296             : 
     297           0 : static void Stroke_ShowNib(StrokeDlg *sd) {
     298             :     SplineSet *ss;
     299             :     real transform[6];
     300             :     double angle,c,s, width, height;
     301           0 :     int err=0;
     302             : 
     303           0 :     SplinePointListsFree(sd->dummy_sf.grid.splines);
     304           0 :     sd->dummy_sf.grid.splines = NULL;
     305           0 :     if ( GGadgetIsChecked(GWidgetGetControl(sd->gw,CID_Polygon)) ) {
     306           0 :         if ( sd->sc_stroke.layers[ly_fore].splines==NULL ) {
     307           0 :             sd->sc_stroke.layers[ly_fore].splines = sd->old_poly;
     308           0 :             sd->old_poly = NULL;
     309             :         }
     310             :     } else {
     311           0 :         if ( sd->old_poly==NULL ) {
     312           0 :             sd->old_poly = sd->sc_stroke.layers[ly_fore].splines;
     313           0 :             sd->sc_stroke.layers[ly_fore].splines = NULL;
     314             :         }
     315             :     }
     316           0 :     if ( GGadgetIsChecked(GWidgetGetControl(sd->gw,CID_Circle)) ||
     317           0 :             GGadgetIsChecked(GWidgetGetControl(sd->gw,CID_Caligraphic)) ) {
     318           0 :         ss = UnitShape( GGadgetIsChecked(GWidgetGetControl(sd->gw,CID_Caligraphic)) );
     319           0 :         memset(transform,0,sizeof(transform));
     320           0 :         width = GetCalmReal8(sd->gw,CID_Width,"",&err)/2;
     321           0 :         height = GetCalmReal8(sd->gw,CID_MinorAxis,"",&err)/2;
     322           0 :         angle = GetCalmReal8(sd->gw,CID_PenAngle,"",&err)*PI/180;
     323           0 :         c = cos(angle); s=sin(angle);
     324           0 :         transform[0] = transform[3] = c;
     325           0 :         transform[1] = s; transform[2] = -s;
     326           0 :         transform[0] *= width;
     327           0 :         transform[1] *= width;
     328           0 :         transform[2] *= height;
     329           0 :         transform[3] *= height;
     330           0 :         SplinePointListTransform(ss,transform,tpt_AllPoints);
     331           0 :         sd->dummy_sf.grid.splines = ss;
     332             :     }
     333           0 :     GDrawRequestExpose(sd->cv_stroke.v,NULL,false);
     334           0 : }
     335             : 
     336           0 : static void StrokeSetup(StrokeDlg *sd, enum si_type stroke_type) {
     337             : 
     338           0 :     sd->dontexpand = ( stroke_type==si_centerline );
     339             : 
     340           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_LineCapTxt), stroke_type==si_std);
     341           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_ButtCap), stroke_type==si_std);
     342           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_RoundCap), stroke_type==si_std);
     343           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_SquareCap), stroke_type==si_std);
     344           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_LineJoinTxt), stroke_type==si_std);
     345           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_BevelJoin), stroke_type==si_std);
     346           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_RoundJoin), stroke_type==si_std);
     347           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_MiterJoin), stroke_type==si_std);
     348             : 
     349           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_WidthTxt    ), stroke_type==si_std || stroke_type==si_caligraphic);
     350           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_Width       ), stroke_type==si_std || stroke_type==si_caligraphic);
     351           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_MinorAxisTxt), stroke_type==si_std || stroke_type==si_caligraphic);
     352           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_MinorAxis   ), stroke_type==si_std || stroke_type==si_caligraphic);
     353           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_PenAngleTxt ), stroke_type==si_std || stroke_type==si_caligraphic);
     354           0 :     GGadgetSetEnabled(GWidgetGetControl(sd->gw,CID_PenAngle    ), stroke_type==si_std || stroke_type==si_caligraphic);
     355           0 : }
     356             : 
     357           0 : static int Stroke_TextChanged(GGadget *g, GEvent *e) {
     358           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
     359           0 :         StrokeDlg *sd = (StrokeDlg *) ((CharViewBase *) GDrawGetUserData(GGadgetGetWindow(g)))->container;
     360           0 :         Stroke_ShowNib(sd);
     361             :     }
     362           0 : return( true );
     363             : }
     364             : 
     365           0 : static int Stroke_CenterLine(GGadget *g, GEvent *e) {
     366           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
     367           0 :         StrokeDlg *sd = (StrokeDlg *) ((CharViewBase *) GDrawGetUserData(GGadgetGetWindow(g)))->container;
     368           0 :         StrokeSetup(sd,si_centerline);
     369           0 :         Stroke_ShowNib(sd);
     370             :     }
     371           0 : return( true );
     372             : }
     373             : 
     374           0 : static int Stroke_Caligraphic(GGadget *g, GEvent *e) {
     375           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
     376           0 :         StrokeDlg *sd = (StrokeDlg *) ((CharViewBase *) GDrawGetUserData(GGadgetGetWindow(g)))->container;
     377           0 :         StrokeSetup(sd,si_caligraphic);
     378           0 :         Stroke_ShowNib(sd);
     379             :     }
     380           0 : return( true );
     381             : }
     382             : 
     383           0 : static int Stroke_Stroke(GGadget *g, GEvent *e) {
     384           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
     385           0 :         StrokeDlg *sd = (StrokeDlg *) ((CharViewBase *) GDrawGetUserData(GGadgetGetWindow(g)))->container;
     386           0 :         StrokeSetup(sd,si_std);
     387           0 :         Stroke_ShowNib(sd);
     388             :     }
     389           0 : return( true );
     390             : }
     391             : 
     392           0 : static int Stroke_Polygon(GGadget *g, GEvent *e) {
     393           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
     394           0 :         StrokeDlg *sd = (StrokeDlg *) ((CharViewBase *) GDrawGetUserData(GGadgetGetWindow(g)))->container;
     395           0 :         StrokeSetup(sd,si_poly);
     396           0 :         Stroke_ShowNib(sd);
     397             :     }
     398           0 : return( true );
     399             : }
     400             : 
     401           0 : static void Stroke_SubResize(StrokeDlg *sd, GEvent *event) {
     402             :     int width, height;
     403             : 
     404           0 :     if ( !event->u.resize.sized )
     405           0 : return;
     406             : 
     407           0 :     width = event->u.resize.size.width;
     408           0 :     height = event->u.resize.size.height;
     409           0 :     if ( width!=sd->cv_width || height!=sd->cv_height ) {
     410           0 :         sd->cv_width = width; sd->cv_height = height;
     411           0 :         GDrawResize(sd->cv_stroke.gw,width,height);
     412             :     }
     413             : 
     414           0 :     GDrawSync(NULL);
     415           0 :     GDrawProcessPendingEvents(NULL);
     416             : }
     417             : 
     418           0 : static void Stroke_Draw(StrokeDlg *sd, GWindow pixmap, GEvent *event) {
     419             :     GRect r,pos;
     420             : 
     421           0 :     GGadgetGetSize(GWidgetGetControl(sd->gw,CID_Nib),&pos);
     422           0 :     r.x = pos.x-1; r.y = pos.y-1;
     423           0 :     r.width = pos.width+1; r.height = pos.height+1;
     424           0 :     GDrawDrawRect(pixmap,&r,0);
     425           0 : }
     426             : 
     427           0 : static void Stroke_MakeActive(StrokeDlg *sd,CharView *cv) {
     428             : 
     429           0 :     if ( sd==NULL )
     430           0 : return;
     431           0 :     cv->inactive = false;
     432           0 :     GDrawSetUserData(sd->gw,cv);
     433           0 :     GDrawRequestExpose(cv->v,NULL,false);
     434           0 :     GDrawRequestExpose(sd->gw,NULL,false);
     435             : }
     436             : 
     437           0 : static void Stroke_Char(StrokeDlg *sd, GEvent *event) {
     438             : 
     439           0 :     if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     440           0 :         help("elementmenu.html#Expand");
     441           0 : return;
     442           0 :     } else if ( event->u.chr.keysym == GK_Return ) {
     443           0 :         _Stroke_OK(sd,false);
     444           0 : return;
     445           0 :     } else if ( event->u.chr.keysym == GK_Escape ) {
     446           0 :         _Stroke_Cancel(sd);
     447           0 : return;
     448             :     }
     449             : 
     450           0 :     CVChar((&sd->cv_stroke),event);
     451             : }
     452             : 
     453           0 : static void Stroke_DoClose(struct cvcontainer *cvc) {
     454           0 :     StrokeDlg *sd = (StrokeDlg *) cvc;
     455             : 
     456             :      {
     457           0 :         SplineChar *msc = &sd->sc_stroke;
     458           0 :         SplinePointListsFree(msc->layers[0].splines);
     459           0 :         SplinePointListsFree(msc->layers[1].splines);
     460           0 :         free( msc->layers );
     461             :     }
     462             : 
     463           0 :     sd->done = true;
     464           0 : }
     465             : 
     466           0 : static int stroke_sub_e_h(GWindow gw, GEvent *event) {
     467           0 :     StrokeDlg *sd = (StrokeDlg *) ((CharViewBase *) GDrawGetUserData(gw))->container;
     468             : 
     469           0 :     switch ( event->type ) {
     470             :       case et_resize:
     471           0 :         if ( event->u.resize.sized )
     472           0 :             Stroke_SubResize(sd,event);
     473           0 :       break;
     474             :       case et_char:
     475           0 :         Stroke_Char(sd,event);
     476           0 :       break;
     477             :       case et_mouseup: case et_mousedown: case et_mousemove:
     478           0 : return( false );
     479             :       break;
     480             :     }
     481           0 : return( true );
     482             : }
     483             : 
     484           0 : static int Stroke_Can_Navigate(struct cvcontainer *cvc, enum nav_type type) {
     485           0 : return( false );
     486             : }
     487             : 
     488           0 : static int Stroke_Can_Open(struct cvcontainer *cvc) {
     489           0 : return( false );
     490             : }
     491             : 
     492           0 : static SplineFont *SF_Of_Stroke(struct cvcontainer *foo) {
     493           0 : return( NULL );
     494             : }
     495             : 
     496             : struct cvcontainer_funcs stroke_funcs = {
     497             :     cvc_stroke,
     498             :     (void (*) (struct cvcontainer *cvc,CharViewBase *cv)) Stroke_MakeActive,
     499             :     (void (*) (struct cvcontainer *cvc,void *)) Stroke_Char,
     500             :     Stroke_Can_Navigate,
     501             :     NULL,
     502             :     Stroke_Can_Open,
     503             :     Stroke_DoClose,
     504             :     SF_Of_Stroke
     505             : };
     506             : 
     507             : 
     508           0 : static void StrokeInit(StrokeDlg *sd) {
     509             :     real transform[6];
     510             : 
     511             :     /*memset(sd,0,sizeof(*sd));*/
     512           0 :     sd->base.funcs = &stroke_funcs;
     513             : 
     514             :     {
     515           0 :         SplineChar *msc = (&sd->sc_stroke);
     516           0 :         CharView *mcv = (&sd->cv_stroke);
     517           0 :         msc->orig_pos = 0;
     518           0 :         msc->unicodeenc = -1;
     519           0 :         msc->name = "Nib";
     520           0 :         msc->parent = &sd->dummy_sf;
     521           0 :         msc->layer_cnt = 2;
     522           0 :         msc->layers = calloc(2,sizeof(Layer));
     523           0 :         msc->width = 200;
     524           0 :         LayerDefault(&msc->layers[0]);
     525           0 :         LayerDefault(&msc->layers[1]);
     526           0 :         sd->chars[0] = msc;
     527             : 
     528           0 :         mcv->b.sc = msc;
     529           0 :         mcv->b.layerheads[dm_fore] = &msc->layers[ly_fore];
     530           0 :         mcv->b.layerheads[dm_back] = &msc->layers[ly_back];
     531           0 :         mcv->b.layerheads[dm_grid] = &sd->dummy_sf.grid;
     532           0 :         mcv->b.drawmode = dm_fore;
     533           0 :         mcv->b.container = (struct cvcontainer *) sd;
     534           0 :         mcv->inactive = false;
     535             :     }
     536           0 :     sd->dummy_sf.glyphs = sd->chars;
     537           0 :     sd->dummy_sf.glyphcnt = sd->dummy_sf.glyphmax = 1;
     538           0 :     sd->dummy_sf.pfminfo.fstype = -1;
     539           0 :     sd->dummy_sf.pfminfo.stylemap = -1;
     540           0 :     sd->dummy_sf.fontname = sd->dummy_sf.fullname = sd->dummy_sf.familyname = "dummy";
     541           0 :     sd->dummy_sf.weight = "Medium";
     542           0 :     sd->dummy_sf.origname = "dummy";
     543           0 :     sd->dummy_sf.ascent = 200;
     544           0 :     sd->dummy_sf.descent = 200;
     545           0 :     sd->dummy_sf.layers = sd->layerinfo;
     546           0 :     sd->dummy_sf.layer_cnt = 2;
     547           0 :     sd->layerinfo[ly_back].order2 = false;
     548           0 :     sd->layerinfo[ly_back].name = _("Back");
     549           0 :     sd->layerinfo[ly_fore].order2 = false;
     550           0 :     sd->layerinfo[ly_fore].name = _("Fore");
     551           0 :     sd->dummy_sf.grid.order2 = false;
     552           0 :     sd->dummy_sf.anchor = NULL;
     553             : 
     554           0 :     sd->dummy_sf.fv = (FontViewBase *) &sd->dummy_fv;
     555           0 :     sd->dummy_fv.b.active_layer = ly_fore;
     556           0 :     sd->dummy_fv.b.sf = &sd->dummy_sf;
     557           0 :     sd->dummy_fv.b.selected = sd->sel;
     558           0 :     sd->dummy_fv.cbw = sd->dummy_fv.cbh = default_fv_font_size+1;
     559           0 :     sd->dummy_fv.magnify = 1;
     560             : 
     561           0 :     sd->dummy_fv.b.map = &sd->dummy_map;
     562           0 :     sd->dummy_map.map = sd->map;
     563           0 :     sd->dummy_map.backmap = sd->backmap;
     564           0 :     sd->dummy_map.enccount = sd->dummy_map.encmax = sd->dummy_map.backmax = 1;
     565           0 :     sd->dummy_map.enc = &custom;
     566             : 
     567             :     /* Default poly to a 50x50 square */
     568           0 :     if ( sd->old_poly==NULL ) {
     569           0 :         sd->old_poly = UnitShape( true );
     570           0 :         memset(transform,0,sizeof(transform));
     571           0 :         transform[0] = transform[3] = 25;
     572           0 :         SplinePointListTransform(sd->old_poly,transform,tpt_AllPoints);
     573             :     }
     574           0 : }
     575             : 
     576           0 : static int stroke_e_h(GWindow gw, GEvent *event) {
     577           0 :     if ( event->type==et_expose ) {
     578           0 :         StrokeDlg *sd = (StrokeDlg *) ((CharViewBase *) GDrawGetUserData(gw))->container;
     579           0 :         Stroke_Draw(sd,gw,event);
     580           0 :     } else if ( event->type==et_close ) {
     581           0 :         StrokeDlg *sd = (StrokeDlg *) ((CharViewBase *) GDrawGetUserData(gw))->container;
     582           0 :         sd->done = true;
     583           0 :     } else if ( event->type == et_char ) {
     584           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
     585           0 :             help("elementmenu.html#Expand");
     586           0 : return( true );
     587             :         }
     588           0 : return( false );
     589           0 :     } else if ( event->type == et_mousemove ) {
     590           0 :     } else if ( event->type == et_map ) {
     591             :         /* Above palettes */
     592           0 :         GDrawRaise(gw);
     593             :     }
     594           0 : return( true );
     595             : }
     596             : 
     597             : #define SD_Width        230
     598             : #define SD_Height       335
     599             : #define FH_Height       (SD_Height+75)
     600             : 
     601           0 : static void MakeStrokeDlg(void *cv,void (*strokeit)(void *,StrokeInfo *,int),StrokeInfo *si) {
     602             :     static StrokeDlg strokedlg;
     603             :     StrokeDlg *sd, freehand_dlg;
     604             :     GRect pos;
     605             :     GWindow gw;
     606             :     GWindowAttrs wattrs;
     607             :     GGadgetCreateData gcd[39], boxes[9], *buttons[13], *mainarray[11][2],
     608             :             *caparray[7], *joinarray[7], *swarray[7][5], *pens[10];
     609             :     GTextInfo label[39];
     610           0 :     int yoff=0;
     611             :     int gcdoff, mi, swpos;
     612             :     static StrokeInfo defaults = {
     613             :         25,
     614             :         lj_round,
     615             :         lc_butt,
     616             :         si_std,
     617             :         false, /* removeinternal */
     618             :         false, /* removeexternal */
     619             :         false, /* leave users center */
     620             :         3.1415926535897932/4,
     621             :         25,
     622             :         NULL,
     623             :         50,
     624             :         0.0,
     625             :         0,
     626             :         0,
     627             :         NULL,
     628             :         NULL
     629             :     };
     630           0 :     StrokeInfo *def = si?si:&defaults;
     631             :     char anglebuf[20], widthbuf[20], axisbuf[20];
     632             : 
     633           0 :     if ( strokeit!=NULL )
     634           0 :         sd = &strokedlg;
     635             :     else {
     636           0 :         sd = &freehand_dlg;
     637           0 :         memset(&freehand_dlg,0,sizeof(freehand_dlg));
     638           0 :         sd->si = si;
     639           0 :         yoff = 18;
     640             :     }
     641           0 :     if ( sd->old_poly==NULL && si!=NULL && si->poly!=NULL ) {
     642           0 :         sd->old_poly = si->poly;
     643           0 :         si->poly = NULL;
     644             :     }
     645             : 
     646           0 :     if ( sd->gw==NULL ) {
     647           0 :         StrokeInit(sd);
     648           0 :         memset(&wattrs,0,sizeof(wattrs));
     649           0 :         wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
     650           0 :         wattrs.event_masks = ~(1<<et_charup);
     651           0 :         wattrs.restrict_input_to_me = 1;
     652           0 :         wattrs.undercursor = 1;
     653           0 :         wattrs.cursor = ct_pointer;
     654           0 :         wattrs.utf8_window_title = strokeit!=NULL ? _("Expand Stroke") :
     655             : /* GT: This does not mean the program, but freehand drawing */
     656             :                     _("Freehand");
     657           0 :         wattrs.is_dlg = true;
     658           0 :         pos.x = pos.y = 0;
     659           0 :         pos.width = GGadgetScale(GDrawPointsToPixels(NULL,SD_Width));
     660           0 :         pos.height = GDrawPointsToPixels(NULL,strokeit!=NULL ? SD_Height : FH_Height);
     661           0 :         sd->gw = gw = GDrawCreateTopWindow(NULL,&pos,stroke_e_h,&sd->cv_stroke,&wattrs);
     662           0 :         if ( si!=NULL )
     663           0 :             GDrawRequestDeviceEvents(gw,input_em_cnt,input_em);
     664             : 
     665           0 :         memset(&label,0,sizeof(label));
     666           0 :         memset(&gcd,0,sizeof(gcd));
     667           0 :         memset(&boxes,0,sizeof(boxes));
     668             : 
     669           0 :         gcdoff = mi = swpos = 0;
     670             : 
     671           0 :         gcd[gcdoff].gd.flags = gg_visible|gg_enabled ;          /* This space is for the menubar */
     672           0 :         gcd[gcdoff].gd.pos.height = 18; gcd[gcdoff].gd.pos.width = 20;
     673           0 :         gcd[gcdoff++].creator = GSpacerCreate;
     674           0 :         mainarray[mi][0] = &gcd[gcdoff-1]; mainarray[mi++][1] = NULL;
     675             : 
     676           0 :         gcd[gcdoff].gd.pos.width = gcd[gcdoff].gd.pos.height = 200;
     677           0 :         gcd[gcdoff].gd.flags = gg_visible | gg_enabled;
     678           0 :         gcd[gcdoff].gd.cid = CID_Nib;
     679           0 :         gcd[gcdoff].gd.u.drawable_e_h = stroke_sub_e_h;
     680           0 :         gcd[gcdoff++].creator = GDrawableCreate;
     681           0 :         mainarray[mi][0] = &gcd[gcdoff-1]; mainarray[mi++][1] = NULL;
     682             : 
     683           0 :         label[gcdoff].text = (unichar_t *) _("Pen Type:");
     684           0 :         label[gcdoff].text_is_1byte = true;
     685           0 :         label[gcdoff].text_in_resource = true;
     686           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     687           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
     688           0 :         gcd[gcdoff++].creator = GLabelCreate;
     689           0 :         pens[0] = &gcd[gcdoff-1];
     690             : 
     691           0 :         label[gcdoff].text = (unichar_t *) _("_Circular\n(Elliptical)");
     692           0 :         label[gcdoff].text_is_1byte = true;
     693           0 :         label[gcdoff].text_in_resource = true;
     694           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     695           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->stroke_type==si_std? gg_cb_on : 0);
     696           0 :         gcd[gcdoff].gd.u.radiogroup = 1;
     697           0 :         gcd[gcdoff].gd.cid = CID_Circle;
     698           0 :         gcd[gcdoff].gd.handle_controlevent = Stroke_Stroke;
     699           0 :         gcd[gcdoff++].creator = GRadioCreate;
     700           0 :         pens[1] = &gcd[gcdoff-1];
     701             : 
     702           0 :         label[gcdoff].text = (unichar_t *) _("Ca_lligraphic\n(Rectangular)");
     703           0 :         label[gcdoff].text_is_1byte = true;
     704           0 :         label[gcdoff].text_in_resource = true;
     705           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     706           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->stroke_type == si_caligraphic ? gg_cb_on : 0);
     707           0 :         gcd[gcdoff].gd.u.radiogroup = 1;
     708           0 :         gcd[gcdoff].gd.cid = CID_Caligraphic;
     709           0 :         gcd[gcdoff].gd.handle_controlevent = Stroke_Caligraphic;
     710           0 :         gcd[gcdoff++].creator = GRadioCreate;
     711           0 :         pens[2] = &gcd[gcdoff-1];
     712             : 
     713           0 :         label[gcdoff].text = (unichar_t *) _("_Polygon");
     714           0 :         label[gcdoff].text_is_1byte = true;
     715           0 :         label[gcdoff].text_in_resource = true;
     716           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     717           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->stroke_type == si_poly ? gg_cb_on : 0);
     718           0 :         gcd[gcdoff].gd.u.radiogroup = 1;
     719           0 :         gcd[gcdoff].gd.cid = CID_Polygon;
     720           0 :         gcd[gcdoff].gd.handle_controlevent = Stroke_Polygon;
     721           0 :         gcd[gcdoff++].creator = GRadioCreate;
     722           0 :         pens[3] = &gcd[gcdoff-1]; pens[4] = NULL; pens[5] = NULL;
     723             : 
     724           0 :         if ( strokeit==NULL ) {
     725           0 :             label[gcdoff].text = (unichar_t *) _("_Don't Expand");
     726           0 :             label[gcdoff].text_is_1byte = true;
     727           0 :             label[gcdoff].text_in_resource = true;
     728           0 :             gcd[gcdoff].gd.label = &label[gcdoff];
     729           0 :             gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->stroke_type==si_centerline ? gg_cb_on : 0 );
     730           0 :             gcd[gcdoff].gd.u.radiogroup = 1;
     731           0 :             gcd[gcdoff].gd.cid = CID_CenterLine;
     732           0 :             gcd[gcdoff].gd.handle_controlevent = Stroke_CenterLine;
     733           0 :             gcd[gcdoff++].creator = GRadioCreate;
     734           0 :             pens[3] = NULL; pens[4] = GCD_Glue;
     735           0 :             pens[5] = &gcd[gcdoff-2]; pens[6] = &gcd[gcdoff-1]; pens[7] = NULL; pens[8] = NULL;
     736             :         }
     737             : 
     738           0 :         boxes[2].gd.flags = gg_enabled|gg_visible;
     739           0 :         boxes[2].gd.u.boxelements = pens;
     740           0 :         boxes[2].creator = GHVBoxCreate;
     741           0 :         mainarray[mi][0] = &boxes[2]; mainarray[mi++][1] = NULL;
     742             : 
     743           0 :         label[gcdoff].text = (unichar_t *) _("Main Stroke _Width:");
     744           0 :         label[gcdoff].text_is_1byte = true;
     745           0 :         label[gcdoff].text_in_resource = true;
     746           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     747           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
     748           0 :         gcd[gcdoff].gd.cid = CID_WidthTxt;
     749           0 :         gcd[gcdoff++].creator = GLabelCreate;
     750           0 :         swarray[swpos][0] = &gcd[gcdoff-1];
     751             : 
     752           0 :         sprintf( widthbuf, "%g", (double) (2*def->radius) );
     753           0 :         label[gcdoff].text = (unichar_t *) widthbuf;
     754           0 :         label[gcdoff].text_is_1byte = true;
     755           0 :         gcd[gcdoff].gd.pos.width = 50;
     756           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     757           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
     758           0 :         gcd[gcdoff].gd.cid = CID_Width;
     759           0 :         gcd[gcdoff].gd.handle_controlevent = Stroke_TextChanged;
     760           0 :         gcd[gcdoff++].creator = GTextFieldCreate;
     761           0 :         swarray[swpos][1] = &gcd[gcdoff-1]; swarray[swpos][2] = swarray[swpos][3] = GCD_Glue; swarray[swpos++][4] = NULL;
     762             : 
     763           0 :         label[gcdoff].text = (unichar_t *) _("Minor Stroke _Height:");
     764           0 :         label[gcdoff].text_is_1byte = true;
     765           0 :         label[gcdoff].text_in_resource = true;
     766           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     767           0 :         gcd[gcdoff].gd.flags = gg_visible | gg_enabled;
     768           0 :         gcd[gcdoff].gd.cid = CID_MinorAxisTxt;
     769           0 :         gcd[gcdoff++].creator = GLabelCreate;
     770           0 :         swarray[swpos][0] = &gcd[gcdoff-1];
     771             : 
     772           0 :         sprintf( axisbuf, "%g", (double) (2*def->minorradius) );
     773           0 :         label[gcdoff].text = (unichar_t *) axisbuf;
     774           0 :         label[gcdoff].text_is_1byte = true;
     775           0 :         gcd[gcdoff].gd.pos.width = 50;
     776           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     777           0 :         gcd[gcdoff].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
     778           0 :         gcd[gcdoff].gd.cid = CID_MinorAxis;
     779           0 :         gcd[gcdoff].gd.handle_controlevent = Stroke_TextChanged;
     780           0 :         gcd[gcdoff].gd.popup_msg = (unichar_t *) _(
     781             :             "A calligraphic pen or an eliptical pen has two widths\n"
     782             :             "(which may be the same, giving a circular or square pen,\n"
     783             :             "or different giving an eliptical or rectangular pen).");
     784           0 :         gcd[gcdoff++].creator = GTextFieldCreate;
     785           0 :         swarray[swpos][1] = &gcd[gcdoff-1]; swarray[swpos][2] = swarray[swpos][3] = GCD_Glue; swarray[swpos++][4] = NULL;
     786             : 
     787           0 :         label[gcdoff].text = (unichar_t *) _("Pen _Angle:");
     788           0 :         label[gcdoff].text_is_1byte = true;
     789           0 :         label[gcdoff].text_in_resource = true;
     790           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     791           0 :         gcd[gcdoff].gd.flags = gg_visible | gg_enabled;
     792           0 :         gcd[gcdoff].gd.cid = CID_PenAngleTxt;
     793           0 :         gcd[gcdoff++].creator = GLabelCreate;
     794           0 :         swarray[2][0] = &gcd[gcdoff-1];
     795             : 
     796           0 :         sprintf( anglebuf, "%g", (double) (def->penangle*180/3.1415926535897932) );
     797           0 :         label[gcdoff].text = (unichar_t *) anglebuf;
     798           0 :         label[gcdoff].text_is_1byte = true;
     799           0 :         gcd[gcdoff].gd.pos.width = 50;
     800           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     801           0 :         gcd[gcdoff].gd.flags = gg_visible | gg_enabled;
     802           0 :         gcd[gcdoff].gd.cid = CID_PenAngle;
     803           0 :         gcd[gcdoff].gd.handle_controlevent = Stroke_TextChanged;
     804           0 :         gcd[gcdoff++].creator = GTextFieldCreate;
     805           0 :         swarray[swpos][1] = &gcd[gcdoff-1]; swarray[swpos][2] = swarray[swpos][3] = GCD_Glue; swarray[swpos++][4] = NULL;
     806           0 :         swarray[swpos][0] = NULL;
     807             : 
     808           0 :         boxes[3].gd.flags = gg_enabled|gg_visible;
     809           0 :         boxes[3].gd.u.boxelements = swarray[0];
     810           0 :         boxes[3].creator = GHVBoxCreate;
     811           0 :         mainarray[mi][0] = &boxes[3]; mainarray[mi++][1] = NULL;
     812             : 
     813             : /* GT: Butt is a PostScript concept which refers to a way of ending strokes */
     814             : /* GT: In the following image the line drawn with "=" is the original, and */
     815             : /* GT: the others are the results. The "Round" style is hard to draw with */
     816             : /* GT: ASCII glyphs. If this is unclear I suggest you look at the Expand Stroke */
     817             : /* GT: dialog which has little pictures */
     818             : /* GT: */
     819             : /* GT: -----------------+    -----------------+    ----------------+--+ */
     820             : /* GT:                  |                      \                      | */
     821             : /* GT: =================+    ================== )  =================  | */
     822             : /* GT:                  |                      /                      | */
     823             : /* GT: -----------------+    -----------------+    ----------------+--+ */
     824             : /* GT:       Butt                 Round                Square */
     825           0 :         label[gcdoff].text = (unichar_t *) _("_Butt");
     826           0 :         label[gcdoff].text_is_1byte = true;
     827           0 :         label[gcdoff].text_in_resource = true;
     828           0 :         label[gcdoff].image = &GIcon_buttcap;
     829           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     830           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->cap==lc_butt?gg_cb_on:0);
     831           0 :         gcd[gcdoff].gd.cid = CID_ButtCap;
     832           0 :         gcd[gcdoff++].creator = GRadioCreate;
     833           0 :         caparray[0] = &gcd[gcdoff-1]; caparray[1] = GCD_Glue;
     834             : 
     835           0 :         label[gcdoff].text = (unichar_t *) _("_Round");
     836           0 :         label[gcdoff].text_is_1byte = true;
     837           0 :         label[gcdoff].text_in_resource = true;
     838           0 :         label[gcdoff].image = &GIcon_roundcap;
     839           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     840           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->cap==lc_round?gg_cb_on:0);
     841           0 :         gcd[gcdoff].gd.cid = CID_RoundCap;
     842           0 :         gcd[gcdoff++].creator = GRadioCreate;
     843           0 :         caparray[2] = &gcd[gcdoff-1]; caparray[3] = GCD_Glue;
     844             : 
     845           0 :         label[gcdoff].text = (unichar_t *) _("S_quare");
     846           0 :         label[gcdoff].text_is_1byte = true;
     847           0 :         label[gcdoff].text_in_resource = true;
     848           0 :         label[gcdoff].image = &GIcon_squarecap;
     849           0 :         gcd[gcdoff].gd.mnemonic = 'q';
     850           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     851           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->cap==lc_square?gg_cb_on:0);
     852           0 :         gcd[gcdoff].gd.cid = CID_SquareCap;
     853           0 :         gcd[gcdoff++].creator = GRadioCreate;
     854           0 :         caparray[4] = &gcd[gcdoff-1]; caparray[5] = NULL; caparray[6] = NULL;
     855             : 
     856           0 :         label[gcdoff].text = (unichar_t *) _("Line Cap");
     857           0 :         label[gcdoff].text_is_1byte = true;
     858           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     859           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
     860           0 :         gcd[gcdoff].gd.cid = CID_LineCapTxt;
     861           0 :         gcd[gcdoff++].creator = GLabelCreate;
     862             : 
     863           0 :         boxes[4].gd.label = (GTextInfo *) &gcd[gcdoff-1];
     864           0 :         boxes[4].gd.flags = gg_enabled|gg_visible;
     865           0 :         boxes[4].gd.u.boxelements = caparray;
     866           0 :         boxes[4].creator = GHVGroupCreate;
     867           0 :         mainarray[mi][0] = &boxes[4]; mainarray[mi++][1] = NULL;
     868             : 
     869           0 :         label[gcdoff].text = (unichar_t *) _("_Miter");
     870           0 :         label[gcdoff].text_is_1byte = true;
     871           0 :         label[gcdoff].text_in_resource = true;
     872           0 :         label[gcdoff].image = &GIcon_miterjoin;
     873           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     874           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->join==lj_miter?gg_cb_on:0);
     875           0 :         gcd[gcdoff].gd.cid = CID_MiterJoin;
     876           0 :         gcd[gcdoff++].creator = GRadioCreate;
     877           0 :         joinarray[0] = &gcd[gcdoff-1]; joinarray[1] = GCD_Glue;
     878             : 
     879           0 :         label[gcdoff].text = (unichar_t *) _("Ro_und");
     880           0 :         label[gcdoff].text_is_1byte = true;
     881           0 :         label[gcdoff].text_in_resource = true;
     882           0 :         label[gcdoff].image = &GIcon_roundjoin;
     883           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     884           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->join==lj_round?gg_cb_on:0);
     885           0 :         gcd[gcdoff].gd.cid = CID_RoundJoin;
     886           0 :         gcd[gcdoff++].creator = GRadioCreate;
     887           0 :         joinarray[2] = &gcd[gcdoff-1]; joinarray[3] = GCD_Glue;
     888             : 
     889           0 :         label[gcdoff].text = (unichar_t *) _("Be_vel");
     890           0 :         label[gcdoff].text_is_1byte = true;
     891           0 :         label[gcdoff].text_in_resource = true;
     892           0 :         label[gcdoff].image = &GIcon_beveljoin;
     893           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     894           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->join==lj_bevel?gg_cb_on:0);
     895           0 :         gcd[gcdoff].gd.cid = CID_BevelJoin;
     896           0 :         gcd[gcdoff++].creator = GRadioCreate;
     897           0 :         joinarray[4] = &gcd[gcdoff-1]; joinarray[5] = NULL; joinarray[6] = NULL;
     898             : 
     899           0 :         label[gcdoff].text = (unichar_t *) _("Line Join");
     900           0 :         label[gcdoff].text_is_1byte = true;
     901           0 :         label[gcdoff].text_in_resource = true;
     902           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     903           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
     904           0 :         gcd[gcdoff].gd.cid = CID_LineJoinTxt;
     905           0 :         gcd[gcdoff++].creator = GLabelCreate;
     906             : 
     907           0 :         boxes[5].gd.label = (GTextInfo *) &gcd[gcdoff-1];
     908           0 :         boxes[5].gd.flags = gg_enabled|gg_visible;
     909           0 :         boxes[5].gd.u.boxelements = joinarray;
     910           0 :         boxes[5].creator = GHVGroupCreate;
     911           0 :         mainarray[mi][0] = &boxes[5]; mainarray[mi++][1] = NULL;
     912             : 
     913           0 :         label[gcdoff].text = (unichar_t *) _("Remove Internal Contour");
     914           0 :         label[gcdoff].text_is_1byte = true;
     915           0 :         label[gcdoff].text_in_resource = true;
     916           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     917           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->removeinternal?gg_cb_on:0);
     918           0 :         gcd[gcdoff].gd.cid = CID_RmInternal;
     919           0 :         gcd[gcdoff++].creator = GCheckBoxCreate;
     920           0 :         mainarray[mi][0] = &gcd[gcdoff-1]; mainarray[mi++][1] = NULL;
     921             : 
     922           0 :         label[gcdoff].text = (unichar_t *) _("Remove External Contour");
     923           0 :         label[gcdoff].text_is_1byte = true;
     924           0 :         label[gcdoff].text_in_resource = true;
     925           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     926           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (def->removeexternal?gg_cb_on:0);
     927           0 :         gcd[gcdoff].gd.cid = CID_RmExternal;
     928           0 :         gcd[gcdoff++].creator = GCheckBoxCreate;
     929           0 :         mainarray[mi][0] = &gcd[gcdoff-1]; mainarray[mi++][1] = NULL;
     930             : 
     931           0 :         gcd[gcdoff].gd.flags = gg_visible | gg_enabled | gg_but_default;
     932           0 :         label[gcdoff].text = (unichar_t *) _("_OK");
     933           0 :         label[gcdoff].text_is_1byte = true;
     934           0 :         label[gcdoff].text_in_resource = true;
     935           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     936           0 :         gcd[gcdoff].gd.handle_controlevent = Stroke_OK;
     937           0 :         gcd[gcdoff++].creator = GButtonCreate;
     938           0 :         buttons[0] = GCD_Glue; buttons[1] = &gcd[gcdoff-1]; buttons[2] = GCD_Glue; buttons[3] = GCD_Glue;
     939             : 
     940           0 :         gcd[gcdoff].gd.flags = gg_visible | gg_enabled;
     941           0 :         label[gcdoff].text = (unichar_t *) _("_Apply");
     942           0 :         label[gcdoff].text_is_1byte = true;
     943           0 :         label[gcdoff].text_in_resource = true;
     944           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     945           0 :         gcd[gcdoff].gd.handle_controlevent = Stroke_OK;
     946           0 :         gcd[gcdoff].gd.cid = CID_Apply;
     947           0 :         gcd[gcdoff++].creator = GButtonCreate;
     948           0 :         buttons[4] = GCD_Glue; buttons[5] = &gcd[gcdoff-1]; buttons[6] = GCD_Glue; buttons[7] = GCD_Glue;
     949             : 
     950           0 :         gcd[gcdoff].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
     951           0 :         label[gcdoff].text = (unichar_t *) _("_Cancel");
     952           0 :         label[gcdoff].text_is_1byte = true;
     953           0 :         label[gcdoff].text_in_resource = true;
     954           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
     955           0 :         gcd[gcdoff].gd.handle_controlevent = Stroke_Cancel;
     956           0 :         gcd[gcdoff].creator = GButtonCreate;
     957           0 :         buttons[8] = GCD_Glue; buttons[9] = &gcd[gcdoff]; buttons[10] = GCD_Glue;
     958           0 :         buttons[11] = NULL;
     959             : 
     960           0 :         boxes[6].gd.flags = gg_enabled|gg_visible;
     961           0 :         boxes[6].gd.u.boxelements = buttons;
     962           0 :         boxes[6].creator = GHBoxCreate;
     963           0 :         mainarray[mi][0] = &boxes[6]; mainarray[mi++][1] = NULL;
     964           0 :         mainarray[mi][0] = GCD_Glue; mainarray[mi++][1] = NULL;
     965           0 :         mainarray[mi][0] = NULL;
     966             : 
     967           0 :         boxes[0].gd.pos.x = boxes[0].gd.pos.y = 2;
     968           0 :         boxes[0].gd.flags = gg_enabled|gg_visible;
     969           0 :         boxes[0].gd.u.boxelements = mainarray[0];
     970           0 :         boxes[0].gd.cid = CID_TopBox;
     971           0 :         boxes[0].creator = GHVGroupCreate;
     972             : 
     973           0 :         GGadgetsCreate(gw,boxes);
     974           0 :         GHVBoxSetExpandableRow(boxes[0].ret,1);
     975           0 :         GHVBoxSetExpandableCol(boxes[2].ret,gb_expandglue);
     976           0 :         GHVBoxSetExpandableCol(boxes[3].ret,gb_expandglue);
     977           0 :         GHVBoxSetExpandableCol(boxes[5].ret,gb_expandglue);
     978           0 :         GHVBoxSetExpandableCol(boxes[6].ret,gb_expandgluesame);
     979             : 
     980           0 :         StrokeCharViewInits(sd,CID_Nib);
     981           0 :         sd->cv_stroke.showfore = true;
     982           0 :         sd->cv_stroke.showgrids = true;
     983             :     } else
     984           0 :         GDrawSetTransientFor(sd->gw,(GWindow) -1);
     985             : 
     986           0 :     Stroke_MakeActive(sd,&sd->cv_stroke);
     987           0 :     Stroke_ShowNib(sd);
     988             : 
     989           0 :     sd->cv = cv;
     990           0 :     sd->strokeit = strokeit;
     991           0 :     sd->done = false;
     992           0 :     sd->up[0] = sd->up[1] = true;
     993           0 :     GWidgetHidePalettes();
     994           0 :     GWidgetIndicateFocusGadget(GWidgetGetControl(sd->gw,CID_Width));
     995           0 :     if ( si==NULL ) {
     996           0 :         StrokeSetup(sd,GGadgetIsChecked( GWidgetGetControl(sd->gw,CID_Caligraphic))?si_caligraphic:
     997           0 :                 GGadgetIsChecked( GWidgetGetControl(sd->gw,CID_Circle))?si_std:
     998           0 :                 GGadgetIsChecked( GWidgetGetControl(sd->gw,CID_Polygon))?si_poly:
     999             :                 si_centerline);
    1000           0 :         GGadgetSetVisible( GWidgetGetControl(sd->gw,CID_Apply),strokeit==CVStrokeIt );
    1001             :     } else {
    1002           0 :         StrokeSetup(sd,def->stroke_type);
    1003           0 :         GGadgetSetVisible( GWidgetGetControl(sd->gw,CID_Apply),false );
    1004             :     }
    1005           0 :     GWidgetToDesiredSize(sd->gw);
    1006             : 
    1007           0 :     GDrawSetVisible(sd->gw,true);
    1008           0 :     while ( !sd->done )
    1009           0 :         GDrawProcessOneEvent(NULL);
    1010             : 
    1011           0 :     CVPalettesHideIfMine(&sd->cv_stroke);
    1012           0 :     if ( strokeit!=NULL )
    1013           0 :         GDrawSetVisible(sd->gw,false);
    1014             :     else
    1015           0 :         GDrawDestroyWindow(sd->gw);
    1016           0 : }
    1017             : 
    1018           0 : void CVStroke(CharView *cv) {
    1019             : 
    1020           0 :     if ( cv->b.layerheads[cv->b.drawmode]->splines==NULL )
    1021           0 : return;
    1022             : 
    1023           0 :     MakeStrokeDlg(cv,CVStrokeIt,NULL);
    1024             : }
    1025             : 
    1026           0 : void FVStroke(FontView *fv) {
    1027           0 :     MakeStrokeDlg(fv,FVStrokeItScript,NULL);
    1028           0 : }
    1029             : 
    1030           0 : void FreeHandStrokeDlg(StrokeInfo *si) {
    1031           0 :     MakeStrokeDlg(NULL,NULL,si);
    1032           0 : }
    1033             : 
    1034             : /* ************************************************************************** */
    1035             : /* ****************************** Layer Dialog ****************************** */
    1036             : /* ************************************************************************** */
    1037             : #define LY_Width        300
    1038             : #define LY_Height       336
    1039             : 
    1040             : #define CID_FillColor           2001
    1041             : #define CID_FillCInherit        2002
    1042             : #define CID_FillOpacity         2003
    1043             : #define CID_FillOInherit        2004
    1044             : #define CID_StrokeColor         2005
    1045             : #define CID_StrokeCInherit      2006
    1046             : #define CID_StrokeOpacity       2007
    1047             : #define CID_StrokeOInherit      2008
    1048             : #define CID_StrokeWInherit      2009
    1049             : #define CID_Trans               2010
    1050             : #define CID_InheritCap          2011
    1051             : #define CID_InheritJoin         2012
    1052             : #define CID_Fill                2013
    1053             : #define CID_Dashes              2014
    1054             : #define CID_DashesTxt           2015
    1055             : #define CID_DashesInherit       2016
    1056             : #define CID_Stroke              2017
    1057             : 
    1058             : #define CID_FillGradAdd         2100
    1059             : #define CID_FillGradEdit        2101
    1060             : #define CID_FillGradDelete      2102
    1061             : #define CID_StrokeGradAdd       2110
    1062             : #define CID_StrokeGradEdit      2111
    1063             : #define CID_StrokeGradDelete    2112
    1064             : 
    1065             : #define CID_FillPatAdd          2200
    1066             : #define CID_FillPatEdit         2201
    1067             : #define CID_FillPatDelete       2202
    1068             : #define CID_StrokePatAdd        2210
    1069             : #define CID_StrokePatEdit       2211
    1070             : #define CID_StrokePatDelete     2212
    1071             : 
    1072             : struct layer_dlg {
    1073             :     int done;
    1074             :     int ok;
    1075             :     Layer *layer;
    1076             :     SplineFont *sf;
    1077             :     GWindow gw;
    1078             :     struct gradient *fillgrad, *strokegrad;
    1079             :     struct pattern  *fillpat,  *strokepat;
    1080             : 
    1081             :     int pat_done;
    1082             :     struct pattern *curpat;
    1083             : };
    1084             : 
    1085             : #define CID_Gradient    1001
    1086             : #define CID_Stops       1002
    1087             : #define CID_Pad         1003
    1088             : #define CID_Repeat      1004
    1089             : #define CID_Reflect     1005
    1090             : #define CID_Linear      1006
    1091             : #define CID_Radial      1007
    1092             : #define CID_GradStops   1008
    1093             : 
    1094           0 : static void GDDSubResize(GradientDlg *gdd, GEvent *event) {
    1095             :     int width, height;
    1096             : 
    1097           0 :     if ( !event->u.resize.sized )
    1098           0 : return;
    1099             : 
    1100           0 :     width = event->u.resize.size.width;
    1101           0 :     height = event->u.resize.size.height;
    1102           0 :     if ( width!=gdd->cv_width || height!=gdd->cv_height ) {
    1103           0 :         gdd->cv_width = width; gdd->cv_height = height;
    1104           0 :         GDrawResize(gdd->cv_grad.gw,width,height);
    1105             :     }
    1106             : 
    1107           0 :     GDrawSync(NULL);
    1108           0 :     GDrawProcessPendingEvents(NULL);
    1109             : }
    1110             : 
    1111           0 : static void GDDDraw(GradientDlg *gdd, GWindow pixmap, GEvent *event) {
    1112             :     GRect r,pos;
    1113             : 
    1114           0 :     GGadgetGetSize(GWidgetGetControl(gdd->gw,CID_Gradient),&pos);
    1115           0 :     r.x = pos.x-1; r.y = pos.y-1;
    1116           0 :     r.width = pos.width+1; r.height = pos.height+1;
    1117           0 :     GDrawDrawRect(pixmap,&r,0);
    1118           0 : }
    1119             : 
    1120           0 : static void GDDMakeActive(GradientDlg *gdd,CharView *cv) {
    1121             : 
    1122           0 :     if ( gdd==NULL )
    1123           0 : return;
    1124           0 :     cv->inactive = false;
    1125           0 :     GDrawSetUserData(gdd->gw,cv);
    1126           0 :     GDrawRequestExpose(cv->v,NULL,false);
    1127           0 :     GDrawRequestExpose(gdd->gw,NULL,false);
    1128             : }
    1129             : 
    1130           0 : static void GDDChar(GradientDlg *gdd, GEvent *event) {
    1131           0 :     CVChar((&gdd->cv_grad),event);
    1132           0 : }
    1133             : 
    1134           0 : static void GDD_DoClose(struct cvcontainer *cvc) {
    1135           0 :     GradientDlg *gdd = (GradientDlg *) cvc;
    1136             : 
    1137             :      {
    1138           0 :         SplineChar *msc = &gdd->sc_grad;
    1139           0 :         SplinePointListsFree(msc->layers[0].splines);
    1140           0 :         SplinePointListsFree(msc->layers[1].splines);
    1141           0 :         free( msc->layers );
    1142             :     }
    1143             : 
    1144           0 :     gdd->done = true;
    1145           0 : }
    1146             : 
    1147           0 : static int gdd_sub_e_h(GWindow gw, GEvent *event) {
    1148           0 :     GradientDlg *gdd = (GradientDlg *) ((CharViewBase *) GDrawGetUserData(gw))->container;
    1149             : 
    1150           0 :     switch ( event->type ) {
    1151             :       case et_resize:
    1152           0 :         if ( event->u.resize.sized )
    1153           0 :             GDDSubResize(gdd,event);
    1154           0 :       break;
    1155             :       case et_char:
    1156           0 :         GDDChar(gdd,event);
    1157           0 :       break;
    1158             :       case et_mouseup: case et_mousedown: case et_mousemove:
    1159           0 : return( false );
    1160             :       break;
    1161             :     }
    1162           0 : return( true );
    1163             : }
    1164             : 
    1165           0 : static int gdd_e_h(GWindow gw, GEvent *event) {
    1166           0 :     GradientDlg *gdd = (GradientDlg *) ((CharViewBase *) GDrawGetUserData(gw))->container;
    1167             : 
    1168           0 :     switch ( event->type ) {
    1169             :       case et_expose:
    1170           0 :         GDDDraw(gdd, gw, event);
    1171           0 :       break;
    1172             :       case et_char:
    1173           0 :         GDDChar(gdd,event);
    1174           0 :       break;
    1175             :       case et_close:
    1176           0 :         GDD_DoClose((struct cvcontainer *) gdd);
    1177           0 :       break;
    1178             :       case et_create:
    1179           0 :       break;
    1180             :       case et_map:
    1181             :          {
    1182           0 :             CharView *cv = (&gdd->cv_grad);
    1183           0 :             if ( !cv->inactive ) {
    1184           0 :                 if ( event->u.map.is_visible )
    1185           0 :                     CVPaletteActivate(cv);
    1186             :                 else
    1187           0 :                     CVPalettesHideIfMine(cv);
    1188             :             }
    1189             :         }
    1190             :         /* gdd->isvisible = event->u.map.is_visible; */
    1191           0 :       break;
    1192             :     }
    1193           0 : return( true );
    1194             : }
    1195             : 
    1196           0 : static int Gradient_Cancel(GGadget *g, GEvent *e) {
    1197           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1198           0 :         GradientDlg *gdd = (GradientDlg *) (((CharViewBase *) GDrawGetUserData(GGadgetGetWindow(g)))->container);
    1199           0 :         GDD_DoClose(&gdd->base);
    1200             :     }
    1201           0 : return( true );
    1202             : }
    1203             : 
    1204           0 : static int orderstops(const void *_md1, const void *_md2) {
    1205           0 :     const struct matrix_data *md1 = _md1, *md2 = _md2;
    1206             : 
    1207           0 :     if ( md1->u.md_real>md2->u.md_real )
    1208           0 : return( 1 );
    1209           0 :     else if ( md1->u.md_real==md2->u.md_real )
    1210           0 : return( 0 );
    1211             :     else
    1212           0 : return( -1 );
    1213             : }
    1214             : 
    1215           0 : static int Gradient_OK(GGadget *g, GEvent *e) {
    1216           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1217           0 :         GradientDlg *gdd = (GradientDlg *) (((CharViewBase *) GDrawGetUserData(GGadgetGetWindow(g)))->container);
    1218           0 :         struct gradient *gradient = gdd->active;
    1219             :         BasePoint start, end, offset;
    1220             :         real radius;
    1221             :         int pad, linear;
    1222             :         SplineSet *ss, *ss2;
    1223           0 :         int i, rows, cols = GMatrixEditGetColCnt(GWidgetGetControl(gdd->gw,CID_GradStops));
    1224           0 :         struct matrix_data *md = GMatrixEditGet(GWidgetGetControl(gdd->gw,CID_GradStops), &rows);
    1225             : 
    1226           0 :         if ( rows<2 ) {
    1227           0 :             ff_post_error(_("Bad Gradient"),_("There must be at least 2 gradient stops"));
    1228           0 : return( true );
    1229             :         }
    1230           0 :         for ( i=0; i<rows; ++i ) {
    1231           0 :             if ( md[cols*i+0].u.md_real<0 || md[cols*i+0].u.md_real>100.0 ) {
    1232           0 :                 ff_post_error(_("Bad Gradient"),_("Bad offset on line %d, must be between 0% and 100%."), i );
    1233           0 : return( true );
    1234             :             }
    1235           0 :             if ( md[cols*i+1].u.md_ival<0 || md[cols*i+1].u.md_ival>0xffffff ) {
    1236           0 :                 ff_post_error(_("Bad Gradient"),_("Bad color on line %d, must be between 000000 and ffffff."), i );
    1237           0 : return( true );
    1238             :             }
    1239           0 :             if ( md[cols*i+2].u.md_real<0 || md[cols*i+2].u.md_real>1.0 ) {
    1240           0 :                 ff_post_error(_("Bad Gradient"),_("Bad opacity on line %d, must be between 0.0 and 1.0."), i );
    1241           0 : return( true );
    1242             :             }
    1243             :         }
    1244             : 
    1245           0 :         linear = GGadgetIsChecked(GWidgetGetControl(gdd->gw,CID_Linear));
    1246           0 :         if ( GGadgetIsChecked(GWidgetGetControl(gdd->gw,CID_Pad)) )
    1247           0 :             pad = sm_pad;
    1248           0 :         else if ( GGadgetIsChecked(GWidgetGetControl(gdd->gw,CID_Repeat)) )
    1249           0 :             pad = sm_repeat;
    1250             :         else
    1251           0 :             pad = sm_reflect;
    1252           0 :         ss = gdd->sc_grad.layers[ly_fore].splines;
    1253           0 :         if ( ss==NULL || gdd->sc_grad.layers[ly_fore].refs!=NULL ||
    1254           0 :                 (linear && ss->next!=NULL) ||
    1255           0 :                 (!linear && ss->next!=NULL && ss->next->next!=NULL)) {
    1256           0 :             ff_post_error(_("Bad Gradient"),_("You must draw a line"));
    1257           0 : return( true );
    1258             :         }
    1259           0 :         ss2 = NULL;
    1260           0 :         if ( !linear && ss->next!=NULL ) {
    1261           0 :             if ( ss->first->next==NULL ) {
    1262           0 :                 ss2 = ss;
    1263           0 :                 ss = ss2->next;
    1264             :             } else {
    1265           0 :                 ss2 = ss->next;
    1266           0 :                 if ( ss2->first->next!=NULL ) {
    1267           0 :                     ff_post_error(_("Bad Gradient"),_("You must draw a line, with at most one additional point"));
    1268           0 : return( true );
    1269             :                 }
    1270             :             }
    1271             :         }
    1272           0 :         if ( (ss->first->next==NULL || ss->first==ss->last ||
    1273           0 :                 ss->first->next->to->next!=NULL ) ||
    1274           0 :                 !ss->first->next->islinear ) {
    1275           0 :             ff_post_error(_("Bad Gradient"),_("You must draw a line"));
    1276           0 : return( true );
    1277             :         }
    1278             : 
    1279           0 :         if ( linear ) {
    1280           0 :             start = ss->first->me;
    1281           0 :             end = ss->last->me;
    1282           0 :             radius = 0;
    1283             :         } else {
    1284           0 :             end = ss->first->me;
    1285           0 :             offset.x = ss->last->me.x-end.x;
    1286           0 :             offset.y = ss->last->me.y-end.y;
    1287           0 :             radius = sqrt(offset.x*offset.x + offset.y*offset.y);
    1288           0 :             if ( ss2!=NULL )
    1289           0 :                 start = ss2->first->me;
    1290             :             else
    1291           0 :                 start = end;
    1292             :         }
    1293           0 :         if ( gradient==NULL )
    1294           0 :             gdd->active = gradient = chunkalloc(sizeof(struct gradient));
    1295           0 :         gradient->start = start;
    1296           0 :         gradient->stop = end;
    1297           0 :         gradient->radius = radius;
    1298           0 :         gradient->sm = pad;
    1299             : 
    1300             :         /* Stops must be stored in ascending order */
    1301           0 :         qsort(md,rows,cols*sizeof(struct matrix_data),orderstops);
    1302           0 :         gradient->grad_stops = realloc(gradient->grad_stops,rows*sizeof(struct grad_stops));
    1303           0 :         gradient->stop_cnt = rows;
    1304           0 :         for ( i=0; i<rows; ++i ) {
    1305           0 :             gradient->grad_stops[i].offset  = md[cols*i+0].u.md_real/100.0;
    1306           0 :             gradient->grad_stops[i].col     = md[cols*i+1].u.md_ival;
    1307           0 :             gradient->grad_stops[i].opacity = md[cols*i+2].u.md_real;
    1308             :         }
    1309             : 
    1310           0 :         GDD_DoClose(&gdd->base);
    1311           0 :         gdd->oked = true;
    1312             :     }
    1313           0 : return( true );
    1314             : }
    1315             : 
    1316           0 : static int GDD_Can_Navigate(struct cvcontainer *cvc, enum nav_type type) {
    1317           0 : return( false );
    1318             : }
    1319             : 
    1320           0 : static int GDD_Can_Open(struct cvcontainer *cvc) {
    1321           0 : return( false );
    1322             : }
    1323             : 
    1324           0 : static SplineFont *SF_Of_GDD(struct cvcontainer *foo) {
    1325           0 : return( NULL );
    1326             : }
    1327             : 
    1328             : struct cvcontainer_funcs gradient_funcs = {
    1329             :     cvc_gradient,
    1330             :     (void (*) (struct cvcontainer *cvc,CharViewBase *cv)) GDDMakeActive,
    1331             :     (void (*) (struct cvcontainer *cvc,void *)) GDDChar,
    1332             :     GDD_Can_Navigate,
    1333             :     NULL,
    1334             :     GDD_Can_Open,
    1335             :     GDD_DoClose,
    1336             :     SF_Of_GDD
    1337             : };
    1338             : 
    1339             : 
    1340           0 : static void GDDInit(GradientDlg *gdd,SplineFont *sf,Layer *ly,struct gradient *grad) {
    1341             : 
    1342           0 :     memset(gdd,0,sizeof(*gdd));
    1343           0 :     gdd->base.funcs = &gradient_funcs;
    1344             : 
    1345             :     {
    1346           0 :         SplineChar *msc = (&gdd->sc_grad);
    1347           0 :         CharView *mcv = (&gdd->cv_grad);
    1348           0 :         msc->orig_pos = 0;
    1349           0 :         msc->unicodeenc = -1;
    1350           0 :         msc->name = "Gradient";
    1351           0 :         msc->parent = &gdd->dummy_sf;
    1352           0 :         msc->layer_cnt = 2;
    1353           0 :         msc->layers = calloc(2,sizeof(Layer));
    1354           0 :         LayerDefault(&msc->layers[0]);
    1355           0 :         LayerDefault(&msc->layers[1]);
    1356           0 :         gdd->chars[0] = msc;
    1357             : 
    1358           0 :         mcv->b.sc = msc;
    1359           0 :         mcv->b.layerheads[dm_fore] = &msc->layers[ly_fore];
    1360           0 :         mcv->b.layerheads[dm_back] = &msc->layers[ly_back];
    1361           0 :         mcv->b.layerheads[dm_grid] = &gdd->dummy_sf.grid;
    1362           0 :         mcv->b.drawmode = dm_fore;
    1363           0 :         mcv->b.container = (struct cvcontainer *) gdd;
    1364           0 :         mcv->inactive = false;
    1365             :     }
    1366           0 :     gdd->dummy_sf.glyphs = gdd->chars;
    1367           0 :     gdd->dummy_sf.glyphcnt = gdd->dummy_sf.glyphmax = 1;
    1368           0 :     gdd->dummy_sf.pfminfo.fstype = -1;
    1369           0 :     gdd->dummy_sf.pfminfo.stylemap = -1;
    1370           0 :     gdd->dummy_sf.fontname = gdd->dummy_sf.fullname = gdd->dummy_sf.familyname = "dummy";
    1371           0 :     gdd->dummy_sf.weight = "Medium";
    1372           0 :     gdd->dummy_sf.origname = "dummy";
    1373           0 :     gdd->dummy_sf.ascent = sf->ascent;
    1374           0 :     gdd->dummy_sf.descent = sf->descent;
    1375           0 :     gdd->dummy_sf.layers = gdd->layerinfo;
    1376           0 :     gdd->dummy_sf.layer_cnt = 2;
    1377           0 :     gdd->layerinfo[ly_back].order2 = sf->layers[ly_back].order2;
    1378           0 :     gdd->layerinfo[ly_back].name = _("Back");
    1379           0 :     gdd->layerinfo[ly_fore].order2 = sf->layers[ly_fore].order2;
    1380           0 :     gdd->layerinfo[ly_fore].name = _("Fore");
    1381           0 :     gdd->dummy_sf.grid.order2 = sf->grid.order2;
    1382           0 :     gdd->dummy_sf.anchor = NULL;
    1383             : 
    1384           0 :     gdd->dummy_sf.fv = (FontViewBase *) &gdd->dummy_fv;
    1385           0 :     gdd->dummy_fv.b.active_layer = ly_fore;
    1386           0 :     gdd->dummy_fv.b.sf = &gdd->dummy_sf;
    1387           0 :     gdd->dummy_fv.b.selected = gdd->sel;
    1388           0 :     gdd->dummy_fv.cbw = gdd->dummy_fv.cbh = default_fv_font_size+1;
    1389           0 :     gdd->dummy_fv.magnify = 1;
    1390             : 
    1391           0 :     gdd->dummy_fv.b.map = &gdd->dummy_map;
    1392           0 :     gdd->dummy_map.map = gdd->map;
    1393           0 :     gdd->dummy_map.backmap = gdd->backmap;
    1394           0 :     gdd->dummy_map.enccount = gdd->dummy_map.encmax = gdd->dummy_map.backmax = 1;
    1395           0 :     gdd->dummy_map.enc = &custom;
    1396             : 
    1397           0 :     if ( grad!=NULL ) {
    1398             :         SplineSet *ss1, *ss2;
    1399             :         SplinePoint *sp1, *sp2, *sp3;
    1400           0 :         ss1 = chunkalloc(sizeof(SplineSet));
    1401           0 :         sp2 = SplinePointCreate(grad->stop.x,grad->stop.y);
    1402           0 :         if ( grad->radius==0 ) {
    1403           0 :             sp1 = SplinePointCreate(grad->start.x,grad->start.y);
    1404           0 :             SplineMake(sp1,sp2,sf->layers[ly_fore].order2);
    1405           0 :             ss1->first = sp1; ss1->last = sp2;
    1406             :         } else {
    1407           0 :             sp3 = SplinePointCreate(grad->start.x+grad->radius,grad->start.y);
    1408           0 :             SplineMake(sp2,sp3,sf->layers[ly_fore].order2);
    1409           0 :             ss1->first = sp2; ss1->last = sp3;
    1410           0 :             if ( grad->start.x!=grad->stop.x || grad->start.y!=grad->stop.y ) {
    1411           0 :                 ss2 = chunkalloc(sizeof(SplineSet));
    1412           0 :                 sp1 = SplinePointCreate(grad->start.x,grad->start.y);
    1413           0 :                 ss2->first = ss2->last = sp1;
    1414           0 :                 ss1->next = ss2;
    1415             :             }
    1416             :         }
    1417           0 :         gdd->sc_grad.layers[ly_fore].splines = ss1;
    1418             :     }
    1419             : 
    1420           0 :     gdd->sc_grad.layers[ly_back]. splines = SplinePointListCopy( LayerAllSplines(ly));
    1421           0 :     LayerUnAllSplines(ly);
    1422           0 : }
    1423             : 
    1424             : static struct col_init stopci[] = {
    1425             :     { me_real , NULL, NULL, NULL, N_("Offset %") },
    1426             :     { me_hex, NULL, NULL, NULL, N_("Color") },
    1427             :     { me_real, NULL, NULL, NULL, N_("Opacity") }
    1428             :     };
    1429             : 
    1430           0 : static int Grad_CanDelete(GGadget *g,int row) {
    1431             :     int rows;
    1432           0 :     struct matrix_data *md = GMatrixEditGet(g, &rows);
    1433           0 :     if ( md==NULL )
    1434           0 : return( false );
    1435             : 
    1436             :     /* There must always be at least two entries in the table */
    1437           0 : return( rows>2 );
    1438             : }
    1439             : 
    1440           0 : static void Grad_NewRow(GGadget *g,int row) {
    1441             :     int rows;
    1442           0 :     struct matrix_data *md = GMatrixEditGet(g, &rows);
    1443           0 :     if ( md==NULL )
    1444           0 : return;
    1445             : 
    1446           0 :     md[3*row+2].u.md_real = 1.0;
    1447             : }
    1448             : 
    1449           0 : static void StopMatrixInit(struct matrixinit *mi,struct gradient *grad) {
    1450             :     int i;
    1451             :     struct matrix_data *md;
    1452             : 
    1453           0 :     memset(mi,0,sizeof(*mi));
    1454           0 :     mi->col_cnt = 3;
    1455           0 :     mi->col_init = stopci;
    1456             : 
    1457           0 :     if ( grad==NULL ) {
    1458           0 :         md = calloc(2*mi->col_cnt,sizeof(struct matrix_data));
    1459           0 :         md[3*0+0].u.md_real = 0;
    1460           0 :         md[3*0+1].u.md_ival = 0x000000;
    1461           0 :         md[3*0+2].u.md_real = 1;
    1462           0 :         md[3*1+0].u.md_real = 100;
    1463           0 :         md[3*1+1].u.md_ival = 0xffffff;
    1464           0 :         md[3*1+2].u.md_real = 1;
    1465           0 :         mi->initial_row_cnt = 2;
    1466             :     } else {
    1467           0 :         md = calloc(3*grad->stop_cnt,sizeof(struct matrix_data));
    1468           0 :         for ( i=0; i<grad->stop_cnt; ++i ) {
    1469           0 :             md[3*i+0].u.md_real = grad->grad_stops[i].offset*100.0;
    1470           0 :             md[3*i+1].u.md_ival = grad->grad_stops[i].col;
    1471           0 :             md[3*i+2].u.md_real = grad->grad_stops[i].opacity;
    1472             :         }
    1473           0 :         mi->initial_row_cnt = grad->stop_cnt;
    1474             :     }
    1475           0 :     mi->matrix_data = md;
    1476             : 
    1477           0 :     mi->initrow = Grad_NewRow;
    1478           0 :     mi->candelete = Grad_CanDelete;
    1479           0 : }
    1480             : 
    1481           0 : static struct gradient *GradientEdit(struct layer_dlg *ld,struct gradient *active) {
    1482             :     GradientDlg gdd;
    1483             :     GRect pos;
    1484             :     GWindow gw;
    1485             :     GWindowAttrs wattrs;
    1486             :     GGadgetCreateData gcd[14], boxes[5], *harray[8], *varray[10],
    1487             :         *rharray[5], *gtarray[5];
    1488             :     GTextInfo label[14];
    1489             :     int j,k;
    1490             :     struct matrixinit stopmi;
    1491             : 
    1492           0 :     GDDInit( &gdd,ld->sf,ld->layer,active );
    1493           0 :     gdd.active = active;
    1494             : 
    1495           0 :     memset(&wattrs,0,sizeof(wattrs));
    1496           0 :     wattrs.mask = wam_events|wam_cursor|wam_isdlg|wam_restrict|wam_undercursor|wam_utf8_wtitle;
    1497           0 :     wattrs.is_dlg = true;
    1498           0 :     wattrs.restrict_input_to_me = 1;
    1499           0 :     wattrs.undercursor = 1;
    1500           0 :     wattrs.event_masks = -1;
    1501           0 :     wattrs.cursor = ct_pointer;
    1502           0 :     wattrs.utf8_window_title = _("Gradient");
    1503           0 :     pos.width = 600;
    1504           0 :     pos.height = 300;
    1505           0 :     gdd.gw = gw = GDrawCreateTopWindow(NULL,&pos,gdd_e_h,&gdd.cv_grad,&wattrs);
    1506             : 
    1507           0 :     memset(&label,0,sizeof(label));
    1508           0 :     memset(&gcd,0,sizeof(gcd));
    1509           0 :     memset(&boxes,0,sizeof(boxes));
    1510             : 
    1511           0 :     k = j = 0;
    1512           0 :     gcd[k].gd.flags = gg_visible|gg_enabled ;           /* This space is for the menubar */
    1513           0 :     gcd[k].gd.pos.height = 18; gcd[k].gd.pos.width = 20;
    1514           0 :     gcd[k++].creator = GSpacerCreate;
    1515           0 :     varray[j++] = &gcd[k-1];
    1516             : 
    1517           0 :     label[k].text = (unichar_t *) _(
    1518             :         "  A linear gradient is represented by a line drawn\n"
    1519             :         "from its start point to its end point.\n"
    1520             :         "  A radial gradient is represented by a line drawn\n"
    1521             :         "from its center whose length is the ultimate radius.\n"
    1522             :         "If there is a single additional point, that point\n"
    1523             :         "represents the gradient's focus, if omitted the focus\n"
    1524             :         "is the same as the radius." );
    1525           0 :     label[k].text_is_1byte = true;
    1526           0 :     gcd[k].gd.label = &label[k];
    1527           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    1528           0 :     gcd[k++].creator = GLabelCreate;
    1529           0 :     varray[j++] = &gcd[k-1];
    1530             : 
    1531           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1532           0 :     label[k].text = (unichar_t *) _("Linear");
    1533           0 :     label[k].text_is_1byte = true;
    1534           0 :     label[k].text_in_resource = true;
    1535           0 :     gcd[k].gd.label = &label[k];
    1536           0 :     gcd[k].gd.popup_msg = (unichar_t *) _(
    1537             :             "The gradient will be a linear gradient,\n"
    1538             :             "With the color change happening along\n"
    1539             :             "the line drawn in the view" );
    1540           0 :     gcd[k].gd.cid = CID_Linear;
    1541           0 :     gcd[k++].creator = GRadioCreate;
    1542           0 :     gtarray[0] = &gcd[k-1];
    1543             : 
    1544           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1545           0 :     label[k].text = (unichar_t *) _("Radial");
    1546           0 :     label[k].text_is_1byte = true;
    1547           0 :     label[k].text_in_resource = true;
    1548           0 :     gcd[k].gd.label = &label[k];
    1549           0 :     gcd[k].gd.popup_msg = (unichar_t *) _(
    1550             :             "The gradient will be a radial gradient,\n"
    1551             :             "With the color change happening in circles\n"
    1552             :             "starting at the focus (if specified) and\n"
    1553             :             "extending outward until it reaches the\n"
    1554             :             "specified radius." );
    1555           0 :     gcd[k].gd.cid = CID_Radial;
    1556           0 :     gcd[k++].creator = GRadioCreate;
    1557           0 :     gtarray[1] = &gcd[k-1]; gtarray[2] = GCD_Glue; gtarray[3] = NULL;
    1558             : 
    1559           0 :     boxes[4].gd.flags = gg_enabled|gg_visible;
    1560           0 :     boxes[4].gd.u.boxelements = gtarray;
    1561           0 :     boxes[4].creator = GHBoxCreate;
    1562           0 :     varray[j++] = &boxes[4];
    1563             : 
    1564           0 :     gcd[k].gd.pos.width = gcd[k].gd.pos.height = 200;
    1565           0 :     gcd[k].gd.flags = gg_visible | gg_enabled;
    1566           0 :     gcd[k].gd.cid = CID_Gradient;
    1567           0 :     gcd[k].gd.u.drawable_e_h = gdd_sub_e_h;
    1568           0 :     gcd[k++].creator = GDrawableCreate;
    1569           0 :     varray[j++] = &gcd[k-1];
    1570             : 
    1571           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1572           0 :     label[k].text = (unichar_t *) _("_Pad");
    1573           0 :     label[k].text_is_1byte = true;
    1574           0 :     label[k].text_in_resource = true;
    1575           0 :     gcd[k].gd.label = &label[k];
    1576           0 :     gcd[k].gd.popup_msg = (unichar_t *) _("Beyond the endpoints, the gradient takes on the color at the end-points\n"
    1577             :                 "This does not work for PostScript linear gradients");
    1578           0 :     gcd[k].gd.cid = CID_Pad;
    1579           0 :     gcd[k++].creator = GRadioCreate;
    1580           0 :     rharray[0] = &gcd[k-1];
    1581             : 
    1582           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1583           0 :     label[k].text = (unichar_t *) _("Repeat");
    1584           0 :     label[k].text_is_1byte = true;
    1585           0 :     label[k].text_in_resource = true;
    1586           0 :     gcd[k].gd.label = &label[k];
    1587           0 :     gcd[k].gd.popup_msg = (unichar_t *) _("Beyond the endpoints the gradient repeats itself\n"
    1588             :             "This does not work for PostScript gradients." );
    1589           0 :     gcd[k].gd.cid = CID_Repeat;
    1590           0 :     gcd[k++].creator = GRadioCreate;
    1591           0 :     rharray[1] = &gcd[k-1];
    1592             : 
    1593           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    1594           0 :     label[k].text = (unichar_t *) _("Reflect");
    1595           0 :     label[k].text_is_1byte = true;
    1596           0 :     label[k].text_in_resource = true;
    1597           0 :     gcd[k].gd.label = &label[k];
    1598           0 :     gcd[k].gd.popup_msg = (unichar_t *) _("Beyond the endpoint the gradient repeats itself, but reflected.\n"
    1599             :             "This does not work for PostScript gradients");
    1600           0 :     gcd[k].gd.cid = CID_Reflect;
    1601           0 :     gcd[k++].creator = GRadioCreate;
    1602           0 :     rharray[2] = &gcd[k-1];
    1603           0 :     rharray[3] = GCD_Glue; rharray[4] = NULL;
    1604             : 
    1605           0 :     boxes[2].gd.flags = gg_enabled|gg_visible;
    1606           0 :     boxes[2].gd.u.boxelements = rharray;
    1607           0 :     boxes[2].creator = GHBoxCreate;
    1608           0 :     varray[j++] = &boxes[2];
    1609             : 
    1610           0 :     label[k].text = (unichar_t *) _(
    1611             :             "Specify the color (& opacity) at stop points\n"
    1612             :             "along the line drawn above. The offset is a\n"
    1613             :             "percentage of the distance from the start to\n"
    1614             :             "the end of the line. The color is a 6 (hex)\n"
    1615             :             "digit number expressing an RGB color.");
    1616           0 :     label[k].text_is_1byte = true;
    1617           0 :     gcd[k].gd.label = &label[k];
    1618           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    1619           0 :     gcd[k++].creator = GLabelCreate;
    1620           0 :     varray[j++] = &gcd[k-1];
    1621             : 
    1622           0 :     StopMatrixInit(&stopmi,active);
    1623             : 
    1624           0 :     gcd[k].gd.pos.width = 300; gcd[k].gd.pos.height = 200;
    1625           0 :     gcd[k].gd.flags = gg_enabled | gg_visible | gg_utf8_popup;
    1626           0 :     gcd[k].gd.cid = CID_GradStops;
    1627           0 :     gcd[k].gd.u.matrix = &stopmi;
    1628           0 :     gcd[k++].creator = GMatrixEditCreate;
    1629           0 :     varray[j++] = &gcd[k-1];
    1630             : 
    1631           0 :     label[k].text = (unichar_t *) _("_OK");
    1632           0 :     label[k].text_is_1byte = true;
    1633           0 :     label[k].text_in_resource = true;
    1634           0 :     gcd[k].gd.label = &label[k];
    1635           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_but_default;
    1636           0 :     gcd[k].gd.handle_controlevent = Gradient_OK;
    1637           0 :     gcd[k++].creator = GButtonCreate;
    1638             : 
    1639           0 :     label[k].text = (unichar_t *) _("_Cancel");
    1640           0 :     label[k].text_is_1byte = true;
    1641           0 :     label[k].text_in_resource = true;
    1642           0 :     gcd[k].gd.label = &label[k];
    1643           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_but_cancel;
    1644           0 :     gcd[k].gd.handle_controlevent = Gradient_Cancel;
    1645           0 :     gcd[k++].creator = GButtonCreate;
    1646             : 
    1647           0 :     harray[0] = GCD_Glue; harray[1] = &gcd[k-2]; harray[2] = GCD_Glue;
    1648           0 :     harray[3] = GCD_Glue; harray[4] = &gcd[k-1]; harray[5] = GCD_Glue;
    1649           0 :     harray[6] = NULL;
    1650             : 
    1651           0 :     boxes[3].gd.flags = gg_enabled|gg_visible;
    1652           0 :     boxes[3].gd.u.boxelements = harray;
    1653           0 :     boxes[3].creator = GHBoxCreate;
    1654           0 :     varray[j++] = &boxes[3];
    1655           0 :     varray[j] = NULL;
    1656             : 
    1657           0 :     boxes[0].gd.flags = gg_enabled|gg_visible;
    1658           0 :     boxes[0].gd.u.boxelements = varray;
    1659           0 :     boxes[0].creator = GVBoxCreate;
    1660             : 
    1661           0 :     GGadgetsCreate(gw,boxes);
    1662             : 
    1663           0 :     GDDCharViewInits(&gdd,CID_Gradient);
    1664             : 
    1665           0 :     GHVBoxSetExpandableRow(boxes[0].ret,3);
    1666           0 :     GHVBoxSetExpandableCol(boxes[2].ret,gb_expandgluesame);
    1667           0 :     GHVBoxSetExpandableRow(boxes[3].ret,gb_expandgluesame);
    1668           0 :     GGadgetResize(boxes[0].ret,pos.width,pos.height);
    1669             : 
    1670           0 :     if ( active!=NULL ) {
    1671           0 :         GGadgetSetChecked(GWidgetGetControl(gw,CID_Linear),active->radius==0);
    1672           0 :         GGadgetSetChecked(GWidgetGetControl(gw,CID_Radial),active->radius!=0);
    1673           0 :         GGadgetSetChecked(GWidgetGetControl(gw,CID_Pad),active->sm==sm_pad);
    1674           0 :         GGadgetSetChecked(GWidgetGetControl(gw,CID_Reflect),active->sm==sm_reflect);
    1675           0 :         GGadgetSetChecked(GWidgetGetControl(gw,CID_Repeat),active->sm==sm_repeat);
    1676             :     } else {
    1677           0 :         GGadgetSetChecked(GWidgetGetControl(gw,CID_Linear),true);
    1678           0 :         GGadgetSetChecked(GWidgetGetControl(gw,CID_Pad),true);
    1679             :     }
    1680             : 
    1681           0 :     GDDMakeActive(&gdd,&gdd.cv_grad);
    1682             : 
    1683           0 :     GDrawResize(gw,400,768);            /* Force a resize event */
    1684             : 
    1685           0 :     GDrawSetVisible(gdd.gw,true);
    1686             : 
    1687           0 :     while ( !gdd.done )
    1688           0 :         GDrawProcessOneEvent(NULL);
    1689             : 
    1690             :     {
    1691           0 :         CharView *cv = &gdd.cv_grad;
    1692           0 :         if ( cv->backimgs!=NULL ) {
    1693           0 :             GDrawDestroyWindow(cv->backimgs);
    1694           0 :             cv->backimgs = NULL;
    1695             :         }
    1696           0 :         CVPalettesHideIfMine(cv);
    1697             :     }
    1698           0 :     GDrawDestroyWindow(gdd.gw);
    1699             :     /* Now because the cv of the nested window is on the stack, we need to */
    1700             :     /*  handle its destruction HERE while that stack location still makes */
    1701             :     /*  sense. Can't do it in whoever calls us */
    1702           0 :     GDrawSync(NULL);
    1703           0 :     GDrawProcessPendingEvents(NULL);
    1704           0 :     GDrawSync(NULL);
    1705           0 :     GDrawProcessPendingEvents(NULL);
    1706           0 : return( gdd.active );
    1707             : }
    1708             : 
    1709           0 : static void Layer_GradSet(struct layer_dlg *ld) {
    1710           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_FillGradAdd),ld->fillgrad==NULL);
    1711           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_FillGradEdit),ld->fillgrad!=NULL);
    1712           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_FillGradDelete),ld->fillgrad!=NULL);
    1713           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_StrokeGradAdd),ld->strokegrad==NULL);
    1714           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_StrokeGradEdit),ld->strokegrad!=NULL);
    1715           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_StrokeGradDelete),ld->strokegrad!=NULL);
    1716           0 : }
    1717             : 
    1718           0 : static int Layer_FillGradDelete(GGadget *g, GEvent *e) {
    1719             : 
    1720           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1721           0 :         struct layer_dlg *ld = GDrawGetUserData(GGadgetGetWindow(g));
    1722           0 :         GradientFree(ld->fillgrad);
    1723           0 :         ld->fillgrad=NULL;
    1724           0 :         Layer_GradSet(ld);
    1725             :     }
    1726           0 : return( true );
    1727             : }
    1728             : 
    1729           0 : static int Layer_FillGradAddEdit(GGadget *g, GEvent *e) {
    1730             : 
    1731           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1732           0 :         struct layer_dlg *ld = GDrawGetUserData(GGadgetGetWindow(g));
    1733           0 :         ld->fillgrad = GradientEdit(ld,ld->fillgrad);
    1734           0 :         Layer_GradSet(ld);
    1735             :     }
    1736           0 : return( true );
    1737             : }
    1738             : 
    1739           0 : static int Layer_StrokeGradDelete(GGadget *g, GEvent *e) {
    1740             : 
    1741           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1742           0 :         struct layer_dlg *ld = GDrawGetUserData(GGadgetGetWindow(g));
    1743           0 :         GradientFree(ld->strokegrad);
    1744           0 :         ld->strokegrad=NULL;
    1745           0 :         Layer_GradSet(ld);
    1746             :     }
    1747           0 : return( true );
    1748             : }
    1749             : 
    1750           0 : static int Layer_StrokeGradAddEdit(GGadget *g, GEvent *e) {
    1751             : 
    1752           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1753           0 :         struct layer_dlg *ld = GDrawGetUserData(GGadgetGetWindow(g));
    1754           0 :         ld->strokegrad = GradientEdit(ld,ld->strokegrad);
    1755           0 :         Layer_GradSet(ld);
    1756             :     }
    1757           0 : return( true );
    1758             : }
    1759             : 
    1760             : #define CID_PatternName 1001
    1761             : #define CID_Skew        1002
    1762             : #define CID_Rotate      1003
    1763             : #define CID_TransX      1004
    1764             : #define CID_TransY      1005
    1765             : #define CID_Transform   1006
    1766             : #define CID_Aspect      1007
    1767             : #define CID_TWidth      1008
    1768             : #define CID_THeight     1009
    1769             : 
    1770           0 : static int Pat_WidthChanged(GGadget *g, GEvent *e) {
    1771             : 
    1772           0 :     if ( e->type==et_controlevent &&
    1773           0 :             (e->u.control.subtype == et_textchanged ||
    1774           0 :              e->u.control.subtype == et_radiochanged)) {
    1775           0 :         GWindow gw = GGadgetGetWindow(g);
    1776           0 :         struct layer_dlg *ld = GDrawGetUserData(gw);
    1777           0 :         char *name = GGadgetGetTitle8(GWidgetGetControl(gw,CID_PatternName));
    1778           0 :         SplineChar *patternsc = SFGetChar(ld->sf,-1,name);
    1779             :         DBounds b;
    1780           0 :         int err = false;
    1781             :         real height, width;
    1782             :         char buffer[50];
    1783             : 
    1784           0 :         free(name);
    1785           0 :         if ( patternsc==NULL )
    1786           0 : return( true );
    1787           0 :         if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_Aspect)))
    1788           0 : return( true );
    1789           0 :         width = GetCalmReal8(gw,CID_TWidth,_("Width"),&err);
    1790           0 :         if ( err )
    1791           0 : return( true );
    1792           0 :         PatternSCBounds(patternsc,&b);
    1793           0 :         height = width * (b.maxy - b.miny)/(b.maxx - b.minx);
    1794           0 :         sprintf( buffer, "%g", (double) height );
    1795           0 :         GGadgetSetTitle8(GWidgetGetControl(gw,CID_THeight), buffer);
    1796             :     }
    1797           0 : return( true );
    1798             : }
    1799             : 
    1800           0 : static int Pat_HeightChanged(GGadget *g, GEvent *e) {
    1801             : 
    1802           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_textchanged ) {
    1803           0 :         GWindow gw = GGadgetGetWindow(g);
    1804           0 :         struct layer_dlg *ld = GDrawGetUserData(gw);
    1805           0 :         char *name = GGadgetGetTitle8(GWidgetGetControl(gw,CID_PatternName));
    1806           0 :         SplineChar *patternsc = SFGetChar(ld->sf,-1,name);
    1807             :         DBounds b;
    1808           0 :         int err = false;
    1809             :         real height, width;
    1810             :         char buffer[50];
    1811             : 
    1812           0 :         free(name);
    1813           0 :         if ( patternsc==NULL )
    1814           0 : return( true );
    1815           0 :         if ( !GGadgetIsChecked(GWidgetGetControl(gw,CID_Aspect)))
    1816           0 : return( true );
    1817           0 :         height = GetCalmReal8(gw,CID_THeight,_("Height"),&err);
    1818           0 :         if ( err )
    1819           0 : return( true );
    1820           0 :         PatternSCBounds(patternsc,&b);
    1821           0 :         width = height * (b.maxx - b.minx)/(b.maxy - b.miny);
    1822           0 :         sprintf( buffer, "%g", (double) width );
    1823           0 :         GGadgetSetTitle8(GWidgetGetControl(gw,CID_TWidth), buffer);
    1824             :     }
    1825           0 : return( true );
    1826             : }
    1827             : 
    1828           0 : static int Pat_TransformChanged(GGadget *g, GEvent *e) {
    1829             : 
    1830           0 :     if ( e==NULL ||
    1831           0 :             (e->type==et_controlevent && e->u.control.subtype == et_textchanged )) {
    1832           0 :         GWindow gw = GGadgetGetWindow(g);
    1833             :         double trans[6];
    1834           0 :         char *name = GGadgetGetTitle8(g);
    1835             :         double c, s, t;
    1836             :         char buffer[50];
    1837             : 
    1838           0 :         if ( sscanf( name, "[%lg %lg %lg %lg %lg %lg]", &trans[0], &trans[1], &trans[2],
    1839             :                 &trans[3], &trans[4], &trans[5])!=6 ) {
    1840           0 :             free(name );
    1841           0 : return( true );
    1842             :         }
    1843           0 :         free(name );
    1844             : 
    1845           0 :         c = trans[0]; s = trans[1];
    1846           0 :         if ( c!=0 )
    1847           0 :             t = (trans[2]+s)/c;
    1848           0 :         else if ( s!=0 )
    1849           0 :             t = (trans[3]-c)/s;
    1850             :         else
    1851           0 :             t = 9999;
    1852           0 :         if ( RealWithin(c*c+s*s,1,.005) && RealWithin(t*c-s,trans[2],.01) && RealWithin(t*s+c,trans[3],.01)) {
    1853           0 :             double skew = atan(t)*180/3.1415926535897932;
    1854           0 :             double rot  = atan2(s,c)*180/3.1415926535897932;
    1855           0 :             sprintf( buffer, "%g", skew );
    1856           0 :             GGadgetSetTitle8(GWidgetGetControl(gw,CID_Skew), buffer);
    1857           0 :             sprintf( buffer, "%g", rot );
    1858           0 :             GGadgetSetTitle8(GWidgetGetControl(gw,CID_Rotate), buffer);
    1859           0 :             sprintf( buffer, "%g", trans[4] );
    1860           0 :             GGadgetSetTitle8(GWidgetGetControl(gw,CID_TransX), buffer);
    1861           0 :             sprintf( buffer, "%g", trans[5] );
    1862           0 :             GGadgetSetTitle8(GWidgetGetControl(gw,CID_TransY), buffer);
    1863             :         } else {
    1864           0 :             GGadgetSetTitle8(GWidgetGetControl(gw,CID_Skew), "");
    1865           0 :             GGadgetSetTitle8(GWidgetGetControl(gw,CID_Rotate), "");
    1866           0 :             GGadgetSetTitle8(GWidgetGetControl(gw,CID_TransX), "");
    1867           0 :             GGadgetSetTitle8(GWidgetGetControl(gw,CID_TransY), "");
    1868             :         }
    1869             :     }
    1870           0 : return( true );
    1871             : }
    1872             : 
    1873           0 : static int Pat_AnglesChanged(GGadget *g, GEvent *e) {
    1874             : 
    1875           0 :     if ( e==NULL ||
    1876           0 :             (e->type==et_controlevent && e->u.control.subtype == et_textchanged )) {
    1877           0 :         GWindow gw = GGadgetGetWindow(g);
    1878             :         double rotate, skew, x, y;
    1879             :         double c, s, t;
    1880             :         char buffer[340];
    1881           0 :         int err=false;
    1882             : 
    1883           0 :         skew   = GetCalmReal8(gw,CID_Skew,_("Skew"),&err)*3.1415926535897932/180;
    1884           0 :         rotate = GetCalmReal8(gw,CID_Rotate,_("Rotate"),&err)*3.1415926535897932/180;
    1885           0 :         x      = GetCalmReal8(gw,CID_TransX,_("Translation in X"),&err);
    1886           0 :         y      = GetCalmReal8(gw,CID_TransY,_("Translation in Y"),&err);
    1887           0 :         if ( err )
    1888           0 : return( true );
    1889           0 :         t = tan(skew);
    1890           0 :         c = cos(rotate); s = sin(rotate);
    1891           0 :         sprintf( buffer, "[%g %g %g %g %g %g]", c, s, t*c-s, t*s+c, x, y );
    1892           0 :         GGadgetSetTitle8(GWidgetGetControl(gw,CID_Transform),buffer );
    1893             :     }
    1894           0 : return( true );
    1895             : }
    1896             : 
    1897           0 : static unichar_t **Pat_GlyphNameCompletion(GGadget *t,int from_tab) {
    1898           0 :     struct layer_dlg *ld = GDrawGetUserData(GGadgetGetWindow(t));
    1899             : 
    1900           0 : return( SFGlyphNameCompletion(ld->sf,t,from_tab,false));
    1901             : }
    1902             : 
    1903           0 : static int Pat_OK(GGadget *g, GEvent *e) {
    1904           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1905           0 :         GWindow gw = GGadgetGetWindow(g);
    1906           0 :         struct layer_dlg *ld = GDrawGetUserData(gw);
    1907           0 :         char *transstring = GGadgetGetTitle8(GWidgetGetControl(gw,CID_Transform));
    1908             :         char *name;
    1909             :         double width, height;
    1910             :         double trans[6];
    1911             :         int i;
    1912             :         SplineChar *patternsc;
    1913             :         int err;
    1914             : 
    1915           0 :         if ( sscanf( transstring, "[%lg %lg %lg %lg %lg %lg]", &trans[0], &trans[1], &trans[2],
    1916             :                 &trans[3], &trans[4], &trans[5])!=6 ) {
    1917           0 :             free( transstring );
    1918           0 :             ff_post_error(_("Bad Transformation matrix"),_("Bad Transformation matrix"));
    1919           0 : return( true );
    1920             :         }
    1921           0 :         free(transstring);
    1922             : 
    1923           0 :         name = GGadgetGetTitle8(GWidgetGetControl(gw,CID_PatternName));
    1924           0 :         patternsc = SFGetChar(ld->sf,-1,name);
    1925           0 :         if ( patternsc==NULL ) {
    1926           0 :             ff_post_error(_("No Glyph"),_("This font does not contain a glyph named \"%.40s\""), name);
    1927           0 :             free(name);
    1928           0 : return( true );
    1929             :         }
    1930             : 
    1931           0 :         err = false;
    1932           0 :         width = GetReal8(gw,CID_TWidth,_("Width"),&err);
    1933           0 :         height = GetReal8(gw,CID_THeight,_("Height"),&err);
    1934           0 :         if ( err )
    1935           0 : return( true );
    1936             : 
    1937           0 :         if ( ld->curpat == NULL )
    1938           0 :             ld->curpat = chunkalloc(sizeof(struct pattern));
    1939           0 :         free( ld->curpat->pattern );
    1940           0 :         ld->curpat->pattern = name;
    1941           0 :         for ( i=0; i<6; ++i )
    1942           0 :             ld->curpat->transform[i] = trans[i];
    1943           0 :         ld->curpat->width = width;
    1944           0 :         ld->curpat->height = height;
    1945           0 :         ld->pat_done = true;
    1946             :     }
    1947           0 : return( true );
    1948             : }
    1949             : 
    1950           0 : static int Pat_Cancel(GGadget *g, GEvent *e) {
    1951           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    1952           0 :         GWindow gw = GGadgetGetWindow(g);
    1953           0 :         struct layer_dlg *ld = GDrawGetUserData(gw);
    1954           0 :         ld->pat_done = true;
    1955             :     }
    1956           0 : return( true );
    1957             : }
    1958             : 
    1959           0 : static int pat_e_h(GWindow gw, GEvent *event) {
    1960           0 :     struct layer_dlg *ld = GDrawGetUserData(gw);
    1961             : 
    1962           0 :     switch ( event->type ) {
    1963             :       case et_char:
    1964           0 : return( false );
    1965             :       break;
    1966             :       case et_close:
    1967           0 :         ld->pat_done = true;
    1968           0 :       break;
    1969             :     }
    1970           0 : return( true );
    1971             : }
    1972             : 
    1973           0 : static struct pattern *PatternEdit(struct layer_dlg *ld,struct pattern *active) {
    1974             :     GRect pos;
    1975             :     GWindow gw;
    1976             :     GWindowAttrs wattrs;
    1977             :     GGadgetCreateData gcd[25], boxes[5], *harray[8], *varray[10],
    1978             :         *hvarray[42];
    1979             :     GTextInfo label[25];
    1980             :     int j,k;
    1981             :     char *name;
    1982             :     char width[50], height[50], transform[340];
    1983           0 :     int aspect_fixed = true;
    1984             : 
    1985           0 :     ld->pat_done = false;
    1986           0 :     ld->curpat = active;
    1987             : 
    1988           0 :     name = "";
    1989           0 :     width[0] = height[0] = '\0';
    1990           0 :     strcpy(transform,"[1 0 0 1 0 0]");
    1991           0 :     aspect_fixed = true;
    1992           0 :     if ( active!=NULL ) {
    1993           0 :         SplineChar *patternsc = SFGetChar(ld->sf,-1,active->pattern);
    1994           0 :         name = active->pattern;
    1995           0 :         sprintf( width, "%g", (double) active->width );
    1996           0 :         sprintf( height, "%g", (double) active->height );
    1997           0 :         sprintf( transform, "[%g %g %g %g %g %g]",
    1998             :                 (double) active->transform[0], (double) active->transform[1],
    1999             :                 (double) active->transform[2], (double) active->transform[3],
    2000             :                 (double) active->transform[4], (double) active->transform[5]);
    2001           0 :         if ( patternsc!=NULL ) {
    2002             :             DBounds b;
    2003           0 :             PatternSCBounds(patternsc,&b);
    2004           0 :             aspect_fixed = RealNear(active->width*(b.maxy-b.miny),active->height*(b.maxx-b.minx));
    2005             :         }
    2006             :     }
    2007             : 
    2008           0 :     memset(&wattrs,0,sizeof(wattrs));
    2009           0 :     wattrs.mask = wam_events|wam_cursor|wam_isdlg|wam_restrict|wam_undercursor|wam_utf8_wtitle;
    2010           0 :     wattrs.is_dlg = true;
    2011           0 :     wattrs.restrict_input_to_me = 1;
    2012           0 :     wattrs.undercursor = 1;
    2013           0 :     wattrs.event_masks = -1;
    2014           0 :     wattrs.cursor = ct_pointer;
    2015           0 :     wattrs.utf8_window_title = _("Tile Pattern");
    2016           0 :     pos.width = 600;
    2017           0 :     pos.height = 300;
    2018           0 :     gw = GDrawCreateTopWindow(NULL,&pos,pat_e_h,ld,&wattrs);
    2019             : 
    2020           0 :     memset(&label,0,sizeof(label));
    2021           0 :     memset(&gcd,0,sizeof(gcd));
    2022           0 :     memset(&boxes,0,sizeof(boxes));
    2023             : 
    2024           0 :     k = j = 0;
    2025             : 
    2026           0 :     label[k].text = (unichar_t *) _(
    2027             :         "The pattern itself should be drawn in another glyph\n"
    2028             :         "of the current font. Specify a glyph name:");
    2029           0 :     label[k].text_is_1byte = true;
    2030           0 :     gcd[k].gd.label = &label[k];
    2031           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    2032           0 :     gcd[k++].creator = GLabelCreate;
    2033           0 :     varray[j++] = &gcd[k-1];
    2034             : 
    2035           0 :     label[k].text = (unichar_t *) name;
    2036           0 :     label[k].text_is_1byte = true;
    2037           0 :     gcd[k].gd.label = &label[k];
    2038           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    2039           0 :     gcd[k].gd.handle_controlevent = Pat_WidthChanged;           /* That will make sure the aspect ratio stays correct */
    2040           0 :     gcd[k].gd.cid = CID_PatternName;
    2041           0 :     gcd[k++].creator = GTextCompletionCreate;
    2042           0 :     varray[j++] = &gcd[k-1];
    2043             : 
    2044           0 :     gcd[k].gd.flags = gg_visible | gg_enabled | gg_utf8_popup;
    2045           0 :     if ( aspect_fixed )
    2046           0 :         gcd[k].gd.flags |= gg_cb_on;
    2047           0 :     label[k].text = (unichar_t *) _("Aspect Ratio same as Tile Glyph");
    2048           0 :     label[k].text_is_1byte = true;
    2049           0 :     label[k].text_in_resource = true;
    2050           0 :     gcd[k].gd.label = &label[k];
    2051           0 :     gcd[k].gd.cid = CID_Aspect;
    2052           0 :     gcd[k].gd.handle_controlevent = Pat_WidthChanged;           /* That will make sure the aspect ratio stays correct */
    2053           0 :     gcd[k++].creator = GCheckBoxCreate;
    2054           0 :     varray[j++] = &gcd[k-1];
    2055             : 
    2056           0 :     label[k].text = (unichar_t *) _("Width:");
    2057           0 :     label[k].text_is_1byte = true;
    2058           0 :     gcd[k].gd.label = &label[k];
    2059           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    2060           0 :     gcd[k++].creator = GLabelCreate;
    2061           0 :     hvarray[0] = &gcd[k-1];
    2062             : 
    2063           0 :     label[k].text = (unichar_t *) width;
    2064           0 :     label[k].text_is_1byte = true;
    2065           0 :     gcd[k].gd.label = &label[k];
    2066           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    2067           0 :     gcd[k].gd.handle_controlevent = Pat_WidthChanged;
    2068           0 :     gcd[k].gd.cid = CID_TWidth;
    2069           0 :     gcd[k++].creator = GTextFieldCreate;
    2070           0 :     hvarray[1] = &gcd[k-1]; hvarray[2] = GCD_Glue; hvarray[3] = NULL;
    2071             : 
    2072           0 :     label[k].text = (unichar_t *) _("Height:");
    2073           0 :     label[k].text_is_1byte = true;
    2074           0 :     gcd[k].gd.label = &label[k];
    2075           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    2076           0 :     gcd[k++].creator = GLabelCreate;
    2077           0 :     hvarray[4] = &gcd[k-1];
    2078             : 
    2079           0 :     label[k].text = (unichar_t *) height;
    2080           0 :     label[k].text_is_1byte = true;
    2081           0 :     gcd[k].gd.label = &label[k];
    2082           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    2083           0 :     gcd[k].gd.handle_controlevent = Pat_HeightChanged;
    2084           0 :     gcd[k].gd.cid = CID_THeight;
    2085           0 :     gcd[k++].creator = GTextFieldCreate;
    2086           0 :     hvarray[5] = &gcd[k-1]; hvarray[6] = GCD_Glue; hvarray[7] = NULL;
    2087             : 
    2088           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    2089           0 :     gcd[k++].creator = GLineCreate;
    2090           0 :     hvarray[8] = &gcd[k-1];
    2091           0 :     hvarray[9] = GCD_ColSpan; hvarray[10] = GCD_Glue; hvarray[11] = NULL;
    2092             : 
    2093           0 :     label[k].text = (unichar_t *) _("Rotate:");
    2094           0 :     label[k].text_is_1byte = true;
    2095           0 :     gcd[k].gd.label = &label[k];
    2096           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    2097           0 :     gcd[k++].creator = GLabelCreate;
    2098           0 :     hvarray[12] = &gcd[k-1];
    2099             : 
    2100           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    2101           0 :     gcd[k].gd.handle_controlevent = Pat_AnglesChanged;
    2102           0 :     gcd[k].gd.cid = CID_Rotate;
    2103           0 :     gcd[k++].creator = GTextFieldCreate;
    2104           0 :     hvarray[13] = &gcd[k-1]; hvarray[14] = GCD_Glue; hvarray[15] = NULL;
    2105             : 
    2106           0 :     label[k].text = (unichar_t *) _("Skew:");
    2107           0 :     label[k].text_is_1byte = true;
    2108           0 :     gcd[k].gd.label = &label[k];
    2109           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    2110           0 :     gcd[k++].creator = GLabelCreate;
    2111           0 :     hvarray[16] = &gcd[k-1];
    2112             : 
    2113           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    2114           0 :     gcd[k].gd.handle_controlevent = Pat_AnglesChanged;
    2115           0 :     gcd[k].gd.cid = CID_Skew;
    2116           0 :     gcd[k++].creator = GTextFieldCreate;
    2117           0 :     hvarray[17] = &gcd[k-1]; hvarray[18] = GCD_Glue; hvarray[19] = NULL;
    2118             : 
    2119           0 :     label[k].text = (unichar_t *) _("Translate By");
    2120           0 :     label[k].text_is_1byte = true;
    2121           0 :     gcd[k].gd.label = &label[k];
    2122           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    2123           0 :     gcd[k++].creator = GLabelCreate;
    2124           0 :     hvarray[20] = &gcd[k-1];
    2125           0 :     hvarray[21] = GCD_ColSpan; hvarray[22] = GCD_Glue; hvarray[23] = NULL;
    2126             : 
    2127           0 :     label[k].text = (unichar_t *) _("X:");
    2128           0 :     label[k].text_is_1byte = true;
    2129           0 :     gcd[k].gd.label = &label[k];
    2130           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    2131           0 :     gcd[k++].creator = GLabelCreate;
    2132           0 :     hvarray[24] = &gcd[k-1];
    2133             : 
    2134           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    2135           0 :     gcd[k].gd.handle_controlevent = Pat_AnglesChanged;
    2136           0 :     gcd[k].gd.cid = CID_TransX;
    2137           0 :     gcd[k++].creator = GTextFieldCreate;
    2138           0 :     hvarray[25] = &gcd[k-1]; hvarray[26] = GCD_Glue; hvarray[27] = NULL;
    2139             : 
    2140           0 :     label[k].text = (unichar_t *) _("Y:");
    2141           0 :     label[k].text_is_1byte = true;
    2142           0 :     gcd[k].gd.label = &label[k];
    2143           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    2144           0 :     gcd[k++].creator = GLabelCreate;
    2145           0 :     hvarray[28] = &gcd[k-1];
    2146             : 
    2147           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    2148           0 :     gcd[k].gd.handle_controlevent = Pat_AnglesChanged;
    2149           0 :     gcd[k].gd.cid = CID_TransY;
    2150           0 :     gcd[k++].creator = GTextFieldCreate;
    2151           0 :     hvarray[29] = &gcd[k-1]; hvarray[30] = GCD_Glue; hvarray[31] = NULL;
    2152             : 
    2153           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    2154           0 :     gcd[k++].creator = GLineCreate;
    2155           0 :     hvarray[32] = &gcd[k-1];
    2156           0 :     hvarray[33] = GCD_ColSpan; hvarray[34] = GCD_Glue; hvarray[35] = NULL;
    2157             : 
    2158           0 :     label[k].text = (unichar_t *) _("Transform:");
    2159           0 :     label[k].text_is_1byte = true;
    2160           0 :     gcd[k].gd.label = &label[k];
    2161           0 :     gcd[k].gd.flags = gg_enabled | gg_visible;
    2162           0 :     gcd[k++].creator = GLabelCreate;
    2163           0 :     hvarray[36] = &gcd[k-1];
    2164             : 
    2165           0 :     label[k].text = (unichar_t *) transform;
    2166           0 :     label[k].text_is_1byte = true;
    2167           0 :     gcd[k].gd.label = &label[k];
    2168           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_utf8_popup;
    2169           0 :     gcd[k].gd.handle_controlevent = Pat_TransformChanged;
    2170           0 :     gcd[k].gd.cid = CID_Transform;
    2171           0 :     gcd[k++].creator = GTextFieldCreate;
    2172           0 :     hvarray[37] = &gcd[k-1]; hvarray[38] = GCD_ColSpan; hvarray[39] = NULL;
    2173           0 :     hvarray[40] = NULL;
    2174             : 
    2175           0 :     boxes[2].gd.flags = gg_enabled|gg_visible;
    2176           0 :     boxes[2].gd.u.boxelements = hvarray;
    2177           0 :     boxes[2].creator = GHVBoxCreate;
    2178           0 :     varray[j++] = &boxes[2];
    2179             : 
    2180           0 :     label[k].text = (unichar_t *) _("_OK");
    2181           0 :     label[k].text_is_1byte = true;
    2182           0 :     label[k].text_in_resource = true;
    2183           0 :     gcd[k].gd.label = &label[k];
    2184           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_but_default;
    2185           0 :     gcd[k].gd.handle_controlevent = Pat_OK;
    2186           0 :     gcd[k++].creator = GButtonCreate;
    2187             : 
    2188           0 :     label[k].text = (unichar_t *) _("_Cancel");
    2189           0 :     label[k].text_is_1byte = true;
    2190           0 :     label[k].text_in_resource = true;
    2191           0 :     gcd[k].gd.label = &label[k];
    2192           0 :     gcd[k].gd.flags = gg_enabled|gg_visible|gg_but_cancel;
    2193           0 :     gcd[k].gd.handle_controlevent = Pat_Cancel;
    2194           0 :     gcd[k++].creator = GButtonCreate;
    2195             : 
    2196           0 :     harray[0] = GCD_Glue; harray[1] = &gcd[k-2]; harray[2] = GCD_Glue;
    2197           0 :     harray[3] = GCD_Glue; harray[4] = &gcd[k-1]; harray[5] = GCD_Glue;
    2198           0 :     harray[6] = NULL;
    2199             : 
    2200           0 :     boxes[3].gd.flags = gg_enabled|gg_visible;
    2201           0 :     boxes[3].gd.u.boxelements = harray;
    2202           0 :     boxes[3].creator = GHBoxCreate;
    2203           0 :     varray[j++] = &boxes[3];
    2204           0 :     varray[j++] = GCD_Glue;
    2205           0 :     varray[j] = NULL;
    2206             : 
    2207           0 :     boxes[0].gd.flags = gg_enabled|gg_visible;
    2208           0 :     boxes[0].gd.u.boxelements = varray;
    2209           0 :     boxes[0].creator = GVBoxCreate;
    2210             : 
    2211           0 :     GGadgetsCreate(gw,boxes);
    2212             : 
    2213           0 :     GHVBoxSetExpandableRow(boxes[0].ret,gb_expandglue);
    2214           0 :     GHVBoxSetExpandableCol(boxes[2].ret,2);
    2215           0 :     GHVBoxSetExpandableRow(boxes[3].ret,gb_expandgluesame);
    2216           0 :     GHVBoxFitWindow(boxes[0].ret);
    2217             : 
    2218             : 
    2219           0 :     Pat_TransformChanged(GWidgetGetControl(gw,CID_Transform),NULL);
    2220           0 :     GCompletionFieldSetCompletion(gcd[1].ret,Pat_GlyphNameCompletion);
    2221             : 
    2222           0 :     GDrawSetVisible(gw,true);
    2223             : 
    2224           0 :     while ( !ld->pat_done )
    2225           0 :         GDrawProcessOneEvent(NULL);
    2226             : 
    2227           0 :     GDrawDestroyWindow(gw);
    2228           0 : return( ld->curpat );
    2229             : }
    2230             : 
    2231           0 : static void Layer_PatSet(struct layer_dlg *ld) {
    2232           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_FillPatAdd),ld->fillpat==NULL);
    2233           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_FillPatEdit),ld->fillpat!=NULL);
    2234           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_FillPatDelete),ld->fillpat!=NULL);
    2235           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_StrokePatAdd),ld->strokepat==NULL);
    2236           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_StrokePatEdit),ld->strokepat!=NULL);
    2237           0 :     GGadgetSetEnabled(GWidgetGetControl(ld->gw,CID_StrokePatDelete),ld->strokepat!=NULL);
    2238           0 : }
    2239             : 
    2240           0 : static int Layer_FillPatDelete(GGadget *g, GEvent *e) {
    2241             : 
    2242           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    2243           0 :         struct layer_dlg *ld = GDrawGetUserData(GGadgetGetWindow(g));
    2244           0 :         PatternFree(ld->fillpat);
    2245           0 :         ld->fillpat=NULL;
    2246           0 :         Layer_PatSet(ld);
    2247             :     }
    2248           0 : return( true );
    2249             : }
    2250             : 
    2251           0 : static int Layer_FillPatAddEdit(GGadget *g, GEvent *e) {
    2252             : 
    2253           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    2254           0 :         struct layer_dlg *ld = GDrawGetUserData(GGadgetGetWindow(g));
    2255           0 :         ld->fillpat = PatternEdit(ld,ld->fillpat);
    2256           0 :         Layer_PatSet(ld);
    2257             :     }
    2258           0 : return( true );
    2259             : }
    2260             : 
    2261           0 : static int Layer_StrokePatDelete(GGadget *g, GEvent *e) {
    2262             : 
    2263           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    2264           0 :         struct layer_dlg *ld = GDrawGetUserData(GGadgetGetWindow(g));
    2265           0 :         PatternFree(ld->strokepat);
    2266           0 :         ld->strokepat=NULL;
    2267           0 :         Layer_PatSet(ld);
    2268             :     }
    2269           0 : return( true );
    2270             : }
    2271             : 
    2272           0 : static int Layer_StrokePatAddEdit(GGadget *g, GEvent *e) {
    2273             : 
    2274           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    2275           0 :         struct layer_dlg *ld = GDrawGetUserData(GGadgetGetWindow(g));
    2276           0 :         ld->strokepat = PatternEdit(ld,ld->strokepat);
    2277           0 :         Layer_PatSet(ld);
    2278             :     }
    2279           0 : return( true );
    2280             : }
    2281             : 
    2282           0 : static uint32 getcol(GGadget *g,int *err) {
    2283           0 :     const unichar_t *ret=_GGadgetGetTitle(g);
    2284             :     unichar_t *end;
    2285           0 :     uint32 col = COLOR_INHERITED;
    2286             : 
    2287           0 :     if ( *ret=='#' ) ++ret;
    2288           0 :     col = u_strtol(ret,&end,16);
    2289           0 :     if ( col<0 || col>0xffffff || *end!='\0' ) {
    2290           0 :         *err = true;
    2291           0 :         ff_post_error(_("Bad Color"),_("Bad Color"));
    2292             :     }
    2293           0 : return( col );
    2294             : }
    2295             : 
    2296           0 : static int Layer_OK(GGadget *g, GEvent *e) {
    2297             : 
    2298           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    2299           0 :         GWindow gw = GGadgetGetWindow(g);
    2300           0 :         struct layer_dlg *ld = GDrawGetUserData(GGadgetGetWindow(g));
    2301             :         Layer temp;
    2302           0 :         int err=false;
    2303             :         const unichar_t *ret;
    2304             :         unichar_t *end, *end2;
    2305             :         int i;
    2306             : 
    2307           0 :         LayerDefault(&temp);
    2308           0 :         temp.dofill = GGadgetIsChecked(GWidgetGetControl(gw,CID_Fill));
    2309           0 :         temp.dostroke = GGadgetIsChecked(GWidgetGetControl(gw,CID_Stroke));
    2310           0 :         if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_FillCInherit)) )
    2311           0 :             temp.fill_brush.col = COLOR_INHERITED;
    2312             :         else
    2313           0 :             temp.fill_brush.col = getcol(GWidgetGetControl(gw,CID_FillColor),&err);
    2314           0 :         if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_FillOInherit)) )
    2315           0 :             temp.fill_brush.opacity = -1;
    2316             :         else
    2317           0 :             temp.fill_brush.opacity = GetReal8(gw,CID_FillOpacity,_("Opacity:"),&err);
    2318             : 
    2319           0 :         if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_StrokeCInherit)) )
    2320           0 :             temp.stroke_pen.brush.col = COLOR_INHERITED;
    2321             :         else
    2322           0 :             temp.stroke_pen.brush.col = getcol(GWidgetGetControl(gw,CID_StrokeColor),&err);
    2323           0 :         if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_StrokeOInherit)) )
    2324           0 :             temp.stroke_pen.brush.opacity = -1;
    2325             :         else
    2326           0 :             temp.stroke_pen.brush.opacity = GetReal8(gw,CID_StrokeOpacity,_("Opacity:"),&err);
    2327           0 :         if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_StrokeWInherit)) )
    2328           0 :             temp.stroke_pen.width = WIDTH_INHERITED;
    2329             :         else
    2330           0 :             temp.stroke_pen.width = GetReal8(gw,CID_Width,_("_Width"),&err);
    2331           0 :         if ( err )
    2332           0 : return( true );
    2333             : 
    2334           0 :         ret = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Trans));
    2335           0 :         while ( *ret==' ' || *ret=='[' ) ++ret;
    2336           0 :         temp.stroke_pen.trans[0] = u_strtod(ret,&end);
    2337           0 :         temp.stroke_pen.trans[1] = u_strtod(end,&end);
    2338           0 :         temp.stroke_pen.trans[2] = u_strtod(end,&end);
    2339           0 :         temp.stroke_pen.trans[3] = u_strtod(end,&end2);
    2340           0 :         for ( ret = end2 ; *ret==' ' || *ret==']' ; ++ret );
    2341           0 :         if ( end2==end || *ret!='\0' || temp.stroke_pen.trans[0] ==0 || temp.stroke_pen.trans[3]==0 ) {
    2342           0 :             ff_post_error(_("Bad Transformation Matrix"),_("Bad Transformation Matrix"));
    2343           0 : return( true );
    2344             :         }
    2345           0 :         if ( GGadgetIsChecked(GWidgetGetControl(gw,CID_DashesInherit)) ) {
    2346           0 :             temp.stroke_pen.dashes[0] = 0; temp.stroke_pen.dashes[1] = DASH_INHERITED;
    2347             :         } else {
    2348           0 :             ret = _GGadgetGetTitle(GWidgetGetControl(gw,CID_Dashes));
    2349           0 :             while ( *ret==' ' || *ret=='[' ) ++ret;
    2350           0 :             for ( i=0; ; ++i ) {
    2351           0 :                 long val = u_strtol(ret,&end,10);
    2352           0 :                 if ( *end=='\0' )
    2353           0 :             break;
    2354           0 :                 if ( val<0 || val>255 ) {
    2355           0 :                     ff_post_error(_("Bad dash list"),_("Value out of range"));
    2356           0 : return( true );
    2357           0 :                 } else if ( *end!=' ' ) {
    2358           0 :                     ff_post_error(_("Bad dash list"),_("Bad Number"));
    2359           0 : return( true );
    2360           0 :                 } else if ( i>=DASH_MAX ) {
    2361           0 :                     ff_post_error(_("Bad dash list"),_("Too many dashes (at most %d allowed)"), DASH_MAX);
    2362           0 : return( true );
    2363             :                 }
    2364           0 :                 temp.stroke_pen.dashes[i] = val;
    2365           0 :                 ret = end;
    2366           0 :                 while ( *ret==' ' ) ++ret;
    2367           0 :             }
    2368           0 :             if ( i<DASH_MAX ) temp.stroke_pen.dashes[i] = 0;
    2369             :         }
    2370           0 :         temp.stroke_pen.linecap =
    2371           0 :                 GGadgetIsChecked(GWidgetGetControl(gw,CID_ButtCap))?lc_butt:
    2372           0 :                 GGadgetIsChecked(GWidgetGetControl(gw,CID_RoundCap))?lc_round:
    2373           0 :                 GGadgetIsChecked(GWidgetGetControl(gw,CID_SquareCap))?lc_square:
    2374             :                         lc_inherited;
    2375           0 :         temp.stroke_pen.linejoin =
    2376           0 :                 GGadgetIsChecked(GWidgetGetControl(gw,CID_BevelJoin))?lj_bevel:
    2377           0 :                 GGadgetIsChecked(GWidgetGetControl(gw,CID_RoundJoin))?lj_round:
    2378           0 :                 GGadgetIsChecked(GWidgetGetControl(gw,CID_MiterJoin))?lj_miter:
    2379             :                         lj_inherited;
    2380             : 
    2381           0 :         GradientFree(ld->layer->fill_brush.gradient);
    2382           0 :         PatternFree(ld->layer->fill_brush.pattern);
    2383           0 :         GradientFree(ld->layer->stroke_pen.brush.gradient);
    2384           0 :         PatternFree(ld->layer->stroke_pen.brush.pattern);
    2385             : 
    2386           0 :         ld->done = ld->ok = true;
    2387           0 :         ld->layer->stroke_pen = temp.stroke_pen;
    2388           0 :         ld->layer->fill_brush = temp.fill_brush;
    2389           0 :         ld->layer->dofill = temp.dofill;
    2390           0 :         ld->layer->dostroke = temp.dostroke;
    2391           0 :         ld->layer->fillfirst = temp.fillfirst;
    2392             : 
    2393           0 :         ld->layer->fill_brush.gradient = ld->fillgrad;
    2394           0 :         ld->layer->stroke_pen.brush.gradient = ld->strokegrad;
    2395           0 :         ld->layer->fill_brush.pattern = ld->fillpat;
    2396           0 :         ld->layer->stroke_pen.brush.pattern = ld->strokepat;
    2397             :     }
    2398           0 : return( true );
    2399             : }
    2400             : 
    2401           0 : static int Layer_Cancel(GGadget *g, GEvent *e) {
    2402           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    2403           0 :         struct layer_dlg *ld = GDrawGetUserData(GGadgetGetWindow(g));
    2404           0 :         ld->done = true;
    2405             :     }
    2406           0 : return( true );
    2407             : }
    2408             : 
    2409           0 : static int Layer_Inherit(GGadget *g, GEvent *e) {
    2410           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_radiochanged ) {
    2411           0 :         GWindow gw = GGadgetGetWindow(g);
    2412           0 :         int cid = (intpt) GGadgetGetUserData(g);
    2413           0 :         GGadgetSetEnabled(GWidgetGetControl(gw,cid),
    2414           0 :                 !GGadgetIsChecked(g));
    2415             :     }
    2416           0 : return( true );
    2417             : }
    2418             : 
    2419           0 : static int Layer_DoColorWheel(GGadget *g, GEvent *e) {
    2420           0 :     if ( e->type==et_controlevent && e->u.control.subtype == et_buttonactivate ) {
    2421           0 :         GWindow gw = GGadgetGetWindow(g);
    2422           0 :         int cid = (intpt) GGadgetGetUserData(g);
    2423           0 :         GGadget *tf = GWidgetGetControl(gw,cid);
    2424           0 :         if ( GGadgetIsEnabled(tf)) {
    2425           0 :             char *pt, *text = GGadgetGetTitle8(tf);
    2426             :             char buf[12];
    2427             :             Color val;
    2428             :             struct hslrgb col;
    2429           0 :             pt = text;
    2430           0 :             while ( isspace(*pt)) ++pt;
    2431           0 :             if ( *pt=='0' && (pt[1]=='x' || pt[1]=='X')) pt += 2;
    2432           0 :             else if ( *pt=='#' ) ++pt;
    2433           0 :             val = strtoul(pt,NULL,16);
    2434           0 :             gColor2Hslrgb(&col,val);
    2435           0 :             col = GWidgetColor(_("Pick a color"),&col,NULL);
    2436           0 :             if ( col.rgb ) {
    2437           0 :                 val = gHslrgb2Color(&col);
    2438           0 :                 sprintf(buf,"#%06x", val );
    2439           0 :                 GGadgetSetTitle8(tf,buf);
    2440             :             }
    2441             :         }
    2442             :     }
    2443           0 : return( true );
    2444             : }
    2445             : 
    2446           0 : static int layer_e_h(GWindow gw, GEvent *event) {
    2447           0 :     if ( event->type==et_close ) {
    2448           0 :         struct layer_dlg *ld = GDrawGetUserData(gw);
    2449           0 :         ld->done = true;
    2450           0 :     } else if ( event->type == et_char ) {
    2451           0 :         if ( event->u.chr.keysym == GK_F1 || event->u.chr.keysym == GK_Help ) {
    2452           0 :             help("multilayer.html#Layer");
    2453           0 : return( true );
    2454             :         }
    2455           0 : return( false );
    2456             :     }
    2457           0 : return( true );
    2458             : }
    2459             : 
    2460           0 : int LayerDialog(Layer *layer,SplineFont *sf) {
    2461             :     GRect pos;
    2462             :     GWindow gw;
    2463             :     GWindowAttrs wattrs;
    2464             :     GGadgetCreateData gcd[62], boxes[12];
    2465             :     GGadgetCreateData *barray[10], *varray[4], *fhvarray[22], *shvarray[46],
    2466             :             *lcarray[6], *ljarray[6], *fgarray[5], *fparray[5], *sgarray[5],
    2467             :             *sparray[5];
    2468             :     GTextInfo label[62];
    2469             :     struct layer_dlg ld;
    2470           0 :     int yoff=0;
    2471             :     int gcdoff, fill_gcd, stroke_gcd, k, j;
    2472             :     char widthbuf[20], fcol[12], scol[12], fopac[30], sopac[30], transbuf[150],
    2473             :             dashbuf[60];
    2474             :     int i;
    2475             :     char *pt;
    2476             : 
    2477           0 :     memset(&ld,0,sizeof(ld));
    2478           0 :     ld.layer = layer;
    2479           0 :     ld.sf    = sf;
    2480             : 
    2481           0 :     memset(&wattrs,0,sizeof(wattrs));
    2482           0 :     wattrs.mask = wam_events|wam_cursor|wam_utf8_wtitle|wam_undercursor|wam_isdlg|wam_restrict;
    2483           0 :     wattrs.event_masks = ~(1<<et_charup);
    2484           0 :     wattrs.restrict_input_to_me = 1;
    2485           0 :     wattrs.undercursor = 1;
    2486           0 :     wattrs.cursor = ct_pointer;
    2487           0 :     wattrs.utf8_window_title = _("Layer");
    2488           0 :     wattrs.is_dlg = true;
    2489           0 :     pos.x = pos.y = 0;
    2490           0 :     pos.width = GGadgetScale(GDrawPointsToPixels(NULL,LY_Width));
    2491           0 :     pos.height = GDrawPointsToPixels(NULL,LY_Height);
    2492           0 :     ld.gw = gw = GDrawCreateTopWindow(NULL,&pos,layer_e_h,&ld,&wattrs);
    2493             : 
    2494           0 :     ld.fillgrad = GradientCopy(layer->fill_brush.gradient,NULL);
    2495           0 :     ld.strokegrad = GradientCopy(layer->stroke_pen.brush.gradient,NULL);
    2496           0 :     ld.fillpat = PatternCopy(layer->fill_brush.pattern,NULL);
    2497           0 :     ld.strokepat = PatternCopy(layer->stroke_pen.brush.pattern,NULL);
    2498             : 
    2499           0 :     memset(&label,0,sizeof(label));
    2500           0 :     memset(&gcd,0,sizeof(gcd));
    2501           0 :     memset(&boxes,0,sizeof(boxes));
    2502             : 
    2503           0 :     gcdoff = k = 0;
    2504             : 
    2505           0 :     label[gcdoff].text = (unichar_t *) _("Fi_ll");
    2506           0 :     label[gcdoff].text_is_1byte = true;
    2507           0 :     label[gcdoff].text_in_resource = true;
    2508           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2509           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = 5+yoff;
    2510           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->dofill? gg_cb_on : 0);
    2511           0 :     gcd[gcdoff].gd.cid = CID_Fill;
    2512           0 :     gcd[gcdoff++].creator = GCheckBoxCreate;
    2513             : 
    2514           0 :     fill_gcd = gcdoff;
    2515             : 
    2516           0 :     label[gcdoff].text = (unichar_t *) _("Color:");
    2517           0 :     label[gcdoff].text_is_1byte = true;
    2518           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2519           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+12;
    2520           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2521           0 :     gcd[gcdoff++].creator = GLabelCreate;
    2522           0 :     fhvarray[k++] = &gcd[gcdoff-1];
    2523             : 
    2524           0 :     sprintf( fcol, "#%06x", layer->fill_brush.col );
    2525           0 :     label[gcdoff].text = (unichar_t *) fcol;
    2526           0 :     label[gcdoff].text_is_1byte = true;
    2527           0 :     if ( layer->fill_brush.col==COLOR_INHERITED ) 
    2528           0 :         gcd[gcdoff].gd.flags = gg_visible;
    2529             :     else {
    2530           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
    2531           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2532             :     }
    2533           0 :     gcd[gcdoff].gd.pos.x = 80; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y-3;
    2534           0 :     gcd[gcdoff].gd.pos.width = 80;
    2535           0 :     gcd[gcdoff].gd.cid = CID_FillColor;
    2536           0 :     gcd[gcdoff++].creator = GTextFieldCreate;
    2537           0 :     fhvarray[k++] = &gcd[gcdoff-1];
    2538             : 
    2539           0 :     label[gcdoff].text = (unichar_t *) _("Inherited");
    2540           0 :     label[gcdoff].text_is_1byte = true;
    2541           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2542           0 :     gcd[gcdoff].gd.pos.x = 165; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+2;
    2543           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->fill_brush.col==COLOR_INHERITED? gg_cb_on : 0);
    2544           0 :     gcd[gcdoff].data = (void *) CID_FillColor;
    2545           0 :     gcd[gcdoff].gd.cid = CID_FillCInherit;
    2546           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_Inherit;
    2547           0 :     gcd[gcdoff++].creator = GCheckBoxCreate;
    2548           0 :     fhvarray[k++] = &gcd[gcdoff-1];
    2549             : 
    2550           0 :     label[gcdoff].image = GGadgetImageCache("colorwheel.png");
    2551           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2552           0 :     gcd[gcdoff].gd.flags = gg_enabled|gg_visible;
    2553           0 :     gcd[gcdoff].data = (void *) CID_FillColor;
    2554           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_DoColorWheel;
    2555           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2556           0 :     fhvarray[k++] = &gcd[gcdoff-1];
    2557           0 :     fhvarray[k++] = NULL;
    2558             : 
    2559           0 :     label[gcdoff].text = (unichar_t *) _("Opacity:");
    2560           0 :     label[gcdoff].text_is_1byte = true;
    2561           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2562           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+25;
    2563           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2564           0 :     gcd[gcdoff++].creator = GLabelCreate;
    2565           0 :     fhvarray[k++] = &gcd[gcdoff-1];
    2566             : 
    2567           0 :     sprintf( fopac, "%g", layer->fill_brush.opacity );
    2568           0 :     label[gcdoff].text = (unichar_t *) fopac;
    2569           0 :     label[gcdoff].text_is_1byte = true;
    2570           0 :     if ( layer->fill_brush.opacity<0 ) 
    2571           0 :         gcd[gcdoff].gd.flags = gg_visible;
    2572             :     else {
    2573           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
    2574           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2575             :     }
    2576           0 :     gcd[gcdoff].gd.pos.x = 80; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y-3;
    2577           0 :     gcd[gcdoff].gd.pos.width = 80;
    2578           0 :     gcd[gcdoff].gd.cid = CID_FillOpacity;
    2579           0 :     gcd[gcdoff++].creator = GTextFieldCreate;
    2580           0 :     fhvarray[k++] = &gcd[gcdoff-1];
    2581             : 
    2582           0 :     label[gcdoff].text = (unichar_t *) _("Inherited");
    2583           0 :     label[gcdoff].text_is_1byte = true;
    2584           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2585           0 :     gcd[gcdoff].gd.pos.x = 165; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+2;
    2586           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->fill_brush.opacity<0? gg_cb_on : 0);
    2587           0 :     gcd[gcdoff].data = (void *) CID_FillOpacity;
    2588           0 :     gcd[gcdoff].gd.cid = CID_FillOInherit;
    2589           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_Inherit;
    2590           0 :     gcd[gcdoff++].creator = GCheckBoxCreate;
    2591           0 :     fhvarray[k++] = &gcd[gcdoff-1];
    2592           0 :     fhvarray[k++] = GCD_Glue;
    2593           0 :     fhvarray[k++] = NULL;
    2594             : 
    2595           0 :     label[gcdoff].text = (unichar_t *) _("Gradient:");
    2596           0 :     label[gcdoff].text_is_1byte = true;
    2597           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2598           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+25;
    2599           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2600           0 :     gcd[gcdoff++].creator = GLabelCreate;
    2601           0 :     fhvarray[k++] = &gcd[gcdoff-1];
    2602             : 
    2603           0 :     gcd[gcdoff].gd.flags = layer->fill_brush.gradient==NULL ? (gg_visible | gg_enabled) : gg_visible;
    2604           0 :     label[gcdoff].text = (unichar_t *) _("Add");
    2605           0 :     label[gcdoff].text_is_1byte = true;
    2606           0 :     label[gcdoff].text_in_resource = true;
    2607           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2608           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_FillGradAddEdit;
    2609           0 :     gcd[gcdoff].gd.cid = CID_FillGradAdd;
    2610           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2611           0 :     fgarray[0] = &gcd[gcdoff-1];
    2612             : 
    2613           0 :     gcd[gcdoff].gd.flags = layer->fill_brush.gradient!=NULL ? (gg_visible | gg_enabled) : gg_visible;
    2614           0 :     label[gcdoff].text = (unichar_t *) _("Edit");
    2615           0 :     label[gcdoff].text_is_1byte = true;
    2616           0 :     label[gcdoff].text_in_resource = true;
    2617           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2618           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_FillGradAddEdit;
    2619           0 :     gcd[gcdoff].gd.cid = CID_FillGradEdit;
    2620           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2621           0 :     fgarray[1] = &gcd[gcdoff-1];
    2622             : 
    2623           0 :     gcd[gcdoff].gd.flags = layer->fill_brush.gradient!=NULL ? (gg_visible | gg_enabled) : gg_visible;
    2624           0 :     label[gcdoff].text = (unichar_t *) _("Delete");
    2625           0 :     label[gcdoff].text_is_1byte = true;
    2626           0 :     label[gcdoff].text_in_resource = true;
    2627           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2628           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_FillGradDelete;
    2629           0 :     gcd[gcdoff].gd.cid = CID_FillGradDelete;
    2630           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2631           0 :     fgarray[2] = &gcd[gcdoff-1];
    2632           0 :     fgarray[3] = GCD_Glue;
    2633           0 :     fgarray[4] = NULL;
    2634             : 
    2635           0 :     boxes[7].gd.flags = gg_enabled|gg_visible;
    2636           0 :     boxes[7].gd.u.boxelements = fgarray;
    2637           0 :     boxes[7].creator = GHBoxCreate;
    2638           0 :     fhvarray[k++] = &boxes[7];
    2639           0 :     fhvarray[k++] = GCD_ColSpan;
    2640           0 :     fhvarray[k++] = GCD_Glue;
    2641           0 :     fhvarray[k++] = NULL;
    2642             : 
    2643           0 :     label[gcdoff].text = (unichar_t *) _("Pattern:");
    2644           0 :     label[gcdoff].text_is_1byte = true;
    2645           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2646           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+25;
    2647           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2648           0 :     gcd[gcdoff++].creator = GLabelCreate;
    2649           0 :     fhvarray[k++] = &gcd[gcdoff-1];
    2650             : 
    2651           0 :     gcd[gcdoff].gd.flags = layer->fill_brush.pattern==NULL ? (gg_visible | gg_enabled) : gg_visible;
    2652           0 :     label[gcdoff].text = (unichar_t *) _("Add");
    2653           0 :     label[gcdoff].text_is_1byte = true;
    2654           0 :     label[gcdoff].text_in_resource = true;
    2655           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2656           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_FillPatAddEdit;
    2657           0 :     gcd[gcdoff].gd.cid = CID_FillPatAdd;
    2658           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2659           0 :     fparray[0] = &gcd[gcdoff-1];
    2660             : 
    2661           0 :     gcd[gcdoff].gd.flags = layer->fill_brush.pattern!=NULL ? (gg_visible | gg_enabled) : gg_visible;
    2662           0 :     label[gcdoff].text = (unichar_t *) _("Edit");
    2663           0 :     label[gcdoff].text_is_1byte = true;
    2664           0 :     label[gcdoff].text_in_resource = true;
    2665           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2666           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_FillPatAddEdit;
    2667           0 :     gcd[gcdoff].gd.cid = CID_FillPatEdit;
    2668           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2669           0 :     fparray[1] = &gcd[gcdoff-1];
    2670             : 
    2671           0 :     gcd[gcdoff].gd.flags = layer->fill_brush.pattern!=NULL ? (gg_visible | gg_enabled) : gg_visible;
    2672           0 :     label[gcdoff].text = (unichar_t *) _("Delete");
    2673           0 :     label[gcdoff].text_is_1byte = true;
    2674           0 :     label[gcdoff].text_in_resource = true;
    2675           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2676           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_FillPatDelete;
    2677           0 :     gcd[gcdoff].gd.cid = CID_FillPatDelete;
    2678           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2679           0 :     fparray[2] = &gcd[gcdoff-1];
    2680           0 :     fparray[3] = GCD_Glue;
    2681           0 :     fparray[4] = NULL;
    2682             : 
    2683           0 :     boxes[8].gd.flags = gg_enabled|gg_visible;
    2684           0 :     boxes[8].gd.u.boxelements = fparray;
    2685           0 :     boxes[8].creator = GHBoxCreate;
    2686           0 :     fhvarray[k++] = &boxes[8];
    2687           0 :     fhvarray[k++] = GCD_ColSpan;
    2688           0 :     fhvarray[k++] = GCD_Glue;
    2689           0 :     fhvarray[k++] = NULL;
    2690           0 :     fhvarray[k++] = NULL;
    2691             : 
    2692             : 
    2693           0 :     boxes[2].gd.pos.x = boxes[2].gd.pos.y = 2;
    2694           0 :     boxes[2].gd.flags = gg_enabled|gg_visible;
    2695           0 :     boxes[2].gd.u.boxelements = fhvarray;
    2696           0 :     boxes[2].gd.label = (GTextInfo *) &gcd[fill_gcd-1];
    2697           0 :     boxes[2].creator = GHVGroupCreate;
    2698             : 
    2699           0 :     label[gcdoff].text = (unichar_t *) _("Stroke");
    2700           0 :     label[gcdoff].text_is_1byte = true;
    2701           0 :     gcd[gcdoff].gd.mnemonic = 'S';
    2702           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2703           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[fill_gcd].gd.pos.y+gcd[fill_gcd].gd.pos.height+4;
    2704           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->dostroke? gg_cb_on : 0);
    2705           0 :     gcd[gcdoff].gd.cid = CID_Stroke;
    2706           0 :     gcd[gcdoff++].creator = GCheckBoxCreate;
    2707             : 
    2708           0 :     stroke_gcd = gcdoff;
    2709           0 :     k = 0;
    2710             : 
    2711           0 :     label[gcdoff].text = (unichar_t *) _("Color:");
    2712           0 :     label[gcdoff].text_is_1byte = true;
    2713           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2714           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+12;
    2715           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2716           0 :     gcd[gcdoff++].creator = GLabelCreate;
    2717           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2718             : 
    2719           0 :     sprintf( scol, "#%06x", layer->stroke_pen.brush.col );
    2720           0 :     label[gcdoff].text = (unichar_t *) scol;
    2721           0 :     label[gcdoff].text_is_1byte = true;
    2722           0 :     if ( layer->stroke_pen.brush.col==COLOR_INHERITED ) 
    2723           0 :         gcd[gcdoff].gd.flags = gg_visible;
    2724             :     else {
    2725           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
    2726           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2727             :     }
    2728           0 :     gcd[gcdoff].gd.pos.x = 80; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y-3;
    2729           0 :     gcd[gcdoff].gd.pos.width = 80;
    2730           0 :     gcd[gcdoff].gd.cid = CID_StrokeColor;
    2731           0 :     gcd[gcdoff++].creator = GTextFieldCreate;
    2732           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2733             : 
    2734           0 :     label[gcdoff].text = (unichar_t *) _("Inherited");
    2735           0 :     label[gcdoff].text_is_1byte = true;
    2736           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2737           0 :     gcd[gcdoff].gd.pos.x = 165; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+2;
    2738           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->stroke_pen.brush.col==COLOR_INHERITED? gg_cb_on : 0);
    2739           0 :     gcd[gcdoff].data = (void *) CID_StrokeColor;
    2740           0 :     gcd[gcdoff].gd.cid = CID_StrokeCInherit;
    2741           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_Inherit;
    2742           0 :     gcd[gcdoff++].creator = GCheckBoxCreate;
    2743           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2744             : 
    2745           0 :     label[gcdoff].image = GGadgetImageCache("colorwheel.png");
    2746           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2747           0 :     gcd[gcdoff].gd.flags = gg_enabled|gg_visible;
    2748           0 :     gcd[gcdoff].data = (void *) CID_StrokeColor;
    2749           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_DoColorWheel;
    2750           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2751           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2752           0 :     shvarray[k++] = NULL;
    2753             : 
    2754           0 :     label[gcdoff].text = (unichar_t *) _("Opacity:");
    2755           0 :     label[gcdoff].text_is_1byte = true;
    2756           0 :     gcd[gcdoff].gd.mnemonic = 'W';
    2757           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2758           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+25;
    2759           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2760           0 :     gcd[gcdoff++].creator = GLabelCreate;
    2761           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2762             : 
    2763           0 :     sprintf( sopac, "%g", layer->stroke_pen.brush.opacity );
    2764           0 :     label[gcdoff].text = (unichar_t *) sopac;
    2765           0 :     label[gcdoff].text_is_1byte = true;
    2766           0 :     if ( layer->stroke_pen.brush.opacity<0 ) 
    2767           0 :         gcd[gcdoff].gd.flags = gg_visible;
    2768             :     else {
    2769           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
    2770           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2771             :     }
    2772           0 :     gcd[gcdoff].gd.pos.x = 80; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y-3;
    2773           0 :     gcd[gcdoff].gd.pos.width = 80;
    2774           0 :     gcd[gcdoff].gd.cid = CID_StrokeOpacity;
    2775           0 :     gcd[gcdoff++].creator = GTextFieldCreate;
    2776           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2777             : 
    2778           0 :     label[gcdoff].text = (unichar_t *) _("Inherited");
    2779           0 :     label[gcdoff].text_is_1byte = true;
    2780           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2781           0 :     gcd[gcdoff].gd.pos.x = 165; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+2;
    2782           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->stroke_pen.brush.opacity<0? gg_cb_on : 0);
    2783           0 :     gcd[gcdoff].data = (void *) CID_StrokeOpacity;
    2784           0 :     gcd[gcdoff].gd.cid = CID_StrokeOInherit;
    2785           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_Inherit;
    2786           0 :     gcd[gcdoff++].creator = GCheckBoxCreate;
    2787           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2788           0 :     shvarray[k++] = GCD_Glue;
    2789           0 :     shvarray[k++] = NULL;
    2790             : 
    2791           0 :     label[gcdoff].text = (unichar_t *) _("Gradient:");
    2792           0 :     label[gcdoff].text_is_1byte = true;
    2793           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2794           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+25;
    2795           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2796           0 :     gcd[gcdoff++].creator = GLabelCreate;
    2797           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2798             : 
    2799           0 :     gcd[gcdoff].gd.flags = layer->stroke_pen.brush.gradient==NULL ? (gg_visible | gg_enabled) : gg_visible;
    2800           0 :     label[gcdoff].text = (unichar_t *) _("Add");
    2801           0 :     label[gcdoff].text_is_1byte = true;
    2802           0 :     label[gcdoff].text_in_resource = true;
    2803           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2804           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_StrokeGradAddEdit;
    2805           0 :     gcd[gcdoff].gd.cid = CID_StrokeGradAdd;
    2806           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2807           0 :     sgarray[0] = &gcd[gcdoff-1];
    2808             : 
    2809           0 :     gcd[gcdoff].gd.flags = layer->stroke_pen.brush.gradient!=NULL ? (gg_visible | gg_enabled) : gg_visible;
    2810           0 :     label[gcdoff].text = (unichar_t *) _("Edit");
    2811           0 :     label[gcdoff].text_is_1byte = true;
    2812           0 :     label[gcdoff].text_in_resource = true;
    2813           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2814           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_StrokeGradAddEdit;
    2815           0 :     gcd[gcdoff].gd.cid = CID_StrokeGradEdit;
    2816           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2817           0 :     sgarray[1] = &gcd[gcdoff-1];
    2818             : 
    2819           0 :     gcd[gcdoff].gd.flags = layer->stroke_pen.brush.gradient!=NULL ? (gg_visible | gg_enabled) : gg_visible;
    2820           0 :     label[gcdoff].text = (unichar_t *) _("Delete");
    2821           0 :     label[gcdoff].text_is_1byte = true;
    2822           0 :     label[gcdoff].text_in_resource = true;
    2823           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2824           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_StrokeGradDelete;
    2825           0 :     gcd[gcdoff].gd.cid = CID_StrokeGradDelete;
    2826           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2827           0 :     sgarray[2] = &gcd[gcdoff-1];
    2828           0 :     sgarray[3] = GCD_Glue;
    2829           0 :     sgarray[4] = NULL;
    2830             : 
    2831           0 :     boxes[9].gd.flags = gg_enabled|gg_visible;
    2832           0 :     boxes[9].gd.u.boxelements = sgarray;
    2833           0 :     boxes[9].creator = GHBoxCreate;
    2834           0 :     shvarray[k++] = &boxes[9];
    2835           0 :     shvarray[k++] = GCD_ColSpan;
    2836           0 :     shvarray[k++] = GCD_Glue;
    2837           0 :     shvarray[k++] = NULL;
    2838             : 
    2839           0 :     label[gcdoff].text = (unichar_t *) _("Pattern:");
    2840           0 :     label[gcdoff].text_is_1byte = true;
    2841           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2842           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+25;
    2843           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2844           0 :     gcd[gcdoff++].creator = GLabelCreate;
    2845           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2846             : 
    2847           0 :     gcd[gcdoff].gd.flags = layer->stroke_pen.brush.pattern==NULL ? (gg_visible | gg_enabled) : gg_visible;
    2848           0 :     label[gcdoff].text = (unichar_t *) _("Add");
    2849           0 :     label[gcdoff].text_is_1byte = true;
    2850           0 :     label[gcdoff].text_in_resource = true;
    2851           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2852           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_StrokePatAddEdit;
    2853           0 :     gcd[gcdoff].gd.cid = CID_StrokePatAdd;
    2854           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2855           0 :     sparray[0] = &gcd[gcdoff-1];
    2856             : 
    2857           0 :     gcd[gcdoff].gd.flags = layer->stroke_pen.brush.pattern!=NULL ? (gg_visible | gg_enabled) : gg_visible;
    2858           0 :     label[gcdoff].text = (unichar_t *) _("Edit");
    2859           0 :     label[gcdoff].text_is_1byte = true;
    2860           0 :     label[gcdoff].text_in_resource = true;
    2861           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2862           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_StrokePatAddEdit;
    2863           0 :     gcd[gcdoff].gd.cid = CID_StrokePatEdit;
    2864           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2865           0 :     sparray[1] = &gcd[gcdoff-1];
    2866             : 
    2867           0 :     gcd[gcdoff].gd.flags = layer->stroke_pen.brush.pattern!=NULL ? (gg_visible | gg_enabled) : gg_visible;
    2868           0 :     label[gcdoff].text = (unichar_t *) _("Delete");
    2869           0 :     label[gcdoff].text_is_1byte = true;
    2870           0 :     label[gcdoff].text_in_resource = true;
    2871           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2872           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_StrokePatDelete;
    2873           0 :     gcd[gcdoff].gd.cid = CID_StrokePatDelete;
    2874           0 :     gcd[gcdoff++].creator = GButtonCreate;
    2875           0 :     sparray[2] = &gcd[gcdoff-1];
    2876           0 :     sparray[3] = GCD_Glue;
    2877           0 :     sparray[4] = NULL;
    2878             : 
    2879           0 :     boxes[10].gd.flags = gg_enabled|gg_visible;
    2880           0 :     boxes[10].gd.u.boxelements = sparray;
    2881           0 :     boxes[10].creator = GHBoxCreate;
    2882           0 :     shvarray[k++] = &boxes[10];
    2883           0 :     shvarray[k++] = GCD_ColSpan;
    2884           0 :     shvarray[k++] = GCD_Glue;
    2885           0 :     shvarray[k++] = NULL;
    2886             : 
    2887           0 :     label[gcdoff].text = (unichar_t *) _("Stroke _Width:");
    2888           0 :     label[gcdoff].text_is_1byte = true;
    2889           0 :     label[gcdoff].text_in_resource = true;
    2890           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2891           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2892           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+26;
    2893           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2894           0 :     gcd[gcdoff].gd.cid = CID_WidthTxt;
    2895           0 :     gcd[gcdoff++].creator = GLabelCreate;
    2896           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2897             : 
    2898           0 :     sprintf( widthbuf, "%g", layer->stroke_pen.width );
    2899           0 :     label[gcdoff].text = (unichar_t *) widthbuf;
    2900           0 :     label[gcdoff].text_is_1byte = true;
    2901           0 :     if ( layer->stroke_pen.width==WIDTH_INHERITED ) 
    2902           0 :         gcd[gcdoff].gd.flags = gg_visible;
    2903             :     else {
    2904           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
    2905           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2906             :     }
    2907           0 :     gcd[gcdoff].gd.pos.x = 80; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y-3;
    2908           0 :     gcd[gcdoff].gd.pos.width = 80;
    2909           0 :     gcd[gcdoff].gd.cid = CID_Width;
    2910           0 :     gcd[gcdoff++].creator = GTextFieldCreate;
    2911           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2912             : 
    2913           0 :     label[gcdoff].text = (unichar_t *) _("Inherited");
    2914           0 :     label[gcdoff].text_is_1byte = true;
    2915           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2916           0 :     gcd[gcdoff].gd.pos.x = 165; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+2;
    2917           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->stroke_pen.width==WIDTH_INHERITED? gg_cb_on : 0);
    2918           0 :     gcd[gcdoff].data = (void *) CID_Width;
    2919           0 :     gcd[gcdoff].gd.cid = CID_StrokeWInherit;
    2920           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_Inherit;
    2921           0 :     gcd[gcdoff++].creator = GCheckBoxCreate;
    2922           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2923           0 :     shvarray[k++] = GCD_Glue;
    2924           0 :     shvarray[k++] = NULL;
    2925             : 
    2926           0 :     label[gcdoff].text = (unichar_t *) _("Dashes");
    2927           0 :     label[gcdoff].text_is_1byte = true;
    2928           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2929           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+26;
    2930           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | gg_utf8_popup;
    2931           0 :     gcd[gcdoff].gd.cid = CID_DashesTxt;
    2932           0 :     gcd[gcdoff].gd.popup_msg = (unichar_t *) _("This specifies the dash pattern for a line.\nLeave this field blank for a solid line.\nOtherwise specify a list of up to 8 integers\n(between 0 and 255) which give the dash pattern\nin em-units. So \"10 10\" will draw the first\n10 units of a line, leave the next 10 blank,\ndraw the next 10, and so on.");
    2933           0 :     gcd[gcdoff++].creator = GLabelCreate;
    2934           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2935             : 
    2936           0 :     pt = dashbuf; dashbuf[0] = '\0';
    2937           0 :     for ( i=0; i<DASH_MAX && layer->stroke_pen.dashes[i]!=0; ++i ) {
    2938           0 :         sprintf( pt, "%d ", layer->stroke_pen.dashes[i]);
    2939           0 :         pt += strlen(pt);
    2940             :     }
    2941           0 :     if ( pt>dashbuf ) pt[-1] = '\0';
    2942           0 :     label[gcdoff].text = (unichar_t *) dashbuf;
    2943           0 :     label[gcdoff].text_is_1byte = true;
    2944           0 :     if ( layer->stroke_pen.dashes[0]==0 && layer->stroke_pen.dashes[1]==DASH_INHERITED ) 
    2945           0 :         gcd[gcdoff].gd.flags = gg_visible;
    2946             :     else {
    2947           0 :         gcd[gcdoff].gd.label = &label[gcdoff];
    2948           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2949             :     }
    2950           0 :     gcd[gcdoff].gd.pos.x = 80; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y-3;
    2951           0 :     gcd[gcdoff].gd.pos.width = 80;
    2952           0 :     gcd[gcdoff].gd.cid = CID_Dashes;
    2953           0 :     gcd[gcdoff++].creator = GTextFieldCreate;
    2954           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2955             : 
    2956           0 :     label[gcdoff].text = (unichar_t *) _("Inherited");
    2957           0 :     label[gcdoff].text_is_1byte = true;
    2958           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2959           0 :     gcd[gcdoff].gd.pos.x = 165; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+2;
    2960           0 :     if ( layer->stroke_pen.dashes[0]==0 && layer->stroke_pen.dashes[1]==DASH_INHERITED ) 
    2961           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | gg_cb_on | gg_utf8_popup;
    2962             :     else
    2963           0 :         gcd[gcdoff].gd.flags = gg_enabled | gg_visible | gg_utf8_popup;
    2964           0 :     gcd[gcdoff].data = (void *) CID_Dashes;
    2965           0 :     gcd[gcdoff].gd.cid = CID_DashesInherit;
    2966           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_Inherit;
    2967           0 :     gcd[gcdoff].gd.popup_msg = (unichar_t *) _("This specifies the dash pattern for a line.\nLeave this field blank for a solid line.\nOtherwise specify a list of up to 8 integers\n(between 0 and 255) which give the dash pattern\nin em-units. So \"10 10\" will draw the first\n10 units of a line, leave the next 10 blank,\ndraw the next 10, and so on.");
    2968           0 :     gcd[gcdoff++].creator = GCheckBoxCreate;
    2969           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2970           0 :     shvarray[k++] = GCD_Glue;
    2971           0 :     shvarray[k++] = NULL;
    2972             : 
    2973           0 :     label[gcdoff].text = (unichar_t *) _("_Transform Pen:");
    2974           0 :     label[gcdoff].text_in_resource = true;
    2975           0 :     label[gcdoff].text_is_1byte = true;
    2976           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2977           0 :     gcd[gcdoff].gd.pos.x = 5; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+25;
    2978           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2979           0 :     gcd[gcdoff++].creator = GLabelCreate;
    2980           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2981             : 
    2982           0 :     sprintf( transbuf, "[%.4g %.4g %.4g %.4g]", (double) layer->stroke_pen.trans[0],
    2983             :             (double) layer->stroke_pen.trans[1], (double) layer->stroke_pen.trans[2],
    2984             :             (double) layer->stroke_pen.trans[3]);
    2985           0 :     label[gcdoff].text = (unichar_t *) transbuf;
    2986           0 :     label[gcdoff].text_is_1byte = true;
    2987           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    2988           0 :     gcd[gcdoff].gd.pos.x = 80; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y-3;
    2989           0 :     gcd[gcdoff].gd.pos.width = 210;
    2990           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    2991           0 :     gcd[gcdoff].gd.cid = CID_Trans;
    2992           0 :     gcd[gcdoff++].creator = GTextFieldCreate;
    2993           0 :     shvarray[k++] = &gcd[gcdoff-1];
    2994           0 :     shvarray[k++] = GCD_ColSpan;
    2995           0 :     shvarray[k++] = GCD_ColSpan;
    2996           0 :     shvarray[k++] = NULL;
    2997             : 
    2998           0 :     j = 0;
    2999           0 :     label[gcdoff].text = (unichar_t *) _("Line Cap");
    3000           0 :     label[gcdoff].text_is_1byte = true;
    3001           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3002           0 :     gcd[gcdoff].gd.pos.x = 10; gcd[gcdoff].gd.pos.y = gcd[gcdoff-2].gd.pos.y+20;
    3003           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    3004           0 :     gcd[gcdoff].gd.cid = CID_LineCapTxt;
    3005           0 :     gcd[gcdoff++].creator = GLabelCreate;
    3006             : 
    3007           0 :     label[gcdoff].text = (unichar_t *) _("_Butt");
    3008           0 :     label[gcdoff].text_is_1byte = true;
    3009           0 :     label[gcdoff].text_in_resource = true;
    3010           0 :     label[gcdoff].image = &GIcon_buttcap;
    3011           0 :     gcd[gcdoff].gd.mnemonic = 'B';
    3012           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3013           0 :     gcd[gcdoff].gd.pos.x = 15; gcd[gcdoff].gd.pos.y = gcd[gcdoff-2].gd.pos.y+12;
    3014           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->stroke_pen.linecap==lc_butt?gg_cb_on:0);
    3015           0 :     gcd[gcdoff].gd.cid = CID_ButtCap;
    3016           0 :     gcd[gcdoff++].creator = GRadioCreate;
    3017           0 :     lcarray[j++] = &gcd[gcdoff-1];
    3018             : 
    3019           0 :     label[gcdoff].text = (unichar_t *) _("_Round");
    3020           0 :     label[gcdoff].text_is_1byte = true;
    3021           0 :     label[gcdoff].text_in_resource = true;
    3022           0 :     label[gcdoff].image = &GIcon_roundcap;
    3023           0 :     gcd[gcdoff].gd.mnemonic = 'R';
    3024           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3025           0 :     gcd[gcdoff].gd.pos.x = 80; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y;
    3026           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->stroke_pen.linecap==lc_round?gg_cb_on:0);
    3027           0 :     gcd[gcdoff].gd.cid = CID_RoundCap;
    3028           0 :     gcd[gcdoff++].creator = GRadioCreate;
    3029           0 :     lcarray[j++] = &gcd[gcdoff-1];
    3030             : 
    3031           0 :     label[gcdoff].text = (unichar_t *) _("S_quare");
    3032           0 :     label[gcdoff].text_is_1byte = true;
    3033           0 :     label[gcdoff].text_in_resource = true;
    3034           0 :     label[gcdoff].image = &GIcon_squarecap;
    3035           0 :     gcd[gcdoff].gd.mnemonic = 'q';
    3036           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3037           0 :     gcd[gcdoff].gd.pos.x = 150; gcd[gcdoff].gd.pos.y = gcd[gcdoff-2].gd.pos.y;
    3038           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->stroke_pen.linecap==lc_square?gg_cb_on:0);
    3039           0 :     gcd[gcdoff].gd.cid = CID_SquareCap;
    3040           0 :     gcd[gcdoff++].creator = GRadioCreate;
    3041           0 :     lcarray[j++] = &gcd[gcdoff-1];
    3042             : 
    3043           0 :     label[gcdoff].text = (unichar_t *) _("Inherited");
    3044           0 :     label[gcdoff].text_is_1byte = true;
    3045           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3046           0 :     gcd[gcdoff].gd.pos.x = 220; gcd[gcdoff].gd.pos.y = gcd[gcdoff-2].gd.pos.y;
    3047           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->stroke_pen.linecap==lc_inherited?gg_cb_on:0);
    3048           0 :     gcd[gcdoff].gd.cid = CID_InheritCap;
    3049           0 :     gcd[gcdoff++].creator = GRadioCreate;
    3050           0 :     lcarray[j++] = &gcd[gcdoff-1];
    3051           0 :     lcarray[j++] = NULL;
    3052           0 :     lcarray[j++] = NULL;
    3053             : 
    3054           0 :     boxes[3].gd.pos.x = boxes[3].gd.pos.y = 2;
    3055           0 :     boxes[3].gd.flags = gg_enabled|gg_visible;
    3056           0 :     boxes[3].gd.u.boxelements = lcarray;
    3057           0 :     boxes[3].gd.label = (GTextInfo *) &gcd[gcdoff-5];
    3058           0 :     boxes[3].creator = GHVGroupCreate;
    3059           0 :     shvarray[k++] = &boxes[3];
    3060           0 :     shvarray[k++] = GCD_ColSpan;
    3061           0 :     shvarray[k++] = GCD_ColSpan;
    3062           0 :     shvarray[k++] = GCD_ColSpan;
    3063           0 :     shvarray[k++] = NULL;
    3064             : 
    3065           0 :     j=0;
    3066           0 :     label[gcdoff].text = (unichar_t *) _("Line Join");
    3067           0 :     label[gcdoff].text_is_1byte = true;
    3068           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3069           0 :     gcd[gcdoff].gd.pos.x = gcd[gcdoff-6].gd.pos.x; gcd[gcdoff].gd.pos.y = gcd[gcdoff-3].gd.pos.y+25;
    3070           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible;
    3071           0 :     gcd[gcdoff].gd.cid = CID_LineJoinTxt;
    3072           0 :     gcd[gcdoff++].creator = GLabelCreate;
    3073             : 
    3074           0 :     label[gcdoff].text = (unichar_t *) _("_Miter");
    3075           0 :     label[gcdoff].text_is_1byte = true;
    3076           0 :     label[gcdoff].text_in_resource = true;
    3077           0 :     label[gcdoff].image = &GIcon_miterjoin;
    3078           0 :     gcd[gcdoff].gd.mnemonic = 'M';
    3079           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3080           0 :     gcd[gcdoff].gd.pos.x = gcd[gcdoff-6].gd.pos.x; gcd[gcdoff].gd.pos.y = gcd[gcdoff-2].gd.pos.y+12;
    3081           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->stroke_pen.linejoin==lj_miter?gg_cb_on:0);
    3082           0 :     gcd[gcdoff].gd.cid = CID_MiterJoin;
    3083           0 :     gcd[gcdoff++].creator = GRadioCreate;
    3084           0 :     ljarray[j++] = &gcd[gcdoff-1];
    3085             : 
    3086           0 :     label[gcdoff].text = (unichar_t *) _("Ro_und");
    3087           0 :     label[gcdoff].text_is_1byte = true;
    3088           0 :     label[gcdoff].text_in_resource = true;
    3089           0 :     label[gcdoff].image = &GIcon_roundjoin;
    3090           0 :     gcd[gcdoff].gd.mnemonic = 'u';
    3091           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3092           0 :     gcd[gcdoff].gd.pos.x = gcd[gcdoff-6].gd.pos.x; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y;
    3093           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->stroke_pen.linejoin==lj_round?gg_cb_on:0);
    3094           0 :     gcd[gcdoff].gd.cid = CID_RoundJoin;
    3095           0 :     gcd[gcdoff++].creator = GRadioCreate;
    3096           0 :     ljarray[j++] = &gcd[gcdoff-1];
    3097             : 
    3098           0 :     label[gcdoff].text = (unichar_t *) _("Be_vel");
    3099           0 :     label[gcdoff].text_is_1byte = true;
    3100           0 :     label[gcdoff].text_in_resource = true;
    3101           0 :     label[gcdoff].image = &GIcon_beveljoin;
    3102           0 :     gcd[gcdoff].gd.mnemonic = 'v';
    3103           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3104           0 :     gcd[gcdoff].gd.pos.x = gcd[gcdoff-6].gd.pos.x; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y;
    3105           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->stroke_pen.linejoin==lj_bevel?gg_cb_on:0);
    3106           0 :     gcd[gcdoff].gd.cid = CID_BevelJoin;
    3107           0 :     gcd[gcdoff++].creator = GRadioCreate;
    3108           0 :     ljarray[j++] = &gcd[gcdoff-1];
    3109             : 
    3110           0 :     label[gcdoff].text = (unichar_t *) _("Inherited");
    3111           0 :     label[gcdoff].text_is_1byte = true;
    3112           0 :     gcd[gcdoff].gd.mnemonic = 'q';
    3113           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3114           0 :     gcd[gcdoff].gd.pos.x = 220; gcd[gcdoff].gd.pos.y = gcd[gcdoff-2].gd.pos.y;
    3115           0 :     gcd[gcdoff].gd.flags = gg_enabled | gg_visible | (layer->stroke_pen.linejoin==lj_inherited?gg_cb_on:0);
    3116           0 :     gcd[gcdoff].gd.cid = CID_InheritCap;
    3117           0 :     gcd[gcdoff++].creator = GRadioCreate;
    3118           0 :     ljarray[j++] = &gcd[gcdoff-1];
    3119           0 :     ljarray[j++] = NULL;
    3120           0 :     ljarray[j++] = NULL;
    3121             : 
    3122           0 :     boxes[4].gd.pos.x = boxes[4].gd.pos.y = 2;
    3123           0 :     boxes[4].gd.flags = gg_enabled|gg_visible;
    3124           0 :     boxes[4].gd.u.boxelements = ljarray;
    3125           0 :     boxes[4].gd.label = (GTextInfo *) &gcd[gcdoff-5];
    3126           0 :     boxes[4].creator = GHVGroupCreate;
    3127           0 :     shvarray[k++] = &boxes[4];
    3128           0 :     shvarray[k++] = GCD_ColSpan;
    3129           0 :     shvarray[k++] = GCD_ColSpan;
    3130           0 :     shvarray[k++] = NULL;
    3131           0 :     shvarray[k++] = NULL;
    3132             : 
    3133           0 :     boxes[5].gd.pos.x = boxes[5].gd.pos.y = 2;
    3134           0 :     boxes[5].gd.flags = gg_enabled|gg_visible;
    3135           0 :     boxes[5].gd.u.boxelements = shvarray;
    3136           0 :     boxes[5].gd.label = (GTextInfo *) &gcd[stroke_gcd-1];
    3137           0 :     boxes[5].creator = GHVGroupCreate;
    3138             : 
    3139             : 
    3140           0 :     gcd[gcdoff].gd.pos.x = 30-3; gcd[gcdoff].gd.pos.y = LY_Height-30-3;
    3141           0 :     gcd[gcdoff].gd.pos.width = -1;
    3142           0 :     gcd[gcdoff].gd.flags = gg_visible | gg_enabled | gg_but_default;
    3143           0 :     label[gcdoff].text = (unichar_t *) _("_OK");
    3144           0 :     label[gcdoff].text_is_1byte = true;
    3145           0 :     label[gcdoff].text_in_resource = true;
    3146           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3147           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_OK;
    3148           0 :     gcd[gcdoff++].creator = GButtonCreate;
    3149           0 :     barray[0] = GCD_Glue; barray[1] = &gcd[gcdoff-1]; barray[2] = GCD_Glue; barray[3] = GCD_Glue;
    3150             : 
    3151           0 :     gcd[gcdoff].gd.pos.x = -30; gcd[gcdoff].gd.pos.y = gcd[gcdoff-1].gd.pos.y+3;
    3152           0 :     gcd[gcdoff].gd.pos.width = -1;
    3153           0 :     gcd[gcdoff].gd.flags = gg_visible | gg_enabled | gg_but_cancel;
    3154           0 :     label[gcdoff].text = (unichar_t *) _("_Cancel");
    3155           0 :     label[gcdoff].text_is_1byte = true;
    3156           0 :     label[gcdoff].text_in_resource = true;
    3157           0 :     gcd[gcdoff].gd.label = &label[gcdoff];
    3158           0 :     gcd[gcdoff].gd.handle_controlevent = Layer_Cancel;
    3159           0 :     gcd[gcdoff++].creator = GButtonCreate;
    3160           0 :     barray[4] = GCD_Glue; barray[5] = &gcd[gcdoff-1]; barray[6] = GCD_Glue; barray[7] = NULL;
    3161             : 
    3162           0 :     boxes[6].gd.flags = gg_enabled|gg_visible;
    3163           0 :     boxes[6].gd.u.boxelements = barray;
    3164           0 :     boxes[6].creator = GHBoxCreate;
    3165             : 
    3166           0 :     varray[0] = &boxes[2]; varray[1] = &boxes[5]; varray[2] = &boxes[6]; varray[3] = NULL;
    3167             : 
    3168           0 :     boxes[0].gd.flags = gg_enabled|gg_visible;
    3169           0 :     boxes[0].gd.u.boxelements = varray;
    3170           0 :     boxes[0].creator = GVBoxCreate;
    3171             : 
    3172           0 :     GGadgetsCreate(gw,boxes);
    3173           0 :     GHVBoxSetExpandableCol(boxes[2].ret,2);
    3174           0 :     GHVBoxSetExpandableCol(boxes[5].ret,2);
    3175           0 :     GHVBoxSetExpandableCol(boxes[6].ret,gb_expandgluesame);
    3176           0 :     GHVBoxSetExpandableCol(boxes[7].ret,gb_expandgluesame);
    3177           0 :     GHVBoxSetExpandableCol(boxes[8].ret,gb_expandgluesame);
    3178           0 :     GHVBoxSetExpandableCol(boxes[9].ret,gb_expandgluesame);
    3179           0 :     GHVBoxSetExpandableCol(boxes[10].ret,gb_expandgluesame);
    3180           0 :     GHVBoxFitWindow(boxes[0].ret);
    3181             : 
    3182           0 :     GWidgetHidePalettes();
    3183             :     /*GWidgetIndicateFocusGadget(GWidgetGetControl(ld.gw,CID_Width));*/
    3184           0 :     GDrawSetVisible(ld.gw,true);
    3185           0 :     while ( !ld.done )
    3186           0 :         GDrawProcessOneEvent(NULL);
    3187           0 :     GDrawDestroyWindow(ld.gw);
    3188           0 :     if ( !ld.ok ) {
    3189           0 :         GradientFree(ld.fillgrad);
    3190           0 :         GradientFree(ld.strokegrad);
    3191           0 :         PatternFree(ld.fillpat);
    3192           0 :         PatternFree(ld.strokepat);
    3193             :     }
    3194           0 : return( ld.ok );
    3195             : }

Generated by: LCOV version 1.10