react-native-enriched-markdown-scaffold 0.7.4-scaffold.9 → 1.0.2-scaffold.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +54 -8
- package/ReactNativeEnrichedMarkdown.podspec +82 -73
- package/android/build.gradle +188 -1
- package/android/consumer-rules.pro +1 -1
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerDelegate.java +27 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownManagerInterface.java +7 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerDelegate.java +24 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextInputManagerInterface.java +8 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerDelegate.java +27 -0
- package/android/generated/java/com/facebook/react/viewmanagers/EnrichedMarkdownTextManagerInterface.java +7 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.cpp +223 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/EventEmitters.h +183 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.cpp +65 -0
- package/android/generated/jni/react/renderer/components/EnrichedMarkdownTextSpec/Props.h +1086 -61
- package/android/src/main/baseline-prof.txt +1 -1
- package/android/src/main/cpp/jni-adapter.cpp +74 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdown.kt +351 -13
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownInternalText.kt +62 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownManager.kt +85 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownText.kt +160 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextLayoutManager.kt +10 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/EnrichedMarkdownTextManager.kt +76 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/MeasurementStore.kt +126 -10
- package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/events/CopyRequestEvent.kt +28 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/events/LinkLayoutEvent.kt +36 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/events/SelectionChangeEvent.kt +43 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputManager.kt +54 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/input/EnrichedMarkdownTextInputView.kt +923 -462
- package/android/src/main/java/com/swmansion/enriched/markdown/input/MarkdownClipboard.kt +42 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/BlockEditCoordinator.kt +196 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/ClipboardCoordinator.kt +73 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditContext.kt +19 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditPipeline.kt +248 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/EditSession.kt +52 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/InputConnectionWrapper.kt +108 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/LinkCoordinator.kt +69 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MarkdownTextWatcher.kt +3 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/input/editing/MentionCoordinator.kt +118 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnChangeStateEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnContextMenuItemPressEvent.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnInputKeyPressEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/events/OnPasteEvent.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/BlockStore.kt +254 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/FormattingStore.kt +80 -87
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputFormatter.kt +109 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/InputParser.kt +116 -22
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/MarkdownSerializer.kt +167 -38
- package/android/src/main/java/com/swmansion/enriched/markdown/input/formatting/RangeEditAdjustment.kt +149 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputEventEmitter.kt +66 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/input/layout/InputMeasurementStore.kt +4 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockRange.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/BlockType.kt +48 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/FormattingRange.kt +9 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/InputFormatterStyle.kt +39 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathAtom.kt +20 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MathChipStyle.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/input/model/MutableRangeBounds.kt +11 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputBulletSpan.kt +82 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputHeadingSpan.kt +58 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputListItemSpacingSpan.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/spans/InputOrderedListMarkerSpan.kt +63 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/BlockHandler.kt +54 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/HeadingBlockHandler.kt +27 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/OrderedListBlockHandler.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/styles/UnorderedListBlockHandler.kt +37 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/input/toolbar/InputContextMenu.kt +8 -26
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/MarkdownASTNode.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/parser/Parser.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockStyleContext.kt +9 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/BlockquoteRenderer.kt +100 -12
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/CodeBlockRenderer.kt +16 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/HeadingRenderer.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/LinkRenderer.kt +37 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListContextManager.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListItemRenderer.kt +74 -18
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/ListRenderer.kt +43 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/NodeRenderer.kt +9 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SoftBreakRenderer.kt +16 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/renderer/SpanStyleCache.kt +35 -28
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BaseListSpan.kt +24 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/BlockquoteSpan.kt +174 -24
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBackgroundSpan.kt +20 -82
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeBlockSpan.kt +13 -16
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/CodeSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/EmphasisSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ImageSpan.kt +182 -46
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/InlineChipPainter.kt +140 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkChipSpans.kt +177 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/LinkSpan.kt +1 -6
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListItemSpacingSpan.kt +33 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/ListMarkerAnchorSpan.kt +38 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/OrderedListSpan.kt +2 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/StrongSpan.kt +1 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/TaskListSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/spans/UnorderedListSpan.kt +3 -2
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/BlockquoteStyle.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/CodeBlockStyle.kt +26 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ImageStyle.kt +7 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/InlineMathStyle.kt +16 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkStyle.kt +36 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/LinkVariantEntry.kt +7 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/ListStyle.kt +4 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/MathStyle.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/StyleConfig.kt +13 -4
- package/android/src/main/java/com/swmansion/enriched/markdown/styles/TableStyle.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockHighlighter.kt +90 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/CodeBlockNode.kt +57 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/FeatureFlags.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownSegment.kt +9 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/MarkdownViewManagerUtils.kt +84 -7
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/ReadableMapExtensions.kt +3 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/RenderedSegment.kt +10 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/SegmentSignature.kt +1 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/StreamingMarkdownFilter.kt +83 -5
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/common/serialization/MarkdownASTSerializer.kt +4 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/MarkdownStyleParser.kt +74 -44
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/input/PasteTextUtils.kt +52 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageCache.kt +26 -3
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/ImageDownloader.kt +22 -9
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/LocalImageLoader.kt +161 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/HTMLGenerator.kt +2 -1
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/conversion/MarkdownExtractor.kt +6 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/extensions/TextPaintExtensions.kt +23 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/CheckboxTouchHelper.kt +7 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/interaction/TaskListTapUtils.kt +41 -21
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/span/BlockSpacing.kt +15 -8
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/HeadlessActionMode.kt +88 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLayoutCollector.kt +100 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/LinkLongPressMovementMethod.kt +58 -27
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionActionMode.kt +72 -16
- package/android/src/main/java/com/swmansion/enriched/markdown/utils/text/view/SelectionChangeReporter.kt +232 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/BlockMenuOptions.kt +64 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CodeBlockContainerView.kt +414 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/ContextMenuPopup.kt +9 -6
- package/android/src/main/java/com/swmansion/enriched/markdown/views/CopyGlyph.kt +101 -0
- package/android/src/main/java/com/swmansion/enriched/markdown/views/TableContainerView.kt +61 -11
- package/android/src/main/jni/CMakeLists.txt +53 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.cpp +10 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownContainerShadowNode.h +11 -2
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.cpp +10 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextShadowNode.h +12 -2
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.cpp +9 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/MarkdownTextState.h +24 -0
- package/android/src/main/jni/react/renderer/components/EnrichedMarkdownTextSpec/conversions.h +16 -0
- package/android/src/math/java/com/swmansion/enriched/markdown/input/math/MathChipControllerImpl.kt +21 -4
- package/android/src/math/java/com/swmansion/enriched/markdown/renderer/MathInlineRenderer.kt +8 -2
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathChipSpan.kt +1 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathInlineSpan.kt +13 -6
- package/android/src/math/java/com/swmansion/enriched/markdown/spans/MathMeasureHelper.kt +2 -1
- package/android/src/math/java/com/swmansion/enriched/markdown/views/MathContainerView.kt +26 -8
- package/cpp/highlight/CodeBlockHighlighter.cpp +284 -0
- package/cpp/highlight/CodeBlockHighlighter.hpp +66 -0
- package/cpp/highlight/CodeBlockLanguages.cpp +138 -0
- package/cpp/highlight/CodeBlockLanguages.hpp +25 -0
- package/cpp/highlight/HighlightGrammars.hpp +28 -0
- package/cpp/highlight/code_highlight_podspec.rb +211 -0
- package/cpp/highlight/gen-registry.mjs +155 -0
- package/cpp/highlight/grammar-versions.json +159 -0
- package/cpp/highlight/vendor/generated/generated_queries.h +1665 -0
- package/cpp/highlight/vendor/generated/generated_registry.cpp +59 -0
- package/cpp/parser/MD4CParser.cpp +173 -61
- package/cpp/parser/MD4CParser.hpp +1 -0
- package/cpp/parser/MarkdownASTNode.hpp +2 -1
- package/cpp/wasm/ASTSerializer.cpp +2 -0
- package/cpp/wasm/build.sh +1 -0
- package/cpp/wasm/md4c_wasm.cpp +3 -1
- package/docs/ACCESSIBILITY.md +14 -2
- package/docs/API_REFERENCE.md +405 -12
- package/docs/BREAKING_CHANGES.md +129 -0
- package/docs/CODE_HIGHLIGHT.md +133 -0
- package/docs/COPY_OPTIONS.md +61 -3
- package/docs/ELEMENTS_STRUCTURE.md +52 -4
- package/docs/IMAGE_CACHING.md +30 -0
- package/docs/INPUT.md +110 -11
- package/docs/LATEX_MATH.md +87 -45
- package/docs/MACOS.md +1 -1
- package/docs/MARKDOWN_STREAMING.md +27 -1
- package/docs/MENTIONS.md +8 -1
- package/docs/NATIVE_ASSETS.md +127 -0
- package/docs/RTL.md +1 -1
- package/docs/STYLES.md +73 -6
- package/docs/TESTING.md +112 -0
- package/docs/TEXT.md +18 -6
- package/docs/WEB.md +4 -1
- package/ios/EnrichedMarkdown.h +7 -0
- package/ios/EnrichedMarkdown.mm +583 -76
- package/ios/EnrichedMarkdownText.h +7 -0
- package/ios/EnrichedMarkdownText.mm +299 -73
- package/ios/attachments/ENRMImageAttachment.h +9 -0
- package/ios/attachments/ENRMImageAttachment.m +143 -40
- package/ios/attachments/ENRMMathInlineAttachment+macOS.m +2 -1
- package/ios/attachments/ENRMMathInlineAttachment.h +5 -0
- package/ios/attachments/ENRMMathInlineAttachment.m +50 -82
- package/ios/attachments/ENRMMathInlineAttachmentShared.h +2 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.cpp +223 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/EventEmitters.h +183 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.cpp +65 -0
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/Props.h +1086 -61
- package/ios/generated/ReactCodegen/EnrichedMarkdownTextSpec/RCTComponentViewHelpers.h +181 -2
- package/ios/input/ENRMAutoLinkDetector.h +2 -1
- package/ios/input/ENRMAutoLinkDetector.mm +79 -41
- package/ios/input/ENRMBlockEditCoordinator.h +71 -0
- package/ios/input/ENRMBlockEditCoordinator.mm +195 -0
- package/ios/input/ENRMBlockRange.h +28 -0
- package/ios/input/ENRMBlockRange.mm +30 -0
- package/ios/input/ENRMBlockStore.h +56 -0
- package/ios/input/ENRMBlockStore.mm +275 -0
- package/ios/input/ENRMClipboardCoordinator.h +45 -0
- package/ios/input/ENRMClipboardCoordinator.mm +120 -0
- package/ios/input/ENRMDetectorPipeline.h +2 -1
- package/ios/input/ENRMEditPipeline.h +76 -0
- package/ios/input/ENRMEditPipeline.mm +228 -0
- package/ios/input/ENRMEditSession.h +36 -0
- package/ios/input/ENRMEditSession.mm +63 -0
- package/ios/input/ENRMFormattingStore.h +17 -0
- package/ios/input/ENRMFormattingStore.mm +95 -105
- package/ios/input/ENRMInputBlockType.h +91 -0
- package/ios/input/ENRMInputBlockType.mm +5 -0
- package/ios/input/ENRMInputDecorationDrawer.h +18 -0
- package/ios/input/ENRMInputEventEmitter.h +56 -0
- package/ios/input/ENRMInputEventEmitter.mm +308 -0
- package/ios/input/ENRMInputFormatter.h +29 -69
- package/ios/input/ENRMInputFormatter.mm +216 -124
- package/ios/input/ENRMInputFormatterStyle.h +99 -0
- package/ios/input/ENRMInputFormatterStyle.mm +188 -0
- package/ios/input/ENRMInputLayoutManager.h +9 -0
- package/ios/input/ENRMInputLayoutManager.mm +30 -0
- package/ios/input/ENRMInputListMarkerDrawer.h +32 -0
- package/ios/input/ENRMInputListMarkerDrawer.mm +426 -0
- package/ios/input/ENRMInputParser.h +5 -6
- package/ios/input/ENRMInputParser.mm +461 -178
- package/ios/input/ENRMInputRemend.mm +2 -2
- package/ios/input/ENRMInputStyleStateBuilder.h +40 -0
- package/ios/input/ENRMInputStyleStateBuilder.mm +60 -0
- package/ios/input/ENRMInputTextView.mm +103 -8
- package/ios/input/ENRMInputTypingAttributesController.h +42 -0
- package/ios/input/ENRMInputTypingAttributesController.mm +203 -0
- package/ios/input/ENRMLinkCoordinator.h +41 -0
- package/ios/input/ENRMLinkCoordinator.mm +89 -0
- package/ios/input/ENRMMarkdownSerializer.h +29 -5
- package/ios/input/ENRMMarkdownSerializer.mm +170 -48
- package/ios/input/ENRMMathAtom.h +26 -0
- package/ios/input/ENRMMathAtom.mm +12 -0
- package/ios/input/ENRMMentionCoordinator.h +45 -0
- package/ios/input/ENRMMentionCoordinator.mm +167 -0
- package/ios/input/ENRMRangeEditAdjustment.h +38 -0
- package/ios/input/ENRMRangeEditAdjustment.mm +91 -0
- package/ios/input/ENRMRangeStoreUtils.h +39 -0
- package/ios/input/EnrichedMarkdownTextInput+ContextMenu.mm +6 -6
- package/ios/input/EnrichedMarkdownTextInput+Internal.h +11 -3
- package/ios/input/EnrichedMarkdownTextInput.h +7 -1
- package/ios/input/EnrichedMarkdownTextInput.mm +1089 -1023
- package/ios/input/InputStylePropsUtils.h +109 -68
- package/ios/input/internals/EnrichedMarkdownTextInputShadowNode.mm +2 -1
- package/ios/input/styles/ENRMBlockHandler.h +46 -0
- package/ios/input/styles/ENRMHeadingBlockHandler.h +15 -0
- package/ios/input/styles/ENRMHeadingBlockHandler.mm +38 -0
- package/ios/input/styles/ENRMOrderedListBlockHandler.h +14 -0
- package/ios/input/styles/ENRMOrderedListBlockHandler.mm +48 -0
- package/ios/input/styles/ENRMUnorderedListBlockHandler.h +15 -0
- package/ios/input/styles/ENRMUnorderedListBlockHandler.mm +51 -0
- package/ios/internals/ENRMViewFreeMeasurement.h +331 -0
- package/ios/internals/EnrichedMarkdownShadowNode.h +1 -3
- package/ios/internals/EnrichedMarkdownShadowNode.mm +16 -20
- package/ios/internals/EnrichedMarkdownTextShadowNode.h +1 -3
- package/ios/internals/EnrichedMarkdownTextShadowNode.mm +15 -20
- package/ios/internals/MeasurementCache.h +41 -9
- package/ios/internals/ShadowMeasurementUtils.h +63 -58
- package/ios/math/ENRMMathChipController.h +74 -0
- package/ios/math/ENRMMathChipController.mm +476 -0
- package/ios/math/ENRMRaTeXBridge.swift +27 -6
- package/ios/parser/ENRMMarkdownParser.h +1 -8
- package/ios/parser/ENRMMarkdownParser.mm +2 -11
- package/ios/parser/MarkdownASTNode.h +2 -1
- package/ios/parser/MarkdownParserBridge.mm +4 -0
- package/ios/renderer/AttributedRenderer.m +20 -2
- package/ios/renderer/BaseRenderer.h +17 -2
- package/ios/renderer/BaseRenderer.m +30 -0
- package/ios/renderer/BlockquoteRenderer.h +1 -1
- package/ios/renderer/BlockquoteRenderer.m +144 -35
- package/ios/renderer/CodeBlockRenderer.h +1 -1
- package/ios/renderer/CodeBlockRenderer.m +27 -23
- package/ios/renderer/CodeRenderer.h +1 -1
- package/ios/renderer/CodeRenderer.m +3 -1
- package/ios/renderer/ENRMImageRenderer.h +1 -1
- package/ios/renderer/ENRMImageRenderer.m +5 -1
- package/ios/renderer/ENRMMathInlineRenderer.h +1 -1
- package/ios/renderer/ENRMMathInlineRenderer.m +6 -1
- package/ios/renderer/ENRMSpoilerRenderer.h +1 -1
- package/ios/renderer/ENRMSpoilerRenderer.m +3 -1
- package/ios/renderer/EmphasisRenderer.h +1 -1
- package/ios/renderer/EmphasisRenderer.m +3 -1
- package/ios/renderer/HeadingRenderer.h +1 -1
- package/ios/renderer/HeadingRenderer.m +13 -6
- package/ios/renderer/HighlightRenderer.h +1 -1
- package/ios/renderer/HighlightRenderer.m +3 -1
- package/ios/renderer/LinkRenderer.h +1 -1
- package/ios/renderer/LinkRenderer.m +50 -16
- package/ios/renderer/ListItemRenderer.h +13 -1
- package/ios/renderer/ListItemRenderer.m +102 -44
- package/ios/renderer/ListRenderer.h +2 -2
- package/ios/renderer/ListRenderer.m +63 -25
- package/ios/renderer/ParagraphRenderer.h +1 -1
- package/ios/renderer/ParagraphRenderer.m +16 -8
- package/ios/renderer/RenderContext.h +10 -0
- package/ios/renderer/RenderContext.m +44 -0
- package/ios/renderer/RendererFactory.m +14 -0
- package/ios/renderer/StrikethroughRenderer.h +1 -1
- package/ios/renderer/StrikethroughRenderer.m +3 -1
- package/ios/renderer/StrongRenderer.h +1 -1
- package/ios/renderer/StrongRenderer.m +3 -1
- package/ios/renderer/SubscriptRenderer.h +1 -1
- package/ios/renderer/SubscriptRenderer.m +3 -1
- package/ios/renderer/SuperscriptRenderer.h +1 -1
- package/ios/renderer/SuperscriptRenderer.m +3 -1
- package/ios/renderer/TextRenderer.h +2 -2
- package/ios/renderer/TextRenderer.m +3 -1
- package/ios/renderer/ThematicBreakRenderer.h +1 -1
- package/ios/renderer/ThematicBreakRenderer.m +3 -1
- package/ios/renderer/UnderlineRenderer.h +1 -1
- package/ios/renderer/UnderlineRenderer.m +3 -1
- package/ios/styles/StyleConfig.h +42 -0
- package/ios/styles/StyleConfig.mm +216 -0
- package/ios/utils/BlockquoteBorder.h +6 -0
- package/ios/utils/BlockquoteBorder.m +249 -52
- package/ios/utils/CodeBackground.m +3 -65
- package/ios/utils/CodeBlockBackground.m +16 -2
- package/ios/utils/ENRMAtomicSize.h +65 -0
- package/ios/utils/ENRMBlockMenu.h +66 -0
- package/ios/utils/ENRMChipDrawing.h +24 -0
- package/ios/utils/ENRMChipDrawing.m +83 -0
- package/ios/utils/ENRMCodeBlockContent.h +37 -0
- package/ios/utils/ENRMCodeBlockContent.mm +79 -0
- package/ios/utils/ENRMCodeBlockHighlighter.h +37 -0
- package/ios/utils/ENRMCodeBlockHighlighter.mm +51 -0
- package/ios/utils/ENRMFeatureFlags.h +7 -0
- package/ios/utils/ENRMImageDownloader.h +11 -1
- package/ios/utils/ENRMImageDownloader.m +60 -16
- package/ios/utils/ENRMLinkChip.h +70 -0
- package/ios/utils/ENRMLinkChip.m +213 -0
- package/ios/utils/ENRMLinkLayout.h +50 -0
- package/ios/utils/ENRMLinkLayout.m +45 -0
- package/ios/utils/ENRMLocalImageLoader.h +31 -0
- package/ios/utils/ENRMLocalImageLoader.m +68 -0
- package/ios/utils/ENRMMathFallback.h +26 -0
- package/ios/utils/ENRMMathFallback.m +18 -0
- package/ios/utils/ENRMSelectionChange.h +120 -0
- package/ios/utils/ENRMSelectionChange.m +282 -0
- package/ios/utils/ENRMTextViewSetup.h +35 -17
- package/ios/utils/EditMenuUtils+macOS.m +4 -1
- package/ios/utils/EditMenuUtils.h +35 -6
- package/ios/utils/EditMenuUtils.m +188 -11
- package/ios/utils/HTMLGenerator.m +2 -1
- package/ios/utils/ImageRequestHeaderUtils.h +35 -0
- package/ios/utils/LastElementUtils.h +1 -0
- package/ios/utils/ListMarkerDrawer.m +29 -42
- package/ios/utils/MarkdownASTSerializer.m +4 -0
- package/ios/utils/MarkdownAccessibilityElementBuilder.m +3 -1
- package/ios/utils/MarkdownExtractor.m +2 -1
- package/ios/utils/ParagraphStyleUtils.h +5 -0
- package/ios/utils/ParagraphStyleUtils.m +77 -17
- package/ios/utils/RTFExportUtils.m +2 -0
- package/ios/utils/RenderedMarkdownSegment.h +13 -1
- package/ios/utils/RenderedMarkdownSegment.m +20 -0
- package/ios/utils/SegmentRenderer.m +17 -4
- package/ios/utils/StreamingMarkdownFilter.h +11 -1
- package/ios/utils/StreamingMarkdownFilter.m +98 -2
- package/ios/utils/StylePropsUtils.h +110 -1
- package/ios/utils/TaskListTapUtils.m +24 -0
- package/ios/utils/TextViewLayoutManager.mm +3 -0
- package/ios/views/ENRMCodeBlockContainerView.h +60 -0
- package/ios/views/ENRMCodeBlockContainerView.m +569 -0
- package/ios/views/ENRMMathContainerView.h +23 -0
- package/ios/views/ENRMMathContainerView.m +87 -20
- package/ios/views/TableContainerView.h +32 -0
- package/ios/views/TableContainerView.m +291 -175
- package/jest.d.ts +1 -0
- package/jest.js +5 -0
- package/lib/module/EnrichedMarkdownNativeComponent.ts +203 -1
- package/lib/module/EnrichedMarkdownTextInput.js +84 -5
- package/lib/module/EnrichedMarkdownTextInput.js.map +1 -1
- package/lib/module/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
- package/lib/module/EnrichedMarkdownTextNativeComponent.ts +204 -1
- package/lib/module/headingDefaults.js +34 -0
- package/lib/module/headingDefaults.js.map +1 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/jest/index.js +205 -0
- package/lib/module/jest/index.js.map +1 -0
- package/lib/module/native/EnrichedMarkdownText.js +199 -15
- package/lib/module/native/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.js +98 -23
- package/lib/module/normalizeMarkdownStyle.js.map +1 -1
- package/lib/module/normalizeMarkdownStyle.web.js +73 -22
- package/lib/module/normalizeMarkdownStyle.web.js.map +1 -1
- package/lib/module/normalizeMarkdownTextInputStyle.js +62 -15
- package/lib/module/normalizeMarkdownTextInputStyle.js.map +1 -1
- package/lib/module/normalizeMenuItem.js +1 -1
- package/lib/module/utils/textInputState.js +26 -0
- package/lib/module/utils/textInputState.js.map +1 -0
- package/lib/module/web/EnrichedMarkdownText.js +15 -8
- package/lib/module/web/EnrichedMarkdownText.js.map +1 -1
- package/lib/module/web/parseMarkdown.js +4 -3
- package/lib/module/web/parseMarkdown.js.map +1 -1
- package/lib/module/web/renderers/InlineRenderers.js +102 -3
- package/lib/module/web/renderers/InlineRenderers.js.map +1 -1
- package/lib/module/web/renderers/ListRenderers.js +7 -2
- package/lib/module/web/renderers/ListRenderers.js.map +1 -1
- package/lib/module/web/renderers/index.js +7 -4
- package/lib/module/web/renderers/index.js.map +1 -1
- package/lib/module/web/styles.js +101 -6
- package/lib/module/web/styles.js.map +1 -1
- package/lib/module/web/utils.js +14 -0
- package/lib/module/web/utils.js.map +1 -1
- package/lib/module/web/wasm/md4c.js +0 -0
- package/lib/module/web/wasm/md4c.js.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts +185 -2
- package/lib/typescript/src/EnrichedMarkdownNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts +94 -9
- package/lib/typescript/src/EnrichedMarkdownTextInput.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts +69 -5
- package/lib/typescript/src/EnrichedMarkdownTextInputNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts +185 -2
- package/lib/typescript/src/EnrichedMarkdownTextNativeComponent.d.ts.map +1 -1
- package/lib/typescript/src/headingDefaults.d.ts +9 -0
- package/lib/typescript/src/headingDefaults.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +3 -3
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/index.web.d.ts +2 -2
- package/lib/typescript/src/index.web.d.ts.map +1 -1
- package/lib/typescript/src/jest/index.d.ts +6 -0
- package/lib/typescript/src/jest/index.d.ts.map +1 -0
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts +5 -5
- package/lib/typescript/src/native/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownStyle.web.d.ts.map +1 -1
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts +19 -5
- package/lib/typescript/src/normalizeMarkdownTextInputStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyle.d.ts +122 -5
- package/lib/typescript/src/types/MarkdownStyle.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts +39 -0
- package/lib/typescript/src/types/MarkdownStyleInternal.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.d.ts +207 -10
- package/lib/typescript/src/types/MarkdownTextProps.d.ts.map +1 -1
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts +60 -1
- package/lib/typescript/src/types/MarkdownTextProps.web.d.ts.map +1 -1
- package/lib/typescript/src/types/events.d.ts +85 -0
- package/lib/typescript/src/types/events.d.ts.map +1 -1
- package/lib/typescript/src/utils/textInputState.d.ts +24 -0
- package/lib/typescript/src/utils/textInputState.d.ts.map +1 -0
- package/lib/typescript/src/web/EnrichedMarkdownText.d.ts +1 -1
- package/lib/typescript/src/web/EnrichedMarkdownText.d.ts.map +1 -1
- package/lib/typescript/src/web/parseMarkdown.d.ts +1 -1
- package/lib/typescript/src/web/parseMarkdown.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/InlineRenderers.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/ListRenderers.d.ts.map +1 -1
- package/lib/typescript/src/web/renderers/index.d.ts +2 -1
- package/lib/typescript/src/web/renderers/index.d.ts.map +1 -1
- package/lib/typescript/src/web/styles.d.ts +2 -1
- package/lib/typescript/src/web/styles.d.ts.map +1 -1
- package/lib/typescript/src/web/types.d.ts +10 -2
- package/lib/typescript/src/web/types.d.ts.map +1 -1
- package/lib/typescript/src/web/utils.d.ts +4 -0
- package/lib/typescript/src/web/utils.d.ts.map +1 -1
- package/package.json +36 -9
- package/postinstall.mjs +131 -0
- package/ratex-version.json +21 -0
- package/src/EnrichedMarkdownNativeComponent.ts +203 -1
- package/src/EnrichedMarkdownTextInput.tsx +159 -8
- package/src/EnrichedMarkdownTextInputNativeComponent.ts +78 -5
- package/src/EnrichedMarkdownTextNativeComponent.ts +204 -1
- package/src/headingDefaults.ts +21 -0
- package/src/index.tsx +15 -0
- package/src/index.web.tsx +6 -1
- package/src/jest/index.tsx +236 -0
- package/src/native/EnrichedMarkdownText.tsx +260 -11
- package/src/normalizeMarkdownStyle.ts +117 -16
- package/src/normalizeMarkdownStyle.web.ts +76 -15
- package/src/normalizeMarkdownTextInputStyle.ts +110 -35
- package/src/normalizeMenuItem.ts +1 -1
- package/src/types/MarkdownStyle.ts +125 -5
- package/src/types/MarkdownStyleInternal.ts +51 -0
- package/src/types/MarkdownTextProps.ts +215 -10
- package/src/types/MarkdownTextProps.web.ts +62 -1
- package/src/types/events.ts +90 -0
- package/src/utils/textInputState.ts +35 -0
- package/src/web/EnrichedMarkdownText.tsx +26 -5
- package/src/web/parseMarkdown.ts +6 -2
- package/src/web/renderers/InlineRenderers.tsx +116 -3
- package/src/web/renderers/ListRenderers.tsx +14 -2
- package/src/web/renderers/index.tsx +6 -2
- package/src/web/styles.ts +114 -5
- package/src/web/types.ts +10 -1
- package/src/web/utils.ts +9 -0
- package/src/web/wasm/md4c.js +0 -0
- package/vendor-grammars.mjs +511 -0
- package/vendor-ratex.mjs +173 -0
- package/app.plugin.js +0 -2
- package/plugin/build/withAndroidMath.js +0 -19
- package/plugin/build/withIosMath.js +0 -28
- package/plugin/build/withReactNativeEnrichedMarkdown.js +0 -11
- package/plugin/src/withAndroidMath.ts +0 -24
- package/plugin/src/withIosMath.ts +0 -35
- package/plugin/src/withReactNativeEnrichedMarkdown.ts +0 -17
- package/plugin/tsconfig.build.json +0 -16
|
@@ -12,27 +12,25 @@ import android.text.style.LeadingMarginSpan
|
|
|
12
12
|
import android.text.style.LineBackgroundSpan
|
|
13
13
|
import android.text.style.MetricAffectingSpan
|
|
14
14
|
import androidx.core.graphics.withSave
|
|
15
|
-
import com.swmansion.enriched.markdown.renderer.BlockStyle
|
|
16
15
|
import com.swmansion.enriched.markdown.renderer.SpanStyleCache
|
|
17
16
|
import com.swmansion.enriched.markdown.styles.CodeBlockStyle
|
|
18
|
-
import com.swmansion.enriched.markdown.utils.text.extensions.
|
|
17
|
+
import com.swmansion.enriched.markdown.utils.text.extensions.applyCodeBlockTextStyle
|
|
19
18
|
import com.swmansion.enriched.markdown.utils.text.extensions.applyColorPreserving
|
|
20
19
|
|
|
20
|
+
/**
|
|
21
|
+
* Draws the commonmark-flavor code block box as per-line strips. The visual
|
|
22
|
+
* conventions (half-stroke border inset, radius reduced by that inset) must
|
|
23
|
+
* stay in sync with the whole-rect box the github flavor draws in
|
|
24
|
+
* CodeBlockContainerView.
|
|
25
|
+
*/
|
|
21
26
|
class CodeBlockSpan(
|
|
22
27
|
private val codeBlockStyle: CodeBlockStyle,
|
|
23
28
|
private val context: Context,
|
|
24
29
|
private val styleCache: SpanStyleCache,
|
|
30
|
+
private val leadingIndent: Int = 0,
|
|
25
31
|
) : MetricAffectingSpan(),
|
|
26
32
|
LineBackgroundSpan,
|
|
27
33
|
LeadingMarginSpan {
|
|
28
|
-
private val blockStyle =
|
|
29
|
-
BlockStyle(
|
|
30
|
-
fontSize = codeBlockStyle.fontSize,
|
|
31
|
-
fontFamily = codeBlockStyle.fontFamily,
|
|
32
|
-
fontWeight = codeBlockStyle.fontWeight,
|
|
33
|
-
color = codeBlockStyle.color,
|
|
34
|
-
)
|
|
35
|
-
|
|
36
34
|
private val path = Path()
|
|
37
35
|
private val rect = RectF()
|
|
38
36
|
private val arcRect = RectF()
|
|
@@ -59,7 +57,7 @@ class CodeBlockSpan(
|
|
|
59
57
|
color = codeBlockStyle.borderColor
|
|
60
58
|
}
|
|
61
59
|
|
|
62
|
-
override fun getLeadingMargin(first: Boolean): Int = codeBlockStyle.padding.toInt()
|
|
60
|
+
override fun getLeadingMargin(first: Boolean): Int = codeBlockStyle.padding.toInt() + leadingIndent
|
|
63
61
|
|
|
64
62
|
override fun drawLeadingMargin(
|
|
65
63
|
c: Canvas?,
|
|
@@ -105,11 +103,12 @@ class CodeBlockSpan(
|
|
|
105
103
|
val inset = codeBlockStyle.borderWidth / 2f
|
|
106
104
|
|
|
107
105
|
rect.set(
|
|
108
|
-
left.toFloat() + inset,
|
|
106
|
+
left.toFloat() + leadingIndent + inset,
|
|
109
107
|
top.toFloat() + (if (isFirstLine) inset else 0f),
|
|
110
108
|
right.toFloat() - inset,
|
|
111
109
|
bottom.toFloat() - (if (isLastLine) inset else 0f),
|
|
112
110
|
)
|
|
111
|
+
if (rect.left >= rect.right) return
|
|
113
112
|
|
|
114
113
|
val radius = codeBlockStyle.borderRadius
|
|
115
114
|
val adjRadius = if (radius > inset) radius - inset else radius
|
|
@@ -187,10 +186,8 @@ class CodeBlockSpan(
|
|
|
187
186
|
}
|
|
188
187
|
|
|
189
188
|
private fun applyTextStyle(tp: TextPaint) {
|
|
190
|
-
tp.
|
|
191
|
-
|
|
192
|
-
tp.applyBlockStyleFont(blockStyle, context)
|
|
189
|
+
tp.applyCodeBlockTextStyle(codeBlockStyle, context)
|
|
193
190
|
|
|
194
|
-
tp.applyColorPreserving(
|
|
191
|
+
tp.applyColorPreserving(codeBlockStyle.color, *styleCache.colorsToPreserve)
|
|
195
192
|
}
|
|
196
193
|
}
|
|
@@ -24,7 +24,7 @@ class CodeSpan(
|
|
|
24
24
|
val preservedStyle = (paint.typeface?.style ?: 0) and (Typeface.BOLD or Typeface.ITALIC)
|
|
25
25
|
paint.typeface =
|
|
26
26
|
if (styleCache.codeFontFamily.isNotEmpty()) {
|
|
27
|
-
|
|
27
|
+
styleCache.getTypeface(styleCache.codeFontFamily, preservedStyle)
|
|
28
28
|
} else {
|
|
29
29
|
SpanStyleCache.getMonospaceTypeface(preservedStyle)
|
|
30
30
|
}
|
|
@@ -27,7 +27,7 @@ class EmphasisSpan(
|
|
|
27
27
|
tp.typeface =
|
|
28
28
|
if (styleCache.emphasisFontFamily.isNotEmpty()) {
|
|
29
29
|
val resolvedStyle = if (styleCache.emphasisFontStyle == "normal") Typeface.NORMAL else style
|
|
30
|
-
|
|
30
|
+
styleCache.getTypeface(styleCache.emphasisFontFamily, resolvedStyle)
|
|
31
31
|
} else if (styleCache.emphasisFontStyle == "normal") {
|
|
32
32
|
currentTypeface
|
|
33
33
|
} else {
|
|
@@ -7,6 +7,7 @@ import android.graphics.Color
|
|
|
7
7
|
import android.graphics.Paint
|
|
8
8
|
import android.graphics.Path
|
|
9
9
|
import android.graphics.drawable.Drawable
|
|
10
|
+
import android.net.Uri
|
|
10
11
|
import android.os.Build
|
|
11
12
|
import android.text.Spannable
|
|
12
13
|
import android.text.Spanned
|
|
@@ -17,9 +18,12 @@ import androidx.core.graphics.createBitmap
|
|
|
17
18
|
import androidx.core.graphics.drawable.toDrawable
|
|
18
19
|
import androidx.core.graphics.withClip
|
|
19
20
|
import androidx.core.graphics.withSave
|
|
21
|
+
import com.swmansion.enriched.markdown.EnrichedMarkdown
|
|
22
|
+
import com.swmansion.enriched.markdown.EnrichedMarkdownText
|
|
20
23
|
import com.swmansion.enriched.markdown.styles.StyleConfig
|
|
21
24
|
import com.swmansion.enriched.markdown.utils.text.ImageCache
|
|
22
25
|
import com.swmansion.enriched.markdown.utils.text.ImageDownloader
|
|
26
|
+
import com.swmansion.enriched.markdown.utils.text.LocalImageLoader
|
|
23
27
|
import java.lang.ref.WeakReference
|
|
24
28
|
import java.util.concurrent.Executors
|
|
25
29
|
import android.text.style.ImageSpan as AndroidImageSpan
|
|
@@ -39,36 +43,84 @@ class ImageSpan(
|
|
|
39
43
|
AndroidLineHeightSpan {
|
|
40
44
|
private var loadedDrawable: Drawable? = null
|
|
41
45
|
private val height: Int = if (isInline) styleConfig.inlineImageStyle.size.toInt() else styleConfig.imageStyle.height.toInt()
|
|
42
|
-
|
|
46
|
+
|
|
47
|
+
private val borderRadiusPx: Int = styleConfig.imageStyle.borderRadius.toInt()
|
|
48
|
+
private val maxHeightPx: Int = if (isInline) 0 else styleConfig.imageStyle.maxHeight.toInt()
|
|
49
|
+
private val aspectRatio: Float = if (isInline) 0f else styleConfig.imageStyle.aspectRatio
|
|
50
|
+
private val resizeMode: String = if (isInline) "" else styleConfig.imageStyle.resizeMode
|
|
51
|
+
|
|
52
|
+
// so legacy always implies a fixed height box.
|
|
53
|
+
private val legacySizing: Boolean = resizeMode.isEmpty()
|
|
54
|
+
|
|
55
|
+
private val dynamicBoxHeight: Boolean = !isInline && (maxHeightPx > 0 || aspectRatio > 0f)
|
|
56
|
+
|
|
57
|
+
private var boxHeight: Int =
|
|
58
|
+
when {
|
|
59
|
+
isInline -> height
|
|
60
|
+
maxHeightPx > 0 -> maxHeightPx
|
|
61
|
+
else -> height
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
private val requestHeaders: Map<String, String> = styleConfig.imageRequestHeaders
|
|
65
|
+
private val requestKey: String = ImageCache.requestKey(imageUrl, requestHeaders)
|
|
43
66
|
|
|
44
67
|
private var cachedWidth: Int = 0
|
|
45
68
|
private var viewRef: WeakReference<TextView>? = null
|
|
46
69
|
private var sourceDrawable: Drawable? = null
|
|
47
70
|
|
|
71
|
+
private fun intrinsicImageSize(): Pair<Int, Int> {
|
|
72
|
+
sourceDrawable?.let { return it.intrinsicWidth to it.intrinsicHeight }
|
|
73
|
+
val cached = ImageCache.getOriginal(imageUrl) ?: return 0 to 0
|
|
74
|
+
return cached.width to cached.height
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Sizing precedence: aspectRatio > maxHeight > height. Returns the legacy fixed
|
|
78
|
+
// height when no new knob is set.
|
|
79
|
+
private fun resolveBoxHeight(targetWidth: Int): Int {
|
|
80
|
+
if (isInline) return height
|
|
81
|
+
if (aspectRatio > 0f && targetWidth > 0) {
|
|
82
|
+
return (targetWidth / aspectRatio).toInt().coerceAtLeast(1)
|
|
83
|
+
}
|
|
84
|
+
if (maxHeightPx > 0) {
|
|
85
|
+
val (intrinsicWidth, intrinsicHeight) = intrinsicImageSize()
|
|
86
|
+
if (targetWidth > 0 && intrinsicWidth > 0 && intrinsicHeight > 0) {
|
|
87
|
+
val fitted = targetWidth.toFloat() * intrinsicHeight / intrinsicWidth
|
|
88
|
+
return minOf(maxHeightPx.toFloat(), fitted).toInt().coerceAtLeast(1)
|
|
89
|
+
}
|
|
90
|
+
return maxHeightPx
|
|
91
|
+
}
|
|
92
|
+
return height
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
fun prepareForMeasurement(
|
|
96
|
+
text: Spanned,
|
|
97
|
+
widthPx: Int,
|
|
98
|
+
) {
|
|
99
|
+
if (!dynamicBoxHeight || widthPx <= 0) return
|
|
100
|
+
val available = availableWidthIn(text, widthPx)
|
|
101
|
+
if (available > 0) boxHeight = resolveBoxHeight(available)
|
|
102
|
+
}
|
|
103
|
+
|
|
48
104
|
init {
|
|
49
105
|
loadImage()
|
|
50
106
|
}
|
|
51
107
|
|
|
52
108
|
private fun loadImage() {
|
|
53
|
-
|
|
54
|
-
|
|
109
|
+
val scheme = Uri.parse(imageUrl).scheme?.lowercase()
|
|
110
|
+
if (scheme == "http" || scheme == "https") {
|
|
111
|
+
ImageDownloader.download(context, imageUrl, requestHeaders) { bitmap ->
|
|
55
112
|
if (bitmap != null) {
|
|
56
113
|
sourceDrawable = bitmap.toDrawable(context.resources)
|
|
57
114
|
wrapAndAssignDrawable()
|
|
58
115
|
}
|
|
59
116
|
}
|
|
60
117
|
} else {
|
|
61
|
-
val
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
sourceDrawable = bitmap.toDrawable(context.resources)
|
|
68
|
-
wrapAndAssignDrawable()
|
|
69
|
-
}
|
|
70
|
-
} catch (e: Exception) {
|
|
71
|
-
Log.w(TAG, "Failed to load local image: $path", e)
|
|
118
|
+
val cached = ImageCache.getOriginal(imageUrl)
|
|
119
|
+
val bitmap = cached ?: LocalImageLoader.load(context, imageUrl)
|
|
120
|
+
if (bitmap != null) {
|
|
121
|
+
if (cached == null) ImageCache.putOriginal(imageUrl, bitmap)
|
|
122
|
+
sourceDrawable = bitmap.toDrawable(context.resources)
|
|
123
|
+
wrapAndAssignDrawable()
|
|
72
124
|
}
|
|
73
125
|
}
|
|
74
126
|
}
|
|
@@ -83,21 +135,26 @@ class ImageSpan(
|
|
|
83
135
|
available.coerceAtLeast(0)
|
|
84
136
|
}
|
|
85
137
|
|
|
86
|
-
|
|
138
|
+
boxHeight = resolveBoxHeight(targetWidth)
|
|
139
|
+
|
|
140
|
+
val cachedBitmap = ImageCache.getProcessed(requestKey, targetWidth, boxHeight, borderRadiusPx, resizeMode)
|
|
141
|
+
|
|
87
142
|
if (cachedBitmap != null) {
|
|
88
143
|
loadedDrawable =
|
|
89
144
|
cachedBitmap.toDrawable(context.resources).apply {
|
|
90
|
-
setBounds(0, 0, targetWidth,
|
|
145
|
+
setBounds(0, 0, targetWidth, boxHeight)
|
|
91
146
|
}
|
|
92
147
|
} else {
|
|
93
148
|
loadedDrawable =
|
|
94
149
|
ScaledImageDrawable(
|
|
95
150
|
imageDrawable = base,
|
|
96
151
|
targetWidth = targetWidth,
|
|
97
|
-
targetHeight =
|
|
152
|
+
targetHeight = boxHeight,
|
|
98
153
|
borderRadius = borderRadiusPx,
|
|
99
154
|
isBlockImage = !isInline,
|
|
100
|
-
|
|
155
|
+
resizeMode = resizeMode,
|
|
156
|
+
legacySizing = legacySizing,
|
|
157
|
+
cacheKey = CacheKey(requestKey, targetWidth, boxHeight, borderRadiusPx, resizeMode),
|
|
101
158
|
)
|
|
102
159
|
}
|
|
103
160
|
requestReflow()
|
|
@@ -116,6 +173,22 @@ class ImageSpan(
|
|
|
116
173
|
view.invalidate()
|
|
117
174
|
view.requestLayout()
|
|
118
175
|
}
|
|
176
|
+
notifyBoxHeightMayHaveChanged(view)
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// With maxHeight/aspectRatio the box height can change after the image loads
|
|
180
|
+
// (maxHeight fitted, aspectRatio at a late width). The React container height
|
|
181
|
+
// was measured with the pre-load value, so ask the owning component to
|
|
182
|
+
// re-measure; it only propagates when the stored height actually changed.
|
|
183
|
+
private fun notifyBoxHeightMayHaveChanged(view: TextView) {
|
|
184
|
+
if (!dynamicBoxHeight) return
|
|
185
|
+
if (view is EnrichedMarkdownText) {
|
|
186
|
+
view.layoutManager.invalidateLayout()
|
|
187
|
+
return
|
|
188
|
+
}
|
|
189
|
+
var parent = view.parent
|
|
190
|
+
while (parent != null && parent !is EnrichedMarkdown) parent = parent.parent
|
|
191
|
+
parent?.onImageLayoutChanged()
|
|
119
192
|
}
|
|
120
193
|
|
|
121
194
|
fun registerTextView(view: TextView) {
|
|
@@ -137,12 +210,27 @@ class ImageSpan(
|
|
|
137
210
|
cachedWidth = newWidth
|
|
138
211
|
if (sourceDrawable != null) {
|
|
139
212
|
wrapAndAssignDrawable()
|
|
213
|
+
return
|
|
214
|
+
}
|
|
215
|
+
if (dynamicBoxHeight) {
|
|
216
|
+
val newBoxHeight = resolveBoxHeight(newWidth)
|
|
217
|
+
if (newBoxHeight != boxHeight) {
|
|
218
|
+
boxHeight = newBoxHeight
|
|
219
|
+
requestReflow()
|
|
220
|
+
}
|
|
140
221
|
}
|
|
141
222
|
}
|
|
142
223
|
|
|
143
224
|
private fun getAvailableWidth(view: TextView): Int {
|
|
144
225
|
val baseWidth = (view.layout?.width ?: view.width).coerceAtLeast(0)
|
|
145
226
|
val text = view.text as? Spanned ?: return baseWidth
|
|
227
|
+
return availableWidthIn(text, baseWidth)
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
private fun availableWidthIn(
|
|
231
|
+
text: Spanned,
|
|
232
|
+
baseWidth: Int,
|
|
233
|
+
): Int {
|
|
146
234
|
val start = text.getSpanStart(this).takeIf { it >= 0 } ?: return baseWidth
|
|
147
235
|
val end = text.getSpanEnd(this).coerceAtLeast(start)
|
|
148
236
|
// Subtract leading margins (list bullet/indent, blockquote bar) that consume
|
|
@@ -159,7 +247,7 @@ class ImageSpan(
|
|
|
159
247
|
val drawable = loadedDrawable ?: transparentDrawable
|
|
160
248
|
if (drawable !is ScaledImageDrawable) {
|
|
161
249
|
val drawableWidth = if (isInline) height else cachedWidth.takeIf { it > 0 } ?: drawable.intrinsicWidth
|
|
162
|
-
drawable.setBounds(0, 0, drawableWidth.coerceAtLeast(0),
|
|
250
|
+
drawable.setBounds(0, 0, drawableWidth.coerceAtLeast(0), boxHeight.coerceAtLeast(0))
|
|
163
251
|
}
|
|
164
252
|
return drawable
|
|
165
253
|
}
|
|
@@ -182,8 +270,8 @@ class ImageSpan(
|
|
|
182
270
|
) {
|
|
183
271
|
if (fm == null || isInline) return
|
|
184
272
|
val currentLineHeight = fm.descent - fm.ascent
|
|
185
|
-
if (
|
|
186
|
-
val extraHeight =
|
|
273
|
+
if (boxHeight > currentLineHeight) {
|
|
274
|
+
val extraHeight = boxHeight - currentLineHeight
|
|
187
275
|
fm.descent += extraHeight
|
|
188
276
|
fm.bottom += extraHeight
|
|
189
277
|
}
|
|
@@ -217,6 +305,7 @@ class ImageSpan(
|
|
|
217
305
|
val width: Int,
|
|
218
306
|
val height: Int,
|
|
219
307
|
val borderRadius: Int,
|
|
308
|
+
val resizeMode: String,
|
|
220
309
|
)
|
|
221
310
|
|
|
222
311
|
private class ScaledImageDrawable(
|
|
@@ -225,6 +314,8 @@ class ImageSpan(
|
|
|
225
314
|
private val targetHeight: Int,
|
|
226
315
|
private val borderRadius: Int,
|
|
227
316
|
isBlockImage: Boolean,
|
|
317
|
+
private val resizeMode: String = "",
|
|
318
|
+
private val legacySizing: Boolean = true,
|
|
228
319
|
private val cacheKey: CacheKey? = null,
|
|
229
320
|
) : Drawable() {
|
|
230
321
|
private val clipPath: Path?
|
|
@@ -235,14 +326,26 @@ class ImageSpan(
|
|
|
235
326
|
val intrinsicWidth = imageDrawable.intrinsicWidth
|
|
236
327
|
val intrinsicHeight = imageDrawable.intrinsicHeight
|
|
237
328
|
|
|
329
|
+
// New sizing needs a clip to the box so cropping
|
|
330
|
+
// modes don't spill over neighbouring lines.
|
|
331
|
+
val clipToBox = isBlockImage && !legacySizing
|
|
332
|
+
|
|
238
333
|
val (scaledWidth, scaledHeight) =
|
|
239
334
|
if (intrinsicWidth > 0 && intrinsicHeight > 0) {
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
335
|
+
when {
|
|
336
|
+
!isBlockImage -> {
|
|
337
|
+
val scale = minOf(targetWidth.toFloat() / intrinsicWidth, targetHeight.toFloat() / intrinsicHeight)
|
|
338
|
+
(intrinsicWidth * scale).toInt() to (intrinsicHeight * scale).toInt()
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
legacySizing -> {
|
|
342
|
+
val scale = targetWidth.toFloat() / intrinsicWidth
|
|
343
|
+
targetWidth to (intrinsicHeight * scale).toInt()
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
else -> {
|
|
347
|
+
resizeModeSize(intrinsicWidth, intrinsicHeight)
|
|
348
|
+
}
|
|
246
349
|
}
|
|
247
350
|
} else {
|
|
248
351
|
targetWidth to targetHeight
|
|
@@ -252,26 +355,53 @@ class ImageSpan(
|
|
|
252
355
|
val top = (targetHeight - scaledHeight) / 2
|
|
253
356
|
imageDrawable.setBounds(left, top, left + scaledWidth, top + scaledHeight)
|
|
254
357
|
|
|
358
|
+
val clipLeft = maxOf(0, left).toFloat()
|
|
359
|
+
val clipTop = maxOf(0, top).toFloat()
|
|
360
|
+
val clipRight = minOf(targetWidth, left + scaledWidth).toFloat()
|
|
361
|
+
val clipBottom = minOf(targetHeight, top + scaledHeight).toFloat()
|
|
255
362
|
clipPath =
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
Path.Direction.CW,
|
|
270
|
-
)
|
|
363
|
+
when {
|
|
364
|
+
borderRadius > 0 -> {
|
|
365
|
+
Path().apply {
|
|
366
|
+
addRoundRect(
|
|
367
|
+
clipLeft,
|
|
368
|
+
clipTop,
|
|
369
|
+
clipRight,
|
|
370
|
+
clipBottom,
|
|
371
|
+
borderRadius.toFloat(),
|
|
372
|
+
borderRadius.toFloat(),
|
|
373
|
+
Path.Direction.CW,
|
|
374
|
+
)
|
|
375
|
+
}
|
|
271
376
|
}
|
|
272
|
-
|
|
273
|
-
|
|
377
|
+
|
|
378
|
+
clipToBox -> {
|
|
379
|
+
Path().apply {
|
|
380
|
+
addRect(clipLeft, clipTop, clipRight, clipBottom, Path.Direction.CW)
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
else -> {
|
|
385
|
+
null
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
private fun resizeModeSize(
|
|
391
|
+
intrinsicWidth: Int,
|
|
392
|
+
intrinsicHeight: Int,
|
|
393
|
+
): Pair<Int, Int> {
|
|
394
|
+
if (resizeMode == "stretch") return targetWidth to targetHeight
|
|
395
|
+
val widthScale = targetWidth.toFloat() / intrinsicWidth
|
|
396
|
+
val heightScale = targetHeight.toFloat() / intrinsicHeight
|
|
397
|
+
val scale =
|
|
398
|
+
when (resizeMode) {
|
|
399
|
+
"contain" -> minOf(widthScale, heightScale)
|
|
400
|
+
"center" -> minOf(1f, minOf(widthScale, heightScale))
|
|
401
|
+
"none" -> 1f
|
|
402
|
+
else -> maxOf(widthScale, heightScale) // cover (default)
|
|
274
403
|
}
|
|
404
|
+
return (intrinsicWidth * scale).toInt() to (intrinsicHeight * scale).toInt()
|
|
275
405
|
}
|
|
276
406
|
|
|
277
407
|
override fun draw(canvas: Canvas) {
|
|
@@ -303,7 +433,14 @@ class ImageSpan(
|
|
|
303
433
|
} else {
|
|
304
434
|
source.draw(offscreen)
|
|
305
435
|
}
|
|
306
|
-
ImageCache.putProcessed(
|
|
436
|
+
ImageCache.putProcessed(
|
|
437
|
+
cachedKey.url,
|
|
438
|
+
cachedKey.width,
|
|
439
|
+
cachedKey.height,
|
|
440
|
+
cachedKey.borderRadius,
|
|
441
|
+
cachedKey.resizeMode,
|
|
442
|
+
bitmap,
|
|
443
|
+
)
|
|
307
444
|
} catch (_: OutOfMemoryError) {
|
|
308
445
|
Log.e("ScaledImageDrawable", "OOM caching bitmap ${width}x$height")
|
|
309
446
|
}
|
|
@@ -328,7 +465,6 @@ class ImageSpan(
|
|
|
328
465
|
}
|
|
329
466
|
|
|
330
467
|
companion object {
|
|
331
|
-
private const val TAG = "ImageSpan"
|
|
332
468
|
private val transparentDrawable by lazy { Color.TRANSPARENT.toDrawable() }
|
|
333
469
|
private val cacheExecutor = Executors.newSingleThreadExecutor()
|
|
334
470
|
}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
package com.swmansion.enriched.markdown.spans
|
|
2
|
+
|
|
3
|
+
import android.graphics.Canvas
|
|
4
|
+
import android.graphics.Paint
|
|
5
|
+
import android.graphics.Path
|
|
6
|
+
import android.graphics.RectF
|
|
7
|
+
import android.text.Spanned
|
|
8
|
+
import android.text.StaticLayout
|
|
9
|
+
import android.text.TextPaint
|
|
10
|
+
import android.text.style.LeadingMarginSpan
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Shared geometry and drawing for inline "chips" painted from a [android.text.style.LineBackgroundSpan]
|
|
14
|
+
* (inline code, link chips). For a chip that wraps, only the outer ends are rounded and the border
|
|
15
|
+
* stays open where a fragment is cut.
|
|
16
|
+
*/
|
|
17
|
+
internal object InlineChipPainter {
|
|
18
|
+
/**
|
|
19
|
+
* Returns the x position of [index] relative to the line's left edge, including any
|
|
20
|
+
* leading margin. The measuring StaticLayout is built from a subSequence that keeps
|
|
21
|
+
* all spans, so LeadingMarginSpans (lists, blockquotes) are already applied to
|
|
22
|
+
* getPrimaryHorizontal; adding the margin again on top would shift the background
|
|
23
|
+
* right by the indent. The margin is only added explicitly in the early-return case,
|
|
24
|
+
* where no layout is built.
|
|
25
|
+
*/
|
|
26
|
+
fun horizontalOffset(
|
|
27
|
+
text: CharSequence,
|
|
28
|
+
lineStart: Int,
|
|
29
|
+
lineEnd: Int,
|
|
30
|
+
index: Int,
|
|
31
|
+
paint: Paint,
|
|
32
|
+
leadingMargin: Int,
|
|
33
|
+
): Float {
|
|
34
|
+
if (index <= lineStart) return leadingMargin.toFloat()
|
|
35
|
+
val lineText = text.subSequence(lineStart, lineEnd)
|
|
36
|
+
val textPaint = paint as? TextPaint ?: TextPaint(paint)
|
|
37
|
+
val layout = StaticLayout.Builder.obtain(lineText, 0, lineText.length, textPaint, 10000).build()
|
|
38
|
+
return layout.getPrimaryHorizontal(index - lineStart)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fun leadingMarginAt(
|
|
42
|
+
text: Spanned,
|
|
43
|
+
lineStart: Int,
|
|
44
|
+
): Int {
|
|
45
|
+
if (lineStart >= text.length) return 0
|
|
46
|
+
val spans = text.getSpans(lineStart, lineStart + 1, LeadingMarginSpan::class.java)
|
|
47
|
+
var margin = 0
|
|
48
|
+
for (span in spans) {
|
|
49
|
+
margin += span.getLeadingMargin(false)
|
|
50
|
+
}
|
|
51
|
+
return margin
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Fills [rect] and strokes its border. [strokeInset] keeps a closed border inside [rect]
|
|
56
|
+
* (link chips); otherwise it is centered on the edge (inline code, kept for pixel parity).
|
|
57
|
+
* [path] is caller-owned scratch space to avoid per-draw allocations.
|
|
58
|
+
*/
|
|
59
|
+
fun draw(
|
|
60
|
+
canvas: Canvas,
|
|
61
|
+
rect: RectF,
|
|
62
|
+
path: Path,
|
|
63
|
+
cornerRadius: Float,
|
|
64
|
+
backgroundPaint: Paint?,
|
|
65
|
+
borderPaint: Paint?,
|
|
66
|
+
isFirst: Boolean,
|
|
67
|
+
isLast: Boolean,
|
|
68
|
+
strokeInset: Boolean,
|
|
69
|
+
) {
|
|
70
|
+
val r = minOf(maxOf(cornerRadius, 0f), minOf(rect.width(), rect.height()) / 2f)
|
|
71
|
+
|
|
72
|
+
if (backgroundPaint != null) {
|
|
73
|
+
path.reset()
|
|
74
|
+
path.addRoundRect(rect, radii(r, isFirst, isLast), Path.Direction.CW)
|
|
75
|
+
canvas.drawPath(path, backgroundPaint)
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (borderPaint == null || borderPaint.strokeWidth <= 0f) return
|
|
79
|
+
|
|
80
|
+
path.reset()
|
|
81
|
+
if (isFirst && isLast) {
|
|
82
|
+
if (strokeInset) {
|
|
83
|
+
val inset = borderPaint.strokeWidth / 2f
|
|
84
|
+
val insetRect = RectF(rect.left + inset, rect.top + inset, rect.right - inset, rect.bottom - inset)
|
|
85
|
+
path.addRoundRect(insetRect, radii(maxOf(r - inset, 0f), true, true), Path.Direction.CW)
|
|
86
|
+
} else {
|
|
87
|
+
path.addRoundRect(rect, radii(r, true, true), Path.Direction.CW)
|
|
88
|
+
}
|
|
89
|
+
} else {
|
|
90
|
+
val inset = if (strokeInset) borderPaint.strokeWidth / 2f else 0f
|
|
91
|
+
addOpenBorder(path, rect, r, inset, isFirst, isLast)
|
|
92
|
+
}
|
|
93
|
+
canvas.drawPath(path, borderPaint)
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
private fun addOpenBorder(
|
|
97
|
+
path: Path,
|
|
98
|
+
rect: RectF,
|
|
99
|
+
r: Float,
|
|
100
|
+
inset: Float,
|
|
101
|
+
isFirst: Boolean,
|
|
102
|
+
isLast: Boolean,
|
|
103
|
+
) {
|
|
104
|
+
val left = rect.left + inset
|
|
105
|
+
val top = rect.top + inset
|
|
106
|
+
val right = rect.right - inset
|
|
107
|
+
val bottom = rect.bottom - inset
|
|
108
|
+
|
|
109
|
+
if (isFirst) {
|
|
110
|
+
path.moveTo(rect.right, top)
|
|
111
|
+
path.lineTo(left + r, top)
|
|
112
|
+
path.quadTo(left, top, left, top + r)
|
|
113
|
+
path.lineTo(left, bottom - r)
|
|
114
|
+
path.quadTo(left, bottom, left + r, bottom)
|
|
115
|
+
path.lineTo(rect.right, bottom)
|
|
116
|
+
} else if (isLast) {
|
|
117
|
+
path.moveTo(rect.left, top)
|
|
118
|
+
path.lineTo(right - r, top)
|
|
119
|
+
path.quadTo(right, top, right, top + r)
|
|
120
|
+
path.lineTo(right, bottom - r)
|
|
121
|
+
path.quadTo(right, bottom, right - r, bottom)
|
|
122
|
+
path.lineTo(rect.left, bottom)
|
|
123
|
+
} else {
|
|
124
|
+
path.moveTo(rect.left, top)
|
|
125
|
+
path.lineTo(rect.right, top)
|
|
126
|
+
path.moveTo(rect.left, bottom)
|
|
127
|
+
path.lineTo(rect.right, bottom)
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
private fun radii(
|
|
132
|
+
r: Float,
|
|
133
|
+
isFirst: Boolean,
|
|
134
|
+
isLast: Boolean,
|
|
135
|
+
): FloatArray {
|
|
136
|
+
val left = if (isFirst) r else 0f
|
|
137
|
+
val right = if (isLast) r else 0f
|
|
138
|
+
return floatArrayOf(left, left, right, right, right, right, left, left)
|
|
139
|
+
}
|
|
140
|
+
}
|