diff --git a/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel2.form b/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel2.form index 9e6c8aff6..0f6cb4878 100644 --- a/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel2.form +++ b/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel2.form @@ -1,4 +1,4 @@ - +
@@ -25,22 +25,23 @@ - + - - + + + - + - - - - - + + + + + @@ -80,7 +81,7 @@ - + @@ -93,16 +94,13 @@ - - - - - - + + + + - + - @@ -233,21 +231,41 @@ - - - - - - + + + + + + + + + + + + + + + + + + + - + - - - - + + + + + + + + + + + - + @@ -268,10 +286,17 @@ - + - + + + + + + + + @@ -355,6 +380,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel2.java b/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel2.java index da57bca97..999acc144 100644 --- a/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel2.java +++ b/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/AngelFontVisualPanel2.java @@ -18,6 +18,8 @@ public final class AngelFontVisualPanel2 extends JPanel { int letterSpacing = 0; String fileName = ""; int style = Font.PLAIN; + int charRangeStart = 0; + int charRangeEnd = 256; /** Creates new form AngelFontVisualPanel2 */ public AngelFontVisualPanel2() { @@ -26,7 +28,6 @@ public final class AngelFontVisualPanel2 extends JPanel { jComboBox1.addItem("PLAIN"); jComboBox1.addItem("ITALIC"); jComboBox1.addItem("BOLD"); - } @Override @@ -46,7 +47,7 @@ public final class AngelFontVisualPanel2 extends JPanel { } private void updateFont() { - jLabel3.setIcon(new ImageIcon(FontCreator.buildFont(fontName, getFileName(), imageSize, fontSize, style, paddingX, paddingY, letterSpacing, true).getImage())); + jLabel3.setIcon(new ImageIcon(FontCreator.buildFont(fontName, getFileName(), imageSize, fontSize, style, paddingX, paddingY, letterSpacing, charRangeStart, charRangeEnd, true).getImage())); jLabel3.repaint(); jPanel1.repaint(); } @@ -81,6 +82,10 @@ public final class AngelFontVisualPanel2 extends JPanel { jLabel10 = new javax.swing.JLabel(); jLabel11 = new javax.swing.JLabel(); jSpinner5 = new javax.swing.JSpinner(); + jLabel12 = new javax.swing.JLabel(); + jSpinner6 = new javax.swing.JSpinner(); + jLabel13 = new javax.swing.JLabel(); + jSpinner7 = new javax.swing.JSpinner(); org.openide.awt.Mnemonics.setLocalizedText(jButton1, org.openide.util.NbBundle.getMessage(AngelFontVisualPanel2.class, "AngelFontVisualPanel2.jButton1.text")); // NOI18N @@ -147,14 +152,12 @@ public final class AngelFontVisualPanel2 extends JPanel { .addComponent(jLabel5) .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 52, javax.swing.GroupLayout.PREFERRED_SIZE)) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jSpinner3, javax.swing.GroupLayout.DEFAULT_SIZE, 156, Short.MAX_VALUE) - .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(jSpinner2) - .addComponent(jTextField1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 156, Short.MAX_VALUE)) - .addComponent(jSpinner4, javax.swing.GroupLayout.DEFAULT_SIZE, 156, Short.MAX_VALUE)) + .addComponent(jSpinner3) + .addComponent(jSpinner4) + .addComponent(jSpinner2) + .addComponent(jTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 188, Short.MAX_VALUE)) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jLabel8) - .addGap(45, 45, 45)) + .addComponent(jLabel8)) ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) @@ -213,23 +216,57 @@ public final class AngelFontVisualPanel2 extends JPanel { } }); + org.openide.awt.Mnemonics.setLocalizedText(jLabel12, org.openide.util.NbBundle.getMessage(AngelFontVisualPanel2.class, "AngelFontVisualPanel2.jLabel12.text")); // NOI18N + + jSpinner6.setModel(new javax.swing.SpinnerNumberModel(0, 0, 65535, 32)); + jSpinner6.setToolTipText(org.openide.util.NbBundle.getMessage(AngelFontVisualPanel2.class, "AngelFontVisualPanel2.jSpinner6.toolTipText")); // NOI18N + jSpinner6.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + jSpinner6letterSpacingUpdate(evt); + } + }); + + org.openide.awt.Mnemonics.setLocalizedText(jLabel13, org.openide.util.NbBundle.getMessage(AngelFontVisualPanel2.class, "AngelFontVisualPanel2.jLabel13.text")); // NOI18N + + jSpinner7.setModel(new javax.swing.SpinnerNumberModel(256, 0, 65535, 32)); + jSpinner7.setToolTipText(org.openide.util.NbBundle.getMessage(AngelFontVisualPanel2.class, "AngelFontVisualPanel2.jSpinner7.toolTipText")); // NOI18N + jSpinner7.addChangeListener(new javax.swing.event.ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + jSpinner7letterSpacingUpdate(evt); + } + }); + javax.swing.GroupLayout jPanel3Layout = new javax.swing.GroupLayout(jPanel3); jPanel3.setLayout(jPanel3Layout); jPanel3Layout.setHorizontalGroup( jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel3Layout.createSequentialGroup() - .addContainerGap() - .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) - .addComponent(jLabel11) - .addComponent(jLabel9) - .addComponent(jLabel1) - .addComponent(jLabel6)) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel3Layout.createSequentialGroup() + .addGap(27, 27, 27) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel9) + .addComponent(jLabel1) + .addComponent(jLabel6))) + .addGroup(javax.swing.GroupLayout.Alignment.LEADING, jPanel3Layout.createSequentialGroup() + .addContainerGap() + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addGroup(jPanel3Layout.createSequentialGroup() + .addGap(10, 10, 10) + .addComponent(jLabel12, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)) + .addComponent(jLabel11, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)))) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addComponent(jSpinner1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 78, Short.MAX_VALUE) - .addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, 78, Short.MAX_VALUE) - .addComponent(jComboBox1, javax.swing.GroupLayout.Alignment.TRAILING, 0, 78, Short.MAX_VALUE) - .addComponent(jSpinner5, javax.swing.GroupLayout.DEFAULT_SIZE, 78, Short.MAX_VALUE)) + .addComponent(jSpinner1, javax.swing.GroupLayout.Alignment.TRAILING) + .addComponent(jLabel10, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jComboBox1, javax.swing.GroupLayout.Alignment.TRAILING, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addComponent(jSpinner5) + .addGroup(jPanel3Layout.createSequentialGroup() + .addComponent(jSpinner6, javax.swing.GroupLayout.PREFERRED_SIZE, 60, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jLabel13) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addComponent(jSpinner7, javax.swing.GroupLayout.PREFERRED_SIZE, 58, Short.MAX_VALUE))) .addContainerGap()) ); jPanel3Layout.setVerticalGroup( @@ -246,10 +283,16 @@ public final class AngelFontVisualPanel2 extends JPanel { .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) .addComponent(jSpinner1, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) .addComponent(jLabel1)) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 7, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) + .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) + .addComponent(jSpinner5, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel11)) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 8, Short.MAX_VALUE) .addGroup(jPanel3Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE) - .addComponent(jLabel11) - .addComponent(jSpinner5, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)) + .addComponent(jLabel12, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jSpinner6, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jLabel13) + .addComponent(jSpinner7, javax.swing.GroupLayout.PREFERRED_SIZE, 23, javax.swing.GroupLayout.PREFERRED_SIZE)) .addContainerGap()) ); @@ -257,20 +300,21 @@ public final class AngelFontVisualPanel2 extends JPanel { this.setLayout(layout); layout.setHorizontalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() + .addGroup(layout.createSequentialGroup() .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)) - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 531, Short.MAX_VALUE) + .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) + .addContainerGap()) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) ); layout.setVerticalGroup( layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() - .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 404, Short.MAX_VALUE) - .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED) - .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false) - .addComponent(jPanel2, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) - .addComponent(jPanel3, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))) + .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, 432, Short.MAX_VALUE) + .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED) + .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) + .addComponent(jPanel2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE) + .addComponent(jPanel3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))) ); }// //GEN-END:initComponents @@ -312,12 +356,25 @@ private void jTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-F private void letterSpacingUpdate(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_letterSpacingUpdate letterSpacing = (Integer) jSpinner5.getValue(); }//GEN-LAST:event_letterSpacingUpdate + + private void jSpinner6letterSpacingUpdate(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSpinner6letterSpacingUpdate + charRangeStart = (Integer)jSpinner6.getValue(); + updateFont(); + }//GEN-LAST:event_jSpinner6letterSpacingUpdate + + private void jSpinner7letterSpacingUpdate(javax.swing.event.ChangeEvent evt) {//GEN-FIRST:event_jSpinner7letterSpacingUpdate + charRangeEnd = (Integer)jSpinner7.getValue(); + updateFont(); + }//GEN-LAST:event_jSpinner7letterSpacingUpdate + // Variables declaration - do not modify//GEN-BEGIN:variables private javax.swing.JButton jButton1; private javax.swing.JComboBox jComboBox1; private javax.swing.JLabel jLabel1; private javax.swing.JLabel jLabel10; private javax.swing.JLabel jLabel11; + private javax.swing.JLabel jLabel12; + private javax.swing.JLabel jLabel13; private javax.swing.JLabel jLabel2; private javax.swing.JLabel jLabel3; private javax.swing.JLabel jLabel4; @@ -334,6 +391,8 @@ private void letterSpacingUpdate(javax.swing.event.ChangeEvent evt) {//GEN-FIRST private javax.swing.JSpinner jSpinner3; private javax.swing.JSpinner jSpinner4; private javax.swing.JSpinner jSpinner5; + private javax.swing.JSpinner jSpinner6; + private javax.swing.JSpinner jSpinner7; private javax.swing.JTextField jTextField1; // End of variables declaration//GEN-END:variables } diff --git a/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/Bundle.properties b/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/Bundle.properties index 3e53a0607..bcf24347c 100644 --- a/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/Bundle.properties +++ b/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/Bundle.properties @@ -28,3 +28,7 @@ AngelFontVisualPanel2.jComboBox1.toolTipText=The style of the font AngelFontVisualPanel2.jTextField1.toolTipText=The name of the generated files AngelFontVisualPanel2.jSpinner2.toolTipText=The resulting png image size will be Image Size x Image Size AngelFontVisualPanel2.jSpinner5.toolTipText=Defines the vertical padding used for each letter cell +AngelFontVisualPanel2.jLabel12.text=Char Range: +AngelFontVisualPanel2.jSpinner6.toolTipText=Defines the vertical padding used for each letter cell +AngelFontVisualPanel2.jLabel13.text=to +AngelFontVisualPanel2.jSpinner7.toolTipText=Defines the vertical padding used for each letter cell diff --git a/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/FontCreator.java b/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/FontCreator.java index eb8091d9d..46b370686 100644 --- a/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/FontCreator.java +++ b/sdk/jme3-angelfont/src/com/jme3/gde/angelfont/FontCreator.java @@ -9,6 +9,8 @@ import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics2D; import java.awt.RenderingHints; +import java.awt.font.FontRenderContext; +import java.awt.font.TextLayout; import java.awt.geom.Rectangle2D; import java.awt.image.BufferedImage; @@ -43,8 +45,12 @@ public abstract class FontCreator { public static AngelFont buildFont(String fontName, int bitmapSize, int fontSize, int style, boolean debug) { return buildFont(fontName, fontName, bitmapSize, fontSize, style, 0, 0, 0, debug); } - + public static AngelFont buildFont(String fontName, String fileName, int bitmapSize, int fontSize, int style, int paddingX, int paddingY, int letterSpacing, boolean debug) { + return buildFont(fontName, fileName, bitmapSize, fontSize, style, paddingX, paddingY, letterSpacing, 0, 256, debug); + } + + public static AngelFont buildFont(String fontName, String fileName, int bitmapSize, int fontSize, int style, int paddingX, int paddingY, int letterSpacing, int firstChar, int lastChar, boolean debug) { BufferedImage fontImage; Font font; @@ -62,6 +68,7 @@ public abstract class FontCreator { } g.setColor(OPAQUE_WHITE); g.setBackground(TRANSPARENT_BLACK); + FontRenderContext frc = g.getFontRenderContext(); FontMetrics fm = g.getFontMetrics(); @@ -70,38 +77,49 @@ public abstract class FontCreator { g.drawRect(0, 0, bitmapSize - 1, bitmapSize - 1); } int xPos = 0; - int yPos = 0; - int height = 0; - for (int i = 0; i < 256; i++) { + int height = fm.getDescent() + fm.getAscent(); + int yPos = height + (paddingY * 2); + + for (int i = firstChar; i <= lastChar; i++) { char ch[] = {(char) i}; String temp = new String(ch); - Rectangle2D bounds = fm.getStringBounds(temp, g); - height = fm.getDescent() + fm.getAscent(); - if (yPos == 0) { - yPos = height + (paddingY * 2); + + if (!font.canDisplay((char)i)) { + continue; } - if (xPos + bounds.getWidth() + (paddingX * 2) > bitmapSize) { + + TextLayout tl = new TextLayout(temp, font, frc); + Rectangle2D pixelBounds = tl.getPixelBounds(frc, xPos, yPos); + + int width = (int)Math.ceil(pixelBounds.getWidth()); + + int advance = (int)Math.ceil(tl.getAdvance()); + + int xOffset = (int)Math.round(pixelBounds.getX()) - xPos; + + if (xPos + width + (paddingX * 2) > bitmapSize) { xPos = 0; yPos += height + (paddingY * 2); } - g.drawString(temp, xPos + paddingX, yPos + paddingY); + + g.drawString(temp, xPos + paddingX - xOffset, yPos + paddingY); if (debug) { g.setColor(Color.BLUE); - g.drawRect(xPos, yPos - fm.getAscent(), (int) bounds.getWidth() + (paddingX * 2), height + (paddingY * 2)); + g.drawRect(xPos, yPos - fm.getAscent(), width + (paddingX * 2), height + (paddingY * 2)); g.setColor(Color.WHITE); } charLocs = charLocs + "char id=" + i + " x=" + xPos + " y=" + (yPos - fm.getAscent()) - + " width=" + ((int) bounds.getWidth() + (paddingX * 2)) - + " height=" + ((int) bounds.getHeight() + (paddingY * 2)) - + " xoffset=0" + + " width=" + (width + (paddingX * 2)) + + " height=" + (fm.getHeight() + (paddingY * 2)) + + " xoffset=" + (xOffset) + " yoffset=0" - + " xadvance=" + (((int) bounds.getWidth() + letterSpacing) - 1) + " " + + " xadvance=" + ((advance + letterSpacing) - 1) + " " + " page=0" + " chnl=0\n"; - xPos += bounds.getWidth() + (paddingX * 2); + xPos += width + (paddingX * 2); } charLocs = "info face=null " + "size=" + fontSize + " "