diff --git a/app/src/cc/arduino/view/preferences/Preferences.java b/app/src/cc/arduino/view/preferences/Preferences.java index 4ea522e35..7b52ccee1 100644 --- a/app/src/cc/arduino/view/preferences/Preferences.java +++ b/app/src/cc/arduino/view/preferences/Preferences.java @@ -197,7 +197,7 @@ public class Preferences extends javax.swing.JDialog { additionalBoardsManagerField.setToolTipText(tr("Enter a comma separated list of urls")); - extendedAdditionalUrlFieldWindow.setIcon(new ImageIcon(Theme.getThemeImage("newwindow.png", this))); + extendedAdditionalUrlFieldWindow.setIcon(new ImageIcon(Theme.getThemeImage("newwindow", this, Theme.scale(16), Theme.scale(14)))); extendedAdditionalUrlFieldWindow.setMargin(new java.awt.Insets(1, 1, 1, 1)); extendedAdditionalUrlFieldWindow.addActionListener(new java.awt.event.ActionListener() { public void actionPerformed(java.awt.event.ActionEvent evt) { diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index c018702fe..575925cb2 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -43,7 +43,6 @@ import processing.app.debug.TargetBoard; import processing.app.debug.TargetPackage; import processing.app.debug.TargetPlatform; import processing.app.helpers.*; -import processing.app.helpers.FileUtils.SplitFile; import processing.app.helpers.filefilters.OnlyDirs; import processing.app.helpers.filefilters.OnlyFilesWithExtension; import processing.app.javax.swing.filechooser.FileNameExtensionFilter; @@ -1743,7 +1742,8 @@ public class Base { */ @SuppressWarnings("serial") public void handleAbout() { - final Image image = Theme.getLibImage("about.png", activeEditor); + final Image image = Theme.getLibImage("about", activeEditor, + Theme.scale(475), Theme.scale(300)); final Window window = new Window(activeEditor) { public void paint(Graphics g) { g.drawImage(image, 0, 0, null); diff --git a/app/src/processing/app/EditorHeader.java b/app/src/processing/app/EditorHeader.java index 5d6b3d104..27d887b25 100644 --- a/app/src/processing/app/EditorHeader.java +++ b/app/src/processing/app/EditorHeader.java @@ -73,6 +73,7 @@ public class EditorHeader extends JComponent { static final int MENU = 3; static final int PIECE_WIDTH = scale(4); + static final int PIECE_HEIGHT = scale(33); // value for the size bars, buttons, etc static final int GRID_SIZE = scale(33); @@ -150,8 +151,12 @@ public class EditorHeader extends JComponent { pieces = new Image[STATUS.length][WHERE.length]; for (int i = 0; i < STATUS.length; i++) { for (int j = 0; j < WHERE.length; j++) { - String path = "tab-" + STATUS[i] + "-" + WHERE[j] + ".png"; - pieces[i][j] = Theme.getThemeImage(path, this); + String path = "tab-" + STATUS[i] + "-" + WHERE[j]; + pieces[i][j] = Theme.getThemeImage(path, this, + // TODO: Refactor this mess... + j == MENU ? PIECE_HEIGHT + : PIECE_WIDTH, + PIECE_HEIGHT); } } } diff --git a/app/src/processing/app/EditorLineStatus.java b/app/src/processing/app/EditorLineStatus.java index a4dc6af0a..1f21590ea 100644 --- a/app/src/processing/app/EditorLineStatus.java +++ b/app/src/processing/app/EditorLineStatus.java @@ -60,7 +60,7 @@ public class EditorLineStatus extends JComponent { high = scale(Theme.getInteger("linestatus.height")); if (OSUtils.isMacOS()) { - resize = Theme.getThemeImage("resize.png", this); + resize = Theme.getThemeImage("resize", this, RESIZE_IMAGE_SIZE, RESIZE_IMAGE_SIZE); } //linestatus.bgcolor = #000000 //linestatus.font = SansSerif,plain,10 diff --git a/app/src/processing/app/EditorToolbar.java b/app/src/processing/app/EditorToolbar.java index 9ca232633..add87784c 100644 --- a/app/src/processing/app/EditorToolbar.java +++ b/app/src/processing/app/EditorToolbar.java @@ -139,7 +139,9 @@ public class EditorToolbar extends JComponent implements MouseInputListener, Key } private void loadButtons() { - Image allButtons = Theme.getThemeImage("buttons.png", this); + Image allButtons = Theme.getThemeImage("buttons", this, + BUTTON_IMAGE_SIZE * BUTTON_COUNT, + BUTTON_IMAGE_SIZE * 3); buttonImages = new Image[BUTTON_COUNT][3]; for (int i = 0; i < BUTTON_COUNT; i++) { diff --git a/app/src/processing/app/Theme.java b/app/src/processing/app/Theme.java index 523c3150b..47eb7c31d 100644 --- a/app/src/processing/app/Theme.java +++ b/app/src/processing/app/Theme.java @@ -21,21 +21,35 @@ package processing.app; -import processing.app.helpers.FileUtils; -import processing.app.helpers.FileUtils.SplitFile; -import processing.app.helpers.OSUtils; -import processing.app.helpers.PreferencesHelper; -import processing.app.helpers.PreferencesMap; +import static processing.app.I18n.tr; -import javax.swing.text.StyleContext; -import java.awt.*; +import java.awt.Color; +import java.awt.Component; +import java.awt.Font; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.RenderingHints; +import java.awt.SystemColor; +import java.awt.Toolkit; import java.awt.font.TextAttribute; +import java.io.ByteArrayOutputStream; import java.io.File; +import java.net.URL; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; -import static processing.app.I18n.tr; +import javax.swing.text.StyleContext; + +import org.apache.batik.transcoder.Transcoder; +import org.apache.batik.transcoder.TranscoderException; +import org.apache.batik.transcoder.TranscoderInput; +import org.apache.batik.transcoder.TranscoderOutput; +import org.apache.batik.transcoder.image.PNGTranscoder; + +import processing.app.helpers.OSUtils; +import processing.app.helpers.PreferencesHelper; +import processing.app.helpers.PreferencesMap; /** * Storage class for theme settings. This was separated from the Preferences @@ -200,51 +214,77 @@ public class Theme { /** * Return an Image object from inside the Processing lib folder. */ - static public Image getLibImage(String filename, Component who) { - Toolkit tk = Toolkit.getDefaultToolkit(); + static public Image getLibImage(String filename, Component who, int width, + int height) { + File libFolder = BaseNoGui.getContentFile("lib"); + Image image = null; - SplitFile name = FileUtils.splitFilename(filename); - int scale = getScale(); - File libFolder = Base.getContentFile("lib"); - File imageFile1x = new File(libFolder, name.basename + "." + name.extension); - File imageFile2x = new File(libFolder, name.basename + "@2x." + name.extension); - - File imageFile; - int sourceScale; - if ((scale > 125 && imageFile2x.exists()) || !imageFile1x.exists()) { - imageFile = imageFile2x; - sourceScale = 200; - } else { - imageFile = imageFile1x; - sourceScale = 100; + // Use vector image when available + File vectorFile = new File(libFolder, filename + ".svg"); + if (vectorFile.exists()) { + try { + image = imageFromSVG(vectorFile.toURI().toURL(), width, height); + } catch (Exception e) { + System.err.println("Failed to load " + vectorFile.getAbsolutePath() + + ": " + e.getMessage()); + } + } + + // Otherwise fall-back to PNG bitmaps + if (image == null) { + File bitmapFile = new File(libFolder, filename + ".png"); + File bitmap2xFile = new File(libFolder, filename + "@2x.png"); + + File imageFile; + if ((getScale() > 125 && bitmap2xFile.exists()) || !bitmapFile.exists()) { + imageFile = bitmap2xFile; + } else { + imageFile = bitmapFile; + } + Toolkit tk = Toolkit.getDefaultToolkit(); + image = tk.getImage(imageFile.getAbsolutePath()); } - Image image = tk.getImage(imageFile.getAbsolutePath()); MediaTracker tracker = new MediaTracker(who); - tracker.addImage(image, 0); try { + tracker.addImage(image, 0); tracker.waitForAll(); } catch (InterruptedException e) { } - if (scale != sourceScale) { - int width = image.getWidth(null) * scale / sourceScale; - int height = image.getHeight(null) * scale / sourceScale; + if (image.getWidth(null) != width || image.getHeight(null) != height) { image = image.getScaledInstance(width, height, Image.SCALE_SMOOTH); - tracker.addImage(image, 1); try { + tracker.addImage(image, 1); tracker.waitForAll(); } catch (InterruptedException e) { } } + return image; } /** * Get an image associated with the current color theme. */ - static public Image getThemeImage(String name, Component who) { - return getLibImage("theme/" + name, who); + static public Image getThemeImage(String name, Component who, int width, + int height) { + return getLibImage("theme/" + name, who, width, height); + } + + private static Image imageFromSVG(URL url, int width, int height) + throws TranscoderException { + Transcoder t = new PNGTranscoder(); + t.addTranscodingHint(PNGTranscoder.KEY_WIDTH, new Float(width)); + t.addTranscodingHint(PNGTranscoder.KEY_HEIGHT, new Float(height)); + + TranscoderInput input = new TranscoderInput(url.toString()); + ByteArrayOutputStream ostream = new ByteArrayOutputStream(); + TranscoderOutput output = new TranscoderOutput(ostream); + t.transcode(input, output); + + byte[] imgData = ostream.toByteArray(); + return Toolkit.getDefaultToolkit().createImage(imgData); } }