capacitor-sora-editor 1.2.1 → 1.8.2

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.
Files changed (571) hide show
  1. package/DEPENDENCY_SOLUTION.md +87 -87
  2. package/DEVELOPMENT.md +152 -152
  3. package/NO_JITPACK_WARNING.md +14 -14
  4. package/README.md +36 -0
  5. package/WORDWRAP_FLICKER_FIX.md +268 -205
  6. package/android/sora-editor/editor/src/main/AndroidManifest.xml +1 -1
  7. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/I18nConfig.kt +42 -0
  8. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/annotations/Experimental.kt +16 -0
  9. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/annotations/InvalidateRequired.kt +10 -0
  10. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/annotations/UnsupportedUserUsage.kt +14 -0
  11. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/ClickEvent.kt +22 -0
  12. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/ColorSchemeUpdateEvent.kt +1 -1
  13. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/ContentChangeEvent.kt +41 -0
  14. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/DoubleClickEvent.kt +23 -0
  15. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/EditorKeyEvent.kt +103 -0
  16. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/EditorMotionEvent.kt +111 -0
  17. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/Event.kt +69 -0
  18. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/EventManager.kt +267 -0
  19. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/EventReceiver.kt +5 -0
  20. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/HandleStateChangeEvent.kt +21 -0
  21. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/InterceptTarget.kt +18 -0
  22. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/KeyBindingEvent.kt +34 -0
  23. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/LongPressEvent.kt +25 -0
  24. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/ResultedEvent.kt +21 -0
  25. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/ScrollEvent.kt +48 -0
  26. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/SelectionChangeEvent.kt +81 -0
  27. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/SideIconClickEvent.kt +1 -1
  28. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/SnippetEvent.kt +41 -0
  29. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/SubscriptionReceipt.kt +35 -0
  30. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/Unsubscribe.kt +28 -0
  31. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/Utils.kt +1 -1
  32. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/editorMinorEvents.kt +1 -1
  33. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/BubbleHelper.kt +59 -0
  34. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/BufferedDrawPoints.kt +37 -0
  35. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/GraphemeBoundsBreaker.kt +31 -0
  36. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/GraphicCharacter.kt +28 -0
  37. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/GraphicsCompat.kt +48 -0
  38. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/Paint.kt +191 -0
  39. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/RectUtils.kt +16 -0
  40. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/SingleCharacterWidths.kt +156 -0
  41. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/TextRow.kt +1465 -0
  42. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/TextRowParams.kt +1 -1
  43. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/inlayHint/ColorInlayHintRenderer.kt +1 -1
  44. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/inlayHint/InlayHintRenderer.kt +2 -2
  45. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/inlayHint/InlayHintRendererProvider.kt +1 -1
  46. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/inlayHint/TextInlayHintRenderer.kt +2 -2
  47. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/EmptyLanguage.kt +94 -0
  48. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/Language.kt +188 -0
  49. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/QuickQuoteHandler.kt +46 -0
  50. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/AnalyzeManager.kt +67 -0
  51. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/AsyncIncrementalAnalyzeManager.kt +504 -0
  52. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/IncrementalAnalyzeManager.kt +93 -0
  53. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/SequenceUpdateRange.kt +1 -1
  54. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/SimpleAnalyzeManager.kt +194 -0
  55. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/StyleReceiver.kt +63 -0
  56. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/StyleUpdateRange.kt +1 -1
  57. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/brackets/BracketsProvider.kt +21 -0
  58. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/brackets/OnlineBracketsMatcher.kt +83 -0
  59. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/brackets/PairedBracket.kt +13 -0
  60. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/brackets/SimpleBracketsCollector.kt +53 -0
  61. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/CompletionCancelledException.kt +14 -0
  62. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/CompletionHelper.kt +48 -0
  63. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/CompletionItem.kt +131 -0
  64. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/CompletionItemKind.kt +1 -1
  65. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/CompletionPublisher.kt +250 -0
  66. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/IdentifierAutoComplete.kt +352 -0
  67. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/MatchHelper.kt +126 -0
  68. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/SimpleCompletionIconDrawer.kt +1 -1
  69. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/SimpleCompletionItem.kt +77 -0
  70. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/SimpleSnippetCompletionItem.kt +35 -0
  71. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/SnippetDescription.kt +1 -1
  72. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/comparators.kt +1 -1
  73. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/filters.kt +3 -3
  74. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/CodeSnippet.kt +171 -0
  75. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/ConditionalFormat.kt +8 -0
  76. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/FormatString.kt +3 -0
  77. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/InterpolatedShellItem.kt +13 -0
  78. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/NextUpperCaseFormat.kt +3 -0
  79. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/NoFormat.kt +3 -0
  80. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/PlaceHolderElement.kt +1 -1
  81. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/PlaceholderDefinition.kt +2 -2
  82. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/PlaceholderItem.kt +22 -0
  83. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/PlainPlaceholderElement.kt +1 -1
  84. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/PlainTextItem.kt +17 -0
  85. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/SnippetItem.kt +33 -0
  86. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/Transform.kt +15 -0
  87. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/VariableItem.kt +15 -0
  88. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/parser/CodeSnippetParser.kt +544 -0
  89. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/parser/CodeSnippetTokenizer.kt +108 -0
  90. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/parser/Token.kt +7 -0
  91. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/parser/TokenType.kt +20 -0
  92. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/diagnostic/DiagnosticDetail.kt +1 -1
  93. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/diagnostic/DiagnosticRegion.kt +56 -0
  94. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/diagnostic/DiagnosticsContainer.kt +109 -0
  95. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/diagnostic/Quickfix.kt +1 -1
  96. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/folding/FoldingRegion.kt +50 -0
  97. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/format/AsyncFormatter.kt +182 -0
  98. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/format/Formatter.kt +72 -0
  99. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/smartEnter/NewlineHandleResult.kt +18 -0
  100. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/smartEnter/NewlineHandler.kt +32 -0
  101. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/BlocksUpdater.kt +34 -0
  102. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/CodeBlock.kt +165 -0
  103. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/EmptyReader.kt +30 -0
  104. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/HighlightTextContainer.kt +1 -1
  105. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/MappedSpanUpdater.kt +180 -0
  106. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/MappedSpans.kt +210 -0
  107. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/Span.kt +139 -0
  108. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/SpanFactory.kt +41 -0
  109. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/SpanPool.kt +1 -1
  110. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/Spans.kt +104 -0
  111. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/Styles.kt +219 -0
  112. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/StylesUtils.kt +82 -0
  113. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/TextStyle.kt +130 -31
  114. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/color/ConstColor.kt +1 -1
  115. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/color/EditorColor.kt +1 -1
  116. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/color/ResolvableColor.kt +1 -1
  117. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/inlayHint/InlayHint.kt +1 -1
  118. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/inlayHint/InlayHintsContainer.kt +1 -1
  119. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/inlayHint/IntSetUpdateRange.kt +1 -1
  120. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/inlayHint/SparseUpdateRange.kt +1 -1
  121. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/inlayHint/inlayHints.kt +1 -1
  122. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/line/LineAnchorStyle.kt +2 -2
  123. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/line/LineBackground.kt +2 -2
  124. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/line/LineGutterBackground.kt +1 -1
  125. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/line/LineSideIcon.kt +1 -1
  126. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/line/LineStyles.kt +1 -1
  127. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/patching/SparseStylePatches.kt +2 -2
  128. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/patching/StylePatch.kt +1 -1
  129. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/SpanClickableUrl.kt +1 -1
  130. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/SpanColorResolver.kt +1 -1
  131. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/SpanConstColorResolver.kt +1 -1
  132. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/SpanExt.kt +1 -1
  133. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/SpanExtAttrs.kt +39 -0
  134. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/SpanExternalRenderer.kt +1 -1
  135. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/SpanInteractionInfo.kt +1 -1
  136. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/internal/NoExtSpanImpl.kt +89 -0
  137. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/internal/SpanImpl.kt +103 -0
  138. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/util/PointAnchorContainer.kt +1 -1
  139. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/util/BaseAnalyzeManager.kt +44 -0
  140. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/util/PlainTextAnalyzeManager.kt +30 -0
  141. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/util/PlainTextSpans.kt +42 -0
  142. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/{AndroidEmoji.java → AndroidEmoji.kt} +29 -27
  143. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/CachedIndexer.kt +408 -0
  144. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/CharArrayWrapper.kt +40 -0
  145. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/CharPosition.kt +97 -0
  146. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/CharSequenceIterator.kt +66 -0
  147. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ComposingText.kt +72 -0
  148. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/Content.kt +889 -33
  149. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/{widget/component/EditorBuiltinComponent.java → text/ContentExtensions.kt} +14 -24
  150. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ContentIO.kt +149 -0
  151. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ContentLine.kt +252 -0
  152. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ContentListener.kt +67 -0
  153. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ContentReference.kt +177 -0
  154. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/Cursor.kt +316 -0
  155. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/FunctionCharacters.kt +46 -0
  156. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ICUUtils.kt +58 -0
  157. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/Indexer.kt +63 -0
  158. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/InsertTextHelper.kt +95 -0
  159. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/LineSeparator.kt +51 -0
  160. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/SpanRecycler.kt +71 -0
  161. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/TextLayoutHelper.kt +105 -0
  162. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/TextRange.kt +48 -0
  163. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/TextReference.kt +91 -0
  164. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/TextUtils.kt +181 -0
  165. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/TextUtilsP.kt +232 -0
  166. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/UndoManager.kt +569 -0
  167. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/UnicodeIterator.kt +69 -0
  168. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/BidiRequirementChecker.kt +5 -0
  169. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/ContentBidi.kt +104 -0
  170. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/Directions.kt +43 -0
  171. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/IDirections.kt +9 -0
  172. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/TextBidi.kt +67 -0
  173. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/VisualDirections.kt +45 -0
  174. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/breaker/WordBreaker.kt +19 -0
  175. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/breaker/WordBreakerEmpty.kt +13 -0
  176. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/breaker/WordBreakerIcu.kt +36 -0
  177. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/breaker/WordBreakerProgram.kt +23 -0
  178. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/method/KeyMetaStates.kt +55 -0
  179. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/BinaryHeap.kt +216 -0
  180. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/BlockIntList.kt +314 -0
  181. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/CharCode.kt +1 -1
  182. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/Chars.kt +1 -1
  183. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/ClipDataUtils.kt +29 -0
  184. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/EditorHandler.kt +1 -1
  185. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/Floats.kt +10 -0
  186. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/IntPair.kt +76 -0
  187. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/KeyboardUtils.kt +1 -1
  188. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/Logger.kt +78 -0
  189. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/LongArrayList.kt +104 -0
  190. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/MutableInt.kt +14 -0
  191. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/MutableIntList.kt +35 -0
  192. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/MutableLongLongMap.kt +36 -0
  193. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/MyCharacter.kt +127 -0
  194. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/Numbers.kt +109 -0
  195. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/ObjectPool.kt +44 -0
  196. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/RegionIterator.kt +123 -0
  197. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/RendererUtils.kt +1 -1
  198. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/ReversedListView.kt +1 -1
  199. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/SegmentList.kt +273 -0
  200. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/ShareableData.kt +1 -1
  201. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/TemporaryCharBuffer.kt +31 -0
  202. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/TemporaryFloatBuffer.kt +44 -0
  203. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/ThemeUtils.kt +14 -0
  204. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/TrieTree.kt +137 -0
  205. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/ViewUtils.kt +39 -0
  206. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/regex/RegexBackrefGrammar.kt +11 -0
  207. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/regex/RegexBackrefHelper.kt +27 -0
  208. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/regex/RegexBackrefParser.kt +89 -0
  209. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/regex/RegexBackrefToken.kt +16 -0
  210. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/CodeEditor.kt +5509 -0
  211. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/CursorBlink.kt +78 -0
  212. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/DirectAccessProps.kt +604 -0
  213. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/Editor.kt +1 -1
  214. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorInputConnection.kt +708 -0
  215. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorKeyEventHandler.kt +678 -0
  216. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorRenderer.kt +3542 -0
  217. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorScroller.kt +89 -0
  218. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorSearcher.kt +531 -0
  219. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorStyleDelegate.kt +109 -0
  220. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorTouchEventHandler.kt +1349 -0
  221. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/LanguageHelper.kt +38 -0
  222. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/RegionResolver.kt +1 -1
  223. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/SelectionMovement.kt +27 -37
  224. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/SymbolInputView.kt +103 -0
  225. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/SymbolPairMatch.kt +261 -0
  226. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/base/EditorPopupWindow.kt +244 -0
  227. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/CompletionLayout.kt +59 -0
  228. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/DefaultCompletionItemAdapter.kt +60 -0
  229. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/DefaultCompletionLayout.kt +225 -0
  230. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/EditorAutoCompletion.kt +300 -0
  231. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/EditorBuiltinComponent.kt +15 -0
  232. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/EditorCompletionAdapter.kt +87 -0
  233. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/EditorContextMenuCreator.kt +6 -28
  234. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/EditorDiagnosticTooltipWindow.kt +27 -20
  235. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/EditorTextActionWindow.kt +358 -0
  236. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/Magnifier.kt +354 -0
  237. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/ext/EditorSpanInteractionHandler.kt +3 -3
  238. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/AbstractLayout.kt +126 -0
  239. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/{Layout.java → Layout.kt} +30 -63
  240. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/LineBreakLayout.kt +370 -0
  241. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/Row.kt +57 -0
  242. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/RowElement.kt +52 -0
  243. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/RowElementTypes.kt +18 -0
  244. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/RowIterator.kt +38 -0
  245. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/ViewMeasureHelper.kt +135 -0
  246. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/WordwrapLayout.kt +703 -0
  247. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/rendering/MeasureCacheItem.kt +1 -1
  248. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/rendering/RenderCache.kt +1 -1
  249. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/rendering/RenderContext.kt +1 -1
  250. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/rendering/RenderNodeHolder.kt +3 -25
  251. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/rendering/RenderingConstants.kt +53 -0
  252. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/rendering/TextAdvancesCache.kt +89 -0
  253. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/EditorColorScheme.kt +393 -0
  254. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/SchemeDarcula.kt +40 -0
  255. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/SchemeEclipse.kt +34 -0
  256. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/SchemeGitHub.kt +28 -0
  257. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/SchemeNotepadXX.kt +34 -0
  258. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/SchemeVS2019.kt +40 -0
  259. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/SnippetController.kt +4 -3
  260. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/TransformApplier.kt +103 -0
  261. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/ClipboardBasedSnippetVariableResolver.kt +21 -0
  262. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/CommentBasedSnippetVariableResolver.kt +23 -0
  263. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/CompositeSnippetVariableResolver.kt +35 -0
  264. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/EditorBasedSnippetVariableResolver.kt +36 -0
  265. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/FileBasedSnippetVariableResolver.kt +11 -0
  266. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/ISnippetVariableResolver.kt +21 -0
  267. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/RandomBasedSnippetVariableResolver.kt +22 -0
  268. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/TimeBasedSnippetVariableResolver.kt +58 -0
  269. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/WorkspaceBasedSnippetVariableResolver.kt +11 -0
  270. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/CursorAnimator.kt +54 -0
  271. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/DiagnosticIndicatorStyle.kt +13 -0
  272. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/LineInfoPanelPosition.kt +9 -0
  273. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/LineInfoPanelPositionMode.kt +6 -0
  274. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/LineNumberTipTextProvider.kt +1 -1
  275. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/SelectionHandleStyle.kt +82 -0
  276. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/DefaultLineNumberTip.kt +1 -1
  277. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/FadeCursorAnimator.kt +143 -0
  278. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/HandleStyleDrop.kt +66 -0
  279. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/HandleStyleNone.kt +30 -0
  280. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/HandleStyleSideDrop.kt +62 -0
  281. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/MoveCursorAnimator.kt +127 -0
  282. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/ScaleCursorAnimator.kt +134 -0
  283. package/android/sora-editor/editor/src/main/res/anim/anim_diagnostic_tooltip_window_enter.xml +1 -1
  284. package/android/sora-editor/editor/src/main/res/anim/anim_diagnostic_tooltip_window_exit.xml +1 -1
  285. package/android/sora-editor/editor/src/main/res/anim/anim_text_action_popup_enter.xml +1 -1
  286. package/android/sora-editor/editor/src/main/res/anim/anim_text_action_popup_exit.xml +1 -1
  287. package/android/sora-editor/editor/src/main/res/drawable/baseline_more_vert_24.xml +1 -1
  288. package/android/sora-editor/editor/src/main/res/drawable/editor_text_select_start.xml +1 -1
  289. package/android/sora-editor/editor/src/main/res/drawable/ic_more_vert_black_20dp.xml +1 -1
  290. package/android/sora-editor/editor/src/main/res/drawable/ic_sora_handle_drop.xml +1 -1
  291. package/android/sora-editor/editor/src/main/res/drawable/line_break.xml +1 -1
  292. package/android/sora-editor/editor/src/main/res/drawable/magnifier_background.xml +1 -1
  293. package/android/sora-editor/editor/src/main/res/drawable/round_content_copy_20.xml +1 -1
  294. package/android/sora-editor/editor/src/main/res/drawable/round_content_cut_20.xml +1 -1
  295. package/android/sora-editor/editor/src/main/res/drawable/round_content_paste_20.xml +1 -1
  296. package/android/sora-editor/editor/src/main/res/drawable/round_save_20.xml +1 -1
  297. package/android/sora-editor/editor/src/main/res/drawable/round_select_all_20.xml +1 -1
  298. package/android/sora-editor/editor/src/main/res/drawable/softwrap_left.xml +1 -1
  299. package/android/sora-editor/editor/src/main/res/drawable/softwrap_right.xml +1 -1
  300. package/android/sora-editor/editor/src/main/res/layout/default_completion_result_item.xml +1 -1
  301. package/android/sora-editor/editor/src/main/res/layout/diagnostic_tooltip_window.xml +1 -1
  302. package/android/sora-editor/editor/src/main/res/layout/magnifier_popup.xml +1 -1
  303. package/android/sora-editor/editor/src/main/res/layout/text_compose_panel.xml +2 -1
  304. package/android/sora-editor/editor/src/main/res/values/attrs.xml +1 -1
  305. package/android/sora-editor/editor/src/main/res/values/colors.xml +1 -1
  306. package/android/sora-editor/editor/src/main/res/values/dimens.xml +1 -1
  307. package/android/sora-editor/editor/src/main/res/values/strings.xml +1 -1
  308. package/android/sora-editor/editor/src/main/res/values/style.xml +1 -1
  309. package/android/sora-editor/editor/src/main/res/values-night/colors.xml +1 -1
  310. package/android/sora-editor/editor/src/main/res/values-zh/strings.xml +1 -1
  311. package/android/sora-editor/language-textmate/src/main/AndroidManifest.xml +1 -1
  312. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/MyState.kt +11 -0
  313. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/TextMateAnalyzer.kt +269 -0
  314. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/TextMateColorScheme.kt +298 -0
  315. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/TextMateLanguage.kt +219 -0
  316. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/TextMateNewlineHandler.kt +268 -0
  317. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/TextMateSymbolPairMatch.kt +167 -0
  318. package/android/sora-editor/{editor/src/main/java/io/github/abc15018045126/sora/event/EventReceiver.java → language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/FoldingHelper.kt} +7 -6
  319. package/android/sora-editor/{editor/src/main/java/io/github/abc15018045126/sora/util/MutableInt.java → language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/FoldingRegion.kt} +12 -14
  320. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/FoldingRegions.kt +93 -0
  321. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/IndentRange.kt +156 -0
  322. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/PreviousRegion.kt +7 -0
  323. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/RangesCollector.kt +25 -0
  324. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/FileProviderRegistry.kt +53 -0
  325. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/GrammarRegistry.kt +222 -0
  326. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/ThemeRegistry.kt +121 -0
  327. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/dsl/GrammarDefinitionDSL.kt +1 -1
  328. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/model/DefaultGrammarDefinition.kt +68 -0
  329. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/model/GrammarDefinition.kt +12 -0
  330. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/model/ThemeModel.kt +50 -0
  331. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/provider/AssetsFileResolver.java +1 -23
  332. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/provider/FileResolver.java +1 -23
  333. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/reader/LanguageDefinitionReader.java +1 -23
  334. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/utils/ColorUtils.kt +57 -0
  335. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/utils/MatcherUtils.kt +29 -0
  336. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/utils/StringUtils.kt +46 -0
  337. package/android/sora-editor/oniguruma-native/src/main/java/io/github/abc15018045126/oniguruma/OnigNative.kt +95 -0
  338. package/android/src/main/java/com/abc15018045126/capacitor/soraeditor/SoraEditorPlugin.kt +342 -337
  339. package/android/src/main/java/com/abc15018045126/capacitor/soraeditor/compose/ComposeEditorActivity.kt +63 -63
  340. package/android/src/main/java/com/abc15018045126/capacitor/soraeditor/compose/EditorViewModel.kt +141 -5
  341. package/android/src/main/java/com/abc15018045126/capacitor/soraeditor/compose/ui/EditorColorSettings.kt +190 -0
  342. package/android/src/main/java/com/abc15018045126/capacitor/soraeditor/compose/ui/EditorScreen.kt +390 -234
  343. package/android/src/main/java/com/abc15018045126/capacitor/soraeditor/compose/ui/SoraEditorWrapper.kt +104 -104
  344. package/android/src/main/java/com/abc15018045126/capacitor/soraeditor/compose/ui/theme/Theme.kt +38 -38
  345. package/package.json +1 -1
  346. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/I18nConfig.java +0 -69
  347. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/annotations/Experimental.java +0 -41
  348. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/annotations/InvalidateRequired.java +0 -40
  349. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/annotations/UnsupportedUserUsage.java +0 -39
  350. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/ClickEvent.java +0 -49
  351. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/ContentChangeEvent.java +0 -122
  352. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/DoubleClickEvent.java +0 -50
  353. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/EditorKeyEvent.java +0 -157
  354. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/EditorMotionEvent.java +0 -212
  355. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/Event.java +0 -132
  356. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/EventManager.java +0 -328
  357. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/HandleStateChangeEvent.java +0 -67
  358. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/InterceptTarget.java +0 -44
  359. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/KeyBindingEvent.java +0 -77
  360. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/LongPressEvent.java +0 -53
  361. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/ResultedEvent.java +0 -63
  362. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/ScrollEvent.java +0 -126
  363. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/SelectionChangeEvent.java +0 -155
  364. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/SnippetEvent.java +0 -92
  365. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/SubscriptionReceipt.java +0 -67
  366. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/event/Unsubscribe.java +0 -60
  367. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/BubbleHelper.java +0 -76
  368. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/BufferedDrawPoints.java +0 -66
  369. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/GraphemeBoundsBreaker.java +0 -55
  370. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/GraphicCharacter.java +0 -52
  371. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/GraphicsCompat.java +0 -55
  372. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/Paint.java +0 -159
  373. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/RectUtils.java +0 -39
  374. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/SingleCharacterWidths.java +0 -160
  375. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/graphics/TextRow.java +0 -1402
  376. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/EmptyLanguage.java +0 -159
  377. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/Language.java +0 -215
  378. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/QuickQuoteHandler.java +0 -78
  379. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/AnalyzeManager.java +0 -97
  380. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/AsyncIncrementalAnalyzeManager.java +0 -604
  381. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/IncrementalAnalyzeManager.java +0 -120
  382. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/SimpleAnalyzeManager.java +0 -238
  383. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/analysis/StyleReceiver.java +0 -90
  384. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/brackets/BracketsProvider.java +0 -49
  385. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/brackets/OnlineBracketsMatcher.java +0 -112
  386. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/brackets/PairedBracket.java +0 -57
  387. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/brackets/SimpleBracketsCollector.java +0 -83
  388. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/CompletionCancelledException.java +0 -44
  389. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/CompletionHelper.java +0 -72
  390. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/CompletionItem.java +0 -163
  391. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/CompletionPublisher.java +0 -284
  392. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/IdentifierAutoComplete.java +0 -359
  393. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/MatchHelper.java +0 -131
  394. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/SimpleCompletionItem.java +0 -112
  395. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/SimpleSnippetCompletionItem.java +0 -71
  396. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/CodeSnippet.java +0 -223
  397. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/ConditionalFormat.java +0 -68
  398. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/FormatString.java +0 -30
  399. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/InterpolatedShellItem.java +0 -55
  400. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/NextUpperCaseFormat.java +0 -28
  401. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/NoFormat.java +0 -43
  402. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/PlaceholderItem.java +0 -58
  403. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/PlainTextItem.java +0 -56
  404. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/SnippetItem.java +0 -70
  405. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/Transform.java +0 -54
  406. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/VariableItem.java +0 -81
  407. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/parser/CodeSnippetParser.java +0 -571
  408. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/parser/CodeSnippetTokenizer.java +0 -131
  409. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/parser/Token.java +0 -47
  410. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/completion/snippet/parser/TokenType.java +0 -59
  411. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/diagnostic/DiagnosticRegion.java +0 -95
  412. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/diagnostic/DiagnosticsContainer.java +0 -148
  413. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/folding/FoldingRegion.java +0 -89
  414. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/format/AsyncFormatter.java +0 -198
  415. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/format/Formatter.java +0 -104
  416. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/smartEnter/NewlineHandleResult.java +0 -47
  417. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/smartEnter/NewlineHandler.java +0 -60
  418. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/BlocksUpdater.java +0 -60
  419. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/CodeBlock.java +0 -182
  420. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/EmptyReader.java +0 -66
  421. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/MappedSpanUpdater.java +0 -190
  422. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/MappedSpans.java +0 -264
  423. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/Span.java +0 -203
  424. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/SpanFactory.java +0 -73
  425. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/Spans.java +0 -133
  426. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/Styles.java +0 -280
  427. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/StylesUtils.java +0 -108
  428. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/TextStyle.java +0 -141
  429. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/SpanExtAttrs.java +0 -67
  430. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/internal/NoExtSpanImpl.java +0 -165
  431. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/styling/span/internal/SpanImpl.java +0 -188
  432. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/util/BaseAnalyzeManager.java +0 -95
  433. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/util/PlainTextAnalyzeManager.java +0 -65
  434. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/lang/util/PlainTextSpans.java +0 -78
  435. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/CachedIndexer.java +0 -458
  436. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/CharArrayWrapper.java +0 -81
  437. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/CharPosition.java +0 -150
  438. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/CharSequenceIterator.java +0 -109
  439. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ComposingText.java +0 -91
  440. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/Content.java +0 -1306
  441. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ContentIO.java +0 -173
  442. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ContentLine.java +0 -405
  443. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ContentListener.java +0 -81
  444. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ContentReference.java +0 -212
  445. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/Cursor.java +0 -374
  446. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/FunctionCharacters.java +0 -71
  447. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/ICUUtils.java +0 -85
  448. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/Indexer.java +0 -92
  449. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/InsertTextHelper.java +0 -117
  450. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/LineSeparator.java +0 -123
  451. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/SpanRecycler.java +0 -103
  452. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/TextLayoutHelper.java +0 -122
  453. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/TextRange.java +0 -85
  454. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/TextReference.java +0 -132
  455. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/TextUtils.java +0 -196
  456. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/TextUtilsP.java +0 -236
  457. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/UndoManager.java +0 -750
  458. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/UnicodeIterator.java +0 -106
  459. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/BidiRequirementChecker.java +0 -31
  460. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/ContentBidi.java +0 -143
  461. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/Directions.java +0 -79
  462. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/IDirections.java +0 -39
  463. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/TextBidi.java +0 -93
  464. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/bidi/VisualDirections.java +0 -88
  465. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/breaker/WordBreaker.java +0 -47
  466. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/breaker/WordBreakerEmpty.java +0 -38
  467. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/breaker/WordBreakerIcu.java +0 -62
  468. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/breaker/WordBreakerProgram.java +0 -54
  469. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/text/method/KeyMetaStates.java +0 -93
  470. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/BinaryHeap.java +0 -239
  471. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/BlockIntList.java +0 -366
  472. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/ClipDataUtils.java +0 -55
  473. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/Floats.java +0 -33
  474. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/IntPair.java +0 -96
  475. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/Logger.java +0 -109
  476. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/LongArrayList.java +0 -132
  477. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/MyCharacter.java +0 -143
  478. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/Numbers.java +0 -123
  479. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/ObjectPool.java +0 -77
  480. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/RegionIterator.java +0 -162
  481. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/SegmentList.java +0 -323
  482. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/TemporaryCharBuffer.java +0 -52
  483. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/TemporaryFloatBuffer.java +0 -68
  484. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/ThemeUtils.java +0 -38
  485. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/TrieTree.java +0 -177
  486. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/ViewUtils.java +0 -67
  487. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/regex/RegexBackrefGrammar.java +0 -40
  488. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/regex/RegexBackrefHelper.java +0 -53
  489. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/regex/RegexBackrefParser.java +0 -119
  490. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/util/regex/RegexBackrefToken.java +0 -65
  491. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/CodeEditor.java +0 -5433
  492. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/CursorBlink.java +0 -98
  493. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/DirectAccessProps.java +0 -561
  494. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorInputConnection.java +0 -714
  495. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorKeyEventHandler.java +0 -646
  496. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorRenderer.java +0 -2620
  497. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorScroller.java +0 -119
  498. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorSearcher.java +0 -553
  499. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorStyleDelegate.java +0 -143
  500. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/EditorTouchEventHandler.java +0 -1306
  501. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/LanguageHelper.java +0 -66
  502. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/SymbolInputView.java +0 -154
  503. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/SymbolPairMatch.java +0 -334
  504. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/base/EditorPopupWindow.java +0 -351
  505. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/CompletionLayout.java +0 -89
  506. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/DefaultCompletionItemAdapter.java +0 -76
  507. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/DefaultCompletionLayout.java +0 -206
  508. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/EditorAutoCompletion.java +0 -684
  509. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/EditorCompletionAdapter.java +0 -118
  510. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/EditorTextActionWindow.java +0 -362
  511. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/component/Magnifier.java +0 -396
  512. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/AbstractLayout.java +0 -158
  513. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/LineBreakLayout.java +0 -393
  514. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/Row.java +0 -77
  515. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/RowElement.java +0 -70
  516. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/RowElementTypes.java +0 -41
  517. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/RowIterator.java +0 -67
  518. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/ViewMeasureHelper.java +0 -123
  519. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/layout/WordwrapLayout.java +0 -683
  520. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/rendering/RenderingConstants.java +0 -79
  521. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/rendering/TextAdvancesCache.java +0 -122
  522. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/rendering/package-info.java +0 -30
  523. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/EditorColorScheme.java +0 -544
  524. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/SchemeDarcula.java +0 -70
  525. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/SchemeEclipse.java +0 -60
  526. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/SchemeGitHub.java +0 -54
  527. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/SchemeNotepadXX.java +0 -60
  528. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/schemes/SchemeVS2019.java +0 -70
  529. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/TransformApplier.java +0 -134
  530. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/ClipboardBasedSnippetVariableResolver.java +0 -61
  531. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/CommentBasedSnippetVariableResolver.java +0 -77
  532. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/CompositeSnippetVariableResolver.java +0 -79
  533. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/EditorBasedSnippetVariableResolver.java +0 -76
  534. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/FileBasedSnippetVariableResolver.java +0 -39
  535. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/ISnippetVariableResolver.java +0 -49
  536. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/RandomBasedSnippetVariableResolver.java +0 -55
  537. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/TimeBasedSnippetVariableResolver.java +0 -101
  538. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/snippet/variable/WorkspaceBasedSnippetVariableResolver.java +0 -39
  539. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/CursorAnimator.java +0 -78
  540. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/DiagnosticIndicatorStyle.java +0 -37
  541. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/LineInfoPanelPosition.java +0 -33
  542. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/LineInfoPanelPositionMode.java +0 -30
  543. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/SelectionHandleStyle.java +0 -98
  544. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/FadeCursorAnimator.java +0 -179
  545. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/HandleStyleDrop.java +0 -80
  546. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/HandleStyleNone.java +0 -28
  547. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/HandleStyleSideDrop.java +0 -60
  548. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/MoveCursorAnimator.java +0 -159
  549. package/android/sora-editor/editor/src/main/java/io/github/abc15018045126/sora/widget/style/builtin/ScaleCursorAnimator.java +0 -166
  550. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/MyState.java +0 -46
  551. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/TextMateAnalyzer.java +0 -301
  552. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/TextMateColorScheme.java +0 -369
  553. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/TextMateLanguage.java +0 -314
  554. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/TextMateNewlineHandler.java +0 -547
  555. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/TextMateSymbolPairMatch.java +0 -240
  556. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/FoldingHelper.java +0 -35
  557. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/FoldingRegion.java +0 -51
  558. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/FoldingRegions.java +0 -96
  559. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/IndentRange.java +0 -169
  560. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/PreviousRegion.java +0 -41
  561. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/folding/RangesCollector.java +0 -71
  562. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/FileProviderRegistry.java +0 -83
  563. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/GrammarRegistry.java +0 -321
  564. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/ThemeRegistry.java +0 -186
  565. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/model/DefaultGrammarDefinition.java +0 -121
  566. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/model/GrammarDefinition.java +0 -51
  567. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/registry/model/ThemeModel.java +0 -106
  568. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/utils/ColorUtils.java +0 -79
  569. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/utils/MatcherUtils.java +0 -54
  570. package/android/sora-editor/language-textmate/src/main/java/io/github/abc15018045126/sora/langs/textmate/utils/StringUtils.java +0 -64
  571. package/android/sora-editor/oniguruma-native/src/main/java/io/github/abc15018045126/oniguruma/OnigNative.java +0 -121
