From e69d2320b247af0b99113f3529be4dee275215f6 Mon Sep 17 00:00:00 2001 From: Mikael Sand Date: Sun, 10 Feb 2019 02:52:15 +0200 Subject: [PATCH] Improve text subtree advance calculation caching --- android/src/main/java/com/horcrux/svg/TSpanView.java | 8 +++++++- android/src/main/java/com/horcrux/svg/TextView.java | 6 +++++- .../src/main/java/com/horcrux/svg/VirtualView.java | 2 +- ios/RNSVGNode.h | 2 ++ ios/Text/RNSVGTSpan.m | 12 ++++++++++++ ios/Text/RNSVGText.m | 7 ++++++- 6 files changed, 33 insertions(+), 4 deletions(-) diff --git a/android/src/main/java/com/horcrux/svg/TSpanView.java b/android/src/main/java/com/horcrux/svg/TSpanView.java index 9103c215..def6d4fd 100644 --- a/android/src/main/java/com/horcrux/svg/TSpanView.java +++ b/android/src/main/java/com/horcrux/svg/TSpanView.java @@ -108,6 +108,9 @@ class TSpanView extends TextView { } double getSubtreeTextChunksTotalAdvance(Paint paint) { + if (!Double.isNaN(cachedAdvance)) { + return cachedAdvance; + } double advance = 0; if (mContent == null) { @@ -118,6 +121,7 @@ class TSpanView extends TextView { advance += text.getSubtreeTextChunksTotalAdvance(paint); } } + cachedAdvance = advance; return advance; } @@ -125,6 +129,7 @@ class TSpanView extends TextView { final int length = line.length(); if (length == 0) { + cachedAdvance = 0; return advance; } @@ -149,7 +154,8 @@ class TSpanView extends TextView { paint.setLetterSpacing((float)(letterSpacing / (font.fontSize * mScale))); } - return paint.measureText(line); + cachedAdvance = paint.measureText(line); + return cachedAdvance; } @SuppressWarnings("ConstantConditions") diff --git a/android/src/main/java/com/horcrux/svg/TextView.java b/android/src/main/java/com/horcrux/svg/TextView.java index 5d17f772..5aa98ec9 100644 --- a/android/src/main/java/com/horcrux/svg/TextView.java +++ b/android/src/main/java/com/horcrux/svg/TextView.java @@ -50,11 +50,15 @@ class TextView extends GroupView { if (mPath == null) { return; } - cachedAdvance = Double.NaN; super.invalidate(); clearChildCache(); } + void clearCache() { + cachedAdvance = Double.NaN; + super.clearCache(); + } + @ReactProp(name = "textLength") public void setTextLength(Dynamic length) { mTextLength = SVGLength.from(length); diff --git a/android/src/main/java/com/horcrux/svg/VirtualView.java b/android/src/main/java/com/horcrux/svg/VirtualView.java index 07d28da0..933ab5ad 100644 --- a/android/src/main/java/com/horcrux/svg/VirtualView.java +++ b/android/src/main/java/com/horcrux/svg/VirtualView.java @@ -101,7 +101,7 @@ abstract public class VirtualView extends ReactViewGroup { super.invalidate(); } - private void clearCache() { + void clearCache() { canvasDiagonal = -1; canvasHeight = -1; canvasWidth = -1; diff --git a/ios/RNSVGNode.h b/ios/RNSVGNode.h index bb94d891..83dde07e 100644 --- a/ios/RNSVGNode.h +++ b/ios/RNSVGNode.h @@ -118,4 +118,6 @@ extern CGFloat const RNSVG_DEFAULT_FONT_SIZE; - (void)clearChildCache; +- (void)clearPath; + @end diff --git a/ios/Text/RNSVGTSpan.m b/ios/Text/RNSVGTSpan.m index a219f89f..11a0e98c 100644 --- a/ios/Text/RNSVGTSpan.m +++ b/ios/Text/RNSVGTSpan.m @@ -25,6 +25,7 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI; BOOL isClosed; NSMutableArray *emoji; NSMutableArray *emojiTransform; + CGFloat cachedAdvance; } - (id)init @@ -41,6 +42,12 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI; return self; } +- (void)clearPath +{ + [super clearPath]; + cachedAdvance = NAN; +} + - (void)setContent:(NSString *)content { if ([content isEqualToString:_content]) { @@ -102,6 +109,9 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI; - (CGFloat)getSubtreeTextChunksTotalAdvance { + if (!isnan(cachedAdvance)) { + return cachedAdvance; + } CGFloat advance = 0; NSString *str = self.content; @@ -112,6 +122,7 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI; advance += [text getSubtreeTextChunksTotalAdvance]; } } + cachedAdvance = advance; return advance; } @@ -155,6 +166,7 @@ static CGFloat RNSVGTSpan_radToDeg = 180 / (CGFloat)M_PI; CGRect textBounds = CTLineGetBoundsWithOptions(line, 0); CGFloat textMeasure = CGRectGetWidth(textBounds); + cachedAdvance = textMeasure; return textMeasure; } diff --git a/ios/Text/RNSVGText.m b/ios/Text/RNSVGText.m index 48f52e97..b9e69996 100644 --- a/ios/Text/RNSVGText.m +++ b/ios/Text/RNSVGText.m @@ -26,11 +26,16 @@ if (self.dirty || self.merging) { return; } - cachedAdvance = NAN; [super invalidate]; [self clearChildCache]; } +- (void)clearPath +{ + [super clearPath]; + cachedAdvance = NAN; +} + - (void)setTextLength:(RNSVGLength *)textLength { if ([textLength isEqualTo:_textLength]) {