Package org.jfree.fonts.truetype

Source Code of org.jfree.fonts.truetype.TrueTypeFontRegistry

/**
* ===========================================
* LibFonts : a free Java font reading library
* ===========================================
*
* Project Info:  http://reporting.pentaho.org/libfonts/
*
* (C) Copyright 2006-2007, by Pentaho Corporation and Contributors.
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
*
* [Java is a trademark or registered trademark of Sun Microsystems, Inc.
* in the United States and other countries.]
*
* ------------
* $Id: TrueTypeFontRegistry.java 3523 2007-10-16 11:03:09Z tmorgner $
* ------------
* (C) Copyright 2006-2007, by Pentaho Corporation.
*/
package org.jfree.fonts.truetype;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.io.Serializable;
import java.util.HashMap;

import org.jfree.fonts.FontException;
import org.jfree.fonts.registry.AbstractFontFileRegistry;
import org.jfree.fonts.registry.DefaultFontFamily;
import org.jfree.fonts.registry.FontFamily;
import org.jfree.fonts.registry.FontMetricsFactory;
import org.jfree.util.Log;
import org.jfree.util.StringUtils;

/**
* Creation-Date: 07.11.2005, 19:05:46
*
* @author Thomas Morgner
*/
public class TrueTypeFontRegistry extends AbstractFontFileRegistry
{
  private static class FontFileRecord implements Serializable
  {
    private long lastAccessTime;
    private long fileSize;
    private String filename;

    protected FontFileRecord(final File file) throws IOException
    {
      this(file.getCanonicalPath(), file.length(), file.lastModified());
    }

    protected FontFileRecord(final String filename,
                             final long fileSize,
                             final long lastAccessTime)
    {
      if (filename == null)
      {
        throw new NullPointerException();
      }
      this.filename = filename;
      this.fileSize = fileSize;
      this.lastAccessTime = lastAccessTime;
    }

    public long getLastAccessTime()
    {
      return lastAccessTime;
    }

    public long getFileSize()
    {
      return fileSize;
    }

    public String getFilename()
    {
      return filename;
    }

    public boolean equals(final Object o)
    {
      if (this == o)
      {
        return true;
      }
      if (o == null || getClass() != o.getClass())
      {
        return false;
      }

      final FontFileRecord that = (FontFileRecord) o;

      if (fileSize != that.fileSize)
      {
        return false;
      }
      if (lastAccessTime != that.lastAccessTime)
      {
        return false;
      }
      if (!filename.equals(that.filename))
      {
        return false;
      }

      return true;
    }

    public int hashCode()
    {
      int result = (int) (lastAccessTime ^ (lastAccessTime >>> 32));
      result = 29 * result + (int) (fileSize ^ (fileSize >>> 32));
      result = 29 * result + filename.hashCode();
      return result;
    }
  }

  /**
   * The font path filter is used to collect font files and directories during the font path registration.
   */
  private static class FontPathFilter implements FileFilter, Serializable
  {
    /**
     * Default Constructor.
     */
    protected FontPathFilter()
    {
    }

    /**
     * Tests whether or not the specified abstract pathname should be included in a pathname list.
     *
     * @param pathname The abstract pathname to be tested
     * @return <code>true</code> if and only if <code>pathname</code> should be included
     */
    public boolean accept(final File pathname)
    {
      if (pathname.canRead() == false)
      {
        return false;
      }
      if (pathname.isDirectory())
      {
        return true;
      }
      final String name = pathname.getName();
      if (StringUtils.endsWithIgnoreCase(name, ".ttf"))
      {
        return true;
      }
      if (StringUtils.endsWithIgnoreCase(name, ".ttc"))
      {
        return true;
      }
      if (StringUtils.endsWithIgnoreCase(name, ".otf"))
      {
        return true;
      }
      return false;
    }

  }

  /**
   * The singleton instance of the font path filter.
   */
  private static final FontPathFilter FONTPATHFILTER = new FontPathFilter();

  private HashMap seenFiles;
  private HashMap fontFamilies;
  private HashMap alternateFamilyNames;
  private HashMap fullFontNames;

  public TrueTypeFontRegistry()
  {
    this.seenFiles = new HashMap();
    this.fontFamilies = new HashMap();
    this.alternateFamilyNames = new HashMap();
    this.fullFontNames = new HashMap();
  }

  protected FileFilter getFileFilter()
  {
    return FONTPATHFILTER;
  }

