/*

   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.

 */
package org.apache.batik.bridge;

import java.util.List;
import java.util.LinkedList;

import org.w3c.dom.Element;
import org.w3c.dom.Node;

import org.apache.batik.dom.AbstractNode;
import org.apache.batik.dom.util.XLinkSupport;
import org.apache.batik.util.ParsedURL;

Bridge class for the <font-face> element.
Author:Bella Robinson
Version:$Id: SVGFontFaceElementBridge.java 1805408 2017-08-18 12:21:52Z ssteiner $
/** * Bridge class for the &lt;font-face&gt; element. * * @author <a href="mailto:bella.robinson@cmis.csiro.au">Bella Robinson</a> * @version $Id: SVGFontFaceElementBridge.java 1805408 2017-08-18 12:21:52Z ssteiner $ */
public class SVGFontFaceElementBridge extends AbstractSVGBridge implements ErrorConstants {
Constructs a new bridge for the <font-face> element.
/** * Constructs a new bridge for the &lt;font-face&gt; element. */
public SVGFontFaceElementBridge() { }
Returns 'font-face'.
/** * Returns 'font-face'. */
public String getLocalName() { return SVG_FONT_FACE_TAG; }
Creates an SVGFontFace that repesents the specified <font-face> element.
Params:
  • ctx – The current bridge context.
  • fontFaceElement – The <font-face> element.
Returns:A new SVGFontFace.
/** * Creates an SVGFontFace that repesents the specified * &lt;font-face&gt; element. * * @param ctx The current bridge context. * @param fontFaceElement The &lt;font-face&gt; element. * * @return A new SVGFontFace. */
public SVGFontFace createFontFace(BridgeContext ctx, Element fontFaceElement) { // get all the font-face attributes String familyNames = fontFaceElement.getAttributeNS (null, SVG_FONT_FAMILY_ATTRIBUTE); // units per em String unitsPerEmStr = fontFaceElement.getAttributeNS (null, SVG_UNITS_PER_EM_ATTRIBUTE); if (unitsPerEmStr.length() == 0) { unitsPerEmStr = SVG_FONT_FACE_UNITS_PER_EM_DEFAULT_VALUE; } float unitsPerEm; try { unitsPerEm = SVGUtilities.convertSVGNumber(unitsPerEmStr); } catch (NumberFormatException nfEx ) { throw new BridgeException (ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED, new Object [] {SVG_UNITS_PER_EM_ATTRIBUTE, unitsPerEmStr}); } // font-weight String fontWeight = fontFaceElement.getAttributeNS (null, SVG_FONT_WEIGHT_ATTRIBUTE); if (fontWeight.length() == 0) { fontWeight = SVG_FONT_FACE_FONT_WEIGHT_DEFAULT_VALUE; } // font-style String fontStyle = fontFaceElement.getAttributeNS (null, SVG_FONT_STYLE_ATTRIBUTE); if (fontStyle.length() == 0) { fontStyle = SVG_FONT_FACE_FONT_STYLE_DEFAULT_VALUE; } // font-variant String fontVariant = fontFaceElement.getAttributeNS (null, SVG_FONT_VARIANT_ATTRIBUTE); if (fontVariant.length() == 0) { fontVariant = SVG_FONT_FACE_FONT_VARIANT_DEFAULT_VALUE; } // font-stretch String fontStretch = fontFaceElement.getAttributeNS (null, SVG_FONT_STRETCH_ATTRIBUTE); if (fontStretch.length() == 0) { fontStretch = SVG_FONT_FACE_FONT_STRETCH_DEFAULT_VALUE; } // slopeStr String slopeStr = fontFaceElement.getAttributeNS (null, SVG_SLOPE_ATTRIBUTE); if (slopeStr.length() == 0) { slopeStr = SVG_FONT_FACE_SLOPE_DEFAULT_VALUE; } float slope; try { slope = SVGUtilities.convertSVGNumber(slopeStr); } catch (NumberFormatException nfEx ) { throw new BridgeException (ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED, new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, slopeStr}); } // panose-1 String panose1 = fontFaceElement.getAttributeNS (null, SVG_PANOSE_1_ATTRIBUTE); if (panose1.length() == 0) { panose1 = SVG_FONT_FACE_PANOSE_1_DEFAULT_VALUE; } // ascent String ascentStr = fontFaceElement.getAttributeNS (null, SVG_ASCENT_ATTRIBUTE); if (ascentStr.length() == 0) { // set it to be unitsPerEm * .8 ascentStr = String.valueOf( unitsPerEm * 0.8); } float ascent; try { ascent = SVGUtilities.convertSVGNumber(ascentStr); } catch (NumberFormatException nfEx ) { throw new BridgeException (ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED, new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, ascentStr}); } // descent String descentStr = fontFaceElement.getAttributeNS (null, SVG_DESCENT_ATTRIBUTE); if (descentStr.length() == 0) { // set it to be unitsPerEm *.2. descentStr = String.valueOf(unitsPerEm*0.2); } float descent; try { descent = SVGUtilities.convertSVGNumber(descentStr); } catch (NumberFormatException nfEx ) { throw new BridgeException (ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED, new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, descentStr }); } // underline-position String underlinePosStr = fontFaceElement.getAttributeNS (null, SVG_UNDERLINE_POSITION_ATTRIBUTE); if (underlinePosStr.length() == 0) { underlinePosStr = String.valueOf(-3*unitsPerEm/40); } float underlinePos; try { underlinePos = SVGUtilities.convertSVGNumber(underlinePosStr); } catch (NumberFormatException nfEx ) { throw new BridgeException (ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED, new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, underlinePosStr}); } // underline-thickness String underlineThicknessStr = fontFaceElement.getAttributeNS (null, SVG_UNDERLINE_THICKNESS_ATTRIBUTE); if (underlineThicknessStr.length() == 0) { underlineThicknessStr = String.valueOf(unitsPerEm/20); } float underlineThickness; try { underlineThickness = SVGUtilities.convertSVGNumber(underlineThicknessStr); } catch (NumberFormatException nfEx ) { throw new BridgeException (ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED, new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, underlineThicknessStr}); } // strikethrough-position String strikethroughPosStr = fontFaceElement.getAttributeNS (null, SVG_STRIKETHROUGH_POSITION_ATTRIBUTE); if (strikethroughPosStr.length() == 0) { strikethroughPosStr = String.valueOf(3*ascent/8); } float strikethroughPos; try { strikethroughPos = SVGUtilities.convertSVGNumber(strikethroughPosStr); } catch (NumberFormatException nfEx ) { throw new BridgeException (ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED, new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, strikethroughPosStr}); } // strikethrough-thickness String strikethroughThicknessStr = fontFaceElement.getAttributeNS (null, SVG_STRIKETHROUGH_THICKNESS_ATTRIBUTE); if (strikethroughThicknessStr.length() == 0) { strikethroughThicknessStr = String.valueOf(unitsPerEm/20); } float strikethroughThickness; try { strikethroughThickness = SVGUtilities.convertSVGNumber(strikethroughThicknessStr); } catch (NumberFormatException nfEx ) { throw new BridgeException (ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED, new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, strikethroughThicknessStr}); } // overline-position String overlinePosStr = fontFaceElement.getAttributeNS (null, SVG_OVERLINE_POSITION_ATTRIBUTE); if (overlinePosStr.length() == 0) { overlinePosStr = String.valueOf(ascent); } float overlinePos; try { overlinePos = SVGUtilities.convertSVGNumber(overlinePosStr); } catch (NumberFormatException nfEx ) { throw new BridgeException (ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED, new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, overlinePosStr}); } // overline-thickness String overlineThicknessStr = fontFaceElement.getAttributeNS (null, SVG_OVERLINE_THICKNESS_ATTRIBUTE); if (overlineThicknessStr.length() == 0) { overlineThicknessStr = String.valueOf(unitsPerEm/20); } float overlineThickness; try { overlineThickness = SVGUtilities.convertSVGNumber(overlineThicknessStr); } catch (NumberFormatException nfEx ) { throw new BridgeException (ctx, fontFaceElement, nfEx, ERR_ATTRIBUTE_VALUE_MALFORMED, new Object [] {SVG_FONT_FACE_SLOPE_DEFAULT_VALUE, overlineThicknessStr}); } List srcs = null; Element fontElt = SVGUtilities.getParentElement(fontFaceElement); if (!fontElt.getNamespaceURI().equals(SVG_NAMESPACE_URI) || !fontElt.getLocalName().equals(SVG_FONT_TAG)) { srcs = getFontFaceSrcs(fontFaceElement); } // TODO: get the rest of the attributes return new SVGFontFace(fontFaceElement, srcs, familyNames, unitsPerEm, fontWeight, fontStyle, fontVariant, fontStretch, slope, panose1, ascent, descent, strikethroughPos, strikethroughThickness, underlinePos, underlineThickness, overlinePos, overlineThickness); }
the returned list may contain Strings and ParsedURLs
/** * the returned list may contain Strings and ParsedURLs */
public List getFontFaceSrcs(Element fontFaceElement) { // Search for a font-face-src element Element ffsrc = null; for (Node n = fontFaceElement.getFirstChild(); n != null; n = n.getNextSibling()) { if ((n.getNodeType() == Node.ELEMENT_NODE) && n.getNamespaceURI().equals(SVG_NAMESPACE_URI) && n.getLocalName().equals(SVG_FONT_FACE_SRC_TAG)) { ffsrc = (Element)n; break; } } if (ffsrc == null) return null; List ret = new LinkedList(); // Search for a font-face-uri, or font-face-name elements for (Node n = ffsrc.getFirstChild(); n != null; n = n.getNextSibling()) { if ((n.getNodeType() != Node.ELEMENT_NODE) || !n.getNamespaceURI().equals(SVG_NAMESPACE_URI)) continue; if (n.getLocalName().equals(SVG_FONT_FACE_URI_TAG)) { Element ffuri = (Element)n; String uri = XLinkSupport.getXLinkHref(ffuri); String base = AbstractNode.getBaseURI(ffuri); ParsedURL purl; if (base != null) purl = new ParsedURL(base, uri); else purl = new ParsedURL(uri); ret.add(purl); // here we add a ParsedURL continue; } if (n.getLocalName().equals(SVG_FONT_FACE_NAME_TAG)) { Element ffname = (Element)n; String s = ffname.getAttribute("name"); if (s.length() != 0) ret.add(s); // here we add a String } } return ret; } }