don't depend on sharedrawweb

use directly sharedrawweb java code here

Signed-off-by: philippe lhardy <philippe.lhardy@astrolabe.coop>
This commit is contained in:
2025-11-02 18:03:10 +01:00
parent e78da6ec76
commit 36e58808d5
16 changed files with 1383 additions and 13 deletions

View File

@@ -0,0 +1,28 @@
/*
This file is part of ShareDrawWeb.
ShareDrawWeb is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
ShareDrawWeb is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ShareDrawWeb; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.artisanlogiciel.graphics;
import java.io.Serializable;
public class DrawException extends Exception implements Serializable {
public DrawException() {
super();
}
}

View File

@@ -0,0 +1,106 @@
/**
Drawing
contains a set of DrawingLine to create a Drawing
- feature of load / save
*/
package org.artisanlogiciel.graphics;
import java.awt.Graphics;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.util.ArrayList;
import org.artisanlogiciel.graphics.Importer;
import org.artisanlogiciel.graphics.ResetException;
import org.artisanlogiciel.graphics.NoMoreLineException;
public class Drawing
{
private ArrayList<DrawingLine> lines;
public Drawing()
{
reset();
}
public void reset() {
lines = new ArrayList<DrawingLine>(10);
}
public void addLine( DrawingLine line) {
lines.add( line);
}
public void saveLines( DataOutputStream destination) throws
java.io.IOException {
destination.writeInt( lines.size());
for ( DrawingLine line : lines )
{
line.save( destination);
}
}
public void loadLines( DataInputStream source) throws
java.io.IOException {
int nb_lines = source.readInt();
DrawingLine line;
for ( int i = 0; i < nb_lines; i++ ) {
line = new DrawingLine();
line.load( source);
lines.add( line);
}
}
public void importImage( Importer importer) throws
java.io.IOException
{
importer.importInto(this);
}
public void saveLinesKompressed( DataOutputStream destination) throws
java.io.IOException {
destination.writeInt( lines.size());
for ( DrawingLine line : lines )
{
line.saveKompressed( destination);
}
}
public void loadLinesExpanded( DataInputStream source) throws
java.io.IOException {
// DrawLineExpander expander = new DrawLineExpander();
int nb_lines = source.readInt();
DrawingLine line;
for ( int i = 0; i < nb_lines; i++ ) {
line = new DrawingLine();
line.loadExpanded( source);
lines.add( line);
}
}
public int length() {
return lines.size();
}
public DrawingLine getLine( int line) throws ResetException, NoMoreLineException {
if ( line == lines.size() ) {
throw new NoMoreLineException();
}
if ( line > lines.size() ) {
throw new ResetException();
}
return lines.get( line);
}
public ArrayList<DrawingLine> getLines() {
return new ArrayList<DrawingLine>(lines);
}
/** Not a copy, use with care */
public ArrayList<DrawingLine> getInternLines() {
return lines;
}
}

View File

@@ -0,0 +1,96 @@
/**
DrawingLine
keep track of list of Points constituting a line
*/
package org.artisanlogiciel.graphics;
import java.awt.Point;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import org.artisanlogiciel.compression.graphics.DrawLineExpander;
import org.artisanlogiciel.compression.graphics.DrawLineKompressor;
public class DrawingLine implements Cloneable, Serializable
{
ArrayList<Point> lines;
public DrawingLine() {
lines = new ArrayList<>();
}
public void addPoint( Point point) {
lines.add( point);
}
public void setPoints( ArrayList<Point> points) {
lines = points;
}
public Object clone() throws java.lang.CloneNotSupportedException {
return super.clone();
}
private void writePoint( Point p, DataOutputStream destination) throws
java.io.IOException {
destination.writeInt( p.x);
destination.writeInt( p.y);
}
private void readPoint( DataInputStream source) throws java.io.IOException {
Point point = new Point( source.readInt(), source.readInt());
lines.add( point);
}
public void save( DataOutputStream destination) throws
java.io.IOException {
destination.writeInt( lines.size());
for (int i=0; i < lines.size(); i++) {
writePoint( (Point) lines.get(i), destination);
}
}
public void load( DataInputStream source) throws
java.io.IOException {
int point_number = source.readInt();
for (int i=0; i < point_number; i++) {
readPoint( source);
}
}
/**
* send over the stream a compressed version of this line
*/
public void saveKompressed( OutputStream destination) throws
java.io.IOException {
DrawLineKompressor kompressor = new DrawLineKompressor( lines);
kompressor.kompress( destination);
}
/**
* load form the stream a compressed version of this line
*/
public void loadExpanded( InputStream source) throws
java.io.IOException {
DrawLineExpander expander = new DrawLineExpander();
lines = expander.expand( source);
}
public ArrayList<Point> getPoints() {
return new ArrayList<Point>(lines);
}
public ArrayList<Point> internalGetPoints() {
return lines;
}
}

