org.apache.fop.svg.ACIUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of fop Show documentation
Show all versions of fop Show documentation
Apache FOP (Formatting Objects Processor) is the world's first print formatter driven by XSL formatting objects (XSL-FO) and the world's first output independent formatter. It is a Java application that reads a formatting object (FO) tree and renders the resulting pages to a specified output. Output formats currently supported include PDF, PCL, PS, AFP, TIFF, PNG, SVG, XML (area tree representation), Print, AWT and TXT. The primary output target is PDF.
/*
* 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.
*/
/* $Id: ACIUtils.java 1761019 2016-09-16 10:43:45Z ssteiner $ */
package org.apache.fop.svg;
import java.awt.font.TextAttribute;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;
import java.text.CharacterIterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.batik.bridge.SVGFontFamily;
import org.apache.batik.gvt.font.GVTFont;
import org.apache.batik.gvt.font.GVTFontFamily;
import org.apache.batik.gvt.text.GVTAttributedCharacterIterator;
import org.apache.fop.fonts.Font;
import org.apache.fop.fonts.FontInfo;
import org.apache.fop.svg.font.FOPGVTFont;
import org.apache.fop.svg.font.FOPGVTFontFamily;
/**
* Utilities for java.text.AttributedCharacterIterator.
*/
public final class ACIUtils {
/** the logger for this class */
private static final Log LOG = LogFactory.getLog(ACIUtils.class);
private ACIUtils() {
//This class shouldn't be instantiated.
}
/**
* Tries to find matching fonts in FOP's {@link FontInfo} instance for fonts used by
* Apache Batik. The method inspects the various GVT attributes found in the ACI.
* @param aci the ACI to find matching fonts for
* @param fontInfo the font info instance with FOP's fonts
* @return an array of matching fonts
*/
public static Font[] findFontsForBatikACI(AttributedCharacterIterator aci, FontInfo fontInfo) {
List fonts = new java.util.ArrayList();
@SuppressWarnings("unchecked")
List gvtFonts = (List) aci.getAttribute(
GVTAttributedCharacterIterator.TextAttribute.GVT_FONT_FAMILIES);
String style = toStyle((Float) aci.getAttribute(TextAttribute.POSTURE));
int weight = toCSSWeight((Float) aci.getAttribute(TextAttribute.WEIGHT));
float fontSize = (Float) aci.getAttribute(TextAttribute.SIZE);
String firstFontFamily = null;
//GVT_FONT can sometimes be different from the fonts in GVT_FONT_FAMILIES
//or GVT_FONT_FAMILIES can even be empty and only GVT_FONT is set
GVTFont gvtFont = (GVTFont) aci.getAttribute(GVTAttributedCharacterIterator.TextAttribute.GVT_FONT);
if (gvtFont != null) {
String gvtFontFamily = gvtFont.getFamilyName();
if (gvtFont instanceof FOPGVTFont) {
Font font = ((FOPGVTFont) gvtFont).getFont();
if (LOG.isDebugEnabled()) {
LOG.debug("Found a font that matches the GVT font: "
+ gvtFontFamily + ", " + weight + ", " + style
+ " -> " + font);
}
fonts.add(font);
}
firstFontFamily = gvtFontFamily;
}
if (gvtFonts != null) {
boolean haveInstanceOfSVGFontFamily = false;
for (GVTFontFamily fontFamily : gvtFonts) {
if (fontFamily instanceof SVGFontFamily) {
haveInstanceOfSVGFontFamily = true;
} else if (fontFamily instanceof FOPGVTFontFamily) {
Font font = ((FOPGVTFontFamily) fontFamily).deriveFont(fontSize, aci).getFont();
if (LOG.isDebugEnabled()) {
LOG.debug("Found a font that matches the GVT font family: "
+ fontFamily.getFamilyName() + ", " + weight + ", " + style + " -> " + font);
}
fonts.add(font);
}
if (firstFontFamily == null) {
firstFontFamily = fontFamily.getFamilyName();
}
}
// SVG fonts are embedded fonts in the SVG document and are rarely used; however if they
// are used but the fonts also exists in the system and are known to FOP then FOP should
// use them; then the decision whether Batik should stroke the text should be made after
// no matching fonts are found
if (fonts.isEmpty() && haveInstanceOfSVGFontFamily) {
fontInfo.notifyStrokingSVGTextAsShapes(firstFontFamily);
return null; // Let Batik paint this text!
}
}
return fonts.isEmpty() ? null : fonts.toArray(new Font[fonts.size()]);
}
public static int toCSSWeight(Float weight) {
if (weight == null) {
return 400;
} else if (weight <= TextAttribute.WEIGHT_EXTRA_LIGHT) {
return 100;
} else if (weight <= TextAttribute.WEIGHT_LIGHT) {
return 200;
} else if (weight <= TextAttribute.WEIGHT_DEMILIGHT) {
return 300;
} else if (weight <= TextAttribute.WEIGHT_REGULAR) {
return 400;
} else if (weight <= TextAttribute.WEIGHT_SEMIBOLD) {
return 500;
} else if (weight < TextAttribute.WEIGHT_BOLD) {
return 600;
} else if (weight == TextAttribute.WEIGHT_BOLD.floatValue()) {
return 700;
} else if (weight <= TextAttribute.WEIGHT_HEAVY) {
return 800;
} else if (weight <= TextAttribute.WEIGHT_EXTRABOLD) {
return 900;
} else {
return 900;
}
}
public static String toStyle(Float posture) {
return ((posture != null) && (posture > 0.0))
? Font.STYLE_ITALIC
: Font.STYLE_NORMAL;
}
/**
* Dumps the contents of an ACI to System.out. Used for debugging only.
* @param aci the ACI to dump
*/
public static void dumpAttrs(AttributedCharacterIterator aci) {
aci.first();
Set> entries = aci.getAttributes().entrySet();
for (Map.Entry entry : entries) {
if (entry.getValue() != null) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
int start = aci.getBeginIndex();
System.out.print("AttrRuns: ");
while (aci.current() != CharacterIterator.DONE) {
int end = aci.getRunLimit();
System.out.print("" + (end - start) + ", ");
aci.setIndex(end);
if (start == end) {
break;
}
start = end;
}
System.out.println("");
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy