(*******************************************************************
 *
 *  ttcmap.pas                                                   1.0
 *
 *    Character Mappings unit.
 *
 *  Copyright 1996, 1997 by
 *  David Turner, Robert Wilhelm, and Werner Lemberg.
 *
 *  This file is part of the FreeType project, and may only be used
 *  modified and distributed under the terms of the FreeType project
 *  license, LICENSE.TXT. By continuing to use, modify or distribute
 *  this file you indicate that you have read the license and
 *  understand and accept it fully.
 *
 ******************************************************************)

unit TTCMap;

interface

uses FreeType, TTTypes;

type
  (********************************************************************)
  (*                                                                  *)
  (*  CHARACTER MAPPINGS SUBTABLES                                    *)
  (*                                                                  *)
  (********************************************************************)

  (* FORMAT 0 *)

  (* Apple standard character to glyph index mapping table *)
  (* the glyphIdArray for this format has 256 entries      *)

  TCMap0 = record
             glyphIdArray : PUShort;
           end;

  (* FORMAT 2 *)

  (* the format 2 table contains a variable-length array of subHeaders   *)
  (* (at most 256 entries) whose size must be determined algorithmically *)
  TCMap2SubHeader = record
                      firstCode     : UShort; (* first valid low byte       *)
                      entryCount    : UShort; (* number of valid low bytes  *)
                      idDelta       : Short;  (* delta value to glyphIndex  *)
                      idRangeOffset : UShort; (* offset fr. here to 1stCode *)
                    end;

  TCMap2SubHeaders = array[0..100] of TCMap2SubHeader;
  PCMap2SubHeaders = ^TCMap2SubHeaders;

  (* Format 2 is used for mixed 8/16bit encodings (usually CJK fonts) *)
  TCMap2 = record
             subHeaderKeys : PUShort;
             (* high byte mapping table            *)
             (* value = subHeader index * 8        *)
             subHeaders    : PCMap2SubHeaders;
             glyphIdArray  : PUShort;
           end;

  (* FORMAT 4 *)

  (*The format 4 table contains segCount segments *)
  TCMap4Segment = record
                    endCount      : UShort;
                    startCount    : UShort;
                    idDelta       : UShort;
                    idRangeOffset : UShort;
                  end;
  TCMap4Segments = array[0..100] of TCMap4Segment;
  PCMap4Segments = ^TCMap4Segments;

  (* Microsoft standard character to glyph index mapping table *)
  TCMap4 = record
             segCountX2    : UShort;  (* segments number * 2          *)
             searchRange   : UShort;  (* these parameters can be used *)
             entrySelector : UShort;  (* for a binary search          *)
             rangeShift    : UShort;
             segments      : PCMap4Segments;
             glyphIdArray  : PUShort;
           end;

  (* FORMAT 6 *)

  (* trimmed table mapping (for representing one subrange) *)
  TCMap6 = record
             firstCode    : UShort; (* first character code of subrange    *)
             entryCount   : UShort; (* num. of character codes in subrange *)

             glyphIdArray : PUShort;
           end;

  (* CHARMAP TABLE *)

  PCMapTable = ^TCMapTable;
  TCMapTable = record
                 platformID         : UShort;
                 platformEncodingID : UShort;

                 Format  : word;
                 Length  : word;
                 Version : word;
                 Loaded  : Boolean;
                 Offset  : Long;

                 case Byte of
                   0 : ( cmap0 : TCMap0 );
                   2 : ( cmap2 : TCMap2 );
                   4 : ( cmap4 : TCMap4 );
                   6 : ( cmap6 : TCMap6 );
               end;

  TCMapTables = array[0..9] of TCMapTable;
  PCMapTables = ^TCMapTables;

 procedure CharMap_Free( var cmap : TCMapTable );

implementation

uses
  TTMemory;

 procedure CharMap_Free( var cmap : TCMapTable );
 begin
   with cmap do
     case format of

       0 : begin
             Free( cmap.cmap0.glyphIdArray );
           end;

       2 : begin
             Free( cmap.cmap2.glyphIdArray );
             Free( cmap.cmap2.subHeaders );
             Free( cmap.cmap2.glyphIdArray );
           end;

       4 : begin
             Free( cmap.cmap4.segments );
             Free( cmap.cmap4.glyphIdArray );
             cmap.cmap4.segCountX2 := 0;
           end;

       6 : begin
             Free( cmap.cmap6.glyphIdArray );
             cmap.cmap6.entryCount := 0;
           end;
     end;

   cmap.loaded  := False;
   cmap.format  := 0;
   cmap.length  := 0;
   cmap.version := 0;
 end;

end.
