Better default values + ObjectsPool
This commit is contained in:
		
							parent
							
								
									6f5fd08de4
								
							
						
					
					
						commit
						d280095281
					
				| @ -7,6 +7,7 @@ import ru.noties.markwon.spans.BlockQuoteSpan; | ||||
| import ru.noties.markwon.spans.BulletListItemSpan; | ||||
| import ru.noties.markwon.spans.CodeSpan; | ||||
| import ru.noties.markwon.spans.HeadingSpan; | ||||
| import ru.noties.markwon.spans.ThematicBreakSpan; | ||||
| 
 | ||||
| public class SpannableConfiguration { | ||||
| 
 | ||||
| @ -23,12 +24,14 @@ public class SpannableConfiguration { | ||||
|     private final CodeSpan.Config codeConfig; | ||||
|     private final BulletListItemSpan.Config bulletListConfig; | ||||
|     private final HeadingSpan.Config headingConfig; | ||||
|     private final ThematicBreakSpan.Config thematicConfig; | ||||
| 
 | ||||
|     private SpannableConfiguration(Builder builder) { | ||||
|         this.blockQuoteConfig = builder.blockQuoteConfig; | ||||
|         this.codeConfig = builder.codeConfig; | ||||
|         this.bulletListConfig = builder.bulletListConfig; | ||||
|         this.headingConfig = builder.headingConfig; | ||||
|         this.thematicConfig = builder.thematicConfig; | ||||
|     } | ||||
| 
 | ||||
|     public BlockQuoteSpan.Config getBlockQuoteConfig() { | ||||
| @ -47,6 +50,10 @@ public class SpannableConfiguration { | ||||
|         return headingConfig; | ||||
|     } | ||||
| 
 | ||||
|     public ThematicBreakSpan.Config getThematicConfig() { | ||||
|         return thematicConfig; | ||||
|     } | ||||
| 
 | ||||
|     public static class Builder { | ||||
| 
 | ||||
|         private final Context context; | ||||
| @ -54,6 +61,7 @@ public class SpannableConfiguration { | ||||
|         private CodeSpan.Config codeConfig; | ||||
|         private BulletListItemSpan.Config bulletListConfig; | ||||
|         private HeadingSpan.Config headingConfig; | ||||
|         private ThematicBreakSpan.Config thematicConfig; | ||||
| 
 | ||||
|         public Builder(Context context) { | ||||
|             this.context = context; | ||||
| @ -79,13 +87,18 @@ public class SpannableConfiguration { | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public Builder setThematicConfig(@NonNull ThematicBreakSpan.Config thematicConfig) { | ||||
|             this.thematicConfig = thematicConfig; | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         // todo, change to something more reliable | ||||
|         public SpannableConfiguration build() { | ||||
|             if (blockQuoteConfig == null) { | ||||
|                 blockQuoteConfig = new BlockQuoteSpan.Config( | ||||
|                         px(16), | ||||
|                         px(4), | ||||
|                         0xFFcccccc | ||||
|                         0, | ||||
|                         0 | ||||
|                 ); | ||||
|             } | ||||
|             if (codeConfig == null) { | ||||
| @ -99,6 +112,9 @@ public class SpannableConfiguration { | ||||
|             if (headingConfig == null) { | ||||
|                 headingConfig = new HeadingSpan.Config(px(1), 0); | ||||
|             } | ||||
|             if (thematicConfig == null) { | ||||
|                 thematicConfig = new ThematicBreakSpan.Config(0, px(2)); | ||||
|             } | ||||
|             return new SpannableConfiguration(this); | ||||
|         } | ||||
| 
 | ||||
|  | ||||
| @ -194,10 +194,9 @@ public class SpannableMarkdownVisitor extends AbstractVisitor { | ||||
| 
 | ||||
|         newLine(); | ||||
| 
 | ||||
|         // todo, new lines... | ||||
|         final int length = builder.length(); | ||||
|         builder.append(' '); // without space it won't render | ||||
|         builder.setSpan(new ThematicBreakSpan(), length, builder.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); | ||||
|         setSpan(length, new ThematicBreakSpan(configuration.getThematicConfig())); | ||||
| 
 | ||||
|         newLine(); | ||||
|     } | ||||
|  | ||||
| @ -11,15 +11,17 @@ import android.text.style.LeadingMarginSpan; | ||||
| 
 | ||||
| public class BlockQuoteSpan implements LeadingMarginSpan { | ||||
| 
 | ||||
|     private static final int DEF_COLOR_ALPHA = 50; | ||||
| 
 | ||||
|     @SuppressWarnings("WeakerAccess") | ||||
|     public static class Config { | ||||
| 
 | ||||
|         final int totalWidth; | ||||
|         final int quoteWidth; | ||||
|         final int quoteColor; // by default textColor with 0.1 alpha | ||||
|         final int quoteWidth; // by default 1/4 of width | ||||
|         final int quoteColor; // by default textColor with 0.2 alpha | ||||
| 
 | ||||
|         public Config( | ||||
|                 @IntRange(from = 0) int totalWidth, | ||||
|                 @IntRange(from = 1) int totalWidth, | ||||
|                 @IntRange(from = 0) int quoteWidth, | ||||
|                 @ColorInt int quoteColor) { | ||||
|             this.totalWidth = totalWidth; | ||||
| @ -29,16 +31,13 @@ public class BlockQuoteSpan implements LeadingMarginSpan { | ||||
|     } | ||||
| 
 | ||||
|     private final Config config; | ||||
|     private final Rect rect = new Rect(); | ||||
|     private final Paint paint = new Paint(); | ||||
|     private final Rect rect = ObjectsPool.rect(); | ||||
|     private final Paint paint = ObjectsPool.paint(); | ||||
|     private final int indent; | ||||
| 
 | ||||
|     public BlockQuoteSpan(@NonNull Config config, int indent) { | ||||
|         this.config = config; | ||||
|         this.indent = indent; | ||||
| 
 | ||||
|         paint.setStyle(Paint.Style.FILL); | ||||
|         paint.setColor(config.quoteColor); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
| @ -61,13 +60,25 @@ public class BlockQuoteSpan implements LeadingMarginSpan { | ||||
|             boolean first, | ||||
|             Layout layout) { | ||||
| 
 | ||||
|         final int save = c.save(); | ||||
|         try { | ||||
|             final int left = config.totalWidth * (indent - 1); | ||||
|             rect.set(left, top, left + config.quoteWidth, bottom); | ||||
|             c.drawRect(rect, paint); | ||||
|         } finally { | ||||
|             c.restoreToCount(save); | ||||
|         final int width; | ||||
|         if (config.quoteWidth == 0) { | ||||
|             width = (int) (config.totalWidth / 4.F + .5F); | ||||
|         } else { | ||||
|             width = config.quoteWidth; | ||||
|         } | ||||
| 
 | ||||
|         final int color; | ||||
|         if (config.quoteColor != 0) { | ||||
|             color = config.quoteColor; | ||||
|         } else { | ||||
|             color = ColorUtils.applyAlpha(p.getColor(), DEF_COLOR_ALPHA); | ||||
|         } | ||||
|         paint.setStyle(Paint.Style.FILL); | ||||
|         paint.setColor(color); | ||||
| 
 | ||||
|         final int left = config.totalWidth * (indent - 1); | ||||
|         rect.set(left, top, left + width, bottom); | ||||
| 
 | ||||
|         c.drawRect(rect, paint); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -30,10 +30,10 @@ public class BulletListItemSpan implements LeadingMarginSpan { | ||||
|     } | ||||
| 
 | ||||
|     private final Config config; | ||||
|     private final Paint paint = new Paint(); | ||||
| 
 | ||||
|     private RectF circle; | ||||
|     private Rect rectangle; | ||||
|     private final Paint paint = ObjectsPool.paint(); | ||||
|     private final RectF circle = ObjectsPool.rectF(); | ||||
|     private final Rect rectangle = ObjectsPool.rect(); | ||||
| 
 | ||||
|     private final int blockIndent; | ||||
|     private final int level; | ||||
| @ -101,11 +101,6 @@ public class BulletListItemSpan implements LeadingMarginSpan { | ||||
|             if (level == 0 | ||||
|                     || level == 1) { | ||||
| 
 | ||||
|                 // ensure we have circle rectF | ||||
|                 if (circle == null) { | ||||
|                     circle = new RectF(); | ||||
|                 } | ||||
| 
 | ||||
|                 circle.set(l, t, r, b); | ||||
| 
 | ||||
|                 final Paint.Style style = level == 0 | ||||
| @ -116,11 +111,6 @@ public class BulletListItemSpan implements LeadingMarginSpan { | ||||
|                 c.drawOval(circle, paint); | ||||
|             } else { | ||||
| 
 | ||||
|                 // ensure rectangle | ||||
|                 if (rectangle == null) { | ||||
|                     rectangle = new Rect(); | ||||
|                 } | ||||
| 
 | ||||
|                 rectangle.set(l, t, r, b); | ||||
| 
 | ||||
|                 paint.setStyle(Paint.Style.FILL); | ||||
|  | ||||
| @ -14,14 +14,7 @@ import android.text.style.MetricAffectingSpan; | ||||
| 
 | ||||
| public class CodeSpan extends MetricAffectingSpan implements LeadingMarginSpan { | ||||
| 
 | ||||
|     // the thing is.. we cannot use replacementSpan, because it won't let us create multiline code.. | ||||
|     // and we want new lines when we do not fit the width | ||||
|     // plus it complicates the copying | ||||
| 
 | ||||
|     // replacement span is great because we can have additional paddings & can actually get a hold | ||||
|     // of Canvas to draw background, but it implies a lot of manual text handling | ||||
| 
 | ||||
|     // also, we can reuse Rect instance as long as we apply our dimensions in each draw call | ||||
|     private static final int DEF_COLOR_ALPHA = 25; | ||||
| 
 | ||||
|     @SuppressWarnings("WeakerAccess") | ||||
|     public static class Config { | ||||
| @ -87,17 +80,14 @@ public class CodeSpan extends MetricAffectingSpan implements LeadingMarginSpan { | ||||
|     } | ||||
| 
 | ||||
|     private final Config config; | ||||
|     private final Rect rect = new Rect(); | ||||
|     private final Paint paint = new Paint(); | ||||
|     private final Rect rect = ObjectsPool.rect(); | ||||
|     private final Paint paint = ObjectsPool.paint(); | ||||
| 
 | ||||
|     private final boolean multiline; | ||||
| 
 | ||||
|     public CodeSpan(@NonNull Config config, boolean multiline) { | ||||
|         this.config = config; | ||||
|         this.multiline = multiline; | ||||
| 
 | ||||
|         paint.setStyle(Paint.Style.FILL); | ||||
|         paint.setTypeface(config.typeface); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
| @ -111,7 +101,7 @@ public class CodeSpan extends MetricAffectingSpan implements LeadingMarginSpan { | ||||
|         if (!multiline) { | ||||
|             final int color; | ||||
|             if (config.backgroundColor == 0) { | ||||
|                 color = applyAlpha(ds.getColor(), 25); | ||||
|                 color = ColorUtils.applyAlpha(ds.getColor(), DEF_COLOR_ALPHA); | ||||
|             } else { | ||||
|                 color = config.backgroundColor; | ||||
|             } | ||||
| @ -141,167 +131,16 @@ public class CodeSpan extends MetricAffectingSpan implements LeadingMarginSpan { | ||||
| 
 | ||||
|             final int color; | ||||
|             if (config.backgroundColor == 0) { | ||||
|                 color = applyAlpha(p.getColor(), 25); | ||||
|                 color = ColorUtils.applyAlpha(p.getColor(), DEF_COLOR_ALPHA); | ||||
|             } else { | ||||
|                 color = config.backgroundColor; | ||||
|             } | ||||
|             paint.setStyle(Paint.Style.FILL); | ||||
|             paint.setColor(color); | ||||
| 
 | ||||
|             rect.set(x, top, c.getWidth(), bottom); | ||||
| 
 | ||||
|             c.drawRect(rect, paint); | ||||
|         } | ||||
| 
 | ||||
| //        paint.setTextSize(p.getTextSize()); | ||||
| // | ||||
| //        final int left = (int) (x + .5F); | ||||
| // | ||||
| //        final int right; | ||||
| //        if (multiline) { | ||||
| //            right = c.getWidth(); | ||||
| //        } else { | ||||
| //            final int width = (config.paddingHorizontal * 2) + (int) (paint.measureText(text, start, end) + .5F); | ||||
| //            right = left + width; | ||||
| //        } | ||||
| // | ||||
| //        rect.set(left, top, right, bottom); | ||||
| // | ||||
| //        // okay, draw background first | ||||
| //        drawBackground(c); | ||||
| 
 | ||||
|         // then, if any, draw borders | ||||
| //        drawBorders(c, this.start == start, this.end == end); | ||||
| 
 | ||||
| //        final int color; | ||||
| //        if (config.textColor == 0) { | ||||
| //            color = p.getColor(); | ||||
| //        } else { | ||||
| //            color = config.textColor; | ||||
| //        } | ||||
| //        paint.setColor(color); | ||||
| // | ||||
| //        // draw text | ||||
| //        // y center position | ||||
| //        final int b = bottom - ((bottom - top) / 2) - (int) ((paint.descent() + paint.ascent()) / 2); | ||||
| //        canvas.drawText(text, start, end, x + config.paddingHorizontal, b, paint); | ||||
|     } | ||||
| 
 | ||||
|     private static int applyAlpha(int color, int alpha) { | ||||
|         return (color & 0x00FFFFFF) | (alpha << 24); | ||||
|     } | ||||
| 
 | ||||
| 
 | ||||
| //    @Override | ||||
| //    public int getSize( | ||||
| //            @NonNull Paint p, | ||||
| //            CharSequence text, | ||||
| //            @IntRange(from = 0) int start, | ||||
| //            @IntRange(from = 0) int end, | ||||
| //            @Nullable Paint.FontMetricsInt fm | ||||
| //    ) { | ||||
| // | ||||
| //        paint.setTextSize(p.getTextSize()); | ||||
| // | ||||
| //        final int width = (config.paddingHorizontal * 2) + (int) (paint.measureText(text, start, end) + .5F); | ||||
| // | ||||
| //        if (fm != null) { | ||||
| //            // we add a padding top & bottom | ||||
| //            final float ratio = .62F; // golden ratio, there is no much point of moving this to config... it seems a bit `specific`... | ||||
| //            fm.ascent = fm.ascent - (config.paddingVertical); | ||||
| //            fm.descent = (int) (-fm.ascent * ratio); | ||||
| //            fm.top = fm.ascent; | ||||
| //            fm.bottom = fm.descent; | ||||
| //        } | ||||
| // | ||||
| //        return width; | ||||
| //    } | ||||
| 
 | ||||
| //    @Override | ||||
| //    public void draw( | ||||
| //            @NonNull Canvas canvas, | ||||
| //            CharSequence text, | ||||
| //            @IntRange(from = 0) int start, | ||||
| //            @IntRange(from = 0) int end, | ||||
| //            float x, | ||||
| //            int top, | ||||
| //            int y, | ||||
| //            int bottom, | ||||
| //            @NonNull Paint p | ||||
| //    ) { | ||||
| // | ||||
| //        paint.setTextSize(p.getTextSize()); | ||||
| // | ||||
| //        final int left = (int) (x + .5F); | ||||
| // | ||||
| //        final int right; | ||||
| //        if (multiline) { | ||||
| //            right = canvas.getWidth(); | ||||
| //        } else { | ||||
| //            final int width = (config.paddingHorizontal * 2) + (int) (paint.measureText(text, start, end) + .5F); | ||||
| //            right = left + width; | ||||
| //        } | ||||
| // | ||||
| //        rect.set(left, top, right, bottom); | ||||
| // | ||||
| //        // okay, draw background first | ||||
| //        drawBackground(canvas); | ||||
| // | ||||
| //        // then, if any, draw borders | ||||
| //        drawBorders(canvas, this.start == start, this.end == end); | ||||
| // | ||||
| //        final int color; | ||||
| //        if (config.textColor == 0) { | ||||
| //            color = p.getColor(); | ||||
| //        } else { | ||||
| //            color = config.textColor; | ||||
| //        } | ||||
| //        paint.setColor(color); | ||||
| // | ||||
| //        // draw text | ||||
| //        // y center position | ||||
| //        final int b = bottom - ((bottom - top) / 2) - (int) ((paint.descent() + paint.ascent()) / 2); | ||||
| //        canvas.drawText(text, start, end, x + config.paddingHorizontal, b, paint); | ||||
| //    } | ||||
| 
 | ||||
| //    private void drawBackground(Canvas canvas) { | ||||
| //        final int color = config.backgroundColor; | ||||
| //        if (color != 0) { | ||||
| //            paint.setColor(color); | ||||
| //            canvas.drawRect(rect, paint); | ||||
| //        } | ||||
| //    } | ||||
| // | ||||
| //    private void drawBorders(Canvas canvas, boolean top, boolean bottom) { | ||||
| // | ||||
| //        final int color = config.borderColor; | ||||
| //        final int width = config.borderWidth; | ||||
| //        if (color == 0 | ||||
| //                || width == 0) { | ||||
| //            return; | ||||
| //        } | ||||
| // | ||||
| //        paint.setColor(color); | ||||
| // | ||||
| //        // left and right are always drawn | ||||
| // | ||||
| //        // LEFT | ||||
| //        borderRect.set(rect.left, rect.top, rect.left + width, rect.bottom); | ||||
| //        canvas.drawRect(borderRect, paint); | ||||
| // | ||||
| //        // RIGHT | ||||
| //        borderRect.set(rect.right - width, rect.top, rect.right, rect.bottom); | ||||
| //        canvas.drawRect(borderRect, paint); | ||||
| // | ||||
| //        // TOP | ||||
| //        if (top) { | ||||
| //            borderRect.set(rect.left, rect.top, rect.right, rect.top + width); | ||||
| //            canvas.drawRect(borderRect, paint); | ||||
| //        } | ||||
| // | ||||
| //        // BOTTOM | ||||
| //        if (bottom) { | ||||
| //            borderRect.set(rect.left, rect.bottom - width, rect.right, rect.bottom); | ||||
| //            canvas.drawRect(borderRect, paint); | ||||
| //        } | ||||
| //    } | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,11 @@ | ||||
| package ru.noties.markwon.spans; | ||||
| 
 | ||||
| class ColorUtils { | ||||
| 
 | ||||
|     static int applyAlpha(int color, int alpha) { | ||||
|         return (color & 0x00FFFFFF) | (alpha << 24); | ||||
|     } | ||||
| 
 | ||||
|     private ColorUtils() { | ||||
|     } | ||||
| } | ||||
| @ -18,10 +18,12 @@ public class HeadingSpan extends MetricAffectingSpan implements LeadingMarginSpa | ||||
|             2.F, 1.5F, 1.17F, 1.F, .83F, .67F, | ||||
|     }; | ||||
| 
 | ||||
|     private static final int DEF_BREAK_COLOR_ALPHA = 127; | ||||
| 
 | ||||
|     public static class Config { | ||||
| 
 | ||||
|         final int breakHeight; // by default stroke width | ||||
|         final int breakColor; // by default -> textColor | ||||
|         final int breakColor; // by default -> textColor with 0.5 alpha | ||||
| 
 | ||||
|         public Config(@IntRange(from = 0) int breakHeight, @ColorInt int breakColor) { | ||||
|             this.breakHeight = breakHeight; | ||||
| @ -30,8 +32,8 @@ public class HeadingSpan extends MetricAffectingSpan implements LeadingMarginSpa | ||||
|     } | ||||
| 
 | ||||
|     private final Config config; | ||||
|     private final Rect rect = new Rect(); | ||||
|     private final Paint paint = new Paint(); | ||||
|     private final Rect rect = ObjectsPool.rect(); | ||||
|     private final Paint paint = ObjectsPool.paint(); | ||||
|     private final int level; | ||||
|     private final int end; | ||||
| 
 | ||||
| @ -39,8 +41,6 @@ public class HeadingSpan extends MetricAffectingSpan implements LeadingMarginSpa | ||||
|         this.config = config; | ||||
|         this.level = level - 1; | ||||
|         this.end = end; | ||||
| 
 | ||||
|         paint.setStyle(Paint.Style.FILL); | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
| @ -77,7 +77,7 @@ public class HeadingSpan extends MetricAffectingSpan implements LeadingMarginSpa | ||||
|                 final int color; | ||||
|                 final int breakHeight; | ||||
|                 if (config.breakColor == 0) { | ||||
|                     color = p.getColor(); | ||||
|                     color = ColorUtils.applyAlpha(p.getColor(), DEF_BREAK_COLOR_ALPHA); | ||||
|                 } else { | ||||
|                     color = config.breakColor; | ||||
|                 } | ||||
| @ -86,6 +86,7 @@ public class HeadingSpan extends MetricAffectingSpan implements LeadingMarginSpa | ||||
|                 } else { | ||||
|                     breakHeight = config.breakHeight; | ||||
|                 } | ||||
|                 paint.setStyle(Paint.Style.FILL); | ||||
|                 paint.setColor(color); | ||||
| 
 | ||||
|                 rect.set(x, bottom - breakHeight, c.getWidth(), bottom); | ||||
|  | ||||
| @ -0,0 +1,33 @@ | ||||
| package ru.noties.markwon.spans; | ||||
| 
 | ||||
| import android.graphics.Paint; | ||||
| import android.graphics.Rect; | ||||
| import android.graphics.RectF; | ||||
| 
 | ||||
| class ObjectsPool { | ||||
| 
 | ||||
|     // maybe it's premature optimization, but as all the drawing is done in one thread | ||||
|     // and we apply needed values before actual drawing it's (I assume) safe to reuse some frequently used objects | ||||
| 
 | ||||
|     // if one of the spans need some really specific handling for Paint object (like colorFilters, masks, etc) | ||||
|     // it should instantiate own instance of it | ||||
| 
 | ||||
|     private static final Rect RECT = new Rect(); | ||||
|     private static final RectF RECT_F = new RectF(); | ||||
|     private static final Paint PAINT = new Paint(Paint.ANTI_ALIAS_FLAG); | ||||
| 
 | ||||
|     static Rect rect() { | ||||
|         return RECT; | ||||
|     } | ||||
| 
 | ||||
|     static RectF rectF() { | ||||
|         return RECT_F; | ||||
|     } | ||||
| 
 | ||||
|     static Paint paint() { | ||||
|         return PAINT; | ||||
|     } | ||||
| 
 | ||||
|     private ObjectsPool() { | ||||
|     } | ||||
| } | ||||
| @ -3,23 +3,62 @@ package ru.noties.markwon.spans; | ||||
| import android.graphics.Canvas; | ||||
| import android.graphics.Paint; | ||||
| import android.graphics.Rect; | ||||
| import android.support.annotation.ColorInt; | ||||
| import android.support.annotation.IntRange; | ||||
| import android.text.Layout; | ||||
| import android.text.style.LeadingMarginSpan; | ||||
| 
 | ||||
| public class ThematicBreakSpan implements LeadingMarginSpan { | ||||
| 
 | ||||
|     private static final int DEF_COLOR_ALPHA = 127; | ||||
| 
 | ||||
|     public static class Config { | ||||
| 
 | ||||
|         final int color; // by default textColor with 0.5 alpha | ||||
|         final int height; // by default strokeWidth of paint | ||||
| 
 | ||||
|         public Config(@ColorInt int color, @IntRange(from = 0) int height) { | ||||
|             this.color = color; | ||||
|             this.height = height; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private final Config config; | ||||
|     private final Rect rect = ObjectsPool.rect(); | ||||
|     private final Paint paint = ObjectsPool.paint(); | ||||
| 
 | ||||
|     public ThematicBreakSpan(Config config) { | ||||
|         this.config = config; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public int getLeadingMargin(boolean first) { | ||||
|         return 1; | ||||
|         return 0; | ||||
|     } | ||||
| 
 | ||||
|     @Override | ||||
|     public void drawLeadingMargin(Canvas c, Paint p, int x, int dir, int top, int baseline, int bottom, CharSequence text, int start, int end, boolean first, Layout layout) { | ||||
|         final int middle = (bottom - top) / 2; | ||||
|         final Rect rect = new Rect(0, top + middle - 2, c.getWidth(), top + middle + 2); | ||||
|         final Paint paint = new Paint(); | ||||
| 
 | ||||
|         final int middle = top + ((bottom - top) / 2); | ||||
| 
 | ||||
|         final int color; | ||||
|         if (config.color == 0) { | ||||
|             color = ColorUtils.applyAlpha(p.getColor(), DEF_COLOR_ALPHA); | ||||
|         } else { | ||||
|             color = config.color; | ||||
|         } | ||||
|         paint.setColor(color); | ||||
|         paint.setStyle(Paint.Style.FILL); | ||||
|         paint.setColor(0x80000000); | ||||
| 
 | ||||
|         final int height; | ||||
|         if (config.height == 0) { | ||||
|             height = (int) (p.getStrokeWidth() + .5F); | ||||
|         } else { | ||||
|             height = config.height; | ||||
|         } | ||||
|         final int halfHeight = (int) (height / 2.F + .5F); | ||||
| 
 | ||||
|         rect.set(x, middle - halfHeight, c.getWidth(), middle + halfHeight); | ||||
|         c.drawRect(rect, paint); | ||||
|     } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dimitry Ivanov
						Dimitry Ivanov