From 80d30d8b2d7d58fcec2f31b71b424c9ae7648d3f Mon Sep 17 00:00:00 2001 From: Dimitry Ivanov Date: Thu, 25 May 2017 14:08:09 +0300 Subject: [PATCH] Working tables span --- .../renderer/SpannableMarkdownVisitor.java | 9 +- .../noties/markwon/spans/SpannableTheme.java | 83 ++++++++++++++++++- .../ru/noties/markwon/spans/TableRowSpan.java | 45 +++++++++- 3 files changed, 129 insertions(+), 8 deletions(-) diff --git a/library-renderer/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java b/library-renderer/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java index ba64fdf9..8ac89cb0 100644 --- a/library-renderer/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java +++ b/library-renderer/src/main/java/ru/noties/markwon/renderer/SpannableMarkdownVisitor.java @@ -306,6 +306,8 @@ public class SpannableMarkdownVisitor extends AbstractVisitor { if (pendingTableRow != null) { builder.append(' '); + Debug.i("adding a row: %d", tableRows); + final TableRowSpan span = new TableRowSpan( configuration.theme(), pendingTableRow, @@ -313,6 +315,10 @@ public class SpannableMarkdownVisitor extends AbstractVisitor { tableRows % 2 == 1 ); + tableRows = tableRowIsHeader + ? 0 + : tableRows + 1; + setSpan(length, span); newLine(); pendingTableRow = null; @@ -334,9 +340,6 @@ public class SpannableMarkdownVisitor extends AbstractVisitor { builder.replace(length, builder.length(), ""); tableRowIsHeader = cell.isHeader(); - tableRows = tableRowIsHeader - ? 0 - : tableRows + 1; handled = true; } else { diff --git a/library-renderer/src/main/java/ru/noties/markwon/spans/SpannableTheme.java b/library-renderer/src/main/java/ru/noties/markwon/spans/SpannableTheme.java index b8e4bfa6..d1ae16bc 100644 --- a/library-renderer/src/main/java/ru/noties/markwon/spans/SpannableTheme.java +++ b/library-renderer/src/main/java/ru/noties/markwon/spans/SpannableTheme.java @@ -44,7 +44,9 @@ public class SpannableTheme { .blockMargin(px.px(24)) .bulletListItemStrokeWidth(px.px(1)) .headingBreakHeight(px.px(1)) - .thematicBreakHeight(px.px(2)); + .thematicBreakHeight(px.px(2)) + .tableCellPadding(px.px(4)) + .tableBorderWidth(px.px(1)); } private static int resolve(Context context, @AttrRes int attr) { @@ -75,6 +77,10 @@ public class SpannableTheme { protected static final int THEMATIC_BREAK_DEF_ALPHA = 75; + protected static final int TABLE_BORDER_DEF_ALPHA = 75; + + protected static final int TABLE_ODD_ROW_DEF_ALPHA = 22; + protected final int linkColor; // used in quote, lists @@ -127,6 +133,17 @@ public class SpannableTheme { // by default paint.strokeWidth protected final int thematicBreakHeight; + // by default 0 + protected final int tableCellPadding; + + // by default paint.color * TABLE_BORDER_DEF_ALPHA + protected final int tableBorderColor; + + protected final int tableBorderWidth; + + // by default paint.color * TABLE_ODD_ROW_DEF_ALPHA + protected final int tableOddRowBackgroundColor; + protected SpannableTheme(@NonNull Builder builder) { this.linkColor = builder.linkColor; this.blockMargin = builder.blockMargin; @@ -145,6 +162,10 @@ public class SpannableTheme { this.scriptTextSizeRatio = builder.scriptTextSizeRatio; this.thematicBreakColor = builder.thematicBreakColor; this.thematicBreakHeight = builder.thematicBreakHeight; + this.tableCellPadding = builder.tableCellPadding; + this.tableBorderColor = builder.tableBorderColor; + this.tableBorderWidth = builder.tableBorderWidth; + this.tableOddRowBackgroundColor = builder.tableOddRowBackgroundColor; } @@ -307,6 +328,38 @@ public class SpannableTheme { } } + public int tableCellPadding() { + return tableCellPadding; + } + + public void applyTableBorderStyle(@NonNull Paint paint) { + + final int color; + if (tableBorderColor == 0) { + color = ColorUtils.applyAlpha(paint.getColor(), TABLE_BORDER_DEF_ALPHA); + } else { + color = tableBorderColor; + } + + if (tableBorderWidth != 0) { + paint.setStrokeWidth(tableBorderWidth); + } + + paint.setColor(color); + paint.setStyle(Paint.Style.STROKE); + } + + public void applyTableOddRowStyle(@NonNull Paint paint) { + final int color; + if (tableOddRowBackgroundColor == 0) { + color = ColorUtils.applyAlpha(paint.getColor(), TABLE_ODD_ROW_DEF_ALPHA); + } else { + color = tableOddRowBackgroundColor; + } + paint.setColor(color); + paint.setStyle(Paint.Style.FILL); + } + public static class Builder { private int linkColor; @@ -326,6 +379,10 @@ public class SpannableTheme { private float scriptTextSizeRatio; private int thematicBreakColor; private int thematicBreakHeight; + private int tableCellPadding; + private int tableBorderColor; + private int tableBorderWidth; + private int tableOddRowBackgroundColor; Builder() { @@ -350,6 +407,10 @@ public class SpannableTheme { this.scriptTextSizeRatio = theme.scriptTextSizeRatio; this.thematicBreakColor = theme.thematicBreakColor; this.thematicBreakHeight = theme.thematicBreakHeight; + this.tableCellPadding = theme.tableCellPadding; + this.tableBorderColor = theme.tableBorderColor; + this.tableBorderWidth = theme.tableBorderWidth; + this.tableOddRowBackgroundColor = theme.tableOddRowBackgroundColor; } public Builder linkColor(int linkColor) { @@ -437,6 +498,26 @@ public class SpannableTheme { return this; } + public Builder tableCellPadding(int tableCellPadding) { + this.tableCellPadding = tableCellPadding; + return this; + } + + public Builder tableBorderColor(int tableBorderColor) { + this.tableBorderColor = tableBorderColor; + return this; + } + + public Builder tableBorderWidth(int tableBorderWidth) { + this.tableBorderWidth = tableBorderWidth; + return this; + } + + public Builder tableOddRowBackgroundColor(int tableOddRowBackgroundColor) { + this.tableOddRowBackgroundColor = tableOddRowBackgroundColor; + return this; + } + public SpannableTheme build() { return new SpannableTheme(this); } diff --git a/library-renderer/src/main/java/ru/noties/markwon/spans/TableRowSpan.java b/library-renderer/src/main/java/ru/noties/markwon/spans/TableRowSpan.java index f5fc26f4..7a70d601 100644 --- a/library-renderer/src/main/java/ru/noties/markwon/spans/TableRowSpan.java +++ b/library-renderer/src/main/java/ru/noties/markwon/spans/TableRowSpan.java @@ -2,6 +2,7 @@ package ru.noties.markwon.spans; import android.graphics.Canvas; import android.graphics.Paint; +import android.graphics.Rect; import android.support.annotation.IntDef; import android.support.annotation.IntRange; import android.support.annotation.NonNull; @@ -16,6 +17,8 @@ import java.lang.annotation.RetentionPolicy; import java.util.ArrayList; import java.util.List; +import ru.noties.debug.Debug; + public class TableRowSpan extends ReplacementSpan { public static final int ALIGN_LEFT = 0; @@ -66,6 +69,9 @@ public class TableRowSpan extends ReplacementSpan { private final boolean header; private final boolean odd; + private final Rect rect = ObjectsPool.rect(); + private final Paint paint = ObjectsPool.paint(); + private int width; private int height; private Invalidator invalidator; @@ -106,9 +112,13 @@ public class TableRowSpan extends ReplacementSpan { } } + // we store actual height height = max; - fm.ascent = -max; + // but apply height with padding + final int padding = theme.tableCellPadding() * 2; + + fm.ascent = -(max + padding); fm.descent = 0; fm.top = fm.ascent; @@ -139,13 +149,38 @@ public class TableRowSpan extends ReplacementSpan { int maxHeight = 0; + final int padding = theme.tableCellPadding(); + + final int size = layouts.size(); + + final int w = width / size; + + if (odd) { + final int save = canvas.save(); + try { + rect.set(0, 0, width, bottom - top); + theme.applyTableOddRowStyle(this.paint); + canvas.translate(x, top); + canvas.drawRect(rect, this.paint); + } finally { + canvas.restoreToCount(save); + } + } + + rect.set(0, 0, w, bottom - top); + + theme.applyTableBorderStyle(this.paint); + StaticLayout layout; - for (int i = 0, size = layouts.size(); i < size; i++) { + for (int i = 0; i < size; i++) { layout = layouts.get(i); final int save = canvas.save(); try { - canvas.translate(x + (i * layout.getWidth()), top); + canvas.translate(x + (i * w), top); + canvas.drawRect(rect, this.paint); + + canvas.translate(padding, padding); layout.draw(canvas); if (layout.getHeight() > maxHeight) { @@ -174,7 +209,9 @@ public class TableRowSpan extends ReplacementSpan { textPaint.setFakeBoldText(true); } - final int w = width / cells.size(); + final int columns = cells.size(); + final int padding = theme.tableCellPadding() * 2; + final int w = (width / columns) - padding; this.layouts.clear(); Cell cell;