Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  hb-ot-kern-table.hh   Sprache: C

 
/*
 * Copyright © 2017  Google, Inc.
 *
 *  This is part of HarfBuzz, a text shaping library.
 *
 * Permission is hereby granted, without written agreement and without
 * license or royalty fees, to use, copy, modify, and distribute this
 * software and its documentation for any purpose, provided that the
 * above copyright notice and the following two paragraphs appear in
 * all copies of this software.
 *
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
 * DAMAGE.
 *
 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
 *
 * Google Author(s): Behdad Esfahbod
 */


#ifndef HB_OT_KERN_TABLE_HH
#define HB_OT_KERN_TABLE_HH

#include "hb-aat-layout-kerx-table.hh"


/*
 * kern -- Kerning
 * https://docs.microsoft.com/en-us/typography/opentype/spec/kern
 * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6kern.html
 */

#define HB_OT_TAG_kern HB_TAG('k','e','r','n')


namespace OT {


template <typename KernSubTableHeader>
struct KernSubTableFormat3
{
  int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
  {
    hb_array_t<const FWORD> kernValue = kernValueZ.as_array (kernValueCount);
    hb_array_t<const HBUINT8> leftClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (kernValue).as_array (glyphCount);
    hb_array_t<const HBUINT8> rightClass = StructAfter<const UnsizedArrayOf<HBUINT8>> (leftClass).as_array (glyphCount);
    hb_array_t<const HBUINT8> kernIndex = StructAfter<const UnsizedArrayOf<HBUINT8>> (rightClass).as_array (leftClassCount * rightClassCount);

    unsigned int leftC = leftClass[left];
    unsigned int rightC = rightClass[right];
    if (unlikely (leftC >= leftClassCount || rightC >= rightClassCount))
      return 0;
    unsigned int i = leftC * rightClassCount + rightC;
    return kernValue[kernIndex[i]];
  }

  bool apply (AAT::hb_aat_apply_context_t *c) const
  {
    TRACE_APPLY (this);

    if (!c->plan->requested_kerning)
      return false;

    if (header.coverage & header.Backwards)
      return false;

    hb_kern_machine_t<KernSubTableFormat3> machine (*this, header.coverage & header.CrossStream);
    machine.kern (c->font, c->buffer, c->plan->kern_mask);

    return_trace (true);
  }

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this) &&
    hb_barrier () &&
    c->check_range (kernValueZ,
      kernValueCount * sizeof (FWORD) +
      glyphCount * 2 +
      leftClassCount * rightClassCount));
  }

  template <typename set_t>
  void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const
  {
    set_t set;
    if (likely (glyphCount))
      set.add_range (0, glyphCount - 1);
    left_set.union_ (set);
    right_set.union_ (set);
  }

  protected:
  KernSubTableHeader
  header;
  HBUINT16 glyphCount; /* The number of glyphs in this font. */
  HBUINT8 kernValueCount; /* The number of kerning values. */
  HBUINT8 leftClassCount; /* The number of left-hand classes. */
  HBUINT8 rightClassCount;/* The number of right-hand classes. */
  HBUINT8 flags;  /* Set to zero (reserved for future use). */
  UnsizedArrayOf<FWORD>
  kernValueZ; /* The kerning values.
 * Length kernValueCount. */

#if 0
  UnsizedArrayOf<HBUINT8>
  leftClass; /* The left-hand classes.
 * Length glyphCount. */

  UnsizedArrayOf<HBUINT8>
  rightClass; /* The right-hand classes.
 * Length glyphCount. */

  UnsizedArrayOf<HBUINT8>kernIndex;
    /* The indices into the kernValue array.
 * Length leftClassCount * rightClassCount */

#endif
  public:
  DEFINE_SIZE_ARRAY (KernSubTableHeader::static_size + 6, kernValueZ);
};

template <typename KernSubTableHeader>
struct KernSubTable
{
  unsigned int get_size () const { return u.header.length; }
  unsigned int get_type () const { return u.header.format; }

  int get_kerning (hb_codepoint_t left, hb_codepoint_t right) const
  {
    switch (get_type ()) {
    /* This method hooks up to hb_font_t's get_h_kerning.  Only support Format0. */
    case 0: hb_barrier (); return u.format0.get_kerning (left, right);
    default:return 0;
    }
  }

