From f0d3deb0ebf7d281aa157fb0b803eaafd39d03dc Mon Sep 17 00:00:00 2001 From: David Schweinsberg Date: Sat, 7 Sep 2019 14:52:37 -0700 Subject: Split off sample application --- .gitignore | 1 + .idea/misc.xml | 2 +- sample/images/Typecast.gif | Bin 0 -> 4985 bytes sample/images/crosshair_16x16.gif | Bin 0 -> 853 bytes sample/images/cursor_16x16.gif | Bin 0 -> 863 bytes sample/images/point_and_cursor_16.gif | Bin 0 -> 881 bytes sample/images/point_selected_16.gif | Bin 0 -> 837 bytes .../java/dev/typecast/app/editor/BitmapPanel.java | 63 ++ .../java/dev/typecast/app/editor/DumpPanel.java | 56 ++ .../dev/typecast/app/editor/EditorFileFilter.java | 264 +++++++++ .../java/dev/typecast/app/editor/EditorMenu.java | 643 +++++++++++++++++++++ .../java/dev/typecast/app/editor/EditorPrefs.java | 192 ++++++ .../java/dev/typecast/app/editor/GlyphPanel.java | 101 ++++ .../typecast/app/editor/GlyphPanelStatusBar.java | 131 +++++ .../dev/typecast/app/editor/GlyphPanelToolBar.java | 53 ++ .../typecast/app/editor/MacOSFilenameFilter.java | 93 +++ .../src/net/java/dev/typecast/app/editor/Main.java | 427 ++++++++++++++ .../java/dev/typecast/app/editor/Main.properties | 81 +++ .../net/java/dev/typecast/app/editor/Splash.java | 51 ++ .../dev/typecast/app/editor/TableTreeBuilder.java | 329 +++++++++++ .../typecast/app/editor/TableTreeCellRenderer.java | 89 +++ .../dev/typecast/app/editor/TableTreeNode.java | 50 ++ .../dev/typecast/app/framework/EditorView.java | 29 + .../net/java/dev/typecast/edit/CharacterMap.java | 217 +++++++ sample/src/net/java/dev/typecast/edit/Command.java | 35 ++ .../src/net/java/dev/typecast/edit/GlyphEdit.java | 339 +++++++++++ .../src/net/java/dev/typecast/edit/PointTool.java | 110 ++++ .../net/java/dev/typecast/edit/SelectCommand.java | 39 ++ sample/src/net/java/dev/typecast/edit/Tool.java | 37 ++ src/images/Typecast.gif | Bin 4985 -> 0 bytes src/images/crosshair_16x16.gif | Bin 853 -> 0 bytes src/images/cursor_16x16.gif | Bin 863 -> 0 bytes src/images/point_and_cursor_16.gif | Bin 881 -> 0 bytes src/images/point_selected_16.gif | Bin 837 -> 0 bytes .../java/dev/typecast/app/editor/BitmapPanel.java | 63 -- .../java/dev/typecast/app/editor/DumpPanel.java | 56 -- .../dev/typecast/app/editor/EditorFileFilter.java | 264 --------- .../java/dev/typecast/app/editor/EditorMenu.java | 643 --------------------- .../java/dev/typecast/app/editor/EditorPrefs.java | 192 ------ .../java/dev/typecast/app/editor/GlyphPanel.java | 101 ---- .../typecast/app/editor/GlyphPanelStatusBar.java | 131 ----- .../dev/typecast/app/editor/GlyphPanelToolBar.java | 53 -- .../typecast/app/editor/MacOSFilenameFilter.java | 93 --- src/net/java/dev/typecast/app/editor/Main.java | 427 -------------- .../java/dev/typecast/app/editor/Main.properties | 81 --- src/net/java/dev/typecast/app/editor/Splash.java | 51 -- .../dev/typecast/app/editor/TableTreeBuilder.java | 329 ----------- .../typecast/app/editor/TableTreeCellRenderer.java | 89 --- .../dev/typecast/app/editor/TableTreeNode.java | 50 -- .../dev/typecast/app/framework/EditorView.java | 29 - src/net/java/dev/typecast/edit/CharacterMap.java | 217 ------- src/net/java/dev/typecast/edit/Command.java | 35 -- src/net/java/dev/typecast/edit/GlyphEdit.java | 339 ----------- src/net/java/dev/typecast/edit/PointTool.java | 110 ---- src/net/java/dev/typecast/edit/SelectCommand.java | 39 -- src/net/java/dev/typecast/edit/Tool.java | 37 -- 56 files changed, 3431 insertions(+), 3430 deletions(-) create mode 100644 sample/images/Typecast.gif create mode 100644 sample/images/crosshair_16x16.gif create mode 100644 sample/images/cursor_16x16.gif create mode 100644 sample/images/point_and_cursor_16.gif create mode 100644 sample/images/point_selected_16.gif create mode 100644 sample/src/net/java/dev/typecast/app/editor/BitmapPanel.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/DumpPanel.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/EditorFileFilter.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/EditorMenu.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/EditorPrefs.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/GlyphPanel.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/GlyphPanelStatusBar.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/GlyphPanelToolBar.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/MacOSFilenameFilter.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/Main.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/Main.properties create mode 100644 sample/src/net/java/dev/typecast/app/editor/Splash.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/TableTreeBuilder.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/TableTreeCellRenderer.java create mode 100644 sample/src/net/java/dev/typecast/app/editor/TableTreeNode.java create mode 100644 sample/src/net/java/dev/typecast/app/framework/EditorView.java create mode 100644 sample/src/net/java/dev/typecast/edit/CharacterMap.java create mode 100644 sample/src/net/java/dev/typecast/edit/Command.java create mode 100644 sample/src/net/java/dev/typecast/edit/GlyphEdit.java create mode 100644 sample/src/net/java/dev/typecast/edit/PointTool.java create mode 100644 sample/src/net/java/dev/typecast/edit/SelectCommand.java create mode 100644 sample/src/net/java/dev/typecast/edit/Tool.java delete mode 100644 src/images/Typecast.gif delete mode 100644 src/images/crosshair_16x16.gif delete mode 100644 src/images/cursor_16x16.gif delete mode 100644 src/images/point_and_cursor_16.gif delete mode 100644 src/images/point_selected_16.gif delete mode 100644 src/net/java/dev/typecast/app/editor/BitmapPanel.java delete mode 100644 src/net/java/dev/typecast/app/editor/DumpPanel.java delete mode 100644 src/net/java/dev/typecast/app/editor/EditorFileFilter.java delete mode 100644 src/net/java/dev/typecast/app/editor/EditorMenu.java delete mode 100644 src/net/java/dev/typecast/app/editor/EditorPrefs.java delete mode 100644 src/net/java/dev/typecast/app/editor/GlyphPanel.java delete mode 100644 src/net/java/dev/typecast/app/editor/GlyphPanelStatusBar.java delete mode 100644 src/net/java/dev/typecast/app/editor/GlyphPanelToolBar.java delete mode 100644 src/net/java/dev/typecast/app/editor/MacOSFilenameFilter.java delete mode 100644 src/net/java/dev/typecast/app/editor/Main.java delete mode 100644 src/net/java/dev/typecast/app/editor/Main.properties delete mode 100644 src/net/java/dev/typecast/app/editor/Splash.java delete mode 100644 src/net/java/dev/typecast/app/editor/TableTreeBuilder.java delete mode 100644 src/net/java/dev/typecast/app/editor/TableTreeCellRenderer.java delete mode 100644 src/net/java/dev/typecast/app/editor/TableTreeNode.java delete mode 100644 src/net/java/dev/typecast/app/framework/EditorView.java delete mode 100644 src/net/java/dev/typecast/edit/CharacterMap.java delete mode 100644 src/net/java/dev/typecast/edit/Command.java delete mode 100644 src/net/java/dev/typecast/edit/GlyphEdit.java delete mode 100644 src/net/java/dev/typecast/edit/PointTool.java delete mode 100644 src/net/java/dev/typecast/edit/SelectCommand.java delete mode 100644 src/net/java/dev/typecast/edit/Tool.java diff --git a/.gitignore b/.gitignore index 89f9ac0..3acb573 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ out/ +.DS_Store diff --git a/.idea/misc.xml b/.idea/misc.xml index 1763e15..5a1f3f4 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/sample/images/Typecast.gif b/sample/images/Typecast.gif new file mode 100644 index 0000000..be06124 Binary files /dev/null and b/sample/images/Typecast.gif differ diff --git a/sample/images/crosshair_16x16.gif b/sample/images/crosshair_16x16.gif new file mode 100644 index 0000000..2f0d771 Binary files /dev/null and b/sample/images/crosshair_16x16.gif differ diff --git a/sample/images/cursor_16x16.gif b/sample/images/cursor_16x16.gif new file mode 100644 index 0000000..5a3865e Binary files /dev/null and b/sample/images/cursor_16x16.gif differ diff --git a/sample/images/point_and_cursor_16.gif b/sample/images/point_and_cursor_16.gif new file mode 100644 index 0000000..d2765c9 Binary files /dev/null and b/sample/images/point_and_cursor_16.gif differ diff --git a/sample/images/point_selected_16.gif b/sample/images/point_selected_16.gif new file mode 100644 index 0000000..1507063 Binary files /dev/null and b/sample/images/point_selected_16.gif differ diff --git a/sample/src/net/java/dev/typecast/app/editor/BitmapPanel.java b/sample/src/net/java/dev/typecast/app/editor/BitmapPanel.java new file mode 100644 index 0000000..bd2a927 --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/BitmapPanel.java @@ -0,0 +1,63 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2016 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import javax.imageio.ImageIO; +import javax.swing.JPanel; +import net.java.dev.typecast.app.framework.EditorView; +import net.java.dev.typecast.ot.OTFont; +import net.java.dev.typecast.ot.table.SbixTable; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * A basic bitmap view. + * @author David Schweinsberg + */ +public final class BitmapPanel extends JPanel implements EditorView { + + private BufferedImage _image; + + private static final long serialVersionUID = 1L; + + static final Logger logger = LoggerFactory.getLogger(BitmapPanel.class); + + public BitmapPanel() { + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + g.drawImage(_image, 0, 0, this); + } + + @Override + public void setModel(OTFont font, Object obj) { + SbixTable.GlyphDataRecord gdr = (SbixTable.GlyphDataRecord) obj; + ByteArrayInputStream input = new ByteArrayInputStream(gdr.getData()); + try { + _image = ImageIO.read(input); + } catch (IOException e) { + logger.error("Unable to load image data: " + e.toString()); + } + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/DumpPanel.java b/sample/src/net/java/dev/typecast/app/editor/DumpPanel.java new file mode 100644 index 0000000..b9ac77e --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/DumpPanel.java @@ -0,0 +1,56 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2016 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +import java.awt.BorderLayout; +import java.awt.Font; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextArea; +import net.java.dev.typecast.app.framework.EditorView; +import net.java.dev.typecast.ot.OTFont; + +/** + * A simple view of an object's "toString()" output. + * @author David Schweinsberg + */ +public class DumpPanel extends JPanel implements EditorView { + + private static final long serialVersionUID = 1L; + + private final JTextArea _dumpTextArea; + + /** Creates a new instance of DumpPanel */ + public DumpPanel() { + setLayout(new BorderLayout()); + _dumpTextArea = new JTextArea(); + _dumpTextArea.setEditable(false); + _dumpTextArea.setFont(new Font("Monospaced", Font.PLAIN, 12)); + add(new JScrollPane( + _dumpTextArea, + JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, + JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS), + BorderLayout.CENTER); + } + + @Override + public void setModel(OTFont font, Object obj) { + _dumpTextArea.setText(obj.toString()); + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/EditorFileFilter.java b/sample/src/net/java/dev/typecast/app/editor/EditorFileFilter.java new file mode 100644 index 0000000..15d6a48 --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/EditorFileFilter.java @@ -0,0 +1,264 @@ +/* + * @(#)ExampleFileFilter.java 1.9 99/04/23 + * + * Copyright (c) 1998, 1999 by Sun Microsystems, Inc. All Rights Reserved. + * + * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, + * modify and redistribute this software in source and binary code form, + * provided that i) this copyright notice and license appear on all copies of + * the software; and ii) Licensee does not utilize the software in a manner + * which is disparaging to Sun. + * + * This software is provided "AS IS," without a warranty of any kind. ALL + * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY + * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR + * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE + * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING + * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS + * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, + * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER + * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF + * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGES. + * + * This software is not designed or intended for use in on-line control of + * aircraft, air traffic, aircraft navigation or aircraft communications; or in + * the design, construction, operation or maintenance of any nuclear + * facility. Licensee represents and warrants that it will not use or + * redistribute the Software for such purposes. + */ +package net.java.dev.typecast.app.editor; + +import java.io.File; +import java.util.Hashtable; +import java.util.Enumeration; +import javax.swing.*; +import javax.swing.filechooser.*; + +/** + * A convenience implementation of FileFilter that filters out + * all files except for those type extensions that it knows about. + * + * Extensions are of the type ".foo", which is typically found on + * Windows and Unix boxes, but not on Macinthosh. Case is ignored. + * + * Example - create a new filter that filerts out all files + * but gif and jpg image files: + * + * JFileChooser chooser = new JFileChooser(); + * ExampleFileFilter filter = new ExampleFileFilter( + * new String{"gif", "jpg"}, "JPEG & GIF Images") + * chooser.addChoosableFileFilter(filter); + * chooser.showOpenDialog(this); + * + * @version 1.9 04/23/99 + * @author Jeff Dinkins + */ +public class EditorFileFilter extends FileFilter { + + private static String TYPE_UNKNOWN = "Type Unknown"; + private static String HIDDEN_FILE = "Hidden File"; + + private Hashtable filters = null; + private String description = null; + private String fullDescription = null; + private boolean useExtensionsInDescription = true; + + /** + * Creates a file filter. If no filters are added, then all + * files are accepted. + * + * @see #addExtension + */ + public EditorFileFilter() { + this.filters = new Hashtable(); + } + + /** + * Creates a file filter that accepts files with the given extension. + * Example: new ExampleFileFilter("jpg"); + * + * @see #addExtension + */ + public EditorFileFilter(String extension) { + this(extension,null); + } + + /** + * Creates a file filter that accepts the given file type. + * Example: new ExampleFileFilter("jpg", "JPEG Image Images"); + * + * Note that the "." before the extension is not needed. If + * provided, it will be ignored. + * + * @see #addExtension + */ + public EditorFileFilter(String extension, String description) { + this(); + if(extension!=null) addExtension(extension); + if(description!=null) setDescription(description); + } + + /** + * Creates a file filter from the given string array. + * Example: new ExampleFileFilter(String {"gif", "jpg"}); + * + * Note that the "." before the extension is not needed adn + * will be ignored. + * + * @see #addExtension + */ + public EditorFileFilter(String[] filters) { + this(filters, null); + } + + /** + * Creates a file filter from the given string array and description. + * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images"); + * + * Note that the "." before the extension is not needed and will be ignored. + * + * @see #addExtension + */ + public EditorFileFilter(String[] filters, String description) { + this(); + for (int i = 0; i < filters.length; i++) { + // add filters one by one + addExtension(filters[i]); + } + if(description!=null) setDescription(description); + } + + /** + * Return true if this file should be shown in the directory pane, + * false if it shouldn't. + * + * Files that begin with "." are ignored. + * + * @see #getExtension + * @see FileFilter#accepts + */ + public boolean accept(File f) { + if(f != null) { + if(f.isDirectory()) { + return true; + } + String extension = getExtension(f); + if(extension != null && filters.get(getExtension(f)) != null) { + return true; + }; + } + return false; + } + + /** + * Return the extension portion of the file's name . + * + * @see #getExtension + * @see FileFilter#accept + */ + public String getExtension(File f) { + if(f != null) { + String filename = f.getName(); + int i = filename.lastIndexOf('.'); + if(i>0 && i(5); + } + filters.put(extension.toLowerCase(), this); + fullDescription = null; + } + + + /** + * Returns the human readable description of this filter. For + * example: "JPEG and GIF Image Files (*.jpg, *.gif)" + * + * @see setDescription + * @see setExtensionListInDescription + * @see isExtensionListInDescription + * @see FileFilter#getDescription + */ + public String getDescription() { + if(fullDescription == null) { + if(description == null || isExtensionListInDescription()) { + fullDescription = description==null ? "(" : description + " ("; + // build the description from the extension list + Enumeration extensions = filters.keys(); + if(extensions != null) { + fullDescription += "." + (String) extensions.nextElement(); + while (extensions.hasMoreElements()) { + fullDescription += ", ." + (String) extensions.nextElement(); + } + } + fullDescription += ")"; + } else { + fullDescription = description; + } + } + return fullDescription; + } + + /** + * Sets the human readable description of this filter. For + * example: filter.setDescription("Gif and JPG Images"); + * + * @see setDescription + * @see setExtensionListInDescription + * @see isExtensionListInDescription + */ + public void setDescription(String description) { + this.description = description; + fullDescription = null; + } + + /** + * Determines whether the extension list (.jpg, .gif, etc) should + * show up in the human readable description. + * + * Only relevent if a description was provided in the constructor + * or using setDescription(); + * + * @see getDescription + * @see setDescription + * @see isExtensionListInDescription + */ + public void setExtensionListInDescription(boolean b) { + useExtensionsInDescription = b; + fullDescription = null; + } + + /** + * Returns whether the extension list (.jpg, .gif, etc) should + * show up in the human readable description. + * + * Only relevent if a description was provided in the constructor + * or using setDescription(); + * + * @see getDescription + * @see setDescription + * @see setExtensionListInDescription + */ + public boolean isExtensionListInDescription() { + return useExtensionsInDescription; + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/EditorMenu.java b/sample/src/net/java/dev/typecast/app/editor/EditorMenu.java new file mode 100644 index 0000000..8ab2a66 --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/EditorMenu.java @@ -0,0 +1,643 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +import java.awt.*; +import java.awt.desktop.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.KeyEvent; + +import java.io.StreamTokenizer; +import java.io.StringReader; + +import java.util.ResourceBundle; + +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.JMenuItem; +import javax.swing.JCheckBoxMenuItem; +import javax.swing.JSeparator; +import javax.swing.KeyStroke; + +import net.java.dev.typecast.ot.OTFontCollection; + +/** + * The application menu bar + * @author David Schweinsberg + */ +public class EditorMenu { + + private Main _app; + private ResourceBundle _rb; + private EditorPrefs _prefs; + private OTFontCollection _selectedFontCollection; + private JMenuItem _closeMenuItem; + private String _closeMenuString; + private JCheckBoxMenuItem _previewMenuItem; + private JCheckBoxMenuItem _showPointsMenuItem; + private JCheckBoxMenuItem _showHintsMenuItem; + private boolean _macPlatform; + private int _primaryKeystrokeMask; + private JMenu _mruMenu; + + /** Creates a new instance of EditorMenu */ + public EditorMenu(Main app, ResourceBundle rb, EditorPrefs prefs) { + _app = app; + _rb = rb; + _prefs = prefs; + _primaryKeystrokeMask = + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + if (System.getProperty("os.name").equals("Mac OS X")) { + _macPlatform = true; + registerForMacOSXEvents(); + } else { + _macPlatform = false; + } + } + + public OTFontCollection getSelectedFontCollection() { + return _selectedFontCollection; + } + + public void setSelectedFontCollection(OTFontCollection fc) { + _selectedFontCollection = fc; + if (_selectedFontCollection != null) { + _closeMenuItem.setText( + _closeMenuString + + " \"" + + _selectedFontCollection.getFileName() + + "\""); + _closeMenuItem.setEnabled(true); + } else { + _closeMenuItem.setText(_closeMenuString); + _closeMenuItem.setEnabled(false); + } + } + + public boolean isPreview() { + return _previewMenuItem.getState(); + } + + public boolean isShowPoints() { + return _showPointsMenuItem.getState(); + } + + public boolean isShowHints() { + return _showHintsMenuItem.getState(); + } + + private static void parseMenuString(String menuString, String[] tokens) { + try { + StreamTokenizer st = new StreamTokenizer(new StringReader(menuString)); + st.nextToken(); + if (st.sval != null) { + tokens[0] = st.sval; + } + st.nextToken(); + if (st.sval != null) { + tokens[1] = st.sval; + } + st.nextToken(); + if (st.sval != null) { + tokens[2] = st.sval; + } + } catch (Exception e) { + } + } + + private static JMenuItem createMenuItem( + Class menuClass, + String name, + String mnemonic, + String description, + KeyStroke accelerator, + boolean enabled, + ActionListener al) { + JMenuItem menuItem = null; + try { + menuItem = menuClass.newInstance(); + menuItem.setText(name); + menuItem.setToolTipText(description); + menuItem.setMnemonic(mnemonic.length() > 0 ? mnemonic.charAt(0) : 0); + menuItem.getAccessibleContext().setAccessibleDescription(description); + menuItem.setEnabled(enabled); + if (accelerator != null) { + menuItem.setAccelerator(accelerator); + } + if (al != null) { + menuItem.addActionListener(al); + } + } catch (Exception e) { + } + return menuItem; + } + + private static JMenuItem createMenuItem( + String menuText, + KeyStroke accelerator, + boolean enabled, + ActionListener al) { + String[] tokens = new String[3]; + parseMenuString(menuText, tokens); + return createMenuItem( + JMenuItem.class, + tokens[0], + tokens[1], + tokens[2], + accelerator, + enabled, + al); + } + + private static JCheckBoxMenuItem createCheckBoxMenuItem( + String menuText, + KeyStroke accelerator, + ActionListener al) { + String[] tokens = new String[3]; + parseMenuString(menuText, tokens); + return (JCheckBoxMenuItem) createMenuItem( + JCheckBoxMenuItem.class, + tokens[0], + tokens[1], + tokens[2], + accelerator, + true, + al); + } + + private static JMenu createMenu(String menuText) { + String[] tokens = new String[3]; + parseMenuString(menuText, tokens); + return (JMenu) createMenuItem(JMenu.class, tokens[0], tokens[1], tokens[2], null, true, null); + } + + public JMenuBar createMenuBar() { + JMenuBar menuBar = new JMenuBar(); + menuBar.add(createFileMenu()); + menuBar.add(createEditMenu()); + menuBar.add(createViewMenu()); + //menuBar.add(createElementMenu()); + //menuBar.add(createPointsMenu()); + //menuBar.add(createMetricsMenu()); + if (_macPlatform) { + menuBar.add(createWindowMenu()); + } + menuBar.add(createHelpMenu()); + return menuBar; + } + + private JMenu createFileMenu() { + JMenu menu = createMenu(_rb.getString("Typecast.menu.file")); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.file.new"), + KeyStroke.getKeyStroke(KeyEvent.VK_N, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.file.open"), + KeyStroke.getKeyStroke(KeyEvent.VK_O, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _app.openFont(); + } + })); + _mruMenu = createMenu(_rb.getString("Typecast.menu.file.openRecent")); + menu.add(_mruMenu); + + // Generate a MRU list + buildMRU(); + + menu.add(new JSeparator()); + menu.add(_closeMenuItem = createMenuItem( + _rb.getString("Typecast.menu.file.close"), + null, + false, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _app.closeFont(); + } + })); + _closeMenuString = _closeMenuItem.getText(); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.file.save"), + KeyStroke.getKeyStroke(KeyEvent.VK_S, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.file.saveAs"), + KeyStroke.getKeyStroke( + KeyEvent.VK_S, + _primaryKeystrokeMask | KeyEvent.SHIFT_MASK), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.file.saveAll"), + null, + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.file.revertToSaved"), + null, + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.file.export"), + null, + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _app.exportFont(); + } + })); + if (!_macPlatform) { + menu.add(new JSeparator()); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.file.preferences"), + null, + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + } + + // Only add "Exit" to the menu if this isn't a Mac + if (!_macPlatform) { + menu.add(new JSeparator()); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.file.exit"), + null, + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _app.close(); + } + })); + } + return menu; + } + + private JMenu createEditMenu() { + JMenu menu = createMenu(_rb.getString("Typecast.menu.edit")); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.edit.undo"), + KeyStroke.getKeyStroke(KeyEvent.VK_Z, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.edit.redo"), + KeyStroke.getKeyStroke(KeyEvent.VK_Y, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + menu.add(new JSeparator()); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.edit.cut"), + KeyStroke.getKeyStroke(KeyEvent.VK_X, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.edit.copy"), + KeyStroke.getKeyStroke(KeyEvent.VK_C, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.edit.paste"), + KeyStroke.getKeyStroke(KeyEvent.VK_V, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.edit.clear"), + KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + //menu.add(createMenuItem( + // _rb.getString("Typecast.menu.edit.copyWidths"), + // null, + // new ActionListener() { + // public void actionPerformed(ActionEvent e) { + // } + // })); + //menu.add(createMenuItem( + // _rb.getString("Typecast.menu.edit.copyReference"), + // null, + // new ActionListener() { + // public void actionPerformed(ActionEvent e) { + // } + // })); + //menu.add(createMenuItem( + // _rb.getString("Typecast.menu.edit.unlinkReference"), + // null, + // new ActionListener() { + // public void actionPerformed(ActionEvent e) { + // } + // })); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.edit.selectAll"), + KeyStroke.getKeyStroke(KeyEvent.VK_A, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + //menu.add(createMenuItem( + // _rb.getString("Typecast.menu.edit.duplicate"), + // KeyStroke.getKeyStroke(KeyEvent.VK_D, _primaryKeystrokeMask), + // new ActionListener() { + // public void actionPerformed(ActionEvent e) { + // } + // })); + //menu.add(createMenuItem( + // _rb.getString("Typecast.menu.edit.clone"), + // null, + // new ActionListener() { + // public void actionPerformed(ActionEvent e) { + // } + // })); + return menu; + } + + private JMenu createViewMenu() { + JMenu menu = createMenu(_rb.getString("Typecast.menu.view")); + menu.add(_previewMenuItem = createCheckBoxMenuItem( + _rb.getString("Typecast.menu.view.preview"), + KeyStroke.getKeyStroke(KeyEvent.VK_L, _primaryKeystrokeMask), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _app.changeGlyphView(); + } + })); + menu.add(_showPointsMenuItem = createCheckBoxMenuItem( + _rb.getString("Typecast.menu.view.showPoints"), + KeyStroke.getKeyStroke(KeyEvent.VK_P, _primaryKeystrokeMask), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _app.changeGlyphView(); + } + })); + menu.add(_showHintsMenuItem = createCheckBoxMenuItem( + _rb.getString("Typecast.menu.view.showHints"), + KeyStroke.getKeyStroke(KeyEvent.VK_H, _primaryKeystrokeMask), + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _app.changeGlyphView(); + } + })); + _showPointsMenuItem.setState(true); + JMenu subMenu = createMenu(_rb.getString("Typecast.menu.view.magnification")); + menu.add(subMenu); + subMenu.add(createMenuItem( + _rb.getString("Typecast.menu.view.magnification.fitInWindow"), + KeyStroke.getKeyStroke(KeyEvent.VK_T, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + subMenu.add(new JSeparator()); + subMenu.add(createMenuItem( + _rb.getString("Typecast.menu.view.magnification.00625"), + KeyStroke.getKeyStroke(KeyEvent.VK_1, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + subMenu.add(createMenuItem( + _rb.getString("Typecast.menu.view.magnification.01250"), + KeyStroke.getKeyStroke(KeyEvent.VK_2, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + subMenu.add(createMenuItem( + _rb.getString("Typecast.menu.view.magnification.02500"), + KeyStroke.getKeyStroke(KeyEvent.VK_3, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + subMenu.add(createMenuItem( + _rb.getString("Typecast.menu.view.magnification.05000"), + KeyStroke.getKeyStroke(KeyEvent.VK_4, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + subMenu.add(createMenuItem( + _rb.getString("Typecast.menu.view.magnification.10000"), + KeyStroke.getKeyStroke(KeyEvent.VK_5, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + subMenu.add(createMenuItem( + _rb.getString("Typecast.menu.view.magnification.20000"), + KeyStroke.getKeyStroke(KeyEvent.VK_6, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + })); + return menu; + } + + private JMenu createElementMenu() { + JMenu menu = createMenu(_rb.getString("Typecast.menu.element")); + + JMenuItem menuItem = menu.add(new JMenuItem("New")); + menuItem.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + } + ); + return menu; + } + + private JMenu createPointsMenu() { + JMenu menu = createMenu(_rb.getString("Typecast.menu.points")); + + JMenuItem menuItem = menu.add(new JMenuItem("New")); + menuItem.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + } + ); + return menu; + } + + private JMenu createMetricsMenu() { + JMenu menu = createMenu(_rb.getString("Typecast.menu.metrics")); + + JMenuItem menuItem = menu.add(new JMenuItem("New")); + menuItem.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + } + } + ); + return menu; + } + + private JMenu createWindowMenu() { + JMenu menu = createMenu(_rb.getString("Typecast.menu.window")); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.help.about"), + null, + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _app.showAbout(); + } + })); + return menu; + } + + private JMenu createHelpMenu() { + JMenu menu = createMenu(_rb.getString("Typecast.menu.help")); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.help.typecast"), + KeyStroke.getKeyStroke(KeyEvent.VK_SLASH, _primaryKeystrokeMask), + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _app.showHelp(); + } + })); + if (!_macPlatform) { + menu.add(new JSeparator()); + menu.add(createMenuItem( + _rb.getString("Typecast.menu.help.about"), + null, + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _app.showAbout(); + } + })); + } + return menu; + } + + private void buildMRU() { + _mruMenu.removeAll(); + for (int i = 0; i < _prefs.getMRUCount(); ++i) { + String mru = _prefs.getMRU(i); + if (mru != null) { + JMenuItem menuItem = _mruMenu.add(new JMenuItem( + mru, + KeyEvent.VK_0 + i)); + menuItem.getAccessibleContext().setAccessibleDescription( + "Recently used font"); + menuItem.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _app.loadFont(e.getActionCommand()); + } + } + ); + } + } + if (_prefs.getMRUCount() == 0) { + + // Add a placeholder + JMenuItem menuItem = _mruMenu.add(new JMenuItem("Recently used files")); + menuItem.setEnabled(false); + } + _mruMenu.add(new JSeparator()); + _mruMenu.add(createMenuItem( + _rb.getString("Typecast.menu.file.openRecent.clearMenu"), + null, + true, + new ActionListener() { + public void actionPerformed(ActionEvent e) { + _prefs.clearMRU(); + buildMRU(); + } + })); + } + + public void addMru(String mru) { + _prefs.addMRU(mru); + buildMRU(); + } + + // Generic registration with the macOS application menu + public void registerForMacOSXEvents() { + Desktop desktop = Desktop.getDesktop(); + desktop.setQuitHandler(new QuitHandler() { + @Override + public void handleQuitRequestWith(QuitEvent e, QuitResponse response) { + _app.close(); + } + }); + desktop.setAboutHandler(new AboutHandler() { + @Override + public void handleAbout(AboutEvent e) { + _app.showAbout(); + } + }); + desktop.setPreferencesHandler(new PreferencesHandler() { + @Override + public void handlePreferences(PreferencesEvent e) { + _app.showPreferences(); + } + }); + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/EditorPrefs.java b/sample/src/net/java/dev/typecast/app/editor/EditorPrefs.java new file mode 100644 index 0000000..054eee0 --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/EditorPrefs.java @@ -0,0 +1,192 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2007 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +import java.util.ArrayList; +import java.util.ListIterator; + +import java.util.prefs.Preferences; + +import java.awt.Point; +import java.awt.Dimension; + +/** + * A class to handle all the various application preferences + * @author David Schweinsberg + */ +public class EditorPrefs { + + public static final int maxMRUCount = 10; + + // Key strings + private static final String APP_WINDOW_POS = "app_position"; + private static final String APP_WINDOW_SIZE = "app_size"; + private static final String TREE_WIDTH = "tree_width"; + private static final String MRU_COUNT = "mru_count"; + private static final String MRU_PREFIX = "mru_"; + + // Default values + private static final int APP_WINDOW_POS_X_DEFAULT = 0; + private static final int APP_WINDOW_POS_Y_DEFAULT = 0; + private static final int APP_WINDOW_SIZE_WIDTH_DEFAULT = 640; + private static final int APP_WINDOW_SIZE_HEIGHT_DEFAULT = 480; + private static final int TREE_WIDTH_DEFAULT = 200; + private static final int MRU_COUNT_DEFAULT = 0; + + private Point _appWindowPos; + private Dimension _appWindowSize; + private int _treeWidth; + private ArrayList _mru = new ArrayList(); + + /** Creates a new instance of TypecastPrefs */ + public EditorPrefs() { + } + + public void load(Preferences prefs) { + _appWindowPos = getPosition( + prefs, + APP_WINDOW_POS, + new Point(APP_WINDOW_POS_X_DEFAULT, APP_WINDOW_POS_Y_DEFAULT)); + _appWindowSize = getSize( + prefs, + APP_WINDOW_SIZE, + new Dimension( + APP_WINDOW_SIZE_WIDTH_DEFAULT, + APP_WINDOW_SIZE_HEIGHT_DEFAULT)); + _treeWidth = prefs.getInt(TREE_WIDTH, TREE_WIDTH_DEFAULT); + int mruCount = prefs.getInt(MRU_COUNT, MRU_COUNT_DEFAULT); + for (int i = 0; i < mruCount; ++i) { + _mru.add(prefs.get(MRU_PREFIX + Integer.toString(i), null)); + } + } + + public void save(Preferences prefs) { + putPosition(prefs, APP_WINDOW_POS, _appWindowPos); + putSize(prefs, APP_WINDOW_SIZE, _appWindowSize); + prefs.putInt(TREE_WIDTH, _treeWidth); + prefs.putInt(MRU_COUNT, getMRUCount()); + for (int i = 0; i < getMRUCount(); ++i) { + prefs.put(MRU_PREFIX + Integer.toString(i), _mru.get(i)); + } + } + + public Point getAppWindowPos() { + return _appWindowPos; + } + + public void setAppWindowPos(Point pos) { + _appWindowPos = pos; + } + + public Dimension getAppWindowSize() { + return _appWindowSize; + } + + public void setAppWindowSize(Dimension size) { + _appWindowSize = size; + } + + public int getTreeWidth() { + return _treeWidth; + } + + public void setTreeWidth(int width) { + _treeWidth = width; + } + + public int getMRUCount() { + return _mru.size(); + } + + public String getMRU(int index) { + return _mru.get(index); + } + + public void addMRU(String mru) { + + // Is this string already in the list? + ListIterator iter = _mru.listIterator(); + while (iter.hasNext()) { + if (iter.next().equals(mru)) { + return; + } + } + + // Insert this file at the beginning of the list and remove any that + // drop off the end of the list + _mru.add(0, mru); + if (_mru.size() > maxMRUCount) { + _mru.remove(maxMRUCount); + } + } + + public void clearMRU() { + _mru.clear(); + } + + public float getZoom() { + return 0.25f; + } + + public void setZoom(float factor) { + + } + + /** + * Read a position string from preferences + */ + public static Point getPosition(Preferences prefs, String keyName, Point defaultPos) { + String position = prefs.get( + keyName, + defaultPos.x + "," + defaultPos.y); + try { + int i = position.indexOf(','); + int x = Integer.parseInt(position.substring(0, i)); + int y = Integer.parseInt(position.substring(i + 1)); + return new Point(x, y); + } catch(Exception e) { + return defaultPos; + } + } + + public static void putPosition(Preferences prefs, String keyName, Point pos) { + prefs.put(keyName, pos.x + "," + pos.y); + } + + /** + * Read a size string from preferences + */ + public static Dimension getSize(Preferences prefs, String keyName, Dimension defaultSize) { + String size = prefs.get( + keyName, + defaultSize.width + "x" + defaultSize.height); + try { + int i = size.indexOf('x'); + int w = Integer.parseInt(size.substring(0, i)); + int h = Integer.parseInt(size.substring(i + 1)); + return new Dimension(w, h); + } catch(Exception e) { + return defaultSize; + } + } + + public static void putSize(Preferences prefs, String keyName, Dimension size) { + prefs.put(keyName, size.width + "x" + size.height); + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/GlyphPanel.java b/sample/src/net/java/dev/typecast/app/editor/GlyphPanel.java new file mode 100644 index 0000000..5aeb06e --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/GlyphPanel.java @@ -0,0 +1,101 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2015 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +import java.awt.BorderLayout; +import java.awt.Color; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import net.java.dev.typecast.app.framework.EditorView; +import net.java.dev.typecast.cff.CharstringType2; +import net.java.dev.typecast.edit.GlyphEdit; +import net.java.dev.typecast.ot.OTFont; +import net.java.dev.typecast.ot.T2Glyph; +import net.java.dev.typecast.ot.TTGlyph; +import net.java.dev.typecast.ot.table.GlyphDescription; + +/** + * + * @author David Schweinsberg + */ +public class GlyphPanel extends JPanel implements EditorView { + + private static final long serialVersionUID = 1L; + + private final EditorPrefs _prefs; + private final GlyphEdit _glyphEdit = new GlyphEdit(); + private final GlyphPanelToolBar _toolBar = new GlyphPanelToolBar(); + private final GlyphPanelStatusBar _glyphPanelStatusBar = + new GlyphPanelStatusBar(); + + /** Creates new GlyphPanel */ + public GlyphPanel(EditorPrefs prefs) { + _prefs = prefs; + setName("Outline"); + setLayout(new BorderLayout()); + + // Toolbar + add(_toolBar, BorderLayout.NORTH); + + // Editor + _glyphEdit.setBackground(Color.white); + _glyphEdit.setScaleFactor(_prefs.getZoom()); + add(new JScrollPane( + _glyphEdit, + JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, + JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS), + BorderLayout.CENTER); + + // Status bar + _glyphPanelStatusBar.setGlyphEdit(_glyphEdit); + add(_glyphPanelStatusBar, BorderLayout.SOUTH); + } + + /** + * The GlyphPanel deals with GlyphDescriptions, so the Object parameter must + * implement the GlyphDescription interface. + */ + @Override + public void setModel(OTFont font, Object obj) { + if (obj instanceof GlyphDescription) { + _glyphEdit.setFont(font); + GlyphDescription gd = (GlyphDescription) obj; + _glyphEdit.setGlyph(new TTGlyph( + gd, + font.getHmtxTable().getLeftSideBearing(gd.getGlyphIndex()), + font.getHmtxTable().getAdvanceWidth(gd.getGlyphIndex()))); + } + else if (obj instanceof CharstringType2) { + _glyphEdit.setFont(font); + CharstringType2 cs = (CharstringType2) obj; + _glyphEdit.setGlyph(new T2Glyph( + cs, + font.getHmtxTable().getLeftSideBearing(cs.getIndex()), + font.getHmtxTable().getAdvanceWidth(cs.getIndex()))); + } + } + + public GlyphEdit getGlyphEdit() { + return _glyphEdit; + } + + public void setProperties() { + _prefs.setZoom((float)_glyphEdit.getScaleFactor()); + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/GlyphPanelStatusBar.java b/sample/src/net/java/dev/typecast/app/editor/GlyphPanelStatusBar.java new file mode 100644 index 0000000..e90ebaa --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/GlyphPanelStatusBar.java @@ -0,0 +1,131 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +import java.awt.GridLayout; + +import java.awt.event.MouseEvent; + +import java.net.URL; + +import java.util.Set; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.SwingConstants; + +import javax.swing.event.MouseInputListener; + +import net.java.dev.typecast.edit.GlyphEdit; + +import net.java.dev.typecast.ot.Point; + +/** + * + * @author David Schweinsberg + */ +public class GlyphPanelStatusBar extends JPanel { + + private static final long serialVersionUID = 1L; + + private GlyphEdit _glyphEdit; + private JLabel _cursorPos; + private JLabel _selPos; + private JLabel _selDelta; + + /** Creates new GlyphEditStatusBar */ + public GlyphPanelStatusBar() { + setLayout(new GridLayout(1, 5)); + URL iconURL = ClassLoader.getSystemResource("images/cursor_16x16.gif"); + add(_cursorPos = new JLabel( + "0, 0", + new ImageIcon(iconURL), + SwingConstants.LEFT)); + iconURL = ClassLoader.getSystemResource("images/point_selected_16.gif"); + add(_selPos = new JLabel( + "---, ---", + new ImageIcon(iconURL), + SwingConstants.LEFT)); + iconURL = ClassLoader.getSystemResource( + "images/point_and_cursor_16.gif"); + add(_selDelta = new JLabel( + "---, ---", + new ImageIcon(iconURL), + SwingConstants.LEFT)); + } + + public GlyphEdit getGlyphEdit() { + return _glyphEdit; + } + + public void setGlyphEdit(GlyphEdit glyphEdit) { + _glyphEdit = glyphEdit; + + // Create a MouseInputListener to track the location of the cursor + // within the GlyphEdit window + MouseInputListener mil = new MouseInputListener() { + public void mouseClicked(MouseEvent e) { } + public void mouseEntered(MouseEvent e) { } + public void mouseExited(MouseEvent e) { } + public void mousePressed(MouseEvent e) { + setCursorStatus(e.getX(), e.getY()); + setSelectedStatus(); + } + public void mouseReleased(MouseEvent e) { } + public void mouseDragged(MouseEvent e) { + setCursorStatus(e.getX(), e.getY()); + setSelectedStatus(); + } + public void mouseMoved(MouseEvent e) { + setCursorStatus(e.getX(), e.getY()); + } + }; + glyphEdit.addMouseListener(mil); + glyphEdit.addMouseMotionListener(mil); + } + + private void setCursorStatus(int x, int y) { + double f = _glyphEdit.getScaleFactor(); + int x1 = (int)((double) x / f - (double) _glyphEdit.getTranslateX()); + int y1 = -(int)((double) y / f - (double) _glyphEdit.getTranslateY()); + + // Cursor position + _cursorPos.setText(x1 + ", " + y1); + + // Difference between cursor and selected point + Set s = _glyphEdit.getSelectedPoints(); + if (s.size() == 1) { + Point p = (Point) s.iterator().next(); + _selDelta.setText((x1 - p.x) + ", " + (y1 - p.y)); + } else { + _selDelta.setText("---, ---"); + } + } + + private void setSelectedStatus() { + Set s = _glyphEdit.getSelectedPoints(); + if (s.size() == 1) { + Point p = (Point) s.iterator().next(); + _selPos.setText(p.x + ", " + p.y); + } else { + _selPos.setText("---, ---"); + } + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/GlyphPanelToolBar.java b/sample/src/net/java/dev/typecast/app/editor/GlyphPanelToolBar.java new file mode 100644 index 0000000..22f229d --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/GlyphPanelToolBar.java @@ -0,0 +1,53 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2016 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +import java.net.URL; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JToolBar; + +/** + * + * @author David Schweinsberg + */ +public class GlyphPanelToolBar extends JToolBar { + + private static final long serialVersionUID = 1L; + + /** Creates new GlyphPanelToolBar */ + public GlyphPanelToolBar() { + URL iconURL = ClassLoader.getSystemResource("images/cursor_16x16.gif"); + JButton button = new JButton(new ImageIcon(iconURL)); + add(button); + + iconURL = ClassLoader.getSystemResource("images/crosshair_16x16.gif"); + button = new JButton(new ImageIcon(iconURL)); + add(button); + + iconURL = ClassLoader.getSystemResource("toolbarButtonGraphics/general/ZoomIn16.gif"); + button = new JButton(new ImageIcon(iconURL)); + add(button); + + iconURL = ClassLoader.getSystemResource("toolbarButtonGraphics/general/ZoomOut16.gif"); + button = new JButton(new ImageIcon(iconURL)); + add(button); + } + +} diff --git a/sample/src/net/java/dev/typecast/app/editor/MacOSFilenameFilter.java b/sample/src/net/java/dev/typecast/app/editor/MacOSFilenameFilter.java new file mode 100644 index 0000000..c88de5a --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/MacOSFilenameFilter.java @@ -0,0 +1,93 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2007 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +import java.io.BufferedInputStream; +import java.io.DataInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.io.FileNotFoundException; +import java.io.IOException; + +import net.java.dev.typecast.ot.mac.ResourceHeader; +import net.java.dev.typecast.ot.mac.ResourceMap; +import net.java.dev.typecast.ot.mac.ResourceType; + +/** + * A FilenameFilter implementation that includes font files based on their + * extension and also by the presence of fonts in the resource fork. + * @author David Schweinsberg + */ +public class MacOSFilenameFilter implements FilenameFilter { + + /** Creates a new instance of MacOSFilenameFilter */ + public MacOSFilenameFilter() { + } + + public boolean accept(File dir, String name) { + if (name.endsWith(".ttf") + || name.endsWith(".ttc") + || name.endsWith(".otf") + || name.endsWith(".dfont") + || name.endsWith(".suit")) { + return true; + } else if (name.indexOf('.') == -1) { + + // This filename has no extension, so we'll look into any + // resource fork. But first, if there is data in the data fork, + // then we'll reject this as a font file + File dataFork = new File(dir, name); + if (dataFork.length() > 0) { + return false; + } + + // OK, go for the resource fork + File file = new File(dataFork, "..namedfork/rsrc"); + if (file.exists() && file.length() > 0) { + try { + DataInputStream dis = new DataInputStream( + new BufferedInputStream( + new FileInputStream(file), (int) file.length())); + dis.mark((int) file.length()); + + // Is this a Macintosh font suitcase resource? + ResourceHeader resourceHeader = new ResourceHeader(dis); + + // Seek to the map offset and read the map + dis.reset(); + dis.skip(resourceHeader.getMapOffset()); + ResourceMap map = new ResourceMap(dis); + + // Get any 'sfnt' resources + ResourceType resourceType = map.getResourceType("sfnt"); + dis.close(); + if (resourceType != null) { + return true; + } + } catch (FileNotFoundException e) { + // ignore + } catch (IOException e) { + // ignore + } + } + } + return false; + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/Main.java b/sample/src/net/java/dev/typecast/app/editor/Main.java new file mode 100644 index 0000000..2ed9582 --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/Main.java @@ -0,0 +1,427 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2016 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + + +import java.awt.Cursor; +import java.awt.FileDialog; +import java.awt.HeadlessException; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.ArrayList; +import java.util.ResourceBundle; +import java.util.prefs.Preferences; +import javax.swing.JFileChooser; +import javax.swing.JFrame; +import javax.swing.JOptionPane; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.JTree; +import javax.swing.ToolTipManager; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreePath; +import net.java.dev.typecast.edit.CharacterMap; +import net.java.dev.typecast.exchange.Exporter; +import net.java.dev.typecast.exchange.SVGExporter; +import net.java.dev.typecast.ot.OTFont; +import net.java.dev.typecast.ot.OTFontCollection; +import net.java.dev.typecast.ot.table.GlyphDescription; +import net.java.dev.typecast.ot.table.TableException; + +/** + * @author David Schweinsberg + */ +public class Main { + + private EditorMenu _menu; + private JFrame _frame; + private JTree _tree; + private JSplitPane _splitPane; + private DefaultTreeModel _treeModel; + private ArrayList _fontCollections = new ArrayList<>(); + private EditorPrefs _appPrefs = new EditorPrefs(); + private JTabbedPane _tabbedPane; + private GlyphPanel _glyphPane; + private Object _treeSelection; + private ResourceBundle _rb; + private OTFont _selectedFont = null; + private TableTreeNode _selectedCollectionNode; + + /** + * Typecast constructor. + */ + public Main() { + + // Before loading Swing, set macOS-specific properties + System.setProperty("apple.awt.application.name", "Typecast"); + System.setProperty("apple.laf.useScreenMenuBar", "true"); + + // Show a splash screen whilst we load up + Splash splash = new Splash(); + splash.setVisible(true); + + // TESTING: The following will be moved to a properties file +// _modelViewPairs.add(new ModelViewPair( +// GlyfDescript.class, +// GlyphPanel.class)); +// _modelViewPairs.add(new ModelViewPair( +// net.java.dev.typecast.ot.table.CmapFormat.class, +// CharacterMap.class)); + + try { + // Set the L&F appropriate for the OS + // (Mac automatically selects Aqua, but Windows goes for Metal) + if (System.getProperty("os.name").startsWith("Windows")) { + UIManager.setLookAndFeel( + "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); + } + + // Load the user's application preferences + _appPrefs.load(Preferences.userNodeForPackage(getClass())); + + // Load the resource bundle + _rb = ResourceBundle.getBundle("sample/app/editor/Main"); + + _frame = new JFrame( + _rb.getString("Typecast.title") + + " " + + _rb.getString("Typecast.version")); + _frame.setLocation(_appPrefs.getAppWindowPos()); + _frame.setPreferredSize(_appPrefs.getAppWindowSize()); + + _treeModel = (DefaultTreeModel) TableTreeBuilder.createTypecastTreeModel(); + _tree = new JTree(_treeModel); + _tree.setRootVisible(false); + _tree.setShowsRootHandles(true); + + // Enable tool tips for the tree, without this tool tips will not + // be picked up + ToolTipManager.sharedInstance().registerComponent(_tree); + + // Make the tree use an instance of TableTreeCellRenderer for + // drawing + _tree.setCellRenderer(new TableTreeCellRenderer()); + + // Put the Tree in a scroller + JScrollPane treePane = new JScrollPane( + JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, + JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); + treePane.getViewport().add(_tree); + + treePane.setBorder(null); + + // Listen for selection events from the tree + TreeSelectionListener tsl = (TreeSelectionEvent e) -> { + TreePath selPath = e.getPath(); + if(selPath != null) { + + // Pick the font collection out of the path + if (selPath.getPathCount() >= 2) { + _selectedCollectionNode = + (TableTreeNode) selPath.getPathComponent(1); + _menu.setSelectedFontCollection( + (OTFontCollection) + _selectedCollectionNode.getUserObject()); + } + + // Pick the selected font out of the path + OTFont font = null; + if (selPath.getPathCount() >= 3) { + TableTreeNode fontNode = + (TableTreeNode) selPath.getPathComponent(2); + font = (OTFont) fontNode.getUserObject(); + } + + // Now get the actually selected node + TableTreeNode tn = + (TableTreeNode) selPath.getLastPathComponent(); + selectElement(font, tn); + } + }; + _tree.addTreeSelectionListener(tsl); + + // Create a tabbed workspace + _tabbedPane = new JTabbedPane(); + + // Split the main frame + _splitPane = new JSplitPane( + JSplitPane.HORIZONTAL_SPLIT, + treePane, + _tabbedPane); + _splitPane.setOneTouchExpandable(true); + _splitPane.setDividerLocation(_appPrefs.getTreeWidth()); + _frame.getContentPane().add("Center", _splitPane); + + _splitPane.setBorder(null); + + // Create a menu bar + _menu = new EditorMenu(this, _rb, _appPrefs); + _frame.setJMenuBar(_menu.createMenuBar()); + + _frame.addWindowListener( + new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + close(); + } + } + ); + + // We're built, so make the main frame visible and hide the splash + _frame.pack(); + _frame.setVisible(true); + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException | HeadlessException e) { + JOptionPane.showMessageDialog( + null, + e.toString(), + "Exception", + JOptionPane.ERROR_MESSAGE); + } finally { + splash.setVisible(false); + } + } + + protected void loadFont(String pathName) { + _frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + try { + File file = new File(pathName); + OTFontCollection fc = OTFontCollection.create(file); + _fontCollections.add(fc); + + // Create the tree to put the information in + TableTreeBuilder.addFontTree(_treeModel, fc); + } catch (IOException e) { + JOptionPane.showMessageDialog( + null, + e.toString(), + "I/O Exception", + JOptionPane.ERROR_MESSAGE); + } catch (Exception e) { + JOptionPane.showMessageDialog( + null, + e.toString(), + "Exception", + JOptionPane.ERROR_MESSAGE); + } + _frame.setCursor(Cursor.getDefaultCursor()); + } + + public static void main(String[] args) { + new Main(); + } + + /** + * Display a file chooser and open the selected font file + */ + protected void openFont() { + String pathName = null; + + // Display a file chooser, depending on what OS we're running on + if (System.getProperty("os.name").equals("Mac OS X")) { + FileDialog fd = new FileDialog(_frame, "Open Font"); + fd.setFilenameFilter(new MacOSFilenameFilter()); + fd.setVisible(true); + if (fd.getFile() != null) { + pathName = fd.getDirectory() + fd.getFile(); + } + } else { + JFileChooser chooser = new JFileChooser(); + + EditorFileFilter filter = new EditorFileFilter(); + filter.addExtension("ttf"); + filter.addExtension("ttc"); + filter.addExtension("otf"); + filter.addExtension("dfont"); + filter.setDescription("OpenType Fonts"); + + chooser.setFileFilter(filter); + + if (chooser.showOpenDialog(_frame) == JFileChooser.APPROVE_OPTION) { + pathName = chooser.getSelectedFile().getPath(); + } + } + + if (pathName != null) { + loadFont(pathName); + _menu.addMru(pathName); + } + } + + /** + * Close the currently selected font + */ + protected void closeFont() { + _fontCollections.remove( + (OTFontCollection) _selectedCollectionNode.getUserObject()); + _treeModel.removeNodeFromParent(_selectedCollectionNode); + selectElement(null, null); + _menu.setSelectedFontCollection(null); + } + + /** + * At this time the only format we export to is SVG + */ + protected void exportFont() { + if (_selectedFont != null) { + JFileChooser chooser = new JFileChooser(); + + EditorFileFilter filter = new EditorFileFilter(); + filter.addExtension("svg"); + filter.setDescription("Scalable Vector Graphics"); + + chooser.setFileFilter(filter); + + if (chooser.showSaveDialog(_frame) == JFileChooser.APPROVE_OPTION) { + try { + try (FileOutputStream fos = new FileOutputStream(chooser.getSelectedFile().getPath())) { + Exporter exporter = new SVGExporter(_selectedFont); + exporter.export(fos); + } + } catch (IOException | TableException e) { + JOptionPane.showMessageDialog( + null, + e.toString(), + "Exception", + JOptionPane.ERROR_MESSAGE); + } + } + } + } + + protected void showHelp() { + JOptionPane.showMessageDialog( + null, + "Typecast currently has no help.", + "Typecast Help", + JOptionPane.INFORMATION_MESSAGE); + } + + protected void showAbout() { + JOptionPane.showMessageDialog( + null, + _rb.getString("Typecast.title") + + " " + + _rb.getString("Typecast.version") + + " - " + + _rb.getString("Typecast.shortDesc") + + "\n" + + _rb.getString("Typecast.copyright") + + "\n" + + _rb.getString("Typecast.copyright2") + + "\n" + + _rb.getString("Typecast.webHome"), + _rb.getString("Typecast.about.title"), + JOptionPane.INFORMATION_MESSAGE); + } + + protected void showPreferences() { + JOptionPane.showMessageDialog( + null, + "Typecast currently has no preferences page.", + "Typecast Preferences", + JOptionPane.INFORMATION_MESSAGE); + } + + protected void close() { + + // Save the user's application preferences + _appPrefs.setAppWindowPos(_frame.getLocation()); + _appPrefs.setAppWindowSize(_frame.getSize()); + _appPrefs.setTreeWidth(_splitPane.getDividerLocation()); + _appPrefs.save(Preferences.userNodeForPackage(getClass())); + + // End the application + System.exit(0); + } + + protected void changeGlyphView() { + _glyphPane.getGlyphEdit().setPreview(_menu.isPreview()); + _glyphPane.getGlyphEdit().setDrawControlPoints(_menu.isShowPoints()); + _glyphPane.getGlyphEdit().setDrawHints(_menu.isShowHints()); + _glyphPane.getGlyphEdit().repaint(); + } + + private void selectElement(OTFont font, TableTreeNode tn) { + + // Note that this font is currently selected + _selectedFont = font; + + Object obj = (tn != null) ? tn.getUserObject() : null; + + // Check that we actually have work to do + if (_treeSelection == obj) { + return; + } + + // Configure the tabbed pane + _tabbedPane.removeAll(); + + // Add all the panes we're interested in +// for (ModelViewPair p : _modelViewPairs) { +// if (p._model.isInstance(obj)) { +// Component view = p._view.newInstance(); +// if (view instanceof EditorView) { +// ((EditorView)view).setModel(font, obj); +// } +// _tabbedPane.add(view); +// } +// } + + // Then add the panes we're interested in + if (obj instanceof GlyphDescription + || obj instanceof net.java.dev.typecast.cff.Charstring) { + _glyphPane = new GlyphPanel(_appPrefs); + _glyphPane.setModel(font, obj); + _tabbedPane.add(_glyphPane); + } + + // Character maps + if (obj instanceof net.java.dev.typecast.ot.table.CmapFormat) { + CharacterMap cm = new CharacterMap(); + cm.setModel(_selectedFont, obj); + _tabbedPane.add(cm); + } + + // Bitmaps + if (obj instanceof net.java.dev.typecast.ot.table.SbixTable.GlyphDataRecord) { + BitmapPanel bitmapPanel = new BitmapPanel(); + bitmapPanel.setName("Bitmap"); + bitmapPanel.setModel(_selectedFont, obj); + _tabbedPane.add(bitmapPanel); + } + + // All selections get a "dump" pane + if (obj != null) { + DumpPanel textPane = new DumpPanel(); + textPane.setName("Dump"); + textPane.setModel(_selectedFont, obj); + _tabbedPane.add(textPane); + } + + _treeSelection = obj; + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/Main.properties b/sample/src/net/java/dev/typecast/app/editor/Main.properties new file mode 100644 index 0000000..6d44a51 --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/Main.properties @@ -0,0 +1,81 @@ +# +# Typecast - The Font Development Environment +# +# Copyright (c) 2004-2016 David Schweinsberg +# +# Licensed 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. +# + +Typecast.title=Typecast +Typecast.version=0.6.0 +Typecast.shortDesc=An OpenType Font Development Environment +Typecast.copyright=Copyright \u00a9 2004-2015 David Schweinsberg +Typecast.copyright2=This product includes software developed by the Apache Software Foundation (http://www.apache.org/). +Typecast.webHome=https://github.com/dcsch/typecast + +Typecast.about.title=About Typecast + +# Menu properties +Typecast.menu.file=File F "File menu" +Typecast.menu.edit=Edit E "Edit menu" +Typecast.menu.view=View V "View menu" +#Typecast.menu.edit.clone=Clone E "Clone the selection" +#Typecast.menu.edit.duplicate=Duplicate D "Duplicate the selection" +Typecast.menu.edit.selectAll="Select All" A "Select everything" +#Typecast.menu.edit.unlinkReference="Unlink Reference" N "Replace the referenced glyph with an explicit glyph" +#Typecast.menu.edit.copyReference="Copy Reference" O "Copy a reference of the glyph to the clipboard" +Typecast.menu.window=Window W "Window menu" +Typecast.menu.help=Help H "Help menu" +#Typecast.menu.metrics=Metrics M "Metrics menu" +#Typecast.menu.points=Points P "Points menu" +#Typecast.menu.element=Element L "Element menu" + +#Typecast.menu.edit.copyWidths="Copy Widths" W "Copy the character width to the clipboard" +Typecast.menu.edit.clear=Clear L "Clear the selection" +Typecast.menu.edit.paste=Paste P "Paste from the clipboard" +Typecast.menu.edit.copy=Copy C "Copy the selection" +Typecast.menu.edit.cut=Cut T "Cut the selection" +Typecast.menu.edit.redo=Redo R "Redo the last undo" +Typecast.menu.edit.undo=Undo U "Undo the last operation" + +#Typecast.menu.view.nextCharacter="Next Character" C "Next Character" +Typecast.menu.view.magnification.02500="25%" "2" "25%" +Typecast.menu.view.magnification.01250="12.5%" "1" "12.5%" +Typecast.menu.view.magnification.00625="6.25%" "6" "6.25%" +Typecast.menu.view.magnification.fitInWindow="Fit In Window" F "Fit In Window" +Typecast.menu.view.magnification=Magnification M "Magnification" + +Typecast.menu.help.about="About Typecast" A "About Typecast" +Typecast.menu.help.typecast="Typecast Help" T "Typecast Help" + +Typecast.menu.view.magnification.20000="200%" "2" "200%" +Typecast.menu.view.magnification.10000="100%" "1" "100%" +Typecast.menu.view.magnification.05000="50%" "5" "50%" +Typecast.menu.view.showPoints="Show Points" S "Show Points" +Typecast.menu.view.showHints="Show Hints" H "Show Hints" +Typecast.menu.view.preview=Preview P "Preview" + +Typecast.menu.file.new=New N "Create a new font" +Typecast.menu.file.open=Open... O "Open an existing font" +Typecast.menu.file.openRecent="Open Recent" R "Open a recently used font" +Typecast.menu.file.openRecent.clearMenu="Clear Menu" C "Clear the list of recently used fonts" +#Typecast.menu.file.mru=Recently used font +Typecast.menu.file.close=Close C "Close the selected font" +Typecast.menu.file.save=Save S "Save the selected font" +Typecast.menu.file.saveAs="Save As..." A "Save the selected font with a new file name" +Typecast.menu.file.saveAll="Save All" L "Save all modified fonts" +Typecast.menu.file.revertToSaved="Revert to Saved" R "Revert to the saved version of the font" +Typecast.menu.file.export="Export..." E "Export the selected font" +Typecast.menu.file.preferences=Preferences P "Show the preferences dialog" +Typecast.menu.file.exit=Exit X "Exit Typecast" + diff --git a/sample/src/net/java/dev/typecast/app/editor/Splash.java b/sample/src/net/java/dev/typecast/app/editor/Splash.java new file mode 100644 index 0000000..bcaed4b --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/Splash.java @@ -0,0 +1,51 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +import java.awt.Dimension; +import java.awt.Image; +import java.awt.Toolkit; + +import java.net.URL; + +import javax.swing.JWindow; + +/** + * + * @author David Schweinsberg + */ +public class Splash extends JWindow { + + private static final long serialVersionUID = 1L; + + private Image image; + + /** Creates new Splash */ + public Splash() { + Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); + URL imageURL = ClassLoader.getSystemResource("images/Typecast.gif"); + image = Toolkit.getDefaultToolkit().getImage(imageURL); + setSize(300, 480); + setLocation(d.width/2 - 150, d.height/2 - 240); + } + + public void paint(java.awt.Graphics graphics) { + graphics.drawImage(image, 0, 0, this); + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/TableTreeBuilder.java b/sample/src/net/java/dev/typecast/app/editor/TableTreeBuilder.java new file mode 100644 index 0000000..732b95e --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/TableTreeBuilder.java @@ -0,0 +1,329 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2016 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeModel; +import net.java.dev.typecast.cff.CffFont; +import net.java.dev.typecast.cff.Charstring; +import net.java.dev.typecast.cff.NameIndex; +import net.java.dev.typecast.ot.OTFont; +import net.java.dev.typecast.ot.OTFontCollection; +import net.java.dev.typecast.ot.table.CffTable; +import net.java.dev.typecast.ot.table.CmapIndexEntry; +import net.java.dev.typecast.ot.table.CmapTable; +import net.java.dev.typecast.ot.table.DirectoryEntry; +import net.java.dev.typecast.ot.table.Feature; +import net.java.dev.typecast.ot.table.GlyfCompositeComp; +import net.java.dev.typecast.ot.table.GlyfCompositeDescript; +import net.java.dev.typecast.ot.table.GlyfDescript; +import net.java.dev.typecast.ot.table.GlyfTable; +import net.java.dev.typecast.ot.table.GsubTable; +import net.java.dev.typecast.ot.table.ID; +import net.java.dev.typecast.ot.table.LangSys; +import net.java.dev.typecast.ot.table.Lookup; +import net.java.dev.typecast.ot.table.LookupSubtable; +import net.java.dev.typecast.ot.table.NameRecord; +import net.java.dev.typecast.ot.table.NameTable; +import net.java.dev.typecast.ot.table.PostTable; +import net.java.dev.typecast.ot.table.SbixTable; +import net.java.dev.typecast.ot.table.Script; +import net.java.dev.typecast.ot.table.Table; + +/** + * @author David Schweinsberg + */ +public class TableTreeBuilder { + + private static void addCmapTable(TableTreeNode parent, CmapTable ct) { + + int lastPlatformId = -1; + int lastEncodingId = -1; + TableTreeNode platformNode = null; + TableTreeNode encodingNode = null; + + for (int i = 0; i < ct.getNumTables(); i++) { + CmapIndexEntry cie = ct.getCmapIndexEntry(i); + + // Have we created the proper grouping? + if (lastPlatformId != cie.getPlatformId()) { + lastPlatformId = cie.getPlatformId(); + lastEncodingId = -1; + String s = "Platform ID: " + cie.getPlatformId() + " (" + + ID.getPlatformName((short) cie.getPlatformId()) + ")"; + platformNode = createNode(s, null); + parent.add(platformNode); + } + if (lastEncodingId != cie.getEncodingId()) { + lastEncodingId = cie.getEncodingId(); + String s = "Encoding ID: " + cie.getEncodingId() + " (" + + ID.getEncodingName( + (short) cie.getPlatformId(), + (short) cie.getEncodingId()) + ")"; + encodingNode = createNode(s, cie.getFormat()); + platformNode.add(encodingNode); + } + } + } + + private static void addNameTable(TableTreeNode parent, NameTable nt) { + + short lastPlatformId = -1; + short lastEncodingId = -1; + short lastLanguageId = -1; + TableTreeNode platformNode = null; + TableTreeNode encodingNode = null; + TableTreeNode languageNode = null; + + for (int i = 0; i < nt.getNumberOfNameRecords(); i++) { + NameRecord nr = nt.getRecord(i); + + // Have we created the proper grouping? + if (lastPlatformId != nr.getPlatformId()) { + lastPlatformId = nr.getPlatformId(); + lastEncodingId = -1; + lastLanguageId = -1; +// String s = "Platform ID: " + lastPlatformId; + String s = "Platform ID: " + nr.getPlatformId() + " (" + + ID.getPlatformName(nr.getPlatformId()) + ")"; + platformNode = createNode(s, null); + parent.add(platformNode); + } + if (lastEncodingId != nr.getEncodingId()) { + lastEncodingId = nr.getEncodingId(); + lastLanguageId = -1; +// String s = "Encoding ID: " + lastEncodingId; + String s = "Encoding ID: " + nr.getEncodingId() + " (" + + ID.getEncodingName(nr.getPlatformId(), nr.getEncodingId()) + ")"; + encodingNode = createNode(s, null); + platformNode.add(encodingNode); + } + if (lastLanguageId != nr.getLanguageId()) { + lastLanguageId = nr.getLanguageId(); +// String s = "Language ID: " + lastLanguageId; + String s = "Language ID: " + nr.getLanguageId() + " (" + + ID.getLanguageName(nr.getPlatformId(), nr.getLanguageId()) + ")"; + languageNode = createNode(s, null); + encodingNode.add(languageNode); + } + String s = "" + nr.getNameId() + " (" + ID.getNameName(nr.getNameId()) + ")"; +// TypecastTreeNode node = createNode(Integer.toString(nr.getNameId()), nr); + TableTreeNode node = createNode(s, nr); + languageNode.add(node); + } + } + + private static void addFeatures(TableTreeNode parent, GsubTable gt, LangSys ls) { + for (int i = 0; i < ls.getFeatureCount(); i++) { + int index = ls.getFeatureIndex(i); + String featureTag = gt.getFeatureList().getFeatureRecord(index).getTagAsString(); + Feature f = gt.getFeatureList().getFeature(index); + TableTreeNode featureNode = new TableTreeNode(featureTag, f); + parent.add(featureNode); + + // Add feature lookups + for (int j = 0; j < f.getLookupCount(); j++) { + Lookup l = gt.getLookupList().getLookup(f.getLookupListIndex(j)); + String type = GsubTable.lookupTypeAsString(l.getType()); + TableTreeNode lookupNode = new TableTreeNode(type, l); + featureNode.add(lookupNode); + + // Add lookup subtables + for (int k = 0; k < l.getSubtableCount(); k++) { + LookupSubtable lsub = l.getSubtable(k); + + // For some reason, lsub can be null + // TODO: find out why + if (lsub != null) { + TableTreeNode lsubNode = new TableTreeNode( + lsub.getTypeAsString(), + lsub); + lookupNode.add(lsubNode); + } + } + } + } + } + + private static void addGsubTable(TableTreeNode parent, GsubTable gt) { + + for (int i = 0; i < gt.getScriptList().getScriptCount(); i++) { + String tag = gt.getScriptList().getScriptRecord(i).getTagAsString(); + Script s = gt.getScriptList().getScript(i); + TableTreeNode scriptNode = new TableTreeNode(tag, s); + parent.add(scriptNode); + + // Add the default LangSys node + TableTreeNode langSysNode = new TableTreeNode( + "default", + s.getDefaultLangSys()); + scriptNode.add(langSysNode); + addFeatures(langSysNode, gt, s.getDefaultLangSys()); + + // Add any additional ones + for (int j = 0; j < s.getLangSysCount(); j++) { + String langSysTag = s.getLangSysRecord(j).getTagAsString(); + LangSys ls = s.getLangSys(j); + langSysNode = new TableTreeNode(langSysTag, ls); + scriptNode.add(langSysNode); + addFeatures(langSysNode, gt, ls); + } + } + } + + private static void addGlyfComposite(OTFont font, TableTreeNode parent, GlyfCompositeDescript gcd) { + PostTable postTable = (PostTable) font.getTable(Table.post); + for (int i = 0; i < gcd.getComponentCount(); i++) { + GlyfCompositeComp gcc = gcd.getComponent(i); + parent.add(new TableTreeNode( + String.valueOf(gcc.getGlyphIndex()) + + ((postTable.getVersion() == 0x00020000) ? + (" " + postTable.getGlyphName(gcc.getGlyphIndex())) : + ""), + gcc, + i)); + } + } + + private static void addGlyfTable(OTFont font, TableTreeNode parent, GlyfTable gt) { + PostTable postTable = (PostTable) font.getTable(Table.post); + for (int i = 0; i < font.getNumGlyphs(); i++) { + GlyfDescript gd = gt.getDescription(i); + TableTreeNode n = new TableTreeNode( + String.valueOf(i) + + ((postTable.getVersion() == 0x00020000) ? + (" " + postTable.getGlyphName(i)) : + ""), + gd, + i); + parent.add(n); + if ((gd != null) && gd.isComposite()) { + + // We need to add the constituent glyphs + addGlyfComposite(font, n, (GlyfCompositeDescript) gd); + } + } + } + + private static void addCffFont( + OTFont font, + TableTreeNode parent, + CffFont cf) { + for (int i = 0; i < cf.getCharstringCount(); ++i) { + Charstring cs = cf.getCharstring(i); + TableTreeNode n = new TableTreeNode( + String.valueOf(i) + " " + cs.getName(), + cs, + i); + parent.add(n); + } + } + + private static void addCffTable(OTFont font, TableTreeNode parent, CffTable ct) { + NameIndex ni = ct.getNameIndex(); + for (int i = 0; i < ni.getCount(); ++i) { + TableTreeNode n = new TableTreeNode( + ni.getName(i), + ni, + i); + parent.add(n); + addCffFont(font, n, ct.getFont(i)); + } + } + + private static void addSbixStrike(OTFont font, TableTreeNode parent, SbixTable.Strike strike) { + int i = 0; + for (SbixTable.GlyphDataRecord gdr : strike.getGlyphDataRecords()) { + TableTreeNode n = new TableTreeNode( + String.valueOf(i), + gdr, + i++); + parent.add(n); + } + } + + private static void addSbixTable(OTFont font, TableTreeNode parent, SbixTable sbix) { + int i = 0; + for (SbixTable.Strike strike : sbix.getStrikes()) { + TableTreeNode n = new TableTreeNode( + strike.toString(), + strike, + i++); + parent.add(n); + addSbixStrike(font, n, strike); + } + } + + private static void addTableDirectoryEntry(OTFont font, TableTreeNode parent, DirectoryEntry de) { + TableTreeNode node = createNode(de.getTagAsString(), font.getTable(de.getTag())); + parent.add(node); + switch (de.getTag()) { + case Table.name: + addNameTable(node, (NameTable) font.getTable(Table.name)); + break; + case Table.cmap: + addCmapTable(node, (CmapTable) font.getTable(Table.cmap)); + break; + case Table.glyf: + addGlyfTable(font, node, (GlyfTable) font.getTable(Table.glyf)); + break; + case Table.CFF: + addCffTable(font, node, (CffTable) font.getTable(Table.CFF)); + break; + case Table.GSUB: + addGsubTable(node, (GsubTable) font.getTable(Table.GSUB)); + break; + case Table.sbix: + addSbixTable(font, node, (SbixTable) font.getTable(Table.sbix)); + break; + default: + break; + } + } + + public static void addFontTree(TreeModel treeModel, OTFontCollection fc) { + + TableTreeNode fcNode = createNode(fc.getPathName(), fc); + ((TableTreeNode) treeModel.getRoot()).add(fcNode); + + // Add each font in this collection + for (int i = 0; i < fc.getFontCount(); i++) { + OTFont font = fc.getFont(i); + TableTreeNode node = createNode( + font.getNameTable().getRecordString(ID.nameFullFontName), + font); + fcNode.add(node); + for (int j = 0; j < font.getTableDirectory().getNumTables(); j++) { + DirectoryEntry de = font.getTableDirectory().getEntry(j); + addTableDirectoryEntry(font, node, de); + } + } + ((DefaultTreeModel) treeModel).reload(); + } + + public static TreeModel createTypecastTreeModel() { + TableTreeNode node = createNode("Root", null); + TreeModel treeModel = new DefaultTreeModel(node); + return treeModel; + } + + private static TableTreeNode createNode(String name, Object obj) { + return new TableTreeNode(name, obj); + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/TableTreeCellRenderer.java b/sample/src/net/java/dev/typecast/app/editor/TableTreeCellRenderer.java new file mode 100644 index 0000000..ef23909 --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/TableTreeCellRenderer.java @@ -0,0 +1,89 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +import java.awt.Font; +import java.awt.Graphics; +import java.awt.SystemColor; + +import javax.swing.Icon; +import javax.swing.JLabel; +import javax.swing.JTree; + +import javax.swing.tree.TreeCellRenderer; + +/** + * @author David Schweinsberg + */ +public class TableTreeCellRenderer extends JLabel implements TreeCellRenderer { + + private static final long serialVersionUID = 1L; + + private boolean _selected; + private Font font = new java.awt.Font("SansSerif", java.awt.Font.PLAIN, 12); + + public java.awt.Component getTreeCellRendererComponent( + JTree tree, + Object value, + boolean selected, + boolean expanded, + boolean leaf, + int row, + boolean hasFocus) { + + String str = tree.convertValueToText( + value, + selected, + expanded, + leaf, + row, + hasFocus); + setFont(font); + setText(str); + setToolTipText(str); + if (leaf) { + setIcon(null); + } else { + setIcon(null); + } + setForeground( + selected ? + SystemColor.textHighlightText : + SystemColor.textText); + _selected = selected; + return this; + } + + public void paint(Graphics g) { + if (_selected) { + g.setColor(SystemColor.textHighlight); + } else if(getParent() != null) { + g.setColor(getParent().getBackground()); + } else { + g.setColor(getBackground()); + } + Icon icon = getIcon(); + int offset = 0; + if (icon != null && getText() != null) { + offset = icon.getIconWidth() + getIconTextGap(); + } + g.fillRect(offset, 0, getWidth() - 1 - offset, getHeight() - 1); + super.paint(g); + } +} diff --git a/sample/src/net/java/dev/typecast/app/editor/TableTreeNode.java b/sample/src/net/java/dev/typecast/app/editor/TableTreeNode.java new file mode 100644 index 0000000..7718eef --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/editor/TableTreeNode.java @@ -0,0 +1,50 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2016 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.editor; + +/** + * + * @author David Schweinsberg + */ +public class TableTreeNode extends javax.swing.tree.DefaultMutableTreeNode { + + private static final long serialVersionUID = 1L; + + private String _nodeName; + private int _index; + + /** Creates new TableTreeNode */ + public TableTreeNode(String nodeName, Object userObject, int index) { + super(userObject); + _nodeName = nodeName; + _index = index; + } + + public TableTreeNode(String nodeName, Object userObject) { + this(nodeName, userObject, -1); + } + + public int getIndex() { + return _index; + } + + public String toString() { + return _nodeName; + } +} diff --git a/sample/src/net/java/dev/typecast/app/framework/EditorView.java b/sample/src/net/java/dev/typecast/app/framework/EditorView.java new file mode 100644 index 0000000..f97e982 --- /dev/null +++ b/sample/src/net/java/dev/typecast/app/framework/EditorView.java @@ -0,0 +1,29 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2016 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.app.framework; + +import net.java.dev.typecast.ot.OTFont; + +/** + * The standard interface for all Typecast editor "view" components. + * @author David Schweinsberg + */ +public interface EditorView { + public void setModel(OTFont font, Object obj); +} diff --git a/sample/src/net/java/dev/typecast/edit/CharacterMap.java b/sample/src/net/java/dev/typecast/edit/CharacterMap.java new file mode 100644 index 0000000..5b95e02 --- /dev/null +++ b/sample/src/net/java/dev/typecast/edit/CharacterMap.java @@ -0,0 +1,217 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2016 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.edit; + +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.awt.geom.AffineTransform; +import java.util.ArrayList; +import javax.swing.AbstractListModel; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.JScrollPane; +import javax.swing.ListCellRenderer; +import net.java.dev.typecast.app.framework.EditorView; +import net.java.dev.typecast.ot.OTFont; +import net.java.dev.typecast.ot.table.CmapFormat; +import net.java.dev.typecast.render.GlyphImageFactory; + +/** + * An editor for the character-to-glyph map, as represented in the CmapTable. + * @author David Schweinsberg + */ +public class CharacterMap extends JScrollPane implements EditorView { + + private static final long serialVersionUID = 1L; + + private static final int CELL_WIDTH = 48; + private static final int CELL_HEIGHT = 60; + + private AbstractListModel _listModel; + private CmapFormat _cmapFormat; + private OTFont _font; + private AffineTransform _tx; + private final Font _labelFont = new Font("SansSerif", Font.PLAIN, 10); + + private class Mapping { + + private final int _charCode; + private final int _glyphCode; + + public Mapping(int charCode, int glyphCode) { + _charCode = charCode; + _glyphCode = glyphCode; + } + + public int getCharCode() { + return _charCode; + } + + public int getGlyphCode() { + return _glyphCode; + } + + public Image getGlyphImage() { + + // NOTE: We're not caching the image as we can be dealing with + // quite a lot of them + return GlyphImageFactory.buildImage( + _font.getGlyph(_glyphCode), + _tx, + CELL_WIDTH, + CELL_HEIGHT - 10); + } + } + + private class CharListCellRenderer extends JComponent implements ListCellRenderer { + + private static final long serialVersionUID = 1L; + + private Mapping _mapping; + private int _index; + private boolean _isSelected; + private final AffineTransform _imageTx = + new AffineTransform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); + + /** + * Renders each individual cell + */ + @Override + protected void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + + if (_isSelected) { + g2d.setColor(Color.BLACK); + g2d.fillRect(0, CELL_HEIGHT - 10, CELL_WIDTH, 10); + g2d.setColor(Color.WHITE); + } else { + g2d.setColor(Color.WHITE); + g2d.fillRect(0, CELL_HEIGHT - 10, CELL_WIDTH, 10); + g2d.setColor(Color.BLACK); + } + + // Draw the glyph + g2d.drawImage(_mapping.getGlyphImage(), _imageTx, null); + + // Label this cell with the character code + g2d.setFont(_labelFont); + g2d.drawString( + String.format("%04X", _mapping.getCharCode()), + 1, + CELL_HEIGHT - 1); + } + + @Override + public Component getListCellRendererComponent( + JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + _mapping = (Mapping) value; + _index = index; + _isSelected = isSelected; + setPreferredSize(new Dimension(CELL_WIDTH + 1, CELL_HEIGHT + 1)); + setToolTipText(String.format("Glyph ID: %d", + _mapping.getGlyphCode())); + return this; + } + } + + /** Creates a new instance of CharacterMap */ + public CharacterMap() { + super( + JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, + JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); + setName("Character Map"); + } + + @Override + public void setModel(OTFont font, Object obj) { + if (obj instanceof CmapFormat) { + _font = font; + _cmapFormat = (CmapFormat) obj; + + // Set up a list model to wrap the cmap + _listModel = new AbstractListModel() { + + private static final long serialVersionUID = 1L; + private final ArrayList _mappings = new ArrayList<>(); + + { + for (int i = 0; i < _cmapFormat.getRangeCount(); ++i) { + CmapFormat.Range range = _cmapFormat.getRange(i); + for (int j = range.getStartCode(); j <= range.getEndCode(); ++j) { + _mappings.add(new Mapping(j, _cmapFormat.mapCharCode(j))); + } + } + } + + @Override + public Object getElementAt(int index) { + return _mappings.get(index); + } + + @Override + public int getSize() { + return _mappings.size(); + } + }; + + final JList list = new JList(_listModel); + list.setBackground(Color.LIGHT_GRAY); + list.setCellRenderer(new CharListCellRenderer()); + list.setLayoutOrientation(JList.HORIZONTAL_WRAP); + list.setVisibleRowCount( + _listModel.getSize() / 16 + + (_listModel.getSize() % 16 > 0 ? 1 : 0)); + setViewportView(list); + + // Create a mouse listener so we can listen to double-clicks + MouseListener mouseListener = new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + int index = list.locationToIndex(e.getPoint()); + } + } + }; + list.addMouseListener(mouseListener); + + // int unitsPerEmBy2 = _font.getHeadTable().getUnitsPerEm() / 2; + // int translateX = 2 * unitsPerEmBy2; + // int translateY = 2 * unitsPerEmBy2; + + // How much should we scale the font to fit it into our tiny bitmap? + double scaleFactor = 40.0 / _font.getHeadTable().getUnitsPerEm(); + + _tx = new AffineTransform(); + _tx.translate(2, CELL_HEIGHT - 20); + _tx.scale(scaleFactor, -scaleFactor); + } + } +} diff --git a/sample/src/net/java/dev/typecast/edit/Command.java b/sample/src/net/java/dev/typecast/edit/Command.java new file mode 100644 index 0000000..5ac42d6 --- /dev/null +++ b/sample/src/net/java/dev/typecast/edit/Command.java @@ -0,0 +1,35 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.edit; + +/** + * + * @author David Schweinsberg + */ +public abstract class Command { + + /** Creates new Command */ + public Command() { + } + + abstract void execute(); + + abstract void unexecute(); + +} diff --git a/sample/src/net/java/dev/typecast/edit/GlyphEdit.java b/sample/src/net/java/dev/typecast/edit/GlyphEdit.java new file mode 100644 index 0000000..a70d1e7 --- /dev/null +++ b/sample/src/net/java/dev/typecast/edit/GlyphEdit.java @@ -0,0 +1,339 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004-2016 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.edit; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.event.MouseEvent; +import java.awt.geom.AffineTransform; +import java.awt.geom.GeneralPath; +import java.awt.geom.Line2D; +import java.awt.geom.Rectangle2D; +import java.util.HashSet; +import java.util.Set; +import javax.swing.JPanel; +import javax.swing.Scrollable; +import javax.swing.event.MouseInputListener; +import net.java.dev.typecast.ot.Glyph; +import net.java.dev.typecast.ot.OTFont; +import net.java.dev.typecast.ot.Point; +import net.java.dev.typecast.ot.T2Glyph; +import net.java.dev.typecast.render.GlyphPathFactory; + +/** + * The glyph editor. The user will perform operations on the glyph within this + * window using a variety of tools derived from {@link Tool Tool}. + * @author David Schweinsberg + */ +public class GlyphEdit extends JPanel implements Scrollable { + + private static final long serialVersionUID = 1L; + + private Glyph _glyph = null; + private OTFont _font = null; + private Tool _tool = null; + private GeneralPath _glyphPath; + + private int _translateX = 0; + private int _translateY = 0; + private double _scaleFactor = 0.25f; + + private boolean _drawControlPoints = true; + private boolean _drawHints = false; + private boolean _preview = false; + private final Set _selectedPoints = new HashSet<>(); + + /** Creates new GlyphEdit */ + public GlyphEdit() { + + setName("ContourView"); + setLayout(null); + + _tool = new PointTool(this); + + MouseInputListener mil = new MouseInputListener() { + @Override + public void mouseClicked(MouseEvent e) { + } + @Override + public void mouseEntered(MouseEvent e) { } + @Override + public void mouseExited(MouseEvent e) { } + @Override + public void mousePressed(MouseEvent e) { + if (_tool != null) { + if (e.isControlDown()) { + _tool.pressedControl(e.getPoint()); + } else { + _tool.pressed(e.getPoint()); + } + } + } + @Override + public void mouseReleased(MouseEvent e) { + if (_tool != null) { + _tool.released(e.getPoint()); + } + } + @Override + public void mouseDragged(MouseEvent e) { + if (_tool != null) { + _tool.dragged(e.getPoint()); + } + } + @Override + public void mouseMoved(MouseEvent e) { } + }; + addMouseListener(mil); + addMouseMotionListener(mil); + } + + @Override + public void paint(Graphics graphics) { + super.paint(graphics); + + if (_glyph == null) { + return; + } + + Graphics2D g2d = (Graphics2D) graphics; + + int unitsPerEmBy2 = _font.getHeadTable().getUnitsPerEm() / 2; + _translateX = 2 * unitsPerEmBy2; + _translateY = 2 * unitsPerEmBy2; + + AffineTransform at = g2d.getTransform(); + AffineTransform atOriginal = new AffineTransform(at); + at.scale(_scaleFactor, _scaleFactor); + at.translate(_translateX, _translateY); + at.scale(1.0, -1.0); + g2d.setTransform(at); + + // Draw grid + g2d.setPaint(Color.gray); + g2d.draw(new Line2D.Float(-unitsPerEmBy2, 0, unitsPerEmBy2, 0)); + g2d.draw(new Line2D.Float(0, -unitsPerEmBy2, 0, unitsPerEmBy2)); + + // Draw guides + g2d.setPaint(Color.lightGray); + g2d.draw(new Line2D.Float(-unitsPerEmBy2, _font.getAscent(), unitsPerEmBy2, _font.getAscent())); + g2d.draw(new Line2D.Float(-unitsPerEmBy2, _font.getDescent(), unitsPerEmBy2, _font.getDescent())); + g2d.draw(new Line2D.Float(_glyph.getLeftSideBearing(), -unitsPerEmBy2, _glyph.getLeftSideBearing(), unitsPerEmBy2)); + g2d.draw(new Line2D.Float(_glyph.getAdvanceWidth(), -unitsPerEmBy2, _glyph.getAdvanceWidth(), unitsPerEmBy2)); + + if (_drawHints && _glyph instanceof T2Glyph) { + T2Glyph t2g = (T2Glyph) _glyph; +// Rectangle2D bounds = t2g.getBounds(); + +// g2d.setPaint(Color.PINK); +// g2d.fill(bounds); + + g2d.setPaint(Color.RED); + + int y = 0; + for (Integer horiz : t2g.getHStems()) { + y += horiz; + g2d.draw(new Line2D.Float(0, y, 1000, y)); + } + + int x = 0; + for (Integer vert : t2g.getVStems()) { + x += vert; + g2d.draw(new Line2D.Float(x, 0, x, 1000)); + } + } + + // Draw contours + g2d.setPaint(Color.black); + + if (_glyphPath == null) { + _glyphPath = GlyphPathFactory.buildPath(_glyph); + } + + // Render the glyph path + if (_preview) { + g2d.fill(_glyphPath); + } else { + g2d.draw(_glyphPath); + } + + if (_drawControlPoints) { + + AffineTransform at2 = new AffineTransform(atOriginal); + g2d.setTransform(at2); + + // Draw control points + for (int i = 0; i < _glyph.getPointCount(); i++) { + int x = (int) (_scaleFactor * (_glyph.getPoint(i).x + _translateX)); + int y = (int) (_scaleFactor * (-_glyph.getPoint(i).y + _translateY)); + + // Set the point colour based on selection + if (_selectedPoints.contains(_glyph.getPoint(i))) { + g2d.setPaint(Color.blue); + } else { + g2d.setPaint(Color.black); + } + + // Draw the point based on its type (on or off curve) + if (_glyph.getPoint(i).onCurve) { + g2d.fill(new Rectangle2D.Float(x - 2, y - 2, 5, 5)); + } else { + g2d.draw(new Rectangle2D.Float(x - 2, y - 2, 5, 5)); + } + g2d.drawString(Integer.toString(i), x + 4, y - 4); + } + } + } + + public Glyph getGlyph() { + return _glyph; + } + + public void setGlyph(Glyph glyph) { + + _glyph = glyph; + + // How much space does this glyph need? +// xOrigin = 0x5000; +// yOrigin = 0x7080; + + setPreferredSize(new Dimension(1024, 1024)); + setSize(new Dimension(1024, 1024)); + + // We have a new glyph, so repaint + _glyphPath = null; + invalidate(); + repaint(); + } + + public void modified() { + _glyphPath = null; + } + + public int getTranslateX() { + return _translateX; + } + + public void setTranslateX(int x) { + _translateX = x; + } + + public int getTranslateY() { + return _translateY; + } + + public void setTranslateY(int y) { + _translateY = y; + } + + public double getScaleFactor() { + return _scaleFactor; + } + + public void setScaleFactor(double factor) { + _scaleFactor = factor; + } + + public boolean isDrawControlPoints() { + return _drawControlPoints; + } + + public void setDrawControlPoints(boolean b) { + _drawControlPoints = b; + } + + public boolean isDrawHints() { + return _drawHints; + } + + public void setDrawHints(boolean b) { + _drawHints = b; + } + + public boolean isPreview() { + return _preview; + } + + public void setPreview(boolean b) { + _preview = b; + } + + public Set getSelectedPoints() { + return _selectedPoints; + } + +// private int transform(int p, int scale, int translate) { +// return ((p * scale) >> 6) + translate; +// } + +// public Font getFont() { +// return font; +// } + + public void setFont(OTFont font) { + _font = font; +// glyph = font.getGlyph(glyphIndex); + _glyph = null; +// repaint(); + + // Determine the default view scaling for this font + short unitsPerEm = _font.getHeadTable().getUnitsPerEm(); + + _scaleFactor = 512.0 / unitsPerEm; + } + + public Tool getTool() { + return _tool; + } + + public void setTool(Tool tool) { + _tool = tool; + } + +// public void executeCommand(Command command) { +// } + + @Override + public boolean getScrollableTracksViewportWidth() { + return false; + } + + @Override + public int getScrollableBlockIncrement(java.awt.Rectangle rectangle, int param, int param2) { + return 10; + } + + @Override + public boolean getScrollableTracksViewportHeight() { + return false; + } + + @Override + public java.awt.Dimension getPreferredScrollableViewportSize() { + return getPreferredSize(); + } + + @Override + public int getScrollableUnitIncrement(java.awt.Rectangle rectangle, int param, int param2) { + return 1; + } + +} diff --git a/sample/src/net/java/dev/typecast/edit/PointTool.java b/sample/src/net/java/dev/typecast/edit/PointTool.java new file mode 100644 index 0000000..692c4a1 --- /dev/null +++ b/sample/src/net/java/dev/typecast/edit/PointTool.java @@ -0,0 +1,110 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.edit; + +import java.awt.Cursor; +import java.awt.Point; + +import java.util.Iterator; +import java.util.Set; + +import net.java.dev.typecast.edit.GlyphEdit; + +import net.java.dev.typecast.ot.Glyph; + +/** + * A simple point selection and manipulation tool. Allows the user to select a + * point with the cursor, to move that point by dragging, and to move the point + * on- and off-curve by selecting the point with the control key pressed. + * @author David Schweinsberg + */ +public class PointTool extends Tool { + + private GlyphEdit _glyphEdit; + private Command _command; + + /** Creates new PointTool */ + public PointTool(GlyphEdit glyphEdit) { + _glyphEdit = glyphEdit; + + // BUG: The crosshair cursor keeps coming up as a text cursor on my + // Windows XP system :-( + //_glyphEdit.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); + _glyphEdit.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); + } + + /** + * Selects a point + */ + public void pressed(Point p) { + _glyphEdit.getSelectedPoints().clear(); + Glyph glyph = _glyphEdit.getGlyph(); + for (int i = 0; i < glyph.getPointCount(); i++) { + net.java.dev.typecast.ot.Point gp = glyph.getPoint(i); + double gpx = _glyphEdit.getScaleFactor() * (gp.x + _glyphEdit.getTranslateX()); + double gpy = _glyphEdit.getScaleFactor() * (-gp.y + _glyphEdit.getTranslateY()); + if (((gpx >= p.x - 2) && (gpx <= p.x + 2)) && + ((gpy >= p.y - 2) && (gpy <= p.y + 2))) { + _glyphEdit.getSelectedPoints().add(gp); + } + } + _glyphEdit.modified(); + _glyphEdit.repaint(); + } + + /** + * Toggles the selected point between on-curve and off-curve + */ + public void pressedControl(Point p) { + Glyph glyph = _glyphEdit.getGlyph(); + for (int i = 0; i < glyph.getPointCount(); i++) { + net.java.dev.typecast.ot.Point gp = glyph.getPoint(i); + double gpx = _glyphEdit.getScaleFactor() * (gp.x + _glyphEdit.getTranslateX()); + double gpy = _glyphEdit.getScaleFactor() * (-gp.y + _glyphEdit.getTranslateY()); + if (((gpx >= p.x - 2) && (gpx <= p.x + 2)) && + ((gpy >= p.y - 2) && (gpy <= p.y + 2))) { + gp.onCurve = !gp.onCurve; + } + } + _glyphEdit.modified(); + _glyphEdit.repaint(); + } + + /** + * Moves the selected points + */ + public void dragged(Point p) { + int x = (int)(p.x / _glyphEdit.getScaleFactor() - _glyphEdit.getTranslateX()); + int y = -(int)(p.y / _glyphEdit.getScaleFactor() - _glyphEdit.getTranslateY()); + Iterator iter = _glyphEdit.getSelectedPoints().iterator(); + while (iter.hasNext()) { + net.java.dev.typecast.ot.Point gp = (net.java.dev.typecast.ot.Point) iter.next(); + gp.x = x; + gp.y = y; + } + _glyphEdit.modified(); + _glyphEdit.repaint(); + } + + /** + * nop + */ + public void released(Point p) { + } +} diff --git a/sample/src/net/java/dev/typecast/edit/SelectCommand.java b/sample/src/net/java/dev/typecast/edit/SelectCommand.java new file mode 100644 index 0000000..c5a41bf --- /dev/null +++ b/sample/src/net/java/dev/typecast/edit/SelectCommand.java @@ -0,0 +1,39 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.edit; + + + +/** + * + * @author David Schweinsberg + */ +public class SelectCommand extends Command { + + /** Creates new SelectCommand */ + public SelectCommand() { + } + + void unexecute() { + } + + void execute() { + } + +} diff --git a/sample/src/net/java/dev/typecast/edit/Tool.java b/sample/src/net/java/dev/typecast/edit/Tool.java new file mode 100644 index 0000000..679a495 --- /dev/null +++ b/sample/src/net/java/dev/typecast/edit/Tool.java @@ -0,0 +1,37 @@ +/* + * Typecast - The Font Development Environment + * + * Copyright (c) 2004 David Schweinsberg + * + * Licensed 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 net.java.dev.typecast.edit; + +import java.awt.Point; +import java.awt.Window; + +/** + * + * @author David Schweinsberg + */ +public abstract class Tool { + + public abstract void pressed(Point p); + + public abstract void pressedControl(Point p); + + public abstract void released(Point p); + + public abstract void dragged(Point p); +} diff --git a/src/images/Typecast.gif b/src/images/Typecast.gif deleted file mode 100644 index be06124..0000000 Binary files a/src/images/Typecast.gif and /dev/null differ diff --git a/src/images/crosshair_16x16.gif b/src/images/crosshair_16x16.gif deleted file mode 100644 index 2f0d771..0000000 Binary files a/src/images/crosshair_16x16.gif and /dev/null differ diff --git a/src/images/cursor_16x16.gif b/src/images/cursor_16x16.gif deleted file mode 100644 index 5a3865e..0000000 Binary files a/src/images/cursor_16x16.gif and /dev/null differ diff --git a/src/images/point_and_cursor_16.gif b/src/images/point_and_cursor_16.gif deleted file mode 100644 index d2765c9..0000000 Binary files a/src/images/point_and_cursor_16.gif and /dev/null differ diff --git a/src/images/point_selected_16.gif b/src/images/point_selected_16.gif deleted file mode 100644 index 1507063..0000000 Binary files a/src/images/point_selected_16.gif and /dev/null differ diff --git a/src/net/java/dev/typecast/app/editor/BitmapPanel.java b/src/net/java/dev/typecast/app/editor/BitmapPanel.java deleted file mode 100644 index bd2a927..0000000 --- a/src/net/java/dev/typecast/app/editor/BitmapPanel.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2016 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -import java.awt.Graphics; -import java.awt.image.BufferedImage; -import java.io.ByteArrayInputStream; -import java.io.IOException; -import javax.imageio.ImageIO; -import javax.swing.JPanel; -import net.java.dev.typecast.app.framework.EditorView; -import net.java.dev.typecast.ot.OTFont; -import net.java.dev.typecast.ot.table.SbixTable; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * A basic bitmap view. - * @author David Schweinsberg - */ -public final class BitmapPanel extends JPanel implements EditorView { - - private BufferedImage _image; - - private static final long serialVersionUID = 1L; - - static final Logger logger = LoggerFactory.getLogger(BitmapPanel.class); - - public BitmapPanel() { - } - - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - g.drawImage(_image, 0, 0, this); - } - - @Override - public void setModel(OTFont font, Object obj) { - SbixTable.GlyphDataRecord gdr = (SbixTable.GlyphDataRecord) obj; - ByteArrayInputStream input = new ByteArrayInputStream(gdr.getData()); - try { - _image = ImageIO.read(input); - } catch (IOException e) { - logger.error("Unable to load image data: " + e.toString()); - } - } -} diff --git a/src/net/java/dev/typecast/app/editor/DumpPanel.java b/src/net/java/dev/typecast/app/editor/DumpPanel.java deleted file mode 100644 index b9ac77e..0000000 --- a/src/net/java/dev/typecast/app/editor/DumpPanel.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2016 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -import java.awt.BorderLayout; -import java.awt.Font; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import javax.swing.JTextArea; -import net.java.dev.typecast.app.framework.EditorView; -import net.java.dev.typecast.ot.OTFont; - -/** - * A simple view of an object's "toString()" output. - * @author David Schweinsberg - */ -public class DumpPanel extends JPanel implements EditorView { - - private static final long serialVersionUID = 1L; - - private final JTextArea _dumpTextArea; - - /** Creates a new instance of DumpPanel */ - public DumpPanel() { - setLayout(new BorderLayout()); - _dumpTextArea = new JTextArea(); - _dumpTextArea.setEditable(false); - _dumpTextArea.setFont(new Font("Monospaced", Font.PLAIN, 12)); - add(new JScrollPane( - _dumpTextArea, - JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, - JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS), - BorderLayout.CENTER); - } - - @Override - public void setModel(OTFont font, Object obj) { - _dumpTextArea.setText(obj.toString()); - } -} diff --git a/src/net/java/dev/typecast/app/editor/EditorFileFilter.java b/src/net/java/dev/typecast/app/editor/EditorFileFilter.java deleted file mode 100644 index 15d6a48..0000000 --- a/src/net/java/dev/typecast/app/editor/EditorFileFilter.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * @(#)ExampleFileFilter.java 1.9 99/04/23 - * - * Copyright (c) 1998, 1999 by Sun Microsystems, Inc. All Rights Reserved. - * - * Sun grants you ("Licensee") a non-exclusive, royalty free, license to use, - * modify and redistribute this software in source and binary code form, - * provided that i) this copyright notice and license appear on all copies of - * the software; and ii) Licensee does not utilize the software in a manner - * which is disparaging to Sun. - * - * This software is provided "AS IS," without a warranty of any kind. ALL - * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY - * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR - * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE - * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING - * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS - * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT, - * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER - * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF - * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGES. - * - * This software is not designed or intended for use in on-line control of - * aircraft, air traffic, aircraft navigation or aircraft communications; or in - * the design, construction, operation or maintenance of any nuclear - * facility. Licensee represents and warrants that it will not use or - * redistribute the Software for such purposes. - */ -package net.java.dev.typecast.app.editor; - -import java.io.File; -import java.util.Hashtable; -import java.util.Enumeration; -import javax.swing.*; -import javax.swing.filechooser.*; - -/** - * A convenience implementation of FileFilter that filters out - * all files except for those type extensions that it knows about. - * - * Extensions are of the type ".foo", which is typically found on - * Windows and Unix boxes, but not on Macinthosh. Case is ignored. - * - * Example - create a new filter that filerts out all files - * but gif and jpg image files: - * - * JFileChooser chooser = new JFileChooser(); - * ExampleFileFilter filter = new ExampleFileFilter( - * new String{"gif", "jpg"}, "JPEG & GIF Images") - * chooser.addChoosableFileFilter(filter); - * chooser.showOpenDialog(this); - * - * @version 1.9 04/23/99 - * @author Jeff Dinkins - */ -public class EditorFileFilter extends FileFilter { - - private static String TYPE_UNKNOWN = "Type Unknown"; - private static String HIDDEN_FILE = "Hidden File"; - - private Hashtable filters = null; - private String description = null; - private String fullDescription = null; - private boolean useExtensionsInDescription = true; - - /** - * Creates a file filter. If no filters are added, then all - * files are accepted. - * - * @see #addExtension - */ - public EditorFileFilter() { - this.filters = new Hashtable(); - } - - /** - * Creates a file filter that accepts files with the given extension. - * Example: new ExampleFileFilter("jpg"); - * - * @see #addExtension - */ - public EditorFileFilter(String extension) { - this(extension,null); - } - - /** - * Creates a file filter that accepts the given file type. - * Example: new ExampleFileFilter("jpg", "JPEG Image Images"); - * - * Note that the "." before the extension is not needed. If - * provided, it will be ignored. - * - * @see #addExtension - */ - public EditorFileFilter(String extension, String description) { - this(); - if(extension!=null) addExtension(extension); - if(description!=null) setDescription(description); - } - - /** - * Creates a file filter from the given string array. - * Example: new ExampleFileFilter(String {"gif", "jpg"}); - * - * Note that the "." before the extension is not needed adn - * will be ignored. - * - * @see #addExtension - */ - public EditorFileFilter(String[] filters) { - this(filters, null); - } - - /** - * Creates a file filter from the given string array and description. - * Example: new ExampleFileFilter(String {"gif", "jpg"}, "Gif and JPG Images"); - * - * Note that the "." before the extension is not needed and will be ignored. - * - * @see #addExtension - */ - public EditorFileFilter(String[] filters, String description) { - this(); - for (int i = 0; i < filters.length; i++) { - // add filters one by one - addExtension(filters[i]); - } - if(description!=null) setDescription(description); - } - - /** - * Return true if this file should be shown in the directory pane, - * false if it shouldn't. - * - * Files that begin with "." are ignored. - * - * @see #getExtension - * @see FileFilter#accepts - */ - public boolean accept(File f) { - if(f != null) { - if(f.isDirectory()) { - return true; - } - String extension = getExtension(f); - if(extension != null && filters.get(getExtension(f)) != null) { - return true; - }; - } - return false; - } - - /** - * Return the extension portion of the file's name . - * - * @see #getExtension - * @see FileFilter#accept - */ - public String getExtension(File f) { - if(f != null) { - String filename = f.getName(); - int i = filename.lastIndexOf('.'); - if(i>0 && i(5); - } - filters.put(extension.toLowerCase(), this); - fullDescription = null; - } - - - /** - * Returns the human readable description of this filter. For - * example: "JPEG and GIF Image Files (*.jpg, *.gif)" - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - * @see FileFilter#getDescription - */ - public String getDescription() { - if(fullDescription == null) { - if(description == null || isExtensionListInDescription()) { - fullDescription = description==null ? "(" : description + " ("; - // build the description from the extension list - Enumeration extensions = filters.keys(); - if(extensions != null) { - fullDescription += "." + (String) extensions.nextElement(); - while (extensions.hasMoreElements()) { - fullDescription += ", ." + (String) extensions.nextElement(); - } - } - fullDescription += ")"; - } else { - fullDescription = description; - } - } - return fullDescription; - } - - /** - * Sets the human readable description of this filter. For - * example: filter.setDescription("Gif and JPG Images"); - * - * @see setDescription - * @see setExtensionListInDescription - * @see isExtensionListInDescription - */ - public void setDescription(String description) { - this.description = description; - fullDescription = null; - } - - /** - * Determines whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see isExtensionListInDescription - */ - public void setExtensionListInDescription(boolean b) { - useExtensionsInDescription = b; - fullDescription = null; - } - - /** - * Returns whether the extension list (.jpg, .gif, etc) should - * show up in the human readable description. - * - * Only relevent if a description was provided in the constructor - * or using setDescription(); - * - * @see getDescription - * @see setDescription - * @see setExtensionListInDescription - */ - public boolean isExtensionListInDescription() { - return useExtensionsInDescription; - } -} diff --git a/src/net/java/dev/typecast/app/editor/EditorMenu.java b/src/net/java/dev/typecast/app/editor/EditorMenu.java deleted file mode 100644 index 8ab2a66..0000000 --- a/src/net/java/dev/typecast/app/editor/EditorMenu.java +++ /dev/null @@ -1,643 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -import java.awt.*; -import java.awt.desktop.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyEvent; - -import java.io.StreamTokenizer; -import java.io.StringReader; - -import java.util.ResourceBundle; - -import javax.swing.JMenu; -import javax.swing.JMenuBar; -import javax.swing.JMenuItem; -import javax.swing.JCheckBoxMenuItem; -import javax.swing.JSeparator; -import javax.swing.KeyStroke; - -import net.java.dev.typecast.ot.OTFontCollection; - -/** - * The application menu bar - * @author David Schweinsberg - */ -public class EditorMenu { - - private Main _app; - private ResourceBundle _rb; - private EditorPrefs _prefs; - private OTFontCollection _selectedFontCollection; - private JMenuItem _closeMenuItem; - private String _closeMenuString; - private JCheckBoxMenuItem _previewMenuItem; - private JCheckBoxMenuItem _showPointsMenuItem; - private JCheckBoxMenuItem _showHintsMenuItem; - private boolean _macPlatform; - private int _primaryKeystrokeMask; - private JMenu _mruMenu; - - /** Creates a new instance of EditorMenu */ - public EditorMenu(Main app, ResourceBundle rb, EditorPrefs prefs) { - _app = app; - _rb = rb; - _prefs = prefs; - _primaryKeystrokeMask = - Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); - if (System.getProperty("os.name").equals("Mac OS X")) { - _macPlatform = true; - registerForMacOSXEvents(); - } else { - _macPlatform = false; - } - } - - public OTFontCollection getSelectedFontCollection() { - return _selectedFontCollection; - } - - public void setSelectedFontCollection(OTFontCollection fc) { - _selectedFontCollection = fc; - if (_selectedFontCollection != null) { - _closeMenuItem.setText( - _closeMenuString + - " \"" + - _selectedFontCollection.getFileName() + - "\""); - _closeMenuItem.setEnabled(true); - } else { - _closeMenuItem.setText(_closeMenuString); - _closeMenuItem.setEnabled(false); - } - } - - public boolean isPreview() { - return _previewMenuItem.getState(); - } - - public boolean isShowPoints() { - return _showPointsMenuItem.getState(); - } - - public boolean isShowHints() { - return _showHintsMenuItem.getState(); - } - - private static void parseMenuString(String menuString, String[] tokens) { - try { - StreamTokenizer st = new StreamTokenizer(new StringReader(menuString)); - st.nextToken(); - if (st.sval != null) { - tokens[0] = st.sval; - } - st.nextToken(); - if (st.sval != null) { - tokens[1] = st.sval; - } - st.nextToken(); - if (st.sval != null) { - tokens[2] = st.sval; - } - } catch (Exception e) { - } - } - - private static JMenuItem createMenuItem( - Class menuClass, - String name, - String mnemonic, - String description, - KeyStroke accelerator, - boolean enabled, - ActionListener al) { - JMenuItem menuItem = null; - try { - menuItem = menuClass.newInstance(); - menuItem.setText(name); - menuItem.setToolTipText(description); - menuItem.setMnemonic(mnemonic.length() > 0 ? mnemonic.charAt(0) : 0); - menuItem.getAccessibleContext().setAccessibleDescription(description); - menuItem.setEnabled(enabled); - if (accelerator != null) { - menuItem.setAccelerator(accelerator); - } - if (al != null) { - menuItem.addActionListener(al); - } - } catch (Exception e) { - } - return menuItem; - } - - private static JMenuItem createMenuItem( - String menuText, - KeyStroke accelerator, - boolean enabled, - ActionListener al) { - String[] tokens = new String[3]; - parseMenuString(menuText, tokens); - return createMenuItem( - JMenuItem.class, - tokens[0], - tokens[1], - tokens[2], - accelerator, - enabled, - al); - } - - private static JCheckBoxMenuItem createCheckBoxMenuItem( - String menuText, - KeyStroke accelerator, - ActionListener al) { - String[] tokens = new String[3]; - parseMenuString(menuText, tokens); - return (JCheckBoxMenuItem) createMenuItem( - JCheckBoxMenuItem.class, - tokens[0], - tokens[1], - tokens[2], - accelerator, - true, - al); - } - - private static JMenu createMenu(String menuText) { - String[] tokens = new String[3]; - parseMenuString(menuText, tokens); - return (JMenu) createMenuItem(JMenu.class, tokens[0], tokens[1], tokens[2], null, true, null); - } - - public JMenuBar createMenuBar() { - JMenuBar menuBar = new JMenuBar(); - menuBar.add(createFileMenu()); - menuBar.add(createEditMenu()); - menuBar.add(createViewMenu()); - //menuBar.add(createElementMenu()); - //menuBar.add(createPointsMenu()); - //menuBar.add(createMetricsMenu()); - if (_macPlatform) { - menuBar.add(createWindowMenu()); - } - menuBar.add(createHelpMenu()); - return menuBar; - } - - private JMenu createFileMenu() { - JMenu menu = createMenu(_rb.getString("Typecast.menu.file")); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.file.new"), - KeyStroke.getKeyStroke(KeyEvent.VK_N, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.file.open"), - KeyStroke.getKeyStroke(KeyEvent.VK_O, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _app.openFont(); - } - })); - _mruMenu = createMenu(_rb.getString("Typecast.menu.file.openRecent")); - menu.add(_mruMenu); - - // Generate a MRU list - buildMRU(); - - menu.add(new JSeparator()); - menu.add(_closeMenuItem = createMenuItem( - _rb.getString("Typecast.menu.file.close"), - null, - false, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _app.closeFont(); - } - })); - _closeMenuString = _closeMenuItem.getText(); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.file.save"), - KeyStroke.getKeyStroke(KeyEvent.VK_S, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.file.saveAs"), - KeyStroke.getKeyStroke( - KeyEvent.VK_S, - _primaryKeystrokeMask | KeyEvent.SHIFT_MASK), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.file.saveAll"), - null, - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.file.revertToSaved"), - null, - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.file.export"), - null, - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _app.exportFont(); - } - })); - if (!_macPlatform) { - menu.add(new JSeparator()); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.file.preferences"), - null, - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - } - - // Only add "Exit" to the menu if this isn't a Mac - if (!_macPlatform) { - menu.add(new JSeparator()); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.file.exit"), - null, - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _app.close(); - } - })); - } - return menu; - } - - private JMenu createEditMenu() { - JMenu menu = createMenu(_rb.getString("Typecast.menu.edit")); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.edit.undo"), - KeyStroke.getKeyStroke(KeyEvent.VK_Z, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.edit.redo"), - KeyStroke.getKeyStroke(KeyEvent.VK_Y, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - menu.add(new JSeparator()); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.edit.cut"), - KeyStroke.getKeyStroke(KeyEvent.VK_X, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.edit.copy"), - KeyStroke.getKeyStroke(KeyEvent.VK_C, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.edit.paste"), - KeyStroke.getKeyStroke(KeyEvent.VK_V, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.edit.clear"), - KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - //menu.add(createMenuItem( - // _rb.getString("Typecast.menu.edit.copyWidths"), - // null, - // new ActionListener() { - // public void actionPerformed(ActionEvent e) { - // } - // })); - //menu.add(createMenuItem( - // _rb.getString("Typecast.menu.edit.copyReference"), - // null, - // new ActionListener() { - // public void actionPerformed(ActionEvent e) { - // } - // })); - //menu.add(createMenuItem( - // _rb.getString("Typecast.menu.edit.unlinkReference"), - // null, - // new ActionListener() { - // public void actionPerformed(ActionEvent e) { - // } - // })); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.edit.selectAll"), - KeyStroke.getKeyStroke(KeyEvent.VK_A, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - //menu.add(createMenuItem( - // _rb.getString("Typecast.menu.edit.duplicate"), - // KeyStroke.getKeyStroke(KeyEvent.VK_D, _primaryKeystrokeMask), - // new ActionListener() { - // public void actionPerformed(ActionEvent e) { - // } - // })); - //menu.add(createMenuItem( - // _rb.getString("Typecast.menu.edit.clone"), - // null, - // new ActionListener() { - // public void actionPerformed(ActionEvent e) { - // } - // })); - return menu; - } - - private JMenu createViewMenu() { - JMenu menu = createMenu(_rb.getString("Typecast.menu.view")); - menu.add(_previewMenuItem = createCheckBoxMenuItem( - _rb.getString("Typecast.menu.view.preview"), - KeyStroke.getKeyStroke(KeyEvent.VK_L, _primaryKeystrokeMask), - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _app.changeGlyphView(); - } - })); - menu.add(_showPointsMenuItem = createCheckBoxMenuItem( - _rb.getString("Typecast.menu.view.showPoints"), - KeyStroke.getKeyStroke(KeyEvent.VK_P, _primaryKeystrokeMask), - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _app.changeGlyphView(); - } - })); - menu.add(_showHintsMenuItem = createCheckBoxMenuItem( - _rb.getString("Typecast.menu.view.showHints"), - KeyStroke.getKeyStroke(KeyEvent.VK_H, _primaryKeystrokeMask), - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _app.changeGlyphView(); - } - })); - _showPointsMenuItem.setState(true); - JMenu subMenu = createMenu(_rb.getString("Typecast.menu.view.magnification")); - menu.add(subMenu); - subMenu.add(createMenuItem( - _rb.getString("Typecast.menu.view.magnification.fitInWindow"), - KeyStroke.getKeyStroke(KeyEvent.VK_T, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - subMenu.add(new JSeparator()); - subMenu.add(createMenuItem( - _rb.getString("Typecast.menu.view.magnification.00625"), - KeyStroke.getKeyStroke(KeyEvent.VK_1, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - subMenu.add(createMenuItem( - _rb.getString("Typecast.menu.view.magnification.01250"), - KeyStroke.getKeyStroke(KeyEvent.VK_2, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - subMenu.add(createMenuItem( - _rb.getString("Typecast.menu.view.magnification.02500"), - KeyStroke.getKeyStroke(KeyEvent.VK_3, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - subMenu.add(createMenuItem( - _rb.getString("Typecast.menu.view.magnification.05000"), - KeyStroke.getKeyStroke(KeyEvent.VK_4, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - subMenu.add(createMenuItem( - _rb.getString("Typecast.menu.view.magnification.10000"), - KeyStroke.getKeyStroke(KeyEvent.VK_5, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - subMenu.add(createMenuItem( - _rb.getString("Typecast.menu.view.magnification.20000"), - KeyStroke.getKeyStroke(KeyEvent.VK_6, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - })); - return menu; - } - - private JMenu createElementMenu() { - JMenu menu = createMenu(_rb.getString("Typecast.menu.element")); - - JMenuItem menuItem = menu.add(new JMenuItem("New")); - menuItem.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - } - ); - return menu; - } - - private JMenu createPointsMenu() { - JMenu menu = createMenu(_rb.getString("Typecast.menu.points")); - - JMenuItem menuItem = menu.add(new JMenuItem("New")); - menuItem.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - } - ); - return menu; - } - - private JMenu createMetricsMenu() { - JMenu menu = createMenu(_rb.getString("Typecast.menu.metrics")); - - JMenuItem menuItem = menu.add(new JMenuItem("New")); - menuItem.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent e) { - } - } - ); - return menu; - } - - private JMenu createWindowMenu() { - JMenu menu = createMenu(_rb.getString("Typecast.menu.window")); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.help.about"), - null, - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _app.showAbout(); - } - })); - return menu; - } - - private JMenu createHelpMenu() { - JMenu menu = createMenu(_rb.getString("Typecast.menu.help")); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.help.typecast"), - KeyStroke.getKeyStroke(KeyEvent.VK_SLASH, _primaryKeystrokeMask), - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _app.showHelp(); - } - })); - if (!_macPlatform) { - menu.add(new JSeparator()); - menu.add(createMenuItem( - _rb.getString("Typecast.menu.help.about"), - null, - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _app.showAbout(); - } - })); - } - return menu; - } - - private void buildMRU() { - _mruMenu.removeAll(); - for (int i = 0; i < _prefs.getMRUCount(); ++i) { - String mru = _prefs.getMRU(i); - if (mru != null) { - JMenuItem menuItem = _mruMenu.add(new JMenuItem( - mru, - KeyEvent.VK_0 + i)); - menuItem.getAccessibleContext().setAccessibleDescription( - "Recently used font"); - menuItem.addActionListener( - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _app.loadFont(e.getActionCommand()); - } - } - ); - } - } - if (_prefs.getMRUCount() == 0) { - - // Add a placeholder - JMenuItem menuItem = _mruMenu.add(new JMenuItem("Recently used files")); - menuItem.setEnabled(false); - } - _mruMenu.add(new JSeparator()); - _mruMenu.add(createMenuItem( - _rb.getString("Typecast.menu.file.openRecent.clearMenu"), - null, - true, - new ActionListener() { - public void actionPerformed(ActionEvent e) { - _prefs.clearMRU(); - buildMRU(); - } - })); - } - - public void addMru(String mru) { - _prefs.addMRU(mru); - buildMRU(); - } - - // Generic registration with the macOS application menu - public void registerForMacOSXEvents() { - Desktop desktop = Desktop.getDesktop(); - desktop.setQuitHandler(new QuitHandler() { - @Override - public void handleQuitRequestWith(QuitEvent e, QuitResponse response) { - _app.close(); - } - }); - desktop.setAboutHandler(new AboutHandler() { - @Override - public void handleAbout(AboutEvent e) { - _app.showAbout(); - } - }); - desktop.setPreferencesHandler(new PreferencesHandler() { - @Override - public void handlePreferences(PreferencesEvent e) { - _app.showPreferences(); - } - }); - } -} diff --git a/src/net/java/dev/typecast/app/editor/EditorPrefs.java b/src/net/java/dev/typecast/app/editor/EditorPrefs.java deleted file mode 100644 index 054eee0..0000000 --- a/src/net/java/dev/typecast/app/editor/EditorPrefs.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2007 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -import java.util.ArrayList; -import java.util.ListIterator; - -import java.util.prefs.Preferences; - -import java.awt.Point; -import java.awt.Dimension; - -/** - * A class to handle all the various application preferences - * @author David Schweinsberg - */ -public class EditorPrefs { - - public static final int maxMRUCount = 10; - - // Key strings - private static final String APP_WINDOW_POS = "app_position"; - private static final String APP_WINDOW_SIZE = "app_size"; - private static final String TREE_WIDTH = "tree_width"; - private static final String MRU_COUNT = "mru_count"; - private static final String MRU_PREFIX = "mru_"; - - // Default values - private static final int APP_WINDOW_POS_X_DEFAULT = 0; - private static final int APP_WINDOW_POS_Y_DEFAULT = 0; - private static final int APP_WINDOW_SIZE_WIDTH_DEFAULT = 640; - private static final int APP_WINDOW_SIZE_HEIGHT_DEFAULT = 480; - private static final int TREE_WIDTH_DEFAULT = 200; - private static final int MRU_COUNT_DEFAULT = 0; - - private Point _appWindowPos; - private Dimension _appWindowSize; - private int _treeWidth; - private ArrayList _mru = new ArrayList(); - - /** Creates a new instance of TypecastPrefs */ - public EditorPrefs() { - } - - public void load(Preferences prefs) { - _appWindowPos = getPosition( - prefs, - APP_WINDOW_POS, - new Point(APP_WINDOW_POS_X_DEFAULT, APP_WINDOW_POS_Y_DEFAULT)); - _appWindowSize = getSize( - prefs, - APP_WINDOW_SIZE, - new Dimension( - APP_WINDOW_SIZE_WIDTH_DEFAULT, - APP_WINDOW_SIZE_HEIGHT_DEFAULT)); - _treeWidth = prefs.getInt(TREE_WIDTH, TREE_WIDTH_DEFAULT); - int mruCount = prefs.getInt(MRU_COUNT, MRU_COUNT_DEFAULT); - for (int i = 0; i < mruCount; ++i) { - _mru.add(prefs.get(MRU_PREFIX + Integer.toString(i), null)); - } - } - - public void save(Preferences prefs) { - putPosition(prefs, APP_WINDOW_POS, _appWindowPos); - putSize(prefs, APP_WINDOW_SIZE, _appWindowSize); - prefs.putInt(TREE_WIDTH, _treeWidth); - prefs.putInt(MRU_COUNT, getMRUCount()); - for (int i = 0; i < getMRUCount(); ++i) { - prefs.put(MRU_PREFIX + Integer.toString(i), _mru.get(i)); - } - } - - public Point getAppWindowPos() { - return _appWindowPos; - } - - public void setAppWindowPos(Point pos) { - _appWindowPos = pos; - } - - public Dimension getAppWindowSize() { - return _appWindowSize; - } - - public void setAppWindowSize(Dimension size) { - _appWindowSize = size; - } - - public int getTreeWidth() { - return _treeWidth; - } - - public void setTreeWidth(int width) { - _treeWidth = width; - } - - public int getMRUCount() { - return _mru.size(); - } - - public String getMRU(int index) { - return _mru.get(index); - } - - public void addMRU(String mru) { - - // Is this string already in the list? - ListIterator iter = _mru.listIterator(); - while (iter.hasNext()) { - if (iter.next().equals(mru)) { - return; - } - } - - // Insert this file at the beginning of the list and remove any that - // drop off the end of the list - _mru.add(0, mru); - if (_mru.size() > maxMRUCount) { - _mru.remove(maxMRUCount); - } - } - - public void clearMRU() { - _mru.clear(); - } - - public float getZoom() { - return 0.25f; - } - - public void setZoom(float factor) { - - } - - /** - * Read a position string from preferences - */ - public static Point getPosition(Preferences prefs, String keyName, Point defaultPos) { - String position = prefs.get( - keyName, - defaultPos.x + "," + defaultPos.y); - try { - int i = position.indexOf(','); - int x = Integer.parseInt(position.substring(0, i)); - int y = Integer.parseInt(position.substring(i + 1)); - return new Point(x, y); - } catch(Exception e) { - return defaultPos; - } - } - - public static void putPosition(Preferences prefs, String keyName, Point pos) { - prefs.put(keyName, pos.x + "," + pos.y); - } - - /** - * Read a size string from preferences - */ - public static Dimension getSize(Preferences prefs, String keyName, Dimension defaultSize) { - String size = prefs.get( - keyName, - defaultSize.width + "x" + defaultSize.height); - try { - int i = size.indexOf('x'); - int w = Integer.parseInt(size.substring(0, i)); - int h = Integer.parseInt(size.substring(i + 1)); - return new Dimension(w, h); - } catch(Exception e) { - return defaultSize; - } - } - - public static void putSize(Preferences prefs, String keyName, Dimension size) { - prefs.put(keyName, size.width + "x" + size.height); - } -} diff --git a/src/net/java/dev/typecast/app/editor/GlyphPanel.java b/src/net/java/dev/typecast/app/editor/GlyphPanel.java deleted file mode 100644 index 5aeb06e..0000000 --- a/src/net/java/dev/typecast/app/editor/GlyphPanel.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2015 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -import java.awt.BorderLayout; -import java.awt.Color; -import javax.swing.JPanel; -import javax.swing.JScrollPane; -import net.java.dev.typecast.app.framework.EditorView; -import net.java.dev.typecast.cff.CharstringType2; -import net.java.dev.typecast.edit.GlyphEdit; -import net.java.dev.typecast.ot.OTFont; -import net.java.dev.typecast.ot.T2Glyph; -import net.java.dev.typecast.ot.TTGlyph; -import net.java.dev.typecast.ot.table.GlyphDescription; - -/** - * - * @author David Schweinsberg - */ -public class GlyphPanel extends JPanel implements EditorView { - - private static final long serialVersionUID = 1L; - - private final EditorPrefs _prefs; - private final GlyphEdit _glyphEdit = new GlyphEdit(); - private final GlyphPanelToolBar _toolBar = new GlyphPanelToolBar(); - private final GlyphPanelStatusBar _glyphPanelStatusBar = - new GlyphPanelStatusBar(); - - /** Creates new GlyphPanel */ - public GlyphPanel(EditorPrefs prefs) { - _prefs = prefs; - setName("Outline"); - setLayout(new BorderLayout()); - - // Toolbar - add(_toolBar, BorderLayout.NORTH); - - // Editor - _glyphEdit.setBackground(Color.white); - _glyphEdit.setScaleFactor(_prefs.getZoom()); - add(new JScrollPane( - _glyphEdit, - JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, - JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS), - BorderLayout.CENTER); - - // Status bar - _glyphPanelStatusBar.setGlyphEdit(_glyphEdit); - add(_glyphPanelStatusBar, BorderLayout.SOUTH); - } - - /** - * The GlyphPanel deals with GlyphDescriptions, so the Object parameter must - * implement the GlyphDescription interface. - */ - @Override - public void setModel(OTFont font, Object obj) { - if (obj instanceof GlyphDescription) { - _glyphEdit.setFont(font); - GlyphDescription gd = (GlyphDescription) obj; - _glyphEdit.setGlyph(new TTGlyph( - gd, - font.getHmtxTable().getLeftSideBearing(gd.getGlyphIndex()), - font.getHmtxTable().getAdvanceWidth(gd.getGlyphIndex()))); - } - else if (obj instanceof CharstringType2) { - _glyphEdit.setFont(font); - CharstringType2 cs = (CharstringType2) obj; - _glyphEdit.setGlyph(new T2Glyph( - cs, - font.getHmtxTable().getLeftSideBearing(cs.getIndex()), - font.getHmtxTable().getAdvanceWidth(cs.getIndex()))); - } - } - - public GlyphEdit getGlyphEdit() { - return _glyphEdit; - } - - public void setProperties() { - _prefs.setZoom((float)_glyphEdit.getScaleFactor()); - } -} diff --git a/src/net/java/dev/typecast/app/editor/GlyphPanelStatusBar.java b/src/net/java/dev/typecast/app/editor/GlyphPanelStatusBar.java deleted file mode 100644 index e90ebaa..0000000 --- a/src/net/java/dev/typecast/app/editor/GlyphPanelStatusBar.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -import java.awt.GridLayout; - -import java.awt.event.MouseEvent; - -import java.net.URL; - -import java.util.Set; - -import javax.swing.ImageIcon; -import javax.swing.JLabel; -import javax.swing.JPanel; -import javax.swing.SwingConstants; - -import javax.swing.event.MouseInputListener; - -import net.java.dev.typecast.edit.GlyphEdit; - -import net.java.dev.typecast.ot.Point; - -/** - * - * @author David Schweinsberg - */ -public class GlyphPanelStatusBar extends JPanel { - - private static final long serialVersionUID = 1L; - - private GlyphEdit _glyphEdit; - private JLabel _cursorPos; - private JLabel _selPos; - private JLabel _selDelta; - - /** Creates new GlyphEditStatusBar */ - public GlyphPanelStatusBar() { - setLayout(new GridLayout(1, 5)); - URL iconURL = ClassLoader.getSystemResource("images/cursor_16x16.gif"); - add(_cursorPos = new JLabel( - "0, 0", - new ImageIcon(iconURL), - SwingConstants.LEFT)); - iconURL = ClassLoader.getSystemResource("images/point_selected_16.gif"); - add(_selPos = new JLabel( - "---, ---", - new ImageIcon(iconURL), - SwingConstants.LEFT)); - iconURL = ClassLoader.getSystemResource( - "images/point_and_cursor_16.gif"); - add(_selDelta = new JLabel( - "---, ---", - new ImageIcon(iconURL), - SwingConstants.LEFT)); - } - - public GlyphEdit getGlyphEdit() { - return _glyphEdit; - } - - public void setGlyphEdit(GlyphEdit glyphEdit) { - _glyphEdit = glyphEdit; - - // Create a MouseInputListener to track the location of the cursor - // within the GlyphEdit window - MouseInputListener mil = new MouseInputListener() { - public void mouseClicked(MouseEvent e) { } - public void mouseEntered(MouseEvent e) { } - public void mouseExited(MouseEvent e) { } - public void mousePressed(MouseEvent e) { - setCursorStatus(e.getX(), e.getY()); - setSelectedStatus(); - } - public void mouseReleased(MouseEvent e) { } - public void mouseDragged(MouseEvent e) { - setCursorStatus(e.getX(), e.getY()); - setSelectedStatus(); - } - public void mouseMoved(MouseEvent e) { - setCursorStatus(e.getX(), e.getY()); - } - }; - glyphEdit.addMouseListener(mil); - glyphEdit.addMouseMotionListener(mil); - } - - private void setCursorStatus(int x, int y) { - double f = _glyphEdit.getScaleFactor(); - int x1 = (int)((double) x / f - (double) _glyphEdit.getTranslateX()); - int y1 = -(int)((double) y / f - (double) _glyphEdit.getTranslateY()); - - // Cursor position - _cursorPos.setText(x1 + ", " + y1); - - // Difference between cursor and selected point - Set s = _glyphEdit.getSelectedPoints(); - if (s.size() == 1) { - Point p = (Point) s.iterator().next(); - _selDelta.setText((x1 - p.x) + ", " + (y1 - p.y)); - } else { - _selDelta.setText("---, ---"); - } - } - - private void setSelectedStatus() { - Set s = _glyphEdit.getSelectedPoints(); - if (s.size() == 1) { - Point p = (Point) s.iterator().next(); - _selPos.setText(p.x + ", " + p.y); - } else { - _selPos.setText("---, ---"); - } - } -} diff --git a/src/net/java/dev/typecast/app/editor/GlyphPanelToolBar.java b/src/net/java/dev/typecast/app/editor/GlyphPanelToolBar.java deleted file mode 100644 index 22f229d..0000000 --- a/src/net/java/dev/typecast/app/editor/GlyphPanelToolBar.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2016 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -import java.net.URL; -import javax.swing.ImageIcon; -import javax.swing.JButton; -import javax.swing.JToolBar; - -/** - * - * @author David Schweinsberg - */ -public class GlyphPanelToolBar extends JToolBar { - - private static final long serialVersionUID = 1L; - - /** Creates new GlyphPanelToolBar */ - public GlyphPanelToolBar() { - URL iconURL = ClassLoader.getSystemResource("images/cursor_16x16.gif"); - JButton button = new JButton(new ImageIcon(iconURL)); - add(button); - - iconURL = ClassLoader.getSystemResource("images/crosshair_16x16.gif"); - button = new JButton(new ImageIcon(iconURL)); - add(button); - - iconURL = ClassLoader.getSystemResource("toolbarButtonGraphics/general/ZoomIn16.gif"); - button = new JButton(new ImageIcon(iconURL)); - add(button); - - iconURL = ClassLoader.getSystemResource("toolbarButtonGraphics/general/ZoomOut16.gif"); - button = new JButton(new ImageIcon(iconURL)); - add(button); - } - -} diff --git a/src/net/java/dev/typecast/app/editor/MacOSFilenameFilter.java b/src/net/java/dev/typecast/app/editor/MacOSFilenameFilter.java deleted file mode 100644 index c88de5a..0000000 --- a/src/net/java/dev/typecast/app/editor/MacOSFilenameFilter.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2007 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -import java.io.BufferedInputStream; -import java.io.DataInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FilenameFilter; -import java.io.FileNotFoundException; -import java.io.IOException; - -import net.java.dev.typecast.ot.mac.ResourceHeader; -import net.java.dev.typecast.ot.mac.ResourceMap; -import net.java.dev.typecast.ot.mac.ResourceType; - -/** - * A FilenameFilter implementation that includes font files based on their - * extension and also by the presence of fonts in the resource fork. - * @author David Schweinsberg - */ -public class MacOSFilenameFilter implements FilenameFilter { - - /** Creates a new instance of MacOSFilenameFilter */ - public MacOSFilenameFilter() { - } - - public boolean accept(File dir, String name) { - if (name.endsWith(".ttf") - || name.endsWith(".ttc") - || name.endsWith(".otf") - || name.endsWith(".dfont") - || name.endsWith(".suit")) { - return true; - } else if (name.indexOf('.') == -1) { - - // This filename has no extension, so we'll look into any - // resource fork. But first, if there is data in the data fork, - // then we'll reject this as a font file - File dataFork = new File(dir, name); - if (dataFork.length() > 0) { - return false; - } - - // OK, go for the resource fork - File file = new File(dataFork, "..namedfork/rsrc"); - if (file.exists() && file.length() > 0) { - try { - DataInputStream dis = new DataInputStream( - new BufferedInputStream( - new FileInputStream(file), (int) file.length())); - dis.mark((int) file.length()); - - // Is this a Macintosh font suitcase resource? - ResourceHeader resourceHeader = new ResourceHeader(dis); - - // Seek to the map offset and read the map - dis.reset(); - dis.skip(resourceHeader.getMapOffset()); - ResourceMap map = new ResourceMap(dis); - - // Get any 'sfnt' resources - ResourceType resourceType = map.getResourceType("sfnt"); - dis.close(); - if (resourceType != null) { - return true; - } - } catch (FileNotFoundException e) { - // ignore - } catch (IOException e) { - // ignore - } - } - } - return false; - } -} diff --git a/src/net/java/dev/typecast/app/editor/Main.java b/src/net/java/dev/typecast/app/editor/Main.java deleted file mode 100644 index e0db0d7..0000000 --- a/src/net/java/dev/typecast/app/editor/Main.java +++ /dev/null @@ -1,427 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2016 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - - -import java.awt.Cursor; -import java.awt.FileDialog; -import java.awt.HeadlessException; -import java.awt.event.WindowAdapter; -import java.awt.event.WindowEvent; -import java.io.File; -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.ArrayList; -import java.util.ResourceBundle; -import java.util.prefs.Preferences; -import javax.swing.JFileChooser; -import javax.swing.JFrame; -import javax.swing.JOptionPane; -import javax.swing.JScrollPane; -import javax.swing.JSplitPane; -import javax.swing.JTabbedPane; -import javax.swing.JTree; -import javax.swing.ToolTipManager; -import javax.swing.UIManager; -import javax.swing.UnsupportedLookAndFeelException; -import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.TreeSelectionListener; -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreePath; -import net.java.dev.typecast.edit.CharacterMap; -import net.java.dev.typecast.exchange.Exporter; -import net.java.dev.typecast.exchange.SVGExporter; -import net.java.dev.typecast.ot.OTFont; -import net.java.dev.typecast.ot.OTFontCollection; -import net.java.dev.typecast.ot.table.GlyphDescription; -import net.java.dev.typecast.ot.table.TableException; - -/** - * @author David Schweinsberg - */ -public class Main { - - private EditorMenu _menu; - private JFrame _frame; - private JTree _tree; - private JSplitPane _splitPane; - private DefaultTreeModel _treeModel; - private ArrayList _fontCollections = new ArrayList<>(); - private EditorPrefs _appPrefs = new EditorPrefs(); - private JTabbedPane _tabbedPane; - private GlyphPanel _glyphPane; - private Object _treeSelection; - private ResourceBundle _rb; - private OTFont _selectedFont = null; - private TableTreeNode _selectedCollectionNode; - - /** - * Typecast constructor. - */ - public Main() { - - // Before loading Swing, set macOS-specific properties - System.setProperty("apple.awt.application.name", "Typecast"); - System.setProperty("apple.laf.useScreenMenuBar", "true"); - - // Show a splash screen whilst we load up - Splash splash = new Splash(); - splash.setVisible(true); - - // TESTING: The following will be moved to a properties file -// _modelViewPairs.add(new ModelViewPair( -// GlyfDescript.class, -// GlyphPanel.class)); -// _modelViewPairs.add(new ModelViewPair( -// net.java.dev.typecast.ot.table.CmapFormat.class, -// CharacterMap.class)); - - try { - // Set the L&F appropriate for the OS - // (Mac automatically selects Aqua, but Windows goes for Metal) - if (System.getProperty("os.name").startsWith("Windows")) { - UIManager.setLookAndFeel( - "com.sun.java.swing.plaf.windows.WindowsLookAndFeel"); - } - - // Load the user's application preferences - _appPrefs.load(Preferences.userNodeForPackage(getClass())); - - // Load the resource bundle - _rb = ResourceBundle.getBundle("net/java/dev/typecast/app/editor/Main"); - - _frame = new JFrame( - _rb.getString("Typecast.title") + - " " + - _rb.getString("Typecast.version")); - _frame.setLocation(_appPrefs.getAppWindowPos()); - _frame.setPreferredSize(_appPrefs.getAppWindowSize()); - - _treeModel = (DefaultTreeModel) TableTreeBuilder.createTypecastTreeModel(); - _tree = new JTree(_treeModel); - _tree.setRootVisible(false); - _tree.setShowsRootHandles(true); - - // Enable tool tips for the tree, without this tool tips will not - // be picked up - ToolTipManager.sharedInstance().registerComponent(_tree); - - // Make the tree use an instance of TableTreeCellRenderer for - // drawing - _tree.setCellRenderer(new TableTreeCellRenderer()); - - // Put the Tree in a scroller - JScrollPane treePane = new JScrollPane( - JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, - JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); - treePane.getViewport().add(_tree); - - treePane.setBorder(null); - - // Listen for selection events from the tree - TreeSelectionListener tsl = (TreeSelectionEvent e) -> { - TreePath selPath = e.getPath(); - if(selPath != null) { - - // Pick the font collection out of the path - if (selPath.getPathCount() >= 2) { - _selectedCollectionNode = - (TableTreeNode) selPath.getPathComponent(1); - _menu.setSelectedFontCollection( - (OTFontCollection) - _selectedCollectionNode.getUserObject()); - } - - // Pick the selected font out of the path - OTFont font = null; - if (selPath.getPathCount() >= 3) { - TableTreeNode fontNode = - (TableTreeNode) selPath.getPathComponent(2); - font = (OTFont) fontNode.getUserObject(); - } - - // Now get the actually selected node - TableTreeNode tn = - (TableTreeNode) selPath.getLastPathComponent(); - selectElement(font, tn); - } - }; - _tree.addTreeSelectionListener(tsl); - - // Create a tabbed workspace - _tabbedPane = new JTabbedPane(); - - // Split the main frame - _splitPane = new JSplitPane( - JSplitPane.HORIZONTAL_SPLIT, - treePane, - _tabbedPane); - _splitPane.setOneTouchExpandable(true); - _splitPane.setDividerLocation(_appPrefs.getTreeWidth()); - _frame.getContentPane().add("Center", _splitPane); - - _splitPane.setBorder(null); - - // Create a menu bar - _menu = new EditorMenu(this, _rb, _appPrefs); - _frame.setJMenuBar(_menu.createMenuBar()); - - _frame.addWindowListener( - new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - close(); - } - } - ); - - // We're built, so make the main frame visible and hide the splash - _frame.pack(); - _frame.setVisible(true); - } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException | HeadlessException e) { - JOptionPane.showMessageDialog( - null, - e.toString(), - "Exception", - JOptionPane.ERROR_MESSAGE); - } finally { - splash.setVisible(false); - } - } - - protected void loadFont(String pathName) { - _frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); - try { - File file = new File(pathName); - OTFontCollection fc = OTFontCollection.create(file); - _fontCollections.add(fc); - - // Create the tree to put the information in - TableTreeBuilder.addFontTree(_treeModel, fc); - } catch (IOException e) { - JOptionPane.showMessageDialog( - null, - e.toString(), - "I/O Exception", - JOptionPane.ERROR_MESSAGE); - } catch (Exception e) { - JOptionPane.showMessageDialog( - null, - e.toString(), - "Exception", - JOptionPane.ERROR_MESSAGE); - } - _frame.setCursor(Cursor.getDefaultCursor()); - } - - public static void main(String[] args) { - new Main(); - } - - /** - * Display a file chooser and open the selected font file - */ - protected void openFont() { - String pathName = null; - - // Display a file chooser, depending on what OS we're running on - if (System.getProperty("os.name").equals("Mac OS X")) { - FileDialog fd = new FileDialog(_frame, "Open Font"); - fd.setFilenameFilter(new MacOSFilenameFilter()); - fd.setVisible(true); - if (fd.getFile() != null) { - pathName = fd.getDirectory() + fd.getFile(); - } - } else { - JFileChooser chooser = new JFileChooser(); - - EditorFileFilter filter = new EditorFileFilter(); - filter.addExtension("ttf"); - filter.addExtension("ttc"); - filter.addExtension("otf"); - filter.addExtension("dfont"); - filter.setDescription("OpenType Fonts"); - - chooser.setFileFilter(filter); - - if (chooser.showOpenDialog(_frame) == JFileChooser.APPROVE_OPTION) { - pathName = chooser.getSelectedFile().getPath(); - } - } - - if (pathName != null) { - loadFont(pathName); - _menu.addMru(pathName); - } - } - - /** - * Close the currently selected font - */ - protected void closeFont() { - _fontCollections.remove( - (OTFontCollection) _selectedCollectionNode.getUserObject()); - _treeModel.removeNodeFromParent(_selectedCollectionNode); - selectElement(null, null); - _menu.setSelectedFontCollection(null); - } - - /** - * At this time the only format we export to is SVG - */ - protected void exportFont() { - if (_selectedFont != null) { - JFileChooser chooser = new JFileChooser(); - - EditorFileFilter filter = new EditorFileFilter(); - filter.addExtension("svg"); - filter.setDescription("Scalable Vector Graphics"); - - chooser.setFileFilter(filter); - - if (chooser.showSaveDialog(_frame) == JFileChooser.APPROVE_OPTION) { - try { - try (FileOutputStream fos = new FileOutputStream(chooser.getSelectedFile().getPath())) { - Exporter exporter = new SVGExporter(_selectedFont); - exporter.export(fos); - } - } catch (IOException | TableException e) { - JOptionPane.showMessageDialog( - null, - e.toString(), - "Exception", - JOptionPane.ERROR_MESSAGE); - } - } - } - } - - protected void showHelp() { - JOptionPane.showMessageDialog( - null, - "Typecast currently has no help.", - "Typecast Help", - JOptionPane.INFORMATION_MESSAGE); - } - - protected void showAbout() { - JOptionPane.showMessageDialog( - null, - _rb.getString("Typecast.title") + - " " + - _rb.getString("Typecast.version") + - " - " + - _rb.getString("Typecast.shortDesc") + - "\n" + - _rb.getString("Typecast.copyright") + - "\n" + - _rb.getString("Typecast.copyright2") + - "\n" + - _rb.getString("Typecast.webHome"), - _rb.getString("Typecast.about.title"), - JOptionPane.INFORMATION_MESSAGE); - } - - protected void showPreferences() { - JOptionPane.showMessageDialog( - null, - "Typecast currently has no preferences page.", - "Typecast Preferences", - JOptionPane.INFORMATION_MESSAGE); - } - - protected void close() { - - // Save the user's application preferences - _appPrefs.setAppWindowPos(_frame.getLocation()); - _appPrefs.setAppWindowSize(_frame.getSize()); - _appPrefs.setTreeWidth(_splitPane.getDividerLocation()); - _appPrefs.save(Preferences.userNodeForPackage(getClass())); - - // End the application - System.exit(0); - } - - protected void changeGlyphView() { - _glyphPane.getGlyphEdit().setPreview(_menu.isPreview()); - _glyphPane.getGlyphEdit().setDrawControlPoints(_menu.isShowPoints()); - _glyphPane.getGlyphEdit().setDrawHints(_menu.isShowHints()); - _glyphPane.getGlyphEdit().repaint(); - } - - private void selectElement(OTFont font, TableTreeNode tn) { - - // Note that this font is currently selected - _selectedFont = font; - - Object obj = (tn != null) ? tn.getUserObject() : null; - - // Check that we actually have work to do - if (_treeSelection == obj) { - return; - } - - // Configure the tabbed pane - _tabbedPane.removeAll(); - - // Add all the panes we're interested in -// for (ModelViewPair p : _modelViewPairs) { -// if (p._model.isInstance(obj)) { -// Component view = p._view.newInstance(); -// if (view instanceof EditorView) { -// ((EditorView)view).setModel(font, obj); -// } -// _tabbedPane.add(view); -// } -// } - - // Then add the panes we're interested in - if (obj instanceof GlyphDescription - || obj instanceof net.java.dev.typecast.cff.Charstring) { - _glyphPane = new GlyphPanel(_appPrefs); - _glyphPane.setModel(font, obj); - _tabbedPane.add(_glyphPane); - } - - // Character maps - if (obj instanceof net.java.dev.typecast.ot.table.CmapFormat) { - CharacterMap cm = new CharacterMap(); - cm.setModel(_selectedFont, obj); - _tabbedPane.add(cm); - } - - // Bitmaps - if (obj instanceof net.java.dev.typecast.ot.table.SbixTable.GlyphDataRecord) { - BitmapPanel bitmapPanel = new BitmapPanel(); - bitmapPanel.setName("Bitmap"); - bitmapPanel.setModel(_selectedFont, obj); - _tabbedPane.add(bitmapPanel); - } - - // All selections get a "dump" pane - if (obj != null) { - DumpPanel textPane = new DumpPanel(); - textPane.setName("Dump"); - textPane.setModel(_selectedFont, obj); - _tabbedPane.add(textPane); - } - - _treeSelection = obj; - } -} diff --git a/src/net/java/dev/typecast/app/editor/Main.properties b/src/net/java/dev/typecast/app/editor/Main.properties deleted file mode 100644 index 6d44a51..0000000 --- a/src/net/java/dev/typecast/app/editor/Main.properties +++ /dev/null @@ -1,81 +0,0 @@ -# -# Typecast - The Font Development Environment -# -# Copyright (c) 2004-2016 David Schweinsberg -# -# Licensed 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. -# - -Typecast.title=Typecast -Typecast.version=0.6.0 -Typecast.shortDesc=An OpenType Font Development Environment -Typecast.copyright=Copyright \u00a9 2004-2015 David Schweinsberg -Typecast.copyright2=This product includes software developed by the Apache Software Foundation (http://www.apache.org/). -Typecast.webHome=https://github.com/dcsch/typecast - -Typecast.about.title=About Typecast - -# Menu properties -Typecast.menu.file=File F "File menu" -Typecast.menu.edit=Edit E "Edit menu" -Typecast.menu.view=View V "View menu" -#Typecast.menu.edit.clone=Clone E "Clone the selection" -#Typecast.menu.edit.duplicate=Duplicate D "Duplicate the selection" -Typecast.menu.edit.selectAll="Select All" A "Select everything" -#Typecast.menu.edit.unlinkReference="Unlink Reference" N "Replace the referenced glyph with an explicit glyph" -#Typecast.menu.edit.copyReference="Copy Reference" O "Copy a reference of the glyph to the clipboard" -Typecast.menu.window=Window W "Window menu" -Typecast.menu.help=Help H "Help menu" -#Typecast.menu.metrics=Metrics M "Metrics menu" -#Typecast.menu.points=Points P "Points menu" -#Typecast.menu.element=Element L "Element menu" - -#Typecast.menu.edit.copyWidths="Copy Widths" W "Copy the character width to the clipboard" -Typecast.menu.edit.clear=Clear L "Clear the selection" -Typecast.menu.edit.paste=Paste P "Paste from the clipboard" -Typecast.menu.edit.copy=Copy C "Copy the selection" -Typecast.menu.edit.cut=Cut T "Cut the selection" -Typecast.menu.edit.redo=Redo R "Redo the last undo" -Typecast.menu.edit.undo=Undo U "Undo the last operation" - -#Typecast.menu.view.nextCharacter="Next Character" C "Next Character" -Typecast.menu.view.magnification.02500="25%" "2" "25%" -Typecast.menu.view.magnification.01250="12.5%" "1" "12.5%" -Typecast.menu.view.magnification.00625="6.25%" "6" "6.25%" -Typecast.menu.view.magnification.fitInWindow="Fit In Window" F "Fit In Window" -Typecast.menu.view.magnification=Magnification M "Magnification" - -Typecast.menu.help.about="About Typecast" A "About Typecast" -Typecast.menu.help.typecast="Typecast Help" T "Typecast Help" - -Typecast.menu.view.magnification.20000="200%" "2" "200%" -Typecast.menu.view.magnification.10000="100%" "1" "100%" -Typecast.menu.view.magnification.05000="50%" "5" "50%" -Typecast.menu.view.showPoints="Show Points" S "Show Points" -Typecast.menu.view.showHints="Show Hints" H "Show Hints" -Typecast.menu.view.preview=Preview P "Preview" - -Typecast.menu.file.new=New N "Create a new font" -Typecast.menu.file.open=Open... O "Open an existing font" -Typecast.menu.file.openRecent="Open Recent" R "Open a recently used font" -Typecast.menu.file.openRecent.clearMenu="Clear Menu" C "Clear the list of recently used fonts" -#Typecast.menu.file.mru=Recently used font -Typecast.menu.file.close=Close C "Close the selected font" -Typecast.menu.file.save=Save S "Save the selected font" -Typecast.menu.file.saveAs="Save As..." A "Save the selected font with a new file name" -Typecast.menu.file.saveAll="Save All" L "Save all modified fonts" -Typecast.menu.file.revertToSaved="Revert to Saved" R "Revert to the saved version of the font" -Typecast.menu.file.export="Export..." E "Export the selected font" -Typecast.menu.file.preferences=Preferences P "Show the preferences dialog" -Typecast.menu.file.exit=Exit X "Exit Typecast" - diff --git a/src/net/java/dev/typecast/app/editor/Splash.java b/src/net/java/dev/typecast/app/editor/Splash.java deleted file mode 100644 index bcaed4b..0000000 --- a/src/net/java/dev/typecast/app/editor/Splash.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -import java.awt.Dimension; -import java.awt.Image; -import java.awt.Toolkit; - -import java.net.URL; - -import javax.swing.JWindow; - -/** - * - * @author David Schweinsberg - */ -public class Splash extends JWindow { - - private static final long serialVersionUID = 1L; - - private Image image; - - /** Creates new Splash */ - public Splash() { - Dimension d = Toolkit.getDefaultToolkit().getScreenSize(); - URL imageURL = ClassLoader.getSystemResource("images/Typecast.gif"); - image = Toolkit.getDefaultToolkit().getImage(imageURL); - setSize(300, 480); - setLocation(d.width/2 - 150, d.height/2 - 240); - } - - public void paint(java.awt.Graphics graphics) { - graphics.drawImage(image, 0, 0, this); - } -} diff --git a/src/net/java/dev/typecast/app/editor/TableTreeBuilder.java b/src/net/java/dev/typecast/app/editor/TableTreeBuilder.java deleted file mode 100644 index 732b95e..0000000 --- a/src/net/java/dev/typecast/app/editor/TableTreeBuilder.java +++ /dev/null @@ -1,329 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2016 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -import javax.swing.tree.DefaultTreeModel; -import javax.swing.tree.TreeModel; -import net.java.dev.typecast.cff.CffFont; -import net.java.dev.typecast.cff.Charstring; -import net.java.dev.typecast.cff.NameIndex; -import net.java.dev.typecast.ot.OTFont; -import net.java.dev.typecast.ot.OTFontCollection; -import net.java.dev.typecast.ot.table.CffTable; -import net.java.dev.typecast.ot.table.CmapIndexEntry; -import net.java.dev.typecast.ot.table.CmapTable; -import net.java.dev.typecast.ot.table.DirectoryEntry; -import net.java.dev.typecast.ot.table.Feature; -import net.java.dev.typecast.ot.table.GlyfCompositeComp; -import net.java.dev.typecast.ot.table.GlyfCompositeDescript; -import net.java.dev.typecast.ot.table.GlyfDescript; -import net.java.dev.typecast.ot.table.GlyfTable; -import net.java.dev.typecast.ot.table.GsubTable; -import net.java.dev.typecast.ot.table.ID; -import net.java.dev.typecast.ot.table.LangSys; -import net.java.dev.typecast.ot.table.Lookup; -import net.java.dev.typecast.ot.table.LookupSubtable; -import net.java.dev.typecast.ot.table.NameRecord; -import net.java.dev.typecast.ot.table.NameTable; -import net.java.dev.typecast.ot.table.PostTable; -import net.java.dev.typecast.ot.table.SbixTable; -import net.java.dev.typecast.ot.table.Script; -import net.java.dev.typecast.ot.table.Table; - -/** - * @author David Schweinsberg - */ -public class TableTreeBuilder { - - private static void addCmapTable(TableTreeNode parent, CmapTable ct) { - - int lastPlatformId = -1; - int lastEncodingId = -1; - TableTreeNode platformNode = null; - TableTreeNode encodingNode = null; - - for (int i = 0; i < ct.getNumTables(); i++) { - CmapIndexEntry cie = ct.getCmapIndexEntry(i); - - // Have we created the proper grouping? - if (lastPlatformId != cie.getPlatformId()) { - lastPlatformId = cie.getPlatformId(); - lastEncodingId = -1; - String s = "Platform ID: " + cie.getPlatformId() + " (" + - ID.getPlatformName((short) cie.getPlatformId()) + ")"; - platformNode = createNode(s, null); - parent.add(platformNode); - } - if (lastEncodingId != cie.getEncodingId()) { - lastEncodingId = cie.getEncodingId(); - String s = "Encoding ID: " + cie.getEncodingId() + " (" + - ID.getEncodingName( - (short) cie.getPlatformId(), - (short) cie.getEncodingId()) + ")"; - encodingNode = createNode(s, cie.getFormat()); - platformNode.add(encodingNode); - } - } - } - - private static void addNameTable(TableTreeNode parent, NameTable nt) { - - short lastPlatformId = -1; - short lastEncodingId = -1; - short lastLanguageId = -1; - TableTreeNode platformNode = null; - TableTreeNode encodingNode = null; - TableTreeNode languageNode = null; - - for (int i = 0; i < nt.getNumberOfNameRecords(); i++) { - NameRecord nr = nt.getRecord(i); - - // Have we created the proper grouping? - if (lastPlatformId != nr.getPlatformId()) { - lastPlatformId = nr.getPlatformId(); - lastEncodingId = -1; - lastLanguageId = -1; -// String s = "Platform ID: " + lastPlatformId; - String s = "Platform ID: " + nr.getPlatformId() + " (" + - ID.getPlatformName(nr.getPlatformId()) + ")"; - platformNode = createNode(s, null); - parent.add(platformNode); - } - if (lastEncodingId != nr.getEncodingId()) { - lastEncodingId = nr.getEncodingId(); - lastLanguageId = -1; -// String s = "Encoding ID: " + lastEncodingId; - String s = "Encoding ID: " + nr.getEncodingId() + " (" + - ID.getEncodingName(nr.getPlatformId(), nr.getEncodingId()) + ")"; - encodingNode = createNode(s, null); - platformNode.add(encodingNode); - } - if (lastLanguageId != nr.getLanguageId()) { - lastLanguageId = nr.getLanguageId(); -// String s = "Language ID: " + lastLanguageId; - String s = "Language ID: " + nr.getLanguageId() + " (" + - ID.getLanguageName(nr.getPlatformId(), nr.getLanguageId()) + ")"; - languageNode = createNode(s, null); - encodingNode.add(languageNode); - } - String s = "" + nr.getNameId() + " (" + ID.getNameName(nr.getNameId()) + ")"; -// TypecastTreeNode node = createNode(Integer.toString(nr.getNameId()), nr); - TableTreeNode node = createNode(s, nr); - languageNode.add(node); - } - } - - private static void addFeatures(TableTreeNode parent, GsubTable gt, LangSys ls) { - for (int i = 0; i < ls.getFeatureCount(); i++) { - int index = ls.getFeatureIndex(i); - String featureTag = gt.getFeatureList().getFeatureRecord(index).getTagAsString(); - Feature f = gt.getFeatureList().getFeature(index); - TableTreeNode featureNode = new TableTreeNode(featureTag, f); - parent.add(featureNode); - - // Add feature lookups - for (int j = 0; j < f.getLookupCount(); j++) { - Lookup l = gt.getLookupList().getLookup(f.getLookupListIndex(j)); - String type = GsubTable.lookupTypeAsString(l.getType()); - TableTreeNode lookupNode = new TableTreeNode(type, l); - featureNode.add(lookupNode); - - // Add lookup subtables - for (int k = 0; k < l.getSubtableCount(); k++) { - LookupSubtable lsub = l.getSubtable(k); - - // For some reason, lsub can be null - // TODO: find out why - if (lsub != null) { - TableTreeNode lsubNode = new TableTreeNode( - lsub.getTypeAsString(), - lsub); - lookupNode.add(lsubNode); - } - } - } - } - } - - private static void addGsubTable(TableTreeNode parent, GsubTable gt) { - - for (int i = 0; i < gt.getScriptList().getScriptCount(); i++) { - String tag = gt.getScriptList().getScriptRecord(i).getTagAsString(); - Script s = gt.getScriptList().getScript(i); - TableTreeNode scriptNode = new TableTreeNode(tag, s); - parent.add(scriptNode); - - // Add the default LangSys node - TableTreeNode langSysNode = new TableTreeNode( - "default", - s.getDefaultLangSys()); - scriptNode.add(langSysNode); - addFeatures(langSysNode, gt, s.getDefaultLangSys()); - - // Add any additional ones - for (int j = 0; j < s.getLangSysCount(); j++) { - String langSysTag = s.getLangSysRecord(j).getTagAsString(); - LangSys ls = s.getLangSys(j); - langSysNode = new TableTreeNode(langSysTag, ls); - scriptNode.add(langSysNode); - addFeatures(langSysNode, gt, ls); - } - } - } - - private static void addGlyfComposite(OTFont font, TableTreeNode parent, GlyfCompositeDescript gcd) { - PostTable postTable = (PostTable) font.getTable(Table.post); - for (int i = 0; i < gcd.getComponentCount(); i++) { - GlyfCompositeComp gcc = gcd.getComponent(i); - parent.add(new TableTreeNode( - String.valueOf(gcc.getGlyphIndex()) + - ((postTable.getVersion() == 0x00020000) ? - (" " + postTable.getGlyphName(gcc.getGlyphIndex())) : - ""), - gcc, - i)); - } - } - - private static void addGlyfTable(OTFont font, TableTreeNode parent, GlyfTable gt) { - PostTable postTable = (PostTable) font.getTable(Table.post); - for (int i = 0; i < font.getNumGlyphs(); i++) { - GlyfDescript gd = gt.getDescription(i); - TableTreeNode n = new TableTreeNode( - String.valueOf(i) + - ((postTable.getVersion() == 0x00020000) ? - (" " + postTable.getGlyphName(i)) : - ""), - gd, - i); - parent.add(n); - if ((gd != null) && gd.isComposite()) { - - // We need to add the constituent glyphs - addGlyfComposite(font, n, (GlyfCompositeDescript) gd); - } - } - } - - private static void addCffFont( - OTFont font, - TableTreeNode parent, - CffFont cf) { - for (int i = 0; i < cf.getCharstringCount(); ++i) { - Charstring cs = cf.getCharstring(i); - TableTreeNode n = new TableTreeNode( - String.valueOf(i) + " " + cs.getName(), - cs, - i); - parent.add(n); - } - } - - private static void addCffTable(OTFont font, TableTreeNode parent, CffTable ct) { - NameIndex ni = ct.getNameIndex(); - for (int i = 0; i < ni.getCount(); ++i) { - TableTreeNode n = new TableTreeNode( - ni.getName(i), - ni, - i); - parent.add(n); - addCffFont(font, n, ct.getFont(i)); - } - } - - private static void addSbixStrike(OTFont font, TableTreeNode parent, SbixTable.Strike strike) { - int i = 0; - for (SbixTable.GlyphDataRecord gdr : strike.getGlyphDataRecords()) { - TableTreeNode n = new TableTreeNode( - String.valueOf(i), - gdr, - i++); - parent.add(n); - } - } - - private static void addSbixTable(OTFont font, TableTreeNode parent, SbixTable sbix) { - int i = 0; - for (SbixTable.Strike strike : sbix.getStrikes()) { - TableTreeNode n = new TableTreeNode( - strike.toString(), - strike, - i++); - parent.add(n); - addSbixStrike(font, n, strike); - } - } - - private static void addTableDirectoryEntry(OTFont font, TableTreeNode parent, DirectoryEntry de) { - TableTreeNode node = createNode(de.getTagAsString(), font.getTable(de.getTag())); - parent.add(node); - switch (de.getTag()) { - case Table.name: - addNameTable(node, (NameTable) font.getTable(Table.name)); - break; - case Table.cmap: - addCmapTable(node, (CmapTable) font.getTable(Table.cmap)); - break; - case Table.glyf: - addGlyfTable(font, node, (GlyfTable) font.getTable(Table.glyf)); - break; - case Table.CFF: - addCffTable(font, node, (CffTable) font.getTable(Table.CFF)); - break; - case Table.GSUB: - addGsubTable(node, (GsubTable) font.getTable(Table.GSUB)); - break; - case Table.sbix: - addSbixTable(font, node, (SbixTable) font.getTable(Table.sbix)); - break; - default: - break; - } - } - - public static void addFontTree(TreeModel treeModel, OTFontCollection fc) { - - TableTreeNode fcNode = createNode(fc.getPathName(), fc); - ((TableTreeNode) treeModel.getRoot()).add(fcNode); - - // Add each font in this collection - for (int i = 0; i < fc.getFontCount(); i++) { - OTFont font = fc.getFont(i); - TableTreeNode node = createNode( - font.getNameTable().getRecordString(ID.nameFullFontName), - font); - fcNode.add(node); - for (int j = 0; j < font.getTableDirectory().getNumTables(); j++) { - DirectoryEntry de = font.getTableDirectory().getEntry(j); - addTableDirectoryEntry(font, node, de); - } - } - ((DefaultTreeModel) treeModel).reload(); - } - - public static TreeModel createTypecastTreeModel() { - TableTreeNode node = createNode("Root", null); - TreeModel treeModel = new DefaultTreeModel(node); - return treeModel; - } - - private static TableTreeNode createNode(String name, Object obj) { - return new TableTreeNode(name, obj); - } -} diff --git a/src/net/java/dev/typecast/app/editor/TableTreeCellRenderer.java b/src/net/java/dev/typecast/app/editor/TableTreeCellRenderer.java deleted file mode 100644 index ef23909..0000000 --- a/src/net/java/dev/typecast/app/editor/TableTreeCellRenderer.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -import java.awt.Font; -import java.awt.Graphics; -import java.awt.SystemColor; - -import javax.swing.Icon; -import javax.swing.JLabel; -import javax.swing.JTree; - -import javax.swing.tree.TreeCellRenderer; - -/** - * @author David Schweinsberg - */ -public class TableTreeCellRenderer extends JLabel implements TreeCellRenderer { - - private static final long serialVersionUID = 1L; - - private boolean _selected; - private Font font = new java.awt.Font("SansSerif", java.awt.Font.PLAIN, 12); - - public java.awt.Component getTreeCellRendererComponent( - JTree tree, - Object value, - boolean selected, - boolean expanded, - boolean leaf, - int row, - boolean hasFocus) { - - String str = tree.convertValueToText( - value, - selected, - expanded, - leaf, - row, - hasFocus); - setFont(font); - setText(str); - setToolTipText(str); - if (leaf) { - setIcon(null); - } else { - setIcon(null); - } - setForeground( - selected ? - SystemColor.textHighlightText : - SystemColor.textText); - _selected = selected; - return this; - } - - public void paint(Graphics g) { - if (_selected) { - g.setColor(SystemColor.textHighlight); - } else if(getParent() != null) { - g.setColor(getParent().getBackground()); - } else { - g.setColor(getBackground()); - } - Icon icon = getIcon(); - int offset = 0; - if (icon != null && getText() != null) { - offset = icon.getIconWidth() + getIconTextGap(); - } - g.fillRect(offset, 0, getWidth() - 1 - offset, getHeight() - 1); - super.paint(g); - } -} diff --git a/src/net/java/dev/typecast/app/editor/TableTreeNode.java b/src/net/java/dev/typecast/app/editor/TableTreeNode.java deleted file mode 100644 index 7718eef..0000000 --- a/src/net/java/dev/typecast/app/editor/TableTreeNode.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2016 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.editor; - -/** - * - * @author David Schweinsberg - */ -public class TableTreeNode extends javax.swing.tree.DefaultMutableTreeNode { - - private static final long serialVersionUID = 1L; - - private String _nodeName; - private int _index; - - /** Creates new TableTreeNode */ - public TableTreeNode(String nodeName, Object userObject, int index) { - super(userObject); - _nodeName = nodeName; - _index = index; - } - - public TableTreeNode(String nodeName, Object userObject) { - this(nodeName, userObject, -1); - } - - public int getIndex() { - return _index; - } - - public String toString() { - return _nodeName; - } -} diff --git a/src/net/java/dev/typecast/app/framework/EditorView.java b/src/net/java/dev/typecast/app/framework/EditorView.java deleted file mode 100644 index f97e982..0000000 --- a/src/net/java/dev/typecast/app/framework/EditorView.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2016 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.app.framework; - -import net.java.dev.typecast.ot.OTFont; - -/** - * The standard interface for all Typecast editor "view" components. - * @author David Schweinsberg - */ -public interface EditorView { - public void setModel(OTFont font, Object obj); -} diff --git a/src/net/java/dev/typecast/edit/CharacterMap.java b/src/net/java/dev/typecast/edit/CharacterMap.java deleted file mode 100644 index 5b95e02..0000000 --- a/src/net/java/dev/typecast/edit/CharacterMap.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2016 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.edit; - -import java.awt.Color; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.Font; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Image; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.awt.geom.AffineTransform; -import java.util.ArrayList; -import javax.swing.AbstractListModel; -import javax.swing.JComponent; -import javax.swing.JList; -import javax.swing.JScrollPane; -import javax.swing.ListCellRenderer; -import net.java.dev.typecast.app.framework.EditorView; -import net.java.dev.typecast.ot.OTFont; -import net.java.dev.typecast.ot.table.CmapFormat; -import net.java.dev.typecast.render.GlyphImageFactory; - -/** - * An editor for the character-to-glyph map, as represented in the CmapTable. - * @author David Schweinsberg - */ -public class CharacterMap extends JScrollPane implements EditorView { - - private static final long serialVersionUID = 1L; - - private static final int CELL_WIDTH = 48; - private static final int CELL_HEIGHT = 60; - - private AbstractListModel _listModel; - private CmapFormat _cmapFormat; - private OTFont _font; - private AffineTransform _tx; - private final Font _labelFont = new Font("SansSerif", Font.PLAIN, 10); - - private class Mapping { - - private final int _charCode; - private final int _glyphCode; - - public Mapping(int charCode, int glyphCode) { - _charCode = charCode; - _glyphCode = glyphCode; - } - - public int getCharCode() { - return _charCode; - } - - public int getGlyphCode() { - return _glyphCode; - } - - public Image getGlyphImage() { - - // NOTE: We're not caching the image as we can be dealing with - // quite a lot of them - return GlyphImageFactory.buildImage( - _font.getGlyph(_glyphCode), - _tx, - CELL_WIDTH, - CELL_HEIGHT - 10); - } - } - - private class CharListCellRenderer extends JComponent implements ListCellRenderer { - - private static final long serialVersionUID = 1L; - - private Mapping _mapping; - private int _index; - private boolean _isSelected; - private final AffineTransform _imageTx = - new AffineTransform(1.0, 0.0, 0.0, 1.0, 0.0, 0.0); - - /** - * Renders each individual cell - */ - @Override - protected void paintComponent(Graphics g) { - Graphics2D g2d = (Graphics2D) g; - - if (_isSelected) { - g2d.setColor(Color.BLACK); - g2d.fillRect(0, CELL_HEIGHT - 10, CELL_WIDTH, 10); - g2d.setColor(Color.WHITE); - } else { - g2d.setColor(Color.WHITE); - g2d.fillRect(0, CELL_HEIGHT - 10, CELL_WIDTH, 10); - g2d.setColor(Color.BLACK); - } - - // Draw the glyph - g2d.drawImage(_mapping.getGlyphImage(), _imageTx, null); - - // Label this cell with the character code - g2d.setFont(_labelFont); - g2d.drawString( - String.format("%04X", _mapping.getCharCode()), - 1, - CELL_HEIGHT - 1); - } - - @Override - public Component getListCellRendererComponent( - JList list, - Object value, - int index, - boolean isSelected, - boolean cellHasFocus) { - _mapping = (Mapping) value; - _index = index; - _isSelected = isSelected; - setPreferredSize(new Dimension(CELL_WIDTH + 1, CELL_HEIGHT + 1)); - setToolTipText(String.format("Glyph ID: %d", - _mapping.getGlyphCode())); - return this; - } - } - - /** Creates a new instance of CharacterMap */ - public CharacterMap() { - super( - JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, - JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); - setName("Character Map"); - } - - @Override - public void setModel(OTFont font, Object obj) { - if (obj instanceof CmapFormat) { - _font = font; - _cmapFormat = (CmapFormat) obj; - - // Set up a list model to wrap the cmap - _listModel = new AbstractListModel() { - - private static final long serialVersionUID = 1L; - private final ArrayList _mappings = new ArrayList<>(); - - { - for (int i = 0; i < _cmapFormat.getRangeCount(); ++i) { - CmapFormat.Range range = _cmapFormat.getRange(i); - for (int j = range.getStartCode(); j <= range.getEndCode(); ++j) { - _mappings.add(new Mapping(j, _cmapFormat.mapCharCode(j))); - } - } - } - - @Override - public Object getElementAt(int index) { - return _mappings.get(index); - } - - @Override - public int getSize() { - return _mappings.size(); - } - }; - - final JList list = new JList(_listModel); - list.setBackground(Color.LIGHT_GRAY); - list.setCellRenderer(new CharListCellRenderer()); - list.setLayoutOrientation(JList.HORIZONTAL_WRAP); - list.setVisibleRowCount( - _listModel.getSize() / 16 + - (_listModel.getSize() % 16 > 0 ? 1 : 0)); - setViewportView(list); - - // Create a mouse listener so we can listen to double-clicks - MouseListener mouseListener = new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (e.getClickCount() == 2) { - int index = list.locationToIndex(e.getPoint()); - } - } - }; - list.addMouseListener(mouseListener); - - // int unitsPerEmBy2 = _font.getHeadTable().getUnitsPerEm() / 2; - // int translateX = 2 * unitsPerEmBy2; - // int translateY = 2 * unitsPerEmBy2; - - // How much should we scale the font to fit it into our tiny bitmap? - double scaleFactor = 40.0 / _font.getHeadTable().getUnitsPerEm(); - - _tx = new AffineTransform(); - _tx.translate(2, CELL_HEIGHT - 20); - _tx.scale(scaleFactor, -scaleFactor); - } - } -} diff --git a/src/net/java/dev/typecast/edit/Command.java b/src/net/java/dev/typecast/edit/Command.java deleted file mode 100644 index 5ac42d6..0000000 --- a/src/net/java/dev/typecast/edit/Command.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.edit; - -/** - * - * @author David Schweinsberg - */ -public abstract class Command { - - /** Creates new Command */ - public Command() { - } - - abstract void execute(); - - abstract void unexecute(); - -} diff --git a/src/net/java/dev/typecast/edit/GlyphEdit.java b/src/net/java/dev/typecast/edit/GlyphEdit.java deleted file mode 100644 index a70d1e7..0000000 --- a/src/net/java/dev/typecast/edit/GlyphEdit.java +++ /dev/null @@ -1,339 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004-2016 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.edit; - -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.event.MouseEvent; -import java.awt.geom.AffineTransform; -import java.awt.geom.GeneralPath; -import java.awt.geom.Line2D; -import java.awt.geom.Rectangle2D; -import java.util.HashSet; -import java.util.Set; -import javax.swing.JPanel; -import javax.swing.Scrollable; -import javax.swing.event.MouseInputListener; -import net.java.dev.typecast.ot.Glyph; -import net.java.dev.typecast.ot.OTFont; -import net.java.dev.typecast.ot.Point; -import net.java.dev.typecast.ot.T2Glyph; -import net.java.dev.typecast.render.GlyphPathFactory; - -/** - * The glyph editor. The user will perform operations on the glyph within this - * window using a variety of tools derived from {@link Tool Tool}. - * @author David Schweinsberg - */ -public class GlyphEdit extends JPanel implements Scrollable { - - private static final long serialVersionUID = 1L; - - private Glyph _glyph = null; - private OTFont _font = null; - private Tool _tool = null; - private GeneralPath _glyphPath; - - private int _translateX = 0; - private int _translateY = 0; - private double _scaleFactor = 0.25f; - - private boolean _drawControlPoints = true; - private boolean _drawHints = false; - private boolean _preview = false; - private final Set _selectedPoints = new HashSet<>(); - - /** Creates new GlyphEdit */ - public GlyphEdit() { - - setName("ContourView"); - setLayout(null); - - _tool = new PointTool(this); - - MouseInputListener mil = new MouseInputListener() { - @Override - public void mouseClicked(MouseEvent e) { - } - @Override - public void mouseEntered(MouseEvent e) { } - @Override - public void mouseExited(MouseEvent e) { } - @Override - public void mousePressed(MouseEvent e) { - if (_tool != null) { - if (e.isControlDown()) { - _tool.pressedControl(e.getPoint()); - } else { - _tool.pressed(e.getPoint()); - } - } - } - @Override - public void mouseReleased(MouseEvent e) { - if (_tool != null) { - _tool.released(e.getPoint()); - } - } - @Override - public void mouseDragged(MouseEvent e) { - if (_tool != null) { - _tool.dragged(e.getPoint()); - } - } - @Override - public void mouseMoved(MouseEvent e) { } - }; - addMouseListener(mil); - addMouseMotionListener(mil); - } - - @Override - public void paint(Graphics graphics) { - super.paint(graphics); - - if (_glyph == null) { - return; - } - - Graphics2D g2d = (Graphics2D) graphics; - - int unitsPerEmBy2 = _font.getHeadTable().getUnitsPerEm() / 2; - _translateX = 2 * unitsPerEmBy2; - _translateY = 2 * unitsPerEmBy2; - - AffineTransform at = g2d.getTransform(); - AffineTransform atOriginal = new AffineTransform(at); - at.scale(_scaleFactor, _scaleFactor); - at.translate(_translateX, _translateY); - at.scale(1.0, -1.0); - g2d.setTransform(at); - - // Draw grid - g2d.setPaint(Color.gray); - g2d.draw(new Line2D.Float(-unitsPerEmBy2, 0, unitsPerEmBy2, 0)); - g2d.draw(new Line2D.Float(0, -unitsPerEmBy2, 0, unitsPerEmBy2)); - - // Draw guides - g2d.setPaint(Color.lightGray); - g2d.draw(new Line2D.Float(-unitsPerEmBy2, _font.getAscent(), unitsPerEmBy2, _font.getAscent())); - g2d.draw(new Line2D.Float(-unitsPerEmBy2, _font.getDescent(), unitsPerEmBy2, _font.getDescent())); - g2d.draw(new Line2D.Float(_glyph.getLeftSideBearing(), -unitsPerEmBy2, _glyph.getLeftSideBearing(), unitsPerEmBy2)); - g2d.draw(new Line2D.Float(_glyph.getAdvanceWidth(), -unitsPerEmBy2, _glyph.getAdvanceWidth(), unitsPerEmBy2)); - - if (_drawHints && _glyph instanceof T2Glyph) { - T2Glyph t2g = (T2Glyph) _glyph; -// Rectangle2D bounds = t2g.getBounds(); - -// g2d.setPaint(Color.PINK); -// g2d.fill(bounds); - - g2d.setPaint(Color.RED); - - int y = 0; - for (Integer horiz : t2g.getHStems()) { - y += horiz; - g2d.draw(new Line2D.Float(0, y, 1000, y)); - } - - int x = 0; - for (Integer vert : t2g.getVStems()) { - x += vert; - g2d.draw(new Line2D.Float(x, 0, x, 1000)); - } - } - - // Draw contours - g2d.setPaint(Color.black); - - if (_glyphPath == null) { - _glyphPath = GlyphPathFactory.buildPath(_glyph); - } - - // Render the glyph path - if (_preview) { - g2d.fill(_glyphPath); - } else { - g2d.draw(_glyphPath); - } - - if (_drawControlPoints) { - - AffineTransform at2 = new AffineTransform(atOriginal); - g2d.setTransform(at2); - - // Draw control points - for (int i = 0; i < _glyph.getPointCount(); i++) { - int x = (int) (_scaleFactor * (_glyph.getPoint(i).x + _translateX)); - int y = (int) (_scaleFactor * (-_glyph.getPoint(i).y + _translateY)); - - // Set the point colour based on selection - if (_selectedPoints.contains(_glyph.getPoint(i))) { - g2d.setPaint(Color.blue); - } else { - g2d.setPaint(Color.black); - } - - // Draw the point based on its type (on or off curve) - if (_glyph.getPoint(i).onCurve) { - g2d.fill(new Rectangle2D.Float(x - 2, y - 2, 5, 5)); - } else { - g2d.draw(new Rectangle2D.Float(x - 2, y - 2, 5, 5)); - } - g2d.drawString(Integer.toString(i), x + 4, y - 4); - } - } - } - - public Glyph getGlyph() { - return _glyph; - } - - public void setGlyph(Glyph glyph) { - - _glyph = glyph; - - // How much space does this glyph need? -// xOrigin = 0x5000; -// yOrigin = 0x7080; - - setPreferredSize(new Dimension(1024, 1024)); - setSize(new Dimension(1024, 1024)); - - // We have a new glyph, so repaint - _glyphPath = null; - invalidate(); - repaint(); - } - - public void modified() { - _glyphPath = null; - } - - public int getTranslateX() { - return _translateX; - } - - public void setTranslateX(int x) { - _translateX = x; - } - - public int getTranslateY() { - return _translateY; - } - - public void setTranslateY(int y) { - _translateY = y; - } - - public double getScaleFactor() { - return _scaleFactor; - } - - public void setScaleFactor(double factor) { - _scaleFactor = factor; - } - - public boolean isDrawControlPoints() { - return _drawControlPoints; - } - - public void setDrawControlPoints(boolean b) { - _drawControlPoints = b; - } - - public boolean isDrawHints() { - return _drawHints; - } - - public void setDrawHints(boolean b) { - _drawHints = b; - } - - public boolean isPreview() { - return _preview; - } - - public void setPreview(boolean b) { - _preview = b; - } - - public Set getSelectedPoints() { - return _selectedPoints; - } - -// private int transform(int p, int scale, int translate) { -// return ((p * scale) >> 6) + translate; -// } - -// public Font getFont() { -// return font; -// } - - public void setFont(OTFont font) { - _font = font; -// glyph = font.getGlyph(glyphIndex); - _glyph = null; -// repaint(); - - // Determine the default view scaling for this font - short unitsPerEm = _font.getHeadTable().getUnitsPerEm(); - - _scaleFactor = 512.0 / unitsPerEm; - } - - public Tool getTool() { - return _tool; - } - - public void setTool(Tool tool) { - _tool = tool; - } - -// public void executeCommand(Command command) { -// } - - @Override - public boolean getScrollableTracksViewportWidth() { - return false; - } - - @Override - public int getScrollableBlockIncrement(java.awt.Rectangle rectangle, int param, int param2) { - return 10; - } - - @Override - public boolean getScrollableTracksViewportHeight() { - return false; - } - - @Override - public java.awt.Dimension getPreferredScrollableViewportSize() { - return getPreferredSize(); - } - - @Override - public int getScrollableUnitIncrement(java.awt.Rectangle rectangle, int param, int param2) { - return 1; - } - -} diff --git a/src/net/java/dev/typecast/edit/PointTool.java b/src/net/java/dev/typecast/edit/PointTool.java deleted file mode 100644 index 692c4a1..0000000 --- a/src/net/java/dev/typecast/edit/PointTool.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.edit; - -import java.awt.Cursor; -import java.awt.Point; - -import java.util.Iterator; -import java.util.Set; - -import net.java.dev.typecast.edit.GlyphEdit; - -import net.java.dev.typecast.ot.Glyph; - -/** - * A simple point selection and manipulation tool. Allows the user to select a - * point with the cursor, to move that point by dragging, and to move the point - * on- and off-curve by selecting the point with the control key pressed. - * @author David Schweinsberg - */ -public class PointTool extends Tool { - - private GlyphEdit _glyphEdit; - private Command _command; - - /** Creates new PointTool */ - public PointTool(GlyphEdit glyphEdit) { - _glyphEdit = glyphEdit; - - // BUG: The crosshair cursor keeps coming up as a text cursor on my - // Windows XP system :-( - //_glyphEdit.setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR)); - _glyphEdit.setCursor(new Cursor(Cursor.DEFAULT_CURSOR)); - } - - /** - * Selects a point - */ - public void pressed(Point p) { - _glyphEdit.getSelectedPoints().clear(); - Glyph glyph = _glyphEdit.getGlyph(); - for (int i = 0; i < glyph.getPointCount(); i++) { - net.java.dev.typecast.ot.Point gp = glyph.getPoint(i); - double gpx = _glyphEdit.getScaleFactor() * (gp.x + _glyphEdit.getTranslateX()); - double gpy = _glyphEdit.getScaleFactor() * (-gp.y + _glyphEdit.getTranslateY()); - if (((gpx >= p.x - 2) && (gpx <= p.x + 2)) && - ((gpy >= p.y - 2) && (gpy <= p.y + 2))) { - _glyphEdit.getSelectedPoints().add(gp); - } - } - _glyphEdit.modified(); - _glyphEdit.repaint(); - } - - /** - * Toggles the selected point between on-curve and off-curve - */ - public void pressedControl(Point p) { - Glyph glyph = _glyphEdit.getGlyph(); - for (int i = 0; i < glyph.getPointCount(); i++) { - net.java.dev.typecast.ot.Point gp = glyph.getPoint(i); - double gpx = _glyphEdit.getScaleFactor() * (gp.x + _glyphEdit.getTranslateX()); - double gpy = _glyphEdit.getScaleFactor() * (-gp.y + _glyphEdit.getTranslateY()); - if (((gpx >= p.x - 2) && (gpx <= p.x + 2)) && - ((gpy >= p.y - 2) && (gpy <= p.y + 2))) { - gp.onCurve = !gp.onCurve; - } - } - _glyphEdit.modified(); - _glyphEdit.repaint(); - } - - /** - * Moves the selected points - */ - public void dragged(Point p) { - int x = (int)(p.x / _glyphEdit.getScaleFactor() - _glyphEdit.getTranslateX()); - int y = -(int)(p.y / _glyphEdit.getScaleFactor() - _glyphEdit.getTranslateY()); - Iterator iter = _glyphEdit.getSelectedPoints().iterator(); - while (iter.hasNext()) { - net.java.dev.typecast.ot.Point gp = (net.java.dev.typecast.ot.Point) iter.next(); - gp.x = x; - gp.y = y; - } - _glyphEdit.modified(); - _glyphEdit.repaint(); - } - - /** - * nop - */ - public void released(Point p) { - } -} diff --git a/src/net/java/dev/typecast/edit/SelectCommand.java b/src/net/java/dev/typecast/edit/SelectCommand.java deleted file mode 100644 index c5a41bf..0000000 --- a/src/net/java/dev/typecast/edit/SelectCommand.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.edit; - - - -/** - * - * @author David Schweinsberg - */ -public class SelectCommand extends Command { - - /** Creates new SelectCommand */ - public SelectCommand() { - } - - void unexecute() { - } - - void execute() { - } - -} diff --git a/src/net/java/dev/typecast/edit/Tool.java b/src/net/java/dev/typecast/edit/Tool.java deleted file mode 100644 index 679a495..0000000 --- a/src/net/java/dev/typecast/edit/Tool.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Typecast - The Font Development Environment - * - * Copyright (c) 2004 David Schweinsberg - * - * Licensed 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 net.java.dev.typecast.edit; - -import java.awt.Point; -import java.awt.Window; - -/** - * - * @author David Schweinsberg - */ -public abstract class Tool { - - public abstract void pressed(Point p); - - public abstract void pressedControl(Point p); - - public abstract void released(Point p); - - public abstract void dragged(Point p); -} -- cgit v1.2.3