1 /******************************************************************************* 2 * Copyright 2011-2015 See AUTHORS file. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 ******************************************************************************/ 16 17 package com.badlogic.gdx.tools.hiero; 18 19 import static org.lwjgl.opengl.GL11.*; 20 21 import java.awt.BorderLayout; 22 import java.awt.Component; 23 import java.awt.Container; 24 import java.awt.Dimension; 25 import java.awt.EventQueue; 26 import java.awt.FileDialog; 27 import java.awt.FlowLayout; 28 import java.awt.Font; 29 import java.awt.Frame; 30 import java.awt.GraphicsEnvironment; 31 import java.awt.GridBagConstraints; 32 import java.awt.GridBagLayout; 33 import java.awt.Insets; 34 import java.awt.LayoutManager; 35 import java.awt.event.ActionEvent; 36 import java.awt.event.ActionListener; 37 import java.awt.event.KeyAdapter; 38 import java.awt.event.KeyEvent; 39 import java.awt.event.MouseAdapter; 40 import java.awt.event.MouseEvent; 41 import java.awt.event.WindowAdapter; 42 import java.awt.event.WindowEvent; 43 import java.awt.image.BufferedImage; 44 import java.io.File; 45 import java.io.IOException; 46 import java.util.ArrayList; 47 import java.util.Iterator; 48 import java.util.List; 49 import java.util.prefs.Preferences; 50 51 import javax.swing.BorderFactory; 52 import javax.swing.ButtonGroup; 53 import javax.swing.DefaultComboBoxModel; 54 import javax.swing.Icon; 55 import javax.swing.ImageIcon; 56 import javax.swing.JButton; 57 import javax.swing.JCheckBox; 58 import javax.swing.JColorChooser; 59 import javax.swing.JComboBox; 60 import javax.swing.JFormattedTextField; 61 import javax.swing.JFrame; 62 import javax.swing.JLabel; 63 import javax.swing.JList; 64 import javax.swing.JMenu; 65 import javax.swing.JMenuBar; 66 import javax.swing.JMenuItem; 67 import javax.swing.JPanel; 68 import javax.swing.JRadioButton; 69 import javax.swing.JScrollPane; 70 import javax.swing.JSpinner; 71 import javax.swing.JTextField; 72 import javax.swing.JTextPane; 73 import javax.swing.JWindow; 74 import javax.swing.KeyStroke; 75 import javax.swing.ScrollPaneConstants; 76 import javax.swing.SpinnerModel; 77 import javax.swing.SpinnerNumberModel; 78 import javax.swing.SwingUtilities; 79 import javax.swing.border.EmptyBorder; 80 import javax.swing.event.ChangeEvent; 81 import javax.swing.event.ChangeListener; 82 import javax.swing.event.DocumentEvent; 83 import javax.swing.event.DocumentListener; 84 import javax.swing.event.ListSelectionEvent; 85 import javax.swing.event.ListSelectionListener; 86 87 import org.lwjgl.opengl.GL11; 88 89 import com.badlogic.gdx.ApplicationAdapter; 90 import com.badlogic.gdx.Gdx; 91 import com.badlogic.gdx.backends.lwjgl.LwjglCanvas; 92 import com.badlogic.gdx.graphics.Color; 93 import com.badlogic.gdx.graphics.Texture; 94 import com.badlogic.gdx.graphics.g2d.BitmapFont; 95 import com.badlogic.gdx.graphics.g2d.SpriteBatch; 96 import com.badlogic.gdx.tools.hiero.unicodefont.GlyphPage; 97 import com.badlogic.gdx.tools.hiero.unicodefont.UnicodeFont; 98 import com.badlogic.gdx.tools.hiero.unicodefont.UnicodeFont.RenderType; 99 import com.badlogic.gdx.tools.hiero.unicodefont.effects.ColorEffect; 100 import com.badlogic.gdx.tools.hiero.unicodefont.effects.ConfigurableEffect; 101 import com.badlogic.gdx.tools.hiero.unicodefont.effects.ConfigurableEffect.Value; 102 import com.badlogic.gdx.utils.StringBuilder; 103 import com.badlogic.gdx.tools.hiero.unicodefont.effects.DistanceFieldEffect; 104 import com.badlogic.gdx.tools.hiero.unicodefont.effects.EffectUtil; 105 import com.badlogic.gdx.tools.hiero.unicodefont.effects.GradientEffect; 106 import com.badlogic.gdx.tools.hiero.unicodefont.effects.OutlineEffect; 107 import com.badlogic.gdx.tools.hiero.unicodefont.effects.OutlineWobbleEffect; 108 import com.badlogic.gdx.tools.hiero.unicodefont.effects.OutlineZigzagEffect; 109 import com.badlogic.gdx.tools.hiero.unicodefont.effects.ShadowEffect; 110 111 /** A tool to visualize settings for {@link UnicodeFont} and to export BMFont files for use with {@link BitmapFont}. 112 * <p> 113 * This tool is quite old. It was originally written for Slick, then ported to libgdx. It has had a few different contributors 114 * over the years, the FreeType rendering was tacked on and in general the code isn't great. It does its job though! 115 * @author Nathan Sweet */ 116 public class Hiero extends JFrame { 117 UnicodeFont unicodeFont; 118 Color renderingBackgroundColor = Color.BLACK; 119 List<EffectPanel> effectPanels = new ArrayList<EffectPanel>(); 120 Preferences prefs; 121 ColorEffect colorEffect; 122 boolean batchMode = false; 123 124 JScrollPane appliedEffectsScroll; 125 JPanel appliedEffectsPanel; 126 JButton addEffectButton; 127 JTextPane sampleTextPane; 128 JSpinner padAdvanceXSpinner; 129 JList effectsList; 130 LwjglCanvas rendererCanvas; 131 JPanel gamePanel; 132 JTextField fontFileText; 133 JRadioButton fontFileRadio; 134 JRadioButton systemFontRadio; 135 JSpinner padBottomSpinner; 136 JSpinner padLeftSpinner; 137 JSpinner padRightSpinner; 138 JSpinner padTopSpinner; 139 JList fontList; 140 JSpinner fontSizeSpinner; 141 JSpinner gammaSpinner; 142 DefaultComboBoxModel fontListModel; 143 JLabel backgroundColorLabel; 144 JButton browseButton; 145 JSpinner padAdvanceYSpinner; 146 JCheckBox italicCheckBox; 147 JCheckBox boldCheckBox; 148 JCheckBox monoCheckBox; 149 JRadioButton javaRadio; 150 JRadioButton nativeRadio; 151 JRadioButton freeTypeRadio; 152 JLabel glyphsTotalLabel; 153 JLabel glyphPagesTotalLabel; 154 JComboBox glyphPageHeightCombo; 155 JComboBox glyphPageWidthCombo; 156 JComboBox glyphPageCombo; 157 JPanel glyphCachePanel; 158 JRadioButton glyphCacheRadio; 159 JRadioButton sampleTextRadio; 160 DefaultComboBoxModel glyphPageComboModel; 161 JButton resetCacheButton; 162 JButton sampleAsciiButton; 163 JButton sampleNeheButton; 164 JButton sampleExtendedButton; 165 DefaultComboBoxModel effectsListModel; 166 JMenuItem openMenuItem; 167 JMenuItem saveMenuItem; 168 JMenuItem exitMenuItem; 169 JMenuItem saveBMFontMenuItem; 170 File saveBmFontFile; 171 String lastSaveFilename = "", lastSaveBMFilename = "", lastOpenFilename = ""; 172 JPanel effectsPanel; 173 JScrollPane effectsScroll; 174 JPanel unicodePanel, bitmapPanel; 175 Hiero(String[] args)176 public Hiero (String[] args) { 177 super("Hiero v5 - Bitmap Font Tool"); 178 Splash splash = new Splash(this, "/splash.jpg", 2000); 179 initialize(); 180 splash.close(); 181 182 rendererCanvas = new LwjglCanvas(new Renderer()); 183 gamePanel.add(rendererCanvas.getCanvas()); 184 185 prefs = Preferences.userNodeForPackage(Hiero.class); 186 java.awt.Color backgroundColor = EffectUtil.fromString(prefs.get("background", "000000")); 187 backgroundColorLabel.setIcon(getColorIcon(backgroundColor)); 188 renderingBackgroundColor = new Color(backgroundColor.getRed() / 255f, backgroundColor.getGreen() / 255f, 189 backgroundColor.getBlue() / 255f, 1); 190 fontList.setSelectedValue(prefs.get("system.font", "Arial"), true); 191 fontFileText.setText(prefs.get("font.file", "")); 192 193 java.awt.Color foregroundColor = EffectUtil.fromString(prefs.get("foreground", "ffffff")); 194 colorEffect = new ColorEffect(); 195 colorEffect.setColor(foregroundColor); 196 effectsListModel.addElement(colorEffect); 197 effectsListModel.addElement(new GradientEffect()); 198 effectsListModel.addElement(new OutlineEffect()); 199 effectsListModel.addElement(new OutlineWobbleEffect()); 200 effectsListModel.addElement(new OutlineZigzagEffect()); 201 effectsListModel.addElement(new ShadowEffect()); 202 effectsListModel.addElement(new DistanceFieldEffect()); 203 new EffectPanel(colorEffect); 204 205 parseArgs(args); 206 207 addWindowListener(new WindowAdapter() { 208 public void windowClosed (WindowEvent event) { 209 System.exit(0); 210 // Gdx.app.quit(); 211 } 212 }); 213 214 updateFontSelector(); 215 setVisible(true); 216 } 217 initialize()218 void initialize () { 219 initializeComponents(); 220 initializeMenus(); 221 initializeEvents(); 222 223 setSize(1024, 600); 224 setLocationRelativeTo(null); 225 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 226 } 227 parseArgs(String[] args)228 private void parseArgs (String[] args) { 229 float scale = 1f; 230 231 for (int i = 0; i < args.length; i++) { 232 final String param = args[i]; 233 final boolean more = i < args.length - 1; 234 235 if (param.equals("-b") || param.equals("--batch")) { 236 batchMode = true; 237 } else if (more && (param.equals("-s") || param.equals("--scale"))) { 238 scale = Float.parseFloat(args[++i]); 239 } else if (more && (param.equals("-i") || param.equals("--input"))) { 240 File f = new File(args[++i]); 241 open(f); 242 fontFileRadio.setText(""); 243 updateFont(); 244 } else if (more && (param.equals("-o") || param.equals("--output"))) { 245 File f = new File(args[++i]); 246 saveBm(f); 247 } else { 248 System.err.println("Unknown parameter: " + param); 249 exit(3); 250 } 251 } 252 253 fontSizeSpinner.setValue((int)(0.5f + Math.max(4, scale * ((Integer)fontSizeSpinner.getValue())))); 254 } 255 256 void updateFontSelector () { 257 final boolean useFile = fontFileRadio.isSelected(); 258 fontList.setEnabled(!useFile); 259 fontFileText.setEnabled(useFile); 260 browseButton.setEnabled(useFile); 261 } 262 263 void updateFont () { 264 int fontSize = ((Integer)fontSizeSpinner.getValue()).intValue(); 265 266 File file = null; 267 if (fontFileRadio.isSelected()) { 268 file = new File(fontFileText.getText()); 269 if (!file.exists() || !file.isFile()) file = null; 270 } 271 272 boolean isFreeType = freeTypeRadio.isSelected(); 273 boolean isNative = nativeRadio.isSelected(); 274 boolean isJava = javaRadio.isSelected(); 275 addEffectButton.setVisible(isJava); 276 effectsScroll.setVisible(isJava); 277 appliedEffectsScroll.setVisible(isJava); 278 boldCheckBox.setEnabled(!isFreeType); 279 italicCheckBox.setEnabled(!isFreeType); 280 bitmapPanel.setVisible(isFreeType); 281 unicodePanel.setVisible(!isFreeType); 282 updateFontSelector(); 283 284 UnicodeFont unicodeFont = null; 285 if (file != null) { 286 // Load from file. 287 try { 288 unicodeFont = new UnicodeFont(fontFileText.getText(), fontSize, boldCheckBox.isSelected(), 289 italicCheckBox.isSelected()); 290 } catch (Throwable ex) { 291 ex.printStackTrace(); 292 fontFileRadio.setSelected(false); 293 } 294 } 295 296 if (unicodeFont == null) { 297 // Load from java.awt.Font (kerning not available!). 298 unicodeFont = new UnicodeFont(Font.decode((String)fontList.getSelectedValue()), fontSize, boldCheckBox.isSelected(), 299 italicCheckBox.isSelected()); 300 } 301 302 unicodeFont.setMono(monoCheckBox.isSelected()); 303 unicodeFont.setGamma(((Number)gammaSpinner.getValue()).floatValue()); 304 unicodeFont.setPaddingTop(((Number)padTopSpinner.getValue()).intValue()); 305 unicodeFont.setPaddingRight(((Number)padRightSpinner.getValue()).intValue()); 306 unicodeFont.setPaddingBottom(((Number)padBottomSpinner.getValue()).intValue()); 307 unicodeFont.setPaddingLeft(((Number)padLeftSpinner.getValue()).intValue()); 308 unicodeFont.setPaddingAdvanceX(((Number)padAdvanceXSpinner.getValue()).intValue()); 309 unicodeFont.setPaddingAdvanceY(((Number)padAdvanceYSpinner.getValue()).intValue()); 310 unicodeFont.setGlyphPageWidth(((Number)glyphPageWidthCombo.getSelectedItem()).intValue()); 311 unicodeFont.setGlyphPageHeight(((Number)glyphPageHeightCombo.getSelectedItem()).intValue()); 312 if (nativeRadio.isSelected()) 313 unicodeFont.setRenderType(RenderType.Native); 314 else if (freeTypeRadio.isSelected()) 315 unicodeFont.setRenderType(RenderType.FreeType); 316 else 317 unicodeFont.setRenderType(RenderType.Java); 318 319 for (Iterator iter = effectPanels.iterator(); iter.hasNext();) { 320 EffectPanel panel = (EffectPanel)iter.next(); 321 unicodeFont.getEffects().add(panel.getEffect()); 322 } 323 324 int size = sampleTextPane.getFont().getSize(); 325 if (size < 14) size = 14; 326 sampleTextPane.setFont(unicodeFont.getFont().deriveFont((float)size)); 327 328 if (this.unicodeFont != null) this.unicodeFont.dispose(); 329 this.unicodeFont = unicodeFont; 330 331 updateFontSelector(); 332 } 333 334 void saveBm (File file) { 335 saveBmFontFile = file; 336 } 337 338 void save (File file) throws IOException { 339 HieroSettings settings = new HieroSettings(); 340 settings.setFontName((String)fontList.getSelectedValue()); 341 settings.setFontSize(((Integer)fontSizeSpinner.getValue()).intValue()); 342 settings.setFont2File(fontFileText.getText()); 343 settings.setFont2Active(fontFileRadio.isSelected()); 344 settings.setBold(boldCheckBox.isSelected()); 345 settings.setItalic(italicCheckBox.isSelected()); 346 settings.setMono(monoCheckBox.isSelected()); 347 settings.setGamma(((Number)gammaSpinner.getValue()).floatValue()); 348 settings.setPaddingTop(((Number)padTopSpinner.getValue()).intValue()); 349 settings.setPaddingRight(((Number)padRightSpinner.getValue()).intValue()); 350 settings.setPaddingBottom(((Number)padBottomSpinner.getValue()).intValue()); 351 settings.setPaddingLeft(((Number)padLeftSpinner.getValue()).intValue()); 352 settings.setPaddingAdvanceX(((Number)padAdvanceXSpinner.getValue()).intValue()); 353 settings.setPaddingAdvanceY(((Number)padAdvanceYSpinner.getValue()).intValue()); 354 settings.setGlyphPageWidth(((Number)glyphPageWidthCombo.getSelectedItem()).intValue()); 355 settings.setGlyphPageHeight(((Number)glyphPageHeightCombo.getSelectedItem()).intValue()); 356 settings.setGlyphText(sampleTextPane.getText()); 357 for (Iterator iter = effectPanels.iterator(); iter.hasNext();) { 358 EffectPanel panel = (EffectPanel)iter.next(); 359 settings.getEffects().add(panel.getEffect()); 360 } 361 settings.save(file); 362 } 363 364 void open (File file) { 365 EffectPanel[] panels = (EffectPanel[])effectPanels.toArray(new EffectPanel[effectPanels.size()]); 366 for (int i = 0; i < panels.length; i++) 367 panels[i].remove(); 368 369 HieroSettings settings = new HieroSettings(file.getAbsolutePath()); 370 fontList.setSelectedValue(settings.getFontName(), true); 371 fontSizeSpinner.setValue(new Integer(settings.getFontSize())); 372 boldCheckBox.setSelected(settings.isBold()); 373 italicCheckBox.setSelected(settings.isItalic()); 374 monoCheckBox.setSelected(settings.isMono()); 375 gammaSpinner.setValue(new Float(settings.getGamma())); 376 padTopSpinner.setValue(new Integer(settings.getPaddingTop())); 377 padRightSpinner.setValue(new Integer(settings.getPaddingRight())); 378 padBottomSpinner.setValue(new Integer(settings.getPaddingBottom())); 379 padLeftSpinner.setValue(new Integer(settings.getPaddingLeft())); 380 padAdvanceXSpinner.setValue(new Integer(settings.getPaddingAdvanceX())); 381 padAdvanceYSpinner.setValue(new Integer(settings.getPaddingAdvanceY())); 382 glyphPageWidthCombo.setSelectedItem(new Integer(settings.getGlyphPageWidth())); 383 glyphPageHeightCombo.setSelectedItem(new Integer(settings.getGlyphPageHeight())); 384 String gt = settings.getGlyphText(); 385 if (gt.length() > 0) { 386 sampleTextPane.setText(settings.getGlyphText()); 387 } 388 389 final String font2 = settings.getFont2File(); 390 if (font2.length() > 0) 391 fontFileText.setText(font2); 392 else 393 fontFileText.setText(prefs.get("font.file", "")); 394 395 fontFileRadio.setSelected(settings.isFont2Active()); 396 systemFontRadio.setSelected(!settings.isFont2Active()); 397 398 for (Iterator iter = settings.getEffects().iterator(); iter.hasNext();) { 399 ConfigurableEffect settingsEffect = (ConfigurableEffect)iter.next(); 400 for (int i = 0, n = effectsListModel.getSize(); i < n; i++) { 401 ConfigurableEffect effect = (ConfigurableEffect)effectsListModel.getElementAt(i); 402 if (effect.getClass() == settingsEffect.getClass()) { 403 effect.setValues(settingsEffect.getValues()); 404 new EffectPanel(effect); 405 break; 406 } 407 } 408 } 409 410 updateFont(); 411 } 412 413 void exit (final int exitCode) { 414 rendererCanvas.stop(); 415 EventQueue.invokeLater(new Runnable() { 416 public void run () { 417 System.exit(exitCode); 418 } 419 }); 420 } 421 422 private void initializeEvents () { 423 fontList.addListSelectionListener(new ListSelectionListener() { 424 public void valueChanged (ListSelectionEvent evt) { 425 if (evt.getValueIsAdjusting()) return; 426 prefs.put("system.font", (String)fontList.getSelectedValue()); 427 updateFont(); 428 } 429 }); 430 431 class FontUpdateListener implements ChangeListener, ActionListener { 432 public void stateChanged (ChangeEvent evt) { 433 updateFont(); 434 } 435 436 public void actionPerformed (ActionEvent evt) { 437 updateFont(); 438 } 439 440 public void addSpinners (JSpinner[] spinners) { 441 for (int i = 0; i < spinners.length; i++) { 442 final JSpinner spinner = spinners[i]; 443 spinner.addChangeListener(this); 444 ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField().addKeyListener(new KeyAdapter() { 445 String lastText; 446 447 public void keyReleased (KeyEvent evt) { 448 JFormattedTextField textField = ((JSpinner.DefaultEditor)spinner.getEditor()).getTextField(); 449 String text = textField.getText(); 450 if (text.length() == 0) return; 451 if (text.equals(lastText)) return; 452 lastText = text; 453 int caretPosition = textField.getCaretPosition(); 454 try { 455 spinner.setValue(Integer.valueOf(text)); 456 } catch (NumberFormatException ex) { 457 } 458 textField.setCaretPosition(caretPosition); 459 } 460 }); 461 } 462 } 463 } 464 FontUpdateListener listener = new FontUpdateListener(); 465 466 listener.addSpinners(new JSpinner[] {padTopSpinner, padRightSpinner, padBottomSpinner, padLeftSpinner, padAdvanceXSpinner, 467 padAdvanceYSpinner}); 468 fontSizeSpinner.addChangeListener(listener); 469 gammaSpinner.addChangeListener(listener); 470 471 glyphPageWidthCombo.addActionListener(listener); 472 glyphPageHeightCombo.addActionListener(listener); 473 boldCheckBox.addActionListener(listener); 474 italicCheckBox.addActionListener(listener); 475 monoCheckBox.addActionListener(listener); 476 resetCacheButton.addActionListener(listener); 477 javaRadio.addActionListener(listener); 478 nativeRadio.addActionListener(listener); 479 freeTypeRadio.addActionListener(listener); 480 481 sampleTextRadio.addActionListener(new ActionListener() { 482 public void actionPerformed (ActionEvent evt) { 483 glyphCachePanel.setVisible(false); 484 } 485 }); 486 glyphCacheRadio.addActionListener(new ActionListener() { 487 public void actionPerformed (ActionEvent evt) { 488 glyphCachePanel.setVisible(true); 489 } 490 }); 491 492 fontFileText.getDocument().addDocumentListener(new DocumentListener() { 493 public void removeUpdate (DocumentEvent evt) { 494 changed(); 495 } 496 497 public void insertUpdate (DocumentEvent evt) { 498 changed(); 499 } 500 501 public void changedUpdate (DocumentEvent evt) { 502 changed(); 503 } 504 505 private void changed () { 506 File file = new File(fontFileText.getText()); 507 if (fontList.isEnabled() && (!file.exists() || !file.isFile())) return; 508 prefs.put("font.file", fontFileText.getText()); 509 updateFont(); 510 } 511 }); 512 513 final ActionListener al = new ActionListener() { 514 public void actionPerformed (ActionEvent evt) { 515 updateFontSelector(); 516 updateFont(); 517 } 518 }; 519 520 systemFontRadio.addActionListener(al); 521 fontFileRadio.addActionListener(al); 522 523 browseButton.addActionListener(new ActionListener() { 524 public void actionPerformed (ActionEvent evt) { 525 FileDialog dialog = new FileDialog(Hiero.this, "Choose TrueType font file", FileDialog.LOAD); 526 dialog.setLocationRelativeTo(null); 527 dialog.setFile("*.ttf"); 528 dialog.setDirectory(prefs.get("dir.font", "")); 529 dialog.setVisible(true); 530 if (dialog.getDirectory() != null) { 531 prefs.put("dir.font", dialog.getDirectory()); 532 } 533 534 String fileName = dialog.getFile(); 535 if (fileName == null) return; 536 fontFileText.setText(new File(dialog.getDirectory(), fileName).getAbsolutePath()); 537 } 538 }); 539 540 backgroundColorLabel.addMouseListener(new MouseAdapter() { 541 public void mouseClicked (MouseEvent evt) { 542 java.awt.Color color = JColorChooser.showDialog(null, "Choose a background color", 543 EffectUtil.fromString(prefs.get("background", "000000"))); 544 if (color == null) return; 545 renderingBackgroundColor = new Color(color.getRed() / 255f, color.getGreen() / 255f, color.getBlue() / 255f, 1); 546 backgroundColorLabel.setIcon(getColorIcon(color)); 547 prefs.put("background", EffectUtil.toString(color)); 548 } 549 }); 550 551 effectsList.addListSelectionListener(new ListSelectionListener() { 552 public void valueChanged (ListSelectionEvent evt) { 553 ConfigurableEffect selectedEffect = (ConfigurableEffect)effectsList.getSelectedValue(); 554 boolean enabled = selectedEffect != null; 555 for (Iterator iter = effectPanels.iterator(); iter.hasNext();) { 556 ConfigurableEffect effect = ((EffectPanel)iter.next()).getEffect(); 557 if (effect == selectedEffect) { 558 enabled = false; 559 break; 560 } 561 } 562 addEffectButton.setEnabled(enabled); 563 } 564 }); 565 566 effectsList.addMouseListener(new MouseAdapter() { 567 public void mouseClicked (MouseEvent evt) { 568 if (evt.getClickCount() == 2 && addEffectButton.isEnabled()) addEffectButton.doClick(); 569 } 570 }); 571 572 addEffectButton.addActionListener(new ActionListener() { 573 public void actionPerformed (ActionEvent evt) { 574 new EffectPanel((ConfigurableEffect)effectsList.getSelectedValue()); 575 } 576 }); 577 578 openMenuItem.addActionListener(new ActionListener() { 579 public void actionPerformed (ActionEvent evt) { 580 FileDialog dialog = new FileDialog(Hiero.this, "Open Hiero settings file", FileDialog.LOAD); 581 dialog.setLocationRelativeTo(null); 582 dialog.setFile("*.hiero"); 583 dialog.setDirectory(prefs.get("dir.open", "")); 584 dialog.setVisible(true); 585 if (dialog.getDirectory() != null) { 586 prefs.put("dir.open", dialog.getDirectory()); 587 } 588 589 String fileName = dialog.getFile(); 590 if (fileName == null) return; 591 lastOpenFilename = fileName; 592 open(new File(dialog.getDirectory(), fileName)); 593 } 594 }); 595 596 saveMenuItem.addActionListener(new ActionListener() { 597 public void actionPerformed (ActionEvent evt) { 598 FileDialog dialog = new FileDialog(Hiero.this, "Save Hiero settings file", FileDialog.SAVE); 599 dialog.setLocationRelativeTo(null); 600 dialog.setFile("*.hiero"); 601 dialog.setDirectory(prefs.get("dir.save", "")); 602 603 if (lastSaveFilename.length() > 0) { 604 dialog.setFile(lastSaveFilename); 605 } else if (lastOpenFilename.length() > 0) { 606 dialog.setFile(lastOpenFilename); 607 } 608 609 dialog.setVisible(true); 610 611 if (dialog.getDirectory() != null) { 612 prefs.put("dir.save", dialog.getDirectory()); 613 } 614 615 String fileName = dialog.getFile(); 616 if (fileName == null) return; 617 if (!fileName.endsWith(".hiero")) fileName += ".hiero"; 618 lastSaveFilename = fileName; 619 File file = new File(dialog.getDirectory(), fileName); 620 try { 621 save(file); 622 } catch (IOException ex) { 623 throw new RuntimeException("Error saving Hiero settings file: " + file.getAbsolutePath(), ex); 624 } 625 } 626 }); 627 628 saveBMFontMenuItem.addActionListener(new ActionListener() { 629 public void actionPerformed (ActionEvent evt) { 630 FileDialog dialog = new FileDialog(Hiero.this, "Save BMFont files", FileDialog.SAVE); 631 dialog.setLocationRelativeTo(null); 632 dialog.setFile("*.fnt"); 633 dialog.setDirectory(prefs.get("dir.savebm", "")); 634 635 if (lastSaveBMFilename.length() > 0) { 636 dialog.setFile(lastSaveBMFilename); 637 } else if (lastOpenFilename.length() > 0) { 638 dialog.setFile(lastOpenFilename.replace(".hiero", ".fnt")); 639 } 640 641 dialog.setVisible(true); 642 if (dialog.getDirectory() != null) { 643 prefs.put("dir.savebm", dialog.getDirectory()); 644 } 645 646 String fileName = dialog.getFile(); 647 if (fileName == null) return; 648 lastSaveBMFilename = fileName; 649 saveBm(new File(dialog.getDirectory(), fileName)); 650 } 651 }); 652 exitMenuItem.addActionListener(new ActionListener() { public void actionPerformed (ActionEvent evt) { dispose(); } })653 exitMenuItem.addActionListener(new ActionListener() { 654 public void actionPerformed (ActionEvent evt) { 655 dispose(); 656 } 657 }); 658 sampleNeheButton.addActionListener(new ActionListener() { public void actionPerformed (ActionEvent evt) { sampleTextPane.setText(NEHE_CHARS); resetCacheButton.doClick(); } })659 sampleNeheButton.addActionListener(new ActionListener() { 660 public void actionPerformed (ActionEvent evt) { 661 sampleTextPane.setText(NEHE_CHARS); 662 resetCacheButton.doClick(); 663 } 664 }); 665 sampleAsciiButton.addActionListener(new ActionListener() { public void actionPerformed (ActionEvent evt) { StringBuilder buffer = new StringBuilder(); buffer.append(NEHE_CHARS); buffer.append('\\n'); int count = 0; for (int i = 33; i <= 255; i++) { if (buffer.indexOf(Character.toString((char)i)) != -1) continue; buffer.append((char)i); if (++count % 30 == 0) buffer.append('\\n'); } sampleTextPane.setText(buffer.toString()); resetCacheButton.doClick(); } })666 sampleAsciiButton.addActionListener(new ActionListener() { 667 public void actionPerformed (ActionEvent evt) { 668 StringBuilder buffer = new StringBuilder(); 669 buffer.append(NEHE_CHARS); 670 buffer.append('\n'); 671 int count = 0; 672 for (int i = 33; i <= 255; i++) { 673 if (buffer.indexOf(Character.toString((char)i)) != -1) continue; 674 buffer.append((char)i); 675 if (++count % 30 == 0) buffer.append('\n'); 676 } 677 sampleTextPane.setText(buffer.toString()); 678 resetCacheButton.doClick(); 679 } 680 }); 681 sampleExtendedButton.addActionListener(new ActionListener() { public void actionPerformed (ActionEvent evt) { sampleTextPane.setText(EXTENDED_CHARS); resetCacheButton.doClick(); } })682 sampleExtendedButton.addActionListener(new ActionListener() { 683 public void actionPerformed (ActionEvent evt) { 684 sampleTextPane.setText(EXTENDED_CHARS); 685 resetCacheButton.doClick(); 686 } 687 }); 688 } 689 initializeComponents()690 private void initializeComponents () { 691 getContentPane().setLayout(new GridBagLayout()); 692 JPanel leftSidePanel = new JPanel(); 693 leftSidePanel.setLayout(new GridBagLayout()); 694 getContentPane().add(leftSidePanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, 695 GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); 696 { 697 JPanel fontPanel = new JPanel(); 698 leftSidePanel.add(fontPanel, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, 699 GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0)); 700 fontPanel.setLayout(new GridBagLayout()); 701 fontPanel.setBorder(BorderFactory.createTitledBorder("Font")); 702 { 703 fontSizeSpinner = new JSpinner(new SpinnerNumberModel(32, 0, 256, 1)); 704 fontPanel.add(fontSizeSpinner, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, 705 GridBagConstraints.NONE, new Insets(0, 0, 5, 10), 0, 0)); 706 ((JSpinner.DefaultEditor)fontSizeSpinner.getEditor()).getTextField().setColumns(2); 707 } 708 { 709 JScrollPane fontScroll = new JScrollPane(); 710 fontPanel.add(fontScroll, new GridBagConstraints(1, 1, 3, 1, 1.0, 1.0, GridBagConstraints.CENTER, 711 GridBagConstraints.BOTH, new Insets(0, 0, 5, 5), 0, 0)); 712 { 713 fontListModel = new DefaultComboBoxModel( 714 GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames()); 715 fontList = new JList(); 716 fontScroll.setViewportView(fontList); 717 fontList.setModel(fontListModel); 718 fontList.setVisibleRowCount(6); 719 fontList.setSelectedIndex(0); 720 fontScroll.setMinimumSize(new Dimension(220, fontList.getPreferredScrollableViewportSize().height)); 721 } 722 } 723 { 724 systemFontRadio = new JRadioButton("System:", true); 725 fontPanel.add(systemFontRadio, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST, 726 GridBagConstraints.NONE, new Insets(0, 5, 0, 5), 0, 0)); 727 systemFontRadio.setMargin(new Insets(0, 0, 0, 0)); 728 } 729 { 730 fontFileRadio = new JRadioButton("File:"); 731 fontPanel.add(fontFileRadio, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 732 GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0)); 733 fontFileRadio.setMargin(new Insets(0, 0, 0, 0)); 734 } 735 { 736 fontFileText = new JTextField(); 737 fontPanel.add(fontFileText, new GridBagConstraints(1, 2, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, 738 GridBagConstraints.HORIZONTAL, new Insets(0, 0, 5, 0), 0, 0)); 739 } 740 { 741 fontPanel.add(new JLabel("Size:"), new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 742 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 743 } 744 745 { 746 unicodePanel = new JPanel(new GridBagLayout()); 747 fontPanel.add(unicodePanel, new GridBagConstraints(2, 3, 2, 1, 0.0, 0.0, GridBagConstraints.EAST, 748 GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 5), 0, 0)); 749 { 750 boldCheckBox = new JCheckBox("Bold"); 751 unicodePanel.add(boldCheckBox, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, 752 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 753 } 754 { 755 italicCheckBox = new JCheckBox("Italic"); 756 unicodePanel.add(italicCheckBox, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, 757 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 758 } 759 } 760 { 761 bitmapPanel = new JPanel(new GridBagLayout()); 762 fontPanel.add(bitmapPanel, new GridBagConstraints(2, 3, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, 763 GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0)); 764 { 765 bitmapPanel.add(new JLabel("Gamma:"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 766 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 767 } 768 { 769 gammaSpinner = new JSpinner(new SpinnerNumberModel(1.8f, 0, 30, 0.01)); 770 ((JSpinner.DefaultEditor)gammaSpinner.getEditor()).getTextField().setColumns(2); 771 bitmapPanel.add(gammaSpinner, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 772 GridBagConstraints.NONE, new Insets(0, 0, 5, 10), 0, 0)); 773 } 774 { 775 monoCheckBox = new JCheckBox("Mono"); 776 bitmapPanel.add(monoCheckBox, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 777 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 778 } 779 } 780 { 781 browseButton = new JButton("..."); 782 fontPanel.add(browseButton, new GridBagConstraints(3, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, 783 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 784 browseButton.setMargin(new Insets(0, 0, 0, 0)); 785 } 786 { 787 fontPanel.add(new JLabel("Rendering:"), new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.NORTHEAST, 788 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 789 } 790 { 791 JPanel renderingPanel = new JPanel(new GridBagLayout()); 792 fontPanel.add(renderingPanel, new GridBagConstraints(1, 4, 3, 1, 0.0, 0.0, GridBagConstraints.NORTHWEST, 793 GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); 794 { 795 freeTypeRadio = new JRadioButton("FreeType"); 796 renderingPanel.add(freeTypeRadio, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, 797 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 798 } 799 { 800 javaRadio = new JRadioButton("Java"); 801 renderingPanel.add(javaRadio, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, 802 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 803 } 804 { 805 nativeRadio = new JRadioButton("Native"); 806 renderingPanel.add(nativeRadio, new GridBagConstraints(2, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, 807 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 808 } 809 } 810 ButtonGroup buttonGroup = new ButtonGroup(); 811 buttonGroup.add(systemFontRadio); 812 buttonGroup.add(fontFileRadio); 813 buttonGroup = new ButtonGroup(); 814 buttonGroup.add(freeTypeRadio); 815 buttonGroup.add(javaRadio); 816 buttonGroup.add(nativeRadio); 817 freeTypeRadio.setSelected(true); 818 } 819 { 820 JPanel samplePanel = new JPanel(); 821 leftSidePanel.add(samplePanel, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, 822 GridBagConstraints.BOTH, new Insets(5, 0, 5, 5), 0, 0)); 823 samplePanel.setLayout(new GridBagLayout()); 824 samplePanel.setBorder(BorderFactory.createTitledBorder("Sample Text")); 825 { 826 JScrollPane textScroll = new JScrollPane(); 827 samplePanel.add(textScroll, new GridBagConstraints(0, 0, 4, 1, 1.0, 1.0, GridBagConstraints.CENTER, 828 GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0, 0)); 829 { 830 sampleTextPane = new JTextPane(); 831 textScroll.setViewportView(sampleTextPane); 832 } 833 } 834 { 835 sampleNeheButton = new JButton(); 836 sampleNeheButton.setText("NEHE"); 837 samplePanel.add(sampleNeheButton, new GridBagConstraints(2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, 838 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 839 } 840 { 841 sampleAsciiButton = new JButton(); 842 sampleAsciiButton.setText("ASCII"); 843 samplePanel.add(sampleAsciiButton, new GridBagConstraints(3, 1, 1, 1, 0, 0.0, GridBagConstraints.EAST, 844 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 845 } 846 { 847 sampleExtendedButton = new JButton(); 848 sampleExtendedButton.setText("Extended"); 849 samplePanel.add(sampleExtendedButton, new GridBagConstraints(1, 1, 1, 1, 1.0, 0.0, GridBagConstraints.EAST, 850 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 851 } 852 } 853 { 854 JPanel renderingPanel = new JPanel(); 855 leftSidePanel.add(renderingPanel, new GridBagConstraints(0, 1, 2, 1, 1.0, 1.0, GridBagConstraints.CENTER, 856 GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0, 0)); 857 renderingPanel.setBorder(BorderFactory.createTitledBorder("Rendering")); 858 renderingPanel.setLayout(new GridBagLayout()); 859 { 860 JPanel wrapperPanel = new JPanel(); 861 renderingPanel.add(wrapperPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, 862 GridBagConstraints.BOTH, new Insets(0, 5, 5, 5), 0, 0)); 863 wrapperPanel.setLayout(new BorderLayout()); 864 wrapperPanel.setBackground(java.awt.Color.white); 865 { 866 gamePanel = new JPanel(); 867 wrapperPanel.add(gamePanel); 868 gamePanel.setLayout(new BorderLayout()); 869 gamePanel.setBackground(java.awt.Color.white); 870 } 871 } 872 { 873 glyphCachePanel = new JPanel() { 874 private int maxWidth; 875 876 public Dimension getPreferredSize () { 877 // Keep glyphCachePanel width from ever going down so the CanvasGameContainer doesn't change sizes and flicker. 878 Dimension size = super.getPreferredSize(); 879 maxWidth = Math.max(maxWidth, size.width); 880 size.width = maxWidth; 881 return size; 882 } 883 }; 884 glyphCachePanel.setVisible(false); 885 renderingPanel.add(glyphCachePanel, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.NORTH, 886 GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); 887 glyphCachePanel.setLayout(new GridBagLayout()); 888 { 889 glyphCachePanel.add(new JLabel("Glyphs:"), new GridBagConstraints(0, 4, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 890 GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0)); 891 } 892 { 893 glyphCachePanel.add(new JLabel("Pages:"), new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 894 GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0)); 895 } 896 { 897 glyphCachePanel.add(new JLabel("Page width:"), new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, 898 GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0)); 899 } 900 { 901 glyphCachePanel.add(new JLabel("Page height:"), new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, 902 GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0)); 903 } 904 { 905 glyphPageWidthCombo = new JComboBox(new DefaultComboBoxModel(new Integer[] {new Integer(32), new Integer(64), 906 new Integer(128), new Integer(256), new Integer(512), new Integer(1024), new Integer(2048)})); 907 glyphCachePanel.add(glyphPageWidthCombo, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, 908 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 909 glyphPageWidthCombo.setSelectedIndex(4); 910 } 911 { 912 glyphPageHeightCombo = new JComboBox(new DefaultComboBoxModel(new Integer[] {new Integer(32), new Integer(64), 913 new Integer(128), new Integer(256), new Integer(512), new Integer(1024), new Integer(2048)})); 914 glyphCachePanel.add(glyphPageHeightCombo, new GridBagConstraints(1, 2, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, 915 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 916 glyphPageHeightCombo.setSelectedIndex(4); 917 } 918 { 919 resetCacheButton = new JButton("Reset Cache"); 920 glyphCachePanel.add(resetCacheButton, new GridBagConstraints(0, 6, 2, 1, 1.0, 0.0, GridBagConstraints.CENTER, 921 GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0)); 922 } 923 { 924 glyphPagesTotalLabel = new JLabel("1"); 925 glyphCachePanel.add(glyphPagesTotalLabel, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, 926 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 927 } 928 { 929 glyphsTotalLabel = new JLabel("0"); 930 glyphCachePanel.add(glyphsTotalLabel, new GridBagConstraints(1, 4, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, 931 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 932 } 933 { 934 glyphPageComboModel = new DefaultComboBoxModel(); 935 glyphPageCombo = new JComboBox(); 936 glyphCachePanel.add(glyphPageCombo, new GridBagConstraints(1, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, 937 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 938 glyphPageCombo.setModel(glyphPageComboModel); 939 } 940 { 941 glyphCachePanel.add(new JLabel("View:"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 942 GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0)); 943 } 944 } 945 { 946 JPanel radioButtonsPanel = new JPanel(); 947 renderingPanel.add(radioButtonsPanel, new GridBagConstraints(0, 0, 2, 1, 0.0, 0.0, GridBagConstraints.CENTER, 948 GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); 949 radioButtonsPanel.setLayout(new GridBagLayout()); 950 { 951 sampleTextRadio = new JRadioButton("Sample text"); 952 radioButtonsPanel.add(sampleTextRadio, new GridBagConstraints(2, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, 953 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 954 sampleTextRadio.setSelected(true); 955 } 956 { 957 glyphCacheRadio = new JRadioButton("Glyph cache"); 958 radioButtonsPanel.add(glyphCacheRadio, new GridBagConstraints(3, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, 959 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 960 } 961 { 962 radioButtonsPanel.add(new JLabel("Background:"), new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, 963 GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets(0, 5, 5, 5), 0, 0)); 964 } 965 { 966 backgroundColorLabel = new JLabel(); 967 radioButtonsPanel.add(backgroundColorLabel, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, 968 GridBagConstraints.NONE, new Insets(0, 0, 5, 5), 0, 0)); 969 } 970 ButtonGroup buttonGroup = new ButtonGroup(); 971 buttonGroup.add(glyphCacheRadio); 972 buttonGroup.add(sampleTextRadio); 973 } 974 } 975 JPanel rightSidePanel = new JPanel(); 976 rightSidePanel.setLayout(new GridBagLayout()); 977 getContentPane().add(rightSidePanel, new GridBagConstraints(1, 0, 1, 2, 0.0, 0.0, GridBagConstraints.CENTER, 978 GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0)); 979 { 980 JPanel paddingPanel = new JPanel(); 981 paddingPanel.setLayout(new GridBagLayout()); 982 rightSidePanel.add(paddingPanel, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, 983 GridBagConstraints.BOTH, new Insets(0, 0, 5, 5), 0, 0)); 984 paddingPanel.setBorder(BorderFactory.createTitledBorder("Padding")); 985 { 986 padTopSpinner = new JSpinner(new SpinnerNumberModel(1, 0, 999, 1)); 987 paddingPanel.add(padTopSpinner, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, 988 GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); 989 ((JSpinner.DefaultEditor)padTopSpinner.getEditor()).getTextField().setColumns(2); 990 } 991 { 992 padRightSpinner = new JSpinner(new SpinnerNumberModel(1, 0, 999, 1)); 993 paddingPanel.add(padRightSpinner, new GridBagConstraints(2, 2, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, 994 GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0)); 995 ((JSpinner.DefaultEditor)padRightSpinner.getEditor()).getTextField().setColumns(2); 996 } 997 { 998 padLeftSpinner = new JSpinner(new SpinnerNumberModel(1, 0, 999, 1)); 999 paddingPanel.add(padLeftSpinner, new GridBagConstraints(0, 2, 1, 1, 1.0, 0.0, GridBagConstraints.EAST, 1000 GridBagConstraints.NONE, new Insets(0, 5, 0, 0), 0, 0)); 1001 ((JSpinner.DefaultEditor)padLeftSpinner.getEditor()).getTextField().setColumns(2); 1002 } 1003 { 1004 padBottomSpinner = new JSpinner(new SpinnerNumberModel(1, 0, 999, 1)); 1005 paddingPanel.add(padBottomSpinner, new GridBagConstraints(1, 3, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, 1006 GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); 1007 ((JSpinner.DefaultEditor)padBottomSpinner.getEditor()).getTextField().setColumns(2); 1008 } 1009 { 1010 JPanel advancePanel = new JPanel(); 1011 FlowLayout advancePanelLayout = new FlowLayout(); 1012 advancePanel.setLayout(advancePanelLayout); 1013 paddingPanel.add(advancePanel, new GridBagConstraints(0, 4, 3, 1, 1.0, 0.0, GridBagConstraints.CENTER, 1014 GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0)); 1015 { 1016 advancePanel.add(new JLabel("X:")); 1017 } 1018 { 1019 padAdvanceXSpinner = new JSpinner(new SpinnerNumberModel(-2, -999, 999, 1)); 1020 advancePanel.add(padAdvanceXSpinner); 1021 ((JSpinner.DefaultEditor)padAdvanceXSpinner.getEditor()).getTextField().setColumns(2); 1022 } 1023 { 1024 advancePanel.add(new JLabel("Y:")); 1025 } 1026 { 1027 padAdvanceYSpinner = new JSpinner(new SpinnerNumberModel(-2, -999, 999, 1)); 1028 advancePanel.add(padAdvanceYSpinner); 1029 ((JSpinner.DefaultEditor)padAdvanceYSpinner.getEditor()).getTextField().setColumns(2); 1030 } 1031 } 1032 } 1033 { 1034 effectsPanel = new JPanel(); 1035 effectsPanel.setLayout(new GridBagLayout()); 1036 rightSidePanel.add(effectsPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.CENTER, 1037 GridBagConstraints.BOTH, new Insets(5, 0, 5, 5), 0, 0)); 1038 effectsPanel.setBorder(BorderFactory.createTitledBorder("Effects")); 1039 effectsPanel.setMinimumSize(new Dimension(210, 1)); 1040 { 1041 effectsScroll = new JScrollPane(); 1042 effectsPanel.add(effectsScroll, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NORTH, 1043 GridBagConstraints.HORIZONTAL, new Insets(0, 5, 5, 5), 0, 0)); 1044 { 1045 effectsListModel = new DefaultComboBoxModel(); 1046 effectsList = new JList(); 1047 effectsScroll.setViewportView(effectsList); 1048 effectsList.setModel(effectsListModel); 1049 effectsList.setVisibleRowCount(7); 1050 effectsScroll.setMinimumSize(effectsList.getPreferredScrollableViewportSize()); 1051 } 1052 } 1053 { 1054 addEffectButton = new JButton("Add"); 1055 effectsPanel.add(addEffectButton, new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 1056 GridBagConstraints.NONE, new Insets(0, 5, 6, 5), 0, 0)); 1057 addEffectButton.setEnabled(false); 1058 } 1059 { 1060 appliedEffectsScroll = new JScrollPane(); 1061 effectsPanel.add(appliedEffectsScroll, new GridBagConstraints(1, 3, 1, 1, 1.0, 1.0, GridBagConstraints.NORTH, 1062 GridBagConstraints.BOTH, new Insets(0, 0, 5, 0), 0, 0)); 1063 appliedEffectsScroll.setBorder(new EmptyBorder(0, 0, 0, 0)); 1064 appliedEffectsScroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 1065 { 1066 JPanel panel = new JPanel(); 1067 panel.setLayout(new GridBagLayout()); 1068 appliedEffectsScroll.setViewportView(panel); 1069 { 1070 appliedEffectsPanel = new JPanel(); 1071 appliedEffectsPanel.setLayout(new GridBagLayout()); 1072 panel.add(appliedEffectsPanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0, GridBagConstraints.NORTH, 1073 GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0)); 1074 appliedEffectsPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, java.awt.Color.black)); 1075 } 1076 } 1077 } 1078 } 1079 } 1080 initializeMenus()1081 private void initializeMenus () { 1082 { 1083 JMenuBar menuBar = new JMenuBar(); 1084 setJMenuBar(menuBar); 1085 { 1086 JMenu fileMenu = new JMenu(); 1087 menuBar.add(fileMenu); 1088 fileMenu.setText("File"); 1089 fileMenu.setMnemonic(KeyEvent.VK_F); 1090 { 1091 openMenuItem = new JMenuItem("Open Hiero settings file..."); 1092 openMenuItem.setMnemonic(KeyEvent.VK_O); 1093 openMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_MASK)); 1094 fileMenu.add(openMenuItem); 1095 } 1096 { 1097 saveMenuItem = new JMenuItem("Save Hiero settings file..."); 1098 saveMenuItem.setMnemonic(KeyEvent.VK_S); 1099 saveMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, KeyEvent.CTRL_MASK)); 1100 fileMenu.add(saveMenuItem); 1101 } 1102 fileMenu.addSeparator(); 1103 { 1104 saveBMFontMenuItem = new JMenuItem("Save BMFont files (text)..."); 1105 saveBMFontMenuItem.setMnemonic(KeyEvent.VK_B); 1106 saveBMFontMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, KeyEvent.CTRL_MASK)); 1107 fileMenu.add(saveBMFontMenuItem); 1108 } 1109 fileMenu.addSeparator(); 1110 { 1111 exitMenuItem = new JMenuItem("Exit"); 1112 exitMenuItem.setMnemonic(KeyEvent.VK_X); 1113 fileMenu.add(exitMenuItem); 1114 } 1115 } 1116 } 1117 } 1118 getColorIcon(java.awt.Color color)1119 static Icon getColorIcon (java.awt.Color color) { 1120 BufferedImage image = new BufferedImage(32, 16, BufferedImage.TYPE_INT_RGB); 1121 java.awt.Graphics g = image.getGraphics(); 1122 g.setColor(color); 1123 g.fillRect(1, 1, 30, 14); 1124 g.setColor(java.awt.Color.black); 1125 g.drawRect(0, 0, 31, 15); 1126 return new ImageIcon(image); 1127 } 1128 1129 private class EffectPanel extends JPanel { 1130 final java.awt.Color selectedColor = new java.awt.Color(0xb1d2e9); 1131 1132 final ConfigurableEffect effect; 1133 List values; 1134 1135 JButton upButton; 1136 JButton downButton; 1137 JButton deleteButton; 1138 private JPanel valuesPanel; 1139 JLabel nameLabel; 1140 1141 GridBagConstraints constrains = new GridBagConstraints(0, -1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, 1142 GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0); 1143 EffectPanel(final ConfigurableEffect effect)1144 EffectPanel (final ConfigurableEffect effect) { 1145 this.effect = effect; 1146 effectPanels.add(this); 1147 effectsList.getListSelectionListeners()[0].valueChanged(null); 1148 1149 setLayout(new GridBagLayout()); 1150 setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, java.awt.Color.black)); 1151 appliedEffectsPanel.add(this, constrains); 1152 { 1153 JPanel titlePanel = new JPanel(); 1154 titlePanel.setLayout(new LayoutManager() { 1155 public void removeLayoutComponent (Component comp) { 1156 } 1157 1158 public Dimension preferredLayoutSize (Container parent) { 1159 return null; 1160 } 1161 1162 public Dimension minimumLayoutSize (Container parent) { 1163 return null; 1164 } 1165 1166 public void layoutContainer (Container parent) { 1167 Dimension buttonSize = upButton.getPreferredSize(); 1168 int upButtonX = getWidth() - buttonSize.width * 3 - 6 - 5; 1169 upButton.setBounds(upButtonX, 0, buttonSize.width, buttonSize.height); 1170 downButton.setBounds(getWidth() - buttonSize.width * 2 - 3 - 5, 0, buttonSize.width, buttonSize.height); 1171 deleteButton.setBounds(getWidth() - buttonSize.width - 5, 0, buttonSize.width, buttonSize.height); 1172 1173 Dimension labelSize = nameLabel.getPreferredSize(); 1174 nameLabel.setBounds(5, buttonSize.height / 2 - labelSize.height / 2, getWidth() - 5, labelSize.height); 1175 } 1176 1177 public void addLayoutComponent (String name, Component comp) { 1178 } 1179 }); 1180 { 1181 upButton = new JButton(); 1182 titlePanel.add(upButton); 1183 upButton.setText("Up"); 1184 upButton.setMargin(new Insets(0, 0, 0, 0)); 1185 Font font = upButton.getFont(); 1186 upButton.setFont(new Font(font.getName(), font.getStyle(), font.getSize() - 2)); 1187 } 1188 { 1189 downButton = new JButton(); 1190 titlePanel.add(downButton); 1191 downButton.setText("Down"); 1192 downButton.setMargin(new Insets(0, 0, 0, 0)); 1193 Font font = downButton.getFont(); 1194 downButton.setFont(new Font(font.getName(), font.getStyle(), font.getSize() - 2)); 1195 } 1196 { 1197 deleteButton = new JButton(); 1198 titlePanel.add(deleteButton); 1199 deleteButton.setText("X"); 1200 deleteButton.setMargin(new Insets(0, 0, 0, 0)); 1201 Font font = deleteButton.getFont(); 1202 deleteButton.setFont(new Font(font.getName(), font.getStyle(), font.getSize() - 2)); 1203 } 1204 { 1205 nameLabel = new JLabel(effect.toString()); 1206 titlePanel.add(nameLabel); 1207 Font font = nameLabel.getFont(); 1208 nameLabel.setFont(new Font(font.getName(), Font.BOLD, font.getSize())); 1209 } 1210 titlePanel.setPreferredSize( 1211 new Dimension(0, Math.max(nameLabel.getPreferredSize().height, deleteButton.getPreferredSize().height))); 1212 add(titlePanel, new GridBagConstraints(0, 0, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, 1213 new Insets(5, 0, 0, 5), 0, 0)); 1214 titlePanel.setOpaque(false); 1215 } 1216 { 1217 valuesPanel = new JPanel(); 1218 valuesPanel.setOpaque(false); 1219 valuesPanel.setLayout(new GridBagLayout()); 1220 add(valuesPanel, new GridBagConstraints(0, 1, 1, 1, 1.0, 0.0, GridBagConstraints.CENTER, 1221 GridBagConstraints.HORIZONTAL, new Insets(0, 10, 5, 0), 0, 0)); 1222 } 1223 1224 upButton.addActionListener(new ActionListener() { 1225 public void actionPerformed (ActionEvent evt) { 1226 int currentIndex = effectPanels.indexOf(EffectPanel.this); 1227 if (currentIndex > 0) { 1228 moveEffect(currentIndex - 1); 1229 updateFont(); 1230 updateUpDownButtons(); 1231 } 1232 } 1233 }); 1234 1235 downButton.addActionListener(new ActionListener() { 1236 public void actionPerformed (ActionEvent evt) { 1237 int currentIndex = effectPanels.indexOf(EffectPanel.this); 1238 if (currentIndex < effectPanels.size() - 1) { 1239 moveEffect(currentIndex + 1); 1240 updateFont(); 1241 updateUpDownButtons(); 1242 } 1243 } 1244 }); 1245 1246 deleteButton.addActionListener(new ActionListener() { 1247 public void actionPerformed (ActionEvent evt) { 1248 remove(); 1249 updateFont(); 1250 updateUpDownButtons(); 1251 } 1252 }); 1253 1254 updateValues(); 1255 updateFont(); 1256 updateUpDownButtons(); 1257 } 1258 remove()1259 public void remove () { 1260 effectPanels.remove(this); 1261 appliedEffectsPanel.remove(EffectPanel.this); 1262 getContentPane().validate(); 1263 effectsList.getListSelectionListeners()[0].valueChanged(null); 1264 } 1265 updateValues()1266 public void updateValues () { 1267 prefs.put("foreground", EffectUtil.toString(colorEffect.getColor())); 1268 valuesPanel.removeAll(); 1269 values = effect.getValues(); 1270 for (Iterator iter = values.iterator(); iter.hasNext();) 1271 addValue((Value)iter.next()); 1272 } 1273 updateUpDownButtons()1274 public void updateUpDownButtons () { 1275 for (int index = 0; index < effectPanels.size(); index++) { 1276 EffectPanel effectPanel = effectPanels.get(index); 1277 if (index == 0) { 1278 effectPanel.upButton.setEnabled(false); 1279 } else { 1280 effectPanel.upButton.setEnabled(true); 1281 } 1282 1283 if (index == effectPanels.size() - 1) { 1284 effectPanel.downButton.setEnabled(false); 1285 } else { 1286 effectPanel.downButton.setEnabled(true); 1287 } 1288 } 1289 } 1290 moveEffect(int newIndex)1291 public void moveEffect (int newIndex) { 1292 appliedEffectsPanel.remove(this); 1293 effectPanels.remove(this); 1294 appliedEffectsPanel.add(this, constrains, newIndex); 1295 effectPanels.add(newIndex, this); 1296 } 1297 addValue(final Value value)1298 public void addValue (final Value value) { 1299 JLabel valueNameLabel = new JLabel(value.getName() + ":"); 1300 valuesPanel.add(valueNameLabel, new GridBagConstraints(0, -1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, 1301 GridBagConstraints.NONE, new Insets(0, 0, 0, 5), 0, 0)); 1302 1303 final JLabel valueValueLabel = new JLabel(); 1304 valuesPanel.add(valueValueLabel, new GridBagConstraints(1, -1, 1, 1, 1.0, 0.0, GridBagConstraints.WEST, 1305 GridBagConstraints.BOTH, new Insets(0, 0, 0, 5), 0, 0)); 1306 valueValueLabel.setOpaque(true); 1307 if (value.getObject() instanceof java.awt.Color) 1308 valueValueLabel.setIcon(getColorIcon((java.awt.Color)value.getObject())); 1309 else 1310 valueValueLabel.setText(value.toString()); 1311 1312 valueValueLabel.addMouseListener(new MouseAdapter() { 1313 public void mouseEntered (MouseEvent evt) { 1314 valueValueLabel.setBackground(selectedColor); 1315 } 1316 1317 public void mouseExited (MouseEvent evt) { 1318 valueValueLabel.setBackground(null); 1319 } 1320 1321 public void mouseClicked (MouseEvent evt) { 1322 Object oldObject = value.getObject(); 1323 value.showDialog(); 1324 if (!value.getObject().equals(oldObject)) { 1325 effect.setValues(values); 1326 updateValues(); 1327 updateFont(); 1328 } 1329 } 1330 }); 1331 } 1332 getEffect()1333 public ConfigurableEffect getEffect () { 1334 return effect; 1335 } 1336 equals(Object obj)1337 public boolean equals (Object obj) { 1338 if (this == obj) return true; 1339 if (obj == null) return false; 1340 if (getClass() != obj.getClass()) return false; 1341 final EffectPanel other = (EffectPanel)obj; 1342 if (effect == null) { 1343 if (other.effect != null) return false; 1344 } else if (!effect.equals(other.effect)) return false; 1345 return true; 1346 } 1347 1348 } 1349 1350 static private class Splash extends JWindow { 1351 final int minMillis; 1352 final long startTime; 1353 Splash(Frame frame, String imageFile, int minMillis)1354 public Splash (Frame frame, String imageFile, int minMillis) { 1355 super(frame); 1356 this.minMillis = minMillis; 1357 getContentPane().add(new JLabel(new ImageIcon(Splash.class.getResource(imageFile))), BorderLayout.CENTER); 1358 pack(); 1359 setLocationRelativeTo(null); 1360 setVisible(true); 1361 startTime = System.currentTimeMillis(); 1362 } 1363 close()1364 public void close () { 1365 final long endTime = System.currentTimeMillis(); 1366 new Thread(new Runnable() { 1367 public void run () { 1368 if (endTime - startTime < minMillis) { 1369 addMouseListener(new MouseAdapter() { 1370 public void mousePressed (MouseEvent evt) { 1371 dispose(); 1372 } 1373 }); 1374 try { 1375 Thread.sleep(minMillis - (endTime - startTime)); 1376 } catch (InterruptedException ignored) { 1377 } 1378 } 1379 EventQueue.invokeLater(new Runnable() { 1380 public void run () { 1381 dispose(); 1382 } 1383 }); 1384 } 1385 }, "Splash").start(); 1386 } 1387 } 1388 1389 class Renderer extends ApplicationAdapter { 1390 SpriteBatch batch; 1391 int width, height; 1392 create()1393 public void create () { 1394 glClearColor(0, 0, 0, 0); 1395 glClearDepth(1); 1396 glDisable(GL_LIGHTING); 1397 1398 batch = new SpriteBatch(); 1399 1400 sampleNeheButton.doClick(); 1401 } 1402 resize(int width, int height)1403 public void resize (int width, int height) { 1404 this.width = width; 1405 this.height = height; 1406 batch.getProjectionMatrix().setToOrtho2D(0, 0, width, height); 1407 } 1408 render()1409 public void render () { 1410 int viewWidth = Gdx.graphics.getWidth(); 1411 int viewHeight = Gdx.graphics.getHeight(); 1412 1413 if (sampleTextRadio.isSelected()) { 1414 GL11.glClearColor(renderingBackgroundColor.r, renderingBackgroundColor.g, renderingBackgroundColor.b, 1415 renderingBackgroundColor.a); 1416 GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); 1417 } else { 1418 GL11.glClearColor(1, 1, 1, 1); 1419 GL11.glClear(GL11.GL_COLOR_BUFFER_BIT); 1420 } 1421 1422 String sampleText = sampleTextPane.getText(); 1423 1424 glEnable(GL_TEXTURE_2D); 1425 glEnableClientState(GL_TEXTURE_COORD_ARRAY); 1426 glEnableClientState(GL_VERTEX_ARRAY); 1427 1428 glEnable(GL_BLEND); 1429 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); 1430 1431 glViewport(0, 0, width, height); 1432 glScissor(0, 0, width, height); 1433 1434 glMatrixMode(GL_PROJECTION); 1435 glLoadIdentity(); 1436 glOrtho(0, width, height, 0, 1, -1); 1437 glMatrixMode(GL_MODELVIEW); 1438 glLoadIdentity(); 1439 1440 unicodeFont.addGlyphs(sampleText); 1441 1442 if (!unicodeFont.getEffects().isEmpty() && unicodeFont.loadGlyphs(64)) { 1443 glyphPageComboModel.removeAllElements(); 1444 int pageCount = unicodeFont.getGlyphPages().size(); 1445 int glyphCount = 0; 1446 for (int i = 0; i < pageCount; i++) { 1447 glyphPageComboModel.addElement("Page " + (i + 1)); 1448 glyphCount += ((GlyphPage)unicodeFont.getGlyphPages().get(i)).getGlyphs().size(); 1449 } 1450 glyphPagesTotalLabel.setText(String.valueOf(pageCount)); 1451 glyphsTotalLabel.setText(String.valueOf(glyphCount)); 1452 } 1453 1454 if (sampleTextRadio.isSelected()) { 1455 int offset = unicodeFont.getYOffset(sampleText); 1456 if (offset > 0) offset = 0; 1457 unicodeFont.drawString(10, 12, sampleText, Color.WHITE, 0, sampleText.length()); 1458 } else { 1459 // GL11.glColor4f(renderingBackgroundColor.r, renderingBackgroundColor.g, renderingBackgroundColor.b, 1460 // renderingBackgroundColor.a); 1461 // fillRect(0, 0, unicodeFont.getGlyphPageWidth() + 2, unicodeFont.getGlyphPageHeight() + 2); 1462 int index = glyphPageCombo.getSelectedIndex(); 1463 List pages = unicodeFont.getGlyphPages(); 1464 if (index >= 0 && index < pages.size()) { 1465 Texture texture = ((GlyphPage)pages.get(glyphPageCombo.getSelectedIndex())).getTexture(); 1466 1467 glDisable(GL_TEXTURE_2D); 1468 glColor4f(renderingBackgroundColor.r, renderingBackgroundColor.g, renderingBackgroundColor.b, 1469 renderingBackgroundColor.a); 1470 glBegin(GL_QUADS); 1471 glVertex3f(0, 0, 0); 1472 glVertex3f(0, texture.getHeight(), 0); 1473 glVertex3f(texture.getWidth(), texture.getHeight(), 0); 1474 glVertex3f(texture.getWidth(), 0, 0); 1475 glEnd(); 1476 glEnable(GL_TEXTURE_2D); 1477 1478 texture.bind(); 1479 glColor4f(1, 1, 1, 1); 1480 glBegin(GL_QUADS); 1481 glTexCoord2f(0, 0); 1482 glVertex3f(0, 0, 0); 1483 1484 glTexCoord2f(0, 1); 1485 glVertex3f(0, texture.getHeight(), 0); 1486 1487 glTexCoord2f(1, 1); 1488 glVertex3f(texture.getWidth(), texture.getHeight(), 0); 1489 1490 glTexCoord2f(1, 0); 1491 glVertex3f(texture.getWidth(), 0, 0); 1492 glEnd(); 1493 } 1494 } 1495 1496 glDisable(GL_TEXTURE_2D); 1497 glDisableClientState(GL_TEXTURE_COORD_ARRAY); 1498 glDisableClientState(GL_VERTEX_ARRAY); 1499 1500 if (saveBmFontFile != null) { 1501 try { 1502 BMFontUtil bmFont = new BMFontUtil(unicodeFont); 1503 bmFont.save(saveBmFontFile); 1504 1505 if (batchMode) { 1506 exit(0); 1507 } 1508 } catch (Throwable ex) { 1509 System.out.println("Error saving BMFont files: " + saveBmFontFile.getAbsolutePath()); 1510 ex.printStackTrace(); 1511 } finally { 1512 saveBmFontFile = null; 1513 } 1514 } 1515 } 1516 1517 } 1518 1519 static final String NEHE_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n" // 1520 + "abcdefghijklmnopqrstuvwxyz\n1234567890 \n" // 1521 + "\"!`?'.,;:()[]{}<>|/@\\^$-%+=#_&~*\u0000\u007F"; 1522 static public final String EXTENDED_CHARS; 1523 1524 static { 1525 StringBuilder buffer = new StringBuilder(); 1526 int i = 0; 1527 for (int c : new int[] {0, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 1528 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 1529 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 1530 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 1531 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 1532 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 1533 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 1534 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 266, 1535 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 1536 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, 1537 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 1538 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 1539 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 884, 885, 890, 1540 891, 892, 893, 894, 900, 901, 902, 903, 904, 905, 906, 908, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 1541 922, 923, 924, 925, 926, 927, 928, 929, 931, 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, 942, 943, 944, 945, 946, 1542 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 1543 971, 972, 973, 974, 976, 977, 978, 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, 1544 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1545 1017, 1018, 1019, 1020, 1021, 1022, 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, 1035, 1036, 1546 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055, 1056, 1547 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1076, 1548 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, 1095, 1096, 1549 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, 1115, 1116, 1550 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, 1135, 1136, 1551 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, 1153, 1154, 1155, 1156, 1552 1157, 1158, 1159, 1160, 1161, 1162, 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, 1173, 1174, 1175, 1176, 1553 1177, 1178, 1179, 1180, 1181, 1182, 1183, 1184, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1192, 1193, 1194, 1195, 1196, 1554 1197, 1198, 1199, 1200, 1201, 1202, 1203, 1204, 1205, 1206, 1207, 1208, 1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216, 1555 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226, 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236, 1556 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246, 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256, 1557 1257, 1258, 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268, 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1558 1277, 1278, 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288, 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1559 1297, 1298, 1299, 1300, 1301, 1302, 1303, 1304, 1305, 1306, 1307, 1308, 1309, 1310, 1311, 1312, 1313, 1314, 1315, 1316, 1560 1317, 1318, 1319, 8192, 8193, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8203, 8204, 8205, 8206, 8207, 8210, 1561 8211, 8212, 8213, 8214, 8215, 8216, 8217, 8218, 8219, 8220, 8221, 8222, 8223, 8224, 8225, 8226, 8230, 8234, 8235, 8236, 1562 8237, 8238, 8239, 8240, 8242, 8243, 8244, 8249, 8250, 8252, 8254, 8260, 8286, 8298, 8299, 8300, 8301, 8302, 8303, 8352, 1563 8353, 8354, 8355, 8356, 8357, 8358, 8359, 8360, 8361, 8363, 8364, 8365, 8366, 8367, 8368, 8369, 8370, 8371, 8372, 8373, 1564 8377, 8378, 11360, 11361, 11362, 11363, 11364, 11365, 11366, 11367, 11368, 11369, 11370, 11371, 11372, 11373, 11377, 1565 11378, 11379, 11380, 11381, 11382, 11383}) { 1566 i++; 1567 if (i > 26) { 1568 i = 0; 1569 buffer.append("\r\n"); 1570 } 1571 buffer.append((char)c); 1572 } 1573 EXTENDED_CHARS = buffer.toString(); 1574 } 1575 main(final String[] args)1576 public static void main (final String[] args) throws Exception { 1577 SwingUtilities.invokeLater(new Runnable() { 1578 public void run () { 1579 new Hiero(args); 1580 } 1581 }); 1582 } 1583 } 1584