tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

hb-aat-layout-just-table.hh (12997B)


      1 /*
      2 * Copyright © 2018  Ebrahim Byagowi
      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 
     25 #ifndef HB_AAT_LAYOUT_JUST_TABLE_HH
     26 #define HB_AAT_LAYOUT_JUST_TABLE_HH
     27 
     28 #include "hb-aat-layout-common.hh"
     29 #include "hb-ot-layout.hh"
     30 #include "hb-open-type.hh"
     31 
     32 #include "hb-aat-layout-morx-table.hh"
     33 
     34 /*
     35 * just -- Justification
     36 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6just.html
     37 */
     38 #define HB_AAT_TAG_just HB_TAG('j','u','s','t')
     39 
     40 
     41 namespace AAT {
     42 
     43 using namespace OT;
     44 
     45 
     46 struct ActionSubrecordHeader
     47 {
     48  bool sanitize (hb_sanitize_context_t *c) const
     49  {
     50    TRACE_SANITIZE (this);
     51    return_trace (c->check_struct (this));
     52  }
     53 
     54  HBUINT16	actionClass;	/* The JustClass value associated with this
     55 			 * ActionSubrecord. */
     56  HBUINT16	actionType;	/* The type of postcompensation action. */
     57  HBUINT16	actionLength;	/* Length of this ActionSubrecord record, which
     58 			 * must be a multiple of 4. */
     59  public:
     60  DEFINE_SIZE_STATIC (6);
     61 };
     62 
     63 struct DecompositionAction
     64 {
     65  bool sanitize (hb_sanitize_context_t *c) const
     66  {
     67    TRACE_SANITIZE (this);
     68    return_trace (c->check_struct (this));
     69  }
     70 
     71  ActionSubrecordHeader
     72 	header;
     73  F16DOT16	lowerLimit;	/* If the distance factor is less than this value,
     74 			 * then the ligature is decomposed. */
     75  F16DOT16	upperLimit;	/* If the distance factor is greater than this value,
     76 			 * then the ligature is decomposed. */
     77  HBUINT16	order;		/* Numerical order in which this ligature will
     78 			 * be decomposed; you may want infrequent ligatures
     79 			 * to decompose before more frequent ones. The ligatures
     80 			 * on the line of text will decompose in increasing
     81 			 * value of this field. */
     82  Array16Of<HBUINT16>
     83 	decomposedglyphs;
     84 			/* Number of 16-bit glyph indexes that follow;
     85 			 * the ligature will be decomposed into these glyphs.
     86 			 *
     87 			 * Array of decomposed glyphs. */
     88  public:
     89  DEFINE_SIZE_ARRAY (18, decomposedglyphs);
     90 };
     91 
     92 struct UnconditionalAddGlyphAction
     93 {
     94  bool sanitize (hb_sanitize_context_t *c) const
     95  {
     96    TRACE_SANITIZE (this);
     97    return_trace (c->check_struct (this));
     98  }
     99 
    100  protected:
    101  ActionSubrecordHeader
    102 	header;
    103  HBGlyphID16	addGlyph;	/* Glyph that should be added if the distance factor
    104 			 * is growing. */
    105 
    106  public:
    107  DEFINE_SIZE_STATIC (8);
    108 };
    109 
    110 struct ConditionalAddGlyphAction
    111 {
    112  bool sanitize (hb_sanitize_context_t *c) const
    113  {
    114    TRACE_SANITIZE (this);
    115    return_trace (c->check_struct (this));
    116  }
    117 
    118  protected:
    119  ActionSubrecordHeader
    120 	header;
    121  F16DOT16	substThreshold; /* Distance growth factor (in ems) at which
    122 			 * this glyph is replaced and the growth factor
    123 			 * recalculated. */
    124  HBGlyphID16	addGlyph;	/* Glyph to be added as kashida. If this value is
    125 			 * 0xFFFF, no extra glyph will be added. Note that
    126 			 * generally when a glyph is added, justification
    127 			 * will need to be redone. */
    128  HBGlyphID16	substGlyph;	/* Glyph to be substituted for this glyph if the
    129 			 * growth factor equals or exceeds the value of
    130 			 * substThreshold. */
    131  public:
    132  DEFINE_SIZE_STATIC (14);
    133 };
    134 
    135 struct DuctileGlyphAction
    136 {
    137  bool sanitize (hb_sanitize_context_t *c) const
    138  {
    139    TRACE_SANITIZE (this);
    140    return_trace (c->check_struct (this));
    141  }
    142 
    143  protected:
    144  ActionSubrecordHeader
    145 	header;
    146  HBUINT32	variationAxis;	/* The 4-byte tag identifying the ductile axis.
    147 			 * This would normally be 0x64756374 ('duct'),
    148 			 * but you may use any axis the font contains. */
    149  F16DOT16	minimumLimit;	/* The lowest value for the ductility axis that
    150 			 * still yields an acceptable appearance. Normally
    151 			 * this will be 1.0. */
    152  F16DOT16	noStretchValue; /* This is the default value that corresponds to
    153 			 * no change in appearance. Normally, this will
    154 			 * be 1.0. */
    155  F16DOT16	maximumLimit;	/* The highest value for the ductility axis that
    156 			 * still yields an acceptable appearance. */
    157  public:
    158  DEFINE_SIZE_STATIC (22);
    159 };
    160 
    161 struct RepeatedAddGlyphAction
    162 {
    163  bool sanitize (hb_sanitize_context_t *c) const
    164  {
    165    TRACE_SANITIZE (this);
    166    return_trace (c->check_struct (this));
    167  }
    168 
    169  protected:
    170  ActionSubrecordHeader
    171 	header;
    172  HBUINT16	flags;		/* Currently unused; set to 0. */
    173  HBGlyphID16	glyph;		/* Glyph that should be added if the distance factor
    174 			 * is growing. */
    175  public:
    176  DEFINE_SIZE_STATIC (10);
    177 };
    178 
    179 struct ActionSubrecord
    180 {
    181  unsigned int get_length () const { return u.header.actionLength; }
    182 
    183  bool sanitize (hb_sanitize_context_t *c) const
    184  {
    185    TRACE_SANITIZE (this);
    186    if (unlikely (!c->check_struct (this)))
    187      return_trace (false);
    188    hb_barrier ();
    189 
    190    switch (u.header.actionType)
    191    {
    192    case 0: hb_barrier ();  return_trace (u.decompositionAction.sanitize (c));
    193    case 1: hb_barrier ();  return_trace (u.unconditionalAddGlyphAction.sanitize (c));
    194    case 2: hb_barrier ();  return_trace (u.conditionalAddGlyphAction.sanitize (c));
    195    // case 3: hb_barrier (); return_trace (u.stretchGlyphAction.sanitize (c));
    196    case 4: hb_barrier ();  return_trace (u.decompositionAction.sanitize (c));
    197    case 5: hb_barrier ();  return_trace (u.decompositionAction.sanitize (c));
    198    default: return_trace (true);
    199    }
    200  }
    201 
    202  protected:
    203  union	{
    204  ActionSubrecordHeader		header;
    205  DecompositionAction		decompositionAction;
    206  UnconditionalAddGlyphAction	unconditionalAddGlyphAction;
    207  ConditionalAddGlyphAction	conditionalAddGlyphAction;
    208  /* StretchGlyphAction stretchGlyphAction; -- Not supported by CoreText */
    209  DuctileGlyphAction		ductileGlyphAction;
    210  RepeatedAddGlyphAction	repeatedAddGlyphAction;
    211  } u;				/* Data. The format of this data depends on
    212 			 * the value of the actionType field. */
    213  public:
    214  DEFINE_SIZE_UNION (6, header);
    215 };
    216 
    217 struct PostcompensationActionChain
    218 {
    219  bool sanitize (hb_sanitize_context_t *c) const
    220  {
    221    TRACE_SANITIZE (this);
    222    if (unlikely (!c->check_struct (this)))
    223      return_trace (false);
    224    hb_barrier ();
    225 
    226    unsigned int offset = min_size;
    227    for (unsigned int i = 0; i < count; i++)
    228    {
    229      const ActionSubrecord& subrecord = StructAtOffset<ActionSubrecord> (this, offset);
    230      if (unlikely (!subrecord.sanitize (c))) return_trace (false);
    231      offset += subrecord.get_length ();
    232    }
    233 
    234    return_trace (true);
    235  }
    236 
    237  protected:
    238  HBUINT32	count;
    239 
    240  public:
    241  DEFINE_SIZE_STATIC (4);
    242 };
    243 
    244 struct JustWidthDeltaEntry
    245 {
    246  enum Flags
    247  {
    248    Reserved1		=0xE000,/* Reserved. You should set these bits to zero. */
    249    UnlimiteGap		=0x1000,/* The glyph can take unlimited gap. When this
    250 			 * glyph participates in the justification process,
    251 			 * it and any other glyphs on the line having this
    252 			 * bit set absorb all the remaining gap. */
    253    Reserved2		=0x0FF0,/* Reserved. You should set these bits to zero. */
    254    Priority		=0x000F /* The justification priority of the glyph. */
    255  };
    256 
    257  enum Priority
    258  {
    259    Kashida		= 0,	/* Kashida priority. This is the highest priority
    260 			 * during justification. */
    261    Whitespace		= 1,	/* Whitespace priority. Any whitespace glyphs (as
    262 			 * identified in the glyph properties table) will
    263 			 * get this priority. */
    264    InterCharacter	= 2,	/* Inter-character priority. Give this to any
    265 			 * remaining glyphs. */
    266    NullPriority	= 3	/* Null priority. You should set this priority for
    267 			 * glyphs that only participate in justification
    268 			 * after the above priorities. Normally all glyphs
    269 			 * have one of the previous three values. If you
    270 			 * don't want a glyph to participate in justification,
    271 			 * and you don't want to set its factors to zero,
    272 			 * you may instead assign it to the null priority. */
    273  };
    274 
    275  protected:
    276  F16DOT16	beforeGrowLimit;/* The ratio by which the advance width of the
    277 			 * glyph is permitted to grow on the left or top side. */
    278  F16DOT16	beforeShrinkLimit;
    279 			/* The ratio by which the advance width of the
    280 			 * glyph is permitted to shrink on the left or top side. */
    281  F16DOT16	afterGrowLimit;	/* The ratio by which the advance width of the glyph
    282 			 * is permitted to shrink on the left or top side. */
    283  F16DOT16	afterShrinkLimit;
    284 			/* The ratio by which the advance width of the glyph
    285 			 * is at most permitted to shrink on the right or
    286 			 * bottom side. */
    287  HBUINT16	growFlags;	/* Flags controlling the grow case. */
    288  HBUINT16	shrinkFlags;	/* Flags controlling the shrink case. */
    289 
    290  public:
    291  DEFINE_SIZE_STATIC (20);
    292 };
    293 
    294 struct WidthDeltaPair
    295 {
    296  bool sanitize (hb_sanitize_context_t *c) const
    297  {
    298    TRACE_SANITIZE (this);
    299    return_trace (c->check_struct (this));
    300  }
    301 
    302  protected:
    303  HBUINT32	justClass;	/* The justification category associated
    304 			 * with the wdRecord field. Only 7 bits of
    305 			 * this field are used. (The other bits are
    306 			 * used as padding to guarantee longword
    307 			 * alignment of the following record). */
    308  JustWidthDeltaEntry
    309 	wdRecord;	/* The actual width delta record. */
    310 
    311  public:
    312  DEFINE_SIZE_STATIC (24);
    313 };
    314 
    315 typedef OT::Array32Of<WidthDeltaPair> WidthDeltaCluster;
    316 
    317 struct JustificationCategory
    318 {
    319  typedef void EntryData;
    320 
    321  enum Flags
    322  {
    323    SetMark		=0x8000,/* If set, make the current glyph the marked
    324 			 * glyph. */
    325    DontAdvance		=0x4000,/* If set, don't advance to the next glyph before
    326 			 * going to the new state. */
    327    MarkCategory	=0x3F80,/* The justification category for the marked
    328 			 * glyph if nonzero. */
    329    CurrentCategory	=0x007F /* The justification category for the current
    330 			 * glyph if nonzero. */
    331  };
    332 
    333  bool sanitize (hb_sanitize_context_t *c, const void *base) const
    334  {
    335    TRACE_SANITIZE (this);
    336    return_trace (likely (c->check_struct (this) &&
    337 		  morphHeader.sanitize (c) &&
    338 		  stHeader.sanitize (c)));
    339  }
    340 
    341  protected:
    342  ChainSubtable<ObsoleteTypes>
    343 	morphHeader;	/* Metamorphosis-style subtable header. */
    344  StateTable<ObsoleteTypes, EntryData>
    345 	stHeader;	/* The justification insertion state table header */
    346  public:
    347  DEFINE_SIZE_STATIC (30);
    348 };
    349 
    350 struct JustificationHeader
    351 {
    352  bool sanitize (hb_sanitize_context_t *c, const void *base) const
    353  {
    354    TRACE_SANITIZE (this);
    355    return_trace (likely (c->check_struct (this) &&
    356 		  justClassTable.sanitize (c, base, base) &&
    357 		  wdcTable.sanitize (c, base) &&
    358 		  pcTable.sanitize (c, base) &&
    359 		  lookupTable.sanitize (c, base)));
    360  }
    361 
    362  protected:
    363  Offset16To<JustificationCategory>
    364 	justClassTable;	/* Offset to the justification category state table. */
    365  Offset16To<WidthDeltaCluster>
    366 	wdcTable;	/* Offset from start of justification table to start
    367 			 * of the subtable containing the width delta factors
    368 			 * for the glyphs in your font.
    369 			 *
    370 			 * The width delta clusters table. */
    371  Offset16To<PostcompensationActionChain>
    372 	pcTable;	/* Offset from start of justification table to start
    373 			 * of postcompensation subtable (set to zero if none).
    374 			 *
    375 			 * The postcompensation subtable, if present in the font. */
    376  Lookup<Offset16To<WidthDeltaCluster>>
    377 	lookupTable;	/* Lookup table associating glyphs with width delta
    378 			 * clusters. See the description of Width Delta Clusters
    379 			 * table for details on how to interpret the lookup values. */
    380 
    381  public:
    382  DEFINE_SIZE_MIN (8);
    383 };
    384 
    385 struct just
    386 {
    387  static constexpr hb_tag_t tableTag = HB_AAT_TAG_just;
    388 
    389  bool sanitize (hb_sanitize_context_t *c) const
    390  {
    391    TRACE_SANITIZE (this);
    392 
    393    return_trace (likely (c->check_struct (this) &&
    394 		  hb_barrier () &&
    395 		  version.major == 1 &&
    396 		  horizData.sanitize (c, this, this) &&
    397 		  vertData.sanitize (c, this, this)));
    398  }
    399 
    400  protected:
    401  FixedVersion<>version;	/* Version of the justification table
    402 			 * (0x00010000u for version 1.0). */
    403  HBUINT16	format;		/* Format of the justification table (set to 0). */
    404  Offset16To<JustificationHeader>
    405 	horizData;	/* Byte offset from the start of the justification table
    406 			 * to the header for tables that contain justification
    407 			 * information for horizontal text.
    408 			 * If you are not including this information,
    409 			 * store 0. */
    410  Offset16To<JustificationHeader>
    411 	vertData;	/* ditto, vertical */
    412 
    413  public:
    414  DEFINE_SIZE_STATIC (10);
    415 };
    416 
    417 } /* namespace AAT */
    418 
    419 
    420 #endif /* HB_AAT_LAYOUT_JUST_TABLE_HH */