summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorge Williams <pfaedit@users.sourceforge.net>2011-02-28 20:53:23 -0800
committerGeorge Williams <pfaedit@users.sourceforge.net>2011-02-28 20:53:23 -0800
commit7964b024db389c173c0ea00b823448e2ff59848e (patch)
treede8fc527fafb23c183fcb41f4fc39d80b00d3e97
parentb7dc08f4571fb4975e6108aa25f67575d3b61250 (diff)
More changes to charinfo. Still a couple of changes that weren't undone by a cancel (if the user changed a glyph name then the encoding was set to custom even if the user cancelled).
-rw-r--r--fontforge/charinfo.c291
-rw-r--r--fontforge/fvfonts.c2
-rw-r--r--fontforge/splinechar.c19
-rw-r--r--fontforge/splinefont.h2
-rw-r--r--fontforge/splineutil.c21
5 files changed, 303 insertions, 32 deletions
diff --git a/fontforge/charinfo.c b/fontforge/charinfo.c
index b67ff39a..af8db852 100644
--- a/fontforge/charinfo.c
+++ b/fontforge/charinfo.c
@@ -50,6 +50,7 @@ typedef struct charinfo {
int lc_seen, lc_aspect, vert_aspect;
Color last, real_last;
struct splinecharlist *changes;
+ int name_change, uni_change;
} CharInfo;
#define CI_Width 218
@@ -1210,6 +1211,203 @@ static void CI_ParseAltUnis(CharInfo *ci) {
}
}
+static KernPair *CI_KPCopy(KernPair *kp) {
+ KernPair *head=NULL, *last=NULL, *newkp;
+
+ while ( kp!=NULL ) {
+ newkp = chunkalloc(sizeof(KernPair));
+ *newkp = *kp;
+#ifdef FONTFORGE_CONFIG_DEVICETABLES
+ newkp->adjust = DeviceTableCopy(kp->adjust);
+#endif;
+ newkp->next = NULL;
+ if ( head==NULL )
+ head = newkp;
+ else
+ last->next = newkp;
+ last = newkp;
+ kp = kp->next;
+ }
+return( head );
+}
+
+static PST *CI_PSTCopy(PST *pst) {
+ PST *head=NULL, *last=NULL, *newpst;
+
+ while ( pst!=NULL ) {
+ newpst = chunkalloc(sizeof(KernPair));
+ *newpst = *pst;
+ if ( newpst->type==pst_ligature ) {
+ newpst->u.lig.components = copy(pst->u.lig.components);
+ } else if ( newpst->type==pst_pair ) {
+ newpst->u.pair.paired = copy(pst->u.pair.paired);
+ newpst->u.pair.vr = chunkalloc(sizeof( struct vr [2]));
+ memcpy(newpst->u.pair.vr,pst->u.pair.vr,sizeof(struct vr [2]));
+#ifdef FONTFORGE_CONFIG_DEVICETABLES
+ newpst->u.pair.vr[0].adjust = ValDevTabCopy(pst->u.pair.vr[0].adjust);
+ newpst->u.pair.vr[1].adjust = ValDevTabCopy(pst->u.pair.vr[1].adjust);
+#endif
+ } else if ( newpst->type==pst_lcaret ) {
+ newpst->u.lcaret.carets = galloc(pst->u.lcaret.cnt*sizeof(uint16));
+ memcpy(newpst->u.lcaret.carets,pst->u.lcaret.carets,pst->u.lcaret.cnt*sizeof(uint16));
+ } else if ( newpst->type==pst_substitution || newpst->type==pst_multiple || newpst->type==pst_alternate )
+ newpst->u.subs.variant = copy(pst->u.subs.variant);
+ newpst->next = NULL;
+ if ( head==NULL )
+ head = newpst;
+ else
+ last->next = newpst;
+ last = newpst;
+ pst = pst->next;
+ }
+return( head );
+}
+
+static SplineChar *CI_SCDuplicate(SplineChar *sc) {
+ SplineChar *newsc; /* copy everything we care about in this dlg */
+
+ newsc = chunkalloc(sizeof(SplineChar));
+ newsc->name = copy(sc->name);
+ newsc->unicodeenc = sc->unicodeenc;
+ newsc->orig_pos = sc->orig_pos;
+ newsc->comment = copy(sc->comment);
+ newsc->unlink_rm_ovrlp_save_undo = sc->unlink_rm_ovrlp_save_undo;
+ newsc->glyph_class = sc->glyph_class;
+ newsc->color = sc->color;
+ if ( sc->countermask_cnt!=0 ) {
+ newsc->countermask_cnt = sc->countermask_cnt;
+ newsc->countermasks = galloc(sc->countermask_cnt*sizeof(HintMask));
+ memcpy(newsc->countermasks,sc->countermasks,sc->countermask_cnt*sizeof(HintMask));
+ }
+ newsc->tex_height = sc->tex_height;
+ newsc->tex_depth = sc->tex_depth;
+ newsc->italic_correction = sc->italic_correction;
+ newsc->top_accent_horiz = sc->top_accent_horiz;
+ newsc->is_extended_shape = sc->is_extended_shape;
+#ifdef FONTFORGE_CONFIG_DEVICETABLES
+ newsc->italic_adjusts = DeviceTableCopy(sc->italic_adjusts);
+ newsc->top_accent_adjusts = DeviceTableCopy(sc->top_accent_adjusts);
+#endif
+ newsc->horiz_variants = GlyphVariantsCopy(sc->horiz_variants);
+ newsc->vert_variants = GlyphVariantsCopy(sc->vert_variants);
+ newsc->altuni = AltUniCopy(sc->altuni,NULL);
+ newsc->lig_caret_cnt_fixed = sc->lig_caret_cnt_fixed;
+ newsc->possub = CI_PSTCopy(sc->possub);
+ newsc->kerns = CI_KPCopy(sc->kerns);
+ newsc->vkerns = CI_KPCopy(sc->vkerns);
+#ifdef FONTFORGE_CONFIG_TYPE3
+ newsc->tile_margin = sc->tile_margin;
+ newsc->tile_bounds = sc->tile_bounds;
+#endif
+return( newsc );
+}
+
+static int CI_CheckMetaData(CharInfo *ci,SplineChar *oldsc,char *name,int unienc, char *comment) {
+ SplineFont *sf = oldsc->parent;
+ int i;
+ int isnotdef, samename=false, sameuni=false;
+ struct altuni *alt;
+ SplineChar *newsc = ci->cachedsc;
+ struct splinecharlist *scl, *baduniscl, *badnamescl;
+ SplineChar *baduni, *badname;
+
+ for ( alt=oldsc->altuni; alt!=NULL && (alt->unienc!=unienc || alt->vs!=-1 || alt->fid!=0); alt=alt->next );
+ if ( unienc==oldsc->unicodeenc || alt!=NULL )
+ sameuni=true;
+ samename = ( strcmp(name,oldsc->name)==0 );
+
+ isnotdef = strcmp(name,".notdef")==0;
+ if (( !sameuni && unienc!=-1) || (!samename && !isnotdef) ) {
+ baduniscl = badnamescl = NULL;
+ baduni = badname = NULL;
+ for ( i=0; i<sf->glyphcnt; ++i ) if ( sf->glyphs[i]!=NULL && sf->glyphs[i]!=ci->sc ) {
+ if ( unienc!=-1 && sf->glyphs[i]->unicodeenc==unienc ) {
+ for ( scl=ci->changes; scl!=NULL && scl->sc->orig_pos!=i; scl = scl->next );
+ if ( scl==NULL ) {
+ baduni = sf->glyphs[i];
+ baduniscl = NULL;
+ } else if ( scl->sc->unicodeenc==unienc ) {
+ baduni = scl->sc;
+ baduniscl = scl;
+ }
+ }
+ if ( !isnotdef && strcmp(name,sf->glyphs[i]->name )==0 ) {
+ for ( scl=ci->changes; scl!=NULL && scl->sc->orig_pos!=i; scl = scl->next );
+ if ( scl==NULL ) {
+ badname = sf->glyphs[i];
+ badnamescl = NULL;
+ } else if ( strcmp(scl->sc->name,name)==0 ) {
+ badname = scl->sc;
+ badnamescl = scl;
+ }
+ }
+ }
+ for ( scl=ci->changes; scl!=NULL ; scl = scl->next ) if ( scl->sc!=newsc ) {
+ if ( unienc!=-1 && scl->sc->unicodeenc==unienc ) {
+ baduni = scl->sc;
+ baduniscl = scl;
+ }
+ if ( !isnotdef && strcmp(scl->sc->name,name)==0 ) {
+ badname = scl->sc;
+ badnamescl = scl;
+ }
+ }
+ if ( baduni!=NULL || badname!=NULL ) {
+ char *buts[3];
+ buts[0] = _("_Yes"); buts[1]=_("_Cancel"); buts[2] = NULL;
+ if ( badname==baduni ) {
+ if ( ff_ask(_("Multiple"),(const char **) buts,0,1,_("There is already a glyph with this name and encoding,\nboth must be unique within a font,\ndo you want to swap them?"))==1 )
+return( false );
+ /* If we're going to swap, then add the swapee to the list of */
+ /* things that need changing */
+ if ( baduniscl==NULL ) {
+ baduni = CI_SCDuplicate(baduni);
+ baduniscl = chunkalloc(sizeof(struct splinecharlist));
+ baduniscl->sc = baduni;
+ baduniscl->next = ci->changes;
+ ci->changes = baduniscl;
+ }
+ baduni->unicodeenc = oldsc->unicodeenc;
+ free(baduni->name); baduni->name = copy(oldsc->name);
+ } else {
+ if ( baduni!=NULL ) {
+ if ( ff_ask(_("Multiple"),(const char **) buts,0,1,_("There is already a glyph with this encoding,\nwhich must be unique within a font,\ndo you want to swap the encodings of the two?"))==1 )
+return( false );
+ if ( baduniscl==NULL ) {
+ baduni = CI_SCDuplicate(baduni);
+ baduniscl = chunkalloc(sizeof(struct splinecharlist));
+ baduniscl->sc = baduni;
+ baduniscl->next = ci->changes;
+ ci->changes = baduniscl;
+ }
+ baduni->unicodeenc = oldsc->unicodeenc;
+ }
+ if ( badname!=NULL ) {
+ if ( ff_ask(_("Multiple"),(const char **) buts,0,1,_("There is already a glyph with this name,\nwhich must be unique within a font,\ndo you want to swap the names of the two?"))==1 )
+return( false );
+ if ( badnamescl==NULL ) {
+ badname = CI_SCDuplicate(badname);
+ badnamescl = chunkalloc(sizeof(struct splinecharlist));
+ badnamescl->sc = badname;
+ badnamescl->next = ci->changes;
+ ci->changes = badnamescl;
+ }
+ free(badname->name); badname->name = copy(oldsc->name);
+ }
+ }
+ }
+ }
+ if ( !samename )
+ ci->name_change = true;
+ if ( !sameuni )
+ ci->uni_change = true;
+ free( newsc->name ); free( newsc->comment );
+ newsc->name = copy( name );
+ newsc->unicodeenc = unienc;
+ newsc->comment = copy( comment );
+return( true );
+}
+
static int _CI_OK(CharInfo *ci) {
int val;
int ret;
@@ -1228,6 +1426,7 @@ static int _CI_OK(CharInfo *ci) {
real tile_margin=0;
DBounds tileb;
#endif
+ SplineChar *oldsc = ci->cachedsc==NULL ? ci->sc : ci->cachedsc;
if ( !CI_ValidateAltUnis(ci))
return( false );
@@ -1309,25 +1508,33 @@ return( false );
}
name = u2utf8_copy( nm );
comment = GGadgetGetTitle8(GWidgetGetControl(ci->gw,CID_Comment));
- ret = SCSetMetaData(ci->cachedsc,name,val,comment);
+ if ( comment!=NULL && *comment=='\0' ) {
+ free(comment);
+ comment=NULL;
+ }
+ ret = CI_CheckMetaData(ci,oldsc,name,val,comment);
free(name); free(comment);
+ if ( !ret ) {
+ free( accentdevtab );
+ free( italicdevtab );
+ free(hicdt); free(vicdt);
+return( true );
+ }
ci->cachedsc->unlink_rm_ovrlp_save_undo = GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_UnlinkRmOverlap));
- if ( ret ) {
- ci->cachedsc->glyph_class = GGadgetGetFirstListSelectedItem(GWidgetGetControl(ci->gw,CID_GClass));
- val = GGadgetGetFirstListSelectedItem(GWidgetGetControl(ci->gw,CID_Color));
- if ( val!=-1 )
- ci->cachedsc->color = (intpt) (std_colors[val].userdata);
- CI_ParseCounters(ci);
- ci->cachedsc->tex_height = tex_height;
- ci->cachedsc->tex_depth = tex_depth;
- ci->cachedsc->italic_correction = italic;
- ci->cachedsc->top_accent_horiz = topaccent;
- ci->cachedsc->is_extended_shape = GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_IsExtended));
+ ci->cachedsc->glyph_class = GGadgetGetFirstListSelectedItem(GWidgetGetControl(ci->gw,CID_GClass));
+ val = GGadgetGetFirstListSelectedItem(GWidgetGetControl(ci->gw,CID_Color));
+ if ( val!=-1 )
+ ci->cachedsc->color = (intpt) (std_colors[val].userdata);
+ CI_ParseCounters(ci);
+ ci->cachedsc->tex_height = tex_height;
+ ci->cachedsc->tex_depth = tex_depth;
+ ci->cachedsc->italic_correction = italic;
+ ci->cachedsc->top_accent_horiz = topaccent;
+ ci->cachedsc->is_extended_shape = GGadgetIsChecked(GWidgetGetControl(ci->gw,CID_IsExtended));
#ifdef FONTFORGE_CONFIG_DEVICETABLES
- ci->cachedsc->italic_adjusts = DeviceTableParse(ci->cachedsc->italic_adjusts,italicdevtab);
- ci->cachedsc->top_accent_adjusts = DeviceTableParse(ci->cachedsc->top_accent_adjusts,accentdevtab);
+ ci->cachedsc->italic_adjusts = DeviceTableParse(ci->cachedsc->italic_adjusts,italicdevtab);
+ ci->cachedsc->top_accent_adjusts = DeviceTableParse(ci->cachedsc->top_accent_adjusts,accentdevtab);
#endif
- }
ci->cachedsc->horiz_variants = CI_ParseVariants(ci->cachedsc->horiz_variants,ci,1,hicdt,hic,false);
ci->cachedsc->vert_variants = CI_ParseVariants(ci->cachedsc->vert_variants ,ci,0,vicdt,vic,false);
@@ -1337,11 +1544,11 @@ return( false );
CI_ParseAltUnis(ci);
- if ( ret && ci->lc_seen ) {
+ if ( ci->lc_seen ) {
PST *pst, *prev=NULL;
int i;
ci->cachedsc->lig_caret_cnt_fixed = lig_caret_cnt_fixed;
- for ( pst = ci->sc->possub; pst!=NULL && pst->type!=pst_lcaret; pst=pst->next )
+ for ( pst = ci->cachedsc->possub; pst!=NULL && pst->type!=pst_lcaret; pst=pst->next )
prev = pst;
if ( pst==NULL && lc_cnt==0 )
/* Nothing to do */;
@@ -1376,7 +1583,7 @@ return( ret );
}
static void CI_ApplyAll(CharInfo *ci) {
- int ret, refresh_fvdi = false;
+ int refresh_fvdi = false;
struct splinecharlist *scl;
SplineChar *cached, *sc;
SplineFont *sf = ci->sc->parent;
@@ -1388,7 +1595,35 @@ static void CI_ApplyAll(CharInfo *ci) {
SCPreserveState(sc,2);
if ( strcmp(cached->name,sc->name)!=0 || cached->unicodeenc!=sc->unicodeenc )
refresh_fvdi = 1;
- ret = SCSetMetaData(sc,cached->name,cached->unicodeenc,cached->comment);
+ if ( sc->name==NULL || strcmp( sc->name,cached->name )!=0 ) {
+ if ( sc->name!=NULL )
+ SFGlyphRenameFixup(sf,sc->name,cached->name);
+ free(sc->name); sc->name = copy(cached->name);
+ sc->namechanged = true;
+ GlyphHashFree(sf);
+ }
+ if ( sc->unicodeenc != cached->unicodeenc ) {
+ struct splinecharlist *scl;
+ int layer;
+ RefChar *ref;
+ struct altuni *alt;
+
+ /* All references need the new unicode value */
+ for ( scl=sc->dependents; scl!=NULL; scl=scl->next ) {
+ for ( layer=ly_back; layer<scl->sc->layer_cnt; ++layer )
+ for ( ref = scl->sc->layers[layer].refs; ref!=NULL; ref=ref->next )
+ if ( ref->sc==sc )
+ ref->unicode_enc = cached->unicodeenc;
+ }
+ /* If the current unicode enc were in the list of alt unis */
+ /* the user might have forgotten to remove it. So if s/he did */
+ /* forget, swap the altuni value with the old value */
+ for ( alt=cached->altuni; alt!=NULL && (alt->unienc!=cached->unicodeenc || alt->vs!=-1 || alt->fid!=0); alt=alt->next );
+ if ( alt!=NULL ) /* alt->unienc==new value */
+ alt->unienc = sc->unicodeenc;
+ sc->unicodeenc = cached->unicodeenc;
+ }
+ free(sc->comment); sc->comment = copy(cached->comment);
sc->unlink_rm_ovrlp_save_undo = cached->unlink_rm_ovrlp_save_undo;
sc->glyph_class = cached->glyph_class;
if ( sc->color != cached->color )
@@ -1422,6 +1657,9 @@ static void CI_ApplyAll(CharInfo *ci) {
PSTFree(sc->possub);
sc->possub = cached->possub;
cached->possub = NULL;
+ KernPairsFree(sc->kerns); KernPairsFree(sc->vkerns);
+ sc->kerns = cached->kerns; sc->vkerns = cached->vkerns;
+ cached->kerns = cached->vkerns = NULL;
#ifdef FONTFORGE_CONFIG_TYPE3
sc->tile_margin = cached->tile_margin;
sc->tile_bounds = cached->tile_bounds;
@@ -1430,9 +1668,22 @@ static void CI_ApplyAll(CharInfo *ci) {
sc->changed = true;
refresh_fvdi = true;
}
+ SCRefreshTitles(sc);
+ }
+ if ( ci->name_change || ci->uni_change ) {
+ for ( fvs=(FontView *) sf->fv; fvs!=NULL; fvs=(FontView *) fvs->b.nextsame ) {
+ /* Postscript encodings are by name, others are by unicode */
+ /* Hence slight differences in when we update the encoding */
+ if ( (ci->name_change && fvs->b.map->enc->psnames!=NULL ) ||
+ (ci->uni_change && fvs->b.map->enc->psnames==NULL )) {
+ fvs->b.map->enc = &custom;
+ FVSetTitle((FontViewBase *) fvs);
+ refresh_fvdi = true;
+ }
+ }
}
if ( refresh_fvdi ) {
- for ( fvs=(FontView *) sf->fv; fvs!=NULL; fvs=(FontView *) fvs->b.next ) {
+ for ( fvs=(FontView *) sf->fv; fvs!=NULL; fvs=(FontView *) fvs->b.nextsame ) {
GDrawRequestExpose(fvs->gw,NULL,false); /* Redraw info area just in case this char is selected */
GDrawRequestExpose(fvs->v,NULL,false); /* Redraw character area in case this char is on screen */
}
diff --git a/fontforge/fvfonts.c b/fontforge/fvfonts.c
index deeb6341..9188db4b 100644
--- a/fontforge/fvfonts.c
+++ b/fontforge/fvfonts.c
@@ -464,7 +464,7 @@ static void KernClassesAdd(SplineFont *into, SplineFont *from,struct sfmergecont
}
}
-static struct altuni *AltUniCopy(struct altuni *altuni,SplineFont *noconflicts) {
+struct altuni *AltUniCopy(struct altuni *altuni,SplineFont *noconflicts) {
struct altuni *head=NULL, *last=NULL, *cur;
while ( altuni!=NULL ) {
diff --git a/fontforge/splinechar.c b/fontforge/splinechar.c
index 5c24ba2f..f5784187 100644
--- a/fontforge/splinechar.c
+++ b/fontforge/splinechar.c
@@ -1023,7 +1023,9 @@ int SCSetMetaData(SplineChar *sc,char *name,int unienc,const char *comment) {
int i, mv=0;
int isnotdef, samename=false, sameuni=false;
struct altuni *alt;
- int real_glyph_change = sf->glyphs[sc->orig_pos]==sc; /* Odd things happen in charinfo when user presses Next/Prev, hence need for the orig_pos check */
+
+ if ( sf->glyphs[sc->orig_pos]!=sc )
+ IError("Bad call to SCSetMetaData");
for ( alt=sc->altuni; alt!=NULL && (alt->unienc!=unienc || alt->vs!=-1 || alt->fid!=0); alt=alt->next );
if ( unienc==sc->unicodeenc || alt!=NULL )
@@ -1076,19 +1078,15 @@ return( false );
alt->unienc = sc->unicodeenc;
sc->unicodeenc = unienc;
if ( sc->name==NULL || strcmp(name,sc->name)!=0 ) {
- if ( sc->name!=NULL && real_glyph_change ) /* Odd things happen in charinfo when user presses Next/Prev, hence need for the orig_pos check */
+ if ( sc->name!=NULL )
SFGlyphRenameFixup(sf,sc->name,name);
free(sc->name);
sc->name = copy(name);
sc->namechanged = true;
- if ( real_glyph_change )
- GlyphHashFree(sf);
+ GlyphHashFree(sf);
}
- if ( real_glyph_change )
- sf->changed = true;
- if ( !real_glyph_change )
- /* Do Nothing */;
- else if ( samename )
+ sf->changed = true;
+ if ( samename )
/* Ok to name it itself */;
else if ( sameuni && ( unienc>=0xe000 && unienc<=0xf8ff ))
/* Ok to name things in the private use area */;
@@ -1107,8 +1105,7 @@ return( false );
if ( comment!=NULL && *comment!='\0' )
sc->comment = copy(comment);
- if ( real_glyph_change )
- SCRefreshTitles(sc);
+ SCRefreshTitles(sc);
return( true );
}
diff --git a/fontforge/splinefont.h b/fontforge/splinefont.h
index 7da111bd..de01d680 100644
--- a/fontforge/splinefont.h
+++ b/fontforge/splinefont.h
@@ -2187,6 +2187,7 @@ extern SplineChar *SplineCharCreate(int layer_cnt);
extern SplineChar *SFSplineCharCreate(SplineFont *sf);
extern RefChar *RefCharCreate(void);
extern RefChar *RefCharsCopy(RefChar *ref); /* Still needs to be instanciated and have the dependency list adjusted */
+extern struct altuni *AltUniCopy(struct altuni *altuni,SplineFont *noconflicts);
extern void SCAddRef(SplineChar *sc,SplineChar *rsc,int layer, real xoff, real yoff);
extern void _SCAddRef(SplineChar *sc,SplineChar *rsc,int layer, real transform[6]);
extern KernClass *KernClassCopy(KernClass *kc);
@@ -2205,6 +2206,7 @@ extern void MacNameListFree(struct macname *mn);
extern void MacSettingListFree(struct macsetting *ms);
extern void MacFeatListFree(MacFeat *mf);
extern void GlyphVariantsFree(struct glyphvariants *gv);
+extern struct glyphvariants *GlyphVariantsCopy(struct glyphvariants *gv);
extern void MathKernVContentsFree(struct mathkernvertex *mk);
extern void MathKernFree(struct mathkern *mk);
extern struct mathkern *MathKernCopy(struct mathkern *mk);
diff --git a/fontforge/splineutil.c b/fontforge/splineutil.c
index 6deb67dc..cc899bea 100644
--- a/fontforge/splineutil.c
+++ b/fontforge/splineutil.c
@@ -5965,6 +5965,27 @@ return;
chunkfree(gv,sizeof(*gv));
}
+struct glyphvariants *GlyphVariantsCopy(struct glyphvariants *gv) {
+ struct glyphvariants *newgv;
+ int i;
+
+ if ( gv==NULL )
+return( NULL );
+ newgv = chunkalloc(sizeof(struct glyphvariants));
+ newgv->variants = copy(gv->variants);
+#ifdef FONTFORGE_CONFIG_DEVICETABLES
+ newgv->italic_adjusts = DeviceTableCopy(gv->italic_adjusts);
+#endif
+ newgv->part_cnt = gv->part_cnt;
+ if ( gv->part_cnt!=0 ) {
+ newgv->parts = gcalloc(gv->part_cnt,sizeof(struct gv_part));
+ memcpy(newgv->parts,gv->parts,gv->part_cnt*sizeof(struct gv_part));
+ for ( i=0; i<gv->part_cnt; ++i )
+ newgv->parts[i].component = copy(gv->parts[i].component);
+ }
+return( newgv );
+}
+
struct mathkern *MathKernCopy(struct mathkern *mk) {
int i,j;
struct mathkern *mknew;