Skip to content

Commit

Permalink
fix(components/Row): fix black bg on two-color char tail not causing …
Browse files Browse the repository at this point in the history
…visual effects

This issue was described in commit a75d550
("Fix two-color character rendering bug when the right-half is black.").

This issue was caused by the HTML layout of two-color chars, e.g.:

```html
<span class="q15 b1"> <!-- Non-black BG. -->
    <span class="q15 b1 rb0 wpadding" data-text="A" style="display: inline-block; width: 24px;">
        A
    </span> <!-- "Black" (transparent) right-half BG., appeared as non-black -->
    M
</span>
```

To fix this issue, WordSegmentBuilder is specialized for two-color chars
(as JavaScript class TwoColorWordBuilder)
so as to instead generate such layout as:

```html
<span class="q15 b1 rb0 wpadding" data-text="A" style="display: inline-block; width: 24px;">
    A
</span>
<span class="q15 b1">
    M
</span>
```

This not only avoids the unwanted background color introduced by the outer span
but also eliminates the unnecessary outer span for a sole two-color char.

Note that this requires the fix introduced in commit d6ebaab
("feat: rework two-color-word effect & implement blinking")
to make the un-nested span rendered expectedly.
  • Loading branch information
IepIweidieng committed Jan 15, 2023
1 parent d6ebaab commit 17fd980
Show file tree
Hide file tree
Showing 2 changed files with 28 additions and 15 deletions.
9 changes: 5 additions & 4 deletions src/components/Row/ColorSegmentBuilder.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import WordSegmentBuilder from "./WordSegmentBuilder";
import { WordSegmentBuilder, TwoColorWordBuilder } from "./WordSegmentBuilder";
import { b2u, isDBCSLead } from "../../js/string_util";
import { symbolTable } from "../../js/symbol_table";

Expand Down Expand Up @@ -56,13 +56,14 @@ export class ColorSegmentBuilder {
return;
}
if (!leadColor.equals(ch.getColor())) {
this.beginSegment(leadColor);
this.wordBuilder.appendTwoColorWord(
text,
this.segs.push(this.wordBuilder.build());
this.wordBuilder = new TwoColorWordBuilder(
this.segs.length,
leadColor,
ch.getColor(),
this.forceWidth
);
this.wordBuilder.appendNormalText(text);
return;
}
const forceWidth = shouldForceWidth(text) ? this.forceWidth : 0;
Expand Down
34 changes: 23 additions & 11 deletions src/components/Row/WordSegmentBuilder/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,24 +32,36 @@ export class WordSegmentBuilder {
);
}

appendTwoColorWord(text, colorLead, colorTail, forceWidth) {
this.inner.push(
<TwoColorWord
key={this.inner.length}
text={text}
colorLead={colorLead}
colorTail={colorTail}
forceWidth={forceWidth}
build() {
return (
<ColorSpan
key={this.key}
colorState={this.colorState}
inner={this.inner}
/>
);
}
}

export class TwoColorWordBuilder extends WordSegmentBuilder {
constructor(key, colorState, colorTail, forceWidth) {
super(key, colorState);
this.colorTail = colorTail;
this.forceWidth = forceWidth;
}

isLastSegmentSameColor(color) {
return false; // forbid appending
}

build() {
return (
<ColorSpan
<TwoColorWord
key={this.key}
colorState={this.colorState}
inner={this.inner}
colorLead={this.colorState}
colorTail={this.colorTail}
forceWidth={this.forceWidth}
text={this.inner}
/>
);
}
Expand Down

0 comments on commit 17fd980

Please sign in to comment.