Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » scout » Font issues: WingDings
Font issues: WingDings [message #929591] Mon, 01 October 2012 11:36 Go to next message
Alex Schroeder is currently offline Alex Schroeder
Messages: 38
Registered: February 2010
Location: Zürich, Switzerland
Member

I'm migrating an application that is ten years old. There is one form in this application that lets you display a value using a font given in font chosen by the user. Here is an example of how it used to work using WingDings: choose WingDings as the font and "a" as the value and you'd see the cancer sign.

www.fileformat.info/info/unicode/char/264b/index.htm
("You can only use links to eclipse.org sites while you have fewer than 25 messages." -- Sorry about that.)

In fact this still works in Microsoft Word, for example. Choose WingDings and type "a" to get the cancer sign. The client would like the Scout Text Field to work the same way.

Unfortunately, this does not work using Scout. In fact, I've appended a Swing application that shows how it doesn't work in Swing, either. Unless you know the secret code... "\uF061" displays as the cancer sign. Why? I don't know.

Anyway, in the code below, WINGDINGS.canDisplay('a') returns false. What I need to discover is how to translate all the old characters like "a" into whatever code points displays the right thing such as "\uF061" for all the old fonts the client still wants to use... Any ideas?

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Font;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class TestForm {

  private static final Font ARIAL = new Font("Arial", Font.PLAIN, 1);
  private static final Font WINGDINGS = new Font("Wingdings", Font.PLAIN, 1);

  private static final Runnable GUI_BUILDER = new Runnable() {
    @Override
    public void run() {

      JLabel a = new JLabel("a");
      a.setFont(ARIAL.deriveFont(32f));

      // www4.carthage.edu/faculty/ewheeler/GrafiX/LessonsAdvanced/wingdings.pdf
      JLabel b = new JLabel("a");
      b.setFont(WINGDINGS.deriveFont(32f));

      // www.fileformat.info/info/unicode/char/264b/index.htm
      JLabel c = new JLabel("\u264B");
      c.setFont(ARIAL.deriveFont(32f));

      // stackoverflow.com/questions/8692095/drawing-exotic-fonts-in-a-java-applet
      JLabel d = new JLabel("\uF061");
      d.setFont(WINGDINGS.deriveFont(32f));

      JFrame f = new JFrame();
      f.getContentPane().add(a, BorderLayout.NORTH);
      f.getContentPane().add(b, BorderLayout.CENTER);
      f.getContentPane().add(c, BorderLayout.SOUTH);
      f.getContentPane().add(d, BorderLayout.EAST);
      f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      f.pack();
      f.setVisible(true);
    }
  };

  public static void main(String[] args) {
    EventQueue.invokeLater(GUI_BUILDER);
  }
}

[Updated on: Mon, 01 October 2012 12:01]

Report message to a moderator

Re: Font issues: WingDings [message #929614 is a reply to message #929591] Mon, 01 October 2012 12:01 Go to previous messageGo to next message
Alex Schroeder is currently offline Alex Schroeder
Messages: 38
Registered: February 2010
Location: Zürich, Switzerland
Member

Currently all I can think of is to run the following code:

@Override
protected String execFormatValue(String str) {

  // Gewisse Schriften können die alten Texte nicht anzeigen.
  // Beispielsweise sollte "A" für WingDings ein Victory Zeichen zeigen.
  // Dies funktioniert neuerdings nur, wenn man in der Private Use Area nachschaut.
  // http://www4.carthage.edu/faculty/ewheeler/GrafiX/LessonsAdvanced/wingdings.pdf
  // http://www.fileformat.info/info/unicode/char/270c/index.htm
  // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6176474
  if (str != null && getSchriftField().getValue() != null) {
    Font font = new Font(getSchriftField().getValue(), Font.PLAIN, 1);
    boolean changed = false;
    char[] chars = getValue().toCharArray();
    for (int i = 0; i < chars.length; i++) {
      if (!font.canDisplay(chars[i])) {
	if (chars[i] < 0xF000) {
	  chars[i] += 0xF000;
	  changed = true;
	}
      }
    }
    if (changed) str = new String(chars);
  }
  return str;
}

[Updated on: Mon, 01 October 2012 12:45]

Report message to a moderator

Re: Font issues: WingDings [message #938053 is a reply to message #929614] Tue, 09 October 2012 10:02 Go to previous messageGo to next message
Ken Lee is currently offline Ken Lee
Messages: 97
Registered: March 2012
Member
Hi Alex,

The problem lies in the different encoding. Since WingDings is very specific, it maps the characters to the Private Use Area (PUA) rather than to the Dingbats region. WingDings is not a Unicode font and therefore does not support Dingbats region.

The only solution I can think of is to check if the font supports Unicode correctly or if they are symbol legacy fonts.

Your suggested solution is fine for the WingDings font but it does not work for symbol fonts in general.

I guess that every symbol font needs it's own mapping, i.e. depending on the chosen font, you have to map them to the Dingbats region and not to the PUA area as in your solution with 0xF000.

But please keep in mind that changing a font should only change how the character is displayed and not the value of the character itself!
In your solution you are going to change the character value.
Therefore, I would use a hidden field that stores the "real" value of the field and use your solution in the field that is displayed to the user.

[Updated on: Tue, 09 October 2012 10:02]

Report message to a moderator

Re: Font issues: WingDings [message #938059 is a reply to message #938053] Tue, 09 October 2012 10:08 Go to previous messageGo to next message
Alex Schroeder is currently offline Alex Schroeder
Messages: 38
Registered: February 2010
Location: Zürich, Switzerland
Member

Unfortunately you are right. Yesterday I also discovered that the database encoding makes a difference (probably because Oracle doesn't treat VARCHAR2 as raw bytes?) -- when I switched Oracle from WE8MSWIN1252 to WE8ISO8859P1 the solution no longer worked -- instead of the Private Use Area, something else was required. Currently I'm using the following heuristic (and I'm still testing it with the five fonts the client supplied).

I'm using the fromDatabase decoding execFormatValue for the fields in question:

        @Override
        protected String execFormatValue(String str) {
          return fromDatabase(str, getSchriftField().getValue());
        }


And I use the toDatabase encoding when calling exportFormData:

  public void exportFormData(EigentumsbezeichnungInformationFormData formData) throws ProcessingException {
    super.exportFormData(formData);
    formData.getWert().setValue(toDatabase(formData.getWert().getValue(), formData.getSchrift().getValue()));
  }


It works, for now... Until I discover a new "block" of characters. And I'm told by the client that Win7 might show yet another behaviour.

  static String fromDatabase(String str, String fontFamily) {

    if (str != null && fontFamily != null) {
      Font font = new Font(fontFamily, Font.PLAIN, 1);
      boolean changed = false;
      char[] chars = str.toCharArray();
      for (int i = 0; i < chars.length; i++) {
        if (chars[i] >= 128 && font.canDisplay(chars[i] + 8000)) {
          // ist auf der Datenbank WE8ISO8859P1 im Einsatz, funktioniert dies mit WinXP
          chars[i] += 8000;
          changed = true;
        }
        else if (font.canDisplay(chars[i] + 0xF000)) {
          // ist auf der Datenbank WE8MSWIN1252 im Einsatz, funktioniert dies mit WinXP
          chars[i] += 0xF000;
          changed = true;
        }
        else if (font.canDisplay(chars[i] + 256)) {
          // ž in LAB1 Eastern = 382
          chars[i] += 256;
          changed = true;
        }
      }
      if (changed) str = new String(chars);
    }
    return str;
  }

  static String toDatabase(String str, String schrift) {

    // Werte, die wegen einer entsprechenden Schrift in die Unicode Private Use Area verschoben wurden, werden wieder zurück verschoben
    // weil die Oracle Datenbank kein UTF-8 verwendet.

    if (str != null && schrift != null) {
      boolean changed = false;
      char[] chars = str.toCharArray();
      for (int i = 0; i < chars.length; i++) {
        if (chars[i] > 0xF000) {
          // ist auf der Datenbank WE8MSWIN1252 im Einsatz, funktioniert dies mit WinXP
          chars[i] -= 0xF000;
          changed = true;
        }
        else if (chars[i] > 8000) {
          // ist auf der Datenbank WE8ISO8859P1 im Einsatz, funktioniert dies mit WinXP
          chars[i] = (char) (chars[i] - 8000);
          changed = true;
        }
        else if (chars[i] > 256) {
          // ž in LAB1 Eastern = 382
          chars[i] = (char) (chars[i] - 256);
          changed = true;
        }
      }
      if (changed) return new String(chars);
    }

    return str;
  }
Re: Font issues: WingDings [message #938101 is a reply to message #938059] Tue, 09 October 2012 10:46 Go to previous messageGo to next message
Ken Lee is currently offline Ken Lee
Messages: 97
Registered: March 2012
Member
You may also have a look at these solutions described in [1], especially at the ones posted on 2006-08-09 and 2006-08-12. I haven't tested them but they might work for your case too.

[1] www.experts-exchange.com/Programming/Languages/Java/Q_21946608.html
Re: Font issues: WingDings [message #938102 is a reply to message #938101] Tue, 09 October 2012 10:48 Go to previous messageGo to next message
Alex Schroeder is currently offline Alex Schroeder
Messages: 38
Registered: February 2010
Location: Zürich, Switzerland
Member

Do you have access to the solution?

This aggravates me to no end:
"This question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.
Subscribe now for full access to Experts Exchange and get Instant Access to this Solution"
Re: Font issues: WingDings [message #938108 is a reply to message #938102] Tue, 09 October 2012 10:53 Go to previous messageGo to next message
Ken Lee is currently offline Ken Lee
Messages: 97
Registered: March 2012
Member
Interesting that it doesn't show the solution if you paste the link directly into your browser Rolling Eyes
Use Google and enter the search terms "wingdings java swing". It should be the 7th link currently.
Re: Font issues: WingDings [message #945653 is a reply to message #938108] Mon, 15 October 2012 09:58 Go to previous message
Alex Schroeder is currently offline Alex Schroeder
Messages: 38
Registered: February 2010
Location: Zürich, Switzerland
Member

Just to provide closure, here's what seems to work:

  static String fromDatabase(String str, String fontFamily) {
    if (str != null && fontFamily != null) {
      try {
        byte[] bytes = str.getBytes("ISO-8859-1"); // database encoding
        if (fontFamily.startsWith("LAB")) {
          str = new String(bytes, "Windows-1252");
        }
      }
      catch (UnsupportedEncodingException e) {
        e.printStackTrace();
      }
    }
    return str;
  }

  static String toDatabase(String str, String fontFamily) {
    if (str != null && fontFamily != null) {
      try {
        if (fontFamily.startsWith("LAB")) {
          str = new String(str.getBytes("Windows-1252"), "ISO-8859-1");
        }
      }
      catch (UnsupportedEncodingException e) {
        e.printStackTrace();
      }
    }
    return str;
  }

  public void exportFormData(EigentumsbezeichnungInformationFormData formData) throws ProcessingException {
    super.exportFormData(formData);
    formData.getWert().setValue(toDatabase(formData.getWert().getValue(), formData.getSchrift().getValue()));
  }

  public void importFormData(EigentumsbezeichnungInformationFormData formData) throws ProcessingException {
    super.importFormData(formData);
    getWertField().setValue(fromDatabase(formData.getWert().getValue(), formData.getSchrift().getValue()));
  }


Here's my explanation: The database uses ISO 8859-1 (aka. Latin 1). Ten years ago, the client commissioned a bunch of special fonts that deliberately say that they are Latin-1 encoded, but in fact they show different characters. Notice how the Omega in this example takes the place of Ù!

http://i.imgur.com/CRsON.png

Furthermore, some of the characters not used by Latin-1 are also used. The easiest solution seems to assume that the correponding Windows code page is being used. This allows Java to transcode the bytes from the database "fake Windows-1252" into Unicode and back. After translation, the Swing application will display a Ù using the font which shows the Omega glyph. Problem "solved."
Previous Topic:How to split a Scout project to several sub-projects.
Next Topic:new Tutorial: JasperReports Integration
Goto Forum:
  


Current Time: Thu Aug 28 23:31:58 EDT 2014

Powered by FUDForum. Page generated in 0.04906 seconds