Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 20 additions & 10 deletions src/core/lib/colorCache.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
import { parseToAbgrString, parseToRgbaString } from './colorParser.js';

const parsedArgbColors: Map<number, string> = new Map();
const parsedRgbaColors: Map<number, string> = new Map();

export function normalizeCanvasColor(color: number, isRGBA: boolean = false) {
let targetCache = isRGBA === true ? parsedRgbaColors : parsedArgbColors;
let out = targetCache.get(color);
export function normalizeCanvasColor(rgbaColor: number) {
let out = parsedRgbaColors.get(rgbaColor);
if (out !== undefined) {
return out;
}
const r = (rgbaColor >>> 24) & 0xff;
const g = (rgbaColor >>> 16) & 0xff;
const b = (rgbaColor >>> 8) & 0xff;
const a = (rgbaColor & 0xff) / 255;
out = `rgba(${r},${g},${b},${a})`;
parsedRgbaColors.set(rgbaColor, out);
return out;
}

if (isRGBA === true) {
out = parseToRgbaString(color);
} else {
out = parseToAbgrString(color);
export function normalizeCanvasColorArgb(argbColor: number) {
let out = parsedArgbColors.get(argbColor);
if (out !== undefined) {
return out;
}
targetCache.set(color, out);
const a = ((argbColor >>> 24) & 0xff) / 255;
const b = (argbColor >>> 16) & 0xff;
const g = (argbColor >>> 8) & 0xff;
const r = argbColor & 0xff;
out = `rgba(${r},${g},${b},${a})`;
parsedArgbColors.set(argbColor, out);
return out;
}
35 changes: 7 additions & 28 deletions src/core/lib/colorParser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,28 +41,12 @@ export function parseColor(abgr: number): IParsedColor {
return WHITE;
}
const a = ((abgr >>> 24) & 0xff) / 255;
const b = (abgr >>> 16) & 0xff & 0xff;
const g = (abgr >>> 8) & 0xff & 0xff;
const r = abgr & 0xff & 0xff;
Comment thread
guilhermesimoes marked this conversation as resolved.
const b = (abgr >>> 16) & 0xff;
const g = (abgr >>> 8) & 0xff;
const r = abgr & 0xff;
return { isWhite: false, a, r, g, b };
}

export function parseToAbgrString(abgr: number): string {
const a = ((abgr >>> 24) & 0xff) / 255;
const b = (abgr >>> 16) & 0xff & 0xff;
const g = (abgr >>> 8) & 0xff & 0xff;
const r = abgr & 0xff & 0xff;
Comment thread
wouterlucas marked this conversation as resolved.
return `rgba(${r},${g},${b},${a})`;
}

export function parseToRgbaString(rgba: number): string {
const r = (rgba >>> 24) & 0xff;
const g = (rgba >>> 16) & 0xff & 0xff;
const b = (rgba >>> 8) & 0xff & 0xff;
const a = (rgba & 0xff & 0xff) / 255;
return `rgba(${r},${g},${b},${a})`;
}

/**
* Extract color components
*/
Expand All @@ -71,15 +55,10 @@ export function parseColorRgba(rgba: number): IParsedColor {
return WHITE;
}
const r = (rgba >>> 24) & 0xff;
const g = (rgba >>> 16) & 0xff & 0xff;
const b = (rgba >>> 8) & 0xff & 0xff;
const a = (rgba & 0xff & 0xff) / 255;
const g = (rgba >>> 16) & 0xff;
const b = (rgba >>> 8) & 0xff;
const a = (rgba & 0xff) / 255;
return { isWhite: false, r, g, b, a };
}

/**
* Format a parsed color into a rgba CSS color
*/
export function formatRgba({ a, r, g, b }: IParsedColor): string {
return `rgba(${r},${g},${b},${a})`;
}