@@ -0,0 +1,3542 @@
1
+ package io.github.abc15018045126.sora.widget
2
+
3
+ import android.graphics.Canvas
4
+ import android.graphics.Color
5
+ import android.graphics.DashPathEffect
6
+ import android.graphics.Path
7
+ import android.graphics.PorterDuff
8
+ import java.util.Collections
9
+ import android.graphics.Rect
10
+ import android.graphics.RectF
11
+ import android.graphics.RenderNode
12
+ import android.graphics.Typeface
13
+ import android.graphics.drawable.Drawable
14
+ import android.os.Build
15
+ import android.os.SystemClock
16
+ import android.util.Log
17
+ import android.util.SparseArray
18
+ import androidx.annotation.NonNull
19
+ import androidx.annotation.Nullable
20
+ import androidx.annotation.RequiresApi
21
+ import io.github.abc15018045126.sora.R
22
+ import io.github.abc15018045126.sora.annotations.UnsupportedUserUsage
23
+ import io.github.abc15018045126.sora.graphics.BufferedDrawPoints
24
+ import io.github.abc15018045126.sora.graphics.GraphicsCompat
25
+ import io.github.abc15018045126.sora.graphics.Paint
26
+ import io.github.abc15018045126.sora.graphics.TextRow
27
+ import io.github.abc15018045126.sora.graphics.TextRowParams
28
+ import io.github.abc15018045126.sora.lang.completion.snippet.SnippetItem
29
+ import io.github.abc15018045126.sora.lang.diagnostic.DiagnosticRegion
30
+ import io.github.abc15018045126.sora.lang.styling.CodeBlock
31
+ import io.github.abc15018045126.sora.lang.styling.EmptyReader
32
+ import io.github.abc15018045126.sora.lang.styling.Span
33
+ import io.github.abc15018045126.sora.lang.styling.Spans
34
+ import io.github.abc15018045126.sora.lang.styling.Styles
35
+ import io.github.abc15018045126.sora.lang.styling.TextStyle
36
+ import io.github.abc15018045126.sora.lang.styling.color.ResolvableColor
37
+ import io.github.abc15018045126.sora.lang.styling.inlayHint.InlayHint
38
+ import io.github.abc15018045126.sora.lang.styling.line.LineAnchorStyle
39
+ import io.github.abc15018045126.sora.lang.styling.line.LineBackground
40
+ import io.github.abc15018045126.sora.lang.styling.line.LineGutterBackground
41
+ import io.github.abc15018045126.sora.lang.styling.line.LineSideIcon
42
+ import io.github.abc15018045126.sora.lang.styling.line.LineStyles
43
+ import io.github.abc15018045126.sora.text.CharPosition
44
+ import io.github.abc15018045126.sora.text.Content
45
+ import io.github.abc15018045126.sora.text.ContentLine
46
+ import io.github.abc15018045126.sora.text.Cursor
47
+ import io.github.abc15018045126.sora.text.bidi.Directions
48
+ import io.github.abc15018045126.sora.util.IntPair
49
+ import io.github.abc15018045126.sora.util.LongArrayList
50
+ import io.github.abc15018045126.sora.util.MutableInt
51
+ import io.github.abc15018045126.sora.util.Numbers
52
+ import io.github.abc15018045126.sora.util.Numbers.stringSize
53
+ import io.github.abc15018045126.sora.util.MutableIntList
54
+ import io.github.abc15018045126.sora.util.MutableLongLongMap
55
+ import io.github.abc15018045126.sora.util.TemporaryCharBuffer
56
+ import io.github.abc15018045126.sora.widget.layout.Row
57
+ import io.github.abc15018045126.sora.widget.layout.RowIterator
58
+ import io.github.abc15018045126.sora.widget.rendering.RenderingConstants
59
+ import io.github.abc15018045126.sora.widget.rendering.TextAdvancesCache
60
+ import io.github.abc15018045126.sora.widget.schemes.EditorColorScheme
61
+ import io.github.abc15018045126.sora.widget.style.DiagnosticIndicatorStyle
62
+ import io.github.abc15018045126.sora.graphics.BubbleHelper
63
+ import java.util.Objects
64
+ import io.github.abc15018045126.sora.widget.style.LineInfoPanelPosition
65
+ import io.github.abc15018045126.sora.widget.style.LineInfoPanelPositionMode
66
+ import io.github.abc15018045126.sora.widget.style.SelectionHandleStyle
67
+ import kotlin.math.max
68
+ import kotlin.math.min
69
+ import kotlin.math.ceil
70
+ import android.graphics.Paint as AndroidPaint
71
+
72
+ class EditorRenderer(@NonNull editor: CodeEditor) {
73
+ internal val bufferedDrawPoints: BufferedDrawPoints
74
+ @JvmField
75
+ internal val paintGeneral: Paint
76
+ @JvmField
77
+ internal val paintOther: Paint
78
+ @JvmField
79
+ internal val viewRect: Rect
80
+ private val tmpRect: RectF
81
+ private val tmpPath: Path
82
+ @JvmField
83
+ internal val paintGraph: Paint
84
+ @JvmField
85
+ internal val verticalScrollBarRect: RectF
86
+ @JvmField
87
+ internal val horizontalScrollBarRect: RectF
88
+ private val postDrawLineNumbers: LongArrayList = LongArrayList()
89
+ private val postDrawCurrentLines: MutableIntList = MutableIntList()
90
+ private val matchedPositions: LongArrayList = LongArrayList()
91
+ private val highlightPositions: MutableLongLongMap = MutableLongLongMap()
92
+ private val preloadedLines: SparseArray<ContentLine> = SparseArray()
93
+ private val preloadedDirections: SparseArray<Directions> = SparseArray()
94
+ private val editor: CodeEditor
95
+ private val collectedDiagnostics: MutableList<DiagnosticRegion> = ArrayList()
96
+
97
+ @JvmField
98
+ var lastStuckLines: List<CodeBlock?>? = null
99
+
100
+ @JvmField
101
+ var metricsText: AndroidPaint.FontMetricsInt? = null
102
+
103
+ private val sharedTextRow = TextRow()
104
+
105
+ @Nullable
106
+ private var horizontalScrollbarThumbDrawable: Drawable? = null
107
+
108
+ @Nullable
109
+ private var horizontalScrollbarTrackDrawable: Drawable? = null
110
+
111
+ @Nullable
112
+ private var verticalScrollbarThumbDrawable: Drawable? = null
113
+
114
+ @Nullable
115
+ private var verticalScrollbarTrackDrawable: Drawable? = null
116
+ private val lineBreakGraph: Drawable?
117
+ private val softwrapLeftGraph: Drawable?
118
+ private val softwrapRightGraph: Drawable?
119
+
120
+ @Volatile
121
+ var timestamp: Long = 0
122
+ private set
123
+ private var metricsLineNumber: AndroidPaint.FontMetricsInt
124
+ private var metricsGraph: AndroidPaint.FontMetricsInt? = null
125
+ private var cachedGutterWidth = 0
126
+ private var cursor: Cursor? = null
127
+ protected var lineBuf: ContentLine? = null
128
+ protected var content: Content? = null
129
+
130
+ @Volatile
131
+ private var renderingFlag = false
132
+ internal var forcedRecreateLayout: Boolean = false
133
+
134
+ /**
135
+ * Called when the editor text is changed by [CodeEditor.setText]
136
+ */
137
+ fun onEditorFullTextUpdate() {
138
+ cursor = editor.cursor
139
+ content = editor.text
140
+ }
141
+
142
+ fun draw(@NonNull canvas: Canvas) {
143
+ val saveCount: Int = canvas.save()
144
+ canvas.translate(editor.offsetX.toFloat(), editor.offsetY.toFloat())
145
+ renderingFlag = true
146
+ try {
147
+ drawView(canvas)
148
+ } finally {
149
+ renderingFlag = false
150
+ }
151
+ canvas.restoreToCount(saveCount)
152
+ }
153
+
154
+ fun onSizeChanged(width: Int, height: Int) {
155
+ viewRect.right = width
156
+ viewRect.bottom = height
157
+ }
158
+
159
+ val paint: Paint
160
+ get() = paintGeneral
161
+
162
+ fun getPaintOther(): Paint {
163
+ return paintOther
164
+ }
165
+
166
+ fun getPaintGraph(): Paint {
167
+ return paintGraph
168
+ }
169
+
170
+ fun setCachedLineNumberWidth(width: Int) {
171
+ cachedGutterWidth = width
172
+ }
173
+
174
+ fun getVerticalScrollBarRect(): RectF {
175
+ return verticalScrollBarRect
176
+ }
177
+
178
+ fun getHorizontalScrollBarRect(): RectF {
179
+ return horizontalScrollBarRect
180
+ }
181
+
182
+ fun setHorizontalScrollbarThumbDrawable(@Nullable drawable: Drawable?) {
183
+ horizontalScrollbarThumbDrawable = drawable
184
+ }
185
+
186
+ @Nullable
187
+ fun getHorizontalScrollbarThumbDrawable(): Drawable? {
188
+ return horizontalScrollbarThumbDrawable
189
+ }
190
+
191
+ fun setHorizontalScrollbarTrackDrawable(@Nullable drawable: Drawable?) {
192
+ horizontalScrollbarTrackDrawable = drawable
193
+ }
194
+
195
+ @Nullable
196
+ fun getHorizontalScrollbarTrackDrawable(): Drawable? {
197
+ return horizontalScrollbarTrackDrawable
198
+ }
199
+
200
+ fun setVerticalScrollbarThumbDrawable(@Nullable drawable: Drawable?) {
201
+ this.verticalScrollbarThumbDrawable = drawable
202
+ }
203
+
204
+ @Nullable
205
+ fun getVerticalScrollbarThumbDrawable(): Drawable? {
206
+ return verticalScrollbarThumbDrawable
207
+ }
208
+
209
+ fun setVerticalScrollbarTrackDrawable(@Nullable drawable: Drawable?) {
210
+ verticalScrollbarTrackDrawable = drawable
211
+ }
212
+
213
+ @Nullable
214
+ fun getVerticalScrollbarTrackDrawable(): Drawable? {
215
+ return verticalScrollbarTrackDrawable
216
+ }
217
+
218
+ fun setTextSizePxDirect(size: Float) {
219
+ paintGeneral.setTextSizeWrapped(size)
220
+ paintOther.setTextSize(size)
221
+ paintGraph.setTextSize(size * editor.props!!.functionCharacterSizeFactor)
222
+ metricsText = paintGeneral.getFontMetricsInt()
223
+ metricsLineNumber = paintOther.getFontMetricsInt()
224
+ metricsGraph = paintGraph.getFontMetricsInt()
225
+ editor.renderContext!!.invalidateRenderNodes()
226
+ updateTimestamp()
227
+ }
228
+
229
+ /**
230
+ * Set text's typeface
231
+ *
232
+ * @param typefaceText New typeface
233
+ */
234
+ fun setTypefaceText(typefaceText: Typeface?) {
235
+ var typefaceText: Typeface? = typefaceText
236
+ if (typefaceText == null) {
237
+ typefaceText = Typeface.DEFAULT
238
+ }
239
+ paintGeneral.setTypefaceWrapped(typefaceText)
240
+ metricsText = paintGeneral.getFontMetricsInt()
241
+ editor.renderContext!!.invalidateRenderNodes()
242
+ updateTimestamp()
243
+ editor.createLayout()
244
+ editor.invalidate()
245
+ }
246
+
247
+ fun setTypefaceLineNumber(typefaceLineNumber: Typeface?) {
248
+ var typefaceLineNumber: Typeface? = typefaceLineNumber
249
+ if (typefaceLineNumber == null) {
250
+ typefaceLineNumber = Typeface.MONOSPACE
251
+ }
252
+ paintOther.setTypeface(typefaceLineNumber)
253
+ metricsLineNumber = paintOther.getFontMetricsInt()
254
+ editor.invalidate()
255
+ }
256
+
257
+ fun setTextScaleX(textScaleX: Float) {
258
+ paintGeneral.setTextScaleX(textScaleX)
259
+ paintOther.setTextScaleX(textScaleX)
260
+ onTextStyleUpdate()
261
+ }
262
+
263
+ fun setLetterSpacing(letterSpacing: Float) {
264
+ paintGeneral.setLetterSpacing(letterSpacing)
265
+ paintOther.setLetterSpacing(letterSpacing)
266
+ onTextStyleUpdate()
267
+ }
268
+
269
+ internal fun onTextStyleUpdate() {
270
+ paintGeneral.isRenderFunctionCharacters = editor.isRenderFunctionCharacters
271
+ metricsGraph = paintGraph.fontMetricsInt
272
+ metricsLineNumber = paintOther.getFontMetricsInt()
273
+ metricsText = paintGeneral.getFontMetricsInt()
274
+ editor.renderContext!!.invalidateRenderNodes()
275
+ updateTimestamp()
276
+ editor.createLayout()
277
+ editor.invalidate()
278
+ }
279
+
280
+ /**
281
+ * Update timestamp required for measuring cache
282
+ */
283
+ fun updateTimestamp() {
284
+ this.timestamp = SystemClock.elapsedRealtimeNanos()
285
+ }
286
+
287
+ protected fun prepareLine(line: Int) {
288
+ lineBuf = getLine(line)
289
+ }
290
+
291
+ protected fun getLine(line: Int): ContentLine {
292
+ if (!renderingFlag) {
293
+ return getLineDirect(line)
294
+ }
295
+ var line2 =
296
+ preloadedLines.get(line)
297
+ if (line2 == null) {
298
+ line2 = content!!.getLine(line)
299
+ preloadedLines.put(line, line2)
300
+ }
301
+ return line2!!
302
+ }
303
+
304
+ protected fun getLineDirections(line: Int): Directions {
305
+ if (!renderingFlag) {
306
+ return content!!.getLineDirections(line)
307
+ }
308
+ var line2 =
309
+ preloadedDirections.get(line)
310
+ if (line2 == null) {
311
+ line2 = content!!.getLineDirections(line)
312
+ preloadedDirections.put(line, line2)
313
+ }
314
+ return line2!!
315
+ }
316
+
317
+ fun getLineDirect(line: Int): ContentLine {
318
+ return content!!.getLine(line)
319
+ }
320
+
321
+ fun getColumnCount(line: Int): Int {
322
+ return getLine(line).length
323
+ }
324
+
325
+ // draw methods
326
+ @RequiresApi(29)
327
+ fun updateLineDisplayList(renderNode: RenderNode, line: Int, spans: Spans.Reader?) {
328
+ val widthLine = drawSingleTextLine(null, line, 0f, 0f, spans, false)
329
+ renderNode.setPosition(0, 0, (widthLine + 0.5f).toInt(), editor.logicalRowHeight)
330
+ val canvas =
331
+ renderNode.beginRecording()
332
+ try {
333
+ drawSingleTextLine(canvas, line, 0f, 0f, spans, false)
334
+ } finally {
335
+ renderNode.endRecording()
336
+ }
337
+ }
338
+
339
+ @UnsupportedUserUsage
340
+ fun createTextRow(rowIndex: Int): TextRow {
341
+ val tr = TextRow()
342
+ updateTextRow(tr, rowIndex)
343
+ return tr
344
+ }
345
+
346
+ private fun updateTextRow(tr: TextRow, rowIndex: Int) {
347
+ val styles = editor.styles
348
+ val spanMap =
349
+ if (styles != null) styles.spans else null
350
+ var spanReader =
351
+ if (spanMap != null) spanMap.read() else null
352
+ spanReader = if (spanReader == null) EmptyReader.INSTANCE else spanReader
353
+ val row =
354
+ editor.layout!!.getRowAt(rowIndex)
355
+ val line =
356
+ content!!.getLine(row.lineIndex)
357
+ val cache =
358
+ editor.renderContext!!.cache.queryMeasureCache(row.lineIndex)
359
+ var widths =
360
+ if (cache != null && cache.updateTimestamp >= this.timestamp) cache.widths else null
361
+ widths = if (widths != null && widths.size > line.length) widths else null
362
+ tr.set(
363
+ line,
364
+ row.startColumn,
365
+ row.endColumn,
366
+ spanReader.getSpansOnLine(row.lineIndex),
367
+ row.inlayHints,
368
+ content!!.getLineDirections(row.lineIndex),
369
+ paintGeneral,
370
+ widths,
371
+ createTextRowParams()
372
+ )
373
+ applySelectedTextRange(tr, row.lineIndex)
374
+ }
375
+
376
+ private fun applySelectedTextRange(tr: TextRow, lineIndex: Int) {
377
+ val cur = cursor ?: return
378
+ if (cur.isSelected() && lineIndex >= cur.leftLine && lineIndex <= cur.rightLine) {
379
+ var startColInLine = if (lineIndex == cur.leftLine) cur.leftColumn else 0
380
+ var endColInLine: Int =
381
+ if (lineIndex == cur.rightLine) cur.rightColumn else (lineBuf?.length ?: 0)
382
+ startColInLine = Math.max(tr.textStart, startColInLine)
383
+ endColInLine = Math.min(tr.textEnd, endColInLine)
384
+ if (startColInLine < endColInLine) {
385
+ tr.setSelectedRange(startColInLine, endColInLine)
386
+ }
387
+ }
388
+ }
389
+
390
+ protected fun drawSingleTextLine(
391
+ canvas: Canvas?,
392
+ line: Int,
393
+ offsetX: Float,
394
+ offsetY: Float,
395
+ spans: Spans.Reader?,
396
+ visibleOnly: Boolean
397
+ ): Float {
398
+ var reader: Spans.Reader? = spans
399
+ prepareLine(line)
400
+ val columnCount = getColumnCount(line)
401
+ if (reader == null || reader.getSpanCount() <= 0) {
402
+ reader = EmptyReader.INSTANCE
403
+ }
404
+ val tr: TextRow = TextRow()
405
+ val inlayHints =
406
+ editor.inlayHints
407
+ val lineInlays: List<InlayHint>? =
408
+ if (inlayHints == null) Collections.emptyList() else inlayHints.getForLine(line) as List<InlayHint>?
409
+ val cache =
410
+ editor.renderContext!!.cache.queryMeasureCache(line)
411
+ var widths =
412
+ if (cache != null && cache.updateTimestamp >= this.timestamp) cache.widths else null
413
+ widths = if (widths != null && widths.size > (lineBuf?.length ?: 0)) widths else null
414
+ tr.set(
415
+ lineBuf!!,
416
+ 0,
417
+ columnCount,
418
+ reader.getSpansOnLine(line),
419
+ lineInlays,
420
+ getLineDirections(line),
421
+ paintGeneral,
422
+ widths,
423
+ createTextRowParams()!!
424
+ )
425
+ applySelectedTextRange(tr, line)
426
+ if (canvas != null) {
427
+ canvas.save()
428
+ canvas.translate(offsetX, editor.getRowTop(0) + offsetY)
429
+ if (visibleOnly) {
430
+ val visibleStart: Float = Math.max(0f, -offsetX)
431
+ val visibleEnd: Float = Math.max(visibleStart, -offsetX + editor.width)
432
+ tr.draw(canvas, visibleStart, visibleEnd)
433
+ } else {
434
+ tr.draw(canvas, 0f, Float.MAX_VALUE)
435
+ }
436
+ canvas.restore()
437
+ }
438
+ return if (canvas == null) tr.computeRowWidth() else 0f
439
+ }
440
+
441
+ fun hasSideHintIcons(): Boolean {
442
+ val styles: Styles? = editor.styles
443
+ if (styles != null) {
444
+ val styleTypeCount = styles.styleTypeCount
445
+ if (styleTypeCount != null) {
446
+ val count =
447
+ styleTypeCount.get(LineSideIcon::class.java)
448
+ if (count == null) {
449
+ return false
450
+ }
451
+ return count.value > 0
452
+ }
453
+ }
454
+ return false
455
+ }
456
+
457
+ /**
458
+ * Paint the view on given Canvas
459
+ *
460
+ * @param canvas Canvas you want to draw
461
+ */
462
+ fun drawView(canvas: Canvas) {
463
+ cursor?.updateCache(editor.firstVisibleLine)
464
+
465
+ val color: EditorColorScheme = editor.colorScheme
466
+ drawColor(canvas, color.getColor(EditorColorScheme.WHOLE_BACKGROUND), viewRect)
467
+
468
+ val lineNumberWidth: Float = editor.measureLineNumber() // include line number margin
469
+ val sideIconWidth = if (hasSideHintIcons()) editor.logicalRowHeight.toFloat() else 0f
470
+ var offsetX: Float = -editor.offsetX.toFloat() + editor.measureTextRegionOffset()
471
+ val textOffset = offsetX
472
+
473
+ val gutterWidth =
474
+ (lineNumberWidth + sideIconWidth + editor.dividerWidth + editor.dividerMarginLeft + editor.dividerMarginRight).toInt()
475
+ if (editor.isWordwrap) {
476
+ if (cachedGutterWidth == 0) {
477
+ cachedGutterWidth = gutterWidth
478
+ } else if (cachedGutterWidth != gutterWidth && !editor.touchHandler!!.isScaling) {
479
+ cachedGutterWidth = gutterWidth
480
+ editor.postInLifecycle(editor::requestLayoutIfNeeded)
481
+ editor.createLayout(false)
482
+ } else if (forcedRecreateLayout) {
483
+ editor.createLayout()
484
+ editor.postInLifecycle(editor::requestLayoutIfNeeded)
485
+ }
486
+ } else {
487
+ cachedGutterWidth = 0
488
+ if (forcedRecreateLayout) {
489
+ editor.createLayout()
490
+ }
491
+ }
492
+ forcedRecreateLayout = false
493
+
494
+ prepareLines(editor.firstVisibleLine, editor.lastVisibleLine)
495
+ buildMeasureCacheForLines(editor.firstVisibleLine, editor.lastVisibleLine, this.timestamp, true)
496
+ val stuckLines: List<CodeBlock?>? = this.stuckCodeBlocks
497
+ val cursor = editor.cursor ?: return
498
+
499
+ if (cursor.isSelected()) {
500
+ editor.handleDescInsert!!.setEmpty()
501
+ } else {
502
+ editor.handleDescLeft!!.setEmpty()
503
+ editor.handleDescRight!!.setEmpty()
504
+ }
505
+
506
+ val lineNumberNotPinned = editor.isLineNumberEnabled && !editor.isLineNumberPinned
507
+
508
+ val postDrawLineNumbers: LongArrayList = this.postDrawLineNumbers
509
+ postDrawLineNumbers.clear()
510
+ val postDrawCurrentLines: MutableIntList = this.postDrawCurrentLines
511
+ postDrawCurrentLines.clear()
512
+ val postDrawCursor: MutableList<DrawCursorTask?> = ArrayList(3)
513
+ val firstLn: MutableInt? =
514
+ if (editor.isFirstLineNumberAlwaysVisible && editor.isWordwrap && !editor.isLineNumberPinned) MutableInt(-1) else null
515
+
516
+ canvas.save()
517
+ val stuckLineBottom = getStuckLineBottom(stuckLines)
518
+ canvas.clipRect(0f, stuckLineBottom, editor.width.toFloat(), editor.height.toFloat())
519
+ drawRows(canvas, textOffset, postDrawLineNumbers, postDrawCursor, postDrawCurrentLines, firstLn)
520
+ patchHighlightedDelimiters(canvas, textOffset)
521
+ drawDiagnosticIndicators(canvas, offsetX)
522
+ canvas.restore()
523
+
524
+ offsetX = -editor.offsetX.toFloat()
525
+
526
+ val currentLineNumber = if (cursor.isSelected()) -1 else cursor.leftLine
527
+
528
+ if (lineNumberNotPinned) {
529
+ drawLineNumberBackground(
530
+ canvas,
531
+ offsetX,
532
+ lineNumberWidth + sideIconWidth + editor.dividerMarginLeft,
533
+ color.getColor(EditorColorScheme.LINE_NUMBER_BACKGROUND)
534
+ )
535
+ val lineNumberColor: Int = editor.colorScheme.getColor(EditorColorScheme.LINE_NUMBER)
536
+ val currentLineBgColor: Int = editor.colorScheme.getColor(EditorColorScheme.CURRENT_LINE)
537
+ if (editor.cursorAnimator.isRunning() && editor.isHighlightCurrentLine && editor.isEditable) {
538
+ tmpRect.bottom = (editor.cursorAnimator.animatedLineBottom() - editor.offsetY).toFloat()
539
+ tmpRect.top = tmpRect.bottom - editor.cursorAnimator.animatedLineHeight()
540
+ tmpRect.left = 0f
541
+ tmpRect.right = (textOffset - editor.dividerMarginRight).toFloat()
542
+ drawColor(canvas, currentLineBgColor, tmpRect)
543
+ }
544
+
545
+ canvas.save()
546
+ canvas.clipRect(0f, stuckLineBottom, editor.width.toFloat(), editor.height.toFloat())
547
+ for (i in 0 until postDrawCurrentLines.size) {
548
+ drawRowBackground(
549
+ canvas,
550
+ currentLineBgColor,
551
+ postDrawCurrentLines.get(i),
552
+ (textOffset - editor.dividerMarginRight).toInt()
553
+ )
554
+ }
555
+ // User defined gutter background
556
+ drawUserGutterBackground(canvas, (textOffset - editor.dividerMarginRight).toInt())
557
+ drawSideIcons(canvas, offsetX + lineNumberWidth)
558
+ canvas.restore()
559
+
560
+ val isRightOfDivider = editor.isLineNumberRightOfDivider()
561
+
562
+ // Draw Divider
563
+ val dividerX = if (isRightOfDivider)
564
+ offsetX
565
+ else
566
+ offsetX + lineNumberWidth + sideIconWidth + editor.dividerMarginLeft
567
+
568
+ drawDivider(
569
+ canvas,
570
+ dividerX,
571
+ color.getColor(EditorColorScheme.LINE_DIVIDER)
572
+ )
573
+
574
+ // Draw Line Numbers
575
+ val numberX = if (isRightOfDivider)
576
+ offsetX + editor.dividerWidth + editor.dividerMarginRight + sideIconWidth
577
+ else
578
+ offsetX
579
+
580
+ canvas.save()
581
+ canvas.clipRect(0f, stuckLineBottom, editor.width.toFloat(), editor.height.toFloat())
582
+ if (firstLn != null && firstLn.value != -1) {
583
+ val bottom: Int = editor.getRowBottom(0)
584
+ val y: Float
585
+ if (postDrawLineNumbers.size == 0 || editor.getRowTop(IntPair.getSecond(postDrawLineNumbers.get(0))) - editor.offsetY > bottom) {
586
+ // Free to draw at first line
587
+ y =
588
+ (editor.getRowBottom(0) + editor.getRowTop(0)) / 2f - (metricsLineNumber.descent - metricsLineNumber.ascent) / 2f - metricsLineNumber.ascent
589
+ } else {
590
+ val row: Int = IntPair.getSecond(postDrawLineNumbers.get(0))
591
+ y =
592
+ (editor.getRowBottom(row - 1) + editor.getRowTop(row - 1)) / 2f - (metricsLineNumber.descent - metricsLineNumber.ascent) / 2f - metricsLineNumber.ascent - editor.offsetY.toFloat()
593
+ }
594
+ paintOther.textAlign = editor.getLineNumberAlign()
595
+ paintOther.color = if (firstLn.value == currentLineNumber) color.getColor(EditorColorScheme.LINE_NUMBER_CURRENT) else lineNumberColor
596
+ val text =
597
+ (firstLn.value + 1).toString()
598
+ when (editor.getLineNumberAlign()) {
599
+ AndroidPaint.Align.LEFT -> canvas.drawText(text, numberX, y, paintOther)
600
+ AndroidPaint.Align.RIGHT -> canvas.drawText(text, numberX + lineNumberWidth, y, paintOther)
601
+ AndroidPaint.Align.CENTER -> canvas.drawText(
602
+ text,
603
+ numberX + (lineNumberWidth + editor.dividerMarginLeft) / 2f,
604
+ y,
605
+ paintOther
606
+ )
607
+ else -> {}
608
+ }
609
+ }
610
+ for (i in 0 until postDrawLineNumbers.size) {
611
+ val packed: Long = postDrawLineNumbers.get(i)
612
+ drawLineNumber(
613
+ canvas,
614
+ IntPair.getFirst(packed),
615
+ IntPair.getSecond(packed),
616
+ numberX,
617
+ lineNumberWidth,
618
+ if (IntPair.getFirst(packed) == currentLineNumber) color.getColor(EditorColorScheme.LINE_NUMBER_CURRENT) else lineNumberColor
619
+ )
620
+ }
621
+ canvas.restore()
622
+ }
623
+
624
+ if (editor.isBlockLineEnabled()) {
625
+ canvas.save()
626
+ canvas.clipRect(0f, stuckLineBottom, editor.width.toFloat(), editor.height.toFloat())
627
+ if (editor.isWordwrap) {
628
+ drawSideBlockLine(canvas)
629
+ } else {
630
+ drawBlockLines(canvas, textOffset)
631
+ }
632
+ canvas.restore()
633
+ }
634
+
635
+ if (!editor.cursorAnimator.isRunning()) {
636
+ for (action in postDrawCursor) {
637
+ action?.execute(canvas)
638
+ }
639
+ } else {
640
+ drawSelectionOnAnimation(canvas)
641
+ }
642
+
643
+ drawStuckLines(canvas, stuckLines, textOffset)
644
+
645
+ if (editor.isLineNumberEnabled && !lineNumberNotPinned) {
646
+ drawLineNumberBackground(
647
+ canvas,
648
+ 0f,
649
+ lineNumberWidth + sideIconWidth + editor.dividerMarginLeft,
650
+ color.getColor(EditorColorScheme.LINE_NUMBER_BACKGROUND)
651
+ )
652
+
653
+ canvas.save()
654
+ canvas.clipRect(0f, stuckLineBottom, editor.width.toFloat(), editor.height.toFloat())
655
+ val lineNumberColor: Int = editor.colorScheme.getColor(EditorColorScheme.LINE_NUMBER)
656
+ val currentLineBgColor: Int = editor.colorScheme.getColor(EditorColorScheme.CURRENT_LINE)
657
+ if (editor.cursorAnimator.isRunning() && editor.isHighlightCurrentLine && editor.isEditable) {
658
+ tmpRect.bottom = (editor.cursorAnimator.animatedLineBottom() - editor.offsetY).toFloat()
659
+ tmpRect.top = tmpRect.bottom - editor.cursorAnimator.animatedLineHeight()
660
+ tmpRect.left = 0f
661
+ tmpRect.right = (textOffset - editor.getDividerMarginRight() + editor.offsetX).toFloat()
662
+ drawColor(canvas, currentLineBgColor, tmpRect)
663
+ }
664
+ for (i in 0 until postDrawCurrentLines.size) {
665
+ drawRowBackground(
666
+ canvas,
667
+ currentLineBgColor,
668
+ postDrawCurrentLines.get(i),
669
+ (textOffset - editor.getDividerMarginRight() + editor.offsetX).toInt()
670
+ )
671
+ }
672
+ drawUserGutterBackground(canvas, (textOffset - editor.getDividerMarginRight() + editor.offsetX).toInt())
673
+ drawSideIcons(canvas, lineNumberWidth)
674
+ canvas.restore()
675
+
676
+ drawDivider(
677
+ canvas,
678
+ lineNumberWidth + sideIconWidth + editor.dividerMarginLeft,
679
+ color.getColor(EditorColorScheme.LINE_DIVIDER)
680
+ )
681
+
682
+ canvas.save()
683
+ canvas.clipRect(0f, stuckLineBottom, editor.width.toFloat(), editor.height.toFloat())
684
+ for (i in 0 until postDrawLineNumbers.size) {
685
+ val packed: Long = postDrawLineNumbers.get(i)
686
+ drawLineNumber(
687
+ canvas,
688
+ IntPair.getFirst(packed),
689
+ IntPair.getSecond(packed),
690
+ 0f,
691
+ lineNumberWidth,
692
+ if (IntPair.getFirst(packed) == currentLineNumber) color.getColor(EditorColorScheme.LINE_NUMBER_CURRENT) else lineNumberColor
693
+ )
694
+ }
695
+ canvas.restore()
696
+ }
697
+
698
+ drawStuckLineNumbers(
699
+ canvas,
700
+ stuckLines,
701
+ offsetX,
702
+ lineNumberWidth,
703
+ editor.colorScheme.getColor(EditorColorScheme.LINE_NUMBER)
704
+ )
705
+ drawScrollBars(canvas)
706
+ drawEdgeEffect(canvas)
707
+
708
+ releasePreloadedData()
709
+ lastStuckLines = stuckLines
710
+ drawFormatTip(canvas)
711
+ }
712
+
713
+ protected fun drawUserGutterBackground(canvas: Canvas, right: Int) {
714
+ var first = editor.firstVisibleLine
715
+ val last = editor.lastVisibleLine
716
+ for (line in first..last) {
717
+ val bg: ResolvableColor? = getUserGutterBackgroundForLine(line)
718
+ if (bg != null) {
719
+ val bgColor =
720
+ bg.resolve(editor.colorScheme)
721
+ val top = (editor.layout!!.getCharLayoutOffset(line, 0)[0] / editor.logicalRowHeight).toInt() - 1
722
+ val count =
723
+ editor.layout!!.getRowCountForLine(line)
724
+ for (i in 0 until count) {
725
+ drawRowBackground(canvas, bgColor, top + i, right)
726
+ }
727
+ }
728
+ }
729
+ }
730
+
731
+ protected fun drawStuckLineNumbers(
732
+ canvas: Canvas,
733
+ candidates: List<CodeBlock?>?,
734
+ offset: Float,
735
+ lineNumberWidth: Float,
736
+ lineNumberColor: Int
737
+ ) {
738
+ if (candidates == null || candidates.isEmpty() || !editor.isLineNumberEnabled) {
739
+ return
740
+ }
741
+ val cur = editor.cursor
742
+ val currentLine = if (cur?.isSelected() == true) -1 else (cur?.leftLine ?: -1)
743
+ canvas.save()
744
+ val offsetY =
745
+ editor.offsetY
746
+ canvas.translate(0f, offsetY.toFloat())
747
+ for (i in 0 until candidates.size) {
748
+ val block =
749
+ candidates[i] ?: continue
750
+ val line = block.startLine
751
+ val bg: ResolvableColor? = getUserGutterBackgroundForLine(line)
752
+ val color = if (bg != null) bg.resolve(editor.colorScheme) else 0
753
+ val bottomOffset =
754
+ editor.getRowBottom(i)
755
+ val endLineTop =
756
+ editor.getRowTop(block.endLine) - editor.offsetY
757
+ val shouldTranslate = endLineTop < bottomOffset && endLineTop >= bottomOffset - editor.logicalRowHeight
758
+ if (shouldTranslate) {
759
+ canvas.save()
760
+ canvas.clipRect(0f, (editor.getRowTop(i) - offsetY).toFloat(), editor.width.toFloat(), editor.height.toFloat())
761
+ canvas.translate(0f, (endLineTop - bottomOffset).toFloat())
762
+ }
763
+ if (currentLine == line || color != 0) {
764
+ tmpRect.top = (editor.getRowTop(i) - offsetY).toFloat()
765
+ tmpRect.bottom = (editor.getRowBottom(i) - offsetY - editor.dpUnit).toFloat()
766
+ tmpRect.left = if (editor.isLineNumberPinned) 0f else offset
767
+ tmpRect.right = tmpRect.left + editor.measureTextRegionOffset()
768
+ if (currentLine == line && editor.isHighlightCurrentLine) drawColor(
769
+ canvas,
770
+ editor.colorScheme.getColor(EditorColorScheme.CURRENT_LINE),
771
+ tmpRect
772
+ )
773
+ if (color != 0) drawColor(canvas, color, tmpRect)
774
+ }
775
+ drawLineNumber(
776
+ canvas, line, i,
777
+ if (editor.isLineNumberPinned) 0f else offset, lineNumberWidth,
778
+ if (currentLine == line) editor.colorScheme
779
+ .getColor(EditorColorScheme.LINE_NUMBER_CURRENT) else lineNumberColor
780
+ )
781
+ if (shouldTranslate) {
782
+ canvas.restore()
783
+ }
784
+ }
785
+ canvas.restore()
786
+ }
787
+
788
+ protected fun getStuckLineBottom(candidates: List<CodeBlock?>?): Float {
789
+ if (candidates == null || candidates.isEmpty()) {
790
+ return 0f
791
+ }
792
+ var bottomOffset = 0f
793
+ var offsetLine = 0
794
+ var previousLine = -1
795
+ for (i in 0 until candidates.size) {
796
+ val block =
797
+ candidates.get(i) ?: continue
798
+ if (block.startLine > previousLine) {
799
+ bottomOffset = editor.getRowBottom(offsetLine).toFloat()
800
+ val endLineTop =
801
+ editor.getRowTop(block.endLine) - editor.offsetY
802
+ val shouldTranslate = endLineTop < bottomOffset && endLineTop >= bottomOffset - editor.logicalRowHeight
803
+ if (shouldTranslate) {
804
+ bottomOffset += (endLineTop - bottomOffset).toFloat()
805
+ }
806
+ previousLine = block.startLine
807
+ offsetLine++
808
+ }
809
+ }
810
+ return bottomOffset
811
+ }
812
+
813
+ protected fun drawStuckLines(canvas: Canvas, candidates: List<CodeBlock?>?, offset: Float) {
814
+ if (candidates == null || candidates.isEmpty()) {
815
+ return
816
+ }
817
+ val styles = editor.styles
818
+ var reader: Spans.Reader? = null
819
+ val spans = styles?.spans
820
+ if (spans != null) {
821
+ reader = spans.read()
822
+ }
823
+ var previousLine = -1
824
+ var offsetLine = 0
825
+ val cur = editor.cursor
826
+ val currentLine = if (cur?.isSelected() == true) -1 else (cur?.leftLine ?: -1)
827
+ var bottomOffset = 0f
828
+ for (i in 0 until (candidates?.size ?: 0)) {
829
+ val block =
830
+ candidates?.get(i) ?: continue
831
+ if (block.startLine > previousLine) {
832
+ tmpRect.top = editor.getRowTop(offsetLine).toFloat()
833
+ tmpRect.bottom = editor.getRowBottom(offsetLine).toFloat()
834
+ bottomOffset = tmpRect.bottom
835
+ tmpRect.left = offset
836
+ tmpRect.right = editor.width.toFloat()
837
+ val endLineTop =
838
+ editor.getRowTop(block.endLine) - editor.offsetY
839
+ val shouldTranslate = endLineTop < tmpRect.bottom && endLineTop >= tmpRect.top
840
+ if (shouldTranslate) {
841
+ canvas.save()
842
+ canvas.clipRect(0f, tmpRect.top, editor.width.toFloat(), editor.height.toFloat())
843
+ canvas.translate(0f, (endLineTop - tmpRect.bottom).toFloat())
844
+ bottomOffset += (endLineTop - tmpRect.bottom).toFloat()
845
+ }
846
+ var colorId =
847
+ EditorColorScheme.WHOLE_BACKGROUND
848
+ if (block.startLine == currentLine && editor.isHighlightCurrentLine) {
849
+ colorId = EditorColorScheme.CURRENT_LINE
850
+ }
851
+ drawColor(canvas, editor.colorScheme.getColor(colorId), tmpRect)
852
+ if (canvas.isHardwareAccelerated && editor.isHardwareAcceleratedDrawAllowed && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && editor.renderContext
853
+ ?.renderNodeHolder != null && !editor.touchHandler!!.isScaling &&
854
+ (editor.props!!.cacheRenderNodeForLongLines || getLine(block.startLine).length < 128)
855
+ ) {
856
+ editor.renderContext?.renderNodeHolder?.drawLineHardwareAccelerated(
857
+ canvas,
858
+ block.startLine,
859
+ offset,
860
+ (offsetLine * editor.logicalRowHeight).toFloat()
861
+ )
862
+ } else {
863
+ try {
864
+ if (reader != null) {
865
+ reader.moveToLine(block.startLine)
866
+ }
867
+ drawSingleTextLine(
868
+ canvas,
869
+ block.startLine,
870
+ offset,
871
+ (offsetLine * editor.logicalRowHeight).toFloat(),
872
+ reader,
873
+ true
874
+ )
875
+ } finally {
876
+ if (reader != null) {
877
+ reader.moveToLine(-1)
878
+ }
879
+ }
880
+ }
881
+ previousLine = block.startLine
882
+ offsetLine++
883
+ if (shouldTranslate) {
884
+ canvas.restore()
885
+ }
886
+ }
887
+ }
888
+ if (bottomOffset > 0f) {
889
+ tmpRect.top = bottomOffset - editor.dpUnit
890
+ tmpRect.bottom = bottomOffset
891
+ tmpRect.left = 0f
892
+ tmpRect.right = editor.width.toFloat()
893
+ val shadow =
894
+ (editor.props!!.stickyLineIndicator and DirectAccessProps.STICKY_LINE_INDICATOR_SHADOW) !== 0
895
+ var showLine =
896
+ (editor.props!!.stickyLineIndicator and DirectAccessProps.STICKY_LINE_INDICATOR_LINE) !== 0
897
+ if (!shadow && !showLine) {
898
+ return
899
+ }
900
+ val lineColor =
901
+ editor.colorScheme.getColor(EditorColorScheme.STICKY_SCROLL_DIVIDER)
902
+ showLine = lineColor != 0
903
+ if (shadow) {
904
+ canvas.save()
905
+ canvas.clipRect(0f, if (showLine) tmpRect.top else tmpRect.bottom, editor.width.toFloat(), editor.height.toFloat())
906
+ paintGeneral.setShadowLayer(
907
+ editor.dpUnit * RenderingConstants.DIVIDER_SHADOW_MAX_RADIUS_DIP,
908
+ 0f,
909
+ 0f,
910
+ Color.BLACK
911
+ )
912
+ }
913
+ val color = if (!showLine && shadow) Color.BLACK else lineColor
914
+ drawColor(canvas, color, tmpRect)
915
+ if (shadow) {
916
+ paintGeneral.setShadowLayer(0f, 0f, 0f, 0)
917
+ canvas.restore()
918
+ }
919
+ }
920
+ }
921
+
922
+ protected fun drawHardwrapMarker(canvas: Canvas?, offset: Float) {
923
+ val column = editor.props!!.hardwrapColumn
924
+ if (!editor.isWordwrap && column > 0) {
925
+ tmpRect.left = offset + paintGeneral.measureText("a") * column
926
+ tmpRect.right = tmpRect.left + editor.dpUnit * 2f
927
+ tmpRect.top = 0f
928
+ tmpRect.bottom = viewRect.bottom.toFloat()
929
+ drawColor(canvas, editor.colorScheme.getColor(EditorColorScheme.HARD_WRAP_MARKER), tmpRect)
930
+ }
931
+ }
932
+
933
+ protected fun drawSideIcons(canvas: Canvas?, offset: Float) {
934
+ if (!hasSideHintIcons()) {
935
+ return
936
+ }
937
+ var row =
938
+ editor.firstVisibleRow
939
+ val itr =
940
+ editor.layout!!.obtainRowIterator(row)
941
+ val iconSizeFactor =
942
+ editor.props!!.sideIconSizeFactor
943
+ val size = (editor.logicalRowHeight * iconSizeFactor) as Int
944
+ val offsetToLeftTop = (editor.logicalRowHeight * (1 - iconSizeFactor) / 2f) as Int
945
+ while (row <= editor.lastVisibleRow && itr.hasNext()) {
946
+ val rowInf = itr.next()
947
+ if (rowInf.isLeadingRow) {
948
+ val hint: LineSideIcon? = getLineStyle(rowInf.lineIndex, LineSideIcon::class.java)
949
+ if (hint != null) {
950
+ val drawable = hint.drawable
951
+ val rect = Rect(0, 0, size, size)
952
+ rect.offsetTo(
953
+ offset.toInt() + offsetToLeftTop,
954
+ (editor.getRowTop(row) - editor.offsetY + offsetToLeftTop).toInt()
955
+ )
956
+ drawable.bounds = rect
957
+ drawable.draw(canvas!!)
958
+ }
959
+ }
960
+ row++
961
+ }
962
+ }
963
+
964
+ protected fun drawFormatTip(canvas: Canvas) {
965
+ if (editor.isFormatting) {
966
+ val text = editor.formatTip
967
+ val baseline = editor.getRowBaseline(0).toFloat()
968
+ val rightX = editor.width.toFloat()
969
+ paintGeneral.color = editor.colorScheme.getColor(EditorColorScheme.TEXT_NORMAL)
970
+ paintGeneral.isFakeBoldText = true
971
+ paintGeneral.textAlign = AndroidPaint.Align.RIGHT
972
+ if (text != null) {
973
+ canvas.drawText(text, rightX, baseline, paintGeneral)
974
+ }
975
+ paintGeneral.textAlign = AndroidPaint.Align.LEFT
976
+ paintGeneral.isFakeBoldText = false
977
+ }
978
+ }
979
+
980
+ /**
981
+ * Draw rect on screen
982
+ * Will not do anything if color is zero
983
+ *
984
+ * @param canvas Canvas to draw
985
+ * @param color Color of rect
986
+ * @param rect Rect to draw
987
+ */
988
+ protected fun drawColor(canvas: Canvas?, color: Int, rect: RectF?) {
989
+ if (canvas != null && color != 0 && rect != null) {
990
+ paintGeneral.color = color
991
+ canvas.drawRect(rect, paintGeneral)
992
+ }
993
+ }
994
+
995
+ /**
996
+ * Draw rect on screen in a round rectangle
997
+ * Will not do anything if color is zero
998
+ *
999
+ * @param canvas Canvas to draw
1000
+ * @param color Color of rect
1001
+ * @param rect Rect to draw
1002
+ */
1003
+ protected fun drawColorRound(canvas: Canvas, color: Int, rect: RectF) {
1004
+ if (color != 0) {
1005
+ paintGeneral.color = color
1006
+ canvas.drawRoundRect(
1007
+ rect,
1008
+ rect.height() * RenderingConstants.ROUND_RECT_FACTOR,
1009
+ rect.height() * RenderingConstants.ROUND_RECT_FACTOR,
1010
+ paintGeneral
1011
+ )
1012
+ }
1013
+ }
1014
+
1015
+ /**
1016
+ * Draw rect on screen
1017
+ * Will not do anything if color is zero
1018
+ *
1019
+ * @param canvas Canvas to draw
1020
+ * @param color Color of rect
1021
+ * @param rect Rect to draw
1022
+ */
1023
+ protected fun drawColor(canvas: Canvas?, color: Int, rect: Rect?) {
1024
+ if (canvas != null && color != 0 && rect != null) {
1025
+ paintGeneral.color = color
1026
+ canvas.drawRect(rect, paintGeneral)
1027
+ }
1028
+ }
1029
+
1030
+ /**
1031
+ * Draw background for whole row
1032
+ */
1033
+ protected fun drawRowBackground(canvas: Canvas, color: Int, row: Int) {
1034
+ drawRowBackground(canvas, color, row, viewRect.right)
1035
+ }
1036
+
1037
+ protected fun drawRowBackground(canvas: Canvas, color: Int, row: Int, right: Int) {
1038
+ tmpRect.top = (editor.getRowTop(row) - editor.offsetY).toFloat()
1039
+ tmpRect.bottom = (editor.getRowBottom(row) - editor.offsetY).toFloat()
1040
+ tmpRect.left = 0f
1041
+ tmpRect.right = right.toFloat()
1042
+ drawColor(canvas, color, tmpRect)
1043
+ }
1044
+
1045
+ /**
1046
+ * Draw single line number
1047
+ */
1048
+ protected fun drawLineNumber(canvas: Canvas, line: Int, row: Int, offsetX: Float, width: Float, color: Int) {
1049
+ var line = line
1050
+ if (width + offsetX <= 0) {
1051
+ return
1052
+ }
1053
+ if (paintOther.getTextAlign() !== editor.getLineNumberAlign()) {
1054
+ paintOther.setTextAlign(editor.getLineNumberAlign())
1055
+ }
1056
+ paintOther.setColor(color)
1057
+ // Line number center align to text center
1058
+ val y: Float =
1059
+ (editor.getRowBottom(row) + editor.getRowTop(row)) / 2f - (metricsLineNumber.descent - metricsLineNumber.ascent) / 2f - metricsLineNumber.ascent - editor.offsetY
1060
+
1061
+ val buffer =
1062
+ TemporaryCharBuffer.obtain(20)
1063
+ line++
1064
+ val i: Int = stringSize(line)
1065
+ io.github.abc15018045126.sora.util.Numbers.getChars(line, i, buffer)
1066
+
1067
+ when (editor.lineNumberAlign) {
1068
+ AndroidPaint.Align.LEFT -> canvas.drawText(buffer, 0, i, offsetX, y, paintOther)
1069
+ AndroidPaint.Align.RIGHT -> canvas.drawText(buffer, 0, i, offsetX + width, y, paintOther)
1070
+ AndroidPaint.Align.CENTER -> canvas.drawText(
1071
+ buffer,
1072
+ 0,
1073
+ i,
1074
+ offsetX + (width + editor.dividerMarginLeft) / 2f,
1075
+ y,
1076
+ paintOther
1077
+ )
1078
+ else -> {}
1079
+ }
1080
+ TemporaryCharBuffer.recycle(buffer)
1081
+ }
1082
+
1083
+ /**
1084
+ * Draw line number background
1085
+ *
1086
+ * @param canvas Canvas to draw
1087
+ * @param offsetX Start x of line number region
1088
+ * @param width Width of line number region
1089
+ * @param color Color of line number background
1090
+ */
1091
+ protected fun drawLineNumberBackground(canvas: Canvas, offsetX: Float, width: Float, color: Int) {
1092
+ val right = offsetX + width
1093
+ if (right < 0) {
1094
+ return
1095
+ }
1096
+ val left = max(0f, offsetX)
1097
+ tmpRect.bottom = editor.height.toFloat()
1098
+ tmpRect.top = 0f
1099
+ val offY = editor.offsetY
1100
+ if (offY < 0) {
1101
+ tmpRect.bottom = tmpRect.bottom - offY.toFloat()
1102
+ tmpRect.top = tmpRect.top - offY.toFloat()
1103
+ }
1104
+ tmpRect.left = left
1105
+ tmpRect.right = right
1106
+ drawColor(canvas, color, tmpRect)
1107
+ }
1108
+
1109
+ /**
1110
+ * Draw divider line
1111
+ *
1112
+ * @param canvas Canvas to draw
1113
+ * @param offsetX End x of line number region
1114
+ * @param color Color to draw divider
1115
+ */
1116
+ protected fun drawDivider(canvas: Canvas, offsetX: Float, color: Int) {
1117
+ val shadow = editor.isLineNumberPinned && !editor.isWordwrap && editor.offsetX > 0
1118
+ val right = offsetX + editor.dividerWidth
1119
+ if (right < 0) {
1120
+ return
1121
+ }
1122
+ val left = max(0f, offsetX)
1123
+ tmpRect.bottom = editor.height.toFloat()
1124
+ tmpRect.top = 0f
1125
+ val offY = editor.offsetY
1126
+ if (offY < 0) {
1127
+ tmpRect.bottom = tmpRect.bottom - offY.toFloat()
1128
+ tmpRect.top = tmpRect.top - offY.toFloat()
1129
+ }
1130
+ tmpRect.left = left
1131
+ tmpRect.right = right
1132
+ if (shadow) {
1133
+ canvas.save()
1134
+ canvas.clipRect(tmpRect.left, tmpRect.top, editor.width.toFloat(), tmpRect.bottom)
1135
+ paintGeneral.setShadowLayer(
1136
+ min(
1137
+ (editor.dpUnit * RenderingConstants.DIVIDER_SHADOW_MAX_RADIUS_DIP).toFloat(),
1138
+ editor.offsetX.toFloat()
1139
+ ), 0f, 0f, Color.BLACK
1140
+ )
1141
+ }
1142
+ drawColor(canvas, color, tmpRect)
1143
+ if (shadow) {
1144
+ canvas.restore()
1145
+ paintGeneral.setShadowLayer(0f, 0f, 0f, 0)
1146
+ }
1147
+ }
1148
+
1149
+ private fun prepareLines(start: Int, end: Int) {
1150
+ val content = this.content ?: return
1151
+ releasePreloadedData()
1152
+ content.runReadActionsOnLines(
1153
+ Math.max(0, start - 5),
1154
+ Math.min(content.lineCount - 1, end + 5),
1155
+ { i: Int, line: ContentLine?, dirs: Directions? ->
1156
+ preloadedLines.put(i, line)
1157
+ preloadedDirections.put(i, dirs)
1158
+ })
1159
+ }
1160
+
1161
+ private fun releasePreloadedData() {
1162
+ preloadedLines.clear()
1163
+ preloadedDirections.clear()
1164
+ }
1165
+
1166
+ protected val stuckCodeBlocks: List<CodeBlock>?
1167
+ get() {
1168
+ if (editor.isWordwrap || !editor.props!!.stickyScroll) {
1169
+ return null
1170
+ }
1171
+ val styles = editor.styles ?: return null
1172
+ val codeBlocks = styles.blocksByStart ?: return null
1173
+
1174
+ var startLine = editor.firstVisibleLine
1175
+ var offsetY = editor.offsetY
1176
+ val rowHeight = editor.logicalRowHeight
1177
+ val size = codeBlocks.size
1178
+ if (size == 0) {
1179
+ return null
1180
+ }
1181
+ val candidates = mutableListOf<CodeBlock>()
1182
+ val limit = editor.props!!.stickyScrollIterationLimit
1183
+ val maxLine = content!!.lineCount
1184
+ var i = 0
1185
+ while (i < size && i < limit) {
1186
+ val block = codeBlocks[i]
1187
+ if (block == null || block.startLine > block.endLine || block.startLine > maxLine || block.endLine > maxLine || block.startLine < 0) {
1188
+ i++
1189
+ continue
1190
+ }
1191
+ if (block.startLine > startLine) {
1192
+ break
1193
+ }
1194
+ if (block.endLine > startLine && editor.getRowTop(block.startLine) - offsetY < 0) {
1195
+ candidates.add(block)
1196
+ startLine++
1197
+ offsetY += rowHeight
1198
+ }
1199
+ i++
1200
+ }
1201
+
1202
+ val maxLines = editor.props!!.stickyScrollMaxLines
1203
+ var finalCandidates: List<CodeBlock> = candidates
1204
+ if (finalCandidates.size > maxLines) {
1205
+ if (maxLines <= 0) {
1206
+ return null
1207
+ }
1208
+ finalCandidates = if (editor.props!!.stickyScrollPreferInnerScope) {
1209
+ finalCandidates.subList(finalCandidates.size - maxLines, finalCandidates.size)
1210
+ } else {
1211
+ finalCandidates.subList(0, maxLines)
1212
+ }
1213
+ }
1214
+ val cur = editor.cursor
1215
+ if (cur != null && cur.isSelected() && editor.props!!.stickyScrollAutoCollapse) {
1216
+ val limitLine = cur.leftLine
1217
+ val firstVis = editor.firstVisibleLine
1218
+ val lastSelectionLine = cur.rightLine
1219
+ if (lastSelectionLine >= firstVis) {
1220
+ val mutableCandidates = finalCandidates.toMutableList()
1221
+ while (mutableCandidates.isNotEmpty() && firstVis + mutableCandidates.size >= limitLine) {
1222
+ mutableCandidates.removeAt(mutableCandidates.size - 1)
1223
+ }
1224
+ finalCandidates = mutableCandidates
1225
+ }
1226
+ }
1227
+ return if (finalCandidates.isEmpty()) null else finalCandidates
1228
+ }
1229
+
1230
+ private val coordinateLine: LineStyles = LineStyles(0)
1231
+
1232
+ init {
1233
+ this.editor = editor
1234
+ verticalScrollBarRect = RectF()
1235
+ horizontalScrollBarRect = RectF()
1236
+
1237
+ bufferedDrawPoints = BufferedDrawPoints()
1238
+
1239
+ paintGeneral = Paint()
1240
+ paintGeneral.isFilterBitmap = editor.isRenderFunctionCharacters
1241
+ paintGeneral.setAntiAlias(true)
1242
+ paintOther = Paint(false)
1243
+ paintOther.setStrokeWidth(this.editor.dpUnit * 1.8f)
1244
+ paintOther.setStrokeCap(AndroidPaint.Cap.ROUND)
1245
+ paintOther.setTypeface(Typeface.MONOSPACE)
1246
+ paintOther.setAntiAlias(true)
1247
+ paintGraph = Paint(false)
1248
+ paintGraph.setAntiAlias(true)
1249
+
1250
+ metricsText = paintGeneral.getFontMetricsInt()
1251
+ metricsLineNumber = paintOther.getFontMetricsInt()
1252
+
1253
+ viewRect = Rect()
1254
+ tmpRect = RectF()
1255
+ tmpPath = Path()
1256
+
1257
+ lineBreakGraph = editor.getContext().getDrawable(R.drawable.line_break)
1258
+ softwrapLeftGraph = editor.getContext().getDrawable(R.drawable.softwrap_left)
1259
+ softwrapRightGraph = editor.getContext().getDrawable(R.drawable.softwrap_right)
1260
+
1261
+ onEditorFullTextUpdate()
1262
+ }
1263
+
1264
+ @Nullable
1265
+ protected fun getLineStyles(line: Int): LineStyles? {
1266
+ val styles = editor.styles ?: return null
1267
+ val lineStylesList = styles.lineStyles ?: return null
1268
+ coordinateLine.line = line
1269
+ val index =
1270
+ Collections.binarySearch(lineStylesList, coordinateLine)
1271
+ if (index >= 0 && index < lineStylesList.size) {
1272
+ return lineStylesList[index]
1273
+ }
1274
+ return null
1275
+ }
1276
+
1277
+ @Nullable
1278
+ internal fun <T : LineAnchorStyle> getLineStyle(line: Int, type: Class<T>): T? {
1279
+ val lineStyles: LineStyles? = getLineStyles(line)
1280
+ if (lineStyles != null) {
1281
+ return lineStyles.findOne(type)
1282
+ }
1283
+ return null
1284
+ }
1285
+
1286
+ @Nullable
1287
+ protected fun getUserBackgroundForLine(line: Int): ResolvableColor? {
1288
+ val bg: LineBackground? = getLineStyle(line, LineBackground::class.java)
1289
+ if (bg != null) {
1290
+ return bg.color
1291
+ }
1292
+ return null
1293
+ }
1294
+
1295
+ @Nullable
1296
+ protected fun getUserGutterBackgroundForLine(line: Int): ResolvableColor? {
1297
+ val bg: LineGutterBackground? = getLineStyle(line, LineGutterBackground::class.java)
1298
+ if (bg != null) {
1299
+ return bg.color
1300
+ }
1301
+ return null
1302
+ }
1303
+
1304
+ /**
1305
+ * Draw current line background during animation
1306
+ */
1307
+ protected fun drawAnimatedCurrentLineBackground(canvas: Canvas, currentLineBgColor: Int) {
1308
+ tmpRect.bottom = (editor.cursorAnimator.animatedLineBottom() - editor.offsetY).toFloat()
1309
+ tmpRect.top = tmpRect.bottom - editor.cursorAnimator.animatedLineHeight()
1310
+ tmpRect.left = 0f
1311
+ tmpRect.right = viewRect.right.toFloat()
1312
+ drawColor(canvas, currentLineBgColor, tmpRect)
1313
+ }
1314
+
1315
+ fun createTextRowParams(): TextRowParams {
1316
+ return TextRowParams(
1317
+ editor.tabWidth, this.metricsText!!, editor.getRowTopOfText(0),
1318
+ editor.getRowBottomOfText(0), editor.logicalRowHeight, editor.getRowBaseline(0),
1319
+ editor.getRowTop(0), editor.getRowBottom(0),
1320
+ editor.logicalRowHeight, editor.props!!.roundTextBackgroundFactor,
1321
+ editor, editor.colorScheme, paintOther, paintGraph, metricsGraph!!
1322
+ )
1323
+ }
1324
+
1325
+ /**
1326
+ * Draw rows with a [RowIterator]
1327
+ *
1328
+ * @param canvas Canvas to draw
1329
+ * @param offset Offset of text region start
1330
+ * @param postDrawLineNumbers Line numbers to be drawn later
1331
+ * @param postDrawCursor Cursors to be drawn later
1332
+ */
1333
+ protected fun drawRows(
1334
+ canvas: Canvas,
1335
+ offset: Float,
1336
+ postDrawLineNumbers: LongArrayList,
1337
+ postDrawCursor: MutableList<DrawCursorTask?>,
1338
+ postDrawCurrentLines: MutableIntList,
1339
+ requiredFirstLn: MutableInt?
1340
+ ) {
1341
+ val cursor = this.cursor ?: return
1342
+ val content = this.content ?: return
1343
+ val firstVis: Int = editor.firstVisibleRow
1344
+ val rowIterator: RowIterator = editor.layout!!.obtainRowIterator(firstVis, preloadedLines)
1345
+ val spans: Spans? = editor.styles?.spans
1346
+ val matchedPositions: LongArrayList = this.matchedPositions
1347
+ val highlightPositions: MutableLongLongMap = this.highlightPositions
1348
+ matchedPositions.clear()
1349
+ highlightPositions.clear()
1350
+ val currentLine = if (cursor.isSelected()) -1 else cursor.leftLine
1351
+ val currentLineBgColor: Int = editor.colorScheme.getColor(EditorColorScheme.CURRENT_LINE)
1352
+ val currentRow = if (cursor.isSelected()) -1 else editor.layout!!.getRowIndexForPosition(cursor.left)
1353
+ val currentRowBorder: Int = editor.colorScheme.getColor(EditorColorScheme.CURRENT_ROW_BORDER)
1354
+ var lastPreparedLine = -1
1355
+ var leadingWhitespaceEnd = 0
1356
+ var trailingWhitespaceStart = 0
1357
+ var circleRadius = 0f
1358
+ val miniGraphWidth =
1359
+ if (editor.isWordwrap && (editor.nonPrintablePaintingFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_SOFT_WRAP) !== 0) this.miniGraphWidth else 0f
1360
+ val composingPosition =
1361
+ if (editor.inputConnection?.composingText?.isComposing() == true && editor.inputConnection!!.composingText.startIndex >= 0 && editor.inputConnection!!.composingText.startIndex < content.length) content.getIndexer()
1362
+ .getCharPosition(editor.inputConnection!!.composingText.startIndex) else null
1363
+ val composingLength =
1364
+ editor.inputConnection!!.composingText.endIndex - editor.inputConnection!!.composingText.startIndex
1365
+ val draggingSelection =
1366
+ editor.touchHandler?.draggingSelection
1367
+ if (editor.shouldInitializeNonPrintable()) {
1368
+ val spaceWidth: Float = paintGeneral.spaceWidth
1369
+ circleRadius =
1370
+ Math.min(editor.logicalRowHeight.toFloat(), spaceWidth) * RenderingConstants.NON_PRINTABLE_CIRCLE_RADIUS_FACTOR
1371
+ }
1372
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !editor.isWordwrap && canvas.isHardwareAccelerated && editor.isHardwareAcceleratedDrawAllowed) {
1373
+ editor.renderContext?.renderNodeHolder?.keepCurrentInDisplay(firstVis, editor.lastVisibleRow)
1374
+ }
1375
+ val offset2: Float = editor.offsetX - editor.measureTextRegionOffset()
1376
+
1377
+ // Step 1 - Draw background of rows
1378
+
1379
+ val trParams = createTextRowParams()
1380
+
1381
+ // Pre-draw animated current line background
1382
+ if (editor.cursorAnimator.isRunning() && editor.isHighlightCurrentLine && editor.isEditable
1383
+ && (editor.props!!.cursorLineBgOverlapBehavior === CURSOR_LINE_BG_OVERLAP_CURSOR || editor.props!!.cursorLineBgOverlapBehavior === CURSOR_LINE_BG_OVERLAP_MIXED)
1384
+ ) {
1385
+ drawAnimatedCurrentLineBackground(canvas, currentLineBgColor)
1386
+ }
1387
+ // Draw custom line backgrounds & normal current line background
1388
+ run {
1389
+ var row = firstVis
1390
+ while (row <= editor.lastVisibleRow && rowIterator.hasNext()) {
1391
+ val rowInf: Row = rowIterator.next()
1392
+ val line: Int = rowInf.lineIndex
1393
+ if (lastPreparedLine != line) {
1394
+ prepareLine(line)
1395
+ lastPreparedLine = line
1396
+ }
1397
+
1398
+ val lineBgOverlapBehavior =
1399
+ editor.props!!.cursorLineBgOverlapBehavior
1400
+
1401
+ var drawCurrentLineBg = line == currentLine && !editor.cursorAnimator.isRunning() &&
1402
+ editor.isHighlightCurrentLine &&
1403
+ editor.isEditable
1404
+
1405
+ val drawCustomLineBg = !drawCurrentLineBg
1406
+ || (editor.props!!.drawCustomLineBgOnCurrentLine && lineBgOverlapBehavior != CURSOR_LINE_BG_OVERLAP_CUSTOM)
1407
+
1408
+ var isOverlapping = false
1409
+
1410
+ if (drawCustomLineBg) {
1411
+ // Draw custom background
1412
+ val customBackground: ResolvableColor? = getUserBackgroundForLine(line)
1413
+ if (customBackground != null) {
1414
+ val color =
1415
+ customBackground.resolve(editor.colorScheme)
1416
+ if (line == currentLine) {
1417
+ isOverlapping = true
1418
+ }
1419
+
1420
+ drawRowBackground(canvas, color, row)
1421
+ }
1422
+ }
1423
+
1424
+ if (isOverlapping) {
1425
+ drawCurrentLineBg = drawCurrentLineBg and (lineBgOverlapBehavior != CURSOR_LINE_BG_OVERLAP_CURSOR)
1426
+ }
1427
+
1428
+ if (drawCurrentLineBg) {
1429
+ var commitCurrentLineBg = currentLineBgColor
1430
+ if (isOverlapping && lineBgOverlapBehavior == CURSOR_LINE_BG_OVERLAP_MIXED) {
1431
+ // alpha = 0.5f = 0.5 * 255 = 128 = 0x80
1432
+ commitCurrentLineBg = (commitCurrentLineBg and 0x00FFFFFF) or -0x80000000
1433
+ }
1434
+
1435
+ // Draw current line background
1436
+ drawRowBackground(canvas, commitCurrentLineBg, row)
1437
+ postDrawCurrentLines.add(row)
1438
+ }
1439
+ row++
1440
+ }
1441
+ }
1442
+ // Post-draw animated current line background
1443
+ if (editor.cursorAnimator.isRunning() && editor.isHighlightCurrentLine
1444
+ && editor.props!!.cursorLineBgOverlapBehavior == CURSOR_LINE_BG_OVERLAP_CUSTOM
1445
+ ) {
1446
+ drawAnimatedCurrentLineBackground(canvas, currentLineBgColor)
1447
+ }
1448
+ rowIterator.reset()
1449
+
1450
+ // Other system line background are drawn last
1451
+ run {
1452
+ var row = firstVis
1453
+ while (row <= editor.lastVisibleRow && rowIterator.hasNext()) {
1454
+ val rowInf: Row = rowIterator.next()
1455
+ canvas.save()
1456
+ canvas.translate(rowInf.renderTranslateX, 0f)
1457
+ val line: Int = rowInf.lineIndex
1458
+ val columnCount = getColumnCount(line)
1459
+ if (lastPreparedLine != line) {
1460
+ editor.computeMatchedPositions(line, matchedPositions)
1461
+ editor.computeHighlightPositions(line, highlightPositions)
1462
+ prepareLine(line)
1463
+ lastPreparedLine = line
1464
+ }
1465
+ var paintingOffset = -offset2
1466
+ if (!rowInf.isLeadingRow) paintingOffset += miniGraphWidth
1467
+
1468
+ // Draw matched text background
1469
+ if (matchedPositions.size > 0) {
1470
+ updateTextRow(sharedTextRow, row)
1471
+ for (i in 0 until matchedPositions.size) {
1472
+ val position =
1473
+ matchedPositions.get(i)
1474
+ val start =
1475
+ IntPair.getFirst(position)
1476
+ val end =
1477
+ IntPair.getSecond(position)
1478
+ drawRowRegionBackground(
1479
+ canvas,
1480
+ row,
1481
+ sharedTextRow,
1482
+ start,
1483
+ end,
1484
+ rowInf.startColumn,
1485
+ rowInf.endColumn,
1486
+ editor.colorScheme.getColor(EditorColorScheme.MATCHED_TEXT_BACKGROUND),
1487
+ editor.colorScheme.getColor(EditorColorScheme.MATCHED_TEXT_BORDER)
1488
+ )
1489
+ }
1490
+ }
1491
+
1492
+ // Draw highlight text background
1493
+ if (highlightPositions.size > 0) {
1494
+ val finalRow = row
1495
+ val tr: TextRow = createTextRow(row)
1496
+ highlightPositions.forEach(object : MutableLongLongMap.Consumer {
1497
+ override fun accept(key: Long, value: Long): Any? {
1498
+ val start = IntPair.getFirst(key)
1499
+ val end = IntPair.getSecond(key)
1500
+ updateTextRow(sharedTextRow, finalRow)
1501
+ drawRowRegionBackground(
1502
+ canvas, finalRow, sharedTextRow, start, end, rowInf.startColumn,
1503
+ rowInf.endColumn, IntPair.getFirst(value), IntPair.getSecond(value)
1504
+ )
1505
+ return null
1506
+ }
1507
+ })
1508
+ }
1509
+
1510
+ // Draw selected text background
1511
+ if (cursor.isSelected() && line >= cursor.leftLine && line <= cursor.rightLine) {
1512
+ var selectionStart = 0
1513
+ var selectionEnd = columnCount
1514
+ if (line == cursor.leftLine) {
1515
+ selectionStart = cursor.leftColumn
1516
+ }
1517
+ if (line == cursor.rightLine) {
1518
+ selectionEnd = cursor.rightColumn
1519
+ }
1520
+ val columnCountLine = getColumnCount(line)
1521
+ if (columnCountLine == 0 && line != cursor.rightLine) {
1522
+ tmpRect.top = (getRowTopForBackground(row) - editor.offsetY).toFloat()
1523
+ tmpRect.bottom = (getRowBottomForBackground(row) - editor.offsetY).toFloat()
1524
+ tmpRect.left = paintingOffset
1525
+ tmpRect.right = tmpRect.left + paintGeneral.spaceWidth * 2
1526
+ drawRowBackgroundRectWithBorder(
1527
+ canvas, tmpRect,
1528
+ editor.colorScheme.getColor(EditorColorScheme.SELECTED_TEXT_BACKGROUND),
1529
+ editor.colorScheme.getColor(EditorColorScheme.SELECTED_TEXT_BORDER)
1530
+ )
1531
+ } else if (selectionStart < selectionEnd) {
1532
+ updateTextRow(sharedTextRow, row)
1533
+ drawRowRegionBackground(
1534
+ canvas, row, sharedTextRow, selectionStart, selectionEnd, rowInf.startColumn, rowInf.endColumn,
1535
+ editor.colorScheme.getColor(EditorColorScheme.SELECTED_TEXT_BACKGROUND),
1536
+ editor.colorScheme.getColor(EditorColorScheme.SELECTED_TEXT_BORDER)
1537
+ )
1538
+ }
1539
+ }
1540
+ canvas.restore()
1541
+
1542
+ // Draw current row border
1543
+ if (row == currentRow && currentRowBorder != 0) {
1544
+ tmpRect.top = (editor.getRowTop(row) - editor.offsetY).toFloat()
1545
+ tmpRect.bottom = (editor.getRowBottom(row) - editor.offsetY).toFloat()
1546
+ tmpRect.left = max(0f, -offset2)
1547
+ tmpRect.right = editor.width.toFloat()
1548
+ paintGeneral.setColor(currentRowBorder)
1549
+ paintGeneral.setStyle(android.graphics.Paint.Style.STROKE)
1550
+ paintGeneral.setStrokeWidth(editor.dpUnit)
1551
+ canvas.drawRect(tmpRect, paintGeneral)
1552
+ paintGeneral.setStyle(android.graphics.Paint.Style.FILL)
1553
+ }
1554
+ row++
1555
+ }
1556
+ }
1557
+ rowIterator.reset()
1558
+
1559
+ // Background of snippets
1560
+ patchSnippetRegions(canvas, offset)
1561
+
1562
+ // Hard wrap marker
1563
+ drawHardwrapMarker(canvas, offset)
1564
+
1565
+ // Step 2 - Draw text and text decorations
1566
+ var reader: Spans.Reader? = null
1567
+ lastPreparedLine = -1
1568
+ var lineCache: TextAdvancesCache? = null
1569
+ var row = firstVis
1570
+ while (row <= editor.lastVisibleRow && rowIterator.hasNext()) {
1571
+ val rowInf: Row = rowIterator.next()
1572
+ val line: Int = rowInf.lineIndex
1573
+ val contentLine: ContentLine = getLine(line)
1574
+ val columnCount: Int = contentLine.length
1575
+ if (row == firstVis && requiredFirstLn != null) {
1576
+ requiredFirstLn.value = line
1577
+ } else if (rowInf.isLeadingRow) {
1578
+ postDrawLineNumbers.add(IntPair.pack(line, row))
1579
+ }
1580
+
1581
+ // Prepare data
1582
+ if (lastPreparedLine != line) {
1583
+ lastPreparedLine = line
1584
+ val cache =
1585
+ editor.renderContext!!.cache.queryMeasureCache(line)
1586
+ if (cache != null && cache.updateTimestamp == this.timestamp && cache.widths != null && cache.widths!!
1587
+ .size > columnCount
1588
+ ) {
1589
+ lineCache = cache.widths
1590
+ } else {
1591
+ lineCache = null
1592
+ }
1593
+ prepareLine(line)
1594
+ // Release old reader
1595
+ if (reader != null) {
1596
+ try {
1597
+ reader.moveToLine(-1)
1598
+ } catch (e: Exception) {
1599
+ Log.w(
1600
+ io.github.abc15018045126.sora.widget.EditorRenderer.Companion.LOG_TAG,
1601
+ "Failed to release SpanReader",
1602
+ e
1603
+ )
1604
+ }
1605
+ }
1606
+ // Get new reader and lock
1607
+ // Note that we should hold the reader during the **text line** rendering process
1608
+ // Otherwise, the spans?.filterNotNull() of that line can be changed during the inter rendering time
1609
+ // between two **rows** because the spans?.filterNotNull() could have been changed concurrently
1610
+ // See #290
1611
+ reader = if (spans == null) EmptyReader.INSTANCE else spans.read()
1612
+ try {
1613
+ reader.moveToLine(line)
1614
+ } catch (e: Exception) {
1615
+ Log.w(
1616
+ io.github.abc15018045126.sora.widget.EditorRenderer.Companion.LOG_TAG,
1617
+ "Failed to read span",
1618
+ e
1619
+ )
1620
+ reader = EmptyReader.INSTANCE
1621
+ }
1622
+ if (reader!!.getSpanCount() == 0) {
1623
+ // Unacceptable span count, use fallback reader
1624
+ reader = EmptyReader.INSTANCE
1625
+ }
1626
+ if (editor.shouldInitializeNonPrintable()) {
1627
+ val positions: Long = editor.findLeadingAndTrailingWhitespacePos(lineBuf!!)
1628
+ leadingWhitespaceEnd = IntPair.getFirst(positions)
1629
+ trailingWhitespaceStart = IntPair.getSecond(positions)
1630
+ }
1631
+ }
1632
+
1633
+ // Get visible region on the line
1634
+ var paintingOffset = -offset2
1635
+ var offsetCopy = offset2
1636
+
1637
+ paintingOffset += rowInf.renderTranslateX
1638
+ offsetCopy -= rowInf.renderTranslateX
1639
+
1640
+ if (!rowInf.isLeadingRow) {
1641
+ if ((editor.nonPrintablePaintingFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_SOFT_WRAP) !== 0) {
1642
+ drawMiniGraph(canvas, offset, row, softwrapLeftGraph)
1643
+ paintingOffset += miniGraphWidth
1644
+ offsetCopy -= miniGraphWidth
1645
+ }
1646
+ }
1647
+
1648
+ val backupOffset = paintingOffset
1649
+ val nonPrintableFlags: Int = editor.nonPrintablePaintingFlags
1650
+
1651
+ // Draw text here
1652
+ if (!editor.isHardwareAcceleratedDrawAllowed || editor.touchHandler!!.isScaling || !canvas.isHardwareAccelerated || editor.isWordwrap || Build.VERSION.SDK_INT < Build.VERSION_CODES.Q || (rowInf.endColumn - rowInf.startColumn > 128 && !editor.props!!.cacheRenderNodeForLongLines) /* Save memory */) {
1653
+ // Draw without hardware acceleration
1654
+ sharedTextRow.set(
1655
+ lineBuf!!,
1656
+ rowInf.startColumn,
1657
+ rowInf.endColumn,
1658
+ reader!!.getSpansOnLine(line),
1659
+ rowInf.inlayHints,
1660
+ getLineDirections(line)!!,
1661
+ paintGeneral,
1662
+ lineCache,
1663
+ trParams
1664
+ )
1665
+ applySelectedTextRange(sharedTextRow, line)
1666
+
1667
+ canvas.save()
1668
+ canvas.translate(-offsetCopy, (editor.getRowTop(row) - editor.offsetY).toFloat())
1669
+ // visible editor window: [offsetX, offsetX+editorWidth]
1670
+ // current row window region: [textRegionOffsetW+leftMiniGraphWidth, textRegionOffsetX+leftMiniGraphX+rowWidth]
1671
+ // shifted start at offsetX-(textRegionOffsetX+leftMiniGraphWidth)
1672
+ // visible in-row offset from max{offsetX, textRegionOffsetX+leftMiniGraphWidth} - (textRegionOffsetX+leftMiniGraphWidth)
1673
+ // to min{textRegionOffsetX+leftMiniGraphX+rowWidth, offsetX+editorWidth-(textRegionOffsetX+leftMiniGraphWidth)}
1674
+ val beginOffset: Float = max(0f, offsetCopy)
1675
+ val endOffset: Float = beginOffset + editor.width
1676
+ val result =
1677
+ sharedTextRow.draw(canvas, beginOffset, endOffset)
1678
+ canvas.restore()
1679
+
1680
+ val exhausted = IntPair.getFirst(result) == 1
1681
+ paintingOffset += IntPair.getSecondAsFloat(result)
1682
+
1683
+ // Draw hard wrap & soft wrap
1684
+ if (exhausted && rowInf.isTrailingRow && (nonPrintableFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_LINE_SEPARATOR) !== 0) {
1685
+ drawMiniGraph(canvas, paintingOffset, row, lineBreakGraph)
1686
+ } else if (!rowInf.isTrailingRow && editor.isWordwrap && (nonPrintableFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_SOFT_WRAP) !== 0) {
1687
+ drawMiniGraph(canvas, paintingOffset, row, softwrapRightGraph)
1688
+ }
1689
+ } else {
1690
+ paintingOffset = editor.renderContext!!.renderNodeHolder
1691
+ ?.drawLineHardwareAccelerated(canvas, line, offset, (editor.getRowTop(row) - editor.offsetY).toFloat())?.toFloat() ?: 0f
1692
+ // Draw hard wrap
1693
+ if (rowInf.isTrailingRow && (nonPrintableFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_LINE_SEPARATOR) !== 0) {
1694
+ drawMiniGraph(canvas, paintingOffset, row, lineBreakGraph)
1695
+ }
1696
+ }
1697
+
1698
+ // Recover the offset
1699
+ paintingOffset = backupOffset
1700
+
1701
+ // Draw non-printable characters
1702
+ if (circleRadius != 0f && (leadingWhitespaceEnd != columnCount || (nonPrintableFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_WHITESPACE_FOR_EMPTY_LINE) !== 0)) {
1703
+ sharedTextRow.set(
1704
+ lineBuf!!,
1705
+ rowInf.startColumn,
1706
+ rowInf.endColumn,
1707
+ reader!!.getSpansOnLine(line),
1708
+ rowInf.inlayHints,
1709
+ getLineDirections(line)!!,
1710
+ paintGeneral,
1711
+ lineCache,
1712
+ trParams
1713
+ )
1714
+ canvas.save()
1715
+ val topOfText = (editor.getRowTopOfText(row) - editor.offsetY).toFloat()
1716
+ canvas.translate(paintingOffset, topOfText)
1717
+ bufferedDrawPoints.setOffsets(paintingOffset, topOfText)
1718
+ val beginOffset: Float = max(0f, paintingOffset)
1719
+ val endOffset: Float = beginOffset + editor.width
1720
+ val wsLeadingEnd = leadingWhitespaceEnd
1721
+ val wsTrailingStart = trailingWhitespaceStart
1722
+
1723
+ paintOther.setColor(editor.colorScheme.getColor(EditorColorScheme.NON_PRINTABLE_CHAR))
1724
+ sharedTextRow.iterateDrawTextRegions(
1725
+ rowInf.startColumn, rowInf.endColumn, canvas, beginOffset, endOffset, false,
1726
+ object : TextRow.DrawTextConsumer {
1727
+ override fun drawText(
1728
+ _canvas: Canvas?,
1729
+ text: CharArray?,
1730
+ index: Int,
1731
+ count: Int,
1732
+ contextIndex: Int,
1733
+ contextCount: Int,
1734
+ isRtl: Boolean,
1735
+ horizontalOffset: Float,
1736
+ width: Float,
1737
+ params: TextRowParams?,
1738
+ span: Span?
1739
+ ) {
1740
+ if ((nonPrintableFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_WHITESPACE_LEADING) != 0) {
1741
+ drawWhitespaces(
1742
+ _canvas!!,
1743
+ sharedTextRow,
1744
+ text!!,
1745
+ index,
1746
+ count,
1747
+ contextIndex,
1748
+ contextCount,
1749
+ isRtl,
1750
+ horizontalOffset,
1751
+ width,
1752
+ 0,
1753
+ wsLeadingEnd
1754
+ )
1755
+ }
1756
+ if ((nonPrintableFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_WHITESPACE_INNER) != 0) {
1757
+ drawWhitespaces(
1758
+ _canvas!!,
1759
+ sharedTextRow,
1760
+ text!!,
1761
+ index,
1762
+ count,
1763
+ contextIndex,
1764
+ contextCount,
1765
+ isRtl,
1766
+ horizontalOffset,
1767
+ width,
1768
+ wsLeadingEnd,
1769
+ wsTrailingStart
1770
+ )
1771
+ }
1772
+ if ((nonPrintableFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_WHITESPACE_TRAILING) != 0) {
1773
+ drawWhitespaces(
1774
+ _canvas!!,
1775
+ sharedTextRow,
1776
+ text!!,
1777
+ index,
1778
+ count,
1779
+ contextIndex,
1780
+ contextCount,
1781
+ isRtl,
1782
+ horizontalOffset,
1783
+ width,
1784
+ wsTrailingStart,
1785
+ columnCount
1786
+ )
1787
+ }
1788
+ if ((nonPrintableFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_WHITESPACE_IN_SELECTION) != 0 && cursor.isSelected() && line >= cursor.leftLine && line <= cursor.rightLine) {
1789
+ var selectionStart = 0
1790
+ var selectionEnd = columnCount
1791
+ if (line == cursor.leftLine) {
1792
+ selectionStart = cursor.leftColumn
1793
+ }
1794
+ if (line == cursor.rightLine) {
1795
+ selectionEnd = cursor.rightColumn
1796
+ }
1797
+ if ((nonPrintableFlags and 14) == 0) {
1798
+ drawWhitespaces(
1799
+ _canvas!!,
1800
+ sharedTextRow,
1801
+ text!!,
1802
+ index,
1803
+ count,
1804
+ contextIndex,
1805
+ contextCount,
1806
+ isRtl,
1807
+ horizontalOffset,
1808
+ width,
1809
+ selectionStart,
1810
+ selectionEnd
1811
+ )
1812
+ } else {
1813
+ if ((nonPrintableFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_WHITESPACE_LEADING) == 0) {
1814
+ drawWhitespaces(
1815
+ _canvas!!,
1816
+ sharedTextRow,
1817
+ text!!,
1818
+ index,
1819
+ count,
1820
+ contextIndex,
1821
+ contextCount,
1822
+ isRtl,
1823
+ horizontalOffset,
1824
+ width,
1825
+ selectionStart,
1826
+ min(wsLeadingEnd, selectionEnd)
1827
+ )
1828
+ }
1829
+ if ((nonPrintableFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_WHITESPACE_INNER) == 0) {
1830
+ drawWhitespaces(
1831
+ _canvas!!,
1832
+ sharedTextRow,
1833
+ text!!,
1834
+ index,
1835
+ count,
1836
+ contextIndex,
1837
+ contextCount,
1838
+ isRtl,
1839
+ horizontalOffset,
1840
+ width,
1841
+ max(wsLeadingEnd, selectionStart),
1842
+ min(wsTrailingStart, selectionEnd)
1843
+ )
1844
+ }
1845
+ if ((nonPrintableFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_WHITESPACE_TRAILING) == 0) {
1846
+ drawWhitespaces(
1847
+ _canvas!!,
1848
+ sharedTextRow,
1849
+ text!!,
1850
+ index,
1851
+ count,
1852
+ contextIndex,
1853
+ contextCount,
1854
+ isRtl,
1855
+ horizontalOffset,
1856
+ width,
1857
+ max(wsTrailingStart, selectionStart),
1858
+ selectionEnd
1859
+ )
1860
+ }
1861
+ }
1862
+ }
1863
+ }
1864
+ })
1865
+ canvas.restore()
1866
+ bufferedDrawPoints.setOffsets(0f, 0f)
1867
+ }
1868
+
1869
+ // Draw composing text underline
1870
+ if (composingPosition != null && line == composingPosition.line) {
1871
+ val composingStart: Int = composingPosition.column
1872
+ val composingEnd: Int = composingStart + composingLength
1873
+ val paintStart: Int = Math.min(Math.max(composingStart, rowInf.startColumn), rowInf.endColumn)
1874
+ val paintEnd: Int = Math.min(Math.max(composingEnd, rowInf.startColumn), rowInf.endColumn)
1875
+
1876
+ if (paintStart < paintEnd) {
1877
+ sharedTextRow.set(
1878
+ lineBuf!!,
1879
+ rowInf.startColumn,
1880
+ rowInf.endColumn,
1881
+ reader!!.getSpansOnLine(line),
1882
+ rowInf.inlayHints,
1883
+ content!!.getLineDirections(line),
1884
+ paintGeneral,
1885
+ lineCache,
1886
+ trParams
1887
+ )
1888
+ tmpRect.top = (editor.getRowBottom(row) - editor.offsetY).toFloat()
1889
+ tmpRect.bottom = tmpRect.top + editor.logicalRowHeight.toFloat() * 0.06f
1890
+ val finalOffset = paintingOffset
1891
+ sharedTextRow.iterateBackgroundRegions(paintStart, paintEnd, false, false, object : TextRow.BackgroundRegionConsumer {
1892
+ override fun handleRegion(left: Float, right: Float): Boolean {
1893
+ tmpRect.left = finalOffset + left
1894
+ tmpRect.right = finalOffset + right
1895
+ if (tmpRect.right > 0f && tmpRect.left < editor.width) drawColor(
1896
+ canvas,
1897
+ editor.colorScheme.getColor(EditorColorScheme.UNDERLINE),
1898
+ tmpRect
1899
+ )
1900
+ return tmpRect.right < editor.width
1901
+ }
1902
+ })
1903
+ }
1904
+ }
1905
+
1906
+ val layout =
1907
+ editor.layout!!
1908
+ // Draw cursors
1909
+ if (cursor.isSelected()) {
1910
+ if (cursor.leftLine == line && isInside(
1911
+ cursor.leftColumn,
1912
+ rowInf.startColumn,
1913
+ rowInf.endColumn,
1914
+ rowInf.isTrailingRow
1915
+ )
1916
+ ) {
1917
+ val centerX: Float = editor.measureTextRegionOffset() + layout.getCharLayoutOffset(
1918
+ cursor.leftLine,
1919
+ cursor.leftColumn
1920
+ )[1] - editor.offsetX
1921
+ val type =
1922
+ if (content!!.isRtlAt(
1923
+ cursor.leftLine,
1924
+ cursor.leftColumn
1925
+ )
1926
+ ) SelectionHandleStyle.HANDLE_TYPE_RIGHT else SelectionHandleStyle.HANDLE_TYPE_LEFT
1927
+ val task: DrawCursorTask = DrawCursorTask(
1928
+ centerX,
1929
+ (getRowBottomForBackground(row) - editor.offsetY).toFloat(),
1930
+ type,
1931
+ editor.handleDescLeft!!
1932
+ )
1933
+ postDrawCursor.add(task)
1934
+ applyBidiIndicatorAttrs(task, cursor.leftLine, cursor.leftColumn)
1935
+ }
1936
+ if (cursor.rightLine == line && isInside(
1937
+ cursor.rightColumn,
1938
+ rowInf.startColumn,
1939
+ rowInf.endColumn,
1940
+ rowInf.isTrailingRow
1941
+ )
1942
+ ) {
1943
+ val centerX: Float = editor.measureTextRegionOffset() + layout.getCharLayoutOffset(
1944
+ cursor.rightLine,
1945
+ cursor.rightColumn
1946
+ )[1] - editor.offsetX
1947
+ val type =
1948
+ if (content!!.isRtlAt(
1949
+ cursor.rightLine,
1950
+ cursor.rightColumn
1951
+ )
1952
+ ) SelectionHandleStyle.HANDLE_TYPE_LEFT else SelectionHandleStyle.HANDLE_TYPE_RIGHT
1953
+ val task: DrawCursorTask = DrawCursorTask(
1954
+ centerX,
1955
+ (getRowBottomForBackground(row) - editor.offsetY).toFloat(),
1956
+ type,
1957
+ editor.handleDescRight!!
1958
+ )
1959
+ postDrawCursor.add(task)
1960
+ applyBidiIndicatorAttrs(task, cursor.rightLine, cursor.rightColumn)
1961
+ }
1962
+ } else if (cursor.leftLine == line && isInside(
1963
+ cursor.leftColumn,
1964
+ rowInf.startColumn,
1965
+ rowInf.endColumn,
1966
+ rowInf.isTrailingRow
1967
+ )
1968
+ ) {
1969
+ val centerX: Float = editor.measureTextRegionOffset() + layout.getCharLayoutOffset(
1970
+ cursor.leftLine,
1971
+ cursor.leftColumn
1972
+ )[1] - editor.offsetX
1973
+ val task: DrawCursorTask = DrawCursorTask(
1974
+ centerX,
1975
+ (getRowBottomForBackground(row) - editor.offsetY).toFloat(),
1976
+ SelectionHandleStyle.HANDLE_TYPE_INSERT,
1977
+ editor.handleDescInsert!!
1978
+ )
1979
+ postDrawCursor.add(task)
1980
+ val c = cursor
1981
+ if (c != null) {
1982
+ applyBidiIndicatorAttrs(task, c.leftLine, c.leftColumn)
1983
+ }
1984
+ }
1985
+ // Draw dragging selection or selecting target
1986
+ val draggingSelection = editor.touchHandler!!.draggingSelection
1987
+ if (draggingSelection != null) {
1988
+ if (draggingSelection.line == line && isInside(
1989
+ draggingSelection.column,
1990
+ rowInf.startColumn,
1991
+ rowInf.endColumn,
1992
+ rowInf.isTrailingRow
1993
+ )
1994
+ ) {
1995
+ val layout: io.github.abc15018045126.sora.widget.layout.Layout = editor.layout!!
1996
+ val centerX: Float = editor.measureTextRegionOffset() + layout.getCharLayoutOffset(
1997
+ draggingSelection.line,
1998
+ draggingSelection.column
1999
+ )[1] - editor.offsetX
2000
+ val task: DrawCursorTask = DrawCursorTask(
2001
+ centerX,
2002
+ (getRowBottomForBackground(row) - editor.offsetY).toFloat(),
2003
+ SelectionHandleStyle.HANDLE_TYPE_UNDEFINED,
2004
+ null
2005
+ )
2006
+ postDrawCursor.add(task)
2007
+ val c = cursor
2008
+ if (c != null) {
2009
+ applyBidiIndicatorAttrs(task, draggingSelection.line, draggingSelection.column)
2010
+ }
2011
+ }
2012
+ } else if (editor.isInMouseMode && editor.isTextSelected) {
2013
+ val target =
2014
+ editor.selectingTarget
2015
+ if (target != null && target.line == line && isInside(
2016
+ target.column,
2017
+ rowInf.startColumn,
2018
+ rowInf.endColumn,
2019
+ rowInf.isTrailingRow
2020
+ )
2021
+ ) {
2022
+ val layout: io.github.abc15018045126.sora.widget.layout.Layout = editor.layout!!
2023
+ val centerX: Float = editor.measureTextRegionOffset() + layout.getCharLayoutOffset(
2024
+ target.line,
2025
+ target.column
2026
+ )[1] - editor.offsetX
2027
+ val task: DrawCursorTask = DrawCursorTask(
2028
+ centerX,
2029
+ (getRowBottomForBackground(row) - editor.offsetY).toFloat(),
2030
+ SelectionHandleStyle.HANDLE_TYPE_UNDEFINED,
2031
+ null
2032
+ )
2033
+ postDrawCursor.add(task)
2034
+ applyBidiIndicatorAttrs(task, target.line, target.column)
2035
+ }
2036
+ }
2037
+ row++
2038
+ }
2039
+
2040
+ // Release last used reader object
2041
+ if (reader != null) {
2042
+ try {
2043
+ reader.moveToLine(-1)
2044
+ } catch (e: Exception) {
2045
+ Log.w(
2046
+ io.github.abc15018045126.sora.widget.EditorRenderer.Companion.LOG_TAG,
2047
+ "Failed to release SpanReader",
2048
+ e
2049
+ )
2050
+ }
2051
+ }
2052
+
2053
+ paintGeneral.isFakeBoldText = false
2054
+ paintGeneral.textSkewX = 0f
2055
+ paintOther.setStrokeWidth(circleRadius * 2)
2056
+ bufferedDrawPoints.commitPoints(canvas, paintOther)
2057
+ }
2058
+
2059
+ private fun getBidiIndicatorAttrs(line: Int, column: Int): Long {
2060
+ val lineDirections: Directions = getLineDirections(line)
2061
+ val count: Int = lineDirections.runCount
2062
+ if (count == 1) {
2063
+ // Simple LTR/RTL Run
2064
+ return IntPair.pack(0, if (lineDirections.isRunRtl(0)) 1 else 0)
2065
+ }
2066
+ for (i in 0..<count) {
2067
+ if (i + 1 == count || lineDirections.getRunStart(i) <= column && column < lineDirections.getRunEnd(i)) {
2068
+ return IntPair.pack(
2069
+ if (editor.props!!.showBidiDirectionIndicator) 1 else 0,
2070
+ if (lineDirections.isRunRtl(i)) 1 else 0
2071
+ )
2072
+ }
2073
+ }
2074
+ return IntPair.pack(0, 0)
2075
+ }
2076
+
2077
+ private fun applyBidiIndicatorAttrs(task: DrawCursorTask, line: Int, column: Int) {
2078
+ val bidiAttrs = getBidiIndicatorAttrs(line, column)
2079
+ task.isBidiIndicatorRequired = IntPair.getFirst(bidiAttrs) == 1
2080
+ task.isRightToLeft = IntPair.getSecond(bidiAttrs) == 1
2081
+ }
2082
+
2083
+ private fun drawBidiSelectionIndicator(
2084
+ canvas: Canvas,
2085
+ x: Float,
2086
+ topY: Float,
2087
+ selectionHeight: Float,
2088
+ isRtl: Boolean
2089
+ ) {
2090
+ val height = selectionHeight * 0.2f
2091
+ val deltaX = height * 0.866f // sqrt(3)/ 2
2092
+ tmpPath.reset()
2093
+ tmpPath.moveTo(x, topY)
2094
+ tmpPath.lineTo(x + (if (isRtl) -deltaX else deltaX), topY + height / 2f)
2095
+ tmpPath.lineTo(x, topY + height)
2096
+ tmpPath.close()
2097
+ canvas.drawPath(tmpPath, paintGeneral)
2098
+ }
2099
+
2100
+ protected fun drawDiagnosticIndicator(
2101
+ canvas: Canvas,
2102
+ style: DiagnosticIndicatorStyle,
2103
+ i: Int,
2104
+ startX: Float,
2105
+ endX: Float
2106
+ ) {
2107
+ val waveLength: Float = editor.dpUnit * editor.props!!.indicatorWaveLength
2108
+ val amplitude: Float = editor.dpUnit * editor.props!!.indicatorWaveAmplitude
2109
+ val waveWidth: Float = editor.dpUnit * editor.props!!.indicatorWaveWidth
2110
+ // Draw
2111
+ val centerY: Float = (editor.getRowBottom(i) - editor.offsetY).toFloat()
2112
+ when (style) {
2113
+ DiagnosticIndicatorStyle.NONE -> {}
2114
+ DiagnosticIndicatorStyle.WAVY_LINE -> {
2115
+ var lineWidth = 0f - startX
2116
+ var waveCount = ceil((lineWidth / waveLength).toDouble()).toInt()
2117
+ val phi = if (lineWidth < 0) 0f else (waveLength * waveCount - lineWidth)
2118
+ lineWidth = endX - startX
2119
+ canvas.save()
2120
+ canvas.clipRect(startX, 0f, endX, canvas.height.toFloat())
2121
+ canvas.translate(startX, centerY)
2122
+ tmpPath.reset()
2123
+ tmpPath.moveTo(0f, 0f)
2124
+ waveCount = ceil(((phi + lineWidth) / waveLength).toDouble()).toInt()
2125
+ var j = 0
2126
+ while (j < waveCount) {
2127
+ tmpPath.quadTo(waveLength * j + waveLength / 4, amplitude, waveLength * j + waveLength / 2, 0f)
2128
+ tmpPath.quadTo(waveLength * j + waveLength * 3 / 4, -amplitude, waveLength * j + waveLength, 0f)
2129
+ j++
2130
+ }
2131
+ // Draw path
2132
+ paintOther.setStrokeWidth(waveWidth)
2133
+ paintOther.setStyle(AndroidPaint.Style.STROKE)
2134
+ canvas.drawPath(tmpPath, paintOther)
2135
+ canvas.restore()
2136
+ paintOther.setStyle(AndroidPaint.Style.FILL)
2137
+ }
2138
+
2139
+ DiagnosticIndicatorStyle.LINE -> {
2140
+ paintOther.setStrokeWidth(waveWidth)
2141
+ canvas.drawLine(startX, centerY, endX, centerY, paintOther)
2142
+ }
2143
+
2144
+ DiagnosticIndicatorStyle.DOUBLE_LINE -> {
2145
+ paintOther.setStrokeWidth(waveWidth / 3f)
2146
+ canvas.drawLine(startX, centerY, endX, centerY, paintOther)
2147
+ canvas.drawLine(startX, centerY - waveWidth, endX, centerY - waveWidth, paintOther)
2148
+ }
2149
+ else -> {}
2150
+ }
2151
+ }
2152
+
2153
+ protected fun drawDiagnosticIndicators(canvas: Canvas, offset: Float) {
2154
+ val diagnosticsContainer =
2155
+ editor.diagnostics
2156
+ val style =
2157
+ editor.diagnosticIndicatorStyle
2158
+ if (diagnosticsContainer != null && style != DiagnosticIndicatorStyle.NONE && style != null) {
2159
+ val text: Content = content!!
2160
+ val firstVisRow =
2161
+ editor.firstVisibleRow
2162
+ val lastVisRow =
2163
+ editor.lastVisibleRow
2164
+ val firstIndex =
2165
+ text.getCharIndex(editor.firstVisibleLine, 0)
2166
+ val lastLine =
2167
+ kotlin.math.min(text.lineCount - 1, editor.lastVisibleLine + 1)
2168
+ val lastIndex =
2169
+ text.getCharIndex(lastLine, 0) + text.getColumnCount(lastLine)
2170
+ diagnosticsContainer.queryInRegion(collectedDiagnostics, firstIndex, lastIndex)
2171
+ if (collectedDiagnostics.isEmpty()) {
2172
+ return
2173
+ }
2174
+ val start: CharPosition = CharPosition()
2175
+ val end: CharPosition = CharPosition()
2176
+ val localCursor = cursor ?: return
2177
+ val indexer =
2178
+ localCursor.getIndexer()
2179
+ for (region in collectedDiagnostics) {
2180
+ val startIndex =
2181
+ max(firstIndex, region.startIndex)
2182
+ val endIndex =
2183
+ min(lastIndex, region.endIndex)
2184
+ indexer.getCharPosition(startIndex, start)
2185
+ indexer.getCharPosition(endIndex, end)
2186
+ val startRow =
2187
+ editor.layout!!.getRowIndexForPosition(startIndex)
2188
+ val endRow =
2189
+ editor.layout!!.getRowIndexForPosition(endIndex)
2190
+ // Setup color
2191
+ val severity = region.severity.toInt()
2192
+ val colorId =
2193
+ if (severity >= 0 && severity <= 3) sDiagnosticsColorMapping[severity] else 0
2194
+ if (colorId == 0) {
2195
+ continue
2196
+ }
2197
+ paintOther.setColor(editor.colorScheme.getColor(colorId))
2198
+ val visStartRow: Int = Math.max(firstVisRow, startRow)
2199
+ val visEndRow: Int = Math.min(lastVisRow, endRow)
2200
+ for (i in visStartRow..visEndRow) {
2201
+ val row =
2202
+ editor.layout!!.getRowAt(i)
2203
+ updateTextRow(sharedTextRow, i)
2204
+ val startColumn: Int = if (i == startRow) start.column else row.startColumn
2205
+ val endColumn: Int = if (i == endRow) end.column else row.endColumn
2206
+ val finalOffset: Float
2207
+ if (editor.isWordwrap && !row.isLeadingRow && (editor.nonPrintablePaintingFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_SOFT_WRAP) !== 0) {
2208
+ finalOffset = offset + row.renderTranslateX + this.miniGraphWidth
2209
+ } else {
2210
+ finalOffset = offset + row.renderTranslateX
2211
+ }
2212
+ if (startColumn == endColumn) {
2213
+ // Make it always visible
2214
+ val startX =
2215
+ finalOffset + sharedTextRow.getCursorOffsetForIndex(startColumn)
2216
+ val endX =
2217
+ startX + paintGeneral.measureText("a")
2218
+ drawDiagnosticIndicator(canvas, style, i, startX, endX)
2219
+ } else {
2220
+ val rowIndex = i
2221
+ sharedTextRow.iterateBackgroundRegions(startColumn, endColumn, false, false, object : TextRow.BackgroundRegionConsumer {
2222
+ override fun handleRegion(left: Float, right: Float): Boolean {
2223
+ if (right > 0f) drawDiagnosticIndicator(
2224
+ canvas,
2225
+ style,
2226
+ rowIndex,
2227
+ finalOffset + left,
2228
+ finalOffset + right
2229
+ )
2230
+ return finalOffset + right < editor.width
2231
+ }
2232
+ })
2233
+ }
2234
+ }
2235
+ }
2236
+ }
2237
+ collectedDiagnostics.clear()
2238
+ }
2239
+
2240
+ /**
2241
+ * Draw non-printable characters
2242
+ */
2243
+ private fun drawWhitespaces(
2244
+ canvas: Canvas,
2245
+ tr: TextRow,
2246
+ chars: CharArray,
2247
+ index: Int,
2248
+ count: Int,
2249
+ contextIndex: Int,
2250
+ contextCount: Int,
2251
+ isRtl: Boolean,
2252
+ horizontalOffset: Float,
2253
+ width: Float,
2254
+ min: Int,
2255
+ max: Int
2256
+ ) {
2257
+ var paintStart: Int = Math.max(index, Math.min(index + count, min))
2258
+ val paintEnd: Int = Math.max(index, Math.min(index + count, max))
2259
+
2260
+ if (paintStart < paintEnd) {
2261
+ val spaceWidth: Float = paintGeneral.spaceWidth
2262
+ val rowCenter: Float = (editor.logicalRowHeight / 2f + editor.getRowTopOfText(0))
2263
+ var offset = if (isRtl) horizontalOffset + width else horizontalOffset
2264
+ while (paintStart < paintEnd) {
2265
+ val ch = chars[paintStart]
2266
+ var paintCount = 0
2267
+ var paintLine = false
2268
+ if (ch == ' ' || ch == '\t') {
2269
+ val advance: Float = tr.measureAdvanceInRun(
2270
+ paintStart,
2271
+ index,
2272
+ paintStart,
2273
+ contextIndex,
2274
+ contextIndex + contextCount,
2275
+ isRtl
2276
+ )
2277
+ offset = if (isRtl) horizontalOffset + width - advance else horizontalOffset + advance
2278
+ }
2279
+ if (ch == ' ') {
2280
+ paintCount = 1
2281
+ } else if (ch == '\t') {
2282
+ if ((editor.nonPrintablePaintingFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_TAB_SAME_AS_SPACE) !== 0) {
2283
+ paintCount = editor.tabWidth
2284
+ } else {
2285
+ paintLine = true
2286
+ }
2287
+ }
2288
+ for (i in 0 until paintCount) {
2289
+ val charStartOffset = offset + spaceWidth * i
2290
+ val charEndOffset = charStartOffset + spaceWidth
2291
+ var centerOffset = (charStartOffset + charEndOffset) / 2f
2292
+ if (isRtl) {
2293
+ centerOffset -= spaceWidth
2294
+ }
2295
+ bufferedDrawPoints.drawPoint(centerOffset, rowCenter)
2296
+ }
2297
+ if (paintLine) {
2298
+ val charWidth =
2299
+ editor.tabWidth * spaceWidth
2300
+ val delta: Float = charWidth * 0.05f
2301
+ val rtlDelta = if (isRtl) -charWidth else 0f
2302
+ canvas.drawLine(
2303
+ offset + delta + rtlDelta,
2304
+ rowCenter,
2305
+ offset + charWidth + rtlDelta - delta,
2306
+ rowCenter,
2307
+ paintOther
2308
+ )
2309
+ }
2310
+
2311
+ if (ch == ' ' || ch == '\t') {
2312
+ val charWidth = (if (ch == ' ') spaceWidth else spaceWidth * editor.tabWidth)
2313
+ offset += if (isRtl) -charWidth else charWidth
2314
+ }
2315
+ paintStart++
2316
+ }
2317
+ }
2318
+ }
2319
+
2320
+ val miniGraphWidth: Float
2321
+ get() {
2322
+ val height: Float = editor.logicalRowHeight * editor.props!!.miniMarkerSizeFactor
2323
+ val graph =
2324
+ editor.context.getDrawable(R.drawable.line_break)
2325
+ if (graph == null) {
2326
+ return 0f
2327
+ }
2328
+ val w: Int = graph.intrinsicWidth
2329
+ val h: Int = graph.intrinsicHeight
2330
+ if (w <= 0 || h <= 0 || height <= 0) {
2331
+ return 0f
2332
+ }
2333
+ return height * (w.toFloat() / h)
2334
+ }
2335
+
2336
+ /**
2337
+ * Draw small characters as graph
2338
+ */
2339
+ protected fun drawMiniGraph(canvas: Canvas?, offset: Float, row: Int, graph: Drawable?) {
2340
+ if (canvas == null) {
2341
+ return
2342
+ }
2343
+ val graphBottom: Float =
2344
+ if (row == -1) (editor.getRowBottomOfText(0)).toFloat() else (editor.getRowBottomOfText(row) - editor.offsetY).toFloat()
2345
+ val height: Float = editor.logicalRowHeight * editor.props!!.miniMarkerSizeFactor
2346
+ if (height <= 0 || graph == null) {
2347
+ return
2348
+ }
2349
+ val w: Int = graph.intrinsicWidth
2350
+ val h: Int = graph.intrinsicHeight
2351
+ if (w <= 0 || h <= 0) {
2352
+ return
2353
+ }
2354
+ val width = height * (w.toFloat() / h)
2355
+ graph.setColorFilter(
2356
+ editor.colorScheme.getColor(EditorColorScheme.NON_PRINTABLE_CHAR),
2357
+ PorterDuff.Mode.SRC_ATOP
2358
+ )
2359
+ graph.setBounds(offset.toInt(), (graphBottom - height).toInt(), (offset + width).toInt(), graphBottom.toInt())
2360
+ graph.draw(canvas)
2361
+ }
2362
+
2363
+ protected fun getRowTopForBackground(row: Int): Int {
2364
+ if (!editor.props!!.textBackgroundWrapTextOnly) {
2365
+ return editor.getRowTop(row)
2366
+ } else {
2367
+ return editor.getRowTopOfText(row)
2368
+ }
2369
+ }
2370
+
2371
+ protected fun getRowBottomForBackground(row: Int): Int {
2372
+ if (!editor.props!!.textBackgroundWrapTextOnly) {
2373
+ return editor.getRowBottom(row)
2374
+ } else {
2375
+ return editor.getRowBottomOfText(row)
2376
+ }
2377
+ }
2378
+
2379
+ /**
2380
+ * Draw background of a text region
2381
+ *
2382
+ * @param canvas Canvas to draw
2383
+ * @param row The row index
2384
+ * @param highlightStart Region start
2385
+ * @param highlightEnd Region end
2386
+ * @param color Color of background
2387
+ */
2388
+ protected fun drawRowRegionBackground(
2389
+ @NonNull canvas: Canvas,
2390
+ row: Int,
2391
+ @Nullable tr: TextRow?,
2392
+ highlightStart: Int,
2393
+ highlightEnd: Int,
2394
+ rowStart: Int,
2395
+ rowEnd: Int,
2396
+ color: Int,
2397
+ borderColor: Int
2398
+ ) {
2399
+ var tr: TextRow? = tr
2400
+ var highlightStart = highlightStart
2401
+ var highlightEnd = highlightEnd
2402
+ highlightStart = Math.max(highlightStart, rowStart)
2403
+ highlightEnd = Math.min(highlightEnd, rowEnd)
2404
+ if (highlightStart < highlightEnd) {
2405
+ tmpRect.top = (getRowTopForBackground(row) - editor.offsetY).toFloat()
2406
+ tmpRect.bottom = (getRowBottomForBackground(row) - editor.offsetY).toFloat()
2407
+ var offset: Float = editor.measureTextRegionOffset() - editor.offsetX
2408
+ if (editor.isWordwrap && !editor.layout!!
2409
+ .getRowAt(row).isLeadingRow && (editor.nonPrintablePaintingFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_SOFT_WRAP) !== 0
2410
+ ) {
2411
+ offset += this.miniGraphWidth
2412
+ }
2413
+ val finalOffset = offset
2414
+ if (tr == null) {
2415
+ tr = createTextRow(row)
2416
+ }
2417
+ val width =
2418
+ editor.width
2419
+ tr.iterateBackgroundRegions(highlightStart, highlightEnd, false, false, object : TextRow.BackgroundRegionConsumer {
2420
+ override fun handleRegion(left: Float, right: Float): Boolean {
2421
+ tmpRect.left = finalOffset + left
2422
+ tmpRect.right = finalOffset + right
2423
+ if (tmpRect.right < 0 || tmpRect.left > width) {
2424
+ return false
2425
+ }
2426
+ drawRowBackgroundRectWithBorder(canvas, tmpRect, color, borderColor)
2427
+ return true
2428
+ }
2429
+ })
2430
+ }
2431
+ }
2432
+
2433
+ protected fun drawRowBackgroundRectWithBorder(
2434
+ canvas: Canvas,
2435
+ rect: RectF?,
2436
+ backgroundColor: Int,
2437
+ borderColor: Int
2438
+ ) {
2439
+ paintGeneral.setColor(backgroundColor)
2440
+ drawRowBackgroundRect(canvas, rect)
2441
+ if (borderColor == 0) {
2442
+ return
2443
+ }
2444
+ paintGeneral.setColor(borderColor)
2445
+ paintGeneral.setStyle(android.graphics.Paint.Style.STROKE)
2446
+ paintGeneral.setStrokeWidth(editor.getTextBorderWidth())
2447
+ drawRowBackgroundRect(canvas, rect)
2448
+ paintGeneral.setStyle(android.graphics.Paint.Style.FILL)
2449
+ }
2450
+
2451
+ protected fun drawRowBackgroundRect(canvas: Canvas, rect: RectF?) {
2452
+ drawRowBackgroundRect(canvas, rect, paintGeneral)
2453
+ }
2454
+
2455
+ protected fun drawRowBackgroundRect(canvas: Canvas, rect: RectF?, p: Paint?) {
2456
+ if (rect == null || p == null) {
2457
+ return
2458
+ }
2459
+ if (editor.props!!.enableRoundTextBackground) {
2460
+ canvas.drawRoundRect(
2461
+ rect,
2462
+ editor.logicalRowHeight * editor.props!!.roundTextBackgroundFactor,
2463
+ editor.logicalRowHeight * editor.props!!.roundTextBackgroundFactor,
2464
+ p
2465
+ )
2466
+ } else {
2467
+ canvas.drawRect(rect, p)
2468
+ }
2469
+ }
2470
+
2471
+ /**
2472
+ * Is inside the region
2473
+ *
2474
+ * @param index Index to test
2475
+ * @param start Start of region
2476
+ * @param end End of region
2477
+ * @return true if cursor should be drawn in this row
2478
+ */
2479
+ private fun isInside(index: Int, start: Int, end: Int, isLastRow: Boolean): Boolean {
2480
+ // Due not to draw duplicate cursors for a single one
2481
+ if (index == end && !isLastRow) {
2482
+ return false
2483
+ }
2484
+ return index >= start && index <= end
2485
+ }
2486
+
2487
+ val lineNumberMetrics: android.graphics.Paint.FontMetricsInt
2488
+ get() = metricsLineNumber
2489
+
2490
+ val textMetrics: android.graphics.Paint.FontMetricsInt?
2491
+ get() = metricsText
2492
+
2493
+ /**
2494
+ * Draw effect of edges
2495
+ *
2496
+ * @param canvas The canvas to draw
2497
+ */
2498
+ protected fun drawEdgeEffect(canvas: Canvas) {
2499
+ var postDraw = false
2500
+ val verticalEdgeEffect =
2501
+ editor.verticalEdgeEffect!!
2502
+ val horizontalEdgeEffect =
2503
+ editor.horizontalEdgeEffect!!
2504
+ if (!verticalEdgeEffect.isFinished) {
2505
+ val bottom: Boolean = editor.touchHandler!!.glowTopOrBottom
2506
+ if (bottom) {
2507
+ canvas.save()
2508
+ canvas.translate(-editor.measuredWidth.toFloat(), editor.measuredHeight.toFloat())
2509
+ canvas.rotate(180f, editor.measuredWidth.toFloat(), 0f)
2510
+ }
2511
+ postDraw = verticalEdgeEffect.draw(canvas)
2512
+ if (bottom) {
2513
+ canvas.restore()
2514
+ }
2515
+ }
2516
+ if (editor.isWordwrap) {
2517
+ horizontalEdgeEffect.finish()
2518
+ }
2519
+ if (!horizontalEdgeEffect.isFinished) {
2520
+ canvas.save()
2521
+ val right: Boolean = editor.touchHandler!!.glowLeftOrRight
2522
+ if (right) {
2523
+ canvas.rotate(90f)
2524
+ canvas.translate(0f, -editor.measuredWidth.toFloat())
2525
+ } else {
2526
+ canvas.translate(0f, editor.measuredHeight.toFloat())
2527
+ canvas.rotate(-90f)
2528
+ }
2529
+ postDraw = horizontalEdgeEffect.draw(canvas) || postDraw
2530
+ canvas.restore()
2531
+ }
2532
+ val scroller =
2533
+ editor.scroller
2534
+ if (scroller.isOverScrolled()) {
2535
+ if (verticalEdgeEffect.isFinished && (scroller.getCurrY() < 0 || scroller.getCurrY() > editor.scrollMaxY)) {
2536
+ editor.eventHandler!!.glowTopOrBottom = scroller.getCurrY() >= editor.scrollMaxY
2537
+ verticalEdgeEffect.onAbsorb(scroller.getCurrVelocity().toInt())
2538
+ postDraw = true
2539
+ }
2540
+ if (horizontalEdgeEffect.isFinished && (scroller.getCurrX() < 0 || scroller.getCurrX() > editor.scrollMaxX)) {
2541
+ editor.eventHandler!!.glowLeftOrRight = scroller.getCurrX() >= editor.scrollMaxX
2542
+ horizontalEdgeEffect.onAbsorb(scroller.getCurrVelocity().toInt())
2543
+ postDraw = true
2544
+ }
2545
+ }
2546
+ if (postDraw) {
2547
+ editor.postInvalidate()
2548
+ }
2549
+ }
2550
+
2551
+ /**
2552
+ * Draw code block lines on screen
2553
+ *
2554
+ * @param canvas The canvas to draw
2555
+ * @param offsetX The start x offset for text
2556
+ */
2557
+ protected fun drawBlockLines(canvas: Canvas?, offsetX: Float) {
2558
+ if (canvas == null) {
2559
+ return
2560
+ }
2561
+ val styles = editor.styles
2562
+ val blocks: List<CodeBlock?>? = if (styles == null) null else styles.blocks
2563
+ val indentMode = styles != null && styles.isIndentCountMode()
2564
+ if (blocks == null || blocks.isEmpty()) {
2565
+ return
2566
+ }
2567
+ val firstLine: Int = editor.firstVisibleLine
2568
+ val lastLine: Int = editor.lastVisibleLine
2569
+ var mark = false
2570
+ var invalidCount = 0
2571
+ val maxCount: Int = styles!!.getSuppressSwitch()
2572
+ var mm: Int = editor.binarySearchEndBlock(firstLine, blocks as List<CodeBlock>)
2573
+ if (mm == -1) {
2574
+ mm = 0
2575
+ }
2576
+ val cursorIdx: Int = editor.blockIndex
2577
+ for (curr in mm until blocks.size) {
2578
+ val block: CodeBlock? = blocks[curr]
2579
+ if (block == null) {
2580
+ continue
2581
+ }
2582
+ if (io.github.abc15018045126.sora.widget.CodeEditor.hasVisibleRegion(block.startLine, block.endLine, firstLine, lastLine)) {
2583
+ try {
2584
+ var lineContent: ContentLine = getLine(block.endLine)
2585
+ val offsetEnd: Float =
2586
+ if (indentMode) paintGeneral.spaceWidth * block.endColumn else createTextRow(block.endLine).getCursorOffsetForIndex(
2587
+ Math.min(block.endColumn, lineContent.length)
2588
+ )
2589
+ lineContent = getLine(block.startLine)
2590
+ val offsetStart: Float =
2591
+ if (indentMode) paintGeneral.spaceWidth * block.startColumn else createTextRow(block.startLine).getCursorOffsetForIndex(
2592
+ Math.min(block.startColumn, lineContent.length)
2593
+ )
2594
+ val offset: Float = min(offsetEnd, offsetStart)
2595
+ val centerX = offset + offsetX
2596
+ tmpRect.top = max(0f, (editor.getRowBottom(block.startLine) - editor.offsetY).toFloat())
2597
+ tmpRect.bottom = min(
2598
+ editor.height.toFloat(),
2599
+ ((if (block.toBottomOfEndLine) editor.getRowBottom(block.endLine) else editor.getRowTop(block.endLine)) - editor.offsetY).toFloat()
2600
+ )
2601
+ tmpRect.left = centerX - editor.dpUnit * editor.getBlockLineWidth() / 2
2602
+ tmpRect.right = centerX + editor.dpUnit * editor.getBlockLineWidth() / 2
2603
+ drawColor(
2604
+ canvas,
2605
+ editor.colorScheme
2606
+ .getColor(if (curr == cursorIdx) EditorColorScheme.BLOCK_LINE_CURRENT else EditorColorScheme.BLOCK_LINE),
2607
+ tmpRect
2608
+ )
2609
+ } catch (e: IndexOutOfBoundsException) {
2610
+ // Ignored
2611
+ // Because the exception usually occurs when the content is changed.
2612
+ }
2613
+ mark = true
2614
+ } else if (mark) {
2615
+ if (invalidCount >= maxCount) break
2616
+ invalidCount++
2617
+ }
2618
+ }
2619
+ }
2620
+
2621
+ protected fun drawSideBlockLine(canvas: Canvas) {
2622
+ if (!editor.props!!.drawSideBlockLine) {
2623
+ return
2624
+ }
2625
+ val styles = editor.styles
2626
+ val blocks: List<CodeBlock?>? = styles?.blocks
2627
+ if (blocks == null || blocks.isEmpty()) {
2628
+ return
2629
+ }
2630
+ val current =
2631
+ editor.blockIndex
2632
+ if (current >= 0 && current < blocks.size) {
2633
+ val block =
2634
+ blocks[current]
2635
+ if (block != null) {
2636
+ val layout: io.github.abc15018045126.sora.widget.layout.Layout = editor.layout!!
2637
+ try {
2638
+ val top: Float = layout.getCharLayoutOffset(
2639
+ block.startLine,
2640
+ block.startColumn
2641
+ )[0] - editor.logicalRowHeight - editor.offsetY
2642
+ val bottom: Float = layout.getCharLayoutOffset(block.endLine, block.endColumn)[0] - editor.offsetY
2643
+ val left: Float = editor.measureLineNumber()
2644
+ val right: Float = left + editor.dividerMarginLeft
2645
+ val center: Float = (left + right) / 2 - editor.offsetX
2646
+ paintGeneral.setColor(editor.colorScheme.getColor(EditorColorScheme.SIDE_BLOCK_LINE))
2647
+ paintGeneral.setStrokeWidth(editor.dpUnit * editor.getBlockLineWidth())
2648
+ canvas.drawLine(center, top, center, bottom, paintGeneral)
2649
+ } catch (e: IndexOutOfBoundsException) {
2650
+ //ignored
2651
+ }
2652
+ }
2653
+ }
2654
+ }
2655
+
2656
+ /**
2657
+ * Draw scroll bars and tracks
2658
+ *
2659
+ * @param canvas The canvas to draw
2660
+ */
2661
+ protected fun drawScrollBars(canvas: Canvas) {
2662
+ verticalScrollBarRect.setEmpty()
2663
+ horizontalScrollBarRect.setEmpty()
2664
+ val handler: io.github.abc15018045126.sora.widget.EditorTouchEventHandler = editor.touchHandler!!
2665
+ if (!handler.shouldDrawScrollBarForTouch() && !(editor.isInMouseMode && editor.props!!.mouseModeAlwaysShowScrollbars)) {
2666
+ return
2667
+ }
2668
+ var percentage =
2669
+ handler.getScrollBarFadeOutPercentageForTouch()
2670
+ if (editor.isInMouseMode && editor.props!!.mouseModeAlwaysShowScrollbars) {
2671
+ percentage = 0f
2672
+ }
2673
+ val size =
2674
+ editor.dpUnit * RenderingConstants.SCROLLBAR_WIDTH_DIP
2675
+ if (editor.isHorizontalScrollBarEnabled() && !editor.isWordwrap && editor.scrollMaxX > editor.width * 3 / 4) {
2676
+ canvas.save()
2677
+ canvas.translate(0f, size * percentage)
2678
+
2679
+ drawScrollBarTrackHorizontal(canvas)
2680
+ drawScrollBarHorizontal(canvas)
2681
+
2682
+ canvas.restore()
2683
+ }
2684
+ if (editor.isVerticalScrollBarEnabled() && editor.scrollMaxY > editor.height / 2) {
2685
+ canvas.save()
2686
+ canvas.translate(size * percentage, 0f)
2687
+
2688
+ drawScrollBarTrackVertical(canvas)
2689
+ drawScrollBarVertical(canvas)
2690
+
2691
+ canvas.restore()
2692
+ }
2693
+ }
2694
+
2695
+ /**
2696
+ * Draw vertical scroll bar track
2697
+ *
2698
+ * @param canvas Canvas to draw
2699
+ */
2700
+ protected fun drawScrollBarTrackVertical(canvas: Canvas?) {
2701
+ if (canvas == null) {
2702
+ return
2703
+ }
2704
+ val handler: io.github.abc15018045126.sora.widget.EditorTouchEventHandler = editor.touchHandler!!
2705
+ if (handler.holdVerticalScrollBar()) {
2706
+ tmpRect.right = editor.width.toFloat()
2707
+ tmpRect.left = editor.width - editor.dpUnit * RenderingConstants.SCROLLBAR_WIDTH_DIP
2708
+ tmpRect.top = 0f
2709
+ tmpRect.bottom = editor.height.toFloat()
2710
+ val track = verticalScrollbarTrackDrawable
2711
+ if (track != null) {
2712
+ track.setBounds(
2713
+ tmpRect.left.toInt(),
2714
+ tmpRect.top.toInt(),
2715
+ tmpRect.right.toInt(),
2716
+ tmpRect.bottom.toInt()
2717
+ )
2718
+ track.draw(canvas)
2719
+ } else {
2720
+ drawColor(canvas, editor.colorScheme.getColor(EditorColorScheme.SCROLL_BAR_TRACK), tmpRect)
2721
+ }
2722
+ }
2723
+ }
2724
+
2725
+ /**
2726
+ * Draw vertical scroll bar
2727
+ *
2728
+ * @param canvas Canvas to draw
2729
+ */
2730
+ protected fun drawScrollBarVertical(canvas: Canvas) {
2731
+ val height: Int = editor.height
2732
+ val all: Float = (editor.scrollMaxY + height).toFloat()
2733
+ val length: Float =
2734
+ max(height / all * height, editor.dpUnit * RenderingConstants.SCROLLBAR_LENGTH_MIN_DIP)
2735
+ val topY: Float = editor.offsetY * 1.0f / editor.scrollMaxY * (height - length)
2736
+ val handler: io.github.abc15018045126.sora.widget.EditorTouchEventHandler = editor.touchHandler!!
2737
+ if (handler.holdVerticalScrollBar()) {
2738
+ drawLineInfoPanel(canvas, topY, length)
2739
+ }
2740
+ tmpRect.right = editor.width.toFloat()
2741
+ tmpRect.left = editor.width - editor.dpUnit * RenderingConstants.SCROLLBAR_WIDTH_DIP
2742
+ tmpRect.top = topY
2743
+ tmpRect.bottom = topY + length
2744
+ verticalScrollBarRect.set(tmpRect)
2745
+ val thumb = verticalScrollbarThumbDrawable
2746
+ if (thumb != null) {
2747
+ thumb.setState(
2748
+ if (handler
2749
+ .holdVerticalScrollBar()
2750
+ ) PRESSED_DRAWABLE_STATE else DEFAULT_DRAWABLE_STATE
2751
+ )
2752
+ thumb.setBounds(
2753
+ tmpRect.left.toInt(),
2754
+ tmpRect.top.toInt(),
2755
+ tmpRect.right.toInt(),
2756
+ tmpRect.bottom.toInt()
2757
+ )
2758
+ thumb.draw(canvas)
2759
+ } else {
2760
+ drawColor(
2761
+ canvas,
2762
+ editor.colorScheme.getColor(
2763
+ if (handler
2764
+ .holdVerticalScrollBar()
2765
+ ) EditorColorScheme.SCROLL_BAR_THUMB_PRESSED else EditorColorScheme.SCROLL_BAR_THUMB
2766
+ ),
2767
+ tmpRect
2768
+ )
2769
+ }
2770
+ }
2771
+
2772
+ /**
2773
+ * Draw line number panel
2774
+ *
2775
+ * @param canvas Canvas to draw
2776
+ * @param topY The y at the top of the vertical scrollbar
2777
+ * @param length The length of vertical scrollbar
2778
+ */
2779
+ protected fun drawLineInfoPanel(canvas: Canvas, topY: Float, length: Float) {
2780
+ if (!editor.isDisplayLnPanel) {
2781
+ return
2782
+ }
2783
+ val mode: Int = editor.lnPanelPositionMode
2784
+ val position: Int = editor.lnPanelPosition
2785
+ val text: String? = editor.getLineNumberTipTextProvider()!!.getCurrentText(editor)
2786
+ val backupSize: Float = paintGeneral.getTextSize()
2787
+ paintGeneral.setTextSize(editor.lineInfoTextSize)
2788
+ val backupMetrics: AndroidPaint.FontMetricsInt? = metricsText
2789
+ metricsText = paintGeneral.getFontMetricsInt()
2790
+ val expand: Float = editor.dpUnit * 8
2791
+ val textWidth: Float = paintGeneral.measureText(text)
2792
+ var baseline: Float
2793
+ var textOffset = 0f
2794
+ if (mode == LineInfoPanelPositionMode.FIXED) {
2795
+ tmpRect.top = editor.height / 2f - editor.logicalRowHeight / 2f - expand
2796
+ tmpRect.bottom = editor.height / 2f + editor.logicalRowHeight / 2f + expand
2797
+ tmpRect.left = editor.width / 2f - textWidth / 2f - expand
2798
+ tmpRect.right = editor.width / 2f + textWidth / 2f + expand
2799
+ baseline = editor.height / 2f + 2 * expand
2800
+ val offset: Float = 10 * editor.dpUnit
2801
+ if (position != LineInfoPanelPosition.CENTER) {
2802
+ if ((position or LineInfoPanelPosition.TOP) == position) {
2803
+ tmpRect.top = offset
2804
+ tmpRect.bottom = offset + editor.logicalRowHeight + 2 * expand
2805
+ baseline = offset + editor.getRowBaseline(0) + expand
2806
+ }
2807
+ if ((position or LineInfoPanelPosition.BOTTOM) == position) {
2808
+ tmpRect.top = editor.height - offset - 2 * expand - editor.logicalRowHeight
2809
+ tmpRect.bottom = editor.height - offset
2810
+ baseline = editor.height - editor.logicalRowHeight + editor.getRowBaseline(0) - offset - expand
2811
+ }
2812
+ if ((position or LineInfoPanelPosition.LEFT) == position) {
2813
+ tmpRect.left = offset
2814
+ tmpRect.right = offset + 2 * expand + textWidth
2815
+ }
2816
+ if ((position or LineInfoPanelPosition.RIGHT) == position) {
2817
+ tmpRect.right = editor.width - offset
2818
+ tmpRect.left = editor.width - offset - expand * 2 - textWidth
2819
+ }
2820
+ }
2821
+ drawColorRound(canvas, editor.colorScheme.getColor(EditorColorScheme.LINE_NUMBER_PANEL), tmpRect)
2822
+ } else {
2823
+ var radii: FloatArray? = null
2824
+ tmpRect.right = editor.width - 30 * editor.dpUnit
2825
+ tmpRect.left = editor.width - 30 * editor.dpUnit - expand * 2 - textWidth
2826
+ if (position == LineInfoPanelPosition.TOP) {
2827
+ tmpRect.top = topY
2828
+ tmpRect.bottom = topY + editor.logicalRowHeight + 2 * expand
2829
+ baseline = topY + editor.getRowBaseline(0) + expand
2830
+ radii = FloatArray(8)
2831
+ for (i in 0..7) {
2832
+ if (i != 5) radii[i] = tmpRect.height() * RenderingConstants.ROUND_BUBBLE_FACTOR
2833
+ }
2834
+ } else if (position == LineInfoPanelPosition.BOTTOM) {
2835
+ tmpRect.top = topY + length - editor.logicalRowHeight - 2 * expand
2836
+ tmpRect.bottom = topY + length
2837
+ baseline = topY + length - editor.getRowBaseline(0) / 2f
2838
+ radii = FloatArray(8)
2839
+ for (i in 0..7) {
2840
+ if (i != 3) radii[i] = tmpRect.height() * RenderingConstants.ROUND_BUBBLE_FACTOR
2841
+ }
2842
+ } else {
2843
+ val centerY = topY + length / 2f
2844
+ tmpRect.top = centerY - editor.logicalRowHeight / 2f - expand
2845
+ tmpRect.bottom = centerY + editor.logicalRowHeight / 2f + expand
2846
+ baseline = centerY - editor.logicalRowHeight / 2f + editor.getRowBaseline(0)
2847
+ }
2848
+ if (radii != null) {
2849
+ tmpPath.reset()
2850
+ tmpPath.addRoundRect(tmpRect, radii, Path.Direction.CW)
2851
+ } else {
2852
+ tmpRect.offset(-expand, 0f)
2853
+ tmpRect.right += expand
2854
+ textOffset = -expand / 2f
2855
+ BubbleHelper.buildBubblePath(tmpPath, tmpRect)
2856
+ }
2857
+ paintGeneral.setColor(editor.colorScheme.getColor(EditorColorScheme.LINE_NUMBER_PANEL))
2858
+ canvas.drawPath(tmpPath, paintGeneral)
2859
+ }
2860
+ val centerX: Float = (tmpRect.left + tmpRect.right) / 2 + textOffset
2861
+ paintGeneral.setColor(editor.colorScheme.getColor(EditorColorScheme.LINE_NUMBER_PANEL_TEXT))
2862
+ paintGeneral.textAlign = AndroidPaint.Align.CENTER
2863
+ if (text != null) {
2864
+ canvas.drawText(text, centerX, baseline, paintGeneral)
2865
+ }
2866
+ paintGeneral.textAlign = AndroidPaint.Align.LEFT
2867
+ paintGeneral.setTextSize(backupSize)
2868
+ metricsText = backupMetrics
2869
+ }
2870
+
2871
+ /**
2872
+ * Draw horizontal scroll bar track
2873
+ *
2874
+ * @param canvas Canvas to draw
2875
+ */
2876
+ protected fun drawScrollBarTrackHorizontal(canvas: Canvas?) {
2877
+ if (canvas == null) {
2878
+ return
2879
+ }
2880
+ val handler: io.github.abc15018045126.sora.widget.EditorTouchEventHandler = editor.touchHandler!!
2881
+ if (handler.holdHorizontalScrollBar()) {
2882
+ tmpRect.set(
2883
+ 0f,
2884
+ editor.height - editor.dpUnit * RenderingConstants.SCROLLBAR_WIDTH_DIP,
2885
+ editor.width.toFloat(),
2886
+ editor.height.toFloat()
2887
+ )
2888
+ val track = horizontalScrollbarTrackDrawable
2889
+ if (track != null) {
2890
+ track.setBounds(
2891
+ tmpRect.left.toInt(),
2892
+ tmpRect.top.toInt(),
2893
+ tmpRect.right.toInt(),
2894
+ tmpRect.bottom.toInt()
2895
+ )
2896
+ track.draw(canvas)
2897
+ } else {
2898
+ drawColor(canvas, editor.colorScheme.getColor(EditorColorScheme.SCROLL_BAR_TRACK), tmpRect)
2899
+ }
2900
+ }
2901
+ }
2902
+
2903
+ protected fun patchSnippetRegions(canvas: Canvas, textOffset: Float) {
2904
+ val controller =
2905
+ editor.snippetController!!
2906
+ if (controller.isInSnippet()) {
2907
+ val editing =
2908
+ controller.getEditingTabStop()
2909
+ if (editing != null) {
2910
+ patchTextRegionWithColor(
2911
+ canvas,
2912
+ textOffset,
2913
+ editing.startIndex,
2914
+ editing.endIndex,
2915
+ 0,
2916
+ editor.colorScheme.getColor(EditorColorScheme.SNIPPET_BACKGROUND_EDITING),
2917
+ 0
2918
+ )
2919
+ }
2920
+ for (snippetItem in controller.getEditingRelatedTabStops()) {
2921
+ patchTextRegionWithColor(
2922
+ canvas,
2923
+ textOffset,
2924
+ snippetItem.startIndex,
2925
+ snippetItem.endIndex,
2926
+ 0,
2927
+ editor.colorScheme.getColor(EditorColorScheme.SNIPPET_BACKGROUND_RELATED),
2928
+ 0
2929
+ )
2930
+ }
2931
+ for (snippetItem in controller.getInactiveTabStops()) {
2932
+ patchTextRegionWithColor(
2933
+ canvas,
2934
+ textOffset,
2935
+ snippetItem.startIndex,
2936
+ snippetItem.endIndex,
2937
+ 0,
2938
+ editor.colorScheme.getColor(EditorColorScheme.SNIPPET_BACKGROUND_INACTIVE),
2939
+ 0
2940
+ )
2941
+ }
2942
+ }
2943
+ }
2944
+
2945
+ protected fun patchHighlightedDelimiters(canvas: Canvas, textOffset: Float) {
2946
+ if (true) return
2947
+ val paired = object {
2948
+ val leftIndex = 0
2949
+ val leftLength = 0
2950
+ val rightIndex = 0
2951
+ val rightLength = 0
2952
+ }
2953
+ if (paired != null) {
2954
+ val color =
2955
+ editor.colorScheme.getColor(EditorColorScheme.HIGHLIGHTED_DELIMITERS_FOREGROUND)
2956
+ var backgroundColor =
2957
+ editor.colorScheme.getColor(EditorColorScheme.HIGHLIGHTED_DELIMITERS_BACKGROUND)
2958
+ val underlineColor =
2959
+ editor.colorScheme.getColor(EditorColorScheme.HIGHLIGHTED_DELIMITERS_UNDERLINE)
2960
+ val borderColor =
2961
+ editor.colorScheme.getColor(EditorColorScheme.HIGHLIGHTED_DELIMITERS_BORDER)
2962
+ val borderWidth =
2963
+ editor.getTextBorderWidth()
2964
+ if (isInvalidTextBounds(paired.leftIndex, paired.leftLength) || isInvalidTextBounds(
2965
+ paired.rightIndex,
2966
+ paired.rightLength
2967
+ )
2968
+ ) {
2969
+ // Index out of bounds
2970
+ return
2971
+ }
2972
+
2973
+ val continuous = paired.leftIndex + paired.leftLength == paired.rightIndex
2974
+ if (color != 0 || underlineColor != 0) {
2975
+ if (continuous) {
2976
+ patchTextRegionWithColor(
2977
+ canvas,
2978
+ textOffset,
2979
+ paired.leftIndex,
2980
+ paired.rightIndex + paired.rightLength,
2981
+ color,
2982
+ backgroundColor,
2983
+ underlineColor
2984
+ )
2985
+ } else {
2986
+ patchTextRegionWithColor(
2987
+ canvas,
2988
+ textOffset,
2989
+ paired.leftIndex,
2990
+ paired.leftIndex + paired.leftLength,
2991
+ color,
2992
+ backgroundColor,
2993
+ underlineColor
2994
+ )
2995
+ patchTextRegionWithColor(
2996
+ canvas,
2997
+ textOffset,
2998
+ paired.rightIndex,
2999
+ paired.rightIndex + paired.rightLength,
3000
+ color,
3001
+ backgroundColor,
3002
+ underlineColor
3003
+ )
3004
+ }
3005
+ backgroundColor = 0
3006
+ }
3007
+ if (backgroundColor != 0 || (borderColor != 0 && borderWidth > 0)) {
3008
+ if (continuous) {
3009
+ patchTextBackgroundRegions(
3010
+ canvas,
3011
+ textOffset,
3012
+ paired.leftIndex,
3013
+ paired.rightIndex + paired.rightLength,
3014
+ backgroundColor,
3015
+ borderWidth,
3016
+ borderColor
3017
+ )
3018
+ } else {
3019
+ patchTextBackgroundRegions(
3020
+ canvas,
3021
+ textOffset,
3022
+ paired.leftIndex,
3023
+ paired.leftIndex + paired.leftLength,
3024
+ backgroundColor,
3025
+ borderWidth,
3026
+ borderColor
3027
+ )
3028
+ patchTextBackgroundRegions(
3029
+ canvas,
3030
+ textOffset,
3031
+ paired.rightIndex,
3032
+ paired.rightIndex + paired.rightLength,
3033
+ backgroundColor,
3034
+ borderWidth,
3035
+ borderColor
3036
+ )
3037
+ }
3038
+ }
3039
+ }
3040
+ }
3041
+
3042
+ protected fun isInvalidTextBounds(index: Int, length: Int): Boolean {
3043
+ return (index < 0 || length < 0 || index + length > content!!.length)
3044
+ }
3045
+
3046
+ protected fun patchTextRegionWithColor(
3047
+ canvas: Canvas,
3048
+ textOffset: Float,
3049
+ start: Int,
3050
+ end: Int,
3051
+ color: Int,
3052
+ backgroundColor: Int,
3053
+ underlineColor: Int
3054
+ ) {
3055
+ paintGeneral.setColor(color)
3056
+ paintOther.setStrokeWidth(editor.logicalRowHeight * RenderingConstants.MATCHING_DELIMITERS_UNDERLINE_WIDTH_FACTOR)
3057
+
3058
+ val useBoldStyle =
3059
+ editor.props!!.boldMatchingDelimiters
3060
+ paintGeneral.setStyle(if (useBoldStyle) AndroidPaint.Style.FILL_AND_STROKE else AndroidPaint.Style.FILL)
3061
+ paintGeneral.setFakeBoldText(useBoldStyle)
3062
+
3063
+ patchTextRegions(
3064
+ canvas,
3065
+ textOffset,
3066
+ start,
3067
+ end,
3068
+ object : TextRow.DrawTextConsumer {
3069
+ override fun drawText(canvasLocal: Canvas?, text: CharArray?, index: Int, count: Int, contextIndex: Int, contextCount: Int, isRtl: Boolean, horizontalOffset: Float, width: Float, params: TextRowParams?, span: Span?) {
3070
+ if (span == null) {
3071
+ return
3072
+ }
3073
+ if (backgroundColor != 0) {
3074
+ tmpRect.top = getRowTopForBackground(0).toFloat()
3075
+ tmpRect.bottom = getRowBottomForBackground(0).toFloat()
3076
+ tmpRect.left = horizontalOffset
3077
+ tmpRect.right = horizontalOffset + width
3078
+ paintOther.setColor(backgroundColor)
3079
+ drawRowBackgroundRect(canvas, tmpRect, paintOther)
3080
+ }
3081
+ val style: Long = span!!.style
3082
+ if (color != 0) {
3083
+ paintGeneral.setTextSkewX(if (TextStyle.isItalics(style)) RenderingConstants.TEXT_SKEW_X else 0f)
3084
+ paintGeneral.setStrikeThruText(TextStyle.isStrikeThrough(style))
3085
+ GraphicsCompat.drawTextRun(
3086
+ canvas,
3087
+ text!!,
3088
+ index,
3089
+ count,
3090
+ contextIndex,
3091
+ contextCount,
3092
+ horizontalOffset,
3093
+ params!!.textBaseline.toFloat(),
3094
+ isRtl,
3095
+ paintGeneral
3096
+ )
3097
+ }
3098
+ if (underlineColor != 0) {
3099
+ paintOther.setColor(underlineColor)
3100
+ val bottom =
3101
+ params!!.textBottom - params.textHeight * 0.05f
3102
+ canvas.drawLine(horizontalOffset, bottom, horizontalOffset + width, bottom, paintOther)
3103
+ }
3104
+ }}, null)
3105
+ paintGeneral.setStyle(AndroidPaint.Style.FILL)
3106
+ paintGeneral.setFakeBoldText(false)
3107
+ paintGeneral.setTextSkewX(0f)
3108
+ paintGeneral.setStrikeThruText(false)
3109
+ }
3110
+
3111
+ protected fun patchTextBackgroundRegions(
3112
+ canvas: Canvas,
3113
+ textOffset: Float,
3114
+ start: Int,
3115
+ end: Int,
3116
+ backgroundColor: Int,
3117
+ borderWidth: Float,
3118
+ borderColor: Int
3119
+ ) {
3120
+ if (backgroundColor == 0 && (borderWidth <= 0 || borderColor == 0)) {
3121
+ return
3122
+ }
3123
+ patchTextRegions(
3124
+ canvas,
3125
+ textOffset,
3126
+ start,
3127
+ end,
3128
+ null,
3129
+ object : TextRow.BackgroundRegionConsumer {
3130
+ override fun handleRegion(left: Float, right: Float): Boolean {
3131
+ if (textOffset + left < 0) {
3132
+ return true
3133
+ }
3134
+ tmpRect.top = getRowTopForBackground(0).toFloat()
3135
+ tmpRect.bottom = getRowBottomForBackground(0).toFloat()
3136
+ tmpRect.left = left
3137
+ tmpRect.right = right
3138
+ if (backgroundColor != 0) {
3139
+ paintOther.setColor(backgroundColor)
3140
+ drawRowBackgroundRect(canvas, tmpRect, paintOther)
3141
+ }
3142
+ if (borderWidth > 0 && borderColor != 0) {
3143
+ paintOther.setStyle(AndroidPaint.Style.STROKE)
3144
+ paintOther.setColor(borderColor)
3145
+ paintOther.setStrokeWidth(borderWidth)
3146
+ drawRowBackgroundRect(canvas, tmpRect, paintOther)
3147
+ paintOther.setStyle(AndroidPaint.Style.FILL)
3148
+ }
3149
+ return textOffset + right > editor.width
3150
+ }
3151
+ })
3152
+ }
3153
+
3154
+
3155
+ protected fun patchTextRegions(
3156
+ canvas: Canvas, textOffset: Float, start: Int, end: Int,
3157
+ @Nullable patch: TextRow.DrawTextConsumer?,
3158
+ @Nullable bgPatch: TextRow.BackgroundRegionConsumer?
3159
+ ) {
3160
+ if (patch == null && bgPatch == null) {
3161
+ return
3162
+ }
3163
+ val firstVisRow =
3164
+ editor.firstVisibleRow
3165
+ val lastVisRow =
3166
+ editor.lastVisibleRow
3167
+
3168
+ val layout: io.github.abc15018045126.sora.widget.layout.Layout = editor.layout!!
3169
+ val startRow =
3170
+ layout.getRowIndexForPosition(start)
3171
+ val endRow =
3172
+ layout.getRowIndexForPosition(end)
3173
+ val cursor = this.cursor ?: return
3174
+ val posStart =
3175
+ cursor.getIndexer().getCharPosition(start)
3176
+ val posEnd =
3177
+ cursor.getIndexer().getCharPosition(end)
3178
+ val itr =
3179
+ layout.obtainRowIterator(startRow, preloadedLines as SparseArray<ContentLine>)
3180
+ var i: Int = startRow
3181
+ while (i <= endRow && itr.hasNext()) {
3182
+ val row = itr.next()
3183
+ if (!(firstVisRow <= i && i <= lastVisRow)) {
3184
+ i++
3185
+ continue
3186
+ }
3187
+ val startOnRow =
3188
+ (if (i == startRow) posStart.column else row.startColumn)
3189
+ val endOnRow =
3190
+ (if (i == endRow) posEnd.column else row.endColumn)
3191
+ val tr: TextRow = createTextRow(i)
3192
+ var horizontalOffset = textOffset
3193
+ if ((editor.nonPrintablePaintingFlags and io.github.abc15018045126.sora.widget.CodeEditor.Companion.FLAG_DRAW_SOFT_WRAP) != 0 && !row.isLeadingRow) {
3194
+ horizontalOffset += this.miniGraphWidth
3195
+ }
3196
+ val minHorizontalOffset: Float = max(0f, -horizontalOffset)
3197
+ val maxHorizontalOffset: Float = minHorizontalOffset + editor.width
3198
+ canvas.save()
3199
+ canvas.translate(horizontalOffset + row.renderTranslateX, (editor.getRowTop(i) - editor.offsetY).toFloat())
3200
+ if (bgPatch != null) {
3201
+ tr.iterateBackgroundRegions(startOnRow, endOnRow, false, false, bgPatch)
3202
+ }
3203
+ if (patch != null) {
3204
+ tr.iterateDrawTextRegions(
3205
+ startOnRow,
3206
+ endOnRow,
3207
+ canvas,
3208
+ minHorizontalOffset,
3209
+ maxHorizontalOffset,
3210
+ true,
3211
+ patch
3212
+ )
3213
+ }
3214
+ canvas.restore()
3215
+ i++
3216
+ }
3217
+ }
3218
+
3219
+ protected fun drawSelectionOnAnimation(canvas: Canvas) {
3220
+ if (!editor.isEditable) {
3221
+ return
3222
+ }
3223
+ tmpRect.bottom = editor.cursorAnimator.animatedY() - editor.offsetY
3224
+ tmpRect.top =
3225
+ tmpRect.bottom - (if (editor.props!!.textBackgroundWrapTextOnly) editor.logicalRowHeight else editor.logicalRowHeight)
3226
+ val centerX: Float = editor.cursorAnimator.animatedX() - editor.offsetX
3227
+ tmpRect.left = centerX - editor.insertSelectionWidth / 2
3228
+ tmpRect.right = centerX + editor.insertSelectionWidth / 2
3229
+ drawColor(canvas, editor.colorScheme.getColor(EditorColorScheme.SELECTION_INSERT), tmpRect)
3230
+ val bidiAttrs = getBidiIndicatorAttrs(cursor!!.leftLine, cursor!!.leftColumn)
3231
+ if (IntPair.getFirst(bidiAttrs) == 1) {
3232
+ drawBidiSelectionIndicator(
3233
+ canvas,
3234
+ centerX,
3235
+ tmpRect.top,
3236
+ tmpRect.height(),
3237
+ IntPair.getSecond(bidiAttrs) == 1
3238
+ )
3239
+ }
3240
+ val handler: io.github.abc15018045126.sora.widget.EditorTouchEventHandler = editor.touchHandler!!
3241
+ if (handler.shouldDrawInsertHandle() && !editor.isInMouseMode) {
3242
+ editor.handleStyle!!.draw(
3243
+ canvas,
3244
+ SelectionHandleStyle.HANDLE_TYPE_INSERT,
3245
+ centerX,
3246
+ tmpRect.bottom,
3247
+ editor.logicalRowHeight,
3248
+ editor.colorScheme.getColor(EditorColorScheme.SELECTION_HANDLE),
3249
+ editor.handleDescInsert!!
3250
+ )
3251
+ }
3252
+ }
3253
+
3254
+ /**
3255
+ * Draw horizontal scroll bar
3256
+ *
3257
+ * @param canvas Canvas to draw
3258
+ */
3259
+ protected fun drawScrollBarHorizontal(canvas: Canvas?) {
3260
+ val page: Int = editor.width
3261
+ val all: Float = editor.scrollMaxX.toFloat()
3262
+ var length: Float = page / (all + editor.width) * editor.width
3263
+ val minLength: Float = RenderingConstants.SCROLLBAR_WIDTH_DIP * editor.dpUnit
3264
+ if (length <= minLength) length = minLength
3265
+ val leftX: Float = editor.offsetX / all * (editor.width - length)
3266
+ tmpRect.top = editor.height - editor.dpUnit * RenderingConstants.SCROLLBAR_WIDTH_DIP
3267
+ tmpRect.bottom = editor.height.toFloat()
3268
+ tmpRect.right = (leftX + length).toFloat()
3269
+ tmpRect.left = leftX
3270
+ horizontalScrollBarRect.set(tmpRect)
3271
+ val thumb = horizontalScrollbarThumbDrawable
3272
+ val handler: io.github.abc15018045126.sora.widget.EditorTouchEventHandler = editor.touchHandler!!
3273
+ if (thumb != null && canvas != null) {
3274
+ thumb.setState(
3275
+ if (handler
3276
+ .holdHorizontalScrollBar()
3277
+ ) PRESSED_DRAWABLE_STATE else DEFAULT_DRAWABLE_STATE
3278
+ )
3279
+ thumb.setBounds(
3280
+ tmpRect.left.toInt(),
3281
+ tmpRect.top.toInt(),
3282
+ tmpRect.right.toInt(),
3283
+ tmpRect.bottom.toInt()
3284
+ )
3285
+ thumb.draw(canvas)
3286
+ } else if (canvas != null) {
3287
+ drawColor(
3288
+ canvas,
3289
+ editor.colorScheme.getColor(
3290
+ if (handler
3291
+ .holdHorizontalScrollBar()
3292
+ ) EditorColorScheme.SCROLL_BAR_THUMB_PRESSED else EditorColorScheme.SCROLL_BAR_THUMB
3293
+ ),
3294
+ tmpRect
3295
+ )
3296
+ }
3297
+ }
3298
+
3299
+ // BEGIN Measure-------------------------------------
3300
+ /**
3301
+ * Build measure cache for the given lines, if the timestamp indicates that it is outdated.
3302
+ */
3303
+ @JvmOverloads
3304
+ fun buildMeasureCacheForLines(
3305
+ startLine: Int,
3306
+ endLine: Int,
3307
+ timestamp: Long = this.timestamp,
3308
+ useCachedContent: Boolean = false
3309
+ ) {
3310
+ var startLine = startLine
3311
+ val text: Content = content!!
3312
+ val context =
3313
+ editor.renderContext!!
3314
+ while (startLine <= endLine && startLine < text.lineCount) {
3315
+ val line: ContentLine = if (useCachedContent) getLine(startLine) else getLineDirect(startLine)
3316
+ val cache =
3317
+ editor.renderContext!!.cache.getOrCreateMeasureCache(startLine)
3318
+ if (cache.updateTimestamp < timestamp) {
3319
+ var forced = false
3320
+ val w = cache.widths
3321
+ if (w == null || w.size < line.length) {
3322
+ cache.widths = TextAdvancesCache(max(line.length + 8, 90))
3323
+ forced = true
3324
+ }
3325
+ val spans =
3326
+ editor.getSpansForLine(startLine)
3327
+ val hash =
3328
+ Objects.hash(
3329
+ spans?.filterNotNull(),
3330
+ line.length,
3331
+ editor.tabWidth,
3332
+ paintGeneral.getFlags(),
3333
+ paintGeneral.getTextSize(),
3334
+ paintGeneral.getTextScaleX(),
3335
+ paintGeneral.letterSpacing,
3336
+ paintGeneral.fontFeatureSettings,
3337
+ paintGeneral.typeface?.hashCode() ?: 0
3338
+ )
3339
+ if (context.cache.getStyleHash(startLine) != hash || forced) {
3340
+ context.cache.setStyleHash(startLine, hash)
3341
+ // Build cache here
3342
+ val layout: io.github.abc15018045126.sora.widget.layout.Layout = editor.layout!!
3343
+ val beginRowIndex =
3344
+ layout.getRowIndexForPosition(text.getCharIndex(startLine, 0))
3345
+ val itr =
3346
+ layout.obtainRowIterator(beginRowIndex)
3347
+ val tr: TextRow = TextRow()
3348
+ val lineText =
3349
+ text.getLine(startLine)
3350
+ val directions =
3351
+ text.getLineDirections(startLine)
3352
+ val requiredSize: Int = lineText.length + 10
3353
+ var widths =
3354
+ cache.widths
3355
+ if (widths == null || widths.size < requiredSize) {
3356
+ widths = TextAdvancesCache(requiredSize)
3357
+ cache.widths = widths
3358
+ }
3359
+ while (itr.hasNext()) {
3360
+ val row =
3361
+ itr.next()
3362
+ if (row.lineIndex != startLine) {
3363
+ break
3364
+ }
3365
+ tr.set(
3366
+ lineText,
3367
+ row.startColumn,
3368
+ row.endColumn,
3369
+ spans?.filterNotNull(),
3370
+ row.inlayHints,
3371
+ directions,
3372
+ paintGeneral,
3373
+ null,
3374
+ createTextRowParams()!!
3375
+ )
3376
+ tr.buildMeasureCacheStep(widths)
3377
+ }
3378
+ tr.setRange(0, lineText.length)
3379
+ tr.buildMeasureCacheTailor(widths)
3380
+ cache.updateTimestamp = timestamp
3381
+ }
3382
+ }
3383
+ startLine++
3384
+ }
3385
+ }
3386
+
3387
+ internal fun getRowWidth(row: Int): Float {
3388
+ return createTextRow(row).computeRowWidth()
3389
+ }
3390
+
3391
+
3392
+ // END Measure---------------------------------------
3393
+ protected inner class DrawCursorTask(
3394
+ protected var x: Float,
3395
+ protected var y: Float,
3396
+ protected var handleType: Int,
3397
+ descriptor: SelectionHandleStyle.HandleDescriptor?
3398
+ ) {
3399
+ protected var descriptor: SelectionHandleStyle.HandleDescriptor?
3400
+ var isBidiIndicatorRequired: Boolean = false
3401
+ var isRightToLeft: Boolean = false
3402
+
3403
+
3404
+ init {
3405
+ this.descriptor = descriptor
3406
+ }
3407
+
3408
+ private val actualHandleType: Int
3409
+ get() {
3410
+ if (isRightToLeft && handleType == SelectionHandleStyle.HANDLE_TYPE_LEFT) {
3411
+ return SelectionHandleStyle.HANDLE_TYPE_RIGHT
3412
+ }
3413
+ if (isRightToLeft && handleType == SelectionHandleStyle.HANDLE_TYPE_RIGHT) {
3414
+ return SelectionHandleStyle.HANDLE_TYPE_LEFT
3415
+ }
3416
+ return handleType
3417
+ }
3418
+
3419
+ private fun drawSelForLeftRight(): Boolean {
3420
+ return ((handleType == SelectionHandleStyle.HANDLE_TYPE_LEFT || handleType == SelectionHandleStyle.HANDLE_TYPE_RIGHT)
3421
+ && editor.props!!.showSelectionWhenSelected && !editor.isInMouseMode)
3422
+ }
3423
+
3424
+ private fun drawSelForInsert(): Boolean {
3425
+ val handler: io.github.abc15018045126.sora.widget.EditorTouchEventHandler = editor.touchHandler!!
3426
+ return (!(handleType == SelectionHandleStyle.HANDLE_TYPE_LEFT || handleType == SelectionHandleStyle.HANDLE_TYPE_RIGHT)
3427
+ && (editor.cursorBlink!!.visibility || handler
3428
+ .holdInsertHandle() || editor.isInLongSelect))
3429
+
3430
+ }
3431
+
3432
+ private val isSelForLongSelect: Boolean
3433
+ get() = editor.isInLongSelect && !(handleType == SelectionHandleStyle.HANDLE_TYPE_LEFT
3434
+ || handleType == SelectionHandleStyle.HANDLE_TYPE_RIGHT)
3435
+
3436
+
3437
+ internal fun execute(canvas: Canvas) {
3438
+ // Hide cursors (API level 31)
3439
+ if (handleType != SelectionHandleStyle.HANDLE_TYPE_UNDEFINED) {
3440
+ if (editor.inputConnection!!.imeConsumingInput || !editor.isFocused()) {
3441
+ return
3442
+ }
3443
+ }
3444
+ if (handleType == SelectionHandleStyle.HANDLE_TYPE_INSERT && !editor.isEditable) {
3445
+
3446
+ return
3447
+ }
3448
+ val descriptor: SelectionHandleStyle.HandleDescriptor =
3449
+ this.descriptor ?: TMP_DESC
3450
+ // Follow the thumb or stick to text row
3451
+ if (!descriptor.position.isEmpty()) {
3452
+ if (!editor.isStickyTextSelection) {
3453
+ val handler: io.github.abc15018045126.sora.widget.EditorTouchEventHandler = editor.touchHandler!!
3454
+ if (handler
3455
+ .getTouchedHandleType() === this.actualHandleType && handleType != SelectionHandleStyle.HANDLE_TYPE_UNDEFINED && handler
3456
+ .isHandleMoving()
3457
+ ) {
3458
+ x =
3459
+ handler.motionX + (if (descriptor.alignment != SelectionHandleStyle.ALIGN_CENTER) descriptor.position.width().toFloat() else 0f) * (if (descriptor.alignment == SelectionHandleStyle.ALIGN_LEFT) 1 else -1)
3460
+ y = handler.motionY - descriptor.position.height().toFloat() * 2 / 3f
3461
+ }
3462
+ }
3463
+
3464
+ }
3465
+
3466
+ if (drawSelForLeftRight() || drawSelForInsert() || handleType == SelectionHandleStyle.HANDLE_TYPE_UNDEFINED) {
3467
+ val startY: Float =
3468
+ y - (if (editor.props!!.textBackgroundWrapTextOnly) editor.logicalRowHeight else editor.logicalRowHeight)
3469
+ val stopY = y
3470
+ paintGeneral.setColor(editor.colorScheme.getColor(EditorColorScheme.SELECTION_INSERT))
3471
+ paintGeneral.setStrokeWidth(editor.insertSelectionWidth)
3472
+
3473
+ paintGeneral.setStyle(android.graphics.Paint.Style.STROKE)
3474
+ if (this.isSelForLongSelect) {
3475
+ paintGeneral.setPathEffect(
3476
+ DashPathEffect(
3477
+ floatArrayOf(
3478
+ (stopY - startY) / 8f,
3479
+ (stopY - startY) / 8f
3480
+ ), (stopY - startY) / 16f
3481
+ )
3482
+ )
3483
+ paintGeneral.setStrokeWidth(editor.insertSelectionWidth.toFloat() * 1.5f)
3484
+
3485
+ }
3486
+ canvas.drawLine(x, startY, x, stopY, paintGeneral)
3487
+ paintGeneral.setStyle(android.graphics.Paint.Style.FILL)
3488
+ paintGeneral.setPathEffect(null)
3489
+ if (drawSelForInsert() && isBidiIndicatorRequired) {
3490
+ // Draw a flag for LTR/RTL mixed row
3491
+ val height = (stopY - startY)
3492
+ drawBidiSelectionIndicator(canvas, x, startY, height, isRightToLeft)
3493
+ }
3494
+ }
3495
+ var handleType = this.handleType
3496
+ // Hide insert handle conditionally
3497
+ val handler: io.github.abc15018045126.sora.widget.EditorTouchEventHandler = editor.touchHandler!!
3498
+ if (handleType == SelectionHandleStyle.HANDLE_TYPE_INSERT && (editor.isInLongSelect || !handler
3499
+ .shouldDrawInsertHandle())
3500
+
3501
+ ) {
3502
+ handleType = SelectionHandleStyle.HANDLE_TYPE_UNDEFINED
3503
+ }
3504
+ if (handleType != SelectionHandleStyle.HANDLE_TYPE_UNDEFINED && !editor.isInMouseMode /* hide if mouse inside */) {
3505
+ editor.handleStyle!!.draw(
3506
+ canvas,
3507
+ handleType,
3508
+ x,
3509
+ y,
3510
+ editor.logicalRowHeight,
3511
+ editor.colorScheme.getColor(EditorColorScheme.SELECTION_HANDLE),
3512
+ descriptor
3513
+ )
3514
+ if (descriptor === TMP_DESC) {
3515
+ descriptor.setEmpty()
3516
+ }
3517
+ } else {
3518
+ descriptor.setEmpty()
3519
+ }
3520
+ }
3521
+
3522
+
3523
+ }
3524
+
3525
+ companion object {
3526
+ internal val TMP_DESC: SelectionHandleStyle.HandleDescriptor = SelectionHandleStyle.HandleDescriptor()
3527
+ private val PRESSED_DRAWABLE_STATE = intArrayOf(android.R.attr.state_pressed, android.R.attr.state_enabled)
3528
+ private val DEFAULT_DRAWABLE_STATE = intArrayOf(android.R.attr.state_enabled)
3529
+
3530
+ internal const val LOG_TAG = "EditorRenderer"
3531
+ private val sDiagnosticsColorMapping = intArrayOf(
3532
+ 0,
3533
+ EditorColorScheme.PROBLEM_TYPO,
3534
+ EditorColorScheme.PROBLEM_WARNING,
3535
+ EditorColorScheme.PROBLEM_ERROR
3536
+ )
3537
+ const val CURSOR_LINE_BG_OVERLAP_CURSOR = 0
3538
+ const val CURSOR_LINE_BG_OVERLAP_MIXED = 1
3539
+ const val CURSOR_LINE_BG_OVERLAP_CUSTOM = 2
3540
+ }
3541
+ }
3542
+