Skip to content

Pure Codename One rich text and code editors (remove BrowserComponent)#5378

Merged
shai-almog merged 20 commits into
masterfrom
pure-cn1-editors
Jul 15, 2026
Merged

Pure Codename One rich text and code editors (remove BrowserComponent)#5378
shai-almog merged 20 commits into
masterfrom
pure-cn1-editors

Conversation

@shai-almog

Copy link
Copy Markdown
Collaborator

Summary

Replaces the BrowserComponent-backed RichTextArea (WYSIWYG) and CodeEditor with a 100% pure Codename One text engine (com.codename1.ui.editor) that renders the document itself with Graphics/Font and binds directly to the platform text input source (soft keyboard, hardware/Bluetooth keyboard, IME). The public API of both components is preserved, so this is a drop-in replacement.

What's included

  • Low-level text input source API (TextInputClient/TextInputState/TextInputConfig + an impl SPI on CodenameOneImplementation), bound per port:
    • Android: a custom InputConnection (CN1TextInputConnection) on the surface views (no shadow EditText).
    • iOS: a first-responder UITextInput view (CN1TextInputView) - soft + hardware/Bluetooth keyboard + IME.
    • JavaSE: InputMethodListener + key listeners.
  • Editor engine: single-buffer document model, incremental stateful syntax tokenizer, coalescing undo, styled rich runs + inline images, HTML import/export, code completion popup and diagnostics squiggles.
  • Bidirectional (RTL) text: a compact Unicode Bidi Algorithm core (BidiUtil) wired into caret geometry, hit-testing, selection and rendering for the base, code and rich views (mixed LTR/RTL, numbers-in-RTL, etc.).
  • IME / CJK marked-text composition with an inline composing underline.
  • Native-feel touch selection: cross-platform CN1-drawn selection handles + a magnifier loupe + a Copy/Cut/Paste/Select All toolbar, plus the native iOS system magnifier / handles / edit menu via UITextInteraction (verified on device).
  • Removes the HTML/BrowserComponent backend: deletes CodeEditorHtml and the createEditorHtml() paths, and the now-dead CodeEditor -> CodeMirror bundling in the Maven plugin IPhoneBuilder/AndroidGradleBuilder and GLViewController.h. Backend-switch methods (setDefaultBackend, getInternalBrowser, CodeEditor.setEngineURL, ...) are kept as deprecated no-ops for source compatibility.

Testing

  • 66 new core unit tests (com.codename1.ui.editor.*): bidi algorithm + geometry integration, document model, CJK composing, pure-backend selection/round-trip.
  • Full core-unittests suite green: 3867 tests, 0 failures.
  • iOS native selection (magnifier + handles + edit menu) verified on the iPhone 16 simulator.
  • New PureEditorScreenshotTest (RTL-in-code + mixed rich text) added to the hellocodenameone suite; its PureEditors golden adopts from the first CI run.

Notes

  • The dead CodeMirror bundling in the separate BuildDaemon repo is removed in a companion PR (codenameone/BuildDaemon drop-codemirror-editor).
  • While the editor is focused on iOS the native text interaction owns drags (no drag-to-scroll inside the editor; caret nav and form scroll still work) - a deliberate tradeoff for the native selection UI.

Co-Authored-By: Claude Opus 4.8 (1M context) noreply@anthropic.com

🤖 Generated with Claude Code

Replace the BrowserComponent-backed RichTextArea and CodeEditor with a 100%
pure Codename One text engine (com.codename1.ui.editor) that renders the
document itself with Graphics/Font and binds to the platform text input source.

- New low-level text input source API (TextInputClient/State/Config + impl SPI)
  bound per port: Android custom InputConnection, iOS UITextInput first
  responder, JavaSE InputMethod/key listeners.
- Editor engine: document model, incremental stateful tokenizer, undo, styled
  rich runs, HTML import/export, code completion popup and diagnostics squiggles.
