package org.geogebra.web.html5.util; import java.util.HashMap; import java.util.Map.Entry; import org.geogebra.common.awt.GBufferedImage; import org.geogebra.common.io.MyXMLio; import org.geogebra.common.kernel.geos.GeoImage; import org.geogebra.common.util.ImageManager; import org.geogebra.common.util.StringUtil; import org.geogebra.common.util.debug.Log; import org.geogebra.web.html5.css.GuiResourcesSimple; import org.geogebra.web.html5.gawt.GBufferedImageW; import org.geogebra.web.html5.main.AppW; import com.google.gwt.dom.client.Document; import com.google.gwt.dom.client.ImageElement; import com.google.gwt.resources.client.ImageResource; public class ImageManagerW extends ImageManager { private HashMap<String, ImageElement> externalImageTable = new HashMap<String, ImageElement>(); private HashMap<String, String> externalImageSrcs = new HashMap<String, String>(); private boolean preventAuxImage; public void reset() { externalImageTable = new HashMap<String, ImageElement>(); externalImageSrcs = new HashMap<String, String>(); imagesLoaded = 0; construction = null; macros = null; defaults2d = null; defaults3d = null; myXMLio = null; } protected int imagesLoaded = 0; /* * ImageLoadCallback callBack = new ImageLoadCallback() { * * public void onLoad() { imagesLoaded++; checkIfAllLoaded(); } }; */ private String construction, defaults2d, defaults3d, macros; private MyXMLio myXMLio; public void addExternalImage(String fileName, String src) { if (fileName != null && src != null) { Log.debug("addExternalImage: " + fileName); String fn = StringUtil.removeLeadingSlash(fileName); ImageElement img = Document.get().createImageElement(); externalImageSrcs.put(fn, src); externalImageTable.put(fn, img); } } public String getExternalImageSrc(String fileName) { return externalImageSrcs.get(StringUtil.removeLeadingSlash(fileName)); } protected void checkIfAllLoaded(AppW app1) { imagesLoaded++; if (imagesLoaded == externalImageSrcs.size()) { try { Log.debug("images loaded"); // Macros (optional) if (macros != null) { // macros = DataUtil.utf8Decode(macros); // //DataUtil.utf8Decode(macros); myXMLio.processXMLString(macros, true, true); } myXMLio.processXMLString(construction, true, false); // defaults (optional) if (defaults2d != null) { myXMLio.processXMLString(defaults2d, false, true); } if (defaults3d != null) { myXMLio.processXMLString(defaults3d, false, true); } app1.afterLoadFileAppOrNot(); imagesLoaded = 0; } catch (Exception e) { e.printStackTrace(); } } } public ImageElement getExternalImage(String fileName, AppW app1) { ImageElement match = externalImageTable.get(StringUtil .removeLeadingSlash(fileName)); // FIXME this is a bit hacky: if we did not get precise match, assume // encoding problem and rely on MD5 if (match == null && fileName.length() > app1.getMD5folderLength(fileName)) { int md5length = app1.getMD5folderLength(fileName); String md5 = fileName.substring(0, md5length); for (Entry<String, ImageElement> entry : externalImageTable .entrySet()) { String s = entry.getKey(); if (md5.equals(s.substring(0, md5length))) { return entry.getValue(); } } } return match; } public static GBufferedImage toBufferedImage(ImageElement im) { return new GBufferedImageW(im); } static class ImageLoadCallback2 implements ImageLoadCallback { public GeoImage gi; public ImageLoadCallback2(GeoImage gi2) { this.gi = gi2; } @Override public void onLoad() { gi.updateRepaint(); } } static class ImageErrorCallback2 implements ImageLoadCallback { public GeoImage gi; private AppW app; public ImageErrorCallback2(GeoImage gi2, AppW app) { this.gi = gi2; this.app = app; } @Override public void onLoad() { // Image onerror and onabort actually gi.getCorner(0).remove(); gi.getCorner(1).remove(); gi.remove(); app.getKernel().notifyRepaint(); } } public void triggerSingleImageLoading(String imageFileName, GeoImage geoi) { ImageElement img = getExternalImage(imageFileName, (AppW) geoi .getKernel().getApplication()); ImageWrapper.nativeon(img, "load", new ImageLoadCallback2(geoi)); ImageErrorCallback2 i2 = new ImageErrorCallback2(geoi, (AppW) geoi .getKernel().getApplication()); ImageWrapper.nativeon(img, "error", i2); ImageWrapper.nativeon(img, "abort", i2); img.setSrc(externalImageSrcs.get(imageFileName)); } public void triggerImageLoading(String construction, String defaults2d, String defaults3d, String macros, MyXMLio myXMLio, final AppW app) { this.construction = construction; this.defaults2d = defaults2d; this.defaults3d = defaults3d; this.macros = macros; this.myXMLio = myXMLio; if (externalImageSrcs.entrySet() != null) { for (Entry<String, String> imgSrc : externalImageSrcs.entrySet()) { ImageWrapper img = new ImageWrapper( getExternalImage( imgSrc.getKey(), app)); img.attachNativeLoadHandler(this, new ImageLoadCallback() { @Override public void onLoad() { checkIfAllLoaded(app); } }); img.getElement().setSrc(imgSrc.getValue()); } } } /** * @return has images because of async call of geogebra.xml if images * exists, but not loaded yet. */ public boolean hasImages() { return !externalImageTable.isEmpty(); } public static ImageElement getInternalImage(ImageResource resource) { ImageElement img = Document.get().createImageElement(); img.setSrc(resource.getSafeUri().asString()); return img; } public void replace(String fileName, String newName) { if (fileName.equals(newName)) { return; } ImageElement el = this.externalImageTable.get(fileName); String src = this.externalImageSrcs.get(fileName); this.externalImageTable.put(newName, el); this.externalImageSrcs.put(newName, src); } public String getErrorURL() { return GuiResourcesSimple.INSTANCE.questionMark().getSafeUri() .asString(); } public boolean isPreventAuxImage() { if (preventAuxImage) { preventAuxImage = false; return true; } return false; } public void setPreventAuxImage(boolean value) { this.preventAuxImage = value; } }