  template <typename context_t, typename ...Ts>
  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
  {
    unsigned int subtable_type = get_type ();
    TRACE_DISPATCH (this, subtable_type);
    switch (subtable_type) {
    case 0: return_trace (c->dispatch (u.format0));
#ifndef HB_NO_AAT_SHAPE
    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
#endif
    case 2: return_trace (c->dispatch (u.format2));
#ifndef HB_NO_AAT_SHAPE
    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
#endif
    default: return_trace (c->default_return_value ());
    }
  }

  template <typename set_t>
  void collect_glyphs (set_t &left_set, set_t &right_set, unsigned num_glyphs) const
  {
    unsigned int subtable_type = get_type ();
    switch (subtable_type) {
    case 0: u.format0.collect_glyphs (left_set, right_set, num_glyphs); return;
    case 1: u.format1.collect_glyphs (left_set, right_set, num_glyphs); return;
    case 2: u.format2.collect_glyphs (left_set, right_set, num_glyphs); return;
    case 3: u.format3.collect_glyphs (left_set, right_set, num_glyphs); return;
    defaultreturn;
    }
  }

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    if (unlikely (!(u.header.sanitize (c) &&
      hb_barrier () &&
      u.header.length >= u.header.min_size &&
      c->check_range (this, u.header.length)))) return_trace (false);

    return_trace (dispatch (c));
  }

  public:
  union {
  KernSubTableHeader    header;
  AAT::KerxSubTableFormat0<KernSubTableHeader> format0;
  AAT::KerxSubTableFormat1<KernSubTableHeader> format1;
  AAT::KerxSubTableFormat2<KernSubTableHeader> format2;
  KernSubTableFormat3<KernSubTableHeader> format3;
  } u;
  public:
  DEFINE_SIZE_MIN (KernSubTableHeader::static_size);
};


struct KernOTSubTableHeader
{
  static constexpr bool apple = false;
  typedef AAT::ObsoleteTypes Types;

  unsigned   tuple_count () const { return 0; }
  bool     is_horizontal () const { return (coverage & Horizontal); }

  enum Coverage
  {
    Horizontal = 0x01u,
    Minimum = 0x02u,
    CrossStream = 0x04u,
    Override = 0x08u,

    /* Not supported: */
    Backwards = 0x00u,
    Variation = 0x00u,
  };

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this));
  }

  public:
  HBUINT16 versionZ; /* Unused. */
  HBUINT16 length;  /* Length of the subtable (including this header). */
  HBUINT8 format;  /* Subtable format. */
  HBUINT8 coverage; /* Coverage bits. */
  public:
  DEFINE_SIZE_STATIC (6);
};

struct KernOT : AAT::KerxTable<KernOT>
{
  friend struct AAT::KerxTable<KernOT>;

  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
  static constexpr unsigned minVersion = 0u;

  typedef KernOTSubTableHeader SubTableHeader;
  typedef SubTableHeader::Types Types;
  typedef KernSubTable<SubTableHeader> SubTable;

  protected:
  HBUINT16 version; /* Version--0x0000u */
  HBUINT16 tableCount; /* Number of subtables in the kerning table. */
  SubTable firstSubTable; /* Subtables. */
  public:
  DEFINE_SIZE_MIN (4);
};


struct KernAATSubTableHeader
{
  static constexpr bool apple = true;
  typedef AAT::ObsoleteTypes Types;

  unsigned   tuple_count () const { return 0; }
  bool     is_horizontal () const { return !(coverage & Vertical); }

  enum Coverage
  {
    Vertical = 0x80u,
    CrossStream = 0x40u,
    Variation = 0x20u,

    /* Not supported: */
    Backwards = 0x00u,
  };

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    return_trace (c->check_struct (this));
  }

  public:
  HBUINT32 length;  /* Length of the subtable (including this header). */
  HBUINT8 coverage; /* Coverage bits. */
  HBUINT8 format;  /* Subtable format. */
  HBUINT16 tupleIndex; /* The tuple index (used for variations fonts).
 * This value specifies which tuple this subtable covers.
 * Note: We don't implement. */

  public:
  DEFINE_SIZE_STATIC (8);
};

struct KernAAT : AAT::KerxTable<KernAAT>
{
  friend struct AAT::KerxTable<KernAAT>;

  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;
  static constexpr unsigned minVersion = 0x00010000u;