- Bidirectional (RTL) text via a Unicode Bidi Algorithm core (BidiUtil) wired
  into caret/selection/hit-test/render for the base, code and rich views.
- IME / CJK marked-text composition with an inline underline.
- Native-feel touch selection: cross-platform CN1-drawn handles + magnifier
  loupe + Copy/Cut/Paste/Select All, plus the native iOS system magnifier /
  handles / edit menu via UITextInteraction.
- Remove the HTML/BrowserComponent backend (CodeEditorHtml, createEditorHtml)
  and the dead CodeEditor CodeMirror bundling in the Maven plugin builders and
  GLViewController.h. Public API preserved (drop-in); backend-switch methods
  kept as deprecated no-ops.
- Tests: 66 core unit tests (bidi, document, composing, geometry, backend) plus
  a hellocodenameone screenshot test. Full core-unittests suite green (3867).
- Developer guide updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@shai-almog

shai-almog commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 12 screenshots: 12 matched.
✅ JavaSE simulator integration screenshots matched stored baselines.

@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Developer Guide build artifacts are available for download from this workflow run:

Developer Guide quality checks:

  • AsciiDoc linter: No issues found (report)
  • Vale: No alerts found (report)
  • Paragraph capitalization: No paragraph capitalization issues (report)
  • LanguageTool: No grammar matches (report)
  • Image references: No unused images detected (report)

@shai-almog

shai-almog commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 146 screenshots: 146 matched.

Native Android coverage

  • 📊 Line coverage: 11.17% (11689/104630 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 9.95% (57618/579222), branch 5.09% (2695/52978), complexity 4.85% (2696/55546), method 7.30% (2088/28584), class 11.42% (464/4064)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)

✅ Native Android screenshot tests passed.

