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