From 1bf7525f9a0aed10327e711cb73aee7e5c2c4bc1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=97=AB=E8=8C=82=E6=BA=90?= Date: Sat, 1 Jun 2024 18:45:01 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../io/github/jmecn/text/EmojiIterator.java | 28 +++++++++++-------- .../jmecn/text/EmojiIteratorResult.java | 22 --------------- .../jmecn/text/EmojiPresentationScanner.java | 21 +++++++------- tools/emoji_presentation_scanner_java.rl | 10 +++---- 4 files changed, 31 insertions(+), 50 deletions(-) delete mode 100644 lib/src/main/java/io/github/jmecn/text/EmojiIteratorResult.java diff --git a/lib/src/main/java/io/github/jmecn/text/EmojiIterator.java b/lib/src/main/java/io/github/jmecn/text/EmojiIterator.java index 50af78e..b90b60f 100644 --- a/lib/src/main/java/io/github/jmecn/text/EmojiIterator.java +++ b/lib/src/main/java/io/github/jmecn/text/EmojiIterator.java @@ -1,12 +1,14 @@ package io.github.jmecn.text; +import java.util.concurrent.atomic.AtomicBoolean; + import static io.github.jmecn.text.EmojiCategory.*; import static io.github.jmecn.text.EmojiPresentationScanner.*; /** * Implementation of EmojiIterator is based on Pango's pango-emoji.c * - * + * @see pango/pango-emoji.c * @author yanmaoyuan */ public class EmojiIterator { @@ -85,24 +87,26 @@ public boolean next() { this.start = this.end; - int cursor = this.cursor; + int p = this.cursor; - EmojiIteratorResult sr = scanEmojiPresentation(this.types, cursor, this.nChars); - cursor = sr.end; - boolean isEmoji = sr.isEmoji; + int scanResult = scanEmojiPresentation(this.types, p, this.nChars); + // because java do not have a referenced boolean type, here I use a bit mask to indicate whether the scanResult is emoji. + // this also avoid instancing a new object. + p = scanResult & 0x7FFFFFFF; + boolean emoji = (scanResult & 0x80000000) != 0; do { - this.cursor = cursor; - this.isEmoji = isEmoji; + this.cursor = p; + this.isEmoji = emoji; - if (cursor == this.nChars) {// end + if (p == this.nChars) {// end break; } - sr = scanEmojiPresentation(this.types, cursor, this.nChars); - cursor = sr.end; - isEmoji = sr.isEmoji; - } while (this.isEmoji == isEmoji); + scanResult = scanEmojiPresentation(this.types, p, this.nChars); + p = scanResult & 0x7FFFFFFF; + emoji = (scanResult & 0x80000000) != 0; + } while (this.isEmoji == emoji); this.end = this.cursor; diff --git a/lib/src/main/java/io/github/jmecn/text/EmojiIteratorResult.java b/lib/src/main/java/io/github/jmecn/text/EmojiIteratorResult.java deleted file mode 100644 index bd9af47..0000000 --- a/lib/src/main/java/io/github/jmecn/text/EmojiIteratorResult.java +++ /dev/null @@ -1,22 +0,0 @@ -package io.github.jmecn.text; - -/** - * desc: - * - * @author yanmaoyuan - */ -public class EmojiIteratorResult { - boolean isEmoji; - int cursor; - int end; - EmojiIteratorResult(boolean isEmoji, int cursor, int end) { - this.isEmoji = isEmoji; - this.cursor = cursor; - this.end = end; - } - - EmojiIteratorResult(boolean isEmoji, int end) { - this.isEmoji = isEmoji; - this.end = end; - } -} diff --git a/lib/src/main/java/io/github/jmecn/text/EmojiPresentationScanner.java b/lib/src/main/java/io/github/jmecn/text/EmojiPresentationScanner.java index 303b3b7..1ab93f8 100644 --- a/lib/src/main/java/io/github/jmecn/text/EmojiPresentationScanner.java +++ b/lib/src/main/java/io/github/jmecn/text/EmojiPresentationScanner.java @@ -68,8 +68,7 @@ private EmojiPresentationScanner() {} 1, 4, 0, 1, 17, 17, 17, 17, 18, 18, 17, 17 }; - @SuppressWarnings("java:S3776") - public static EmojiIteratorResult scanEmojiPresentation(byte[] data, int p, final int pe) { + public static int scanEmojiPresentation(byte[] data, int p, final int pe) { byte act = 0; int cs = EMOJI_PRESENTATION_START; int te = -1; @@ -167,39 +166,39 @@ public static EmojiIteratorResult scanEmojiPresentation(byte[] data, int p, fina break; case 5: { te = p + 1; - return new EmojiIteratorResult(false, te); + return te;// is_emoji = false } case 6: { te = p + 1; - return new EmojiIteratorResult(true, te); + return te | 0x80000000;// is_emoji = true } case 7: { te = p + 1; - return new EmojiIteratorResult(false, te); + return te;// is_emoji = false } case 8: { te = p; p--; - return new EmojiIteratorResult(true, te); + return te | 0x80000000;// is_emoji = true } case 9: { te = p; p--; - return new EmojiIteratorResult(false, te); + return te;// is_emoji = false } case 10: { p = ((te)) - 1; - return new EmojiIteratorResult(true, te); + return te | 0x80000000;// is_emoji = true } case 11: { switch (act) { case 2: { p = ((te)) - 1; - return new EmojiIteratorResult(true, te); + return te | 0x80000000;// is_emoji = true } case 3: { p = ((te)) - 1; - return new EmojiIteratorResult(false, te); + return te;// is_emoji = false } } } @@ -235,6 +234,6 @@ public static EmojiIteratorResult scanEmojiPresentation(byte[] data, int p, fina } /* Should not be reached. */ - return new EmojiIteratorResult(false, pe); + return pe; // is_emoji = false } } \ No newline at end of file diff --git a/tools/emoji_presentation_scanner_java.rl b/tools/emoji_presentation_scanner_java.rl index e97a09b..5f5165c 100644 --- a/tools/emoji_presentation_scanner_java.rl +++ b/tools/emoji_presentation_scanner_java.rl @@ -81,14 +81,14 @@ text_run = any; text_and_emoji_run := |* # In order to give the the VS15 sequences higher priority than detecting # emoji sequences they are listed first as scanner token here. -text_presentation_emoji => { return new EmojiIteratorResult(false, te);}; -emoji_run => { return new EmojiIteratorResult(true, te);}; -text_run => { return new EmojiIteratorResult(false, te);}; +text_presentation_emoji => { return te;}; +emoji_run => { return te | 0x80000000;}; +text_run => { return te;}; *|; }%% -public static EmojiIteratorResult scan_emoji_presentation(byte[] data, int p, final int pe) { +public static int scan_emoji_presentation(byte[] data, int p, final int pe) { int ts, te; final int eof = pe; @@ -101,5 +101,5 @@ public static EmojiIteratorResult scan_emoji_presentation(byte[] data, int p, fi }%% /* Should not be reached. */ - return new EmojiIteratorResult(false, pe); + return pe; } \ No newline at end of file