/*!
* 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 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;
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;
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 );
}
}
}