View File

@@ -0,0 +1,94 @@
package org.artisanlogiciel.graphics;
import java.awt.Point;
import java.io.DataInputStream;
/**
.IMA format is an old proprietary format for laser show program
it contain a list of point the laser beam should goe through,
x=255 has a special meaning to hide (255,254) ( send beam into the box) or show it (255,255): let is flow outside.
*/
public class IMAImporter implements Importer
{
final DataInputStream mStream;
boolean mBeanOn = false;
int mIndex =0;
boolean mDebug = false;
public IMAImporter(DataInputStream inputStream)
{
mStream=inputStream;
}
public void setDebug(boolean pDebug)
{
mDebug=pDebug;
}
@Override
public void importInto(Drawing drawing)
{
int x,y;
DrawingLine line = null;
mBeanOn = false;
try {
// little endian unsigned short
int pointCount = mStream.readUnsignedByte();
pointCount = ( 256 * mStream.readUnsignedByte() ) + pointCount;
if ( mDebug )
{
System.out.println("point count :" + pointCount);
}
for (int j = 0 ; j < pointCount; j+=2)
{
mIndex=j;
x = mStream.readUnsignedByte();
y = mStream.readUnsignedByte();
// special beam on/off
if ( ( x == 0xff ) && ( y >= 0xfe ) )
{
mBeanOn = ( y == 0xff);
if ( mDebug )
{
System.out.println("beam change at " + mIndex + " " + mBeanOn);
}
}
else
{
y = 255-y;
if ( mDebug )
{
System.out.println("point at " + mIndex + " " + mBeanOn + " x " + x + " y " + y);
}
if ( mBeanOn )
{
if (line == null )
{
line = new DrawingLine();
}
line.addPoint(new Point(x,y));
}
else
{
if ( line != null )
{
drawing.addLine(line);
line = null;
}
}
}
}
if ( line != null )
{
drawing.addLine(line);
line = null;
}
}
catch( Exception any)
{
System.err.println(" error at index " + mIndex);
any.printStackTrace(System.err);
}
}
}

View File

