Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added samples/utf16-japanese-v10.cgm
Binary file not shown.
Binary file added samples/utf8-chinese-v10.cgm
Binary file not shown.
10 changes: 10 additions & 0 deletions src/net/sf/jcgm/core/CGM.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ public class CGM implements Cloneable {
private boolean realPrecisionProcessed = false;
private RestrictedTextType.Type restrictedTextType = RestrictedTextType.Type.BASIC;
private DeviceViewportSpecificationMode.Mode deviceViewportSpecificationMode = DeviceViewportSpecificationMode.Mode.FractionOfDrawingSurface;
/** ISO/IEC 8632-1 §6.3.4.5: the default encoding is ISO 8859-1. */
private String currentCharSet = "ISO8859-1";

private final List<ICommandListener> commandListeners = new ArrayList<ICommandListener>();

Expand Down Expand Up @@ -731,6 +733,14 @@ public void setEndMetafileReached() {
public boolean shouldFlattenCurve() {
return this.shouldFlattenCurve;
}

public void setCurrentCharSet(String charSet) {
this.currentCharSet = charSet;
}

public String getCurrentCharSet() {
return this.currentCharSet;
}
}

/*
Expand Down
32 changes: 30 additions & 2 deletions src/net/sf/jcgm/core/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -166,11 +166,39 @@ final protected String makeString() {
c[i] = makeByte();
}

return makeString(c);
}

final protected String makeString(byte[] characters) {
// attempt to detect an encoding switch using DOCS (DECIDE OTHER CODING SYSTEM). See ISO/IEC 2022 or ECMA-35.
// this specifically tests for the most common ones, UTF-8 and UTF-16 as described by
// "ISO-IR: Internation Register of Coded Character Sets to be used with Escape Sequences"
// in chapter 2.8.2 "Coding Systems without Standard return".
// they take the form of ESC 2/5 2/15 F ("<ESC> % / F") where F specifies the coding system.
if (characters.length >= 4 && characters[0] == 0x1B && characters[1] == 0x25 && characters[2] == 0x2F)
{
if (characters[3] >= 0x47 && characters[3] <= 0x49)
{
// ESC 2/5 2/15 4/7: UTF-8 Level 1
// ESC 2/5 2/15 4/8: UTF-8 Level 2
// ESC 2/5 2/15 4/9: UTF-8 Level 3
this.cgm.setCurrentCharSet("UTF-8");
}
else
{
// ESC 2/5 2/15 4/10: UTF-16 Level 1
// ESC 2/5 2/15 4/11: UTF-16 Level 2
// ESC 2/5 2/15 4/12: UTF-16 Level 3
this.cgm.setCurrentCharSet("UTF-16BE");
}
characters = Arrays.copyOfRange(characters, 4, characters.length);
}

try {
return new String(c, "ISO8859-1");
return new String(characters, this.cgm.getCurrentCharSet());
}
catch (UnsupportedEncodingException e) {
return new String(c);
return new String(characters);
}
}

Expand Down
8 changes: 5 additions & 3 deletions src/net/sf/jcgm/core/FontList.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,12 @@ public FontList(int ec, int eid, int l, DataInput in, CGM cgm)
count = 0;
i = 0;
while (i < this.args.length) {
char a[] = new char[this.args[i]];
byte a[] = new byte[this.args[i]];
for (int j = 0; j < this.args[i]; j++)
a[j] = (char) this.args[i + j + 1];
this.fontNames[count] = new String(a);
a[j] = (byte) this.args[i + j + 1];
// NOTE: this should be a fixed string, but some metafile generators use a regular string (based on the current encoding).
// with how makeString produces its result, this should be ok to use and be more forgiving.
this.fontNames[count] = makeString(a);
count++;
i += this.args[i] + 1;
}
Expand Down
7 changes: 5 additions & 2 deletions src/net/sf/jcgm/examples/Analyzer.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
Expand Down Expand Up @@ -94,13 +95,15 @@ public class Analyzer implements ICommandListener {
this.messagesFile = new PrintWriter(new BufferedWriter(
new FileWriter(new File(this.outputPath
.getAbsolutePath()
+ File.separator + "messages.txt"))));
+ File.separator + "messages.txt"),
Charset.forName("UTF-8"))));

if (verbose) {
this.commandFile = new PrintWriter(new BufferedWriter(
new FileWriter(new File(this.outputPath
.getAbsolutePath()
+ File.separator + "commands.txt"))));
+ File.separator + "commands.txt"),
Charset.forName("UTF-8"))));
}
}

Expand Down