  typedef KernAATSubTableHeader SubTableHeader;
  typedef SubTableHeader::Types Types;
  typedef KernSubTable<SubTableHeader> SubTable;

  protected:
  HBUINT32 version; /* Version--0x00010000u */
  HBUINT32 tableCount; /* Number of subtables in the kerning table. */
  SubTable firstSubTable; /* Subtables. */
  public:
  DEFINE_SIZE_MIN (8);
};

struct kern
{
  static constexpr hb_tag_t tableTag = HB_OT_TAG_kern;

  bool     has_data () const { return u.version32; }
  unsigned get_type () const { return u.major; }

  bool has_state_machine () const
  {
    switch (get_type ()) {
    case 0: hb_barrier (); return u.ot.has_state_machine ();
#ifndef HB_NO_AAT_SHAPE
    case 1: hb_barrier (); return u.aat.has_state_machine ();
#endif
    default:return false;
    }
  }

  bool has_cross_stream () const
  {
    switch (get_type ()) {
    case 0: hb_barrier (); return u.ot.has_cross_stream ();
#ifndef HB_NO_AAT_SHAPE
    case 1: hb_barrier (); return u.aat.has_cross_stream ();
#endif
    default:return false;
    }
  }

  int get_h_kerning (hb_codepoint_t left, hb_codepoint_t right) const
  {
    switch (get_type ()) {
    case 0: hb_barrier (); return u.ot.get_h_kerning (left, right);
#ifndef HB_NO_AAT_SHAPE
    case 1: hb_barrier (); return u.aat.get_h_kerning (left, right);
#endif
    default:return 0;
    }
  }

  bool apply (AAT::hb_aat_apply_context_t *c,
       const AAT::kern_accelerator_data_t *accel_data = nullptr) const
  { return dispatch (c, accel_data); }

  template <typename context_t, typename ...Ts>
  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
  {
    unsigned int subtable_type = get_type ();
    TRACE_DISPATCH (this, subtable_type);
    switch (subtable_type) {
    case 0: return_trace (c->dispatch (u.ot, std::forward<Ts> (ds)...));
#ifndef HB_NO_AAT_SHAPE
    case 1: return_trace (c->dispatch (u.aat, std::forward<Ts> (ds)...));
#endif
    default: return_trace (c->default_return_value ());
    }
  }

  bool sanitize (hb_sanitize_context_t *c) const
  {
    TRACE_SANITIZE (this);
    if (!u.version32.sanitize (c)) return_trace (false);
    hb_barrier ();
    return_trace (dispatch (c));
  }

  AAT::kern_accelerator_data_t create_accelerator_data (unsigned num_glyphs) const
  {
    switch (get_type ()) {
    case 0: hb_barrier (); return u.ot.create_accelerator_data (num_glyphs);
#ifndef HB_NO_AAT_SHAPE
    case 1: hb_barrier (); return u.aat.create_accelerator_data (num_glyphs);
#endif
    default:return AAT::kern_accelerator_data_t ();
    }
  }

  struct accelerator_t
  {
    accelerator_t (hb_face_t *face)
    {
      hb_sanitize_context_t sc;
      this->table = sc.reference_table<kern> (face);
      this->accel_data = this->table->create_accelerator_data (face->get_num_glyphs ());
    }
    ~accelerator_t ()
    {
      this->table.destroy ();
    }

    hb_blob_t *get_blob () const { return table.get_blob (); }

    bool apply (AAT::hb_aat_apply_context_t *c) const
    {
      return table->apply (c, &accel_data);
    }

    hb_blob_ptr_t<kern> table;
    AAT::kern_accelerator_data_t accel_data;
  };

  protected:
  union {
  HBUINT32  version32;
  HBUINT16  major;
  KernOT  ot;
#ifndef HB_NO_AAT_SHAPE
  KernAAT  aat;
#endif
  } u;
  public:
  DEFINE_SIZE_UNION (4, version32);
};

struct kern_accelerator_t : kern::accelerator_t {
  kern_accelerator_t (hb_face_t *face) : kern::accelerator_t (face) {}
};

/* namespace OT */


#endif /* HB_OT_KERN_TABLE_HH */

Messung V0.5
C=94 H=100 G=96

¤ Dauer der Verarbeitung: 0.1 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge