diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/mm.c')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/mm.c | 235 |
1 files changed, 235 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/mm.c b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/mm.c new file mode 100644 index 00000000000..6bed24e9a54 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/mm.c @@ -0,0 +1,235 @@ +/* Copyright (C) 2003-2008 by George Williams */ +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + + * The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO + * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; + * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "fontforgevw.h" +#include <ustring.h> +#include <math.h> +#include <utype.h> +#include "ttf.h" +#include "mm.h" + +char *MMAxisAbrev(char *axis_name) { + if ( strcmp(axis_name,"Weight")==0 ) +return( "wt" ); + if ( strcmp(axis_name,"Width")==0 ) +return( "wd" ); + if ( strcmp(axis_name,"OpticalSize")==0 ) +return( "op" ); + if ( strcmp(axis_name,"Slant")==0 ) +return( "sl" ); + +return( axis_name ); +} + +double MMAxisUnmap(MMSet *mm,int axis,double ncv) { + struct axismap *axismap = &mm->axismaps[axis]; + int j; + + if ( ncv<=axismap->blends[0] ) +return(axismap->designs[0]); + + for ( j=1; j<axismap->points; ++j ) { + if ( ncv<=axismap->blends[j]) { + double t = (ncv-axismap->blends[j-1])/(axismap->blends[j]-axismap->blends[j-1]); +return( axismap->designs[j-1]+ t*(axismap->designs[j]-axismap->designs[j-1]) ); + } + } + +return(axismap->designs[axismap->points-1]); +} + +static char *_MMMakeFontname(MMSet *mm,real *normalized,char **fullname) { + char *pt, *pt2, *hyphen=NULL; + char *ret = NULL; + int i,j; + + if ( mm->apple ) { + for ( i=0; i<mm->named_instance_count; ++i ) { + for ( j=0; j<mm->axis_count; ++j ) { + if (( normalized[j] == -1 && + RealApprox(mm->named_instances[i].coords[j],mm->axismaps[j].min) ) || + ( normalized[j] == 0 && + RealApprox(mm->named_instances[i].coords[j],mm->axismaps[j].def) ) || + ( normalized[j] == 1 && + RealApprox(mm->named_instances[i].coords[j],mm->axismaps[j].max) )) + /* A match so far */; + else + break; + } + if ( j==mm->axis_count ) + break; + } + if ( i!=mm->named_instance_count ) { + char *styles = PickNameFromMacName(mm->named_instances[i].names); + if ( styles==NULL ) + styles = FindEnglishNameInMacName(mm->named_instances[i].names); + if ( styles!=NULL ) { + ret = galloc(strlen(mm->normal->familyname)+ strlen(styles)+3 ); + strcpy(ret,mm->normal->familyname); + hyphen = ret+strlen(ret); + strcpy(hyphen," "); + strcpy(hyphen+1,styles); + free(styles); + } + } + } + + if ( ret==NULL ) { + pt = ret = galloc(strlen(mm->normal->familyname)+ mm->axis_count*15 + 1); + strcpy(pt,mm->normal->familyname); + pt += strlen(pt); + *pt++ = '_'; + for ( i=0; i<mm->axis_count; ++i ) { + if ( !mm->apple ) + sprintf( pt, " %d%s", (int) rint(MMAxisUnmap(mm,i,normalized[i])), + MMAxisAbrev(mm->axes[i])); + else + sprintf( pt, " %.1f%s", MMAxisUnmap(mm,i,normalized[i]), + MMAxisAbrev(mm->axes[i])); + pt += strlen(pt); + } + if ( pt>ret && pt[-1]==' ' ) + --pt; + *pt = '\0'; + } + + *fullname = ret; + + ret = copy(ret); + for ( pt=*fullname, pt2=ret; *pt!='\0'; ++pt ) + if ( pt==hyphen ) + *pt2++ = '-'; + else if ( *pt!=' ' ) + *pt2++ = *pt; + *pt2 = '\0'; +return( ret ); +} + +char *MMMakeMasterFontname(MMSet *mm,int ipos,char **fullname) { +return( _MMMakeFontname(mm,&mm->positions[ipos*mm->axis_count],fullname)); +} + +static char *_MMGuessWeight(MMSet *mm,real *normalized,char *def) { + int i; + char *ret; + real design; + + for ( i=0; i<mm->axis_count; ++i ) { + if ( strcmp(mm->axes[i],"Weight")==0 ) + break; + } + if ( i==mm->axis_count ) +return( def ); + design = MMAxisUnmap(mm,i,normalized[i]); + if ( design<50 || design>1500 ) /* Er... Probably not the 0...1000 range I expect */ +return( def ); + ret = NULL; + if ( design<150 ) + ret = "Thin"; + else if ( design<350 ) + ret = "Light"; + else if ( design<550 ) + ret = "Medium"; + else if ( design<650 ) + ret = "DemiBold"; + else if ( design<750 ) + ret = "Bold"; + else if ( design<850 ) + ret = "Heavy"; + else + ret = "Black"; + free( def ); +return( copy(ret) ); +} + +char *MMGuessWeight(MMSet *mm,int ipos,char *def) { +return( _MMGuessWeight(mm,&mm->positions[ipos*mm->axis_count],def)); +} + +/* Given a postscript array of scalars, what's the ipos'th element? */ +char *MMExtractNth(char *pt,int ipos) { + int i; + char *end; + + while ( *pt==' ' ) ++pt; + if ( *pt=='[' ) ++pt; + for ( i=0; *pt!=']' && *pt!='\0'; ++i ) { + while ( *pt==' ' ) ++pt; + if ( *pt==']' || *pt=='\0' ) +return( NULL ); + for ( end=pt; *end!=' ' && *end!=']' && *end!='\0'; ++end ); + if ( i==ipos ) +return( copyn(pt,end-pt)); + pt = end; + } +return( NULL ); +} + +/* Given a postscript array of arrays, such as those found in Blend Private BlueValues */ +/* return the array composed of the ipos'th element of each sub-array */ +char *MMExtractArrayNth(char *pt,int ipos) { + char *hold[40], *ret; + int i,j,len; + + while ( *pt==' ' ) ++pt; + if ( *pt=='[' ) ++pt; + i = 0; + while ( *pt!=']' && *pt!=' ' ) { + while ( *pt==' ' ) ++pt; + if ( *pt=='[' ) { + if ( i<(int)(sizeof(hold)/sizeof(hold[0])) ) + hold[i++] = MMExtractNth(pt,ipos); + ++pt; + while ( *pt!=']' && *pt!='\0' ) ++pt; + } + if ( *pt!='\0' ) + ++pt; + } + if ( i==0 ) +return( NULL ); + for ( j=len=0; j<i; ++j ) { + if ( hold[j]==NULL ) { + for ( j=0; j<i; ++j ) + free(hold[j]); +return( NULL ); + } + len += strlen( hold[j] )+1; + } + + pt = ret = galloc(len+4); + *pt++ = '['; + for ( j=0; j<i; ++j ) { + strcpy(pt,hold[j]); + free(hold[j]); + pt += strlen(pt); + if ( j!=i-1 ) + *pt++ = ' '; + } + *pt++ = ']'; + *pt++ = '\0'; +return( ret ); +} + |