123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- /*
- * 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$ */
-
- 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<Font> fonts = new java.util.ArrayList<Font>();
- @SuppressWarnings("unchecked")
- List<GVTFontFamily> gvtFonts = (List<GVTFontFamily>) 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)).floatValue();
-
- 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.floatValue()) {
- return 100;
- } else if (weight <= TextAttribute.WEIGHT_LIGHT.floatValue()) {
- return 200;
- } else if (weight <= TextAttribute.WEIGHT_DEMILIGHT.floatValue()) {
- return 300;
- } else if (weight <= TextAttribute.WEIGHT_REGULAR.floatValue()) {
- return 400;
- } else if (weight <= TextAttribute.WEIGHT_SEMIBOLD.floatValue()) {
- return 500;
- } else if (weight < TextAttribute.WEIGHT_BOLD.floatValue()) {
- return 600;
- } else if (weight == TextAttribute.WEIGHT_BOLD.floatValue()) {
- return 700;
- } else if (weight <= TextAttribute.WEIGHT_HEAVY.floatValue()) {
- return 800;
- } else if (weight <= TextAttribute.WEIGHT_EXTRABOLD.floatValue()) {
- return 900;
- } else {
- return 900;
- }
- }
-
- public static String toStyle(Float posture) {
- return ((posture != null) && (posture.floatValue() > 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<Entry<Attribute, Object>> entries = aci.getAttributes().entrySet();
- for (Map.Entry<Attribute, Object> 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("");
- }
-
- }
|