diff --git a/project.clj b/project.clj index df0aefe..b24edad 100644 --- a/project.clj +++ b/project.clj @@ -1,4 +1,4 @@ -(defproject stathissideris/ditaa "0.11.0" +(defproject stathissideris/ditaa "0.11.0-borderwidth" :description "command-line utility that can convert diagrams drawn using ascii art into proper bitmap graphics" :min-lein-version "2.0.0" :url "https://github.com/stathissideris/ditaa" diff --git a/src/java/org/stathissideris/ascii2image/core/CommandLineConverter.java b/src/java/org/stathissideris/ascii2image/core/CommandLineConverter.java index 937953a..67e8a7b 100644 --- a/src/java/org/stathissideris/ascii2image/core/CommandLineConverter.java +++ b/src/java/org/stathissideris/ascii2image/core/CommandLineConverter.java @@ -90,6 +90,14 @@ public static void main(String[] args){ .create('t') ); + cmdLnOptions.addOption( + OptionBuilder.withLongOpt("border-width") + .withDescription("Border width around image (minimum 1).") + .hasArg() + .withArgName("BORDERWIDTH") + .create() + ); + cmdLnOptions.addOption( OptionBuilder.withLongOpt("background") .withDescription("The background colour of the image. The format should be a six-digit hexadecimal number (as in HTML, FF0000 for red). Pass an eight-digit hex to define transparency. This is overridden by --transparent.") diff --git a/src/java/org/stathissideris/ascii2image/core/ConversionOptions.java b/src/java/org/stathissideris/ascii2image/core/ConversionOptions.java index 5599f65..e308674 100644 --- a/src/java/org/stathissideris/ascii2image/core/ConversionOptions.java +++ b/src/java/org/stathissideris/ascii2image/core/ConversionOptions.java @@ -1,10 +1,10 @@ /** * ditaa - Diagrams Through Ascii Art - * + * * Copyright (C) 2004-2011 Efstathios Sideris * * ditaa is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as + * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with ditaa. If not, see . - * + * */ package org.stathissideris.ascii2image.core; @@ -32,21 +32,21 @@ import java.util.HashMap; /** - * + * * @author Efstathios Sideris */ public class ConversionOptions { - + public ProcessingOptions processingOptions = new ProcessingOptions(); public RenderingOptions renderingOptions = new RenderingOptions(); - + public void setDebug(boolean value){ processingOptions.setPrintDebugOutput(value); renderingOptions.setRenderDebugLines(value); } - + public ConversionOptions(){} /** Parse a color from a 6- or 8-digit hex string. For example, FF0000 is red. @@ -65,19 +65,19 @@ public static Color parseColor(String hexString) { throw new IllegalArgumentException("Cannot interpret \""+hexString+"\" as background colour. It needs to be a 6- or 8-digit hex number, depending on whether you have transparency or not (same as HTML)."); } } - + public ConversionOptions(CommandLine cmdLine) throws UnsupportedEncodingException{ - + processingOptions.setVerbose(cmdLine.hasOption("verbose")); renderingOptions.setDropShadows(!cmdLine.hasOption("no-shadows")); this.setDebug(cmdLine.hasOption("debug")); processingOptions.setOverwriteFiles(cmdLine.hasOption("overwrite")); - + if(cmdLine.hasOption("scale")){ Float scale = Float.parseFloat(cmdLine.getOptionValue("scale")); renderingOptions.setScale(scale.floatValue()); } - + processingOptions.setAllCornersAreRound(cmdLine.hasOption("round-corners")); processingOptions.setPerformSeparationOfCommonEdges(!cmdLine.hasOption("no-separation")); renderingOptions.setAntialias(!cmdLine.hasOption("no-antialias")); @@ -88,7 +88,7 @@ public ConversionOptions(CommandLine cmdLine) throws UnsupportedEncodingExceptio Color background = parseColor(b); renderingOptions.setBackgroundColor(background); } - + if(cmdLine.hasOption("transparent")) { renderingOptions.setBackgroundColor(new Color(0,0,0,0)); } @@ -100,12 +100,19 @@ public ConversionOptions(CommandLine cmdLine) throws UnsupportedEncodingExceptio processingOptions.setTabSize(tabSizeValue); } + if(cmdLine.hasOption("border-width")){ + Integer borderWidth = Integer.parseInt(cmdLine.getOptionValue("border-width")); + int borderWidthValue = borderWidth.intValue(); + if(borderWidthValue < 1) borderWidthValue = 1; + processingOptions.setBorderWidth(borderWidthValue); + } + String encoding = (String) cmdLine.getOptionValue("encoding"); if(encoding != null){ new String(new byte[2], encoding); processingOptions.setCharacterEncoding(encoding); } - + if (cmdLine.hasOption("svg")){ renderingOptions.setImageType(RenderingOptions.ImageType.SVG); } diff --git a/src/java/org/stathissideris/ascii2image/core/ProcessingOptions.java b/src/java/org/stathissideris/ascii2image/core/ProcessingOptions.java index 1833e9f..2e3a169 100644 --- a/src/java/org/stathissideris/ascii2image/core/ProcessingOptions.java +++ b/src/java/org/stathissideris/ascii2image/core/ProcessingOptions.java @@ -1,10 +1,10 @@ /** * ditaa - Diagrams Through Ascii Art - * + * * Copyright (C) 2004-2011 Efstathios Sideris * * ditaa is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as + * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with ditaa. If not, see . - * + * */ package org.stathissideris.ascii2image.core; @@ -30,7 +30,7 @@ public class ProcessingOptions { private HashMap customShapes = new HashMap(); - + private boolean beVerbose = false; private boolean printDebugOutput = false; private boolean overwriteFiles = false; @@ -55,11 +55,14 @@ public class ProcessingOptions { public static final int DEFAULT_TAB_SIZE = 8; private int tabSize = DEFAULT_TAB_SIZE; + public static final int DEFAULT_BORDER_WIDTH = 2; + private int borderWidth = DEFAULT_BORDER_WIDTH; + private String inputFilename; private String outputFilename; - + private String characterEncoding = null; - + /** * @return */ @@ -214,6 +217,21 @@ public void setTabSize(int i) { tabSize = i; } + /** + * @return + */ + public int getBorderWidth() { + return borderWidth; + } + + /** + * @param i + */ + public void setBorderWidth(int i) { + if (i < 1) borderWidth = 1; + else borderWidth = i; + } + public String getCharacterEncoding() { return characterEncoding; } @@ -233,11 +251,11 @@ public void setCustomShapes(HashMap customShapes) public void putAllInCustomShapes(HashMap customShapes) { this.customShapes.putAll(customShapes); } - + public CustomShapeDefinition getFromCustomShapes(String tagName){ return customShapes.get(tagName); } - - + + } diff --git a/src/java/org/stathissideris/ascii2image/text/TextGrid.java b/src/java/org/stathissideris/ascii2image/text/TextGrid.java index 1ead278..23eb732 100644 --- a/src/java/org/stathissideris/ascii2image/text/TextGrid.java +++ b/src/java/org/stathissideris/ascii2image/text/TextGrid.java @@ -1,10 +1,10 @@ /** * ditaa - Diagrams Through Ascii Art - * + * * Copyright (C) 2004-2011 Efstathios Sideris * * ditaa is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as + * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of * the License, or (at your option) any later version. * @@ -15,7 +15,7 @@ * * You should have received a copy of the GNU Lesser General Public * License along with ditaa. If not, see . - * + * */ package org.stathissideris.ascii2image.text; @@ -31,7 +31,7 @@ /** - * + * * @author Efstathios Sideris */ public class TextGrid { @@ -48,7 +48,7 @@ public class TextGrid { private static char[] cornerChars = {'\\', '/', '+'}; private static char[] pointMarkers = {'*'}; private static char[] dashedLines = {':', '~', '='}; - + private static char[] entryPoints1 = {'\\'}; private static char[] entryPoints2 = {'|', ':', '+', '\\', '/'}; private static char[] entryPoints3 = {'/'}; @@ -68,7 +68,7 @@ public class TextGrid { humanColorCodes.put("RED", "E32"); humanColorCodes.put("YEL", "FF3"); humanColorCodes.put("BLK", "000"); - + } private static HashSet markupTags = @@ -87,7 +87,7 @@ public class TextGrid { public void addToMarkupTags(Collection tags){ markupTags.addAll(tags); } - + public static void main(String[] args) throws Exception { TextGrid grid = new TextGrid(); grid.loadFrom("tests/text/art10.txt"); @@ -95,7 +95,7 @@ public static void main(String[] args) throws Exception { grid.writeStringTo(grid.new Cell(28, 1), "testing"); grid.findMarkupTags(); - + grid.printDebug(); //System.out.println(grid.fillContinuousArea(0, 0, '-').size()+" cells filled"); //grid.fillContinuousArea(4, 4, '-'); @@ -107,7 +107,7 @@ public static void main(String[] args) throws Exception { public TextGrid(){ rows = new ArrayList(); } - + public TextGrid(int width, int height){ String space = StringUtils.repeatString(" ", width); rows = new ArrayList(); @@ -124,7 +124,7 @@ public TextGrid(TextGrid otherGrid){ rows = new ArrayList(); for(StringBuilder row : otherGrid.getRows()) { rows.add(new StringBuilder(row)); - } + } } public void clear(){ @@ -132,7 +132,7 @@ public void clear(){ int height = getHeight(); rows.clear(); for(int i = 0; i < height; i++) - rows.add(new StringBuilder(blank)); + rows.add(new StringBuilder(blank)); } // duplicated code due to lots of hits to this function @@ -152,7 +152,7 @@ public char get(Cell cell){ || cell.y < 0) return 0; return rows.get(cell.y).charAt(cell.x); } - + public StringBuilder getRow(int y){ return rows.get(y); } @@ -181,7 +181,7 @@ public String getStringAt(Cell cell, int length){ || y > getHeight() - 1 || x < 0 || y < 0) return null; - return rows.get(y).substring(x, x + length); + return rows.get(y).substring(x, x + length); } public char getNorthOf(int x, int y){ return get(x, y - 1); } @@ -212,7 +212,7 @@ public void set(int x, int y, char c){ StringBuilder row = rows.get(y); row.setCharAt(x, c); } - + public void setRow(int y, String row){ if(y > getHeight() || row.length() != getWidth()) throw new IllegalArgumentException("setRow out of bounds or string wrong size"); @@ -224,7 +224,7 @@ public void setRow(int y, StringBuilder row){ throw new IllegalArgumentException("setRow out of bounds or string wrong size"); rows.set(y, row); } - + public int getWidth(){ if(rows.size() == 0) return 0; //empty buffer return rows.get(0).length(); @@ -245,7 +245,7 @@ public void printDebug(){ String index = new Integer(i).toString(); if(i < 10) index = " "+index; System.out.println(index+" ("+row+")"); - i++; + i++; } } @@ -263,7 +263,7 @@ public String getDebugString(){ row = row.replaceAll("\n", "\\\\n"); row = row.replaceAll("\r", "\\\\r"); buffer.append(index+" ("+row+")\n"); - i++; + i++; } return buffer.toString(); } @@ -274,9 +274,9 @@ public String toString(){ /** * Adds grid to this. Space characters in this grid - * are replaced with the corresponding contents of + * are replaced with the corresponding contents of * grid, otherwise the contents are unchanged. - * + * * @param grid * @return false if the grids are of different size */ @@ -307,7 +307,7 @@ public void replaceTypeOnLine(){ char c = get(xi, yi); if(Character.isLetterOrDigit(c)) { boolean isOnHorizontalLine = isOnHorizontalLine(xi, yi); - boolean isOnVerticalLine = isOnVerticalLine(xi, yi); + boolean isOnVerticalLine = isOnVerticalLine(xi, yi); if(isOnHorizontalLine && isOnVerticalLine){ set(xi, yi, '+'); if(DEBUG) System.out.println("replaced type on line '"+c+"' with +"); @@ -320,7 +320,7 @@ public void replaceTypeOnLine(){ } } } - } + } } public void replacePointMarkersOnLine(){ @@ -332,7 +332,7 @@ public void replacePointMarkersOnLine(){ Cell cell = new Cell(xi, yi); if(StringUtils.isOneOf(c, pointMarkers) && isStarOnLine(cell)){ - + boolean isOnHorizontalLine = false; if(StringUtils.isOneOf(get(cell.getEast()), horizontalLines)) isOnHorizontalLine = true; @@ -344,7 +344,7 @@ && isStarOnLine(cell)){ isOnVerticalLine = true; if(StringUtils.isOneOf(get(cell.getSouth()), verticalLines)) isOnVerticalLine = true; - + if(isOnHorizontalLine && isOnVerticalLine){ set(xi, yi, '+'); if(DEBUG) System.out.println("replaced marker on line '"+c+"' with +"); @@ -357,7 +357,7 @@ && isStarOnLine(cell)){ } } } - } + } } public CellSet getPointMarkersOnLine(){ @@ -393,13 +393,13 @@ public void replaceHumanColorCodes(){ row = rows.get(y).toString(); } } - } + } } /** * Replace all occurrences of c1 with c2 - * + * * @param c1 * @param c2 */ @@ -411,7 +411,7 @@ public void replaceAll(char c1, char c2){ char c = get(xi, yi); if(c == c1) set(xi, yi, c2); } - } + } } public boolean hasBlankCells(){ @@ -475,7 +475,7 @@ public CellSet getAllBlanksBetweenCharacters(){ * in the grid. Used on buffers that contain only * type, in order to find the positions and the * contents of the strings. - * + * * @return */ public ArrayList findStrings(){ @@ -507,7 +507,7 @@ public ArrayList findStrings(){ /** * This is done in a bit of a messy way, should be impossible * to go out of sync with corresponding GridPatternGroup. - * + * * @param cell * @param entryPointId * @return @@ -517,7 +517,7 @@ public boolean hasEntryPoint(Cell cell, int entryPointId){ char c = get(cell); if(entryPointId == 1) { return StringUtils.isOneOf(c, entryPoints1); - + } else if(entryPointId == 2) { return StringUtils.isOneOf(c, entryPoints2); @@ -545,7 +545,7 @@ public boolean hasEntryPoint(Cell cell, int entryPointId){ /** * true if cell is blank and the east and west cells are not * (used to find gaps between words) - * + * * @param cell * @return */ @@ -577,7 +577,7 @@ public void removeArrowheads(){ Cell cell = new Cell(xi, yi); if(isArrowhead(cell)) set(cell, ' '); } - } + } } public void removeColorCodes(){ @@ -602,10 +602,10 @@ public void removeBoundaries(){ if(isBoundary(cell)) toBeRemoved.add(cell); } } - + //remove in two stages, because decision of //isBoundary depends on content of surrounding - //cells + //cells Iterator it = toBeRemoved.iterator(); while(it.hasNext()){ Cell cell = (Cell) it.next(); @@ -678,7 +678,7 @@ public ArrayList findMarkupTags(){ } return result; } - + public void removeMarkupTags(){ Iterator it = findMarkupTags().iterator(); while (it.hasNext()) { @@ -689,7 +689,7 @@ public void removeMarkupTags(){ writeStringTo(pair.cell, StringUtils.repeatString(" ", length)); } } - + public boolean matchesAny(GridPatternGroup criteria){ @@ -732,9 +732,9 @@ public boolean isBoundary(Cell cell){ if('+' == c || '\\' == c || '/' == c){ System.out.print(""); if( - isIntersection(cell) + isIntersection(cell) || isCorner(cell) - || isStub(cell) + || isStub(cell) || isCrossOnLine(cell)){ return true; } else return false; @@ -773,10 +773,10 @@ public boolean isVerticalLine(int x, int y){ public boolean isLinesEnd(int x, int y){ return isLinesEnd(new Cell(x, y)); } - + /** * Stubs are also considered end of lines - * + * * @param cell * @return */ @@ -821,16 +821,16 @@ public boolean exactlyOneNeighbourIsBoundary(Cell cell) { } /** - * + * * A stub looks like that: - * + * *
-	 * 
+	 *
 	 * +- or -+ or + or + or /- or -/ or / (you get the point)
 	 *             |    |                |
-	 * 
+	 *
 	 * 
- * + * * @param cell * @return */ @@ -874,7 +874,7 @@ public boolean isArrowhead(Cell cell){ || isWestArrowhead(cell) || isEastArrowhead(cell)); } - + public boolean isNorthArrowhead(Cell cell){ return get(cell) == '^'; } @@ -891,8 +891,8 @@ public boolean isSouthArrowhead(Cell cell){ return (get(cell) == 'v' || get(cell) == 'V') && isVerticalLine(cell.getNorth()); } - - + + // unicode for bullets // // 2022 bullet @@ -907,7 +907,7 @@ public boolean isSouthArrowhead(Cell cell){ public boolean isBullet(int x, int y){ return isBullet(new Cell(x, y)); } - + public boolean isBullet(Cell cell){ char c = get(cell); if((c == 'o' || c == '*') @@ -917,7 +917,7 @@ && isBlank(cell.getWest()) return true; return false; } - + public void replaceBullets(){ int width = getWidth(); int height = getHeight(); @@ -931,11 +931,11 @@ public void replaceBullets(){ } } } - + /** * true if the cell is not blank * but the previous (west) is - * + * * @param cell * @return */ @@ -946,7 +946,7 @@ public boolean isStringsStart(Cell cell){ /** * true if the cell is not blank * but the next (east) is - * + * * @param cell * @return */ @@ -1017,7 +1017,7 @@ public CellSet followIntersection(Cell cell, Cell blocked){ /** * Returns the neighbours of a line-cell that are boundaries * (0 to 2 cells are returned) - * + * * @param cell * @return null if the cell is not a line */ @@ -1031,7 +1031,7 @@ public CellSet followLine(Cell cell){ CellSet result = new CellSet(); if(isBoundary(cell.getNorth())) result.add(cell.getNorth()); if(isBoundary(cell.getSouth())) result.add(cell.getSouth()); - return result; + return result; } return null; } @@ -1113,11 +1113,11 @@ public CellSet followStub(Cell cell, Cell blocked){ if(result.contains(blocked)) result.remove(blocked); return result; } - + public CellSet followCell(Cell cell){ return followCell(cell, null); } - + public CellSet followCell(Cell cell, Cell blocked){ if(isIntersection(cell)) return followIntersection(cell, blocked); if(isCorner(cell)) return followCorner(cell, blocked); @@ -1145,7 +1145,7 @@ public String getCellTypeAsString(Cell cell){ return "unrecognisable type"; } - + public CellSet followCrossOnLine(Cell cell, Cell blocked){ CellSet result = new CellSet(); if(isHorizontalCrossOnLine(cell)){ @@ -1197,7 +1197,7 @@ public boolean matchesAny(Cell cell, GridPatternGroup criteria){ TextGrid subGrid = getTestingSubGrid(cell); return subGrid.matchesAny(criteria); } - + public boolean isCorner1(Cell cell){ return matchesAny(cell, GridPatternGroup.corner1Criteria); } @@ -1263,7 +1263,7 @@ public void copyCellsTo(CellSet cells, TextGrid grid){ grid.set(cell, this.get(cell)); } } - + public boolean equals(TextGrid grid){ if(grid.getHeight() != this.getHeight() || grid.getWidth() != this.getWidth() @@ -1278,10 +1278,10 @@ public boolean equals(TextGrid grid){ } return true; } - + /** * Fills all the cells in cells with c - * + * * @param cells * @param c */ @@ -1294,10 +1294,10 @@ public void fillCellsWith(Iterable cells, char c){ } /** - * + * * Fills the continuous area with if c1 characters with c2, * flooding from cell x, y - * + * * @param x * @param y * @param c1 the character to replace @@ -1323,17 +1323,17 @@ public CellSet fillContinuousArea(Cell cell, char c){ private CellSet seedFill(Cell seed, char newChar){ CellSet cellsFilled = new CellSet(); char oldChar = get(seed); - + if(oldChar == newChar) return cellsFilled; if(isOutOfBounds(seed)) return cellsFilled; Stack stack = new Stack(); stack.push(seed); - + while(!stack.isEmpty()){ Cell cell = (Cell) stack.pop(); - + //set(cell, newChar); cellsFilled.add(cell); @@ -1341,30 +1341,30 @@ private CellSet seedFill(Cell seed, char newChar){ Cell sCell = cell.getSouth(); Cell eCell = cell.getEast(); Cell wCell = cell.getWest(); - + if(get(nCell) == oldChar && !cellsFilled.contains(nCell)) stack.push(nCell); if(get(sCell) == oldChar && !cellsFilled.contains(sCell)) stack.push(sCell); if(get(eCell) == oldChar && !cellsFilled.contains(eCell)) stack.push(eCell); if(get(wCell) == oldChar && !cellsFilled.contains(wCell)) stack.push(wCell); } - + return cellsFilled; } private CellSet seedFillOld(Cell seed, char newChar){ CellSet cellsFilled = new CellSet(); char oldChar = get(seed); - + if(oldChar == newChar) return cellsFilled; if(isOutOfBounds(seed)) return cellsFilled; Stack stack = new Stack(); stack.push(seed); - + while(!stack.isEmpty()){ Cell cell = (Cell) stack.pop(); - + set(cell, newChar); cellsFilled.add(cell); @@ -1372,22 +1372,22 @@ private CellSet seedFillOld(Cell seed, char newChar){ Cell sCell = cell.getSouth(); Cell eCell = cell.getEast(); Cell wCell = cell.getWest(); - + if(get(nCell) == oldChar) stack.push(nCell); if(get(sCell) == oldChar) stack.push(sCell); if(get(eCell) == oldChar) stack.push(eCell); if(get(wCell) == oldChar) stack.push(wCell); } - + return cellsFilled; } /** - * + * * Locates and returns the '*' boundaries that we would - * encounter if we did a flood-fill at seed. - * + * encounter if we did a flood-fill at seed. + * * @param seed * @return */ @@ -1402,48 +1402,48 @@ public CellSet findBoundariesExpandingFrom(Cell seed){ Stack stack = new Stack(); stack.push(seed); - + while(!stack.isEmpty()){ Cell cell = (Cell) stack.pop(); - + set(cell, newChar); Cell nCell = cell.getNorth(); Cell sCell = cell.getSouth(); Cell eCell = cell.getEast(); Cell wCell = cell.getWest(); - + if(get(nCell) == oldChar) stack.push(nCell); else if(get(nCell) == '*') boundaries.add(nCell); - + if(get(sCell) == oldChar) stack.push(sCell); else if(get(sCell) == '*') boundaries.add(sCell); - + if(get(eCell) == oldChar) stack.push(eCell); else if(get(eCell) == '*') boundaries.add(eCell); - + if(get(wCell) == oldChar) stack.push(wCell); else if(get(wCell) == '*') boundaries.add(wCell); } - + return boundaries; } - - + + //TODO: incomplete method seedFillLine() private CellSet seedFillLine(Cell cell, char newChar){ CellSet cellsFilled = new CellSet(); - + Stack stack = new Stack(); - + char oldChar = get(cell); - + if(oldChar == newChar) return cellsFilled; if(isOutOfBounds(cell)) return cellsFilled; - + stack.push(new LineSegment(cell.x, cell.x, cell.y, 1)); stack.push(new LineSegment(cell.x, cell.x, cell.y + 1, -1)); - + int left; while(!stack.isEmpty()){ LineSegment segment = (LineSegment) stack.pop(); @@ -1456,9 +1456,9 @@ private CellSet seedFillLine(Cell cell, char newChar){ set(x, segment.y, newChar); cellsFilled.add(new Cell(x, segment.y)); } - + left = cell.getEast().x; - boolean skip = (x > segment.x1)? true : false; + boolean skip = (x > segment.x1)? true : false; if(left < segment.x1){ //leak on left? //TODO: i think the first param should be x @@ -1474,13 +1474,13 @@ private CellSet seedFillLine(Cell cell, char newChar){ set(x, segment.y, newChar); cellsFilled.add(new Cell(x, segment.y)); } - + stack.push(new LineSegment(left, x - 1, segment.y, segment.dy)); if(x > segment.x2 + 1) //leak on right? stack.push(new LineSegment(segment.x2 + 1, x - 1, segment.y, -segment.dy)); } skip = false; //skip only once - + for(++x; x <= segment.x2 && get(x, segment.y) != oldChar; ++x){;} left = x; } while( x < segment.x2); @@ -1488,7 +1488,7 @@ private CellSet seedFillLine(Cell cell, char newChar){ return cellsFilled; } - + public boolean cellContainsDashedLineChar(Cell cell){ char c = get(cell); return StringUtils.isOneOf(c, dashedLines); @@ -1503,7 +1503,7 @@ public boolean loadFrom(String filename) public boolean loadFrom(String filename, ProcessingOptions options) throws IOException { - + String encoding = (options == null) ? null : options.getCharacterEncoding(); ArrayList lines = new ArrayList(); InputStream is; @@ -1514,7 +1514,7 @@ public boolean loadFrom(String filename, ProcessingOptions options) String[] linesArray = FileUtils.readFile(is, filename, encoding).split("(\r)?\n"); for(int i = 0; i < linesArray.length; i++) lines.add(new StringBuilder(linesArray[i])); - + return initialiseWithLines(lines, options); } @@ -1546,15 +1546,21 @@ public boolean initialiseWithLines(ArrayList lines, ProcessingOpt // make all lines of equal length // add blank outline around the buffer to prevent fill glitch // convert tabs to spaces (or remove them if setting is 0) - - int blankBorderSize = 2; - + + int maxLength = 0; int index = 0; - + + // Changed from original hardcoded value of 2. Do not make 0 as that + // breaks TextGrid intersection code (and I'm too lazy to fix that) + // - APN + int blankBorderSize; + if(options != null) blankBorderSize = options.getBorderWidth(); + else blankBorderSize = options.DEFAULT_BORDER_WIDTH; + String encoding = null; if(options != null) encoding = options.getCharacterEncoding(); - + Iterator it = rows.iterator(); while(it.hasNext()){ String row = it.next().toString(); @@ -1569,41 +1575,41 @@ public boolean initialiseWithLines(ArrayList lines, ProcessingOpt it = rows.iterator(); ArrayList newRows = new ArrayList(); - //TODO: make the following depend on blankBorderSize - + StringBuilder topBottomRow = new StringBuilder(StringUtils.repeatString(" ", maxLength + blankBorderSize * 2)); - - newRows.add(topBottomRow); - newRows.add(topBottomRow); + String borderString = StringUtils.repeatString(" ", blankBorderSize); + + for (i = 0; i < blankBorderSize; i++) { + newRows.add(topBottomRow); + } while(it.hasNext()){ StringBuilder row = it.next(); - + if(row.length() < maxLength) { - String borderString = StringUtils.repeatString(" ", blankBorderSize); StringBuilder newRow = new StringBuilder(); - + newRow.append(borderString); newRow.append(row); newRow.append(StringUtils.repeatString(" ", maxLength - row.length())); newRow.append(borderString); - + newRows.add(newRow); - } else { //TODO: why is the following line like that? - newRows.add(new StringBuilder(" ").append(row).append(" ")); + } else { + newRows.add(new StringBuilder().append(borderString).append(row).append(borderString)); } } - //TODO: make the following depend on blankBorderSize - newRows.add(topBottomRow); - newRows.add(topBottomRow); + for (i = 0; i < blankBorderSize; i++) { + newRows.add(topBottomRow); + } rows = newRows; - + replaceBullets(); replaceHumanColorCodes(); - + return true; } - + private void fixTabs(int tabSize){ int rowIndex = 0; @@ -1612,7 +1618,7 @@ private void fixTabs(int tabSize){ while(it.hasNext()){ String row = it.next().toString(); StringBuilder newRow = new StringBuilder(); - + char[] chars = row.toCharArray(); for(int i = 0; i < chars.length; i++){ if(chars[i] == '\t'){ @@ -1631,14 +1637,14 @@ private void fixTabs(int tabSize){ rowIndex++; } } - + /** * @return */ protected ArrayList getRows() { return rows; } - + public class CellColorPair{ public CellColorPair(Cell cell, Color color){ this.cell = cell; @@ -1666,20 +1672,20 @@ public CellTagPair(Cell cell, String tag){ public String tag; } - + public class Cell{ public int x, y; - + public Cell(Cell cell){ this(cell.x, cell.y); } - + public Cell(int x, int y){ this.x = x; this.y = y; } - + public Cell getNorth(){ return new Cell(x, y - 1); } public Cell getSouth(){ return new Cell(x, y + 1); } public Cell getEast(){ return new Cell(x + 1, y); } @@ -1745,32 +1751,32 @@ public boolean equals(Object o){ if(x == cell.x && y == cell.y) return true; else return false; } - + public int hashCode() { return (x << 16) | y; } - + public boolean isNextTo(int x2, int y2){ if(Math.abs(x2 - x) == 1 && Math.abs(y2 - y) == 1) return false; if(Math.abs(x2 - x) == 1 && y2 == y) return true; if(Math.abs(y2 - y) == 1 && x2 == x) return true; return false; } - + public boolean isNextTo(Cell cell){ if(cell == null) throw new IllegalArgumentException("cell cannot be null"); return this.isNextTo(cell.x, cell.y); } - + public String toString(){ return "("+x+", "+y+")"; } - + public void scale(int s){ x = x * s; y = y * s; } - + } private class LineSegment{