diff --git a/AUTHORS b/AUTHORS index b5e225e680..82dc7eed3f 100644 --- a/AUTHORS +++ b/AUTHORS @@ -16,7 +16,7 @@ Arthaey Angosii Alexey Kryukov - nowakowskittfinstr.c Alexandre Prokoudine Andreas Larsen -Barry Schwartz +Barry Schwartz Baruch Even - (debian upstream) baruch Bastien Dejean Behnam Esfahbod diff --git a/Unicode/is_Ligature.c b/Unicode/is_Ligature.c index 5ae19ab93b..342d4a50aa 100644 --- a/Unicode/is_Ligature.c +++ b/Unicode/is_Ligature.c @@ -1,33 +1,220 @@ -/* This is a generated file. */ +/* +Copyright: 2012 Barry Schwartz +Copyright: 2016 Joe Da Silva +License: BSD-3-clause +Contributions: +*/ + +/* This file was generated using the program 'makeutype' */ +#include "utype.h" #include -/* - * Codepoints whose names match the regular expression - * - * LIGATURE|VULGAR FRACTION - * - */ -static unsigned int matching_codepoints[528] = -{ -188, 189, 190, 306, 307, 338, 339, 1188, 1189, 1204, 1205, 1236, 1237, 1415, 1520, 1521, 1522, 1558, 1750, 1751, 8528, 8529, 8530, 8531, 8532, 8533, 8534, 8535, 8536, 8537, 8538, 8539, 8540, 8541, 8542, 8585, 43001, 64256, 64257, 64258, 64259, 64260, 64261, 64262, 64275, 64276, 64277, 64278, 64279, 64287, 64335, 64490, 64491, 64492, 64493, 64494, 64495, 64496, 64497, 64498, 64499, 64500, 64501, 64502, 64503, 64504, 64505, 64506, 64507, 64512, 64513, 64514, 64515, 64516, 64517, 64518, 64519, 64520, 64521, 64522, 64523, 64524, 64525, 64526, 64527, 64528, 64529, 64530, 64531, 64532, 64533, 64534, 64535, 64536, 64537, 64538, 64539, 64540, 64541, 64542, 64543, 64544, 64545, 64546, 64547, 64548, 64549, 64550, 64551, 64552, 64553, 64554, 64555, 64556, 64557, 64558, 64559, 64560, 64561, 64562, 64563, 64564, 64565, 64566, 64567, 64568, 64569, 64570, 64571, 64572, 64573, 64574, 64575, 64576, 64577, 64578, 64579, 64580, 64581, 64582, 64583, 64584, 64585, 64586, 64587, 64588, 64589, 64590, 64591, 64592, 64593, 64594, 64595, 64596, 64597, 64598, 64599, 64600, 64601, 64602, 64603, 64604, 64605, 64606, 64607, 64608, 64609, 64610, 64611, 64612, 64613, 64614, 64615, 64616, 64617, 64618, 64619, 64620, 64621, 64622, 64623, 64624, 64625, 64626, 64627, 64628, 64629, 64630, 64631, 64632, 64633, 64634, 64635, 64636, 64637, 64638, 64639, 64640, 64641, 64642, 64643, 64644, 64645, 64646, 64647, 64648, 64649, 64650, 64651, 64652, 64653, 64654, 64655, 64656, 64657, 64658, 64659, 64660, 64661, 64662, 64663, 64664, 64665, 64666, 64667, 64668, 64669, 64670, 64671, 64672, 64673, 64674, 64675, 64676, 64677, 64678, 64679, 64680, 64681, 64682, 64683, 64684, 64685, 64686, 64687, 64688, 64689, 64690, 64691, 64692, 64693, 64694, 64695, 64696, 64697, 64698, 64699, 64700, 64701, 64702, 64703, 64704, 64705, 64706, 64707, 64708, 64709, 64710, 64711, 64712, 64713, 64714, 64715, 64716, 64717, 64718, 64719, 64720, 64721, 64722, 64723, 64724, 64725, 64726, 64727, 64728, 64729, 64730, 64731, 64732, 64733, 64734, 64735, 64736, 64737, 64738, 64739, 64740, 64741, 64742, 64743, 64744, 64745, 64746, 64747, 64748, 64749, 64750, 64751, 64752, 64753, 64754, 64755, 64756, 64757, 64758, 64759, 64760, 64761, 64762, 64763, 64764, 64765, 64766, 64767, 64768, 64769, 64770, 64771, 64772, 64773, 64774, 64775, 64776, 64777, 64778, 64779, 64780, 64781, 64782, 64783, 64784, 64785, 64786, 64787, 64788, 64789, 64790, 64791, 64792, 64793, 64794, 64795, 64796, 64797, 64798, 64799, 64800, 64801, 64802, 64803, 64804, 64805, 64806, 64807, 64808, 64809, 64810, 64811, 64812, 64813, 64814, 64815, 64816, 64817, 64818, 64819, 64820, 64821, 64822, 64823, 64824, 64825, 64826, 64827, 64828, 64829, 64848, 64849, 64850, 64851, 64852, 64853, 64854, 64855, 64856, 64857, 64858, 64859, 64860, 64861, 64862, 64863, 64864, 64865, 64866, 64867, 64868, 64869, 64870, 64871, 64872, 64873, 64874, 64875, 64876, 64877, 64878, 64879, 64880, 64881, 64882, 64883, 64884, 64885, 64886, 64887, 64888, 64889, 64890, 64891, 64892, 64893, 64894, 64895, 64896, 64897, 64898, 64899, 64900, 64901, 64902, 64903, 64904, 64905, 64906, 64907, 64908, 64909, 64910, 64911, 64914, 64915, 64916, 64917, 64918, 64919, 64920, 64921, 64922, 64923, 64924, 64925, 64926, 64927, 64928, 64929, 64930, 64931, 64932, 64933, 64934, 64935, 64936, 64937, 64938, 64939, 64940, 64941, 64942, 64943, 64944, 64945, 64946, 64947, 64948, 64949, 64950, 64951, 64952, 64953, 64954, 64955, 64956, 64957, 64958, 64959, 64960, 64961, 64962, 64963, 64964, 64965, 64966, 64967, 65008, 65009, 65010, 65011, 65012, 65013, 65014, 65015, 65016, 65017, 65018, 65019, 65021, 65056, 65057, 65269, 65270, 65271, 65272, 65273, 65274, 65275, 65276 -}; - -static int compare_codepoints (const void *codepoint1, const void *codepoint2) -{ - const unsigned int *cp1 = (const unsigned int *) codepoint1; - const unsigned int *cp2 = (const unsigned int *) codepoint2; - return ((*cp1 < *cp2) ? -1 : ((*cp1 == *cp2) ? 0 : 1)); -} - -int is_LIGATURE_or_VULGAR_FRACTION(unsigned int codepoint); - -int is_LIGATURE_or_VULGAR_FRACTION(unsigned int codepoint) -{ - unsigned int *p = - (unsigned int *) bsearch (&codepoint, matching_codepoints, - 528, sizeof (unsigned int), - compare_codepoints); - return (p != (unsigned int *) 0); +/* unicode.org codepoints for ligatures, vulgar fractions, other fractions */ + +const uint16 ____ligature16[] = { + 0x0132, 0x0133, 0x0152, 0x0153, 0x04a4, 0x04a5, 0x04b4, 0x04b5, + 0x04d4, 0x04d5, 0x0587, 0x05f0, 0x05f1, 0x05f2, 0x0616, 0x06d6, + 0x06d7, 0xa7f9, 0xfb00, 0xfb01, 0xfb02, 0xfb03, 0xfb04, 0xfb05, + 0xfb06, 0xfb13, 0xfb14, 0xfb15, 0xfb16, 0xfb17, 0xfb1f, 0xfb4f, + 0xfbea, 0xfbeb, 0xfbec, 0xfbed, 0xfbee, 0xfbef, 0xfbf0, 0xfbf1, + 0xfbf2, 0xfbf3, 0xfbf4, 0xfbf5, 0xfbf6, 0xfbf7, 0xfbf8, 0xfbf9, + 0xfbfa, 0xfbfb, 0xfc00, 0xfc01, 0xfc02, 0xfc03, 0xfc04, 0xfc05, + 0xfc06, 0xfc07, 0xfc08, 0xfc09, 0xfc0a, 0xfc0b, 0xfc0c, 0xfc0d, + 0xfc0e, 0xfc0f, 0xfc10, 0xfc11, 0xfc12, 0xfc13, 0xfc14, 0xfc15, + 0xfc16, 0xfc17, 0xfc18, 0xfc19, 0xfc1a, 0xfc1b, 0xfc1c, 0xfc1d, + 0xfc1e, 0xfc1f, 0xfc20, 0xfc21, 0xfc22, 0xfc23, 0xfc24, 0xfc25, + 0xfc26, 0xfc27, 0xfc28, 0xfc29, 0xfc2a, 0xfc2b, 0xfc2c, 0xfc2d, + 0xfc2e, 0xfc2f, 0xfc30, 0xfc31, 0xfc32, 0xfc33, 0xfc34, 0xfc35, + 0xfc36, 0xfc37, 0xfc38, 0xfc39, 0xfc3a, 0xfc3b, 0xfc3c, 0xfc3d, + 0xfc3e, 0xfc3f, 0xfc40, 0xfc41, 0xfc42, 0xfc43, 0xfc44, 0xfc45, + 0xfc46, 0xfc47, 0xfc48, 0xfc49, 0xfc4a, 0xfc4b, 0xfc4c, 0xfc4d, + 0xfc4e, 0xfc4f, 0xfc50, 0xfc51, 0xfc52, 0xfc53, 0xfc54, 0xfc55, + 0xfc56, 0xfc57, 0xfc58, 0xfc59, 0xfc5a, 0xfc5b, 0xfc5c, 0xfc5d, + 0xfc5e, 0xfc5f, 0xfc60, 0xfc61, 0xfc62, 0xfc63, 0xfc64, 0xfc65, + 0xfc66, 0xfc67, 0xfc68, 0xfc69, 0xfc6a, 0xfc6b, 0xfc6c, 0xfc6d, + 0xfc6e, 0xfc6f, 0xfc70, 0xfc71, 0xfc72, 0xfc73, 0xfc74, 0xfc75, + 0xfc76, 0xfc77, 0xfc78, 0xfc79, 0xfc7a, 0xfc7b, 0xfc7c, 0xfc7d, + 0xfc7e, 0xfc7f, 0xfc80, 0xfc81, 0xfc82, 0xfc83, 0xfc84, 0xfc85, + 0xfc86, 0xfc87, 0xfc88, 0xfc89, 0xfc8a, 0xfc8b, 0xfc8c, 0xfc8d, + 0xfc8e, 0xfc8f, 0xfc90, 0xfc91, 0xfc92, 0xfc93, 0xfc94, 0xfc95, + 0xfc96, 0xfc97, 0xfc98, 0xfc99, 0xfc9a, 0xfc9b, 0xfc9c, 0xfc9d, + 0xfc9e, 0xfc9f, 0xfca0, 0xfca1, 0xfca2, 0xfca3, 0xfca4, 0xfca5, + 0xfca6, 0xfca7, 0xfca8, 0xfca9, 0xfcaa, 0xfcab, 0xfcac, 0xfcad, + 0xfcae, 0xfcaf, 0xfcb0, 0xfcb1, 0xfcb2, 0xfcb3, 0xfcb4, 0xfcb5, + 0xfcb6, 0xfcb7, 0xfcb8, 0xfcb9, 0xfcba, 0xfcbb, 0xfcbc, 0xfcbd, + 0xfcbe, 0xfcbf, 0xfcc0, 0xfcc1, 0xfcc2, 0xfcc3, 0xfcc4, 0xfcc5, + 0xfcc6, 0xfcc7, 0xfcc8, 0xfcc9, 0xfcca, 0xfccb, 0xfccc, 0xfccd, + 0xfcce, 0xfccf, 0xfcd0, 0xfcd1, 0xfcd2, 0xfcd3, 0xfcd4, 0xfcd5, + 0xfcd6, 0xfcd7, 0xfcd8, 0xfcd9, 0xfcda, 0xfcdb, 0xfcdc, 0xfcdd, + 0xfcde, 0xfcdf, 0xfce0, 0xfce1, 0xfce2, 0xfce3, 0xfce4, 0xfce5, + 0xfce6, 0xfce7, 0xfce8, 0xfce9, 0xfcea, 0xfceb, 0xfcec, 0xfced, + 0xfcee, 0xfcef, 0xfcf0, 0xfcf1, 0xfcf2, 0xfcf3, 0xfcf4, 0xfcf5, + 0xfcf6, 0xfcf7, 0xfcf8, 0xfcf9, 0xfcfa, 0xfcfb, 0xfcfc, 0xfcfd, + 0xfcfe, 0xfcff, 0xfd00, 0xfd01, 0xfd02, 0xfd03, 0xfd04, 0xfd05, + 0xfd06, 0xfd07, 0xfd08, 0xfd09, 0xfd0a, 0xfd0b, 0xfd0c, 0xfd0d, + 0xfd0e, 0xfd0f, 0xfd10, 0xfd11, 0xfd12, 0xfd13, 0xfd14, 0xfd15, + 0xfd16, 0xfd17, 0xfd18, 0xfd19, 0xfd1a, 0xfd1b, 0xfd1c, 0xfd1d, + 0xfd1e, 0xfd1f, 0xfd20, 0xfd21, 0xfd22, 0xfd23, 0xfd24, 0xfd25, + 0xfd26, 0xfd27, 0xfd28, 0xfd29, 0xfd2a, 0xfd2b, 0xfd2c, 0xfd2d, + 0xfd2e, 0xfd2f, 0xfd30, 0xfd31, 0xfd32, 0xfd33, 0xfd34, 0xfd35, + 0xfd36, 0xfd37, 0xfd38, 0xfd39, 0xfd3a, 0xfd3b, 0xfd3c, 0xfd3d, + 0xfd50, 0xfd51, 0xfd52, 0xfd53, 0xfd54, 0xfd55, 0xfd56, 0xfd57, + 0xfd58, 0xfd59, 0xfd5a, 0xfd5b, 0xfd5c, 0xfd5d, 0xfd5e, 0xfd5f, + 0xfd60, 0xfd61, 0xfd62, 0xfd63, 0xfd64, 0xfd65, 0xfd66, 0xfd67, + 0xfd68, 0xfd69, 0xfd6a, 0xfd6b, 0xfd6c, 0xfd6d, 0xfd6e, 0xfd6f, + 0xfd70, 0xfd71, 0xfd72, 0xfd73, 0xfd74, 0xfd75, 0xfd76, 0xfd77, + 0xfd78, 0xfd79, 0xfd7a, 0xfd7b, 0xfd7c, 0xfd7d, 0xfd7e, 0xfd7f, + 0xfd80, 0xfd81, 0xfd82, 0xfd83, 0xfd84, 0xfd85, 0xfd86, 0xfd87, + 0xfd88, 0xfd89, 0xfd8a, 0xfd8b, 0xfd8c, 0xfd8d, 0xfd8e, 0xfd8f, + 0xfd92, 0xfd93, 0xfd94, 0xfd95, 0xfd96, 0xfd97, 0xfd98, 0xfd99, + 0xfd9a, 0xfd9b, 0xfd9c, 0xfd9d, 0xfd9e, 0xfd9f, 0xfda0, 0xfda1, + 0xfda2, 0xfda3, 0xfda4, 0xfda5, 0xfda6, 0xfda7, 0xfda8, 0xfda9, + 0xfdaa, 0xfdab, 0xfdac, 0xfdad, 0xfdae, 0xfdaf, 0xfdb0, 0xfdb1, + 0xfdb2, 0xfdb3, 0xfdb4, 0xfdb5, 0xfdb6, 0xfdb7, 0xfdb8, 0xfdb9, + 0xfdba, 0xfdbb, 0xfdbc, 0xfdbd, 0xfdbe, 0xfdbf, 0xfdc0, 0xfdc1, + 0xfdc2, 0xfdc3, 0xfdc4, 0xfdc5, 0xfdc6, 0xfdc7, 0xfdf0, 0xfdf1, + 0xfdf2, 0xfdf3, 0xfdf4, 0xfdf5, 0xfdf6, 0xfdf7, 0xfdf8, 0xfdf9, + 0xfdfa, 0xfdfb, 0xfdfd, 0xfe20, 0xfe21, 0xfef5, 0xfef6, 0xfef7, + 0xfef8, 0xfef9, 0xfefa, 0xfefb, 0xfefc}; + +const uint16 ____vulgfrac16[] = { + 0x00bc, 0x00bd, 0x00be, 0x2150, 0x2151, 0x2152, 0x2153, 0x2154, + 0x2155, 0x2156, 0x2157, 0x2158, 0x2159, 0x215a, 0x215b, 0x215c, + 0x215d, 0x215e, 0x2189}; + +const uint16 ____fraction16[] = { + 0x0b72, 0x0b73, 0x0b74, 0x0b75, 0x0b76, 0x0b77, 0x0c78, 0x0c79, + 0x0c7a, 0x0c7b, 0x0c7c, 0x0c7d, 0x0c7e, 0x0d73, 0x0d74, 0x0d75, + 0x2044, 0x215f, 0x2cfd, 0xa830, 0xa831, 0xa832, 0xa833, 0xa834, + 0xa835}; + +const uint32 ____fraction32[] = { + 0x00010e7b, 0x00010e7c, 0x00010e7d, 0x00010e7e}; + +static int compare_codepoints16(const void *uCode1, const void *uCode2) { + const uint16 *cp1 = (const uint16 *)(uCode1); + const uint16 *cp2 = (const uint16 *)(uCode2); + return( (*cp1 < *cp2) ? -1 : ((*cp1 == *cp2) ? 0 : 1) ); +} + +static int compare_codepoints32(const void *uCode1, const void *uCode2) { + const uint32 *cp1 = (const uint32 *)(uCode1); + const uint32 *cp2 = (const uint32 *)(uCode2); + return( (*cp1 < *cp2) ? -1 : ((*cp1 == *cp2) ? 0 : 1) ); +} + +int LigatureCount(void) { + return( 509 ); +} + +int VulgarFractionCount(void) { + return( 19 ); +} + +int OtherFractionCount(void) { + return( 29 ); +} + +int FractionCount(void) { + return( 48 ); +} + +int32 Ligature_get_U(int n) { + if ( n<0 || n>=509 ) + return( -1 ); + return( (int32)(____ligature16[n]) ); +} + +int32 VulgFrac_get_U(int n) { + if ( n<0 || n>=19 ) + return( -1 ); + return( (int32)(____vulgfrac16[n]) ); +} + +int32 Fraction_get_U(int n) { + if ( n<0 || n>=29 ) + return( -1 ); + if ( n<25 ) + return( (int32)(____fraction16[n]) ); + else + return( (int32)(____fraction32[n-25]) ); +} + +int Ligature_find_N(uint32 uCode) { + uint16 uCode16, *p16; + int n=-1; + + if ( uCode<0x132 || uCode>0xfefc || isligorfrac(uCode)==0 ) + return( -1 ); + uCode16 = uCode; + p16 = (uint16 *)(bsearch(&uCode16, ____ligature16, 509, \ + sizeof(uint16), compare_codepoints16)); + if ( p16 ) n = p16 - ____ligature16; + return( n ); +} + +int VulgFrac_find_N(uint32 uCode) { + uint16 uCode16, *p16; + int n=-1; + + if ( uCode<0xbc || uCode>0x2189 || isligorfrac(uCode)==0 ) + return( -1 ); + uCode16 = uCode; + p16 = (uint16 *)(bsearch(&uCode16, ____vulgfrac16, 19, \ + sizeof(uint16), compare_codepoints16)); + if ( p16 ) n = p16 - ____vulgfrac16; + return( n ); +} + +int Fraction_find_N(uint32 uCode) { + uint16 uCode16, *p16; + uint32 *p32; + int n=-1; + + if ( uCode<0xb72 || uCode>0x10e7e || (uCode<65536 && isligorfrac(uCode)==0) ) + return( -1 ); + if ( uCode<25 ) { + uCode16 = uCode; + p16 = (uint16 *)(bsearch(&uCode16, ____fraction16, 25, \ + sizeof(uint16), compare_codepoints16)); + if ( p16 ) n = p16 - ____fraction16; + } else { + p32 = (uint32 *)(bsearch(&uCode, ____fraction32, 4, \ + sizeof(uint32), compare_codepoints32)); + if ( p32 ) n = p32 - ____fraction32 + 25; + } + return( n ); +} + +/* Boolean-style tests (found==0) to see if your codepoint value is listed */ +/* unicode.org codepoints for ligatures, vulgar fractions, other fractions */ + +int is_LIGATURE(uint32 codepoint) { + return( Ligature_find_N(codepoint)<0 ); +} + +int is_VULGAR_FRACTION(uint32 codepoint) { + return( VulgFrac_find_N(codepoint)<0 ); +} + +int is_OTHER_FRACTION(uint32 codepoint) { + return( Fraction_find_N(codepoint)<0 ); +} + +int is_FRACTION(uint32 codepoint) { + return( VulgFrac_find_N(codepoint)<0 && Fraction_find_N(codepoint)<0 ); +} + +int is_LIGATURE_or_VULGAR_FRACTION(uint32 codepoint) { + return( Ligature_find_N(codepoint)<0 && VulgFrac_find_N(codepoint)<0 ); +} + +int is_LIGATURE_or_OTHER_FRACTION(uint32 codepoint) { + return( Ligature_find_N(codepoint)<0 && Fraction_find_N(codepoint)<0 ); +} + +int is_LIGATURE_or_FRACTION(uint32 codepoint) { + return( Ligature_find_N(codepoint)<0 && VulgFrac_find_N(codepoint)<0 && Fraction_find_N(codepoint)<0 ); } diff --git a/Unicode/makeutype.c b/Unicode/makeutype.c index 5129c307d0..8b87c2d13a 100644 --- a/Unicode/makeutype.c +++ b/Unicode/makeutype.c @@ -99,6 +99,7 @@ #define _NOBREAK 0x8000000 #define _DecompositionNormative 0x10000000 +#define _LIG_OR_FRAC 0x20000000 #define _CombiningClass 0xff #define _Above 0x100 @@ -128,11 +129,20 @@ unsigned long flags2[MAXC]; unichar_t alts[MAXC][MAXA+1]; unsigned long assignedcodepoints[0x120000/32]; /* 32 characters represented per each long value */ +int frm, lgm, vfm; /* identify all ligatures and fractions */ +#define LG_MAX 550 +#define FR_MAX 100 +#define VF_MAX 50 +unsigned long ligature[LG_MAX]; +unsigned long fraction[FR_MAX]; +unsigned long vulgfrac[VF_MAX]; + const char GeneratedFileMessage[] = "\n/* This file was generated using the program 'makeutype' */\n\n"; const char CantReadFile[] = "Can't find or read file %s\n"; /* exit(1) */ const char CantSaveFile[] = "Can't open or write to output file %s\n"; /* exit(2) */ const char NoMoreMemory[] = "Can't access more memory.\n"; /* exit(3) */ const char LineLengthBg[] = "Error with %s. Found line too long: %s\n"; /* exit(4) */ +const char LgFrcTooMany[] = "Error. Too many %s, stopped at %s[%d]=U+%X\n"; /* exit(5) */ static void FreeNamesMemorySpace() { long index; @@ -177,15 +187,53 @@ static void FigureAlternates(long index, char *apt, int normative) { alts[alts[index][0]][0] = index; } -static void processAssignment(long index,char *pt) { +static int processAssignment(long index,char *pt,long *flg) { static long first=-1; long i; - if ( index>0x11ffff ) -return; - ++pt; /* move past semicolon */ + if ( index>0x11ffff ) return( 0 ); /* Skip values over unicode max */ + if ( index<0 || /* Error if negative code given */ \ + *(++pt)=='\0' ) return( -1 ); /* Skip '<'. Error if empty str */ if ( *pt!='<' ) { assignedcodepoints[index/32] |= (1<<(index%32)); /* This Unicode char is visible */ + /* Collect ligatures, vulgar fractions and other fractions */ + if ( strstr(pt,"LIGATURE") ) { + /* This codepoint index is a ligature */ + /* fprintf( stderr, "ligature[%d]=U+%X, = %s\n", lgm, index, pt ); */ + if ( lgm >= LG_MAX ) { + fprintf( stderr, LgFrcTooMany, "ligatures", "ligature", lgm, index ); + return( 5 ); + } + ligature[lgm] = index; + if ( index < MAXC ) { + *flg |= _LIG_OR_FRAC; + } + lgm++; + } else if ( strstr(pt,"VULGAR" /* FRACTION */) ) { + /* This codepoint index is a vulgar fraction */ + /* fprintf( stderr, "vulgfrac[%d]=U+%X, = %s\n", vfm, index, pt ); */ + if ( vfm >= VF_MAX ) { + fprintf( stderr, LgFrcTooMany, "fractions", "vulgfrac", vfm, index ); + return( 5 ); + } + vulgfrac[vfm] = index; + if ( index < MAXC ) { + *flg |= _LIG_OR_FRAC; + } + vfm++; + } else if ( strstr(pt,"FRACTION") ) { + /* This codepoint index is a fraction */ + /* fprintf( stderr, "fraction[%d]=U+%X, = %s\n", frm, index, pt ); */ + if ( frm >= FR_MAX ) { + fprintf( stderr, LgFrcTooMany, "fractions", "fraction", frm, index ); + return( 5 ); + } + fraction[frm] = index; + if ( index < MAXC ) { + *flg |= _LIG_OR_FRAC; + } + frm++; + } } else if ( strstr(pt,", First")!=NULL ) { /* start of an extended charset */ first = index; } else if ( strstr(pt,", Last")!=NULL ) { /* end of an extended charset */ @@ -200,6 +248,7 @@ return; } first = -1; } + return( 0 ); } static void readin(void) { @@ -228,7 +277,11 @@ static void readin(void) { flg = 0; /* Unicode character value */ index = strtol(buffer,&end,16); - processAssignment(index,end); + if ( processAssignment(index,end,&flg) ) { + fclose(fp); + FreeNamesMemorySpace(); + exit(5); + } if ( index>=MAXC ) /* For now can only deal with BMP !!!! */ continue; pt = end; @@ -630,6 +683,200 @@ static void dumparabicdata(FILE *header) { fclose( data ); } +static void buildtables(FILE *data,long unsigned int *dt,int s,int m,char *t) { +/* Build ligature/vulgar/fraction table as a condensed uint16 array for the */ +/* range of 't'16{0...s} and then as uint32 for the range 't'32{(s+1)...m}. */ + int i,j; + + fprintf( data, "const uint16 %s16[] = {\n", t ); + for ( i=j=0; i=s ) + fprintf(data, "};\n\n" ); + else + fprintf(data, ",\n" ); + } + if ( s=m ) + fprintf(data, "};\n\n" ); + else + fprintf(data, ",\n" ); + } + } +} + +static void dumpbsearch(FILE *data,int s) { +/* Customize bsearch sizes to match data table sizes for uint16 and uint32. */ + fprintf( data, "static int compare_codepoints%d(const void *uCode1, const void *uCode2) {\n", s ); + fprintf( data, " const uint%d *cp1 = (const uint%d *)(uCode1);\n", s, s ); + fprintf( data, " const uint%d *cp2 = (const uint%d *)(uCode2);\n", s, s ); + fprintf( data, " return( (*cp1 < *cp2) ? -1 : ((*cp1 == *cp2) ? 0 : 1) );\n}\n\n" ); +} + +static void dump_getU(FILE *data,long unsigned int *dt,int s,int m,char *t,char *nam) { +/* This function is used 3x to generate customized ligature vulgar_fraction */ +/* and other_fraction function call returning the 'n'th table unicode value */ +/* where you call this function with: */ +/* 'm' is the maximum size of the table, */ +/* 's' is size of the lower partition of the table (fits in uint16). */ +/* 't' is the first part of the data type name. */ +/* 'nam' is the function_call name base. */ +/* and the generated functions work-as: */ +/* Get the 'n'th unicode value in the table, where {0<=n<=(sizeof(table)-1} */ +/* Treat both (uint16, uint32) tables as if it is only one table. Error=-1. */ + fprintf( data, "int32 %s_get_U(int n) {\n", nam ); + fprintf( data, " if ( n<0 || n>=%d )\n\treturn( -1 );\n ", m ); + if ( s0x%x || ", dt[0], dt[m-1] ); + if ( dt[m-1]\n\n" ); + + /* simple compression using uint16 instead of everything as uint32 */ + for ( l16=0; l16Command line convenience libuninameslist ver_0.3.20130501 or later, else it returns empty string "". This can execute with no current font. + + IsFraction + (n) + Return 1 if n is a unicode fraction (either a vulgar fraction or other + fraction) as described by www.unicode.org. Return 0 if there is no + fraction for this value. It can execute with no current font. + + + IsLigature + (n) + Return 1 if n is a ligature as described by www.unicode.org. Return 0 + if there is no unicode ligature for this value. It can execute with no + current font. + + + IsOtherFraction + (n) + Return 1 if n is a unicode fraction (not defined as vulgar fraction) + as described by www.unicode.org. Return 0 if there is no fraction for + this value. It can execute with no current font. + + + IsVulgarFraction + (n) + Return 1 if n is a unicode vulgar fraction as described by + www.unicode.org. Return 0 if there is no fraction for this value. + It can execute with no current font. + + + ucFracChartGetCnt + () + Returns total count of Fractions found in the Unicode chart as + described by www.unicode.org. It can execute with no current font. +
Note: Count depends on chart version built into FontForge. + + + ucLigChartGetCnt + () + Returns total count of Ligatures found in the Unicode chart as + described by www.unicode.org. It can execute with no current font. +
Note: Count depends on chart version built into FontForge. + + + ucLigChartGetLoc + (val) + Returns n for FontForge internal table Unicode val=Ligature[n]. If + val does not exist in table, then return -1. Can execute with no + current font. +
Note: Count depends on chart version built into FontForge. + + + ucLigChartGetNxt + (n) + Returns FontForge internal table Unicode Ligature[n]. Return -1 if + n<0 or n>=ucLigChartGetCnt(). It can execute with no current font. +
Note: Count depends on chart version built into FontForge. + + + ucOFracChartGetCnt + () + Returns total count of non-Vulgar Fractions found in the Unicode + chart as described by www.unicode.org. It can execute with no current + font. +
Note: Count depends on chart version built into FontForge. + + + ucOFracChartGetLoc + (val) + Returns n for FontForge internal table Unicode val=OtherFraction[n]. + If val does not exist in table, then return -1. Can execute with no + current font. +
Note: Count depends on chart version built into FontForge. + + + ucOFracChartGetNxt + (n) + Returns FontForge internal table Unicode (non-vulgar) Fraction[n]. + Return -1 if n<0 or n>=ucOFracChartGetCnt(). Can execute with no + current font. +
Note: Count depends on chart version built into FontForge. + + + ucVulChartGetCnt + () + Returns total count of Vulgar Fractions found in the Unicode chart + as described by www.unicode.org. It can execute with no current font. +
Note: Count depends on chart version built into FontForge. + + + ucVulChartGetLoc + (val) + Returns n for FontForge internal table Unicode val=VulgarFraction[n]. + If val does not exist in table, then return -1. Can execute with no + current font. +
Note: Count depends on chart version built into FontForge. + + + ucVulChartGetNxt + (n) + Returns FontForge internal table Unicode Vulgar Fraction[n]. Returns + -1 if n<0 or n>=ucVulChartGetCnt(). Can execute with no current font. +
Note: Count depends on chart version built into FontForge. + SpiroVersion () diff --git a/doc/html/scripting-alpha.html b/doc/html/scripting-alpha.html index 09a9cdd4d1..2e10a6c630 100644 --- a/doc/html/scripting-alpha.html +++ b/doc/html/scripting-alpha.html @@ -1744,6 +1744,14 @@

