[Jrisk-cvs] SF.net SVN: domination-code:[2731] Domination
Brought to you by:
yuranet
|
From: <yu...@us...> - 2026-02-14 16:36:18
|
Revision: 2731
http://sourceforge.net/p/domination/code/2731
Author: yuranet
Date: 2026-02-14 16:36:15 +0000 (Sat, 14 Feb 2026)
Log Message:
-----------
use grapheme to limit names, not perfect but better then before
Modified Paths:
--------------
Domination/src/net/yura/domination/engine/JavaCompatUtil.java
Domination/swingUI/src/net/yura/domination/ui/flashgui/NewGameFrame.java
Added Paths:
-----------
Domination/test/net/yura/domination/engine/JavaCompatUtilTest.java
Modified: Domination/src/net/yura/domination/engine/JavaCompatUtil.java
===================================================================
--- Domination/src/net/yura/domination/engine/JavaCompatUtil.java 2026-02-14 12:27:53 UTC (rev 2730)
+++ Domination/src/net/yura/domination/engine/JavaCompatUtil.java 2026-02-14 16:36:15 UTC (rev 2731)
@@ -3,6 +3,7 @@
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
+import java.text.BreakIterator;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
@@ -129,4 +130,40 @@
return sb.toString();
}
+
+ /**
+ * this is not perfect as many fonts do not obey the unicode grapheme rules, but its the best option.
+ * counting Glyphs {@link java.awt.font.GlyphVector#getNumGlyphs()} gives very large counts for emoji
+ */
+ public static int graphemeCount(String text) {
+ BreakIterator it = BreakIterator.getCharacterInstance();
+ it.setText(text);
+ int count = 0;
+ while (it.next() != BreakIterator.DONE) count++;
+ return count;
+ }
+
+ public static String subGrapheme(String text, int beginIndex, int endIndex) {
+ if (beginIndex == 0 && endIndex == 0) return "";
+
+ BreakIterator it = BreakIterator.getCharacterInstance();
+ it.setText(text);
+
+ int grapheme = 0;
+ int startOffset = beginIndex == 0 ? 0 : -1;
+
+ while (true) {
+ int position = it.next();
+ if (position == BreakIterator.DONE) {
+ throw new IllegalArgumentException("bad index for string \"" + text +"\" beginIndex=" + beginIndex + " endIndex=" + endIndex + " length=" + graphemeCount(text));
+ }
+ grapheme++;
+ if (grapheme == beginIndex) {
+ startOffset = position;
+ }
+ if (grapheme == endIndex) {
+ return text.substring(startOffset, position);
+ }
+ }
+ }
}
Modified: Domination/swingUI/src/net/yura/domination/ui/flashgui/NewGameFrame.java
===================================================================
--- Domination/swingUI/src/net/yura/domination/ui/flashgui/NewGameFrame.java 2026-02-14 12:27:53 UTC (rev 2730)
+++ Domination/swingUI/src/net/yura/domination/ui/flashgui/NewGameFrame.java 2026-02-14 16:36:15 UTC (rev 2731)
@@ -43,6 +43,7 @@
import javax.swing.text.Document;
import javax.swing.text.PlainDocument;
import net.yura.domination.audio.GameSound;
+import net.yura.domination.engine.JavaCompatUtil;
import net.yura.domination.engine.Risk;
import net.yura.domination.engine.RiskSettings;
import net.yura.domination.guishared.RiskUIUtil;
@@ -55,7 +56,6 @@
import net.yura.swing.ImageIcon;
import net.yura.domination.guishared.RiskFileFilter;
import net.yura.domination.engine.translation.TranslationBundle;
-import net.yura.domination.guishared.PicturePanel;
/**
* <p> New Game Frame for FlashGUI </p>
@@ -522,17 +522,20 @@
static class LimitedDocument extends PlainDocument {
+ static final int MAX = 15;
+
public void insertString(int offs, String str, AttributeSet a) throws javax.swing.text.BadLocationException {
if (str == null) {
return;
}
+
+ int currentLength = JavaCompatUtil.graphemeCount(getText(0, getLength()));
+ int newLength = JavaCompatUtil.graphemeCount(str);
- if ( (getLength() + str.length()) > 15 ) {
-
- str = str.substring(0, str.length() - ((getLength() + str.length())-15) );
+ if ((currentLength + newLength) > MAX) {
+ str = JavaCompatUtil.subGrapheme(str, 0, newLength - ((currentLength + newLength) - MAX));
Toolkit.getDefaultToolkit().beep();
-
}
super.insertString(offs, str, a);
Added: Domination/test/net/yura/domination/engine/JavaCompatUtilTest.java
===================================================================
--- Domination/test/net/yura/domination/engine/JavaCompatUtilTest.java (rev 0)
+++ Domination/test/net/yura/domination/engine/JavaCompatUtilTest.java 2026-02-14 16:36:15 UTC (rev 2731)
@@ -0,0 +1,89 @@
+package net.yura.domination.engine;
+
+import junit.framework.TestCase;
+
+/**
+ * WARNING!! this class only work in new version of java, in java 1.8 this test will fail
+ * @author yura
+ */
+public class JavaCompatUtilTest extends TestCase {
+
+ public void testEmptyString() {
+ String empty = "";
+ assertEquals(0, JavaCompatUtil.graphemeCount(empty));
+ assertEquals("", JavaCompatUtil.subGrapheme(empty, 0, 0));
+ }
+
+ public void testSingleLetter() {
+ String s = "A";
+ assertEquals(1, JavaCompatUtil.graphemeCount(s));
+ assertEquals("A", JavaCompatUtil.subGrapheme(s, 0, 1));
+ assertEquals("", JavaCompatUtil.subGrapheme(s, 0, 0));
+ }
+
+ public void testMultipleLetters() {
+ String s = "Hello";
+ assertEquals(5, JavaCompatUtil.graphemeCount(s));
+ assertEquals("He", JavaCompatUtil.subGrapheme(s, 0, 2));
+ assertEquals("llo", JavaCompatUtil.subGrapheme(s, 2, 5));
+ assertEquals("Hello", JavaCompatUtil.subGrapheme(s, 0, 5));
+ }
+
+ public void testSpacesAndPunctuation() {
+ String s = "Hi, there!";
+ assertEquals(10, JavaCompatUtil.graphemeCount(s));
+ assertEquals("Hi,", JavaCompatUtil.subGrapheme(s, 0, 3));
+ assertEquals(" ", JavaCompatUtil.subGrapheme(s, 3, 4));
+ assertEquals("there!", JavaCompatUtil.subGrapheme(s, 4, 10));
+ }
+
+ public void testSimpleEmoji() {
+ String s = "\uD83D\uDE0A\uD83D\uDE02"; // ??
+ assertEquals(2, JavaCompatUtil.graphemeCount(s));
+ assertEquals("\uD83D\uDE0A", JavaCompatUtil.subGrapheme(s, 0, 1)); // ?
+ assertEquals("\uD83D\uDE02", JavaCompatUtil.subGrapheme(s, 1, 2)); // ?
+ assertEquals("\uD83D\uDE0A\uD83D\uDE02", JavaCompatUtil.subGrapheme(s, 0, 2)); // ??
+ }
+
+ public void testMixedTextAndEmoji() {
+ String s = "A\uD83D\uDC4B" + "B\ud83c\uddfa\ud83c\udde6" + "\u0061\u0300\u0301\u0300\u0301\u0300\u0301\u0300\u0301"; // A?B??\xE0???????
+ assertEquals(5, JavaCompatUtil.graphemeCount(s));
+ assertEquals("A", JavaCompatUtil.subGrapheme(s, 0, 1));
+ assertEquals("\uD83D\uDC4BB", JavaCompatUtil.subGrapheme(s, 1, 3)); // ?B
+ assertEquals("\ud83c\uddfa\ud83c\udde6\u0061\u0300\u0301\u0300\u0301\u0300\u0301\u0300\u0301", JavaCompatUtil.subGrapheme(s, 3, 5)); // ??\xE0???????
+ assertEquals("A\uD83D\uDC4BB\ud83c\uddfa\ud83c\udde6\u0061\u0300\u0301\u0300\u0301\u0300\u0301\u0300\u0301", JavaCompatUtil.subGrapheme(s, 0, 5)); // A?B??\xE0???????
+ }
+
+ public void testEdgeCases() {
+ String s = "X\uD83D\uDE0AY"; // X?Y
+ assertEquals(3, JavaCompatUtil.graphemeCount(s));
+ assertEquals("", JavaCompatUtil.subGrapheme(s, 0, 0));
+ assertEquals("Y", JavaCompatUtil.subGrapheme(s, 2, 3));
+ assertEquals("X\uD83D\uDE0AY", JavaCompatUtil.subGrapheme(s, 0, 3));
+ }
+
+ public void testComplexEmoji() {
+ String s = "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66\uD83C\uDDEB\uD83C\uDDF7"; // ?????????
+ assertEquals(2, JavaCompatUtil.graphemeCount(s));
+ assertEquals("\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66", JavaCompatUtil.subGrapheme(s, 0, 1)); // ???????
+ assertEquals("\uD83C\uDDEB\uD83C\uDDF7", JavaCompatUtil.subGrapheme(s, 1, 2)); // ??
+ assertEquals("\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC66\uD83C\uDDEB\uD83C\uDDF7", JavaCompatUtil.subGrapheme(s, 0, 2)); // ?????????
+ }
+
+ public void testLongComplexEmojiSequence() {
+ String s = "\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68" +
+ "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC66" +
+ "\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67";
+ // ????????????????????
+ assertEquals(3, JavaCompatUtil.graphemeCount(s));
+ assertEquals("\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68",
+ JavaCompatUtil.subGrapheme(s, 0, 1)); // ????????
+ assertEquals("\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC66",
+ JavaCompatUtil.subGrapheme(s, 1, 2)); // ?????
+ assertEquals("\uD83D\uDC69\u200D\uD83D\uDC69\u200D\uD83D\uDC67\u200D\uD83D\uDC67",
+ JavaCompatUtil.subGrapheme(s, 2, 3)); // ???????
+ assertEquals("\uD83D\uDC69\u200D\u2764\uFE0F\u200D\uD83D\uDC8B\u200D\uD83D\uDC68" +
+ "\uD83D\uDC68\u200D\uD83D\uDC69\u200D\uD83D\uDC66",
+ JavaCompatUtil.subGrapheme(s, 0, 2)); // ?????????????
+ }
+}
|