Home » pdfbox-1.1.0-src » org.apache.fontbox.ttf » [javadoc | source]

    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one or more
    3    * contributor license agreements.  See the NOTICE file distributed with
    4    * this work for additional information regarding copyright ownership.
    5    * The ASF licenses this file to You under the Apache License, Version 2.0
    6    * (the "License"); you may not use this file except in compliance with
    7    * the License.  You may obtain a copy of the License at
    8    *
    9    *      http://www.apache.org/licenses/LICENSE-2.0
   10    *
   11    * Unless required by applicable law or agreed to in writing, software
   12    * distributed under the License is distributed on an "AS IS" BASIS,
   13    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   14    * See the License for the specific language governing permissions and
   15    * limitations under the License.
   16    */
   17   package org.apache.fontbox.ttf;
   18   
   19   import java.io.IOException;
   20   
   21   /**
   22    * An encoding entry for a cmap.
   23    * 
   24    * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
   25    * @version $Revision: 1.2 $
   26    */
   27   public class CMAPEncodingEntry
   28   {
   29   
   30       private int platformId;
   31       private int platformEncodingId;
   32       private long subTableOffset;
   33       private int[] glyphIdToCharacterCode;
   34       /**
   35        * This will read the required data from the stream.
   36        * 
   37        * @param ttf The font that is being read.
   38        * @param data The stream to read the data from.
   39        * @throws IOException If there is an error reading the data.
   40        */
   41       public void initData( TrueTypeFont ttf, TTFDataStream data ) throws IOException
   42       {
   43           platformId = data.readUnsignedShort();
   44           platformEncodingId = data.readUnsignedShort();
   45           subTableOffset = data.readUnsignedInt();
   46       }
   47       
   48       /**
   49        * This will read the required data from the stream.
   50        * 
   51        * @param ttf The font that is being read.
   52        * @param data The stream to read the data from.
   53        * @throws IOException If there is an error reading the data.
   54        */
   55       public void initSubtable( TrueTypeFont ttf, TTFDataStream data ) throws IOException
   56       {
   57           data.seek( ttf.getCMAP().getOffset() + subTableOffset );
   58           int subtableFormat = data.readUnsignedShort();
   59           int length = data.readUnsignedShort();
   60           int version = data.readUnsignedShort();
   61           int numGlyphs = ttf.getMaximumProfile().getNumGlyphs();
   62           if( subtableFormat == 0 )
   63           {
   64               byte[] glyphMapping = data.read( 256 );
   65               glyphIdToCharacterCode = new int[256];
   66               for( int i=0;i<glyphMapping.length; i++ )
   67               {
   68                   glyphIdToCharacterCode[i]=(glyphMapping[i]+256)%256;
   69               }
   70           }
   71           else if( subtableFormat == 2 )
   72           {
   73               int[] subHeaderKeys = new int[256];
   74               for( int i=0; i<256; i++)
   75               {
   76                   subHeaderKeys[i] = data.readUnsignedShort();
   77               }
   78               int firstCode = data.readUnsignedShort();
   79               int entryCount = data.readUnsignedShort();
   80               short idDelta = data.readSignedShort();
   81               int idRangeOffset = data.readUnsignedShort();
   82               //BJL
   83               //HMM the TTF spec is not very clear about what is suppose to
   84               //happen here.  If you know please submit a patch or point
   85               //me to some better documentation.
   86               throw new IOException( "Not yet implemented:" + subtableFormat );
   87           }
   88           else if( subtableFormat == 4 )
   89           {
   90               int segCountX2 = data.readUnsignedShort();
   91               int segCount = segCountX2/2;
   92               int searchRange = data.readUnsignedShort();
   93               int entrySelector = data.readUnsignedShort();
   94               int rangeShift = data.readUnsignedShort();
   95               int[] endCount = data.readUnsignedShortArray( segCount );
   96               int reservedPad = data.readUnsignedShort();
   97               int[] startCount = data.readUnsignedShortArray( segCount );
   98               int[] idDelta = data.readUnsignedShortArray( segCount );
   99               int[] idRangeOffset = data.readUnsignedShortArray( segCount );
  100               
  101               //this is the final result
  102               //key=glyphId, value is character codes
  103               glyphIdToCharacterCode = new int[numGlyphs];
  104               
  105               long currentPosition = data.getCurrentPosition();
  106               
  107               for( int i=0; i<segCount; i++ )
  108               {
  109                   int start = startCount[i];
  110                   int end = endCount[i];
  111                   int delta = idDelta[i];
  112                   int rangeOffset = idRangeOffset[i];
  113                   if( start != 65535 && end != 65535 )
  114                   {
  115                       for( int j=start; j<=end; j++ )
  116                       {
  117                           if( rangeOffset == 0 )
  118                           {
  119                               glyphIdToCharacterCode[ ((j+delta)%65536) ]=j;
  120                           }
  121                           else
  122                           {
  123                               long glyphOffset = currentPosition +
  124                                   ((rangeOffset/2) + //idRangeOffset[i]/2 
  125                                   (j-start) + //(c - startCount[i])                                   
  126                                   (i-segCount))*2; //&idRangeOffset[i]); 
  127                               data.seek( glyphOffset );
  128                               int glyphIndex = data.readUnsignedShort();
  129                               if( glyphIndex != 0 )
  130                               {
  131                                   glyphIndex += delta;
  132                                   glyphIndex = glyphIndex % 65536;
  133                                   if( glyphIdToCharacterCode[glyphIndex] == 0 )
  134                                   {
  135                                       glyphIdToCharacterCode[glyphIndex] = j;
  136                                   }
  137                               }
  138                               
  139                           }
  140                       }
  141                   }
  142               }
  143           }
  144           else if( subtableFormat == 6 )
  145           {
  146               int firstCode = data.readUnsignedShort();
  147               int entryCount = data.readUnsignedShort();
  148               glyphIdToCharacterCode = new int[numGlyphs];
  149               int[] glyphIdArray = data.readUnsignedShortArray( entryCount );
  150               for( int i=0; i<entryCount; i++)
  151               {
  152                   glyphIdToCharacterCode[glyphIdArray[i]] = firstCode+i;
  153               }
  154           }
  155           else
  156           {
  157               throw new IOException( "Unknown cmap format:" + subtableFormat );
  158           }
  159       }
  160       
  161   
  162       /**
  163        * @return Returns the glyphIdToCharacterCode.
  164        */
  165       public int[] getGlyphIdToCharacterCode()
  166       {
  167           return glyphIdToCharacterCode;
  168       }
  169       /**
  170        * @param glyphIdToCharacterCodeValue The glyphIdToCharacterCode to set.
  171        */
  172       public void setGlyphIdToCharacterCode(int[] glyphIdToCharacterCodeValue)
  173       {
  174           this.glyphIdToCharacterCode = glyphIdToCharacterCodeValue;
  175       }
  176       
  177       /**
  178        * @return Returns the platformEncodingId.
  179        */
  180       public int getPlatformEncodingId()
  181       {
  182           return platformEncodingId;
  183       }
  184       /**
  185        * @param platformEncodingIdValue The platformEncodingId to set.
  186        */
  187       public void setPlatformEncodingId(int platformEncodingIdValue)
  188       {
  189           this.platformEncodingId = platformEncodingIdValue;
  190       }
  191       /**
  192        * @return Returns the platformId.
  193        */
  194       public int getPlatformId()
  195       {
  196           return platformId;
  197       }
  198       /**
  199        * @param platformIdValue The platformId to set.
  200        */
  201       public void setPlatformId(int platformIdValue)
  202       {
  203           this.platformId = platformIdValue;
  204       }
  205   }

Home » pdfbox-1.1.0-src » org.apache.fontbox.ttf » [javadoc | source]