summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJovansonlee Cesar <ivanceras@gmail.com>2020-02-14 18:05:20 +0800
committerGitHub <noreply@github.com>2020-02-14 18:05:20 +0800
commitef274b7941d3705f93efb97e4f5da92012d9ccd2 (patch)
tree4e08e7115c235e0d4e4a9272d3dbbeb1e5b50613
parent049dcb0ddf4826eb69a6884e7d92efdce0e60c4f (diff)
parentf8d41a7d19447e46b6c5cf6f6e93c4a09203c48f (diff)
Merge pull request #48 from ivanceras/rewrite3-vectorize
This is the 3rd major rewrite of the core architecture of svgbob. This provides major improvements in terms of performance, extensibility and modular design.
-rw-r--r--.gitignore1
-rw-r--r--Architecture.md736
-rw-r--r--Cargo.lock491
-rw-r--r--Cargo.toml5
-rw-r--r--README.md342
-rw-r--r--deny.toml191
-rw-r--r--screenshots/vim.svg538
-rw-r--r--svgbob/Behavior.md (renamed from Behavior.md)0
-rw-r--r--svgbob/Cargo.lock900
-rw-r--r--svgbob/Cargo.toml13
-rw-r--r--svgbob/Changelog.md8
-rw-r--r--svgbob/TODO.md (renamed from TODO.md)0
-rw-r--r--svgbob/concepts.md11
-rw-r--r--svgbob/examples/circuits.rs20
-rw-r--r--svgbob/examples/circuits.svg334
-rw-r--r--svgbob/examples/demo.bob296
-rw-r--r--svgbob/examples/demo.rs19
-rw-r--r--svgbob/examples/demo.svg4601
-rw-r--r--svgbob/examples/grid.rs8
-rw-r--r--svgbob/examples/issue19.rs25
-rw-r--r--svgbob/examples/issue19.svg66
-rw-r--r--svgbob/examples/issue25.rs25
-rw-r--r--svgbob/examples/issue25.svg42
-rw-r--r--svgbob/examples/long.rs20
-rw-r--r--svgbob/examples/long.svg21170
-rw-r--r--svgbob/examples/simple.rs12
-rw-r--r--svgbob/examples/spec1.rs17
-rw-r--r--svgbob/examples/spec1.svg45
-rwxr-xr-xsvgbob/run_demo.sh1
-rwxr-xr-xsvgbob/run_long.sh1
-rwxr-xr-xsvgbob/run_simple.sh1
-rwxr-xr-xsvgbob/run_svg_to_ascii.sh1
-rw-r--r--svgbob/spec.md (renamed from spec.md)0
-rw-r--r--svgbob/src/block.rs31
-rw-r--r--svgbob/src/box_drawing.rs225
-rw-r--r--svgbob/src/buffer.rs9
-rw-r--r--svgbob/src/buffer/cell_buffer.rs531
-rw-r--r--svgbob/src/buffer/cell_buffer/cell.rs472
-rw-r--r--svgbob/src/buffer/cell_buffer/cell/cell_grid.rs210
-rw-r--r--svgbob/src/buffer/cell_buffer/contacts.rs78
-rw-r--r--svgbob/src/buffer/cell_buffer/endorse.rs216
-rw-r--r--svgbob/src/buffer/cell_buffer/settings.rs40
-rw-r--r--svgbob/src/buffer/cell_buffer/span.rs630
-rw-r--r--svgbob/src/buffer/fragment_buffer.rs177
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment.rs747
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment/arc.rs273
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment/circle.rs102
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment/line.rs770
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment/marker_line.rs185
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment/polygon.rs183
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment/rect.rs158
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment/text.rs310
-rw-r--r--svgbob/src/buffer/fragment_buffer/fragment_tree.rs238
-rw-r--r--svgbob/src/buffer/property_buffer.rs359
-rw-r--r--svgbob/src/buffer/property_buffer/property.rs309
-rw-r--r--svgbob/src/buffer/string_buffer.rs107
-rw-r--r--svgbob/src/element.rs360
-rw-r--r--svgbob/src/enhance.rs380
-rw-r--r--svgbob/src/enhance_circle.rs583
-rw-r--r--svgbob/src/focus_char.rs431
-rw-r--r--svgbob/src/fragments.rs60
-rw-r--r--svgbob/src/grid.rs646
-rw-r--r--svgbob/src/lib.rs90
-rw-r--r--svgbob/src/loc.rs150
-rw-r--r--svgbob/src/loc_block.rs231
-rw-r--r--svgbob/src/location.rs165
-rw-r--r--svgbob/src/map.rs6
-rw-r--r--svgbob/src/map/ascii_map.rs1027
-rw-r--r--svgbob/src/map/circle_map.rs482
-rw-r--r--svgbob/src/map/unicode_map.rs346
-rw-r--r--svgbob/src/optimizer.rs198
-rw-r--r--svgbob/src/options.rs18
-rw-r--r--svgbob/src/point.rs140
-rw-r--r--svgbob/src/point_block.rs48
-rw-r--r--svgbob/src/properties.rs1750
-rw-r--r--svgbob/src/settings.rs49
-rw-r--r--svgbob/src/svg_element.rs23
-rw-r--r--svgbob/src/tests.rs116
-rw-r--r--svgbob/src/util.rs433
-rwxr-xr-xsvgbob/test.sh1
-rw-r--r--svgbob/test_data/circuits.bob (renamed from svgbob/examples/circuits.bob)0
-rw-r--r--svgbob/test_data/demo.bob965
-rw-r--r--svgbob/test_data/long.bob (renamed from svgbob/examples/long.bob)669
-rw-r--r--svgbob/test_data/simple.bob57
-rw-r--r--svgbob_cli/Cargo.lock873
-rw-r--r--svgbob_cli/Cargo.toml12
-rw-r--r--svgbob_cli/examples/ascii_art.bob267
-rw-r--r--svgbob_cli/examples/ascii_art.rs36
-rw-r--r--svgbob_cli/examples/comic.bob33
-rw-r--r--svgbob_cli/examples/comic.rs33
-rw-r--r--svgbob_cli/examples/demo.rs129
-rw-r--r--svgbob_cli/examples/demo.svg330
-rw-r--r--svgbob_cli/examples/demo_clean.svg1
-rw-r--r--svgbob_cli/examples/long.bob472
-rwxr-xr-xsvgbob_cli/examples/long.sh2
-rw-r--r--svgbob_cli/examples/long.svg3871
-rw-r--r--svgbob_cli/examples/memes.bob570
-rw-r--r--svgbob_cli/examples/memes2.bob450
-rw-r--r--svgbob_cli/examples/memes2.rs33
-rw-r--r--svgbob_cli/examples/memes3.bob436
-rw-r--r--svgbob_cli/examples/memes3.rs33
-rw-r--r--svgbob_cli/examples/nice_to_have.bob63
-rw-r--r--svgbob_cli/examples/render.rs33
-rw-r--r--svgbob_cli/examples/schematic.bob609
-rw-r--r--svgbob_cli/examples/schematic.svg2717
-rw-r--r--svgbob_cli/examples/simple.rs10
-rw-r--r--svgbob_cli/src/main.rs33
107 files changed, 13042 insertions, 43728 deletions
diff --git a/.gitignore b/.gitignore
index 2b2b90f..9be293f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,6 +7,7 @@ public/
parts/
prime/
snap/
+**/out/*
stage/
*.snap*
*.tar*
diff --git a/Architecture.md b/Architecture.md
new file mode 100644
index 0000000..1ec10b6
--- /dev/null
+++ b/Architecture.md
@@ -0,0 +1,736 @@
+# Svgbob Architecture and Design phases
+
+Svgbob creates an svg drawing based on the input ascii art diagrams.
+It achieves this by creating a corresponding fragment for each character, and then this little fragments
+are then merged to form lines and arcs. The lines and arcs are then endorsed into high level shapes such as rect, circles.
+
+### Name inspiration:
+- svg for svg document and drawing.
+- bob for Alice and Bob as common characters in most diagrams
+ Bob Ross - a painter who like to draws happy little trees.
+
+### Library used
+- [nalgebra](https://www.nalgebra.org/) and [ncollide2d](https://ncollide.org/) for geometric function calculations such as calculating whether lines are intersecting, collinear. Computing the clipping of lines and boxes.
+- [pom](https://github.com/J-F-Liu/pom) for parsing the styling directives(Legend) at the bottom of the document
+- [sauron](https://github.com/ivanceras/sauron) for building the svg document object tree.
+
+
+### **Iterations, re-architecture rewrites**
+
+#### Phase 1
+Exploding if statements. This was in elm
+ [fullcode](https://github.com/ivanceras/elm-examples/blob/master/elm-bot-lines/Grid.elm)
+
+```elm
+getElement x y model =
+ let
+ char = get x y model
+ in
+ case char of
+ Just char ->
+ if isVertical char
+ && not (isNeighbor left isAlphaNumeric)
+ && not (isNeighbor right isAlphaNumeric) then
+ Just Vertical
+ else if isHorizontal char
+ && not (isNeighbor left isAlphaNumeric)
+ && not (isNeighbor right isAlphaNumeric) then
+ Just Horizontal
+ else if isIntersection char then
+ let
+ isVerticalJunctionLeft =
+ isNeighbor top isVertical
+ && isNeighbor(bottomOf x y model) isVertical
+ && isNeighbor(leftOf x y model) isHorizontal
+
+ isVerticalJunctionRight =
+ isNeighbor top isVertical
+ && isNeighbor bottom isVertical
+ && isNeighbor right isHorizontal
+
+ isHorizontalJunctionTop =
+ isNeighbor left isHorizontal
+ && isNeighbor right isHorizontal
+ && isNeighbor top isVertical
+
+ isHorizontalJunctionBot =
+ isNeighbor left isHorizontal
+ && isNeighbor right isHorizontal
+ && isNeighbor bottom isVertical
+
+ isTopLeftIntersection =
+ isNeighbor bottom isVertical && isNeighbor right isHorizontal
+
+ isTopRightIntersection =
+ isNeighbor bottom isVertical && isNeighbor left isHorizontal
+
+ isBottomRightIntersection =
+ isNeighbor top isVertical && isNeighbor left isHorizontal
+
+ isBottomLeftIntersection =
+ isNeighbor top isVertical && isNeighbor right isHorizontal
+
+ isCrossIntersection =
+ isNeighbor top isVertical
+ && isNeighbor bottom isVertical
+ && isNeighbor left isHorizontal
+ && isNeighbor right isHorizontal
+
+ ... 200 more lines...
+
+```
+Though elm is fast, but if you throw a lot of conditional branching to it, it will slow it down.
+At least I don't get to have runtime errors here if it was written in js.
+Adding an edgecase is just appending a new if else statement at the bottom of the statements.
+
+**Pros:** Very simple design. Just if statements and return the appropriate shape the character will take form
+ Adding edge case behaviour is just appending an `else if` to the nearest conditional(`if`) behavior.
+
+**Caveats:** The fragments/drawing elements are named. Naming is hard, we can not name all of them. Consistency is broken.
+
+
+
+
+#### Phase2:
+Now in rust. The character behavior is stored in a `Vec<(condition, drawing_elements)>`
+This is already close to the current architecture.
+
+ **Improvements:**
+ - Runs a lot faster than elm. Converting the code from elm to rust, accelerate my learning of the usage of functional programming in rust.
+ - Consumed elements, if certain group of elements matches a higher level shapes, those elements are consumed/remove from the grid to
+ avoid generating additional drawing elements when iterated with the rest of the characters in the grid.
+
+
+```rust
+ //get the paths in the location x,y
+ //if non path, then see if it can return a text path
+ fn get_elements(&self, x:isize, y:isize, settings: &Settings) -> Option<Vec<Element>>{
+ ...
+ //common path lines
+ let vertical = Element::solid_line(center_top, center_bottom);
+ let horizontal = Element::solid_line(mid_left, mid_right);
+ let slant_left = Element::solid_line(high_left, low_right);
+ let slant_right = Element::solid_line(low_left, high_right);
+ let low_horizontal = Element::solid_line(low_left, low_right);
+
+
+ let match_list: Vec<(bool, Vec<Element>)> =
+ vec![
+ /*
+ .-
+ |
+ */
+ (self.is_char(this, is_round)
+ && self.is_char(right, is_horizontal)
+ && self.is_char(bottom, is_vertical),
+ vec![cxdy_cxey.clone(), arc_excy_cxdy.clone()]
+ ),
+ /*
+ -.
+ |
+ */
+ (self.is_char(this, is_round)
+ && self.is_char(left, is_horizontal)
+ && self.is_char(bottom, is_vertical),
+ vec![cxdy_cxey.clone(), arc_cxdy_axcy.clone()]
+ ),
+ /*
+ |
+ '-
+ */
+ (self.is_char(this, is_round)
+ && self.is_char(right, is_horizontal)
+ && self.is_char(top, is_vertical),
+ vec![cxay_cxby.clone(), arc_cxby_excy.clone()]
+ ),
+ /*
+ |
+ -'
+ */
+ (self.is_char(this, is_round)
+ && self.is_char(left, is_horizontal)
+ && self.is_char(top, is_vertical),
+ vec![cxay_cxby.clone(), arc_axcy_cxby.clone()]
+ ),
+ /*
+ .-
+ /
+ */
+ (self.is_char(this, is_round)
+ && self.is_char(right, is_horizontal)
+ && self.is_char(bottom_left, is_slant_right),
+ vec![axey_bxdy.clone(), arc_excy_bxdy.clone()]
+ ),
+ /*
+ -.
+ \
+ */
+ (self.is_char(this, is_round)
+ && self.is_char(left, is_horizontal)
+ && self.is_char(bottom_right, is_slant_left),
+ v