Native Android coverage

  • 📊 Line coverage: 11.17% (11689/104630 lines covered) [HTML preview] (artifact android-coverage-report, jacocoAndroidReport/html/index.html)
    • Other counters: instruction 9.95% (57618/579222), branch 5.09% (2695/52978), complexity 4.85% (2696/55546), method 7.30% (2088/28584), class 11.42% (464/4064)
    • Lowest covered classes
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysKt – 0.00% (0/6327 lines covered)
      • kotlin.collections.unsigned.kotlin.collections.unsigned.UArraysKt___UArraysKt – 0.00% (0/2384 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.ClassReader – 0.00% (0/1519 lines covered)
      • kotlin.collections.kotlin.collections.CollectionsKt___CollectionsKt – 0.00% (0/1148 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.MethodWriter – 0.00% (0/923 lines covered)
      • kotlin.sequences.kotlin.sequences.SequencesKt___SequencesKt – 0.00% (0/730 lines covered)
      • com.google.common.cache.com.google.common.cache.LocalCache$Segment – 0.00% (0/726 lines covered)
      • kotlin.text.kotlin.text.StringsKt___StringsKt – 0.00% (0/623 lines covered)
      • org.jacoco.agent.rt.internal_b6258fc.asm.org.jacoco.agent.rt.internal_b6258fc.asm.Frame – 0.00% (0/564 lines covered)
      • kotlin.collections.kotlin.collections.ArraysKt___ArraysJvmKt – 0.00% (0/495 lines covered)

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend scalar fallback (no native SIMD)
SIMD int-add (64K x300) java 154ms / native 134ms = 1.1x speedup
SIMD float-mul (64K x300) java 148ms / native 115ms = 1.2x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 372.000 ms
Base64 CN1 decode 226.000 ms
Base64 native encode 942.000 ms
Base64 encode ratio (CN1/native) 0.395x (60.5% faster)
Base64 native decode 1641.000 ms
Base64 decode ratio (CN1/native) 0.138x (86.2% faster)
Image encode benchmark status skipped (SIMD unsupported)

@github-actions

Copy link
Copy Markdown
Contributor

Cloudflare Preview

@shai-almog

shai-almog commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 142 screenshots: 142 matched.
Native Windows port, REAL shipping pipeline: the hellocodenameone screenshot suite rendered by a binary CROSS-COMPILED on Linux (clang-cl + xwin, WebView2 linked) and RUN on a Windows x64 runner. Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 75ms / native 7ms = 10.7x speedup
SIMD float-mul (64K x300) java 70ms / native 5ms = 14.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 199.000 ms
Base64 CN1 decode 133.000 ms
Base64 SIMD encode 111.000 ms
Base64 encode ratio (SIMD/CN1) 0.558x (44.2% faster)
Base64 SIMD decode 95.000 ms
Base64 decode ratio (SIMD/CN1) 0.714x (28.6% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 33.000 ms
Image createMask (SIMD on) 32.000 ms
Image createMask ratio (SIMD on/off) 0.970x (3.0% faster)
Image applyMask (SIMD off) 80.000 ms
Image applyMask (SIMD on) 77.000 ms
Image applyMask ratio (SIMD on/off) 0.963x (3.7% faster)
Image modifyAlpha (SIMD off) 74.000 ms
Image modifyAlpha (SIMD on) 71.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.959x (4.1% faster)
Image modifyAlpha removeColor (SIMD off) 81.000 ms
Image modifyAlpha removeColor (SIMD on) 79.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.975x (2.5% faster)

@shai-almog

shai-almog commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 169 screenshots: 169 matched.
✅ JavaScript-port screenshot tests passed.

@shai-almog

shai-almog commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 143 screenshots: 143 matched.
Native Linux port (x64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub x64 runner. Baseline: scripts/linux/screenshots.

@shai-almog

shai-almog commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 143 screenshots: 143 matched.
Native Linux port (arm64), GTK3/Cairo/Pango, ParparVM bytecode-to-C (no JVM): the hellocodenameone screenshot suite rendered by a native ELF built + run on the GitHub arm64 runner. Baseline: scripts/linux/screenshots-arm.

@shai-almog

shai-almog commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 144 screenshots: 144 matched.
✅ Native Mac screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 300 seconds

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 59ms / native 3ms = 19.6x speedup
SIMD float-mul (64K x300) java 60ms / native 2ms = 30.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 243.000 ms
Base64 CN1 decode 207.000 ms
Base64 native encode 1051.000 ms
Base64 encode ratio (CN1/native) 0.231x (76.9% faster)
Base64 native decode 698.000 ms
Base64 decode ratio (CN1/native) 0.297x (70.3% faster)
Base64 SIMD encode 101.000 ms
Base64 encode ratio (SIMD/CN1) 0.416x (58.4% faster)
Base64 SIMD decode 113.000 ms
Base64 decode ratio (SIMD/CN1) 0.546x (45.4% faster)
Base64 encode ratio (SIMD/native) 0.096x (90.4% faster)
Base64 decode ratio (SIMD/native) 0.162x (83.8% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 15.000 ms
Image createMask (SIMD on) 6.000 ms
Image createMask ratio (SIMD on/off) 0.400x (60.0% faster)
Image applyMask (SIMD off) 120.000 ms
Image applyMask (SIMD on) 69.000 ms
Image applyMask ratio (SIMD on/off) 0.575x (42.5% faster)
Image modifyAlpha (SIMD off) 67.000 ms
Image modifyAlpha (SIMD on) 112.000 ms
Image modifyAlpha ratio (SIMD on/off) 1.672x (67.2% slower)
Image modifyAlpha removeColor (SIMD off) 131.000 ms
Image modifyAlpha removeColor (SIMD on) 82.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.626x (37.4% faster)

@shai-almog

shai-almog commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 217 screenshots: 217 matched.
✅ Native Apple Watch (watchOS, Core Graphics) screenshot tests passed.

@shai-almog

shai-almog commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 139 screenshots: 139 matched.
✅ Native iOS screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 299 seconds

Build and Run Timing

Metric Duration
Simulator Boot 64000 ms
Simulator Boot (Run) 1000 ms
App Install 11000 ms
App Launch 1000 ms
Test Execution 466000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 58ms / native 3ms = 19.3x speedup
SIMD float-mul (64K x300) java 54ms / native 3ms = 18.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 1084.000 ms
Base64 CN1 decode 154.000 ms
Base64 native encode 3080.000 ms
Base64 encode ratio (CN1/native) 0.352x (64.8% faster)
Base64 native decode 1247.000 ms
Base64 decode ratio (CN1/native) 0.123x (87.7% faster)
Base64 SIMD encode 52.000 ms
Base64 encode ratio (SIMD/CN1) 0.048x (95.2% faster)
Base64 SIMD decode 80.000 ms
Base64 decode ratio (SIMD/CN1) 0.519x (48.1% faster)
Base64 encode ratio (SIMD/native) 0.017x (98.3% faster)
Base64 decode ratio (SIMD/native) 0.064x (93.6% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 22.000 ms
Image createMask (SIMD on) 2.000 ms
Image createMask ratio (SIMD on/off) 0.091x (90.9% faster)
Image applyMask (SIMD off) 68.000 ms
Image applyMask (SIMD on) 203.000 ms
Image applyMask ratio (SIMD on/off) 2.985x (198.5% slower)
Image modifyAlpha (SIMD off) 154.000 ms
Image modifyAlpha (SIMD on) 130.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.844x (15.6% faster)
Image modifyAlpha removeColor (SIMD off) 167.000 ms
Image modifyAlpha removeColor (SIMD on) 47.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.281x (71.9% faster)

@shai-almog

shai-almog commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 140 screenshots: 140 matched.
✅ Native Apple TV (tvOS, Metal) screenshot tests passed.

@shai-almog

shai-almog commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 145 screenshots: 145 matched.
✅ Native iOS Metal screenshot tests passed.

Benchmark Results

  • VM Translation Time: 0 seconds
  • Compilation Time: 483 seconds

Build and Run Timing

Metric Duration
Simulator Boot 77000 ms
Simulator Boot (Run) 2000 ms
App Install 20000 ms
App Launch 7000 ms
Test Execution 507000 ms

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 149ms / native 4ms = 37.2x speedup
SIMD float-mul (64K x300) java 177ms / native 5ms = 35.4x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path active (NEON-accelerated)
Base64 CN1 encode 734.000 ms
Base64 CN1 decode 487.000 ms
Base64 native encode 931.000 ms
Base64 encode ratio (CN1/native) 0.788x (21.2% faster)
Base64 native decode 529.000 ms
Base64 decode ratio (CN1/native) 0.921x (7.9% faster)
Base64 SIMD encode 83.000 ms
Base64 encode ratio (SIMD/CN1) 0.113x (88.7% faster)
Base64 SIMD decode 93.000 ms
Base64 decode ratio (SIMD/CN1) 0.191x (80.9% faster)
Base64 encode ratio (SIMD/native) 0.089x (91.1% faster)
Base64 decode ratio (SIMD/native) 0.176x (82.4% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 38.000 ms
Image createMask (SIMD on) 7.000 ms
Image createMask ratio (SIMD on/off) 0.184x (81.6% faster)
Image applyMask (SIMD off) 279.000 ms
Image applyMask (SIMD on) 90.000 ms
Image applyMask ratio (SIMD on/off) 0.323x (67.7% faster)
Image modifyAlpha (SIMD off) 143.000 ms
Image modifyAlpha (SIMD on) 68.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.476x (52.4% faster)
Image modifyAlpha removeColor (SIMD off) 386.000 ms
Image modifyAlpha removeColor (SIMD on) 248.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.642x (35.8% faster)

shai-almog and others added 5 commits July 14, 2026 08:54
The core-unittests SpotBugs check (threshold Low, fail on any) flagged the new
editor code. Fix the real findings and suppress a style-only one:

- BidiUtil: use a bitwise odd-check (IM_BAD_CHECK_FOR_ODD) and drop the
  unreachable 0x00A0 branch in typeOf (UC_USELESS_CONDITION).
- RichPureEditor.loadImage: avoid String.getBytes() default encoding
  (DM_DEFAULT_ENCODING) by converting the ASCII base64 payload directly, and
  use >= 0 for the indexOf checks (RV_CHECK_FOR_POSITIVE_INDEXOF).
- RichView.setList: remove a dead local store (DLS_DEAD_LOCAL_STORE).
- spotbugs-exclude: suppress SIC_INNER_SHOULD_BE_STATIC_ANON for the editor
  package (its StyleTransform/StylePredicate/BlockOp anonymous impls capture
  only locals; the refactor is noise).

Also add EditorLayoutTest verifying RichTextArea/CodeEditor lay out below the
form Toolbar.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
HtmlImporter only handled amp/lt/gt/quot/apos/nbsp and numeric entities, so
common named entities such as &mdash; rendered as literal text. Add the common
typography and symbol entities (mdash, ndash, hellip, curly quotes, copy, reg,
trade, times, euro, pound, ...). Covered by HtmlImporterTest.

Also add getVerticalScroll() plus EditorFirstLineTest, which confirms the editor
shows line 0 at the top after loading content (scroll stays 0), complementing
EditorLayoutTest (editors sit below the form Toolbar).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
setText() reset scrollY to 0 and then called scrollCaretVisible(). When the
backend flushes the queued setText before the component is laid out (getHeight()
is still 0), contentHeight() is negative once padding is subtracted, so the
"caret below the viewport" branch fired even for the caret on line 0 and pushed
scrollY to roughly one line. The first content line then scrolled under the
form title bar on device and in the simulator (headless tests missed it because
they set the text after layout).

Guard scrollCaretVisible() against an unlaid-out viewport (contentHeight <= 0)
and add a laidOut() override that re-clamps scrollY and applies any deferred
scroll-to-caret once the real bounds are known. Add a regression test that sets
the text before the first layout, reproducing the device ordering.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The pure editor code tripped several CI gates that only run in the full PR
workflow (not the SpotBugs-only local check):

- PMD forbidden-rules gate (generate-quality-report.py): resolved 62 findings
  in the new editor sources - add @OverRide where methods override/implement,
  convert indexed loops to foreach, split multi-declarations, drop unnecessary
  fully-qualified names / imports / constructor, make BidiUtil final, remove
  unused measureLine params, and restructure a break-as-last-in-loop into a
  helper. Genuine identity comparisons (cached fonts, the ThemePalette
  singleton) and owned StringBuilder buffers (document buffer, HTML importer)
  are marked // NOPMD with a reason since changing them would be incorrect.
- JavaDoc package-info gate: add package-info.java for com.codename1.ui.editor.
- Developer guide quality gate: fix the Vale findings in the RichTextArea /
  CodeEditor sections (contraction, cliche, adverb) and disable the
  LanguageTool UPPERCASE_SENTENCE_START rule, which false-positives on
  deliberately lowercase asciidoc ordered-list continuation items (matching
  the existing ENGLISH_WORD_REPEAT_BEGINNING_RULE exception).

No behavior change. Verified: core-unittests verify (3876 tests pass, SpotBugs
0 bugs, PMD gate clean), Vale 0/0/0 on the edited guide, package-info check
passes.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The RichTextArea and CodeEditor screenshot tests pre-date this PR and their
goldens were captured against the old BrowserComponent editor; the new
PureEditors test had none. Re-capture all three from the CI run of the fixed
commit (first line no longer clipped, HTML entities and RTL/bidi rendering
correctly) across every capturing platform (android, javascript, windows,
mac-native, linux x64/arm, iOS gl/metal/tv/watch). Refresh the tolerance
comments to describe the pure text render instead of the removed web widget.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

✅ Continuous Quality Report

Test & Coverage

Static Analysis

  • SpotBugs [Report archive]
    • ByteCodeTranslator: 0 findings (no issues)
    • android: 0 findings (no issues)
    • codenameone-maven-plugin: 0 findings (no issues)
    • core-unittests: 0 findings (no issues)
    • ios: 0 findings (no issues)
  • PMD: 0 findings (no issues) [Report archive]
  • Checkstyle: 0 findings (no issues) [Report archive]

Generated automatically by the PR CI workflow.

shai-almog and others added 9 commits July 14, 2026 17:46
PureEditorScreenshotTest was registered before the graphics screenshot tests.
Creating a pure editor warms Android's native-font path, so the default-font
text drawn by graphics-draw-string, graphics-draw-string-decorated and
graphics-inscribed-triangle-grid rendered differently than their goldens (which
were captured with the editor tests running after the graphics suite, like
RichTextArea/CodeEditor already do). Android-only, deterministic since the first
branch commit; other platforms were unaffected.

Move the test into the editor-screenshot cluster so every editor test runs after
the graphics tests, restoring the cold-font ordering the graphics goldens
capture. No production code change.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

✅ ByteCodeTranslator Quality Report

Test & Coverage

  • Tests: 395 total, 0 failed, 14 skipped

Benchmark Results

  • Execution Time: 17972 ms

  • Hotspots (Top 20 sampled methods):

    • 20.96% java.util.ArrayList.indexOf (341 samples)
    • 9.71% com.codename1.tools.translator.BytecodeMethod.addToConstantPool (158 samples)
    • 3.20% java.lang.StringBuilder.append (52 samples)
    • 2.58% org.objectweb.asm.tree.analysis.Analyzer.findSubroutine (42 samples)
    • 2.40% com.codename1.tools.translator.BytecodeMethod.optimize (39 samples)
    • 2.40% com.codename1.tools.translator.Parser.generateClassAndMethodIndexHeader (39 samples)
    • 2.27% com.codename1.tools.translator.Parser.cn1EnsureSubclassIndex (37 samples)
    • 2.27% com.codename1.tools.translator.ByteCodeClass.hasDeclaredMethod (37 samples)
    • 2.03% java.lang.System.identityHashCode (33 samples)
    • 1.91% org.objectweb.asm.tree.analysis.Analyzer.analyze (31 samples)
    • 1.84% com.codename1.tools.translator.bytecodes.Invoke.resolveDirectTarget (30 samples)
    • 1.78% java.util.IdentityHashMap$KeySet.toArray (29 samples)
    • 1.78% java.util.HashMap.hash (29 samples)
    • 1.60% com.codename1.tools.translator.ByteCodeClass.findDeclaredMethod (26 samples)
    • 1.35% com.codename1.tools.translator.Parser.addToConstantPool (22 samples)
    • 1.17% com.codename1.tools.translator.BytecodeMethod.appendCMethodPrefix (19 samples)
    • 1.04% java.lang.String.equals (17 samples)
    • 1.04% com.codename1.tools.translator.bytecodes.Invoke.findMethodUp (17 samples)
    • 1.04% java.lang.StringCoding.encode (17 samples)
    • 0.80% com.codename1.tools.translator.Parser.classIndex (13 samples)
  • ⚠️ Coverage report not generated.

Static Analysis

  • ✅ SpotBugs: no findings (report was not generated by the build).
  • ⚠️ PMD report not generated.
  • ⚠️ Checkstyle report not generated.

Generated automatically by the PR CI workflow.

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 142 screenshots: 142 matched.
Native Windows port (x64 / Intel-AMD): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, SSE2 SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 54ms / native 3ms = 18.0x speedup
SIMD float-mul (64K x300) java 49ms / native 3ms = 16.3x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 168.000 ms
Base64 CN1 decode 101.000 ms
Base64 SIMD encode 79.000 ms
Base64 encode ratio (SIMD/CN1) 0.470x (53.0% faster)
Base64 SIMD decode 74.000 ms
Base64 decode ratio (SIMD/CN1) 0.733x (26.7% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 16.000 ms
Image createMask (SIMD on) 13.000 ms
Image createMask ratio (SIMD on/off) 0.813x (18.8% faster)
Image applyMask (SIMD off) 31.000 ms
Image applyMask (SIMD on) 26.000 ms
Image applyMask ratio (SIMD on/off) 0.839x (16.1% faster)
Image modifyAlpha (SIMD off) 23.000 ms
Image modifyAlpha (SIMD on) 20.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.870x (13.0% faster)
Image modifyAlpha removeColor (SIMD off) 26.000 ms
Image modifyAlpha removeColor (SIMD on) 22.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.846x (15.4% faster)

@shai-almog

shai-almog commented Jul 15, 2026

Copy link
Copy Markdown
Collaborator Author

Compared 142 screenshots: 142 matched.
Native Windows port (arm64 / Apple Silicon - Arm): full hellocodenameone screenshot suite rendered offscreen with Direct2D/DirectWrite, plus the real benchmarks (base64 native/CN1/SIMD, image createMask/applyMask/modifyAlpha/PNG/JPEG, NEON SIMD kernels). Compared against the in-repo baseline in scripts/windows/screenshots.

Benchmark Results

Detailed Performance Metrics

Metric Duration
SIMD kernel backend SSE2 (x64) / NEON (arm64) native kernels
SIMD int-add (64K x300) java 58ms / native 3ms = 19.3x speedup
SIMD float-mul (64K x300) java 56ms / native 4ms = 14.0x speedup
SIMD kernel correctness PASS (native result == scalar reference)
Base64 native bridge unavailable (CN1 + SIMD + image benchmarks only)
Base64 payload size 8192 bytes
Base64 benchmark iterations 6000
Base64 SIMD byte path gated to scalar (CPU autovectorizes scalar; explicit SIMD not beneficial here)
Base64 CN1 encode 245.000 ms
Base64 CN1 decode 128.000 ms
Base64 SIMD encode 65.000 ms
Base64 encode ratio (SIMD/CN1) 0.265x (73.5% faster)
Base64 SIMD decode 57.000 ms
Base64 decode ratio (SIMD/CN1) 0.445x (55.5% faster)
Image encode benchmark iterations 100
Image createMask (SIMD off) 11.000 ms
Image createMask (SIMD on) 8.000 ms
Image createMask ratio (SIMD on/off) 0.727x (27.3% faster)
Image applyMask (SIMD off) 24.000 ms
Image applyMask (SIMD on) 19.000 ms
Image applyMask ratio (SIMD on/off) 0.792x (20.8% faster)
Image modifyAlpha (SIMD off) 16.000 ms
Image modifyAlpha (SIMD on) 12.000 ms
Image modifyAlpha ratio (SIMD on/off) 0.750x (25.0% faster)
Image modifyAlpha removeColor (SIMD off) 18.000 ms
Image modifyAlpha removeColor (SIMD on) 14.000 ms
Image modifyAlpha removeColor ratio (SIMD on/off) 0.778x (22.2% faster)

@github-actions

Copy link
Copy Markdown
Contributor

Blog prose gate

✅ No net-new prose findings introduced by this PR.

@shai-almog shai-almog merged commit 4d8237a into master Jul 15, 2026
73 of 76 checks passed
@shai-almog shai-almog deleted the pure-cn1-editors branch July 15, 2026 13:54
@shai-almog shai-almog restored the pure-cn1-editors branch July 15, 2026 14:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant