<commit_before>/*******************************************************************************
 * Copyright (c) 2010-2015 ITER Organization.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 ******************************************************************************/
package org.csstudio.utility.batik;

import java.awt.Dimension;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.DynamicGVTBuilder;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UpdateManagerEvent;
import org.apache.batik.bridge.UpdateManagerListener;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.bridge.ViewBox;
import org.apache.batik.bridge.svg12.SVG12BridgeContext;
import org.apache.batik.css.engine.CSSStyleSheetNode;
import org.apache.batik.css.engine.SVGCSSEngine;
import org.apache.batik.css.engine.StyleSheet;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.dom.svg.SVGOMDocument;
import org.apache.batik.dom.svg.SVGStylableElement;
import org.apache.batik.dom.util.DOMUtilities;
import org.apache.batik.gvt.CanvasGraphicsNode;
import org.apache.batik.gvt.CompositeGraphicsNode;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.renderer.ConcreteImageRendererFactory;
import org.apache.batik.gvt.renderer.ImageRenderer;
import org.apache.batik.gvt.renderer.ImageRendererFactory;
import org.apache.batik.util.SVGConstants;
import org.apache.commons.lang.time.DateUtils;
import org.csstudio.java.thread.ExecutionService;
import org.csstudio.utility.batik.util.ICSSHandler;
import org.csstudio.utility.batik.util.SVGStylableElementCSSHandler;
import org.csstudio.utility.batik.util.StyleSheetCSSHandler;
import org.eclipse.swt.graphics.Color;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;

/**
 * {@link SVGDocument} handler. Handles render and animation of SVG files.
 * @author <NAME> (Sopra Steria Group) - ITER
 */
public class SVGHandler {

	private static final int MILLISEC_IN_SEC = 1000;

	protected SVGHandlerListener handlerListener;

	/**
	 * The listener.
	 */
	protected Listener listener;

	/**
	 * The renderer factory.
	 */
	protected ImageRendererFactory rendererFactory = new ConcreteImageRendererFactory();

	/**
	 * The current renderer.
	 */
	protected ImageRenderer renderer;

	/**
	 * The user agent.
	 */
	protected UserAgent userAgent;

	/**
	 * The current bridge context.
	 */
	protected BridgeContext bridgeContext;

	/**
	 * The concrete bridge document loader.
	 */
	protected DocumentLoader loader;

	/**
	 * The update manager.
	 */
	protected UpdateManager updateManager;

	/**
	 * The current SVG document.
	 */
	protected SVGDocument svgDocument;

	protected SVGDocument originalSVGDocument;

	protected Dimension2D originalDimension;

	/**
	 * Whether the current document has dynamic features.
	 */
	protected boolean isDynamicDocument;

	/**
	 * The animation limiting mode.
	 */
	protected int animationLimitingMode;

	/**
	 * The amount of animation limiting.
	 */
	protected float animationLimitingAmount;
	
	protected GVTBuilder builder;

	private RenderingHints renderingHints;
	private float canvasWidth = -1, canvasHeight = -1;
	private Color colorToChange, colorToApply;
	private double[][] matrix = new double[][] { { 1, 0 }, { 0, 1 } };

	private boolean needRender = true;
	private boolean disposed = false;

	private boolean alignedToNearestSecond = false;
	private boolean started = false;
	private boolean suspended = true;

	public SVGHandler(final SVGDocument doc) {
		listener = new Listener();
		userAgent = createUserAgent();
		renderingHints = new RenderingHints(null);

		DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
		originalSVGDocument = (SVGDocument) DOMUtilities.deepCloneDocument(doc, impl);
		bridgeContext = createBridgeContext((SVGOMDocument) originalSVGDocument);
		isDynamicDocument = bridgeContext.isDynamicDocument(originalSVGDocument);
		// As we update the DOM, it has to be considered as dynamic
		bridgeContext.setDynamicState(BridgeContext.DYNAMIC);
		builder = new DynamicGVTBuilder();
		// Build to calculate original dimension
		GraphicsNode gvtRoot = builder.build(bridgeContext, originalSVGDocument);
		originalDimension = bridgeContext.getDocumentSize();

		svgDocument = (SVGDocument) createWrapper(originalSVGDocument);
		builder.build(bridgeContext, svgDocument);
		buildElementsToUpdateList(bridgeContext, svgDocument);
		if (isDynamicDocument) {
			updateManager = new UpdateManager(bridgeContext, gvtRoot, svgDocument);
			updateManager.addUpdateManagerListener(listener);
		}
	}

	public void dispose() {
		disposed = true;
		if (updateManager != null) {
			updateManager.interrupt();
		}
		updateManager = null;
		if (renderer != null) {
			renderer.dispose();
			renderer = null;
		}
		if (bridgeContext != null) {
			bridgeContext.dispose();
			bridgeContext = null;
		}
	}

