LCOV - code coverage report
Current view: top level - gfx/harfbuzz/src - hb-ot-math-table.hh (source / functions) Hit Total Coverage
Test: output.info Lines: 0 162 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 38 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright © 2016  Igalia S.L.
       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             :  * Igalia Author(s): Frédéric Wang
      25             :  */
      26             : 
      27             : #ifndef HB_OT_MATH_TABLE_HH
      28             : #define HB_OT_MATH_TABLE_HH
      29             : 
      30             : #include "hb-open-type-private.hh"
      31             : #include "hb-ot-layout-common-private.hh"
      32             : #include "hb-ot-math.h"
      33             : 
      34             : namespace OT {
      35             : 
      36             : 
      37             : struct MathValueRecord
      38             : {
      39           0 :   inline hb_position_t get_x_value (hb_font_t *font, const void *base) const
      40           0 :   { return font->em_scale_x (value) + (base+deviceTable).get_x_delta (font); }
      41           0 :   inline hb_position_t get_y_value (hb_font_t *font, const void *base) const
      42           0 :   { return font->em_scale_y (value) + (base+deviceTable).get_y_delta (font); }
      43             : 
      44           0 :   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
      45             :   {
      46           0 :     TRACE_SANITIZE (this);
      47           0 :     return_trace (c->check_struct (this) && deviceTable.sanitize (c, base));
      48             :   }
      49             : 
      50             :   protected:
      51             :   SHORT                 value;          /* The X or Y value in design units */
      52             :   OffsetTo<Device>        deviceTable;    /* Offset to the device table - from the
      53             :                                          * beginning of parent table. May be NULL.
      54             :                                          * Suggested format for device table is 1. */
      55             : 
      56             :   public:
      57             :   DEFINE_SIZE_STATIC (4);
      58             : };
      59             : 
      60             : struct MathConstants
      61             : {
      62           0 :   inline bool sanitize_math_value_records (hb_sanitize_context_t *c) const
      63             :   {
      64           0 :     TRACE_SANITIZE (this);
      65             : 
      66           0 :     unsigned int count = ARRAY_LENGTH (mathValueRecords);
      67           0 :     for (unsigned int i = 0; i < count; i++)
      68           0 :       if (!mathValueRecords[i].sanitize (c, this))
      69           0 :         return_trace (false);
      70             : 
      71           0 :     return_trace (true);
      72             :   }
      73             : 
      74           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
      75             :   {
      76           0 :     TRACE_SANITIZE (this);
      77           0 :     return_trace (c->check_struct (this) && sanitize_math_value_records(c));
      78             :   }
      79             : 
      80           0 :   inline hb_position_t get_value (hb_ot_math_constant_t constant,
      81             :                                   hb_font_t *font) const
      82             :   {
      83           0 :     switch (constant) {
      84             : 
      85             :     case HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN:
      86             :     case HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN:
      87           0 :       return percentScaleDown[constant - HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN];
      88             : 
      89             :     case HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT:
      90             :     case HB_OT_MATH_CONSTANT_DISPLAY_OPERATOR_MIN_HEIGHT:
      91           0 :       return font->em_scale_y (minHeight[constant - HB_OT_MATH_CONSTANT_DELIMITED_SUB_FORMULA_MIN_HEIGHT]);
      92             : 
      93             :     case HB_OT_MATH_CONSTANT_RADICAL_KERN_AFTER_DEGREE:
      94             :     case HB_OT_MATH_CONSTANT_RADICAL_KERN_BEFORE_DEGREE:
      95             :     case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_HORIZONTAL_GAP:
      96             :     case HB_OT_MATH_CONSTANT_SPACE_AFTER_SCRIPT:
      97           0 :       return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_x_value(font, this);
      98             : 
      99             :     case HB_OT_MATH_CONSTANT_ACCENT_BASE_HEIGHT:
     100             :     case HB_OT_MATH_CONSTANT_AXIS_HEIGHT:
     101             :     case HB_OT_MATH_CONSTANT_FLATTENED_ACCENT_BASE_HEIGHT:
     102             :     case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_DISPLAY_STYLE_SHIFT_DOWN:
     103             :     case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_GAP_MIN:
     104             :     case HB_OT_MATH_CONSTANT_FRACTION_DENOMINATOR_SHIFT_DOWN:
     105             :     case HB_OT_MATH_CONSTANT_FRACTION_DENOM_DISPLAY_STYLE_GAP_MIN:
     106             :     case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_DISPLAY_STYLE_SHIFT_UP:
     107             :     case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_GAP_MIN:
     108             :     case HB_OT_MATH_CONSTANT_FRACTION_NUMERATOR_SHIFT_UP:
     109             :     case HB_OT_MATH_CONSTANT_FRACTION_NUM_DISPLAY_STYLE_GAP_MIN:
     110             :     case HB_OT_MATH_CONSTANT_FRACTION_RULE_THICKNESS:
     111             :     case HB_OT_MATH_CONSTANT_LOWER_LIMIT_BASELINE_DROP_MIN:
     112             :     case HB_OT_MATH_CONSTANT_LOWER_LIMIT_GAP_MIN:
     113             :     case HB_OT_MATH_CONSTANT_MATH_LEADING:
     114             :     case HB_OT_MATH_CONSTANT_OVERBAR_EXTRA_ASCENDER:
     115             :     case HB_OT_MATH_CONSTANT_OVERBAR_RULE_THICKNESS:
     116             :     case HB_OT_MATH_CONSTANT_OVERBAR_VERTICAL_GAP:
     117             :     case HB_OT_MATH_CONSTANT_RADICAL_DISPLAY_STYLE_VERTICAL_GAP:
     118             :     case HB_OT_MATH_CONSTANT_RADICAL_EXTRA_ASCENDER:
     119             :     case HB_OT_MATH_CONSTANT_RADICAL_RULE_THICKNESS:
     120             :     case HB_OT_MATH_CONSTANT_RADICAL_VERTICAL_GAP:
     121             :     case HB_OT_MATH_CONSTANT_SKEWED_FRACTION_VERTICAL_GAP:
     122             :     case HB_OT_MATH_CONSTANT_STACK_BOTTOM_DISPLAY_STYLE_SHIFT_DOWN:
     123             :     case HB_OT_MATH_CONSTANT_STACK_BOTTOM_SHIFT_DOWN:
     124             :     case HB_OT_MATH_CONSTANT_STACK_DISPLAY_STYLE_GAP_MIN:
     125             :     case HB_OT_MATH_CONSTANT_STACK_GAP_MIN:
     126             :     case HB_OT_MATH_CONSTANT_STACK_TOP_DISPLAY_STYLE_SHIFT_UP:
     127             :     case HB_OT_MATH_CONSTANT_STACK_TOP_SHIFT_UP:
     128             :     case HB_OT_MATH_CONSTANT_STRETCH_STACK_BOTTOM_SHIFT_DOWN:
     129             :     case HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_ABOVE_MIN:
     130             :     case HB_OT_MATH_CONSTANT_STRETCH_STACK_GAP_BELOW_MIN:
     131             :     case HB_OT_MATH_CONSTANT_STRETCH_STACK_TOP_SHIFT_UP:
     132             :     case HB_OT_MATH_CONSTANT_SUBSCRIPT_BASELINE_DROP_MIN:
     133             :     case HB_OT_MATH_CONSTANT_SUBSCRIPT_SHIFT_DOWN:
     134             :     case HB_OT_MATH_CONSTANT_SUBSCRIPT_TOP_MAX:
     135             :     case HB_OT_MATH_CONSTANT_SUB_SUPERSCRIPT_GAP_MIN:
     136             :     case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BASELINE_DROP_MAX:
     137             :     case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MAX_WITH_SUBSCRIPT:
     138             :     case HB_OT_MATH_CONSTANT_SUPERSCRIPT_BOTTOM_MIN:
     139             :     case HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP:
     140             :     case HB_OT_MATH_CONSTANT_SUPERSCRIPT_SHIFT_UP_CRAMPED:
     141             :     case HB_OT_MATH_CONSTANT_UNDERBAR_EXTRA_DESCENDER:
     142             :     case HB_OT_MATH_CONSTANT_UNDERBAR_RULE_THICKNESS:
     143             :     case HB_OT_MATH_CONSTANT_UNDERBAR_VERTICAL_GAP:
     144             :     case HB_OT_MATH_CONSTANT_UPPER_LIMIT_BASELINE_RISE_MIN:
     145             :     case HB_OT_MATH_CONSTANT_UPPER_LIMIT_GAP_MIN:
     146           0 :       return mathValueRecords[constant - HB_OT_MATH_CONSTANT_MATH_LEADING].get_y_value(font, this);
     147             : 
     148             :     case HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT:
     149           0 :       return radicalDegreeBottomRaisePercent;
     150             : 
     151             :     default:
     152           0 :       return 0;
     153             :     }
     154             :   }
     155             : 
     156             :   protected:
     157             :   SHORT percentScaleDown[2];
     158             :   USHORT minHeight[2];
     159             :   MathValueRecord mathValueRecords[51];
     160             :   SHORT radicalDegreeBottomRaisePercent;
     161             : 
     162             :   public:
     163             :   DEFINE_SIZE_STATIC (214);
     164             : };
     165             : 
     166             : struct MathItalicsCorrectionInfo
     167             : {
     168           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     169             :   {
     170           0 :     TRACE_SANITIZE (this);
     171           0 :     return_trace (c->check_struct (this) &&
     172             :                   coverage.sanitize (c, this) &&
     173             :                   italicsCorrection.sanitize (c, this));
     174             :   }
     175             : 
     176           0 :   inline hb_position_t get_value (hb_codepoint_t glyph,
     177             :                                   hb_font_t *font) const
     178             :   {
     179           0 :     unsigned int index = (this+coverage).get_coverage (glyph);
     180           0 :     return italicsCorrection[index].get_x_value (font, this);
     181             :   }
     182             : 
     183             :   protected:
     184             :   OffsetTo<Coverage>       coverage;              /* Offset to Coverage table -
     185             :                                                  * from the beginning of
     186             :                                                  * MathItalicsCorrectionInfo
     187             :                                                  * table. */
     188             :   ArrayOf<MathValueRecord> italicsCorrection;     /* Array of MathValueRecords
     189             :                                                  * defining italics correction
     190             :                                                  * values for each
     191             :                                                  * covered glyph. */
     192             : 
     193             :   public:
     194             :   DEFINE_SIZE_ARRAY (4, italicsCorrection);
     195             : };
     196             : 
     197             : struct MathTopAccentAttachment
     198             : {
     199           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     200             :   {
     201           0 :     TRACE_SANITIZE (this);
     202           0 :     return_trace (c->check_struct (this) &&
     203             :                   topAccentCoverage.sanitize (c, this) &&
     204             :                   topAccentAttachment.sanitize (c, this));
     205             :   }
     206             : 
     207           0 :   inline hb_position_t get_value (hb_codepoint_t glyph,
     208             :                                   hb_font_t *font) const
     209             :   {
     210           0 :     unsigned int index = (this+topAccentCoverage).get_coverage (glyph);
     211           0 :     if (index == NOT_COVERED)
     212           0 :       return font->get_glyph_h_advance (glyph) / 2;
     213           0 :     return topAccentAttachment[index].get_x_value(font, this);
     214             :   }
     215             : 
     216             :   protected:
     217             :   OffsetTo<Coverage>       topAccentCoverage;   /* Offset to Coverage table -
     218             :                                                  * from the beginning of
     219             :                                                  * MathTopAccentAttachment
     220             :                                                  * table. */
     221             :   ArrayOf<MathValueRecord> topAccentAttachment; /* Array of MathValueRecords
     222             :                                                  * defining top accent
     223             :                                                  * attachment points for each
     224             :                                                  * covered glyph. */
     225             : 
     226             :   public:
     227             :   DEFINE_SIZE_ARRAY (2 + 2, topAccentAttachment);
     228             : };
     229             : 
     230             : struct MathKern
     231             : {
     232           0 :   inline bool sanitize_math_value_records (hb_sanitize_context_t *c) const
     233             :   {
     234           0 :     TRACE_SANITIZE (this);
     235           0 :     unsigned int count = 2 * heightCount + 1;
     236           0 :     for (unsigned int i = 0; i < count; i++)
     237           0 :       if (!mathValueRecords[i].sanitize (c, this)) return_trace (false);
     238           0 :     return_trace (true);
     239             :   }
     240             : 
     241           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     242             :   {
     243           0 :     TRACE_SANITIZE (this);
     244           0 :     return_trace (c->check_struct (this) &&
     245             :                   c->check_array (mathValueRecords,
     246             :                                   mathValueRecords[0].static_size,
     247             :                                   2 * heightCount + 1) &&
     248             :                   sanitize_math_value_records (c));
     249             :   }
     250             : 
     251           0 :   inline hb_position_t get_value (hb_position_t correction_height, hb_font_t *font) const
     252             :   {
     253           0 :     const MathValueRecord* correctionHeight = mathValueRecords;
     254           0 :     const MathValueRecord* kernValue = mathValueRecords + heightCount;
     255           0 :     int sign = font->y_scale < 0 ? -1 : +1;
     256             : 
     257             :     /* The description of the MathKern table is a ambiguous, but interpreting
     258             :      * "between the two heights found at those indexes" for 0 < i < len as
     259             :      *
     260             :      *   correctionHeight[i-1] < correction_height <= correctionHeight[i]
     261             :      *
     262             :      * makes the result consistent with the limit cases and we can just use the
     263             :      * binary search algorithm of std::upper_bound:
     264             :      */
     265           0 :     unsigned int i = 0;
     266           0 :     unsigned int count = heightCount;
     267           0 :     while (count > 0)
     268             :     {
     269           0 :       unsigned int half = count / 2;
     270           0 :       hb_position_t height = correctionHeight[i + half].get_y_value(font, this);
     271           0 :       if (sign * height < sign * correction_height)
     272             :       {
     273           0 :         i += half + 1;
     274           0 :         count -= half + 1;
     275             :       } else
     276           0 :         count = half;
     277             :     }
     278           0 :     return kernValue[i].get_x_value(font, this);
     279             :   }
     280             : 
     281             :   protected:
     282             :   USHORT          heightCount;
     283             :   MathValueRecord mathValueRecords[VAR]; /* Array of correction heights at
     284             :                                           * which the kern value changes.
     285             :                                           * Sorted by the height value in
     286             :                                           * design units (heightCount entries),
     287             :                                           * Followed by:
     288             :                                           * Array of kern values corresponding
     289             :                                           * to heights. (heightCount+1 entries).
     290             :                                           */
     291             : 
     292             :   public:
     293             :   DEFINE_SIZE_ARRAY (2, mathValueRecords);
     294             : };
     295             : 
     296             : struct MathKernInfoRecord
     297             : {
     298           0 :   inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
     299             :   {
     300           0 :     TRACE_SANITIZE (this);
     301             : 
     302           0 :     unsigned int count = ARRAY_LENGTH (mathKern);
     303           0 :     for (unsigned int i = 0; i < count; i++)
     304           0 :       if (unlikely (!mathKern[i].sanitize (c, base)))
     305           0 :         return_trace (false);
     306             : 
     307           0 :     return_trace (true);
     308             :   }
     309             : 
     310           0 :   inline hb_position_t get_kerning (hb_ot_math_kern_t kern,
     311             :                                     hb_position_t correction_height,
     312             :                                     hb_font_t *font,
     313             :                                     const void *base) const
     314             :   {
     315           0 :     unsigned int idx = kern;
     316           0 :     if (unlikely (idx >= ARRAY_LENGTH (mathKern))) return 0;
     317           0 :     return (base+mathKern[idx]).get_value (correction_height, font);
     318             :   }
     319             : 
     320             :   protected:
     321             :   /* Offset to MathKern table for each corner -
     322             :    * from the beginning of MathKernInfo table. May be NULL. */
     323             :   OffsetTo<MathKern> mathKern[4];
     324             : 
     325             :   public:
     326             :   DEFINE_SIZE_STATIC (8);
     327             : };
     328             : 
     329             : struct MathKernInfo
     330             : {
     331           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     332             :   {
     333           0 :     TRACE_SANITIZE (this);
     334           0 :     return_trace (c->check_struct (this) &&
     335             :                   mathKernCoverage.sanitize (c, this) &&
     336             :                   mathKernInfoRecords.sanitize (c, this));
     337             :   }
     338             : 
     339           0 :   inline hb_position_t get_kerning (hb_codepoint_t glyph,
     340             :                                     hb_ot_math_kern_t kern,
     341             :                                     hb_position_t correction_height,
     342             :                                     hb_font_t *font) const
     343             :   {
     344           0 :     unsigned int index = (this+mathKernCoverage).get_coverage (glyph);
     345           0 :     return mathKernInfoRecords[index].get_kerning (kern, correction_height, font, this);
     346             :   }
     347             : 
     348             :   protected:
     349             :   OffsetTo<Coverage>              mathKernCoverage;    /* Offset to Coverage table -
     350             :                                                       * from the beginning of the
     351             :                                                       * MathKernInfo table. */
     352             :   ArrayOf<MathKernInfoRecord>     mathKernInfoRecords; /* Array of
     353             :                                                       * MathKernInfoRecords,
     354             :                                                       * per-glyph information for
     355             :                                                       * mathematical positioning
     356             :                                                       * of subscripts and
     357             :                                                       * superscripts. */
     358             : 
     359             :   public:
     360             :   DEFINE_SIZE_ARRAY (4, mathKernInfoRecords);
     361             : };
     362             : 
     363             : struct MathGlyphInfo
     364             : {
     365           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     366             :   {
     367           0 :     TRACE_SANITIZE (this);
     368           0 :     return_trace (c->check_struct (this) &&
     369             :                   mathItalicsCorrectionInfo.sanitize (c, this) &&
     370             :                   mathTopAccentAttachment.sanitize (c, this) &&
     371             :                   extendedShapeCoverage.sanitize (c, this) &&
     372             :                   mathKernInfo.sanitize(c, this));
     373             :   }
     374             : 
     375             :   inline hb_position_t
     376           0 :   get_italics_correction (hb_codepoint_t  glyph, hb_font_t *font) const
     377           0 :   { return (this+mathItalicsCorrectionInfo).get_value (glyph, font); }
     378             : 
     379             :   inline hb_position_t
     380           0 :   get_top_accent_attachment (hb_codepoint_t  glyph, hb_font_t *font) const
     381           0 :   { return (this+mathTopAccentAttachment).get_value (glyph, font); }
     382             : 
     383           0 :   inline bool is_extended_shape (hb_codepoint_t glyph) const
     384           0 :   { return (this+extendedShapeCoverage).get_coverage (glyph) != NOT_COVERED; }
     385             : 
     386           0 :   inline hb_position_t get_kerning (hb_codepoint_t glyph,
     387             :                                     hb_ot_math_kern_t kern,
     388             :                                     hb_position_t correction_height,
     389             :                                     hb_font_t *font) const
     390           0 :   { return (this+mathKernInfo).get_kerning (glyph, kern, correction_height, font); }
     391             : 
     392             :   protected:
     393             :   /* Offset to MathItalicsCorrectionInfo table -
     394             :    * from the beginning of MathGlyphInfo table. */
     395             :   OffsetTo<MathItalicsCorrectionInfo> mathItalicsCorrectionInfo;
     396             : 
     397             :   /* Offset to MathTopAccentAttachment table -
     398             :    * from the beginning of MathGlyphInfo table. */
     399             :   OffsetTo<MathTopAccentAttachment> mathTopAccentAttachment;
     400             : 
     401             :   /* Offset to coverage table for Extended Shape glyphs -
     402             :    * from the beginning of MathGlyphInfo table. When the left or right glyph of
     403             :    * a box is an extended shape variant, the (ink) box (and not the default
     404             :    * position defined by values in MathConstants table) should be used for
     405             :    * vertical positioning purposes. May be NULL.. */
     406             :   OffsetTo<Coverage> extendedShapeCoverage;
     407             : 
     408             :    /* Offset to MathKernInfo table -
     409             :     * from the beginning of MathGlyphInfo table. */
     410             :   OffsetTo<MathKernInfo> mathKernInfo;
     411             : 
     412             :   public:
     413             :   DEFINE_SIZE_STATIC (8);
     414             : };
     415             : 
     416             : struct MathGlyphVariantRecord
     417             : {
     418             :   friend struct MathGlyphConstruction;
     419             : 
     420             :   inline bool sanitize (hb_sanitize_context_t *c) const
     421             :   {
     422             :     TRACE_SANITIZE (this);
     423             :     return_trace (c->check_struct (this));
     424             :   }
     425             : 
     426             :   protected:
     427             :   GlyphID variantGlyph;       /* Glyph ID for the variant. */
     428             :   USHORT  advanceMeasurement; /* Advance width/height, in design units, of the
     429             :                                * variant, in the direction of requested
     430             :                                * glyph extension. */
     431             : 
     432             :   public:
     433             :   DEFINE_SIZE_STATIC (4);
     434             : };
     435             : 
     436             : struct PartFlags : USHORT
     437             : {
     438             :   enum Flags {
     439             :     Extender    = 0x0001u, /* If set, the part can be skipped or repeated. */
     440             : 
     441             :     Defined     = 0x0001u, /* All defined flags. */
     442             :   };
     443             : 
     444             :   public:
     445             :   DEFINE_SIZE_STATIC (2);
     446             : };
     447             : 
     448             : struct MathGlyphPartRecord
     449             : {
     450             :   inline bool sanitize (hb_sanitize_context_t *c) const
     451             :   {
     452             :     TRACE_SANITIZE (this);
     453             :     return_trace (c->check_struct (this));
     454             :   }
     455             : 
     456           0 :   inline void extract (hb_ot_math_glyph_part_t &out,
     457             :                        int scale,
     458             :                        hb_font_t *font) const
     459             :   {
     460           0 :     out.glyph                   = glyph;
     461             : 
     462           0 :     out.start_connector_length  = font->em_scale (startConnectorLength, scale);
     463           0 :     out.end_connector_length    = font->em_scale (endConnectorLength, scale);
     464           0 :     out.full_advance            = font->em_scale (fullAdvance, scale);
     465             : 
     466             :     ASSERT_STATIC ((unsigned int) HB_MATH_GLYPH_PART_FLAG_EXTENDER ==
     467             :                    (unsigned int) PartFlags::Extender);
     468             : 
     469           0 :     out.flags = (hb_ot_math_glyph_part_flags_t)
     470           0 :                 (unsigned int)
     471           0 :                 (partFlags & PartFlags::Defined);
     472           0 :   }
     473             : 
     474             :   protected:
     475             :   GlyphID   glyph;                /* Glyph ID for the part. */
     476             :   USHORT    startConnectorLength; /* Advance width/ height of the straight bar
     477             :                                    * connector material, in design units, is at
     478             :                                    * the beginning of the glyph, in the
     479             :                                    * direction of the extension. */
     480             :   USHORT    endConnectorLength;   /* Advance width/ height of the straight bar
     481             :                                    * connector material, in design units, is at
     482             :                                    * the end of the glyph, in the direction of
     483             :                                    * the extension. */
     484             :   USHORT    fullAdvance;          /* Full advance width/height for this part,
     485             :                                    * in the direction of the extension.
     486             :                                    * In design units. */
     487             :   PartFlags partFlags;            /* Part qualifiers. */
     488             : 
     489             :   public:
     490             :   DEFINE_SIZE_STATIC (10);
     491             : };
     492             : 
     493             : struct MathGlyphAssembly
     494             : {
     495           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     496             :   {
     497           0 :     TRACE_SANITIZE (this);
     498           0 :     return_trace (c->check_struct (this) &&
     499             :                   italicsCorrection.sanitize(c, this) &&
     500             :                   partRecords.sanitize(c));
     501             :   }
     502             : 
     503           0 :   inline unsigned int get_parts (hb_direction_t direction,
     504             :                                  hb_font_t *font,
     505             :                                  unsigned int start_offset,
     506             :                                  unsigned int *parts_count, /* IN/OUT */
     507             :                                  hb_ot_math_glyph_part_t *parts /* OUT */,
     508             :                                  hb_position_t *italics_correction /* OUT */) const
     509             :   {
     510           0 :     if (parts_count)
     511             :     {
     512           0 :       int scale = font->dir_scale (direction);
     513             :       const MathGlyphPartRecord *arr =
     514           0 :             partRecords.sub_array (start_offset, parts_count);
     515           0 :       unsigned int count = *parts_count;
     516           0 :       for (unsigned int i = 0; i < count; i++)
     517           0 :         arr[i].extract (parts[i], scale, font);
     518             :     }
     519             : 
     520           0 :     if (italics_correction)
     521           0 :       *italics_correction = italicsCorrection.get_x_value (font, this);
     522             : 
     523           0 :     return partRecords.len;
     524             :   }
     525             : 
     526             :   protected:
     527             :   MathValueRecord          italicsCorrection; /* Italics correction of this
     528             :                                                * MathGlyphAssembly. Should not
     529             :                                                * depend on the assembly size. */
     530             :   ArrayOf<MathGlyphPartRecord> partRecords;   /* Array of part records, from
     531             :                                                * left to right and bottom to
     532             :                                                * top. */
     533             : 
     534             :   public:
     535             :   DEFINE_SIZE_ARRAY (6, partRecords);
     536             : };
     537             : 
     538             : struct MathGlyphConstruction
     539             : {
     540           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     541             :   {
     542           0 :     TRACE_SANITIZE (this);
     543           0 :     return_trace (c->check_struct (this) &&
     544             :                   glyphAssembly.sanitize(c, this) &&
     545             :                   mathGlyphVariantRecord.sanitize(c));
     546             :   }
     547             : 
     548           0 :   inline const MathGlyphAssembly &get_assembly (void) const
     549           0 :   { return this+glyphAssembly; }
     550             : 
     551           0 :   inline unsigned int get_variants (hb_direction_t direction,
     552             :                                     hb_font_t *font,
     553             :                                     unsigned int start_offset,
     554             :                                     unsigned int *variants_count, /* IN/OUT */
     555             :                                     hb_ot_math_glyph_variant_t *variants /* OUT */) const
     556             :   {
     557           0 :     if (variants_count)
     558             :     {
     559           0 :       int scale = font->dir_scale (direction);
     560             :       const MathGlyphVariantRecord *arr =
     561           0 :             mathGlyphVariantRecord.sub_array (start_offset, variants_count);
     562           0 :       unsigned int count = *variants_count;
     563           0 :       for (unsigned int i = 0; i < count; i++)
     564             :       {
     565           0 :         variants[i].glyph = arr[i].variantGlyph;
     566           0 :         variants[i].advance = font->em_scale (arr[i].advanceMeasurement, scale);
     567             :       }
     568             :     }
     569           0 :     return mathGlyphVariantRecord.len;
     570             :   }
     571             : 
     572             :   protected:
     573             :   /* Offset to MathGlyphAssembly table for this shape - from the beginning of
     574             :      MathGlyphConstruction table. May be NULL. */
     575             :   OffsetTo<MathGlyphAssembly>       glyphAssembly;
     576             : 
     577             :   /* MathGlyphVariantRecords for alternative variants of the glyphs. */
     578             :   ArrayOf<MathGlyphVariantRecord> mathGlyphVariantRecord;
     579             : 
     580             :   public:
     581             :   DEFINE_SIZE_ARRAY (4, mathGlyphVariantRecord);
     582             : };
     583             : 
     584             : struct MathVariants
     585             : {
     586           0 :   inline bool sanitize_offsets (hb_sanitize_context_t *c) const
     587             :   {
     588           0 :     TRACE_SANITIZE (this);
     589           0 :     unsigned int count = vertGlyphCount + horizGlyphCount;
     590           0 :     for (unsigned int i = 0; i < count; i++)
     591           0 :       if (!glyphConstruction[i].sanitize (c, this)) return_trace (false);
     592           0 :     return_trace (true);
     593             :   }
     594             : 
     595           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     596             :   {
     597           0 :     TRACE_SANITIZE (this);
     598           0 :     return_trace (c->check_struct (this) &&
     599             :                   vertGlyphCoverage.sanitize (c, this) &&
     600             :                   horizGlyphCoverage.sanitize (c, this) &&
     601             :                   c->check_array (glyphConstruction,
     602             :                                   glyphConstruction[0].static_size,
     603             :                                   vertGlyphCount + horizGlyphCount) &&
     604             :                   sanitize_offsets (c));
     605             :   }
     606             : 
     607           0 :   inline hb_position_t get_min_connector_overlap (hb_direction_t direction,
     608             :                                                   hb_font_t *font) const
     609           0 :   { return font->em_scale_dir (minConnectorOverlap, direction); }
     610             : 
     611           0 :   inline unsigned int get_glyph_variants (hb_codepoint_t glyph,
     612             :                                           hb_direction_t direction,
     613             :                                           hb_font_t *font,
     614             :                                           unsigned int start_offset,
     615             :                                           unsigned int *variants_count, /* IN/OUT */
     616             :                                           hb_ot_math_glyph_variant_t *variants /* OUT */) const
     617           0 :   { return get_glyph_construction (glyph, direction, font)
     618           0 :            .get_variants (direction, font, start_offset, variants_count, variants); }
     619             : 
     620           0 :   inline unsigned int get_glyph_parts (hb_codepoint_t glyph,
     621             :                                        hb_direction_t direction,
     622             :                                        hb_font_t *font,
     623             :                                        unsigned int start_offset,
     624             :                                        unsigned int *parts_count, /* IN/OUT */
     625             :                                        hb_ot_math_glyph_part_t *parts /* OUT */,
     626             :                                        hb_position_t *italics_correction /* OUT */) const
     627           0 :   { return get_glyph_construction (glyph, direction, font)
     628           0 :            .get_assembly ()
     629             :            .get_parts (direction, font,
     630             :                        start_offset, parts_count, parts,
     631           0 :                        italics_correction); }
     632             : 
     633             :   private:
     634             :   inline const MathGlyphConstruction &
     635           0 :                 get_glyph_construction (hb_codepoint_t glyph,
     636             :                                         hb_direction_t direction,
     637             :                                         hb_font_t *font) const
     638             :   {
     639           0 :     bool vertical = HB_DIRECTION_IS_VERTICAL (direction);
     640           0 :     unsigned int count = vertical ? vertGlyphCount : horizGlyphCount;
     641             :     const OffsetTo<Coverage> &coverage = vertical ? vertGlyphCoverage
     642           0 :                                                   : horizGlyphCoverage;
     643             : 
     644           0 :     unsigned int index = (this+coverage).get_coverage (glyph);
     645           0 :     if (unlikely (index >= count)) return Null(MathGlyphConstruction);
     646             : 
     647           0 :     if (!vertical)
     648           0 :       index += vertGlyphCount;
     649             : 
     650           0 :     return this+glyphConstruction[index];
     651             :   }
     652             : 
     653             :   protected:
     654             :   USHORT             minConnectorOverlap; /* Minimum overlap of connecting
     655             :                                            * glyphs during glyph construction,
     656             :                                            * in design units. */
     657             :   OffsetTo<Coverage> vertGlyphCoverage;   /* Offset to Coverage table -
     658             :                                            * from the beginning of MathVariants
     659             :                                            * table. */
     660             :   OffsetTo<Coverage> horizGlyphCoverage;  /* Offset to Coverage table -
     661             :                                            * from the beginning of MathVariants
     662             :                                            * table. */
     663             :   USHORT             vertGlyphCount;      /* Number of glyphs for which
     664             :                                            * information is provided for
     665             :                                            * vertically growing variants. */
     666             :   USHORT             horizGlyphCount;     /* Number of glyphs for which
     667             :                                            * information is provided for
     668             :                                            * horizontally growing variants. */
     669             : 
     670             :   /* Array of offsets to MathGlyphConstruction tables - from the beginning of
     671             :      the MathVariants table, for shapes growing in vertical/horizontal
     672             :      direction. */
     673             :   OffsetTo<MathGlyphConstruction> glyphConstruction[VAR];
     674             : 
     675             :   public:
     676             :   DEFINE_SIZE_ARRAY (10, glyphConstruction);
     677             : };
     678             : 
     679             : 
     680             : /*
     681             :  * MATH -- The MATH Table
     682             :  */
     683             : 
     684             : struct MATH
     685             : {
     686             :   static const hb_tag_t tableTag        = HB_OT_TAG_MATH;
     687             : 
     688           0 :   inline bool sanitize (hb_sanitize_context_t *c) const
     689             :   {
     690           0 :     TRACE_SANITIZE (this);
     691           0 :     return_trace (version.sanitize (c) &&
     692             :                   likely (version.major == 1) &&
     693             :                   mathConstants.sanitize (c, this) &&
     694             :                   mathGlyphInfo.sanitize (c, this) &&
     695             :                   mathVariants.sanitize (c, this));
     696             :   }
     697             : 
     698           0 :   inline hb_position_t get_constant (hb_ot_math_constant_t  constant,
     699             :                                      hb_font_t             *font) const
     700           0 :   { return (this+mathConstants).get_value (constant, font); }
     701             : 
     702           0 :   inline const MathGlyphInfo &get_math_glyph_info (void) const
     703           0 :   { return this+mathGlyphInfo; }
     704             : 
     705           0 :   inline const MathVariants &get_math_variants (void) const
     706           0 :   { return this+mathVariants; }
     707             : 
     708             :   protected:
     709             :   FixedVersion<>version;          /* Version of the MATH table
     710             :                                          * initially set to 0x00010000u */
     711             :   OffsetTo<MathConstants> mathConstants;/* MathConstants table */
     712             :   OffsetTo<MathGlyphInfo> mathGlyphInfo;/* MathGlyphInfo table */
     713             :   OffsetTo<MathVariants>  mathVariants;   /* MathVariants table */
     714             : 
     715             :   public:
     716             :   DEFINE_SIZE_STATIC (10);
     717             : };
     718             : 
     719             : } /* namespace OT */
     720             : 
     721             : 
     722             : #endif /* HB_OT_MATH_TABLE_HH */

Generated by: LCOV version 1.13