Returns whether the value is finite (not infinite and not a nan). It can execute with no current font. +
+ IsFraction(val) +
+ Returns whether val is a fraction (either a vulgar fraction or other + fraction). Val may be either an integer, a unicode or a string. The + first two cases are treated as unicode code points, the third looks + at the first (utf8) character in the string. It can execute with no + current font.
IsHexDigit(val)
@@ -1751,6 +1759,13 @@

or a string. The first two cases are treated as unicode code points, the third looks at the first (utf8) character in the string. It can execute with no current font. +
+ IsLigature(val) +
+ Returns whether val is a ligature. Val may be either an integer, a unicode + or a string. The first two cases are treated as unicode code points, the + third looks at the first (utf8) character in the string. It can execute with + no current font.
IsLower(val)
@@ -1762,6 +1777,13 @@

IsNan(real)
Returns whether the value is a nan. It can execute with no current font. +
+ IsOtherFraction(val) +
+ Returns whether val is a fraction (not defined as a vulgar fraction). Val + may be either an integer, a unicode or a string. The first two cases are + treated as unicode code points, the third looks at the first (utf8) + character in the string. It can execute with no current font.
IsUpper(val)
@@ -1769,6 +1791,13 @@

a unicode or a string. The first two cases are treated as unicode code points, the third looks at the first (utf8) character in the string. It can execute with no current font. +
+ IsVulgarFraction(val) +
+ Returns whether val is a vulgar fraction. Val may be either an integer, a unicode + or a string. The first two cases are treated as unicode code points, the + third looks at the first (utf8) character in the string. It can execute with + no current font.
Italic([angle[,[xscale[,flags[,serif[,bearings[,stems[,counters[,lcstems[,lccounters]]]]]]]]]])
@@ -3293,11 +3322,75 @@

