From d8190555291dadfe52955e1b3c05dc45f1c5ba81 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Wed, 18 Jan 2017 20:03:58 +0100 Subject: [PATCH 1/7] Add svg exporter --- .../com/simplemobiletools/draw/MyPath.java | 56 +++--------------- .../java/com/simplemobiletools/draw/Svg.java | 58 +++++++++++++++++++ .../draw/actions/Action.java | 12 ++++ .../simplemobiletools/draw/actions/Line.java | 29 ++++++++++ .../simplemobiletools/draw/actions/Move.java | 30 ++++++++++ .../simplemobiletools/draw/actions/Quad.java | 35 +++++++++++ 6 files changed, 171 insertions(+), 49 deletions(-) create mode 100644 app/src/main/java/com/simplemobiletools/draw/Svg.java create mode 100644 app/src/main/java/com/simplemobiletools/draw/actions/Action.java create mode 100644 app/src/main/java/com/simplemobiletools/draw/actions/Line.java create mode 100644 app/src/main/java/com/simplemobiletools/draw/actions/Move.java create mode 100644 app/src/main/java/com/simplemobiletools/draw/actions/Quad.java diff --git a/app/src/main/java/com/simplemobiletools/draw/MyPath.java b/app/src/main/java/com/simplemobiletools/draw/MyPath.java index ec3fa6b..df70de8 100644 --- a/app/src/main/java/com/simplemobiletools/draw/MyPath.java +++ b/app/src/main/java/com/simplemobiletools/draw/MyPath.java @@ -2,6 +2,11 @@ package com.simplemobiletools.draw; import android.graphics.Path; +import com.simplemobiletools.draw.actions.Action; +import com.simplemobiletools.draw.actions.Line; +import com.simplemobiletools.draw.actions.Move; +import com.simplemobiletools.draw.actions.Quad; + import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serializable; @@ -45,54 +50,7 @@ class MyPath extends Path implements Serializable { super.quadTo(x1, y1, x2, y2); } - private interface Action extends Serializable { - void perform(Path path); - } - - private static final class Move implements Action { - - private final float x, y; - - Move(float x, float y) { - this.x = x; - this.y = y; - } - - @Override - public void perform(Path path) { - path.moveTo(x, y); - } - } - - private static final class Line implements Action { - - private final float x, y; - - Line(float x, float y) { - this.x = x; - this.y = y; - } - - @Override - public void perform(Path path) { - path.lineTo(x, y); - } - } - - private static final class Quad implements Action { - - private final float x1, y1, x2, y2; - - private Quad(float x1, float y1, float x2, float y2) { - this.x1 = x1; - this.y1 = y1; - this.x2 = x2; - this.y2 = y2; - } - - @Override - public void perform(Path path) { - path.quadTo(x1, y1, x2, y2); - } + List getActions() { + return actions; } } diff --git a/app/src/main/java/com/simplemobiletools/draw/Svg.java b/app/src/main/java/com/simplemobiletools/draw/Svg.java new file mode 100644 index 0000000..13aadc3 --- /dev/null +++ b/app/src/main/java/com/simplemobiletools/draw/Svg.java @@ -0,0 +1,58 @@ +package com.simplemobiletools.draw; + +import com.simplemobiletools.draw.actions.Action; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.Map; + +public class Svg { + + public static boolean saveSvg(File output, + Map paths, int width, int height) { + try { + FileOutputStream out = new FileOutputStream(output); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out)); + writeSvg(writer, paths, width, height); + writer.close(); + return true; + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + private static void writeSvg(Writer writer, + Map paths, int width, int height) + throws IOException { + writer.write(""); + for (Map.Entry entry : paths.entrySet()) { + writePath(writer, entry.getKey(), entry.getValue()); + } + writer.write(""); + } + + private static void writePath(Writer writer, MyPath path, PaintOptions options) + throws IOException { + + writer.write(""); + } +} diff --git a/app/src/main/java/com/simplemobiletools/draw/actions/Action.java b/app/src/main/java/com/simplemobiletools/draw/actions/Action.java new file mode 100644 index 0000000..cad7a63 --- /dev/null +++ b/app/src/main/java/com/simplemobiletools/draw/actions/Action.java @@ -0,0 +1,12 @@ +package com.simplemobiletools.draw.actions; + +import android.graphics.Path; + +import java.io.IOException; +import java.io.Serializable; +import java.io.Writer; + +public interface Action extends Serializable { + void perform(Path path); + void perform(Writer writer) throws IOException; +} diff --git a/app/src/main/java/com/simplemobiletools/draw/actions/Line.java b/app/src/main/java/com/simplemobiletools/draw/actions/Line.java new file mode 100644 index 0000000..e5ca3d6 --- /dev/null +++ b/app/src/main/java/com/simplemobiletools/draw/actions/Line.java @@ -0,0 +1,29 @@ +package com.simplemobiletools.draw.actions; + +import android.graphics.Path; + +import java.io.IOException; +import java.io.Writer; + +public final class Line implements Action { + + private final float x, y; + + public Line(float x, float y) { + this.x = x; + this.y = y; + } + + @Override + public void perform(Path path) { + path.lineTo(x, y); + } + + @Override + public void perform(Writer writer) throws IOException { + writer.write("L"); + writer.write(String.valueOf(x)); + writer.write(","); + writer.write(String.valueOf(y)); + } +} diff --git a/app/src/main/java/com/simplemobiletools/draw/actions/Move.java b/app/src/main/java/com/simplemobiletools/draw/actions/Move.java new file mode 100644 index 0000000..69923ba --- /dev/null +++ b/app/src/main/java/com/simplemobiletools/draw/actions/Move.java @@ -0,0 +1,30 @@ +package com.simplemobiletools.draw.actions; + + +import android.graphics.Path; + +import java.io.IOException; +import java.io.Writer; + +public final class Move implements Action { + + private final float x, y; + + public Move(float x, float y) { + this.x = x; + this.y = y; + } + + @Override + public void perform(Path path) { + path.moveTo(x, y); + } + + @Override + public void perform(Writer writer) throws IOException { + writer.write('M'); + writer.write(String.valueOf(x)); + writer.write(','); + writer.write(String.valueOf(y)); + } +} diff --git a/app/src/main/java/com/simplemobiletools/draw/actions/Quad.java b/app/src/main/java/com/simplemobiletools/draw/actions/Quad.java new file mode 100644 index 0000000..28d53ff --- /dev/null +++ b/app/src/main/java/com/simplemobiletools/draw/actions/Quad.java @@ -0,0 +1,35 @@ +package com.simplemobiletools.draw.actions; + +import android.graphics.Path; + +import java.io.IOException; +import java.io.Writer; + +public final class Quad implements Action { + + private final float x1, y1, x2, y2; + + public Quad(float x1, float y1, float x2, float y2) { + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + } + + @Override + public void perform(Path path) { + path.quadTo(x1, y1, x2, y2); + } + + @Override + public void perform(Writer writer) throws IOException { + writer.write('Q'); + writer.write(String.valueOf(x1)); + writer.write(','); + writer.write(String.valueOf(y1)); + writer.write(' '); + writer.write(String.valueOf(x2)); + writer.write(','); + writer.write(String.valueOf(y2)); + } +} From 4b7f123a065ca0282b5806ec9672c9dc34fffea4 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Thu, 19 Jan 2017 11:37:39 +0100 Subject: [PATCH 2/7] Show spinner to select the save format --- app/src/main/res/layout/save_file.xml | 4 ++-- app/src/main/res/values/strings.xml | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/app/src/main/res/layout/save_file.xml b/app/src/main/res/layout/save_file.xml index d9ba347..ce22980 100644 --- a/app/src/main/res/layout/save_file.xml +++ b/app/src/main/res/layout/save_file.xml @@ -20,7 +20,7 @@ android:layout_toLeftOf="@+id/file_extension" android:singleLine="true"/> - + android:entries="@array/save_formats"/> diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 27afbaf..76ed815 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -12,6 +12,10 @@ Could not save the file without accessing the external storage OK Cancel + + .png + .svg + Settings From b7d86c34da59de402ebfe34c2a8fbf36cc6c8fd2 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Thu, 19 Jan 2017 11:46:00 +0100 Subject: [PATCH 3/7] Use the selected extension when saving --- .../com/simplemobiletools/draw/MyCanvas.java | 4 ++ .../java/com/simplemobiletools/draw/Svg.java | 5 +- .../draw/activities/MainActivity.java | 59 ++++++++++++------- 3 files changed, 45 insertions(+), 23 deletions(-) diff --git a/app/src/main/java/com/simplemobiletools/draw/MyCanvas.java b/app/src/main/java/com/simplemobiletools/draw/MyCanvas.java index 4b1f2bc..0fc70bb 100644 --- a/app/src/main/java/com/simplemobiletools/draw/MyCanvas.java +++ b/app/src/main/java/com/simplemobiletools/draw/MyCanvas.java @@ -94,6 +94,10 @@ public class MyCanvas extends View { return bitmap; } + public Map getPaths() { + return mPaths; + } + @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); diff --git a/app/src/main/java/com/simplemobiletools/draw/Svg.java b/app/src/main/java/com/simplemobiletools/draw/Svg.java index 13aadc3..2db2f58 100644 --- a/app/src/main/java/com/simplemobiletools/draw/Svg.java +++ b/app/src/main/java/com/simplemobiletools/draw/Svg.java @@ -12,12 +12,11 @@ import java.util.Map; public class Svg { - public static boolean saveSvg(File output, - Map paths, int width, int height) { + public static boolean saveSvg(File output, MyCanvas canvas) { try { FileOutputStream out = new FileOutputStream(output); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out)); - writeSvg(writer, paths, width, height); + writeSvg(writer, canvas.getPaths(), canvas.getWidth(), canvas.getHeight()); writer.close(); return true; } catch (IOException e) { diff --git a/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java b/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java index ca4069f..d962df2 100644 --- a/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java +++ b/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java @@ -20,11 +20,13 @@ import android.view.View; import android.widget.EditText; import android.widget.ImageView; import android.widget.SeekBar; +import android.widget.Spinner; import android.widget.Toast; import com.simplemobiletools.draw.Config; import com.simplemobiletools.draw.MyCanvas; import com.simplemobiletools.draw.R; +import com.simplemobiletools.draw.Svg; import com.simplemobiletools.draw.Utils; import java.io.ByteArrayOutputStream; @@ -163,6 +165,8 @@ public class MainActivity extends SimpleActivity implements MyCanvas.PathsChange final EditText fileNameET = (EditText) saveFileView.findViewById(R.id.file_name); fileNameET.setText(curFileName); + + final Spinner fileExtensionS = (Spinner) saveFileView.findViewById(R.id.file_extension); builder.setView(saveFileView); builder.setPositiveButton(R.string.ok, null); @@ -174,9 +178,9 @@ public class MainActivity extends SimpleActivity implements MyCanvas.PathsChange @Override public void onClick(View v) { final String fileName = fileNameET.getText().toString().trim(); - + final String extension = (String) fileExtensionS.getSelectedItem(); if (!fileName.isEmpty()) { - if (saveFile(fileName + ".png")) { + if (saveFile(fileName, extension)) { curFileName = fileName; Utils.showToast(getApplicationContext(), R.string.saving_ok); alertDialog.dismiss(); @@ -190,7 +194,7 @@ public class MainActivity extends SimpleActivity implements MyCanvas.PathsChange }); } - private boolean saveFile(final String fileName) { + private boolean saveFile(final String fileName, final String extension) { final String path = Environment.getExternalStorageDirectory().toString(); final File directory = new File(path, SAVE_FOLDER_NAME); if (!directory.exists()) { @@ -199,24 +203,39 @@ public class MainActivity extends SimpleActivity implements MyCanvas.PathsChange } } - final Bitmap bitmap = mMyCanvas.getBitmap(); - FileOutputStream out = null; - try { - final File file = new File(directory, fileName); - out = new FileOutputStream(file); - bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); - MediaScannerConnection.scanFile(getApplicationContext(), new String[]{file.getAbsolutePath()}, null, null); - } catch (Exception e) { - Log.e(TAG, "MainActivity SaveFile " + e.getMessage()); - return false; - } finally { - try { - if (out != null) { - out.close(); + final File file = new File(directory, fileName+extension); + switch (extension) { + case ".png": + final Bitmap bitmap = mMyCanvas.getBitmap(); + FileOutputStream out = null; + try { + out = new FileOutputStream(file); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, out); + MediaScannerConnection.scanFile(getApplicationContext(), + new String[]{file.getAbsolutePath()}, null, null); + } catch (Exception e) { + Log.e(TAG, "MainActivity SaveFile " + e.getMessage()); + return false; + } finally { + try { + if (out != null) { + out.close(); + } + } catch (IOException e) { + Log.e(TAG, "MainActivity SaveFile 2 " + e.getMessage()); + } } - } catch (IOException e) { - Log.e(TAG, "MainActivity SaveFile 2 " + e.getMessage()); - } + break; + + case ".svg": + if (!Svg.saveSvg(file, mMyCanvas)) { + Log.e(TAG, "MainActivity SaveFile failed."); + return false; + } + break; + + default: + return false; } return true; From 81d51c7bb6e906f54c044dbef093087519446169 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Thu, 19 Jan 2017 11:51:11 +0100 Subject: [PATCH 4/7] Use a round stroke line cap --- app/src/main/java/com/simplemobiletools/draw/Svg.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/com/simplemobiletools/draw/Svg.java b/app/src/main/java/com/simplemobiletools/draw/Svg.java index 2db2f58..7c20407 100644 --- a/app/src/main/java/com/simplemobiletools/draw/Svg.java +++ b/app/src/main/java/com/simplemobiletools/draw/Svg.java @@ -52,6 +52,6 @@ public class Svg { writer.write(Integer.toHexString(options.color).substring(2)); // Skip the alpha FF writer.write("\" stroke-width=\""); writer.write(String.valueOf(options.strokeWidth)); - writer.write("\"/>"); + writer.write("\" stroke-linecap=\"round\"/>"); } } From 1acc5e2498e47116523a0786a1b008e1df4ae249 Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Thu, 19 Jan 2017 11:58:56 +0100 Subject: [PATCH 5/7] Remember selected extension --- .../com/simplemobiletools/draw/activities/MainActivity.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java b/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java index d962df2..872a4ec 100644 --- a/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java +++ b/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java @@ -52,6 +52,7 @@ public class MainActivity extends SimpleActivity implements MyCanvas.PathsChange @BindView(R.id.stroke_width_bar) SeekBar mStrokeWidthBar; private String curFileName; + private int curExtensionIndex; private int color; private float strokeWidth; @@ -167,6 +168,7 @@ public class MainActivity extends SimpleActivity implements MyCanvas.PathsChange fileNameET.setText(curFileName); final Spinner fileExtensionS = (Spinner) saveFileView.findViewById(R.id.file_extension); + fileExtensionS.setSelection(curExtensionIndex); builder.setView(saveFileView); builder.setPositiveButton(R.string.ok, null); @@ -182,6 +184,8 @@ public class MainActivity extends SimpleActivity implements MyCanvas.PathsChange if (!fileName.isEmpty()) { if (saveFile(fileName, extension)) { curFileName = fileName; + curExtensionIndex = fileExtensionS.getSelectedItemPosition(); + Utils.showToast(getApplicationContext(), R.string.saving_ok); alertDialog.dismiss(); } else { From eea21a185cb1068ce92a53b43fab90b640761c0e Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Thu, 19 Jan 2017 12:02:03 +0100 Subject: [PATCH 6/7] Let saving as .svg exceptions propagate --- .../java/com/simplemobiletools/draw/Svg.java | 17 ++++++----------- .../draw/activities/MainActivity.java | 10 ++++++---- 2 files changed, 12 insertions(+), 15 deletions(-) diff --git a/app/src/main/java/com/simplemobiletools/draw/Svg.java b/app/src/main/java/com/simplemobiletools/draw/Svg.java index 7c20407..31a97be 100644 --- a/app/src/main/java/com/simplemobiletools/draw/Svg.java +++ b/app/src/main/java/com/simplemobiletools/draw/Svg.java @@ -12,17 +12,12 @@ import java.util.Map; public class Svg { - public static boolean saveSvg(File output, MyCanvas canvas) { - try { - FileOutputStream out = new FileOutputStream(output); - BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out)); - writeSvg(writer, canvas.getPaths(), canvas.getWidth(), canvas.getHeight()); - writer.close(); - return true; - } catch (IOException e) { - e.printStackTrace(); - return false; - } + public static void saveSvg(File output, MyCanvas canvas) + throws IOException { + FileOutputStream out = new FileOutputStream(output); + BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out)); + writeSvg(writer, canvas.getPaths(), canvas.getWidth(), canvas.getHeight()); + writer.close(); } private static void writeSvg(Writer writer, diff --git a/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java b/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java index 872a4ec..74b2cfb 100644 --- a/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java +++ b/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java @@ -218,7 +218,7 @@ public class MainActivity extends SimpleActivity implements MyCanvas.PathsChange MediaScannerConnection.scanFile(getApplicationContext(), new String[]{file.getAbsolutePath()}, null, null); } catch (Exception e) { - Log.e(TAG, "MainActivity SaveFile " + e.getMessage()); + Log.e(TAG, "MainActivity SaveFile (.png) " + e.getMessage()); return false; } finally { try { @@ -226,14 +226,16 @@ public class MainActivity extends SimpleActivity implements MyCanvas.PathsChange out.close(); } } catch (IOException e) { - Log.e(TAG, "MainActivity SaveFile 2 " + e.getMessage()); + Log.e(TAG, "MainActivity SaveFile (.png) 2 " + e.getMessage()); } } break; case ".svg": - if (!Svg.saveSvg(file, mMyCanvas)) { - Log.e(TAG, "MainActivity SaveFile failed."); + try { + Svg.saveSvg(file, mMyCanvas); + } catch (IOException e) { + Log.e(TAG, "MainActivity SaveFile (.svg) " + e.getMessage()); return false; } break; From bd31fbcb6149babeb41244ecef60082e521d44fc Mon Sep 17 00:00:00 2001 From: Lonami Exo Date: Thu, 19 Jan 2017 12:16:49 +0100 Subject: [PATCH 7/7] Consider the background color when saving as .svg --- .../java/com/simplemobiletools/draw/Svg.java | 23 ++++++++++++++++--- .../draw/activities/MainActivity.java | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/com/simplemobiletools/draw/Svg.java b/app/src/main/java/com/simplemobiletools/draw/Svg.java index 31a97be..4928089 100644 --- a/app/src/main/java/com/simplemobiletools/draw/Svg.java +++ b/app/src/main/java/com/simplemobiletools/draw/Svg.java @@ -1,5 +1,7 @@ package com.simplemobiletools.draw; +import android.graphics.drawable.ColorDrawable; + import com.simplemobiletools.draw.actions.Action; import java.io.BufferedWriter; @@ -13,14 +15,18 @@ import java.util.Map; public class Svg { public static void saveSvg(File output, MyCanvas canvas) - throws IOException { + throws Exception { + // This might throw ClassCastException + int backgroundColor = ((ColorDrawable) canvas.getBackground()).getColor(); + + // This might throw IOException FileOutputStream out = new FileOutputStream(output); BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(out)); - writeSvg(writer, canvas.getPaths(), canvas.getWidth(), canvas.getHeight()); + writeSvg(writer, backgroundColor, canvas.getPaths(), canvas.getWidth(), canvas.getHeight()); writer.close(); } - private static void writeSvg(Writer writer, + private static void writeSvg(Writer writer, int backgroundColor, Map paths, int width, int height) throws IOException { writer.write(""); + + // Background color (use a rect) + writer.write(""); + + // Write the paths for (Map.Entry entry : paths.entrySet()) { writePath(writer, entry.getKey(), entry.getValue()); } diff --git a/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java b/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java index 74b2cfb..64f54c5 100644 --- a/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java +++ b/app/src/main/java/com/simplemobiletools/draw/activities/MainActivity.java @@ -234,7 +234,7 @@ public class MainActivity extends SimpleActivity implements MyCanvas.PathsChange case ".svg": try { Svg.saveSvg(file, mMyCanvas); - } catch (IOException e) { + } catch (Exception e) { Log.e(TAG, "MainActivity SaveFile (.svg) " + e.getMessage()); return false; }