diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/zero33/dec1/FCDotDEC2701DashPX0.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/zero33/dec1/FCDotDEC2701DashPX0.java index 6ecc155..2bc41ff 100644 --- a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/zero33/dec1/FCDotDEC2701DashPX0.java +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/cake2/zero33/dec1/FCDotDEC2701DashPX0.java @@ -81,16 +81,16 @@ public enum FCDotDEC2701DashPX0 implements FourCornerX06BaklavaPointSequence, Fo // =========== Embed escape sequence /// _ESC6_X2 _ESC6_X1 _ESC6_X1 = 10 - __ESC_RESERVED_B1, + ESC6_NUMBER_BASE2_LEGO, /// _ESC6_X2 _ESC6_X1 _ESC6_X2 = 11 - __ESC_RESERVED_B2, + ESC6_NUMBER_BASE2_SIGNED, /// _ESC6_X2 _ESC6_X1 _ESC6_X3 = 12 - __ESC_RESERVED_B3, + ESC6_NUMBER_BASE8_LEGO, /// _ESC6_X2 _ESC6_X2 _ESC6_X1 = 13 - __ESC_RESERVED_B4, + ESC6_NUMBER_BASE8_CHOCO, /// _ESC6_X2 _ESC6_X2 _ESC6_X2 = 14 /// Select packed pie 9C terminator symbol on 6 and 8 bit systems. diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java index e40429c..2b2d8d6 100644 --- a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/FourCornerZionStenoGrapher.java @@ -34,6 +34,7 @@ import java.util.function.Function; import java.util.function.IntConsumer; import org.x4o.fc18.cake2.FourCornerDotCake; +import org.x4o.fc18.cake2.FourCornerX00PetitVide; import org.x4o.fc18.cake2.zero33.FCDotCDC1604DashP6; import org.x4o.fc18.cake2.zero33.dec1.FCDotDEC2701DashPX0; import org.x4o.fc18.octal8.PrimordialOctal; @@ -45,6 +46,7 @@ import org.x4o.fc18.zion7.flame4.FCFlameFremanSignedBase2; import org.x4o.fc18.zion7.flame4.FCFlameFremanSuit; import org.x4o.fc18.zion7.flame4.FCFlameNumberTaste; import org.x4o.fc18.zion7.flame4.FCFlameSalahSequence; +import org.x4o.fc18.zion7.flame4.FCFlameStenoTongue; import org.x4o.fc18.zion7.flame4.FCFlameNumberGram; /// Write steno for zion. @@ -54,15 +56,15 @@ import org.x4o.fc18.zion7.flame4.FCFlameNumberGram; public class FourCornerZionStenoGrapher { static public FourCornerZion7Bereshit writerX06(List out) { - return new FourCornerWriter(v -> out.add(v), () -> {}, true); + return new FourCornerWriter(v -> out.add(v), () -> {}, FCFlameStenoTongue.FC6_PLUS); } static public FourCornerZion7Candlelier writerX18(List out) { - return new FourCornerWriter(v -> out.add(v), () -> {}, false); + return new FourCornerWriter(v -> out.add(v), () -> {}, FCFlameStenoTongue.FC18); } static public FourCornerZion7TempleScrolls writerXDBX18(List out) { - return new FourCornerWriter(v -> out.add(v), () -> {}, false); + return new FourCornerWriter(v -> out.add(v), () -> {}, FCFlameStenoTongue.FC18); } /* static public FourCornerZion7Bereshit writerFC6(List out) { @@ -123,12 +125,12 @@ public class FourCornerZionStenoGrapher { private final IntConsumer out; private final Runnable outFlush; - private final boolean isSixBit; + private final FCFlameStenoTongue outTongue; - public FourCornerWriter(IntConsumer out, Runnable outFlush, boolean isSixBit) { + public FourCornerWriter(IntConsumer out, Runnable outFlush, FCFlameStenoTongue outTongue) { this.out = Objects.requireNonNull(out); this.outFlush = Objects.requireNonNull(outFlush); - this.isSixBit = isSixBit; + this.outTongue = Objects.requireNonNull(outTongue); } private void outFlush() { @@ -146,7 +148,7 @@ public class FourCornerZionStenoGrapher { } } - private void outAddBankCake(int bankBits, BigInteger bankMask, int cakeSel0, int cakeBank, int bankStart, BigInteger value, Function overrideMsb) { + private void outAddBankCake(int bankBits, BigInteger bankMask, int cakeSel0, int cakeBank, int bankStart, BigInteger value, IntConsumer pipe, Function overrideMsb) { boolean strobePage = true; for (int i = bankStart; i >= 0; i--) { int bankValue = value.shiftRight(i * bankBits).and(bankMask).intValue(); @@ -159,25 +161,40 @@ public class FourCornerZionStenoGrapher { } if (strobePage) { strobePage = false; - outAdd(cakeSel0 + i); + pipe.accept(cakeSel0 + i); } - outAdd(cakeBank + bankValue); + pipe.accept(cakeBank + bankValue); + } + } + + private void outAddFremanCake8(FCFlameFremanSuit suit, int bankStart, BigInteger value, Function overrideMsb) { + if (outTongue.isSixBit()) { + outAdd(FCDotDEC2701DashPX0.ESC6_NUMBER_BASE2_LEGO.cakePointDotIndex()); /// todo: move as arg... + outAdd(FCDotCDC1604DashP6.NX01_A.cakePointDotIndex() + suit.ordinal()); + // TODO: add octal split for 9 bit and write to out + outAddBankCake(NCR_BANK8_BITS, BIG_BITS_8, suit.cakeOffsetSel0(), suit.cakeOffsetBank(), bankStart, value, v -> { + if (v < suit.cakeOffsetBank()) { + int sel0 = v - suit.cakeOffsetSel0(); + } else { + int bank = v - suit.cakeOffsetBank(); + } + }, overrideMsb); + outAdd(FCDotCDC1604DashP6.NS04_RAKA1_INTERROBANG.cakePointDotIndex()); + } else { + outAddBankCake(NCR_BANK8_BITS, BIG_BITS_8, suit.cakeOffsetSel0(), suit.cakeOffsetBank(), bankStart, value, out, overrideMsb); } outFlush(); } - private void outAddFremanCake8(FCFlameFremanSuit suit, int bankStart, BigInteger value, Function overrideMsb) { - //TODO if (isSixBit) { - outAddBankCake(NCR_BANK8_BITS, BIG_BITS_8, suit.cakeOffsetSel0(), suit.cakeOffsetBank(), bankStart, value, overrideMsb); - } - private void outAddFremanCake9(FCFlameFremanSuit suit, int bankStart, BigInteger value, Function overrideMsb) { //TODO if (isSixBit) { - outAddBankCake(NCR_BANK9_BITS, BIG_BITS_9, suit.cakeOffsetSel0(), suit.cakeOffsetBank(), bankStart, value, overrideMsb); + outAddBankCake(NCR_BANK9_BITS, BIG_BITS_9, suit.cakeOffsetSel0(), suit.cakeOffsetBank(), bankStart, value, out, overrideMsb); + outFlush(); } private void outAddBankCake12(int cakeSel0, int cakeBank, int bankStart, BigInteger value, Function overrideMsb) { - outAddBankCake(NCR_BANK12_BITS, BIG_BITS_12, cakeSel0, cakeBank, bankStart, value, overrideMsb); + outAddBankCake(NCR_BANK12_BITS, BIG_BITS_12, cakeSel0, cakeBank, bankStart, value, out, overrideMsb); + outFlush(); } private BigInteger requireBigPositive(BigInteger value) { @@ -201,6 +218,12 @@ public class FourCornerZionStenoGrapher { return value; } + private void requireTongueFC18() { + if (outTongue.isSixBit()) { + throw new IllegalArgumentException("Value can't be written in six bit mode."); + } + } + // --------------------------------------- BEGIN FC6 @Override @@ -214,11 +237,19 @@ public class FourCornerZionStenoGrapher { @Override public void strobeTheWord(int cakePoint) { - if (isSixBit && cakePoint > CAKE_POINT_MAX_FC6) { - throw new IllegalArgumentException("Cake point is larger than baklave point limit: 0x" + Integer.toHexString(cakePoint)); + if (cakePoint < outTongue.cakePointMin()) { + throw new IllegalArgumentException("Cake point is smaller than limit: 0x" + Integer.toHexString(cakePoint)); } - if (cakePoint > CAKE_POINT_MAX_FC18) { - throw new IllegalArgumentException("Cake point is larger than max value limit: 0x" + Integer.toHexString(cakePoint)); + if (cakePoint > outTongue.cakePointMax()) { + throw new IllegalArgumentException("Cake point is greater than limit: 0x" + Integer.toHexString(cakePoint)); + } + if (FCFlameStenoTongue.FC6_PLUS.equals(outTongue) && cakePoint > CAKE_POINT_MAX_FC6) { + // fixme improve this + FourCornerDotCake slice = FourCornerDotCake.valueFromCakePoint(cakePoint).get(); + FourCornerX00PetitVide pieVide = slice.getVidePoints()[cakePoint - slice.getStart()]; + List escSeq = pieVide.kaasX06BaklavaSequence().get().baklavaPointSequence(); + escSeq.forEach(v -> out.accept(v)); + return; } outAdd(cakePoint); } @@ -282,7 +313,7 @@ public class FourCornerZionStenoGrapher { } Iterator walkItr = sandWalk.iterator(); Iterator spiceItr = sandSpice.iterator(); - if (isSixBit) { + if (outTongue.isSixBit()) { outAdd(FCDotDEC2701DashPX0.ESC6_SAND_WORM.cakePointDotIndex()); while (walkItr.hasNext()) { outAdd(FCDotCDC1604DashP6.NX01_A.cakePointDotIndex() + walkItr.next().ordinal()); @@ -333,13 +364,13 @@ public class FourCornerZionStenoGrapher { } } if (FCFlameSalahSequence.ESC_VT06.equals(type)) { - if (isSixBit) { + if (outTongue.isSixBit()) { outAddAll(FCDotDEC2701DashPX0.ESC_VT06.baklavaPointSequence()); } else { outAddAll(FCDotDEC2701DashPX0.ESC_VT06.cakePointSequence()); } } else { - if (isSixBit) { + if (outTongue.isSixBit()) { outAddAll(FCDotDEC2701DashPX0.valueOf(type.ordinal()).baklavaPointSequence()); } else { outAddAll(FCDotDEC2701DashPX0.valueOf(type.ordinal()).cakePointSequence()); @@ -360,6 +391,7 @@ public class FourCornerZionStenoGrapher { @Override public void strobeNumberGrams(FCFlameNumberGram gram, List values) { + requireTongueFC18(); Objects.requireNonNull(gram); Objects.requireNonNull(values); int gramCount = values.size(); @@ -381,6 +413,7 @@ public class FourCornerZionStenoGrapher { FCFlameNumberTaste tasteMale, FCFlameNumberTaste tasteFemale, BigInteger numerator, BigInteger denominator ) { + requireTongueFC18(); Objects.requireNonNull(tasteMale); Objects.requireNonNull(tasteFemale); Objects.requireNonNull(numerator); @@ -398,10 +431,12 @@ public class FourCornerZionStenoGrapher { @Override public void strobeNumberChocoPigDecimal(FCFlameNumberTaste taste, boolean bias, BigInteger power, BigInteger coefficient) { + requireTongueFC18(); + Objects.requireNonNull(taste); Objects.requireNonNull(power); - Objects.requireNonNull(coefficient); requireBigPositive(power); requireBigMax(power, BIG_BITS_283); + Objects.requireNonNull(coefficient); requireBigPositive(coefficient); requireBigMax(coefficient, BIG_BITS_2016); BigInteger pig = power.shiftLeft(2016).add(coefficient); @@ -412,10 +447,12 @@ public class FourCornerZionStenoGrapher { @Override public void strobeNumberChocoPigFloat(FCFlameNumberTaste taste, boolean bias, BigInteger exponent, BigInteger mantissa) { + requireTongueFC18(); + Objects.requireNonNull(taste); Objects.requireNonNull(exponent); - Objects.requireNonNull(mantissa); requireBigPositive(exponent); requireBigMax(exponent, BIG_BITS_283); + Objects.requireNonNull(mantissa); requireBigPositive(mantissa); requireBigMax(mantissa, BIG_BITS_2016); BigInteger pig = exponent.shiftLeft(2016).add(mantissa); @@ -426,10 +463,11 @@ public class FourCornerZionStenoGrapher { @Override public void strobeNumberChocoPigChoped(FCFlameNumberTaste taste, BigInteger quake, BigInteger fraction) { + requireTongueFC18(); Objects.requireNonNull(quake); - Objects.requireNonNull(fraction); requireBigPositive(quake); requireBigMax(quake, BIG_BITS_1148); + Objects.requireNonNull(fraction); requireBigPositive(fraction); requireBigMax(fraction, BIG_BITS_1152); BigInteger pig = quake.shiftLeft(1152).add(fraction); diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/flame4/FCFlameFremanSuit.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/flame4/FCFlameFremanSuit.java index af12525..14c39fd 100644 --- a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/flame4/FCFlameFremanSuit.java +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/flame4/FCFlameFremanSuit.java @@ -30,6 +30,9 @@ import java.math.BigInteger; /// @version 1.0 Sep 4, 2025 public interface FCFlameFremanSuit { + // copy from enum (temp) + int ordinal(); + // copy from enum String name(); diff --git a/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/flame4/FCFlameStenoTongue.java b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/flame4/FCFlameStenoTongue.java new file mode 100644 index 0000000..9e7b303 --- /dev/null +++ b/nx01-x4o-fc18/src/main/java/org/x4o/fc18/zion7/flame4/FCFlameStenoTongue.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2004-2014, Willem Cazander + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided + * that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, this list of conditions and the + * following disclaimer. + * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and + * the following disclaimer in the documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT + * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package org.x4o.fc18.zion7.flame4; + +/// The steno tongue speak language supported limits. +/// +/// @author Willem Cazander +/// @version 1.0 Sep 6, 2025 +public enum FCFlameStenoTongue { + + FC6 (0x000000, 0x00003F), + FC6_PLUS (0x000000, 0x0003F3), // 63 > auto esc to fc6 + FC18 (0x000000, 0x03FFFF), + FC18_ADULT (0x0003F4, 0x03FFFF), // no candy for adults +// XDBX18 (0x000000, 0x03FFFF), +// XDBX18_ADULT (0x0003F4, 0x03FFFF), // no candy for adults + ; + + private final int cakePointMin; + private final int cakePointMax; + + private FCFlameStenoTongue(int cakePointMin, int cakePointMax) { + this.cakePointMin = cakePointMin; + this.cakePointMax = cakePointMax; + } + + public int cakePointMin() { + return cakePointMin; + } + + public int cakePointMax() { + return cakePointMax; + } + + public boolean isSixBit() { + return this == FC6 || this == FC6_PLUS; + } + + public boolean limitAdult() { + return this == FC18_ADULT; // || this == XDBX18_ADULT; + } + +// public boolean isXDBX18() { +// return this == XDBX18 || this == XDBX18_ADULT; +// } +} diff --git a/nx01-x4o-fc18/src/test/java/org/x4o/fc18/zion7/StenoGrapherTest.java b/nx01-x4o-fc18/src/test/java/org/x4o/fc18/zion7/StenoGrapherTest.java index f83514c..43f06b9 100644 --- a/nx01-x4o-fc18/src/test/java/org/x4o/fc18/zion7/StenoGrapherTest.java +++ b/nx01-x4o-fc18/src/test/java/org/x4o/fc18/zion7/StenoGrapherTest.java @@ -29,6 +29,7 @@ import java.io.InputStream; import java.io.OutputStream; import java.math.BigInteger; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; import org.junit.jupiter.api.Assertions; @@ -47,6 +48,32 @@ import org.x4o.fc18.zion7.flame4.FCFlameNumberTaste; */ public class StenoGrapherTest { + @Test + public void testStenoTongueLimits() throws Exception { + Assertions.assertThrows(IllegalArgumentException.class, () -> { + FourCornerZionStenoGrapher.writerX06(new ArrayList<>()).strobeTheWord(0x040000); + }); + Assertions.assertThrows(IllegalArgumentException.class, () -> { + FourCornerZionStenoGrapher.writerX18(new ArrayList<>()).strobeTheWord(0x040000); + }); + } + + @Test + public void testStenoAutoFC6Plus() throws Exception { + List out = new ArrayList<>(); + FourCornerZion7Bereshit writerFC06 = FourCornerZionStenoGrapher.writerX06(out); + writerFC06.strobeTheWord(0x00012D); + Assertions.assertEquals(5, out.size()); + Iterator outTest = out.iterator(); + Assertions.assertEquals(2, outTest.next()); + Assertions.assertEquals(2, outTest.next()); + Assertions.assertEquals(2, outTest.next()); + Assertions.assertEquals(27, outTest.next()); + Assertions.assertEquals(37, outTest.next()); + String res = FourCornerUnicodeDisplay.text().renderFromInt18(out); + Assertions.assertEquals("0", res); + } + @Test public void testSandWorm() throws Exception { List out = new ArrayList<>();