Eine aufbereitete Darstellung der Quelle

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

Benutzer

Quelle  hb-subset-cff2-to-cff1.hh   Sprache: C

 

/*
 * Copyright © 2026 Behdad Esfahbod
 *
 *  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.
 */


#ifndef HB_SUBSET_CFF2_TO_CFF1_HH
#define HB_SUBSET_CFF2_TO_CFF1_HH

#include "hb.hh"

#ifndef HB_NO_SUBSET_CFF

#include "hb-ot-cff1-table.hh"
#include "hb-ot-cff2-table.hh"
#include "hb-subset-cff-common.hh"

namespace OT {
  // Forward declarations - these are defined in hb-subset-cff2.cc
  struct cff2_subset_plan;
}

namespace CFF {

// Forward declaration
struct cff2_top_dict_values_t;

// Default font name for converted CFF1 fonts
static constexpr const char CFF1_DEFAULT_FONT_NAME[] = "CFF1Font";

/*
 * CFF2 to CFF1 Converter
 *
 * Converts an instantiated (pinned) CFF2 variable font to CFF1 format.
 * This is used when instantiating a variable font to a static instance.
 *
 * IMPLEMENTATION STATUS:
 * ✓ CFF1 structure (Header, Name INDEX, String INDEX, Top DICT INDEX)
 * ✓ ROS operator (makes font CID-keyed: "Adobe-Identity-0")
 * ✓ FDArray and FDSelect in Top DICT (required for CID fonts)
 * ✓ FDSelect3 format (compact range-based, 8 bytes for single-FD fonts)
 * ✓ CID Charset with identity mapping (format 2)
 * ✓ FontBBox from head table (xMin, yMin, xMax, yMax)
 * ✓ Width optimization (defaultWidthX/nominalWidthX with O(n) algorithm)
 * ✓ Width encoding in CharStrings (prepended if != defaultWidthX)
 * ✓ CharString specialization (h/v operators, combined when possible)
 * ✓ Stack depth control (generalize→specialize with maxstack=48)
 * ✓ CharStrings with endchar operators (CFF1 requires, CFF2 doesn't)
 * ✓ Private DICT instantiation (blend operators evaluated)
 * ✓ Desubroutinized path (CharStrings are flattened, no subroutines)
 * ✓ OTS validation passes
 * ✓ HarfBuzz rendering works
 *
 * FUTURE ENHANCEMENTS:
 * - Curve operator specialization (hhcurveto, vvcurveto, etc.)
 * - Peephole optimization (minor additional size savings)
 *
 * Key conversions:
 * - Version: 2 -> 1
 * - Add Name INDEX (required in CFF1)
 * - Wrap Top DICT in an INDEX (inline in CFF2, indexed in CFF1)
 * - Add String INDEX ("Adobe", "Identity" for ROS operator)
 * - Add ROS operator to Top DICT (makes it CID-keyed)
 * - Add FDSelect to Top DICT (required in CFF1 even with single FD)
 * - Add endchar to CharStrings (required in CFF1, optional in CFF2)
 */


struct cff1_subset_plan_from_cff2_t
{
  // Inherits most data from cff2_subset_plan
  const OT::cff2_subset_plan *cff2_plan;

  // CFF1-specific additions
  hb_vector_t<unsigned char> fontName;  // Single font name for Name INDEX

  bool create (const OT::cff2_subset_plan &cff2_plan_)
  {
    cff2_plan = &cff2_plan_;

    // Create a simple font name (CFF1 requires a Name INDEX)
    fontName.resize (strlen (CFF1_DEFAULT_FONT_NAME));
    if (fontName.in_error ()) return false;
    memcpy (fontName.arrayZ, CFF1_DEFAULT_FONT_NAME, strlen (CFF1_DEFAULT_FONT_NAME));

    return true;
  }
};

/* CFF1 Top DICT operator serializer that adds ROS and removes CFF2-specific ops */
struct cff1_from_cff2_top_dict_op_serializer_t : cff_top_dict_op_serializer_t<>
{
  bool serialize (hb_serialize_context_t *c,
                  const op_str_t &opstr,
                  const cff_sub_table_info_t &info) const
  {
    TRACE_SERIALIZE (this);

    switch (opstr.op)
    {
      case OpCode_vstore:
        // CFF2-only operator, skip it
        return_trace (true);

      case OpCode_CharStrings:
        return_trace (FontDict::serialize_link4_op(c, opstr.op, info.char_strings_link, whence_t::Absolute));

      case OpCode_FDArray:
      case OpCode_FDSelect:
        // These are explicitly serialized in the main function to ensure they're present
        // even if CFF2 doesn't have them. Skip them here to avoid duplication.
        return_trace (true);

      default:
        return_trace (copy_opstr (c, opstr));
    }
  }

  // Serialize ROS operator to make this a CID-keyed font
  bool serialize_ros (hb_serialize_context_t *c) const
  {
    TRACE_SERIALIZE (this);

    // ROS = Registry-Ordering-Supplement
    // We use "Adobe", "Identity", 0 for maximum compatibility

    // Allocate space and encode directly
    // Registry: SID for "Adobe" (custom string at index 0 = SID 391)
    // Ordering: SID for "Identity" (custom string at index 1 = SID 392)
    // Supplement: 0
    // Note: CFF standard strings end at SID 390, custom strings start at 391

    str_buff_t buff;
    str_encoder_t encoder (buff);

    encoder.encode_int (391);  // Registry SID ("Adobe" in our String INDEX)
    encoder.encode_int (392);  // Ordering SID ("Identity" in our String INDEX)
    encoder.encode_int (0);    // Supplement
    encoder.encode_op (OpCode_ROS);

    if (encoder.in_error ())
      return_trace (false);

    auto bytes = buff.as_bytes ();
    return_trace (c->embed (bytes.arrayZ, bytes.length));
  }
};

/* Main serialization function */
HB_INTERNAL bool
serialize_cff2_to_cff1 (hb_serialize_context_t *c,
                        OT::cff2_subset_plan &plan,
                        const cff2_top_dict_values_t &cff2_topDict,
                        const OT::cff2::accelerator_subset_t &acc);

} /* namespace CFF */

#endif /* HB_NO_SUBSET_CFF */

#endif /* HB_SUBSET_CFF2_TO_CFF1_HH */

Messung V0.5 in Prozent
C=89 H=86 G=87

¤ Dauer der Verarbeitung: 0.22 Sekunden  (vorverarbeitet am  2026-09-28) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

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

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=1126438
#Domains=1897691