summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/luafontloader/fontforge/fontforge/mm.c
diff options
context:
space:
mode:
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.c235
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 );
+}
+