diff --git a/src/components/draw/text.ts b/src/components/draw/text.ts index 2a3067d8..1b2a37f6 100644 --- a/src/components/draw/text.ts +++ b/src/components/draw/text.ts @@ -129,6 +129,11 @@ export interface TextCompOpt { * @since v2000.2 */ styles?: Record; + /** + * If true, any (whitespace) indent on the first line of the paragraph + * will be copied to all of the lines for those parts that text-wrap. + */ + indentAll?: boolean; } export function text(t: string, opt: TextCompOpt = {}): TextComp { @@ -144,6 +149,7 @@ export function text(t: string, opt: TextCompOpt = {}): TextComp { // TODO: shouldn't run when object / ancestor is paused transform: obj.textTransform, styles: obj.textStyles, + indentAll: opt.indentAll })); if (!opt.width) { diff --git a/src/gfx/draw/drawText.ts b/src/gfx/draw/drawText.ts index 6633ff41..bafb7b42 100644 --- a/src/gfx/draw/drawText.ts +++ b/src/gfx/draw/drawText.ts @@ -67,6 +67,11 @@ export type DrawTextOpt = RenderProps & { * @since v2000.2 */ styles?: Record; + /** + * If true, any (whitespace) indent on the first line of the paragraph + * will be copied to all of the lines for those parts that text-wrap. + */ + indentAll?: boolean }; /** diff --git a/src/gfx/formatText.ts b/src/gfx/formatText.ts index 5b54802d..1340cb54 100644 --- a/src/gfx/formatText.ts +++ b/src/gfx/formatText.ts @@ -270,6 +270,7 @@ export function formatText(opt: DrawTextOpt): FormattedText { let cursor = 0; let lastSpace: number | null = null; let lastSpaceWidth: number = 0; + let paraIndentX: number | undefined = undefined; // TODO: word break while (cursor < chars.length) { @@ -288,6 +289,7 @@ export function formatText(opt: DrawTextOpt): FormattedText { lastSpaceWidth = 0; curX = 0; curLine = []; + paraIndentX = undefined; } else { let q = font.map[ch]; @@ -316,7 +318,7 @@ export function formatText(opt: DrawTextOpt): FormattedText { chars: curLine, }); - curX = 0; + curX = paraIndentX ?? 0; curLine = []; } @@ -344,6 +346,9 @@ export function formatText(opt: DrawTextOpt): FormattedText { lastSpace = curLine.length; lastSpaceWidth = curX; } + if (opt.indentAll && paraIndentX === undefined && /\S/.test(ch)) { + paraIndentX = curX; + } curX += gw; tw = Math.max(tw, curX); diff --git a/tests/playtests/textwrap.js b/tests/playtests/textwrap.js new file mode 100644 index 00000000..23c2f07b --- /dev/null +++ b/tests/playtests/textwrap.js @@ -0,0 +1,24 @@ +kaplay({ background: "#000000" }); + +const theText = `MAN PAGE + Very long description paragraph. Very long description paragraph. Very long description paragraph. Very long description paragraph. Very long description paragraph. Very long description paragraph. Very long description paragraph. + +ANOTHER SECTION + Yet some more text here. Yet some more text here. Yet some more text here. Yet some more text here.` + +add([ + pos(100, 100), + text(theText, { + size: 16, + width: 17 * 16, + }), +]); + +add([ + pos(400, 100), + text(theText, { + size: 16, + width: 17 * 16, + indentAll: true + }), +]);