@@ -0,0 +1,143 @@
package org.artisanlogiciel.graphics;
import java.awt.Point;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
/**
* Write a DrawLine (using its internal Vector representation) into IMA format
* this is with loss ( ima is a 255x255 point resolution )
*
* @author philippe
*
*/
public class IMAWriter {
private final ArrayList<DrawingLine> mLines;
private int mByteCount = 0;
// need to compute bounding box and normalize to 255x255
private Point mOrig = new Point(100000,100000);
private Point mMax = new Point(-100000,-100000);
double ratioX = .1;
double ratioY = .1;
public IMAWriter(ArrayList<DrawingLine> pLines)
{
mLines = pLines;
setup();
}
private void updateOrigMax(Point p)
{
double ox = mOrig.getX(), oy = mOrig.getY(), mx = mMax.getX(), my = mMax.getY();
if (p.getX() < ox )
{
ox = p.getX();
}
if (p.getX() > mx)
{
mx = p.getX();
}
if (p.getY() < oy )
{
oy = p.getY();
}
if (p.getY() > my)
{
my = p.getY();
}
mOrig.setLocation(ox,oy);
mMax.setLocation(mx,my);
}
private void setup()
{
int count = 0;
for (DrawingLine line : mLines)
{
for (Point p : line.getPoints())
{
updateOrigMax(p);
count+=2;
}
// beam on + off
count+=4;
}
mByteCount=count;
if ( mMax.getX() != mOrig.getX())
{
ratioX = 255 / (mMax.getX() - mOrig.getX());
}
else
{
ratioX = 1.;
}
if ( mMax.getY() != mOrig.getY())
{
ratioY = 255 / (mMax.getY() - mOrig.getY());
}
else
{
ratioY = 1.;
}
}
public void writeTo(DataOutputStream pData)
throws IOException
{
int wrote = 0;
// writeheader : number of points ...
// little endian unsigned short.
pData.writeByte(mByteCount%256);
pData.writeByte(mByteCount/256);
for (DrawingLine line : mLines)
{
// write ima line
wrote += writeLine(pData, line.getPoints());
}
}
void writeBeamOnOff(DataOutputStream pData,boolean pOn)
throws IOException
{
pData.writeByte(0xff);
pData.writeByte(pOn ? 0xff : 0xfe);
}
void writePoint(DataOutputStream pData,Point pPoint)
throws IOException
{
int x = (int) ((pPoint.getX()-mOrig.getX()) * ratioX);
int y = 255 - ((int) ((pPoint.getY()-mOrig.getY()) * ratioY));
if ( x == 0xff )
{
x=0xfe;
}
pData.writeByte(x);
pData.writeByte(y);
}
int writeLine(DataOutputStream pData,ArrayList<Point> pPoints)
throws IOException
{
int count = 0;
for (Point p : pPoints)
{
writePoint(pData,p);
if ( count == 0 )
{
writeBeamOnOff(pData,true);
}
count++;
}
writeBeamOnOff(pData,false);
return 2*(count +2);
}
}

View File

@@ -0,0 +1,8 @@
package org.artisanlogiciel.graphics;
public interface Importer {
void importInto(Drawing drawing);
void setDebug(boolean pDebug);
}

View File

@@ -0,0 +1,31 @@
/*
This file is part of ShareDrawWeb.
ShareDrawWeb is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
ShareDrawWeb is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ShareDrawWeb; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.artisanlogiciel.graphics;
import java.io.Serializable;
public class NoMoreLineException
extends DrawException
implements Serializable
{
public NoMoreLineException() {
super();
}
}

View File

@@ -0,0 +1,28 @@
/*
This file is part of ShareDrawWeb.
ShareDrawWeb is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
ShareDrawWeb is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with ShareDrawWeb; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.artisanlogiciel.graphics;
public class ResetException
extends DrawException
{
public ResetException() {
super();
}
}

View File

@@ -0,0 +1,65 @@
package org.artisanlogiciel.graphics;
import java.awt.Point;
//import java.io.DataOutputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.ArrayList;
/**
* Write a DrawLine (using its internal Vector representation) into svg
*
* @author philippe
*
*/
public class SvgWriter {
private final ArrayList<DrawingLine> mLines;
public SvgWriter(ArrayList<DrawingLine> pLines)
{
mLines = pLines;
}
public void writeTo(OutputStream pData)
throws IOException
{
pData.write("<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>".getBytes("UTF8"));
pData.write("<svg>".getBytes("UTF8"));
for (DrawingLine line : mLines)
{
pData.write("<g><path ".getBytes("UTF8"));
pData.write("style=\"fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1\" d=\"".getBytes("UTF8"));
pData.write( getSvgPathString(line.getPoints()).getBytes("UTF8"));
pData.write(" \" /></g>".getBytes("UTF8"));
}
pData.write("</svg>".getBytes("UTF8"));
}
String getSvgPathString(ArrayList<Point> pPoints)
{
StringBuilder sb = new StringBuilder(pPoints.size() * 10);
Point second = null;
Point previous = null;
for ( Point p : pPoints)
{
if ( previous != null )
{
if ( second == null )
{
second = p;
// 'l' a line ( 'c' woudl be a curve )
sb.append(" l ");
}
sb.append( "" + (p.getX() - previous.getX()) + "," + (p.getY() - previous.getY()) );
previous = p;
}
else
{
sb.append("m " + p.getX() + "," + p.getY());
previous = p;
}
}
return sb.toString();
}
}