beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / luafontloader / fontforge / fontforge / mm.c
blobdb051b7fe542d30a23aff119f653d6d66aff1164
1 /* Copyright (C) 2003-2008 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:
6 * Redistributions of source code must retain the above copyright notice, this
7 * list of conditions and the following disclaimer.
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.
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.
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.
27 #include "fontforgevw.h"
28 #include <ustring.h>
29 #include <math.h>
30 #include <utype.h>
31 #include "ttf.h"
32 #include "mm.h"
34 char *MMAxisAbrev(char *axis_name) {
35 if ( strcmp(axis_name,"Weight")==0 )
36 return( "wt" );
37 if ( strcmp(axis_name,"Width")==0 )
38 return( "wd" );
39 if ( strcmp(axis_name,"OpticalSize")==0 )
40 return( "op" );
41 if ( strcmp(axis_name,"Slant")==0 )
42 return( "sl" );
44 return( axis_name );
47 double MMAxisUnmap(MMSet *mm,int axis,double ncv) {
48 struct axismap *axismap = &mm->axismaps[axis];
49 int j;
51 if ( ncv<=axismap->blends[0] )
52 return(axismap->designs[0]);
54 for ( j=1; j<axismap->points; ++j ) {
55 if ( ncv<=axismap->blends[j]) {
56 double t = (ncv-axismap->blends[j-1])/(axismap->blends[j]-axismap->blends[j-1]);
57 return( axismap->designs[j-1]+ t*(axismap->designs[j]-axismap->designs[j-1]) );
61 return(axismap->designs[axismap->points-1]);
64 static char *_MMMakeFontname(MMSet *mm,real *normalized,char **fullname) {
65 char *pt, *pt2, *hyphen=NULL;
66 char *ret = NULL;
67 int i;
69 pt = ret = galloc(strlen(mm->normal->familyname)+ mm->axis_count*15 + 1);
70 strcpy(pt,mm->normal->familyname);
71 pt += strlen(pt);
72 *pt++ = '_';
73 for ( i=0; i<mm->axis_count; ++i ) {
74 sprintf( pt, " %d%s", (int) rint(MMAxisUnmap(mm,i,normalized[i])),
75 MMAxisAbrev(mm->axes[i]));
76 pt += strlen(pt);
78 if ( pt>ret && pt[-1]==' ' )
79 --pt;
80 *pt = '\0';
82 *fullname = ret;
84 ret = copy(ret);
85 for ( pt=*fullname, pt2=ret; *pt!='\0'; ++pt )
86 if ( pt==hyphen )
87 *pt2++ = '-';
88 else if ( *pt!=' ' )
89 *pt2++ = *pt;
90 *pt2 = '\0';
91 return( ret );
94 char *MMMakeMasterFontname(MMSet *mm,int ipos,char **fullname) {
95 return( _MMMakeFontname(mm,&mm->positions[ipos*mm->axis_count],fullname));
98 static char *_MMGuessWeight(MMSet *mm,real *normalized,char *def) {
99 int i;
100 char *ret;
101 real design;
103 for ( i=0; i<mm->axis_count; ++i ) {
104 if ( strcmp(mm->axes[i],"Weight")==0 )
105 break;
107 if ( i==mm->axis_count )
108 return( def );
109 design = MMAxisUnmap(mm,i,normalized[i]);
110 if ( design<50 || design>1500 ) /* Er... Probably not the 0...1000 range I expect */
111 return( def );
112 ret = NULL;
113 if ( design<150 )
114 ret = "Thin";
115 else if ( design<350 )
116 ret = "Light";
117 else if ( design<550 )
118 ret = "Medium";
119 else if ( design<650 )
120 ret = "DemiBold";
121 else if ( design<750 )
122 ret = "Bold";
123 else if ( design<850 )
124 ret = "Heavy";
125 else
126 ret = "Black";
127 free( def );
128 return( copy(ret) );
131 char *MMGuessWeight(MMSet *mm,int ipos,char *def) {
132 return( _MMGuessWeight(mm,&mm->positions[ipos*mm->axis_count],def));
135 /* Given a postscript array of scalars, what's the ipos'th element? */
136 char *MMExtractNth(char *pt,int ipos) {
137 int i;
138 char *end;
140 while ( *pt==' ' ) ++pt;
141 if ( *pt=='[' ) ++pt;
142 for ( i=0; *pt!=']' && *pt!='\0'; ++i ) {
143 while ( *pt==' ' ) ++pt;
144 if ( *pt==']' || *pt=='\0' )
145 return( NULL );
146 for ( end=pt; *end!=' ' && *end!=']' && *end!='\0'; ++end );
147 if ( i==ipos )
148 return( copyn(pt,end-pt));
149 pt = end;
151 return( NULL );
154 /* Given a postscript array of arrays, such as those found in Blend Private BlueValues */
155 /* return the array composed of the ipos'th element of each sub-array */
156 char *MMExtractArrayNth(char *pt,int ipos) {
157 char *hold[40], *ret;
158 int i,j,len;
160 while ( *pt==' ' ) ++pt;
161 if ( *pt=='[' ) ++pt;
162 i = 0;
163 while ( *pt!=']' && *pt!=' ' ) {
164 while ( *pt==' ' ) ++pt;
165 if ( *pt=='[' ) {
166 if ( i<(int)(sizeof(hold)/sizeof(hold[0])) )
167 hold[i++] = MMExtractNth(pt,ipos);
168 ++pt;
169 while ( *pt!=']' && *pt!='\0' ) ++pt;
171 if ( *pt!='\0' )
172 ++pt;
174 if ( i==0 )
175 return( NULL );
176 for ( j=len=0; j<i; ++j ) {
177 if ( hold[j]==NULL ) {
178 for ( j=0; j<i; ++j )
179 free(hold[j]);
180 return( NULL );
182 len += strlen( hold[j] )+1;
185 pt = ret = galloc(len+4);
186 *pt++ = '[';
187 for ( j=0; j<i; ++j ) {
188 strcpy(pt,hold[j]);
189 free(hold[j]);
190 pt += strlen(pt);
191 if ( j!=i-1 )
192 *pt++ = ' ';
194 *pt++ = ']';
195 *pt++ = '\0';
196 return( ret );