4 changes: 2 additions & 2 deletions src/core/renderers/CoreRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ export abstract class CoreRenderer {
* Insert a begin-rounded-clip sentinel into the render op list before a
* node's children are added. No-op on non-WebGL renderers.
*/

beginRoundedClip(_node: CoreNode): void {
// no-op default — overridden by WebGlRenderer
}
Expand All @@ -96,7 +96,7 @@ export abstract class CoreRenderer {
* Insert an end-rounded-clip sentinel after a node's children have been
* added. No-op on non-WebGL renderers.
*/

endRoundedClip(_node: CoreNode): void {
// no-op default — overridden by WebGlRenderer
}
Expand Down
11 changes: 7 additions & 4 deletions src/core/renderers/canvas/CanvasRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,10 @@ import { CoreRenderer } from '../CoreRenderer.js';
import { CanvasTexture } from './CanvasTexture.js';
import { parseColor } from '../../lib/colorParser.js';
import { CanvasShaderNode, type CanvasShaderType } from './CanvasShaderNode.js';
import { normalizeCanvasColor } from '../../lib/colorCache.js';
import {
normalizeCanvasColor,
normalizeCanvasColorArgb,
} from '../../lib/colorCache.js';
import type { Stage } from '../../Stage.js';

export class CanvasRenderer extends CoreRenderer {
Expand Down Expand Up @@ -218,12 +221,12 @@ export class CanvasRenderer extends CoreRenderer {
endColor = node.premultipliedColorTr;
}
const gradient = this.context.createLinearGradient(tx, ty, endX, endY);
gradient.addColorStop(0, normalizeCanvasColor(color));
gradient.addColorStop(1, normalizeCanvasColor(endColor));
gradient.addColorStop(0, normalizeCanvasColorArgb(color));
gradient.addColorStop(1, normalizeCanvasColorArgb(endColor));
this.context.fillStyle = gradient;
this.context.fillRect(tx, ty, width, height);
} else {
this.context.fillStyle = normalizeCanvasColor(color);
this.context.fillStyle = normalizeCanvasColorArgb(color);
this.context.fillRect(tx, ty, width, height);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/renderers/canvas/CanvasShaderNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,6 @@ export class CanvasShaderNode<
}

toColorString(rgba: number) {
return normalizeCanvasColor(rgba, true);
return normalizeCanvasColor(rgba);
}
}
4 changes: 2 additions & 2 deletions src/core/renderers/canvas/CanvasTexture.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@

import type { Dimensions } from '../../../common/CommonTypes.js';
import { assertTruthy } from '../../../utils.js';
import { formatRgba, type IParsedColor } from '../../lib/colorParser.js';
import { type IParsedColor } from '../../lib/colorParser.js';
import { CoreContextTexture } from '../CoreContextTexture.js';
import type { Texture } from '../../textures/Texture.js';

Expand Down Expand Up @@ -109,7 +109,7 @@ export class CanvasTexture extends CoreContextTexture {
}
return image;
}
const key = formatRgba(color);
const key = `rgba(${color.r},${color.g},${color.b},${color.a})`;
if (this.tintCache?.key === key) {
return this.tintCache.image;
}
Expand Down
5 changes: 3 additions & 2 deletions src/core/shaders/canvas/Border.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { formatRgba, parseColorRgba } from '../../lib/colorParser.js';
import { parseColorRgba } from '../../lib/colorParser.js';
import { valuesAreEqual } from '../../lib/utils.js';
import type { CanvasShaderType } from '../../renderers/canvas/CanvasShaderNode.js';
import type { Vec4 } from '../../renderers/webgl/internal/ShaderUtils.js';
Expand All @@ -40,7 +40,8 @@ export interface ComputedBorderValues {
export const Border: CanvasShaderType<BorderProps, ComputedBorderValues> = {
props: BorderTemplate.props,
update() {
this.computed.borderColor = formatRgba(parseColorRgba(this.props!.color));
const c = parseColorRgba(this.props!.color);
this.computed.borderColor = `rgba(${c.r},${c.g},${c.b},${c.a})`;
this.computed.borderAsym = !valuesAreEqual(this.props!.w as number[]);
const borderAlign = this.props!.align as number;
const borderGap = this.props!.gap as number;
Expand Down
6 changes: 2 additions & 4 deletions src/core/text-rendering/CanvasTextRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ const renderText = (props: CoreTextNodeProps): TextRenderInfo => {

// CSS color string for uncolored spans — inherits the node's text color.
// normalizeCanvasColor caches the string, so no allocation in hot path.
const nodeColor = normalizeCanvasColor(color, true);
const nodeColor = normalizeCanvasColor(color);

let strippedPos = 0;
let curSpanIdx = 0;
Expand Down Expand Up @@ -290,9 +290,7 @@ const renderText = (props: CoreTextNodeProps): TextRenderInfo => {

// Colored span uses span.color; uncolored span inherits node color.
const spanFillStyle =
span.color !== 0
? normalizeCanvasColor(span.color, true)
: nodeColor;
span.color !== 0 ? normalizeCanvasColor(span.color) : nodeColor;

if (spanFillStyle !== activeFillStyle) {
context.fillStyle = spanFillStyle;
Expand Down
Loading