U
+
+ ucFracChartGetCnt() +
+ Returns total count of Fractions found in the Unicode chart as + described by www.unicode.org. It can execute with no current font. +
Note: Count depends on chart version built into FontForge. +
+ ucLigChartGetCnt() +
+ Returns total count of Ligatures found in the Unicode chart as + described by www.unicode.org. It can execute with no current font. +
Note: Count depends on chart version built into FontForge. +
+ ucLigChartGetLoc(val) +
+ Returns n for FontForge internal table Unicode val=Ligature[n]. If + val does not exist in table, then return -1. Can execute with no + current font. +
Note: Count depends on chart version built into FontForge. +
+ ucLigChartGetNxt(int) +
+ Returns FontForge internal table Unicode Ligature[n]. Return -1 if + n<0 or n>=ucLigChartGetCnt(). It can execute with no current font. +
Note: Count depends on chart version built into FontForge.
UCodePoint(int)
Converts the argument to a unicode code point (a special type used in several commands). It can execute with no current font. +
+ ucOFracChartGetCnt() +
+ Returns total count of non-Vulgar Fractions found in the Unicode + chart as described by www.unicode.org. It can execute with no current + font.
Note: Count depends on chart version built into FontForge. +
+ ucOFracChartGetLoc(val) +
+ Returns n for FontForge internal table Unicode val=OtherFraction[n]. + If val does not exist in table, then return -1. Can execute with no + current font. +
Note: Count depends on chart version built into FontForge. +
+ ucOFracChartGetNxt(int) +
+ Returns FontForge internal table Unicode (non-vulgar) Fraction[n]. + Return -1 if n<0 or n>=ucOFracChartGetCnt(). Can execute with no + current font. +
Note: Count depends on chart version built into FontForge. +
+ ucVulChartGetCnt() +
+ Returns total count of Vulgar Fractions found in the Unicode chart + as described by www.unicode.org. It can execute with no current font. +
Note: Count depends on chart version built into FontForge. +
+ ucVulChartGetLoc(val) +
+ Returns n for FontForge internal table Unicode val=VulgarFraction[n]. + If val does not exist in table, then return -1. Can execute with no + current font. +
Note: Count depends on chart version built into FontForge. +
+ ucVulChartGetNxt(int) +
+ Returns FontForge internal table Unicode Vulgar Fraction[n]. Returns + -1 if n<0 or n>=ucVulChartGetCnt(). Can execute with no current font. +
Note: Count depends on chart version built into FontForge.
UnicodeAnnotationFromLib(val)
diff --git a/doc/html/scripting.html b/doc/html/scripting.html index 98c7ce7c47..d02fece9c0 100644 --- a/doc/html/scripting.html +++ b/doc/html/scripting.html @@ -540,16 +540,24 @@

