📄 pdfont.java
字号:
float retval = 0;
FontMetric metric = getAFM();
if( metric != null )
{
Encoding encoding = getEncoding();
COSName characterName = encoding.getName( code );
retval = metric.getCharacterWidth( characterName.getName() );
}
return retval;
}
/**
* This will attempt to get the average font width from an AFM file.
*
* @return The average font width from the AFM file.
*
* @throws IOException if we cannot find the width.
*/
protected float getAverageFontWidthFromAFMFile() throws IOException
{
float retval = 0;
FontMetric metric = getAFM();
if( metric != null )
{
retval = metric.getAverageCharacterWidth();
}
return retval;
}
/**
* This will get an AFM object if one exists.
*
* @return The afm object from the name.
*
* @throws IOException If there is an error getting the AFM object.
*/
protected FontMetric getAFM() throws IOException
{
COSName name = (COSName)font.getDictionaryObject( COSName.BASE_FONT );
FontMetric result = null;
if( name != null )
{
result = (FontMetric)afmObjects.get( name );
if( result == null )
{
String resource = (String)afmResources.get( name );
if( resource == null )
{
//ok for now
//throw new IOException( "Unknown AFM font '" + name.getName() + "'" );
}
else
{
InputStream afmStream = ResourceLoader.loadResource( resource );
if( afmStream == null )
{
throw new IOException( "Can't handle font width:" + resource );
}
AFMParser parser = new AFMParser( afmStream );
parser.parse();
result = parser.getResult();
afmObjects.put( name, result );
}
}
}
return result;
}
/**
* This will perform the encoding of a character if needed.
*
* @param c The character to encode.
* @param offset The offset into the array to get the data
* @param length The number of bytes to read.
*
* @return The value of the encoded character.
*
* @throws IOException If there is an error during the encoding.
*/
public String encode( byte[] c, int offset, int length ) throws IOException
{
String retval = null;
COSName fontSubtype = (COSName)font.getDictionaryObject( COSName.SUBTYPE );
String fontSubtypeName = fontSubtype.getName();
if( fontSubtypeName.equals( "Type0" ) ||
fontSubtypeName.equals( "Type1" ) ||
fontSubtypeName.equals( "TrueType" ))
{
if( cmap == null )
{
if( font.getDictionaryObject( COSName.TO_UNICODE ) != null )
{
COSStream toUnicode = (COSStream)font.getDictionaryObject( COSName.TO_UNICODE );
if( toUnicode != null )
{
parseCmap( toUnicode.getUnfilteredStream(), null );
}
}
else
{
COSBase encoding = font.getDictionaryObject( COSName.ENCODING );
if( encoding instanceof COSStream )
{
COSStream encodingStream = (COSStream)encoding;
parseCmap( encodingStream.getUnfilteredStream(), null );
}
else if( fontSubtypeName.equals( "Type0" ) &&
encoding instanceof COSName )
{
COSName encodingName = (COSName)encoding;
cmap = (CMap)cmapObjects.get( encodingName );
if( cmap != null )
{
cmap = (CMap)cmapObjects.get( encodingName );
}
else
{
String cmapName = encodingName.getName();
cmapName = performCMAPSubstitution( cmapName );
String resourceName = "Resources/cmap/" + cmapName;
parseCmap( ResourceLoader.loadResource( resourceName ), encodingName );
if( cmap == null && !encodingName.getName().equals( COSName.IDENTITY_H.getName() ) )
{
throw new IOException( "Error: Could not find predefined " +
"CMAP file for '" + encodingName.getName() + "'" );
}
}
}
else if( encoding instanceof COSName ||
encoding instanceof COSDictionary )
{
Encoding currentFontEncoding = getEncoding();
if( currentFontEncoding != null )
{
retval = currentFontEncoding.getCharacter( getCodeFromArray( c, offset, length ) );
}
}
else
{
COSDictionary fontDescriptor =
(COSDictionary)font.getDictionaryObject( COSName.FONT_DESC );
if( fontSubtypeName.equals( "TrueType" ) &&
fontDescriptor != null &&
(fontDescriptor.getDictionaryObject( COSName.FONT_FILE )!= null ||
fontDescriptor.getDictionaryObject( COSName.FONT_FILE2 ) != null ||
fontDescriptor.getDictionaryObject( COSName.FONT_FILE3 ) != null ) )
{
//If we are using an embedded font then there is not much we can do besides
//return the same character codes.
//retval = new String( c,offset, length );
retval = getStringFromArray( c, offset, length );
}
else
{
//this case will be handled below after checking the cmap
}
}
}
}
}
if( retval == null && cmap != null )
{
retval = cmap.lookup( c, offset, length );
}
//if we havn't found a value yet and
//we are still on the first byte and
//there is no cmap or the cmap does not have 2 byte mappings then try to encode
//using fallback methods.
if( retval == null &&
length == 1 &&
(cmap == null || !cmap.hasTwoByteMappings()))
{
Encoding encoding = getEncoding();
if( encoding != null )
{
retval = encoding.getCharacter( getCodeFromArray( c, offset, length ) );
}
if( retval == null )
{
retval = getStringFromArray( c, offset, length );
}
}
return retval;
}
private static final String[] SINGLE_CHAR_STRING = new String[256];
private static final String[][] DOUBLE_CHAR_STRING = new String[256][256];
static
{
for( int i=0; i<256; i++ )
{
SINGLE_CHAR_STRING[i] = new String( new byte[] {(byte)i} );
for( int j=0; j<256; j++ )
{
DOUBLE_CHAR_STRING[i][j] = new String( new byte[] {(byte)i, (byte)j} );
}
}
}
private static String getStringFromArray( byte[] c, int offset, int length ) throws IOException
{
String retval = null;
if( length == 1 )
{
retval = SINGLE_CHAR_STRING[(c[offset]+256)%256];
}
else if( length == 2 )
{
retval = DOUBLE_CHAR_STRING[(c[offset]+256)%256][(c[offset+1]+256)%256];
}
else
{
throw new IOException( "Error:Unknown character length:" + length );
}
return retval;
}
/**
* Some cmap names are synonyms for other CMAPs. If that is the case
* then this method will perform that substitution.
*
* @param cmapName The name of the cmap to attempt to look up.
*
* @return Either the original name or the substituted name.
*/
private String performCMAPSubstitution( String cmapName )
{
String retval = (String)cmapSubstitutions.get( cmapName );
if( retval == null )
{
//if there is no substitution then just return the same value.
retval = cmapName;
}
return retval;
}
private void parseCmap( InputStream cmapStream, COSName encodingName ) throws IOException
{
if( cmapStream != null )
{
CMapParser parser = new CMapParser();
cmap = parser.parse( cmapStream );
if( encodingName != null )
{
cmapObjects.put( encodingName, cmap );
}
}
}
/**
* The will set the encoding for this font.
*
* @param enc The font encoding.
*/
public void setEncoding( Encoding enc )
{
font.setItem( COSName.ENCODING, enc );
fontEncoding = enc;
}
/**
* This will get or create the encoder.
*
* modified by Christophe Huault : DGBS Strasbourg huault@free.fr october 2004
*
* @return The encoding to use.
*
* @throws IOException If there is an error getting the encoding.
*/
public Encoding getEncoding() throws IOException
{
EncodingManager manager = new EncodingManager();
if( fontEncoding == null )
{
COSBase encoding = font.getDictionaryObject( COSName.ENCODING );
if( encoding == null )
{
FontMetric metric = getAFM();
if( metric != null )
{
fontEncoding = new AFMEncoding( metric );
}
if( fontEncoding == null )
{
fontEncoding = manager.getStandardEncoding();
}
}
/**
* Si la cl
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -