All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.openhtmltopdf.mathmlsupport.MathMLDrawer Maven / Gradle / Ivy

Go to download

Open HTML to PDF is a CSS 2.1 renderer written in Java. This artifact supports drawing MathML graphics on to PDFs using JEuclid.

There is a newer version: 1.0.10
Show newest version
package com.openhtmltopdf.mathmlsupport;

import java.awt.Font;
import java.awt.FontFormatException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;

import com.openhtmltopdf.util.LogMessageId;
import net.sourceforge.jeuclid.font.DefaultFontFactory;
import net.sourceforge.jeuclid.font.FontFactory;

import org.w3c.dom.Element;

import com.openhtmltopdf.css.constants.CSSName;
import com.openhtmltopdf.css.constants.IdentValue;
import com.openhtmltopdf.css.sheet.FontFaceRule;
import com.openhtmltopdf.css.style.CalculatedStyle;
import com.openhtmltopdf.css.style.CssContext;
import com.openhtmltopdf.css.style.FSDerivedValue;
import com.openhtmltopdf.extend.SVGDrawer;
import com.openhtmltopdf.layout.SharedContext;
import com.openhtmltopdf.render.Box;
import com.openhtmltopdf.util.XRLog;

public class MathMLDrawer implements SVGDrawer {
	private final FontFactory _fontFactory;
	private SharedContext _sharedCtx;
	private final Set _loadedFontFamilies = new HashSet();
	private final Map> _availabelFontFamilies = new HashMap>();

	public MathMLDrawer() {
		this._fontFactory = new DefaultFontFactory();
		FontFactory.setThreadFontFactory(this._fontFactory);
	}
	
	@Override
	public void importFontFaceRules(List fontFaces,
			SharedContext shared) {
		
		// In this method, we just load a map of font families to their sources,
		// as we don't yet know which fonts mathml objects will use.
		
		for (FontFaceRule rule : fontFaces) {
			_sharedCtx = shared;
			
			CalculatedStyle style = rule.getCalculatedStyle();
			
			FSDerivedValue src = style.valueByName(CSSName.SRC);

			if (src == IdentValue.NONE ||
				!rule.hasFontFamily()) {
	            continue;
	        }
	        
			String family = style.valueByName(CSSName.FONT_FAMILY).asString();
			
			if (_availabelFontFamilies.containsKey(family)) {
				_availabelFontFamilies.get(family).add(src.asString());
			} else {
				_availabelFontFamilies.put(family, new ArrayList());
				_availabelFontFamilies.get(family).add(src.asString());
			}
		}
	}
	
	private void loadFamilyFonts(String family) {
		// In this method, we load all fonts for a given family,
		// as we don't know which styles and weights will be used.
		
		if (_loadedFontFamilies.contains(family)) {
			return;
		} else {
			_loadedFontFamilies.add(family);
		}
		
		if (!_availabelFontFamilies.containsKey(family)) {
			XRLog.log(Level.WARNING, LogMessageId.LogMessageId1Param.GENERAL_COULD_NOT_FIND_FONT_SPECIFIED_FOR_MATHML_OBJECT_IN_FONT_FACE_RULES,family);
			return;
		}
		
		for (String src : _availabelFontFamilies.get(family)) {
			byte[] font1 = _sharedCtx.getUserAgentCallback().getBinaryResource(src);
			if (font1 == null) {
				XRLog.log(Level.WARNING, LogMessageId.LogMessageId1Param.EXCEPTION_COULD_NOT_LOAD_FONT, src);
				continue;
			}
		
			try {
				_fontFactory.registerFont(Font.TRUETYPE_FONT, new ByteArrayInputStream(font1));
			} catch (IOException | FontFormatException e) {
				XRLog.log(Level.WARNING, LogMessageId.LogMessageId0Param.EXCEPTION_MATHML_COULD_NOT_REGISTER_FONT, e);
			}
		}

	}

	@Override
	public SVGImage buildSVGImage(Element mathMlElement, Box box, CssContext c, double cssWidth,
			double cssHeight, double dotsPerPixel) {
		
		// Make sure the fonts this MathML object uses are loaded.
		String[] fonts = box.getStyle().asStringArray(CSSName.FONT_FAMILY);
		for (String family : fonts) {
			loadFamilyFonts(family);
		}
		
		double cssMaxWidth = CalculatedStyle.getCSSMaxWidth(c, box);
		double cssMaxHeight = CalculatedStyle.getCSSMaxHeight(c, box);
		List fontList = Arrays.asList(fonts);
		
		MathMLImage img = new MathMLImage(mathMlElement, box, cssWidth, cssHeight, cssMaxWidth, cssMaxHeight, dotsPerPixel, fontList);

		return img;
	}

	@Override
	public void close() throws IOException {
		FontFactory.clearThreadFontFactory();
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy