Save This Page
Home » pdfbox-1.1.0-src » org.apache.fontbox.cff » [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.cff;
   18   
   19   import java.awt.geom.Rectangle2D;
   20   import java.io.IOException;
   21   import java.util.ArrayList;
   22   import java.util.Collection;
   23   import java.util.Collections;
   24   import java.util.List;
   25   
   26   import org.apache.fontbox.cff.encoding.CFFEncoding;
   27   
   28   /**
   29    * This class creates all needed AFM font metric data from a CFFFont ready to be read from a AFMPaser.
   30    * 
   31    * @author Villu Ruusmann
   32    * @version $Revision$
   33    */
   34   public class AFMFormatter
   35   {
   36   
   37       private AFMFormatter()
   38       {
   39       }
   40   
   41       /**
   42        * Create font metric data for the given CFFFont.
   43        * @param font the CFFFont
   44        * @return the created font metric data
   45        * @throws IOException if an error occurs during reading
   46        */
   47       public static byte[] format(CFFFont font) throws IOException
   48       {
   49           DataOutput output = new DataOutput();
   50           printFont(font, output);
   51           return output.getBytes();
   52       }
   53   
   54       private static void printFont(CFFFont font, DataOutput output)
   55               throws IOException
   56       {
   57           printFontMetrics(font, output);
   58       }
   59   
   60       @SuppressWarnings(value = { "unchecked" })
   61       private static void printFontMetrics(CFFFont font, DataOutput output)
   62               throws IOException
   63       {
   64           List<CharMetric> metrics = renderFont(font);
   65           output.println("StartFontMetrics 2.0");
   66           output.println("FontName " + font.getName());
   67           output.println("FullName " + font.getProperty("FullName"));
   68           output.println("FamilyName " + font.getProperty("FamilyName"));
   69           output.println("Weight " + font.getProperty("Weight"));
   70           CFFEncoding encoding = font.getEncoding();
   71           if (encoding.isFontSpecific())
   72           {
   73               output.println("EncodingScheme FontSpecific");
   74           }
   75           Rectangle2D bounds = getBounds(metrics);
   76           output.println("FontBBox " + (int)bounds.getX() + " " + (int)bounds.getY()
   77                   + " " + (int)bounds.getMaxX() + " " + (int)bounds.getMaxY());
   78           printDirectionMetrics(font, output);
   79           printCharMetrics(font, metrics, output);
   80           output.println("EndFontMetrics");
   81       }
   82   
   83       private static void printDirectionMetrics(CFFFont font, DataOutput output)
   84               throws IOException
   85       {
   86           output.println("UnderlinePosition "
   87                   + font.getProperty("UnderlinePosition"));
   88           output.println("UnderlineThickness "
   89                   + font.getProperty("UnderlineThickness"));
   90           output.println("ItalicAngle " + font.getProperty("ItalicAngle"));
   91           output.println("IsFixedPitch " + font.getProperty("isFixedPitch"));
   92       }
   93   
   94       private static void printCharMetrics(CFFFont font, List<CharMetric> metrics, DataOutput output)
   95               throws IOException
   96       {
   97           output.println("StartCharMetrics " + metrics.size());
   98           Collections.sort(metrics);
   99           for (CharMetric metric : metrics)
  100           {
  101               output.print("C " + metric.code + " ;");
  102               output.print(" ");
  103               output.print("WX " + metric.width + " ;");
  104               output.print(" ");
  105               output.print("N " + metric.name + " ;");
  106               output.print(" ");
  107               output.print("B " + (int) metric.bounds.getX() + " "
  108                       + (int) metric.bounds.getY() + " "
  109                       + (int) metric.bounds.getMaxX() + " "
  110                       + (int) metric.bounds.getMaxY() + " ;");
  111               output.println();
  112           }
  113           output.println("EndCharMetrics");
  114       }
  115   
  116       private static List<CharMetric> renderFont(CFFFont font) throws IOException
  117       {
  118           List<CharMetric> metrics = new ArrayList<CharMetric>();
  119           CharStringRenderer renderer = font.createRenderer();
  120           Collection<CFFFont.Mapping> mappings = font.getMappings();
  121           for (CFFFont.Mapping mapping : mappings)
  122           {
  123               CharMetric metric = new CharMetric();
  124               metric.code = mapping.getCode();
  125               metric.name = mapping.getName();
  126               renderer.render(mapping.toType1Sequence());
  127               metric.width = renderer.getWidth();
  128               metric.bounds = renderer.getBounds();
  129               metrics.add(metric);
  130           }
  131           return metrics;
  132       }
  133   
  134       private static Rectangle2D getBounds(List<CharMetric> metrics)
  135       {
  136           Rectangle2D bounds = null;
  137           for(CharMetric metric : metrics)
  138           {
  139               if(bounds == null)
  140               {
  141                   bounds = new Rectangle2D.Double();
  142                   bounds.setFrame(metric.bounds);
  143               }
  144               else
  145               {
  146                   Rectangle2D.union(bounds, metric.bounds, bounds);
  147               }
  148           }
  149           return bounds;
  150       }
  151   
  152       /**
  153        * This class represents the metric of one single character. 
  154        *
  155        */
  156       private static class CharMetric implements Comparable<CharMetric>
  157       {
  158           private int code;
  159           private String name;
  160           private int width;
  161           private Rectangle2D bounds;
  162   
  163           public int compareTo(CharMetric that)
  164           {
  165               return code - that.code;
  166           }
  167       }
  168   }

Save This Page
Home » pdfbox-1.1.0-src » org.apache.fontbox.cff » [javadoc | source]