Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright  2014  Google, Inc.
      3  *
      4  *  This is part of HarfBuzz, a text shaping library.
      5  *
      6  * Permission is hereby granted, without written agreement and without
      7  * license or royalty fees, to use, copy, modify, and distribute this
      8  * software and its documentation for any purpose, provided that the
      9  * above copyright notice and the following two paragraphs appear in
     10  * all copies of this software.
     11  *
     12  * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
     13  * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
     14  * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
     15  * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
     16  * DAMAGE.
     17  *
     18  * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
     19  * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
     20  * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
     21  * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
     22  * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
     23  *
     24  * Google Author(s): Behdad Esfahbod
     25  */
     26 
     27 #ifndef HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH
     28 
     29 
     30 /*
     31  * The macros in the first part of this file are generic macros that can
     32  * be used to define the bytes for OpenType table data in code in a
     33  * readable manner.  We can move the macros to reside with their respective
     34  * struct types, but since we only use these to define one data table, the
     35  * Windows-1256 Arabic shaping table in this file, we keep them here.
     36  */
     37 
     38 
     39 /* First we measure, then we cut. */
     40 #ifndef OT_MEASURE
     41 #define OT_MEASURE
     42 #define OT_TABLE_START			static const struct TABLE_NAME {
     43 #define OT_TABLE_END			}
     44 #define OT_LABEL_START(Name)		unsigned char Name[
     45 #define OT_LABEL_END			];
     46 #define OT_BYTE(u8)			+1/*byte*/
     47 #define OT_USHORT(u16)			+2/*bytes*/
     48 #else
     49 #undef  OT_MEASURE
     50 #define OT_TABLE_START			TABLE_NAME = {
     51 #define OT_TABLE_END			};
     52 #define OT_LABEL_START(Name)		{
     53 #define OT_LABEL_END			},
     54 #define OT_BYTE(u8)			(u8),
     55 #define OT_USHORT(u16)			(unsigned char)((u16)>>8), (unsigned char)((u16)&0xFFu),
     56 #define OT_COUNT(Name, ItemSize)	((unsigned int) sizeof(((struct TABLE_NAME*)0)->Name) \
     57 					 / (unsigned int)(ItemSize) \
     58 					 /* OT_ASSERT it's divisible (and positive). */)
     59 #define OT_DISTANCE(From,To)		((unsigned int) \
     60 					 ((char*)(&((struct TABLE_NAME*)0)->To) - \
     61 					  (char*)(&((struct TABLE_NAME*)0)->From)) \
     62 					 /* OT_ASSERT it's positive. */)
     63 #endif
     64 
     65 
     66 #define OT_LABEL(Name) \
     67 	OT_LABEL_END \
     68 	OT_LABEL_START(Name)
     69 
     70 /* Whenever we receive an argument that is a list, it will expand to
     71  * contain commas.  That cannot be passed to another macro because the
     72  * commas will throw off the preprocessor.  The solution is to wrap
     73  * the passed-in argument in OT_LIST() before passing to the next macro.
     74  * Unfortunately this trick requires vararg macros. */
     75 #define OT_LIST(...) __VA_ARGS__
     76 
     77 
     78 /*
     79  * Basic Types
     80  */
     81 
     82 #define OT_TAG(a,b,c,d) \
     83 	OT_BYTE(a) OT_BYTE(b) OT_BYTE(c) OT_BYTE(d)
     84 
     85 #define OT_OFFSET(From, To) /* Offset from From to To in bytes */ \
     86 	OT_USHORT(OT_DISTANCE(From, To))
     87 
     88 #define OT_GLYPHID /* GlyphID */ \
     89 	OT_USHORT
     90 
     91 #define OT_UARRAY(Name, Items) \
     92 	OT_LABEL_START(Name) \
     93 	OT_USHORT(OT_COUNT(Name##Data, 2)) \
     94 	OT_LABEL(Name##Data) \
     95 	Items \
     96 	OT_LABEL_END
     97 
     98 #define OT_UHEADLESSARRAY(Name, Items) \
     99 	OT_LABEL_START(Name) \
    100 	OT_USHORT(OT_COUNT(Name##Data, 2) + 1) \
    101 	OT_LABEL(Name##Data) \
    102 	Items \
    103 	OT_LABEL_END
    104 
    105 
    106 /*
    107  * Common Types
    108  */
    109 
    110 #define OT_LOOKUP_FLAG_IGNORE_MARKS	0x08u
    111 
    112 #define OT_LOOKUP(Name, LookupType, LookupFlag, SubLookupOffsets) \
    113 	OT_LABEL_START(Name) \
    114 	OT_USHORT(LookupType) \
    115 	OT_USHORT(LookupFlag) \
    116 	OT_LABEL_END \
    117 	OT_UARRAY(Name##SubLookupOffsetsArray, OT_LIST(SubLookupOffsets))
    118 
    119 #define OT_SUBLOOKUP(Name, SubFormat, Items) \
    120 	OT_LABEL_START(Name) \
    121 	OT_USHORT(SubFormat) \
    122 	Items
    123 
    124 #define OT_COVERAGE1(Name, Items) \
    125 	OT_LABEL_START(Name) \
    126 	OT_USHORT(1) \
    127 	OT_LABEL_END \
    128 	OT_UARRAY(Name##Glyphs, OT_LIST(Items))
    129 
    130 
    131 /*
    132  * GSUB
    133  */
    134 
    135 #define OT_LOOKUP_TYPE_SUBST_SINGLE	1u
    136 #define OT_LOOKUP_TYPE_SUBST_MULTIPLE	2u
    137 #define OT_LOOKUP_TYPE_SUBST_LIGATURE	4u
    138 
    139 #define OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(Name, FromGlyphs, ToGlyphs) \
    140 	OT_SUBLOOKUP(Name, 2, \
    141 		OT_OFFSET(Name, Name##Coverage) \
    142 		OT_LABEL_END \
    143 		OT_UARRAY(Name##Substitute, OT_LIST(ToGlyphs)) \
    144 	) \
    145 	OT_COVERAGE1(Name##Coverage, OT_LIST(FromGlyphs)) \
    146 	/* ASSERT_STATIC_EXPR len(FromGlyphs) == len(ToGlyphs) */
    147 
    148 #define OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(Name, FirstGlyphs, LigatureSetOffsets) \
    149 	OT_SUBLOOKUP(Name, 1, \
    150 		OT_OFFSET(Name, Name##Coverage) \
    151 		OT_LABEL_END \
    152 		OT_UARRAY(Name##LigatureSetOffsetsArray, OT_LIST(LigatureSetOffsets)) \
    153 	) \
    154 	OT_COVERAGE1(Name##Coverage, OT_LIST(FirstGlyphs)) \
    155 	/* ASSERT_STATIC_EXPR len(FirstGlyphs) == len(LigatureSetOffsets) */
    156 
    157 #define OT_LIGATURE_SET(Name, LigatureSetOffsets) \
    158 	OT_UARRAY(Name, OT_LIST(LigatureSetOffsets))
    159 
    160 #define OT_LIGATURE(Name, Components, LigGlyph) \
    161 	OT_LABEL_START(Name) \
    162 	LigGlyph \
    163 	OT_LABEL_END \
    164 	OT_UHEADLESSARRAY(Name##ComponentsArray, OT_LIST(Components))
    165 
    166 /*
    167  *
    168  * Start of Windows-1256 shaping table.
    169  *
    170  */
    171 
    172 /* Table name. */
    173 #define TABLE_NAME arabic_win1256_gsub_lookups
    174 
    175 /* Table manifest. */
    176 #define MANIFEST(Items) \
    177 	OT_LABEL_START(manifest) \
    178 	OT_USHORT(OT_COUNT(manifestData, 6)) \
    179 	OT_LABEL(manifestData) \
    180 	Items \
    181 	OT_LABEL_END
    182 
    183 #define MANIFEST_LOOKUP(Tag, Name) \
    184 	Tag \
    185 	OT_OFFSET(manifest, Name)
    186 
    187 /* Shorthand. */
    188 #define G	OT_GLYPHID
    189 
    190 /*
    191  * Table Start
    192  */
    193 OT_TABLE_START
    194 
    195 
    196 /*
    197  * Manifest
    198  */
    199 MANIFEST(
    200 	MANIFEST_LOOKUP(OT_TAG('r','l','i','g'), rligLookup)
    201 	MANIFEST_LOOKUP(OT_TAG('i','n','i','t'), initLookup)
    202 	MANIFEST_LOOKUP(OT_TAG('m','e','d','i'), mediLookup)
    203 	MANIFEST_LOOKUP(OT_TAG('f','i','n','a'), finaLookup)
    204 	MANIFEST_LOOKUP(OT_TAG('r','l','i','g'), rligMarksLookup)
    205 )
    206 
    207 /*
    208  * Lookups
    209  */
    210 OT_LOOKUP(initLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
    211 	OT_OFFSET(initLookup, initmediSubLookup)
    212 	OT_OFFSET(initLookup, initSubLookup)
    213 )
    214 OT_LOOKUP(mediLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
    215 	OT_OFFSET(mediLookup, initmediSubLookup)
    216 	OT_OFFSET(mediLookup, mediSubLookup)
    217 	OT_OFFSET(mediLookup, medifinaLamAlefSubLookup)
    218 )
    219 OT_LOOKUP(finaLookup, OT_LOOKUP_TYPE_SUBST_SINGLE, OT_LOOKUP_FLAG_IGNORE_MARKS,
    220 	OT_OFFSET(finaLookup, finaSubLookup)
    221 	/* We don't need this one currently as the sequence inherits masks
    222 	 * from the first item.  Just in case we change that in the future
    223 	 * to be smart about Arabic masks when ligating... */
    224 	OT_OFFSET(finaLookup, medifinaLamAlefSubLookup)
    225 )
    226 OT_LOOKUP(rligLookup, OT_LOOKUP_TYPE_SUBST_LIGATURE, OT_LOOKUP_FLAG_IGNORE_MARKS,
    227 	OT_OFFSET(rligLookup, lamAlefLigaturesSubLookup)
    228 )
    229 OT_LOOKUP(rligMarksLookup, OT_LOOKUP_TYPE_SUBST_LIGATURE, 0,
    230 	OT_OFFSET(rligMarksLookup, shaddaLigaturesSubLookup)
    231 )
    232 
    233 /*
    234  * init/medi/fina forms
    235  */
    236 OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(initmediSubLookup,
    237 	G(198)	G(200)	G(201)	G(202)	G(203)	G(204)	G(205)	G(206)	G(211)
    238 	G(212)	G(213)	G(214)	G(223)	G(225)	G(227)	G(228)	G(236)	G(237),
    239 	G(162)	G(4)	G(5)	G(5)	G(6)	G(7)	G(9)	G(11)	G(13)
    240 	G(14)	G(15)	G(26)	G(140)	G(141)	G(142)	G(143)	G(154)	G(154)
    241 )
    242 OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(initSubLookup,
    243 	G(218)	G(219)	G(221)	G(222)	G(229),
    244 	G(27)	G(30)	G(128)	G(131)	G(144)
    245 )
    246 OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(mediSubLookup,
    247 	G(218)	G(219)	G(221)	G(222)	G(229),
    248 	G(28)	G(31)	G(129)	G(138)	G(149)
    249 )
    250 OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(finaSubLookup,
    251 	G(194)	G(195)	G(197)	G(198)	G(199)	G(201)	G(204)	G(205)	G(206)
    252 	G(218)	G(219)	G(229)	G(236)	G(237),
    253 	G(2)	G(1)	G(3)	G(181)	G(0)	G(159)	G(8)	G(10)	G(12)
    254 	G(29)	G(127)	G(152) G(160)	G(156)
    255 )
    256 OT_SUBLOOKUP_SINGLE_SUBST_FORMAT2(medifinaLamAlefSubLookup,
    257 	G(165)	G(178)	G(180)	G(252),
    258 	G(170)	G(179)	G(185)	G(255)
    259 )
    260 
    261 /*
    262  * Lam+Alef ligatures
    263  */
    264 OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(lamAlefLigaturesSubLookup,
    265 	G(225),
    266 	OT_OFFSET(lamAlefLigaturesSubLookup, lamLigatureSet)
    267 )
    268 OT_LIGATURE_SET(lamLigatureSet,
    269 	OT_OFFSET(lamLigatureSet, lamInitLigature1)
    270 	OT_OFFSET(lamLigatureSet, lamInitLigature2)
    271 	OT_OFFSET(lamLigatureSet, lamInitLigature3)
    272 	OT_OFFSET(lamLigatureSet, lamInitLigature4)
    273 )
    274 OT_LIGATURE(lamInitLigature1, G(199), G(165))
    275 OT_LIGATURE(lamInitLigature2, G(195), G(178))
    276 OT_LIGATURE(lamInitLigature3, G(194), G(180))
    277 OT_LIGATURE(lamInitLigature4, G(197), G(252))
    278 
    279 /*
    280  * Shadda ligatures
    281  */
    282 OT_SUBLOOKUP_LIGATURE_SUBST_FORMAT1(shaddaLigaturesSubLookup,
    283 	G(248),
    284 	OT_OFFSET(shaddaLigaturesSubLookup, shaddaLigatureSet)
    285 )
    286 OT_LIGATURE_SET(shaddaLigatureSet,
    287 	OT_OFFSET(shaddaLigatureSet, shaddaLigature1)
    288 	OT_OFFSET(shaddaLigatureSet, shaddaLigature2)
    289 	OT_OFFSET(shaddaLigatureSet, shaddaLigature3)
    290 )
    291 OT_LIGATURE(shaddaLigature1, G(243), G(172))
    292 OT_LIGATURE(shaddaLigature2, G(245), G(173))
    293 OT_LIGATURE(shaddaLigature3, G(246), G(175))
    294 
    295 /*
    296  * Table end
    297  */
    298 OT_TABLE_END
    299 
    300 
    301 /*
    302  * Clean up
    303  */
    304 #undef OT_TABLE_START
    305 #undef OT_TABLE_END
    306 #undef OT_LABEL_START
    307 #undef OT_LABEL_END
    308 #undef OT_BYTE
    309 #undef OT_USHORT
    310 #undef OT_DISTANCE
    311 #undef OT_COUNT
    312 
    313 /*
    314  * Include a second time to get the table data...
    315  */
    316 #ifdef OT_MEASURE
    317 #include "hb-ot-shape-complex-arabic-win1256.hh"
    318 #endif
    319 
    320 #define HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH
    321 #endif /* HB_OT_SHAPE_COMPLEX_ARABIC_WIN1256_HH */
    322