struct rangeinfo *SFUnicodeRanges(SplineFont *sf, enum ur_flags flags) { int cnt; int i,j, gid; struct rangeinfo *ri; static int initialized = false; if ( !initialized ) { initialized = true; for (i=cnt=0; unicoderange[i].name!=NULL; ++i ) if ( unicoderange[i].display ) { int top = unicoderange[i].last; int bottom = unicoderange[i].first; int cnt = 0; for ( j=bottom; j<=top; ++j ) { if ( isunicodepointassigned(j) ) ++cnt; } if ( cnt==0 ) unicoderange[i].unassigned = true; unicoderange[i].actual = cnt; } } for (i=cnt=0; unicoderange[i].name!=NULL; ++i ) if ( unicoderange[i].display ) ++cnt; for (i=0; unassignedplanes[i].name!=NULL; ++i ) if ( unassignedplanes[i].display ) ++cnt; cnt+=2; /* for nonunicode, unassigned codes */ ri = gcalloc(cnt+1,sizeof(struct rangeinfo)); for (i=cnt=0; unicoderange[i].name!=NULL; ++i ) if ( unicoderange[i].display ) ri[cnt++].range = &unicoderange[i]; for (i=0; unassignedplanes[i].name!=NULL; ++i ) if ( unassignedplanes[i].display ) ri[cnt++].range = &unassignedplanes[i]; ri[cnt++].range = &nonunicode; ri[cnt++].range = &unassigned; for ( j=0; j<cnt-2; ++j ) { int top = ri[j].range->last; int bottom = ri[j].range->first; for ( gid=0; gid<sf->glyphcnt; ++gid ) if ( sf->glyphs[gid]!=NULL ) { int u=sf->glyphs[gid]->unicodeenc; if ( u>=bottom && u<=top && (ri[j].range->unassigned || isunicodepointassigned(u)) ) ++ri[j].cnt; } } /* non unicode glyphs (stylistic variations, etc.) */ for ( gid=0; gid<sf->glyphcnt; ++gid ) if ( sf->glyphs[gid]!=NULL ) { int u=sf->glyphs[gid]->unicodeenc; if ( u<0 || u>0x11ffff ) ++ri[j].cnt; } /* glyphs attached to code points which have not been assigned in */ /* the version of unicode I know about (4.1 when this was written) */ ++j; for ( gid=0; gid<sf->glyphcnt; ++gid ) if ( sf->glyphs[gid]!=NULL ) { int u=sf->glyphs[gid]->unicodeenc; if ( u>=0 && u<=0x11ffff && !isunicodepointassigned(u)) ++ri[j].cnt; } if ( !(flags&ur_includeempty) ) { for ( i=j=0; i<cnt; ++i ) { if ( ri[i].cnt!=0 ) { if ( i!=j ) ri[j] = ri[i]; ++j; } } ri[j].range = NULL; cnt = j; } if ( flags&ur_sortbyunicode ) qsort(ri,cnt,sizeof(struct rangeinfo),ucmp); else if ( flags&ur_sortbyname ) qsort(ri,cnt,sizeof(struct rangeinfo),ncmp); return( ri ); }
struct rangeinfo *SFUnicodeRanges(SplineFont *sf, enum ur_flags flags) { /* Find and return the Unicode range descriptions for these characters */ /* Return NULL if out of memory to hold rangeinfo[cnt]. */ int cnt; int i, gid; int32 j; struct rangeinfo *ri; static int initialized = false; if ( !initialized ) { initialized = true; for (i=cnt=0; unicoderange[i].name!=NULL; ++i ) if ( unicoderange[i].display ) { int32 top = unicoderange[i].last; int32 bottom = unicoderange[i].first; int cnt = 0; for ( j=bottom; j<=top; ++j ) { if ( isunicodepointassigned(j) ) ++cnt; } unicoderange[i].unassigned = (cnt==0); unicoderange[i].actual = cnt; } } /* count number of ranges to return back in rangeinfo[cnt] */ for (i=cnt=0; unicoderange[i].name!=NULL; ++i ) if ( unicoderange[i].display ) ++cnt; for (i=0; unassignedplanes[i].name!=NULL; ++i ) if ( unassignedplanes[i].display ) ++cnt; cnt+=2; /* for nonunicode, unassigned codes */ /* create memory space needed to return back rangeinfo[cnt] */ if ( (ri=calloc(cnt+1,sizeof(struct rangeinfo)))==NULL ) { NoMoreMemMessage(); return( NULL ); } /* populate rangeinfo[0..cnt-1] with unicoderanges we will display */ for (i=cnt=0; unicoderange[i].name!=NULL; ++i ) if ( unicoderange[i].display ) ri[cnt++].range = &unicoderange[i]; for (i=0; unassignedplanes[i].name!=NULL; ++i ) if ( unassignedplanes[i].display ) ri[cnt++].range = &unassignedplanes[i]; ri[cnt++].range = &nonunicode; ri[cnt++].range = &unassigned; /* count glyphs in each range */ for ( j=0; j<cnt-2; ++j ) { int32 top = ri[j].range->last; int32 bottom = ri[j].range->first; for ( gid=0; gid<sf->glyphcnt; ++gid ) if ( sf->glyphs[gid]!=NULL ) { int32 u=sf->glyphs[gid]->unicodeenc; if ( u>=bottom && u<=top && (ri[j].range->unassigned || isunicodepointassigned(u)) ) ++ri[j].cnt; } } /* non unicode glyphs (stylistic variations, etc.) */ for ( gid=0; gid<sf->glyphcnt; ++gid ) if ( sf->glyphs[gid]!=NULL ) { int32 u=sf->glyphs[gid]->unicodeenc; if ( u<0 || u>0x11ffff ) ++ri[j].cnt; } /* glyphs attached to code points which have not been assigned in */ /* the version of unicode I know about (4.1 when this was written) */ ++j; for ( gid=0; gid<sf->glyphcnt; ++gid ) if ( sf->glyphs[gid]!=NULL ) { int32 u=sf->glyphs[gid]->unicodeenc; if ( u>=0 && u<=0x11ffff && !isunicodepointassigned(u)) ++ri[j].cnt; } if ( !(flags&ur_includeempty) ) { for ( i=j=0; i<cnt; ++i ) { if ( ri[i].cnt!=0 ) { if ( i!=j ) ri[j] = ri[i]; ++j; } } ri[j].range = NULL; cnt = j; } if ( flags&ur_sortbyunicode ) qsort(ri,cnt,sizeof(struct rangeinfo),ucmp); /* sort by ranges */ else if ( flags&ur_sortbyname ) qsort(ri,cnt,sizeof(struct rangeinfo),ncmp); /* sort by names */ return( ri ); }