FreeType 1.31.1
This commit is contained in:
347
lib/extend/ftxcmap.c
Normal file
347
lib/extend/ftxcmap.c
Normal file
@@ -0,0 +1,347 @@
|
||||
/*******************************************************************
|
||||
*
|
||||
* ftxcmap.h 1.0
|
||||
*
|
||||
* API extension for iterating over Cmaps
|
||||
*
|
||||
* Copyright 1996-1999 by Juliusz Chroboczek,
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
#include "ftxcmap.h"
|
||||
|
||||
#include "tttypes.h"
|
||||
#include "ttobjs.h"
|
||||
#include "tttables.h"
|
||||
|
||||
static Long charmap_first4 ( PCMap4, UShort* );
|
||||
static Long charmap_next4 ( PCMap4, UShort, UShort* );
|
||||
static Long charmap_last4 ( PCMap4, UShort* );
|
||||
static UShort charmap_find_id4( PCMap4, UShort, TCMap4Segment*, UShort );
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* Function : TT_CharMap_First
|
||||
*
|
||||
* Description : Returns the first valid character code in a
|
||||
* given character map. Also returns the corresponding
|
||||
* glyph index.
|
||||
*
|
||||
* Input : charMap handle to the target character map
|
||||
* id address where the glyph index will be
|
||||
* be returned in case of success
|
||||
*
|
||||
* Output : First valid character code. -1 in case of failure.
|
||||
*
|
||||
* Notes :
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
EXPORT_FUNC
|
||||
TT_Long TT_CharMap_First( TT_CharMap charMap,
|
||||
TT_UShort* id )
|
||||
{
|
||||
PCMapTable cmap;
|
||||
UShort i, c;
|
||||
|
||||
|
||||
if ( !( cmap = HANDLE_CharMap( charMap ) ) )
|
||||
return -1;
|
||||
|
||||
switch ( cmap->format )
|
||||
{
|
||||
case 0:
|
||||
if ( id )
|
||||
*id = cmap->c.cmap0.glyphIdArray[0];
|
||||
return 0;
|
||||
|
||||
case 4:
|
||||
return charmap_first4( &cmap->c.cmap4, id );
|
||||
|
||||
case 6:
|
||||
if ( cmap->c.cmap6.entryCount < 1 )
|
||||
return -1;
|
||||
|
||||
if ( id )
|
||||
*id = cmap->c.cmap6.glyphIdArray[0];
|
||||
return cmap->c.cmap6.firstCode;
|
||||
|
||||
default:
|
||||
/* Now loop from 0 to 65535. We can't use a simple "for' on */
|
||||
/* 16-bits systems, hence the "strange" loop here.. */
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
c = TT_Char_Index( charMap, i );
|
||||
if ( c > 0 )
|
||||
{
|
||||
if ( id )
|
||||
*id = c;
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
} while ( i != 0 ); /* because i is UShort! */
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Long charmap_first4( PCMap4 cmap4,
|
||||
UShort* id )
|
||||
{
|
||||
UShort firstCode;
|
||||
|
||||
|
||||
if ( cmap4->segCountX2 / 2 < 1 )
|
||||
return -1;
|
||||
|
||||
firstCode = cmap4->segments[0].startCount;
|
||||
|
||||
if ( id )
|
||||
*id = charmap_find_id4( cmap4, firstCode, &(cmap4->segments[0]), 0 );
|
||||
|
||||
return firstCode;
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* Function : TT_CharMap_Next
|
||||
*
|
||||
* Description : Returns the next valid character code in a given
|
||||
* charMap.
|
||||
*
|
||||
* Input : charMap handle to the target char. map
|
||||
* index starting character code
|
||||
* id address where the glyph index of the next
|
||||
* character will be returned
|
||||
*
|
||||
* Output : Next valid character code after 'index'. -1 in case
|
||||
* of failure.
|
||||
*
|
||||
* Notes :
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
EXPORT_FUNC
|
||||
TT_Long TT_CharMap_Next( TT_CharMap charMap,
|
||||
TT_UShort index,
|
||||
TT_UShort* id )
|
||||
{
|
||||
PCMapTable cmap;
|
||||
UShort i, c;
|
||||
|
||||
|
||||
cmap = HANDLE_CharMap( charMap );
|
||||
if ( !cmap )
|
||||
return -1;
|
||||
|
||||
switch ( cmap->format )
|
||||
{
|
||||
case 0:
|
||||
if ( index < 255 )
|
||||
{
|
||||
if ( id )
|
||||
*id = cmap->c.cmap0.glyphIdArray[index + 1];
|
||||
return index + 1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
|
||||
case 4:
|
||||
return charmap_next4( &cmap->c.cmap4, index, id );
|
||||
|
||||
case 6:
|
||||
{
|
||||
UShort firstCode = cmap->c.cmap6.firstCode;
|
||||
|
||||
|
||||
if ( index + 1 < firstCode + cmap->c.cmap6.entryCount )
|
||||
{
|
||||
if ( id )
|
||||
*id = cmap->c.cmap6.glyphIdArray[index + 1 - firstCode];
|
||||
return index + 1;
|
||||
}
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
|
||||
default:
|
||||
/* Now loop from 0 to 65535. We can't use a simple "for" on */
|
||||
/* 16-bits systems, hence the "strange" loop here.. */
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
c = TT_Char_Index( charMap, i );
|
||||
if ( c > 0 )
|
||||
{
|
||||
if ( id )
|
||||
*id = c;
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
} while ( i != 0 ); /* because i is UShort! */
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Long charmap_next4( PCMap4 cmap4,
|
||||
UShort charCode,
|
||||
UShort* id)
|
||||
{
|
||||
UShort segCount, nextCode;
|
||||
UShort i;
|
||||
TCMap4Segment seg4;
|
||||
|
||||
|
||||
if ( charCode == 0xFFFF )
|
||||
return -1; /* get it out of the way now */
|
||||
|
||||
segCount = cmap4->segCountX2 / 2;
|
||||
|
||||
for ( i = 0; i < segCount; i++ )
|
||||
if ( charCode < cmap4->segments[i].endCount )
|
||||
break;
|
||||
|
||||
/* Safety check - even though the last endCount should be 0xFFFF */
|
||||
if ( i >= segCount )
|
||||
return -1;
|
||||
|
||||
seg4 = cmap4->segments[i];
|
||||
|
||||
if ( charCode < seg4.startCount )
|
||||
nextCode = seg4.startCount;
|
||||
else
|
||||
nextCode = charCode + 1;
|
||||
|
||||
if ( id )
|
||||
*id = charmap_find_id4( cmap4, nextCode, &seg4, i );
|
||||
|
||||
return nextCode;
|
||||
}
|
||||
|
||||
|
||||
static UShort
|
||||
charmap_find_id4( PCMap4 cmap4,
|
||||
UShort charCode,
|
||||
TCMap4Segment* seg4,
|
||||
UShort i )
|
||||
{
|
||||
UShort index1;
|
||||
|
||||
|
||||
if ( seg4->idRangeOffset == 0 )
|
||||
return (charCode + seg4->idDelta) & 0xFFFF;
|
||||
else
|
||||
{
|
||||
index1 = seg4->idRangeOffset / 2 + charCode-seg4->startCount -
|
||||
( cmap4->segCountX2 / 2 - i );
|
||||
|
||||
if ( index1 >= cmap4->numGlyphId || cmap4->glyphIdArray[index1] == 0 )
|
||||
return 0;
|
||||
else
|
||||
return (cmap4->glyphIdArray[index1] + seg4->idDelta) & 0xFFFF;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*******************************************************************
|
||||
*
|
||||
* Function : TT_CharMap_Last
|
||||
*
|
||||
* Description : Returns the last valid character code in a
|
||||
* given character map. Also returns the corresponding
|
||||
* glyph index.
|
||||
*
|
||||
* Input : charMap handle to the target character map
|
||||
* id address where the glyph index will be
|
||||
* be returned in case of success
|
||||
*
|
||||
* Output : Last valid character code. -1 in case of failure.
|
||||
*
|
||||
* Notes :
|
||||
*
|
||||
******************************************************************/
|
||||
|
||||
EXPORT_FUNC
|
||||
TT_Long TT_CharMap_Last( TT_CharMap charMap,
|
||||
TT_UShort* id )
|
||||
{
|
||||
PCMapTable cmap;
|
||||
UShort i, c;
|
||||
|
||||
|
||||
if ( !( cmap = HANDLE_CharMap( charMap ) ) )
|
||||
return -1;
|
||||
|
||||
switch ( cmap->format )
|
||||
{
|
||||
case 0:
|
||||
if ( id )
|
||||
*id = cmap->c.cmap0.glyphIdArray[255];
|
||||
return 255;
|
||||
|
||||
case 4:
|
||||
return charmap_last4( &cmap->c.cmap4, id );
|
||||
|
||||
case 6:
|
||||
if ( cmap->c.cmap6.entryCount < 1 )
|
||||
return -1;
|
||||
|
||||
if ( id )
|
||||
*id = cmap->c.cmap6.glyphIdArray[cmap->c.cmap6.entryCount - 1];
|
||||
return cmap->c.cmap6.firstCode + cmap->c.cmap6.entryCount - 1;
|
||||
|
||||
default:
|
||||
i = 65535;
|
||||
do
|
||||
{
|
||||
c = TT_Char_Index( charMap, i );
|
||||
if ( c > 0 )
|
||||
{
|
||||
if ( id )
|
||||
*id = c;
|
||||
return i;
|
||||
}
|
||||
i--;
|
||||
} while ( i != 0 );
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static Long charmap_last4( PCMap4 cmap4,
|
||||
UShort* id )
|
||||
{
|
||||
UShort lastCode;
|
||||
|
||||
|
||||
if ( cmap4->segCountX2 / 2 < 1 )
|
||||
return -1;
|
||||
|
||||
lastCode = cmap4->segments[cmap4->segCountX2 / 2 - 1].endCount;
|
||||
|
||||
if ( id )
|
||||
*id = charmap_find_id4( cmap4,
|
||||
lastCode,
|
||||
&(cmap4->segments[cmap4->segCountX2 / 2 - 1]),
|
||||
0 );
|
||||
|
||||
return lastCode;
|
||||
}
|
||||
|
||||
|
||||
/* END */
|
||||
Reference in New Issue
Block a user