/*
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program 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.
*
* Copyright (c) 2006 - 2013 Pentaho Corporation and Contributors. All rights reserved.
*/
package org.pentaho.reporting.libraries.fonts.itext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.reporting.libraries.base.util.ArgumentNullException;
import org.pentaho.reporting.libraries.fonts.cache.FirstLevelFontCache;
import org.pentaho.reporting.libraries.fonts.encoding.EncodingRegistry;
import org.pentaho.reporting.libraries.fonts.registry.FontContext;
import org.pentaho.reporting.libraries.fonts.registry.FontIdentifier;
import org.pentaho.reporting.libraries.fonts.registry.FontKey;
import org.pentaho.reporting.libraries.fonts.registry.FontMetrics;
import org.pentaho.reporting.libraries.fonts.registry.FontRegistry;
import org.pentaho.reporting.libraries.fonts.registry.FontStorage;
/**
* Creation-Date: 22.07.2007, 17:54:43
*
* @author Thomas Morgner
*/
public class ITextFontStorage implements FontStorage
{
private static class EncodingFontContextWrapper implements FontContext
{
private FontContext context;
private String defaultEncoding;
private EncodingFontContextWrapper(final FontContext context,
final String defaultEncoding)
{
this.context = context;
this.defaultEncoding = defaultEncoding;
}
public String getEncoding()
{
return defaultEncoding;
}
public boolean isEmbedded()
{
return context.isEmbedded();
}
public boolean isAntiAliased()
{
return context.isAntiAliased();
}
public boolean isFractionalMetrics()
{
return context.isFractionalMetrics();
}
public double getFontSize()
{
return context.getFontSize();
}
}
private static class EncodingFontKey extends FontKey
{
private String encoding;
public EncodingFontKey(final FontIdentifier identifier,
final boolean aliased,
final boolean fractional,
final double fontSize,
final String encoding)
{
super(identifier, aliased, fractional, fontSize);
this.encoding = encoding;
}
public EncodingFontKey()
{
}
public String getEncoding()
{
return encoding;
}
public void setEncoding(final String encoding)
{
this.encoding = encoding;
}
public boolean equals(final Object o)
{
if (this == o)
{
return true;
}
if (o == null || getClass() != o.getClass())
{
return false;
}
if (!super.equals(o))
{
return false;
}
final EncodingFontKey that = (EncodingFontKey) o;
if (encoding != null ? !encoding.equals(that.encoding) : that.encoding != null)
{
return false;
}
return true;
}
public int hashCode()
{
int result = super.hashCode();
result = 31 * result + (encoding != null ? encoding.hashCode() : 0);
return result;
}
}
private static final Log logger = LogFactory.getLog(ITextFontStorage.class);
private ITextFontRegistry registry;
private ITextFontMetricsFactory metricsFactory;
private EncodingFontKey lookupKey;
private FirstLevelFontCache knownMetrics;
private String defaultEncoding;
private int hits;
private int misses;
public ITextFontStorage(final ITextFontRegistry registry)
{
this(registry, EncodingRegistry.getPlatformDefaultEncoding());
}
public ITextFontStorage(final ITextFontRegistry registry,
final String encoding)
{
ArgumentNullException.validate("registry", registry);
ArgumentNullException.validate("encoding", encoding);
this.lookupKey = new EncodingFontKey();
this.knownMetrics = new FirstLevelFontCache(registry.getSecondLevelCache());
this.registry = registry;
this.defaultEncoding = encoding;
this.metricsFactory = (ITextFontMetricsFactory) registry.createMetricsFactory();
}
public String getDefaultEncoding()
{
return defaultEncoding;
}
public void setDefaultEncoding(final String defaultEncoding)
{
ArgumentNullException.validate("defaultEncoding", defaultEncoding);
this.defaultEncoding = defaultEncoding;
}
public FontRegistry getFontRegistry()
{
return registry;
}
public FontMetrics getFontMetrics(final FontIdentifier rawRecord,
final FontContext context)
{
if (rawRecord == null)
{
throw new NullPointerException();
}
if (context == null)
{
throw new NullPointerException();
}
final String effectiveEncoding;
final String contextEncoding = context.getEncoding();
if (contextEncoding == null)
{
effectiveEncoding = defaultEncoding;
}
else
{
effectiveEncoding = contextEncoding;
}
lookupKey.setAliased(context.isAntiAliased());
lookupKey.setFontSize(context.getFontSize());
lookupKey.setIdentifier(rawRecord);
lookupKey.setFractional(context.isFractionalMetrics());
lookupKey.setEncoding(effectiveEncoding);
final FontMetrics cachedMetrics = knownMetrics.getFontMetrics(lookupKey);
if (cachedMetrics != null)
{
hits += 1;
return cachedMetrics;
}
misses += 1;
final EncodingFontContextWrapper contextWrapper = new EncodingFontContextWrapper(context, effectiveEncoding);
final FontMetrics metrics = metricsFactory.createMetrics(rawRecord, contextWrapper);
final EncodingFontKey key = new EncodingFontKey(rawRecord, context.isAntiAliased(),
context.isFractionalMetrics(), context.getFontSize(), effectiveEncoding);
knownMetrics.putFontMetrics(key, metrics);
return metrics;
}
public void commit()
{
logger.debug("Font-Storage: hits=" + hits + ", misses=" + misses);
metricsFactory.close();
knownMetrics.commit();
}
}