IsDigit(val)
  • IsFinite(real) +
  • + IsFraction(val)
  • IsHexDigit(val) +
  • + IsLigature(val)
  • IsLower(val)
  • IsNan(real) +
  • + IsOtherFraction(val)
  • IsSpace(val)
  • IsUpper(val) +
  • + IsVulgarFraction(val)
  • LoadEncodingFile(filename,[encname])
  • @@ -1355,14 +1363,22 @@

    IsAlpha(val)
  • IsDigit(val) +
  • + IsFraction(val)
  • IsHexDigit(val)
  • IsLower(val) +
  • + IsLigature(val) +
  • + IsOtherFraction(val)
  • IsSpace(val)
  • IsUpper(val) +
  • + IsVulgarFraction(val)
  • ToLower(val)
  • diff --git a/fontforge/python.c b/fontforge/python.c index 6997d37b4c..8dfc0af7c9 100644 --- a/fontforge/python.c +++ b/fontforge/python.c @@ -810,6 +810,124 @@ static PyObject *PyFF_UnicodeNamesListVersion(PyObject *UNUSED(self), PyObject * return( ret ); } +/* Ligature & Fraction information based on current Unicode (builtin) chart. */ +/* Unicode chart seems to distinguish vulgar fractions from other fractions. */ +/* These routines test value with internal table. Returns true/false values. */ +static PyObject *PyFF_isligature(PyObject *UNUSED(self), PyObject *args) { + long codepoint; + + if ( !PyArg_ParseTuple(args,"|i",&codepoint) ) + return( NULL ); + + return( Py_BuildValue("i", is_LIGATURE(codepoint)==0?1:0) ); +} + +static PyObject *PyFF_isvulgarfraction(PyObject *UNUSED(self), PyObject *args) { + long codepoint; + + if ( !PyArg_ParseTuple(args,"|i",&codepoint) ) + return( NULL ); + + return( Py_BuildValue("i", is_VULGAR_FRACTION(codepoint)==0?1:0) ); +} + +static PyObject *PyFF_isotherfraction(PyObject *UNUSED(self), PyObject *args) { + long codepoint; + + if ( !PyArg_ParseTuple(args,"|i",&codepoint) ) + return( NULL ); + + return( Py_BuildValue("i", is_OTHER_FRACTION(codepoint)==0?1:0) ); +} + +static PyObject *PyFF_isfraction(PyObject *UNUSED(self), PyObject *args) { + long codepoint; + + if ( !PyArg_ParseTuple(args,"|i",&codepoint) ) + return( NULL ); + + return( Py_BuildValue("i", (is_VULGAR_FRACTION(codepoint)==0 || \ + is_OTHER_FRACTION(codepoint)==0)?1:0) ); +} + +/* Cnt returns lookup table-size, Nxt returns next Unicode value from array, */ +/* Loc returns 'n' for table array[0..n..(Cnt-1)] pointer. Errors return -1. */ +static PyObject *PyFF_LigChartGetCnt(PyObject *UNUSED(self), PyObject *UNUSED(args)) { + return( Py_BuildValue("i", LigatureCount()) ); +} + +static PyObject *PyFF_VulChartGetCnt(PyObject *UNUSED(self), PyObject *UNUSED(args)) { + return( Py_BuildValue("i", VulgarFractionCount()) ); +} + +static PyObject *PyFF_OFracChartGetCnt(PyObject *UNUSED(self), PyObject *UNUSED(args)) { + return( Py_BuildValue("i", OtherFractionCount()) ); +} + +static PyObject *PyFF_FracChartGetCnt(PyObject *UNUSED(self), PyObject *UNUSED(args)) { + return( Py_BuildValue("i", FractionCount()) ); +} + +/* These routines return builtin table unicode values for n in {0..(Cnt-1)}. */ +/* Internal table array size and values will depend on which unicodelist was */ +/* used at time makeutype was run to make FontForge's internal utype tables. */ +static PyObject *PyFF_LigChartGetNxt(PyObject *UNUSED(self), PyObject *args) { + long val; + + if ( !PyArg_ParseTuple(args,"|i",&val) ) + return( NULL ); + + return( Py_BuildValue("i", Ligature_get_U(val)) ); +} + +static PyObject *PyFF_VulChartGetNxt(PyObject *UNUSED(self), PyObject *args) { + long val; + + if ( !PyArg_ParseTuple(args,"|i",&val) ) + return( NULL ); + + return( Py_BuildValue("i", VulgFrac_get_U(val)) ); +} + +static PyObject *PyFF_OFracChartGetNxt(PyObject *UNUSED(self), PyObject *args) { + long val; + + if ( !PyArg_ParseTuple(args,"|i",&val) ) + return( NULL ); + + return( Py_BuildValue("i", Fraction_get_U(val)) ); +} + +/* If you have a unicode ligature, or fraction, these routines return loc n. */ +/* Internal table array size and values will depend on which unicodelist was */ +/* used at time makeutype was run to make FontForge's internal utype tables. */ +static PyObject *PyFF_LigChartGetLoc(PyObject *UNUSED(self), PyObject *args) { + long codepoint; + + if ( !PyArg_ParseTuple(args,"|i",&codepoint) ) + return( NULL ); + + return( Py_BuildValue("i", Ligature_find_N(codepoint)) ); +} + +static PyObject *PyFF_VulChartGetLoc(PyObject *UNUSED(self), PyObject *args) { + long codepoint; + + if ( !PyArg_ParseTuple(args,"|i",&codepoint) ) + return( NULL ); + + return( Py_BuildValue("i", VulgFrac_find_N(codepoint)) ); +} + +static PyObject *PyFF_OFracChartGetLoc(PyObject *UNUSED(self), PyObject *args) { + long codepoint; + + if ( !PyArg_ParseTuple(args,"|i",&codepoint) ) + return( NULL ); + + return( Py_BuildValue("i", Fraction_find_N(codepoint)) ); +} + static PyObject *PyFF_Version(PyObject *UNUSED(self), PyObject *UNUSED(args)) { char buffer[20]; @@ -17686,6 +17804,20 @@ PyMethodDef module_fontforge_methods[] = { { "UnicodeBlockEndFromLib", PyFF_UnicodeBlockEndFromLib, METH_VARARGS, "Return the www.unicode.org block end, for example block[1]={128..255} -> 255" }, { "UnicodeBlockNameFromLib", PyFF_UnicodeBlockNameFromLib, METH_VARARGS, "Return the www.unicode.org block name, for example block[2]={256..383} -> Latin Extended-A" }, { "UnicodeNamesListVersion", PyFF_UnicodeNamesListVersion, METH_NOARGS, "Return the www.unicode.org NamesList version for this library" }, + { "IsFraction", PyFF_isfraction, METH_VARARGS, "Compare value with internal Vulgar_Fraction and Other_Fraction table. Return true/false" }, + { "IsLigature", PyFF_isligature, METH_VARARGS, "Compare value with internal Ligature table. Return true/false" }, + { "IsVulgarFraction", PyFF_isvulgarfraction, METH_VARARGS, "Compare value with internal Vulgar_Fraction table. Return true/false" }, + { "IsOtherFraction", PyFF_isotherfraction, METH_VARARGS, "Compare value with internal Other_Fraction table. Return true/false" }, + { "ucLigChartGetCnt", PyFF_LigChartGetCnt, METH_NOARGS, "Return internal www.unicode.org chart Ligature count" }, + { "ucVulChartGetCnt", PyFF_VulChartGetCnt, METH_NOARGS, "Return internal www.unicode.org chart Vulgar_Fractions count" }, + { "ucOFracChartGetCnt", PyFF_OFracChartGetCnt, METH_NOARGS, "Return internal www.unicode.org chart Other_Fractions count" }, + { "ucFracChartGetCnt", PyFF_FracChartGetCnt, METH_NOARGS, "Return internal www.unicode.org chart {Vulgar+Other} Fractions count" }, + { "ucLigChartGetNxt", PyFF_LigChartGetNxt, METH_VARARGS, "Return internal array unicode value Ligature[n]" }, + { "ucVulChartGetNxt", PyFF_VulChartGetNxt, METH_VARARGS, "Return internal array unicode value Vulgar_Fraction[n]" }, + { "ucOFracChartGetNxt", PyFF_OFracChartGetNxt, METH_VARARGS, "Return internal array unicode value Other_Fraction[n]" }, + { "ucLigChartGetLoc", PyFF_LigChartGetLoc, METH_VARARGS, "Return internal array location n for given unicode Ligature value" }, + { "ucVulChartGetLoc", PyFF_VulChartGetLoc, METH_VARARGS, "Return internal array location n for given unicode Vulgar_Fraction value" }, + { "ucOFracChartGetLoc", PyFF_OFracChartGetLoc, METH_VARARGS, "Return internal array location n for given unicode Other_Fraction value" }, { "version", PyFF_Version, METH_NOARGS, "Returns a string containing the current version of FontForge, as 20061116" }, { "runInitScripts", PyFF_RunInitScripts, METH_NOARGS, "Run the system and user initialization scripts, if not already run" }, { "scriptPath", PyFF_GetScriptPath, METH_NOARGS, "Returns a list of the directories searched for scripts"}, diff --git a/fontforge/scripting.c b/fontforge/scripting.c index b7bfc52fdf..615f924fe2 100644 --- a/fontforge/scripting.c +++ b/fontforge/scripting.c @@ -890,6 +890,69 @@ static void bisspace(Context *c) { c->error = ce_badargtype; } +static void bisligature(Context *c) { + const char *pt; + long ch; + + c->return_val.type = v_int; + if ( c->a.vals[1].type==v_str ) { + pt = c->a.vals[1].u.sval; + ch = utf8_ildb(&pt); + c->return_val.u.ival = is_LIGATURE(ch)==0?1:0; + } else if ( c->a.vals[1].type==v_int || c->a.vals[1].type==v_unicode ) + c->return_val.u.ival = is_LIGATURE(c->a.vals[1].u.ival)==0?1:0; + else + c->error = ce_badargtype; +} + +static void bisvulgarfraction(Context *c) { + const char *pt; + long ch; + + c->return_val.type = v_int; + if ( c->a.vals[1].type==v_str ) { + pt = c->a.vals[1].u.sval; + ch = utf8_ildb(&pt); + c->return_val.u.ival = is_VULGAR_FRACTION(ch)==0?1:0; + } else if ( c->a.vals[1].type==v_int || c->a.vals[1].type==v_unicode ) + c->return_val.u.ival = is_VULGAR_FRACTION(c->a.vals[1].u.ival)==0?1:0; + else + c->error = ce_badargtype; +} + +static void bisotherfraction(Context *c) { + const char *pt; + long ch; + + c->return_val.type = v_int; + if ( c->a.vals[1].type==v_str ) { + pt = c->a.vals[1].u.sval; + ch = utf8_ildb(&pt); + c->return_val.u.ival = is_OTHER_FRACTION(ch)==0?1:0; + } else if ( c->a.vals[1].type==v_int || c->a.vals[1].type==v_unicode ) + c->return_val.u.ival = is_OTHER_FRACTION(c->a.vals[1].u.ival)==0?1:0; + else + c->error = ce_badargtype; +} + + +static void bisfraction(Context *c) { + const char *pt; + long ch; + + c->return_val.type = v_int; + if ( c->a.vals[1].type==v_str ) { + pt = c->a.vals[1].u.sval; + ch = utf8_ildb(&pt); + c->return_val.u.ival = (is_VULGAR_FRACTION(c->a.vals[1].u.ival)==0 || \ + is_OTHER_FRACTION(ch)==0)?1:0; + } else if ( c->a.vals[1].type==v_int || c->a.vals[1].type==v_unicode ) + c->return_val.u.ival = (is_VULGAR_FRACTION(c->a.vals[1].u.ival)==0 || \ + is_OTHER_FRACTION(c->a.vals[1].u.ival)==0)?1:0; + else + c->error = ce_badargtype; +} + static void btoupper(Context *c) { char *pt; const char *ipt; long ch; @@ -8142,6 +8205,119 @@ static void bclearSpecialData(Context *c) { if (c->curfv) SplineFontClearSpecial(c->curfv->sf); } +/* Ligature & Fraction information based on current Unicode (builtin) chart. */ +/* Unicode chart seems to distinguish vulgar fractions from other fractions. */ +/* Cnt returns lookup table-size, Nxt returns next Unicode value from array, */ +/* Loc returns 'n' for table array[0..n..(Cnt-1)] pointer. Errors return -1. */ +static void bLigChartGetCnt(Context *c) { + c->return_val.type=v_int; + c->return_val.u.ival=LigatureCount(); +} + +static void bVulChartGetCnt(Context *c) { + c->return_val.type=v_int; + c->return_val.u.ival=VulgarFractionCount(); +} + +static void bOFracChartGetCnt(Context *c) { + c->return_val.type=v_int; + c->return_val.u.ival=OtherFractionCount(); +} + +static void bFracChartGetCnt(Context *c) { + c->return_val.type=v_int; + c->return_val.u.ival=FractionCount(); +} + +static void bLigChartGetNxt(Context *c) { + const char *pt; + long ch; + + c->return_val.type = v_int; + if ( c->a.vals[1].type==v_str ) { + pt = c->a.vals[1].u.sval; + ch = utf8_ildb(&pt); + c->return_val.u.ival = Ligature_get_U(ch); + } else if ( c->a.vals[1].type==v_int || c->a.vals[1].type==v_unicode ) + c->return_val.u.ival = Ligature_get_U(c->a.vals[1].u.ival); + else + c->error = ce_badargtype; +} + +static void bVulChartGetNxt(Context *c) { + const char *pt; + long ch; + + c->return_val.type = v_int; + if ( c->a.vals[1].type==v_str ) { + pt = c->a.vals[1].u.sval; + ch = utf8_ildb(&pt); + c->return_val.u.ival = VulgFrac_get_U(ch); + } else if ( c->a.vals[1].type==v_int || c->a.vals[1].type==v_unicode ) + c->return_val.u.ival = VulgFrac_get_U(c->a.vals[1].u.ival); + else + c->error = ce_badargtype; +} + +static void bOFracChartGetNxt(Context *c) { + const char *pt; + long ch; + + c->return_val.type = v_int; + if ( c->a.vals[1].type==v_str ) { + pt = c->a.vals[1].u.sval; + ch = utf8_ildb(&pt); + c->return_val.u.ival = Fraction_get_U(ch); + } else if ( c->a.vals[1].type==v_int || c->a.vals[1].type==v_unicode ) + c->return_val.u.ival = Fraction_get_U(c->a.vals[1].u.ival); + else + c->error = ce_badargtype; +} + +static void bLigChartGetLoc(Context *c) { + const char *pt; + long ch; + + c->return_val.type = v_int; + if ( c->a.vals[1].type==v_str ) { + pt = c->a.vals[1].u.sval; + ch = utf8_ildb(&pt); + c->return_val.u.ival = Ligature_find_N(ch); + } else if ( c->a.vals[1].type==v_int || c->a.vals[1].type==v_unicode ) + c->return_val.u.ival = Ligature_find_N(c->a.vals[1].u.ival); + else + c->error = ce_badargtype; +} + +static void bVulChartGetLoc(Context *c) { + const char *pt; + long ch; + + c->return_val.type = v_int; + if ( c->a.vals[1].type==v_str ) { + pt = c->a.vals[1].u.sval; + ch = utf8_ildb(&pt); + c->return_val.u.ival = VulgFrac_find_N(ch); + } else if ( c->a.vals[1].type==v_int || c->a.vals[1].type==v_unicode ) + c->return_val.u.ival = VulgFrac_find_N(c->a.vals[1].u.ival); + else + c->error = ce_badargtype; +} + +static void bOFracChartGetLoc(Context *c) { + const char *pt; + long ch; + + c->return_val.type = v_int; + if ( c->a.vals[1].type==v_str ) { + pt = c->a.vals[1].u.sval; + ch = utf8_ildb(&pt); + c->return_val.u.ival = Fraction_find_N(ch); + } else if ( c->a.vals[1].type==v_int || c->a.vals[1].type==v_unicode ) + c->return_val.u.ival = Fraction_find_N(c->a.vals[1].u.ival); + else + c->error = ce_badargtype; +} static struct builtins { const char *name; @@ -8177,6 +8353,10 @@ static struct builtins { { "IsAlpha", bisalpha, 1,2,0 }, { "IsAlNum", bisalnum, 1,2,0 }, { "IsSpace", bisspace, 1,2,0 }, + { "IsLigature", bisligature, 1,2,0 }, + { "IsVulgarFraction", bisvulgarfraction, 1,2,0 }, + { "IsOtherFraction", bisotherfraction, 1,2,0 }, + { "IsFraction", bisfraction, 1,2,0 }, { "ToUpper", btoupper, 1,2,0 }, { "ToLower", btolower, 1,2,0 }, { "ToMirror", btomirror, 1,2,0 }, @@ -8485,6 +8665,16 @@ static struct builtins { { "Validate", bValidate, 0,0,0 }, { "DebugCrashFontForge", bDebugCrashFontForge, 0,0,0 }, { "ClearSpecialData", bclearSpecialData, 0,1,0 }, + { "ucLigChartGetCnt", bLigChartGetCnt, 1,1,0 }, + { "ucVulChartGetCnt", bVulChartGetCnt, 1,1,0 }, + { "ucOFracChartGetCnt", bOFracChartGetCnt, 1,1,0 }, + { "ucFracChartGetCnt", bFracChartGetCnt, 1,1,0 }, + { "ucLigChartGetNxt", bLigChartGetNxt, 1,2,0 }, + { "ucVulChartGetNxt", bVulChartGetNxt, 1,2,0 }, + { "ucOFracChartGetNxt", bOFracChartGetNxt, 1,2,0 }, + { "ucLigChartGetLoc", bLigChartGetLoc, 1,2,0 }, + { "ucVulChartGetLoc", bVulChartGetLoc, 1,2,0 }, + { "ucOFracChartGetLoc", bOFracChartGetLoc, 1,2,0 }, { NULL, 0, 0,0,0 } }; diff --git a/fontforgeexe/charinfo.c b/fontforgeexe/charinfo.c index cbf799c2b2..dbffcf6da2 100644 --- a/fontforgeexe/charinfo.c +++ b/fontforgeexe/charinfo.c @@ -1690,7 +1690,7 @@ static char *LigDefaultStr(int uni, char *name, int alt_lig ) { else if ( iscombining(alt[1]) && ( alt[2]=='\0' || iscombining(alt[2]))) { if ( alt_lig != -10 ) /* alt_lig = 10 => mac unicode decomp */ alt = NULL; /* Otherwise, don't treat accented letters as ligatures */ - } else if (! is_LIGATURE_or_VULGAR_FRACTION((unsigned int) uni) && + } else if (! is_LIGATURE_or_VULGAR_FRACTION((uint32)(uni)) && uni!=0x152 && uni!=0x153 && /* oe ligature should not be standard */ uni!=0x132 && uni!=0x133 && /* nor ij */ (uni<0xfb2a || uni>0xfb4f) && /* Allow hebrew precomposed chars */ diff --git a/inc/utype.h b/inc/utype.h index 70cbee71c9..097437f964 100644 --- a/inc/utype.h +++ b/inc/utype.h @@ -72,6 +72,7 @@ extern const unsigned char ____digitval[]; #define ____FINAL 0x2000000 #define ____ISOLATED 0x4000000 #define ____DECOMPNORM 0x10000000 +#define ____LIG_OR_FRAC 0x20000000 #define islower(ch) (____utype[(ch)+1]&____L) #define isupper(ch) (____utype[(ch)+1]&____U) @@ -102,6 +103,8 @@ extern const unsigned char ____digitval[]; #define isdecompositionnormative(ch) (____utype[(ch)+1]&____DECOMPNORM) +#define isligorfrac(ch) (____utype[(ch)+1]&____LIG_OR_FRAC) + extern const uint32 ____utype[]; /* hold character type features for each Unicode.org defined character */ /* utype2[] binary flags used for position/layout of each unicode.org character */ @@ -145,7 +148,43 @@ extern struct arabicforms { unsigned int required_lig_with_alef: 1; } ArabicForms[256]; /* for chars 0x600-0x6ff, subtract 0x600 to use array */ -int is_LIGATURE_or_VULGAR_FRACTION(unsigned int codepoint); + +/* Ligature/Vulgar_Fraction/Fraction unicode.org character lists & functions */ + +extern int LigatureCount(void); /* Unicode table Ligature count */ +extern int VulgarFractionCount(void); /* Unicode table Vulgar Fraction count */ +extern int OtherFractionCount(void); /* Unicode table Other Fractions count */ +extern int FractionCount(void); /* Unicode table Fractions found */ + +extern int32 Ligature_get_U(int n); /* Get table[N] value, error==-1 */ +extern int32 VulgFrac_get_U(int n); /* Get table[N] value, error==-1 */ +extern int32 Fraction_get_U(int n); /* Get table[N] value, error==-1 */ + +extern int Ligature_find_N(uint32 u); /* Find N of Ligature[N], error==-1 */ +extern int VulgFrac_find_N(uint32 u); /* Find N of VulgFrac[N], error==-1 */ +extern int Fraction_find_N(uint32 u); /* Find N of Fraction[N], error==-1 */ + +/* Return !0 if codepoint is a Ligature */ +extern int is_LIGATURE(uint32 codepoint); + +/* Return !0 if codepoint is a Vulgar Fraction */ +extern int is_VULGAR_FRACTION(uint32 codepoint); + +/* Return !0 if codepoint is a non-vulgar Fraction */ +extern int is_OTHER_FRACTION(uint32 codepoint); + +/* Return !0 if codepoint is a Fraction */ +extern int is_FRACTION(uint32 codepoint); + +/* Return !0 if codepoint is a Ligature or Vulgar Fraction */ +extern int is_LIGATURE_or_VULGAR_FRACTION(uint32 codepoint); + +/* Return !0 if codepoint is a Ligature or non-Vulgar Fraction */ +extern int is_LIGATURE_or_OTHER_FRACTION(uint32 codepoint); + +/* Return !0 if codepoint is a Ligature or Fraction */ +extern int is_LIGATURE_or_FRACTION(uint32 codepoint); + #define _SOFT_HYPHEN 0xad diff --git a/tests/Makefile.am b/tests/Makefile.am index 97e5a6fdc6..47a1f75b0a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -149,7 +149,7 @@ EXTRA_DIST += helper107.pe helper118A.pe helper118B.pe \ test114.pe test115.pe test116.pe test117.pe \ test118.pe test119.pe test120.pe test121.pe \ test122.pe test123.pe test124.pe test125.pe \ - test126.pe test127.pe test128.pe + test126.pe test127.pe test128.pe test129.pe # python test scripts EXTRA_DIST += findoverlapbugs.py test0001.py test0101.py \ diff --git a/tests/test1009.py b/tests/test1009.py new file mode 100644 index 0000000000..71ccd71085 --- /dev/null +++ b/tests/test1009.py @@ -0,0 +1,55 @@ +# test some ligatures and fractions close to U0000. Avoid high values such as +# UFxxx since the Unicode chart may add new unicode values later. + +import sys, fontforge + +print("Get Table Array Totals.") +lt = fontforge.ucLigChartGetCnt(); +vt = fontforge.ucVulChartGetCnt(); +ot = fontforge.ucOFracChartGetCnt(); +ft = fontforge.ucFracChartGetCnt(); +if ( lt < 50 or lt > 2000 or vt < 10 or vt > 2000 or ot < 10 or vt > 2000 ): + raise ValueError("Expected totals approximately closer to 500, 50, 20.") +if ( vt + ot != ft ): + raise ValueError("Expected totals to add up.") + +print("Test valid (and invalid) ligatures.") +l1 = fontforge.ucLigChartGetLoc(306) +l2 = fontforge.ucLigChartGetLoc(0x133) +l3 = fontforge.ucLigChartGetLoc(0x153) +l4 = fontforge.ucLigChartGetLoc(0x4b5) +l5 = fontforge.ucLigChartGetLoc(0x135) +if ( l1 != 0 or l2 != 1 or l3 != 3 or l4 != 7 or l5 != -1 ): + raise ValueError("Expected Ligature table array 'n' values of 0,1,3,7,-1.") + +print("Return some ligatures from built-in table.") +l1 = fontforge.ucLigChartGetNxt(0) +l2 = fontforge.ucLigChartGetNxt(1) +l3 = fontforge.ucLigChartGetNxt(3) +l4 = fontforge.ucLigChartGetNxt(7) +l5 = fontforge.ucLigChartGetNxt(lt) # table starts at 0, not 1 (last value is at [lt-1]) +if ( l1 != 306 or l2 != 307 or l3 != 339 or l4 != 1205 or l5 != -1 ): + raise ValueError("Expected Ligatures values from table of: 306,307,339,1205,-1.") + +print("Test valid (and invalid) vulgar fractions.") +v1 = fontforge.ucVulChartGetLoc(0xbd) +v2 = fontforge.ucVulChartGetLoc(0x132) +if ( v1 != 1 or v2 != -1 ): + raise ValueError("Expected Vulgar Fraction table array 'n' values of: 1,-1.") + +print("Verify uint32 code works.") +o1 = fontforge.ucOFracChartGetNxt(ot-1) +if ( o1 <= 69000 ): + raise ValueError("Expected last Other Fraction of 0x10e7e or larger.") + +print("Test boolean found==1, not_found==0.") +b1 = fontforge.IsLigature(306) +b2 = fontforge.IsLigature(0x135) +b3 = fontforge.IsVulgarFraction(0xbd) +b4 = fontforge.IsVulgarFraction(0x132) +b5 = fontforge.IsFraction(0xbd) +b6 = fontforge.IsFraction(0x132) +if ( b1 != 1 or b2 != 0 or b3 != 1 or b4 != 0 or b5 != 1 or b6 != 0 ): + raise ValueError("Expected boolean values of 1,0,1,0,1,0.") + +print("All Tests done and valid.") diff --git a/tests/test129.pe b/tests/test129.pe new file mode 100644 index 0000000000..1f538bdfa9 --- /dev/null +++ b/tests/test129.pe @@ -0,0 +1,60 @@ +# test some ligatures and fractions close to U0000. Avoid high values such as +# UFxxx since the Unicode chart may add new unicode values later. + +Print("Get Table Array Totals.") +lt = ucLigChartGetCnt() +vt = ucVulChartGetCnt() +ot = ucOFracChartGetCnt() +ft = ucFracChartGetCnt() +if ( lt < 50 || lt > 2000 || vt < 10 || vt > 2000 || ot < 10 || vt > 2000) + Error("Expected totals approximately closer to 500, 50, 20.") +endif +if ( vt + ot != ft ) + Error("Expected totals to add up.") +endif + +Print("Test valid (and invalid) ligatures.") +l1 = ucLigChartGetLoc(306) +l2 = ucLigChartGetLoc(0x133) +l3 = ucLigChartGetLoc(0x153) +l4 = ucLigChartGetLoc(0x4b5) +l5 = ucLigChartGetLoc(0x135) +if ( l1 != 0 || l2 != 1 || l3 != 3 || l4 != 7 || l5 != -1 ) + Error("Expected Ligature table array 'n' values of 0,1,3,7,-1.") +endif + +Print("Return some ligatures from built-in table.") +l1 = ucLigChartGetNxt(0) +l2 = ucLigChartGetNxt(1) +l3 = ucLigChartGetNxt(3) +l4 = ucLigChartGetNxt(7) +l5 = ucLigChartGetNxt(lt) # table starts at 0, not 1 (last value is at [lt-1]) +if ( l1 != 306 || l2 != 307 || l3 != 339 || l4 != 1205 || l5 != -1 ) + Error("Expected Ligatures values from table of: 306,307,339,1205,-1.") +endif + +Print("Test valid (and invalid) vulgar fractions.") +v1 = ucVulChartGetLoc(0xbd) +v2 = ucVulChartGetLoc(0x132) +if ( v1 != 1 || v2 != -1 ) + Error("Expected Vulgar Fraction table array 'n' values of: 1,-1.") +endif + +Print("Verify uint32 code works.") +o1 = ucOFracChartGetNxt(ot-1) +if ( o1 <= 69000 ) + Error("Expected last Other Fraction of 0x10e7e or larger.") +endif + +Print("Test boolean found==1, not_found==0.") +b1 = IsLigature(306) +b2 = IsLigature(0x135) +b3 = IsVulgarFraction(0xbd) +b4 = IsVulgarFraction(0x132) +b5 = IsFraction(0xbd) +b6 = IsFraction(0x132) +if ( b1 != 1 || b2 != 0 || b3 != 1 || b4 != 0 || b5 != 1 || b6 != 0 ) + Error("Expected boolean values of 1,0,1,0,1,0.") +endif + +Print("All Tests done and valid.") diff --git a/tests/testsuite.at b/tests/testsuite.at index 33099b0855..7bed621b5b 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -96,6 +96,7 @@ check_pedit([Try SVG and PT3],[test126.pe],[DataURI.sfd]) check_pedit([Test generation of TrueType instructions],[test127.pe],[Ambrosia.sfd]) #check_pedit([],[svg2ttf.pe]) check_pedit([Test StrSplit overrun],[test128.pe]) +check_pedit([Ligatures and Fractions Table Lookups],[test129.pe]) AT_BANNER([FontForge Python Scripting Tests]) @@ -112,6 +113,7 @@ check_python([Generate duplicate fonts test],[test1005.py],[AddExtremaTest2.sfd] check_python([Math table test],[test1006.py]) check_python([Check for splinestroke 0 len fail],[test1007.py],[ayn+meem.init.svg]) check_python([PythonAPI: font glyph iteration],[test1008.py],[OverlapBugs.sfd]) +check_python([Ligatures and Fractions Table Lookups],[test1009.py]) #check_python([find overlap bug],[findoverlapbugs.py]) check_python([Validate WOFF output],[test926.py],[DejaVuSerif.sfd])