  protected boolean isCached(final File file)
  {
    try
    {
      final FontFileRecord stored = (FontFileRecord) seenFiles.get(file.getCanonicalPath());
      if (stored == null)
      {
        return false;
      }

      final FontFileRecord rec = new FontFileRecord(file);
      if (stored.equals(rec) == false)
      {
        seenFiles.remove(rec);
        return false;
      }
      return true;
    }
    catch (IOException e)
    {
      return false;
    }
  }

  protected void addFont(final File file, final String encoding) throws IOException
  {
    try
    {
      if (StringUtils.endsWithIgnoreCase(file.getName(), ".ttc"))
      {
        final TrueTypeCollection ttc = new TrueTypeCollection(file);
        for (int i = 0; i < ttc.getNumFonts(); i++)
        {
          TrueTypeFont font = null;
          try
          {
            font = ttc.getFont(i);
            registerTrueTypeFont(font);
          }
          finally
          {
            if (font != null)
            {
              font.dispose();
            }
          }
        }
      }
      else
      {
        TrueTypeFont font = null;
        try
        {
          font = new TrueTypeFont(file);
          registerTrueTypeFont(font);
        }
        finally
        {
          if (font != null)
          {
            font.dispose();
          }
        }
      }
      final FontFileRecord value = new FontFileRecord(file);
      seenFiles.put(file.getCanonicalPath(), value);
    }
    catch (Exception e)
    {
      // An error must not stop us on our holy mission to find an register
      // all fonts :)
    }
  }

  private void registerTrueTypeFont(final TrueTypeFont font)
      throws IOException
  {
    final NameTable table = (NameTable) font.getTable(NameTable.TABLE_ID);
    if (table == null)
    {
      throw new IOException(
          "The NameTable is required for all conforming fonts.");
    }

    final String familyName = table.getPrimaryName(NameTable.NAME_FAMILY);
    final String[] allNames = table.getAllNames(NameTable.NAME_FAMILY);

    final DefaultFontFamily fontFamily = createFamily(familyName);
    alternateFamilyNames.put(familyName, fontFamily);

    for (int i = 0; i < allNames.length; i++)
    {
      final String name = allNames[i];
      fontFamily.addName(name);
      alternateFamilyNames.put(name, fontFamily);
    }

    final String[] allFullNames = table.getAllNames(NameTable.NAME_FULLNAME);
    for (int i = 0; i < allFullNames.length; i++)
    {
      final String name = allFullNames[i];
      this.fullFontNames.put(name, fontFamily);
    }

    try
    {
      final TrueTypeFontRecord record = new TrueTypeFontRecord(font, fontFamily);
      fontFamily.addFontRecord(record);
    }
    catch (FontException e)
    {
      Log.info("The font '" + font.getFilename() + "' is invalid.");
    }
  }

  private DefaultFontFamily createFamily(final String name)
  {
    final DefaultFontFamily fontFamily = (DefaultFontFamily)
        this.fontFamilies.get(name);
    if (fontFamily != null)
    {
      return fontFamily;
    }

    final DefaultFontFamily createdFamily = new DefaultFontFamily(name);
    this.fontFamilies.put(name, createdFamily);
    return createdFamily;
  }

  public String[] getRegisteredFamilies()
  {
    return (String[]) fontFamilies.keySet().toArray
        (new String[fontFamilies.size()]);
  }

  public String[] getAllRegisteredFamilies()
  {
    return (String[]) alternateFamilyNames.keySet().toArray
        (new String[alternateFamilyNames.size()]);
  }

  public FontFamily getFontFamily(final String name)
  {
    final FontFamily primary = (FontFamily) this.fontFamilies.get(name);
    if (primary != null)
    {
      return primary;
    }
    final FontFamily secondary = (FontFamily)
        this.alternateFamilyNames.get(name);
    if (secondary != null)
    {
      return secondary;
    }
    return (FontFamily) this.fullFontNames.get(name);
  }

  /**
   * Creates a new font metrics factory. That factory is specific to a certain font registry and is not required to
   * handle font records from foreign font registries.
   * <p/>
   * A font metrics factory should never be used on its own. It should be embedded into and used by a FontStorage
   * implementation.
   *
   * @return a new FontMetricsFactory instance
   */
  public FontMetricsFactory createMetricsFactory()
  {
    return new TrueTypeFontMetricsFactory();
  }
}
TOP

Related Classes of org.jfree.fonts.truetype.TrueTypeFontRegistry

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.