Package flex2.tools

Source Code of flex2.tools.FontSnapshot

/*
*
*  Licensed to the Apache Software Foundation (ASF) under one or more
*  contributor license agreements.  See the NOTICE file distributed with
*  this work for additional information regarding copyright ownership.
*  The ASF licenses this file to You under the Apache License, Version 2.0
*  (the "License"); you may not use this file except in compliance with
*  the License.  You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*
*/

package flex2.tools;

import java.io.File;
import java.io.ObjectOutputStream;
import java.io.IOException;
import java.io.FileOutputStream;
import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.util.StringTokenizer;
import java.util.HashMap;
import java.util.Map;
import java.lang.reflect.Method;

import org.apache.flex.forks.batik.svggen.font.Font;
import org.apache.flex.forks.batik.svggen.font.table.Os2Table;
import org.apache.flex.forks.batik.svggen.font.table.NameTable;
import org.apache.flex.forks.batik.svggen.font.table.Table;
import flash.fonts.LocalFont;

/**
* A tool that takes a snapshot of all font information, storing it in LocalFont objects that are serialized
* into localFonts.ser.  This data is read in by JREFontManager.
*
* The fonts are found by looking at the Sun-specific APIs for finding the system font path.  If this API is
* not available, then the system font directories can be passed in.
*
* This is done as a separate tool and not as part of a compilation because of speed.  Reading all of
* the fonts on a system takes a non-trivial amount of time.
*
* @author Brian Deitte
*/
public class FontSnapshot
{
  private static Method getFontPath;
  private Map<String, LocalFont> fonts = new HashMap<String, LocalFont>();

  // for JREFontManager's initDefaultLocalFonts()
  private static boolean printForMap = true;

  public static void main(String[] args) throws Exception
  {
    FontSnapshot snapshot = new FontSnapshot(args);
    snapshot.save();
  }

  public FontSnapshot(String[] paths)
  {
    findFonts(paths);
  }

  protected void findFonts(String[] paths)
  {
    if (paths != null && paths.length != 0)
    {
      for (int i = 0; i < paths.length; i++)
      {
        findFonts(paths[i]);
      }
    }

    // FIXME: add system font dirs to FontLicenseChecker as well?
    // find the system font directories
    if (getFontPath != null)
    {
      String fPath;
      try
      {
        fPath = (String)getFontPath.invoke(null, new Object[] { Boolean.TRUE });
      }
      catch(Exception e)
      {
        throw new RuntimeException("Could not call getFontPath() for initializing system fonts: " + e, e);
      }
      StringTokenizer parser = new StringTokenizer(fPath, File.pathSeparator);
      while (parser.hasMoreTokens())
      {
        findFonts(parser.nextToken());
      }
    }
  }

  protected void findFonts(String path)
  {
    File file = new File(path);

    if (! file.exists())
    {
      throw new RuntimeException("Font or dir not found: " + file);
    }

    if (file.isDirectory())
    {
      File[] children = file.listFiles();
      if (children != null)
      {
        for (int i = 0; i < children.length; i++)
        {
          File child = children[i];
          if (child.isDirectory() || child.toString().toLowerCase().endsWith(".ttf"))
          {
            findFonts(child.toString());
          }
        }
      }
    }
    else
    {
      Font font = null;
      String err = null;
      try
      {
        font = Font.create(file.toString());
      }
      catch(Exception e)
      {
        err = e.toString();
      }

      if (font == null || font.getOS2Table() == null || font.getNameTable() == null)
      {
        System.err.println("Error reading " + file + ": " + err);
      }
      else
      {
        Os2Table os2Table = font.getOS2Table();
        int fsType = os2Table.getLicenseType();

        NameTable name = font.getNameTable();
        String copyright = name.getRecord(Table.nameCopyrightNotice);
        String trademark = name.getRecord(Table.nameTrademark);

        String postScriptName = name.getRecord(Table.namePostscriptName);
        LocalFont localFont = new LocalFont(postScriptName, path, fsType, copyright, trademark);
        LocalFont cachedFont = fonts.get(postScriptName);

        if (cachedFont != null)
        {
          if (! localFont.equals(cachedFont))
          {
            // FIXME: localize if we're keeping this class
            System.out.println("Found different fonts with the same postscript name. Keeping font " +
                postScriptName + " found at  " + cachedFont.path + " and ignoring " + localFont.path);
          }
        }
        else
        {
          fonts.put(postScriptName, localFont);

          if (printForMap)
          {
            System.out.println("defaultLocalFonts.put(\"" + postScriptName + "\", new LocalFont(\"" +
                postScriptName + "\", null, " + fsType + ", \"" + copyright + "\", \"" + trademark + "\"));");
          }
        }
      }
    }
  }

  public void save() throws IOException
  {
    if (fonts.size() == 0)
    {
      System.err.println("No fonts were found.  You must specify the system font directories.");
    }

    OutputStream buffStream = new BufferedOutputStream(new FileOutputStream("localFonts.ser"));
    ObjectOutputStream out = new ObjectOutputStream(buffStream);
    out.writeObject(fonts);
    out.flush();
    buffStream.close();
  }

  static
  {
    try
    {
      Class cls = Class.forName("sun.awt.font.NativeFontWrapper", true, Thread.currentThread().getContextClassLoader());
      //Method method = cls.getMethod("getFontPath", new Class[] { Boolean.class });
      // this is painful... don't know why do we have to do this instead of calling the commented-out call above
      Method[] meth = cls.getMethods();
      for (int i = 0; i < meth.length; i++)
      {
        Method method = meth[i];
        if (method.getName().equals("getFontPath"))
        {
          getFontPath = method;
          break;
        }
      }
    }
    catch(Exception e)
    {
      // ignore exception, not on Sun jdk 1.4 or lower

      try
      {
        Class cls = Class.forName("sun.font.FontManager", true, Thread.currentThread().getContextClassLoader());
        getFontPath = cls.getMethod("getFontPath", new Class[] { Boolean.class });
      }
      catch(Exception e2)
      {
        // ignore exception, not on Sun jdk 1.5
      }
    }

  }
}
TOP

Related Classes of flex2.tools.FontSnapshot

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.