	/**
	 * Creates a new user agent.
	 */
	protected UserAgent createUserAgent() {
		return new UserAgentAdapter();
	}
<commit_msg>Batik: limited animated SVG to 10 frames/s<commit_after>/*******************************************************************************
 * Copyright (c) 2010-2015 ITER Organization.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 ******************************************************************************/
package org.csstudio.utility.batik;

import java.awt.Dimension;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Dimension2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import java.util.logging.Level;

import org.apache.batik.bridge.BridgeContext;
import org.apache.batik.bridge.DocumentLoader;
import org.apache.batik.bridge.DynamicGVTBuilder;
import org.apache.batik.bridge.GVTBuilder;
import org.apache.batik.bridge.UpdateManagerEvent;
import org.apache.batik.bridge.UpdateManagerListener;
import org.apache.batik.bridge.UserAgent;
import org.apache.batik.bridge.UserAgentAdapter;
import org.apache.batik.bridge.ViewBox;
import org.apache.batik.bridge.svg12.SVG12BridgeContext;
import org.apache.batik.css.engine.CSSStyleSheetNode;
import org.apache.batik.css.engine.SVGCSSEngine;
import org.apache.batik.css.engine.StyleSheet;
import org.apache.batik.dom.svg.SVGDOMImplementation;
import org.apache.batik.dom.svg.SVGOMDocument;
import org.apache.batik.dom.svg.SVGStylableElement;
import org.apache.batik.dom.util.DOMUtilities;
import org.apache.batik.gvt.CanvasGraphicsNode;
import org.apache.batik.gvt.CompositeGraphicsNode;
import org.apache.batik.gvt.GraphicsNode;
import org.apache.batik.gvt.renderer.ConcreteImageRendererFactory;
import org.apache.batik.gvt.renderer.ImageRenderer;
import org.apache.batik.gvt.renderer.ImageRendererFactory;
import org.apache.batik.util.SVGConstants;
import org.apache.commons.lang.time.DateUtils;
import org.csstudio.java.thread.ExecutionService;
import org.csstudio.utility.batik.util.ICSSHandler;
import org.csstudio.utility.batik.util.SVGStylableElementCSSHandler;
import org.csstudio.utility.batik.util.StyleSheetCSSHandler;
import org.eclipse.swt.graphics.Color;
import org.w3c.dom.DOMImplementation;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.svg.SVGDocument;
import org.w3c.dom.svg.SVGSVGElement;

/**
 * {@link SVGDocument} handler. Handles render and animation of SVG files.
 * @author <NAME> (Sopra Steria Group) - ITER
 */
public class SVGHandler {

	private static final int MILLISEC_IN_SEC = 1000;

	protected SVGHandlerListener handlerListener;

	/**
	 * The listener.
	 */
	protected Listener listener;

	/**
	 * The renderer factory.
	 */
	protected ImageRendererFactory rendererFactory = new ConcreteImageRendererFactory();

	/**
	 * The current renderer.
	 */
	protected ImageRenderer renderer;

	/**
	 * The user agent.
	 */
	protected UserAgent userAgent;

	/**
	 * The current bridge context.
	 */
	protected BridgeContext bridgeContext;

	/**
	 * The concrete bridge document loader.
	 */
	protected DocumentLoader loader;

	/**
	 * The update manager.
	 */
	protected UpdateManager updateManager;

	/**
	 * The current SVG document.
	 */
	protected SVGDocument svgDocument;

	protected SVGDocument originalSVGDocument;

	protected Dimension2D originalDimension;

	/**
	 * Whether the current document has dynamic features.
	 */
	protected boolean isDynamicDocument;

	/**
	 * The animation limiting mode.
	 */
	protected int animationLimitingMode;

	/**
	 * The amount of animation limiting.
	 */
	protected float animationLimitingAmount;
	
	protected GVTBuilder builder;

	private RenderingHints renderingHints;
	private float canvasWidth = -1, canvasHeight = -1;
	private Color colorToChange, colorToApply;
	private double[][] matrix = new double[][] { { 1, 0 }, { 0, 1 } };

	private boolean needRender = true;
	private boolean disposed = false;

	private boolean alignedToNearestSecond = false;
	private boolean started = false;
	private boolean suspended = true;

	public SVGHandler(final SVGDocument doc) {
		listener = new Listener();
		userAgent = createUserAgent();
		renderingHints = new RenderingHints(null);

		DOMImplementation impl = SVGDOMImplementation.getDOMImplementation();
		originalSVGDocument = (SVGDocument) DOMUtilities.deepCloneDocument(doc, impl);
		bridgeContext = createBridgeContext((SVGOMDocument) originalSVGDocument);
		isDynamicDocument = bridgeContext.isDynamicDocument(originalSVGDocument);
		// As we update the DOM, it has to be considered as dynamic
		bridgeContext.setDynamicState(BridgeContext.DYNAMIC);
		builder = new DynamicGVTBuilder();
		// Build to calculate original dimension
		GraphicsNode gvtRoot = builder.build(bridgeContext, originalSVGDocument);
		originalDimension = bridgeContext.getDocumentSize();

		svgDocument = (SVGDocument) createWrapper(originalSVGDocument);
		builder.build(bridgeContext, svgDocument);
		buildElementsToUpdateList(bridgeContext, svgDocument);
		if (isDynamicDocument) {
			updateManager = new UpdateManager(bridgeContext, gvtRoot, svgDocument);
			updateManager.addUpdateManagerListener(listener);
		}
		setAnimationLimitingFPS(10);
	}

	public void dispose() {
		disposed = true;
		if (updateManager != null) {
			updateManager.interrupt();
		}
		updateManager = null;
		if (renderer != null) {
			renderer.dispose();
			renderer = null;
		}
		if (bridgeContext != null) {
			bridgeContext.dispose();
			bridgeContext = null;
		}
	}

	/**
	 * Creates a new user agent.
	 */
	protected UserAgent createUserAgent() {
		return new UserAgentAdapter();
	}

{'fraction_non_alphanumeric': 0.12403685092127303, 'fraction_numerical': 0.006365159128978224, 'mean_word_length': 5.107928388746803, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '23302', 'n_tokens_mistral': 3752, 'n_tokens_neox': 3520, 'n_words': 805}