/*!
* 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) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.engine.classic.core.testsupport.font;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.pentaho.reporting.libraries.fonts.LibFontBoot;
import org.pentaho.reporting.libraries.fonts.itext.ITextFontRegistry;
import org.pentaho.reporting.libraries.fonts.merge.CompoundFontRecord;
import org.pentaho.reporting.libraries.fonts.registry.DefaultFontContext;
import org.pentaho.reporting.libraries.fonts.registry.FontContext;
import org.pentaho.reporting.libraries.fonts.registry.FontFamily;
import org.pentaho.reporting.libraries.fonts.registry.FontMetrics;
import org.pentaho.reporting.libraries.fonts.registry.FontMetricsFactory;
import org.pentaho.reporting.libraries.fonts.registry.FontRecord;
import org.pentaho.reporting.libraries.fonts.truetype.TrueTypeFontRecord;
import org.pentaho.reporting.libraries.fonts.truetype.TrueTypeFontRegistry;
import org.pentaho.reporting.libraries.xmlns.LibXmlBoot;
import org.pentaho.reporting.libraries.xmlns.common.AttributeList;
import org.pentaho.reporting.libraries.xmlns.writer.DefaultTagDescription;
import org.pentaho.reporting.libraries.xmlns.writer.XmlWriter;
public class LocalFontSpecGenerator
{
public static void main(final String[] args) throws IOException
{
LibFontBoot.getInstance().start();
LibXmlBoot.getInstance().start();
final TrueTypeFontRegistry registry = new TrueTypeFontRegistry();
final ITextFontRegistry itextRegistry = new ITextFontRegistry();
registry.initialize();
itextRegistry.initialize();
final DefaultTagDescription defaultTagDescription = new DefaultTagDescription();
defaultTagDescription.setNamespaceHasCData(null, false);
final XmlWriter writer = new XmlWriter(new OutputStreamWriter(new FileOutputStream("/Users/user/fonts.xml"), "UTF-8"), defaultTagDescription);
writer.writeXmlDeclaration("UTF-8");
writer.writeTag(null, "font-spec", "fallback-font", "Arial", false);
final Map<String, FontRecord> records = new HashMap<String, FontRecord>();
final String[] families = registry.getAllRegisteredFamilies();
// final String[] families = new String[]{"Arial"};
Arrays.sort(families);
for (int i = 0; i < families.length; i++)
{
final String family = families[i];
writer.writeTag(null, "font-family", "name", family, false);
final FontFamily fontFamily = registry.getFontFamily(family);
writeRecord(writer, false, false, fontFamily.getFontRecord(false, false), records);
writeRecord(writer, true, false, fontFamily.getFontRecord(true, false), records);
writeRecord(writer, false, true, fontFamily.getFontRecord(false, true), records);
writeRecord(writer, true, true, fontFamily.getFontRecord(true, true), records);
writer.writeCloseTag();
}
final FontContext context = new DefaultFontContext(1000, false, true, false, "Identity-H");
final FontMetricsFactory metricsFactory = itextRegistry.createMetricsFactory();
final String[] sourceFiles = records.keySet().toArray(new String[records.size()]);
Arrays.sort(sourceFiles);
for (int i = 0; i < sourceFiles.length; i++)
{
final String sourceFile = sourceFiles[i];
final FontRecord fontRecord = records.get(sourceFile);
final FontMetrics metrics = metricsFactory.createMetrics(fontRecord.getIdentifier(), context);
writer.writeTag(null, "font-source", "source", sourceFile, false);
/*
<global-metrics ascent="0" descent="0" italic-angle="0" leading="0"
max-ascent="0" max-char-advance="0" max-descent="0" max-height="0"
overline-position="0" strike-through-position="0" underline-position="0" x-height="0"
uniform="false"/>
*/
final AttributeList globalAttrs = new AttributeList();
globalAttrs.setAttribute(null, "ascent", formatText(metrics.getAscent()));
globalAttrs.setAttribute(null, "descent", formatText(metrics.getDescent()));
globalAttrs.setAttribute(null, "italic-angle", formatText(metrics.getItalicAngle()));
globalAttrs.setAttribute(null, "leading", formatText(metrics.getLeading()));
globalAttrs.setAttribute(null, "max-ascent", formatText(metrics.getMaxAscent()));
globalAttrs.setAttribute(null, "max-char-advance", formatText(metrics.getMaxCharAdvance()));
globalAttrs.setAttribute(null, "max-descent", formatText(metrics.getMaxDescent()));
globalAttrs.setAttribute(null, "max-height", formatText(metrics.getMaxHeight()));
globalAttrs.setAttribute(null, "overline-position", formatText(metrics.getOverlinePosition()));
globalAttrs.setAttribute(null, "strike-through-position", formatText(metrics.getStrikeThroughPosition()));
globalAttrs.setAttribute(null, "underline-position", formatText(metrics.getUnderlinePosition()));
globalAttrs.setAttribute(null, "x-height", formatText(metrics.getXHeight()));
globalAttrs.setAttribute(null, "uniform", String.valueOf(metrics.isUniformFontMetrics()));
writer.writeTag(null, "global-metrics", globalAttrs, true);
for (int c = 0; c < 65536; c++)
{
if (c >= 0xD800 && c <= 0xDFFF)
{
// surrogate range is not valid in unicode
continue;
}
final long width = metrics.getCharWidth(c);
if (width == 0)
{
continue;
}
final AttributeList cwList = new AttributeList();
cwList.setAttribute(null, "codepoint", String.valueOf(c));
cwList.setAttribute(null, "value", String.valueOf(width));
writer.writeTag(null, "char-width", cwList, true);
}
for (int c = 0; c < 65536; c++)
{
if (c >= 0xD800 && c <= 0xDFFF)
{
// surrogate range is not valid in unicode
continue;
}
final long width = metrics.getCharWidth(c);
if (width == 0)
{
// if there is no metrics, there is no kerning info
continue;
}
for (int cPrev = 0; cPrev < 65536; cPrev++)
{
if (cPrev >= 0xD800 && cPrev <= 0xDFFF)
{
// surrogate range is not valid in unicode
continue;
}
final long kerning = metrics.getKerning(cPrev, c);
if (kerning == 0)
{
continue;
}
final AttributeList cwList = new AttributeList();
cwList.setAttribute(null, "codepoint", String.valueOf(c));
cwList.setAttribute(null, "prev", String.valueOf(cPrev));
cwList.setAttribute(null, "value", String.valueOf(kerning));
writer.writeTag(null, "kerning", cwList, true);
}
}
writer.writeCloseTag();
}
writer.writeCloseTag();
writer.flush();
writer.close();
}
private static String formatText(final double number)
{
final DecimalFormat format = new DecimalFormat("#0", new DecimalFormatSymbols(Locale.US));
return format.format(number);
}
private static void writeRecord(final XmlWriter writer,
final boolean bold,
final boolean italics,
FontRecord record,
final Map<String, FontRecord> records) throws IOException
{
final AttributeList attrList = new AttributeList();
attrList.setAttribute(null, "bold", String.valueOf(bold));
attrList.setAttribute(null, "italics", String.valueOf(italics));
if (record instanceof CompoundFontRecord)
{
final CompoundFontRecord cfr = (CompoundFontRecord) record;
record = cfr.getBase();
}
if (record instanceof TrueTypeFontRecord)
{
final TrueTypeFontRecord trueTypeFontRecord = (TrueTypeFontRecord) record;
attrList.setAttribute(null, "source", String.valueOf(trueTypeFontRecord.getFontSource()));
writer.writeTag(null, "font-record", attrList, true);
records.put(trueTypeFontRecord.getFontSource(), record);
}
}
}