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
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import org.codejive.twinkle.ansi.Style;
import org.codejive.twinkle.ansi.util.Printable;
import org.codejive.twinkle.shapes.util.Draw;
import org.codejive.twinkle.text.Buffer;
import org.codejive.twinkle.text.Buffer.StylePrintOption;
import org.codejive.twinkle.text.RenderTarget;
import org.jspecify.annotations.NonNull;

Expand Down Expand Up @@ -156,38 +158,39 @@ private char corner(char corner, LineStyle lineStyle1, LineStyle lineStyle2) {
}

public void render(RenderTarget target) {
target.putAt(0, 0, style, corner(cornerStyle.topLeftChar, leftLineStyle, topLineStyle));
Draw.lineH(target, 1, 0, target.size().width() - 1, style, topLineStyle.horizontalChar);
StylePrintOption styleOpt = Buffer.styleOpt(style);
target.putAt(0, 0, corner(cornerStyle.topLeftChar, leftLineStyle, topLineStyle), styleOpt);
Draw.lineH(target, 1, 0, target.size().width() - 1, topLineStyle.horizontalChar, styleOpt);
target.putAt(
target.size().width() - 1,
0,
style,
corner(cornerStyle.topRightChar, rightLineStyle, topLineStyle));
Draw.lineV(target, 0, 1, target.size().height() - 1, style, leftLineStyle.verticalChar);
corner(cornerStyle.topRightChar, rightLineStyle, topLineStyle),
styleOpt);
Draw.lineV(target, 0, 1, target.size().height() - 1, leftLineStyle.verticalChar, styleOpt);
target.putAt(
0,
target.size().height() - 1,
style,
corner(cornerStyle.bottomLeftChar, leftLineStyle, bottomLineStyle));
corner(cornerStyle.bottomLeftChar, leftLineStyle, bottomLineStyle),
styleOpt);
Draw.lineH(
target,
1,
target.size().height() - 1,
target.size().width() - 1,
style,
bottomLineStyle.horizontalChar);
bottomLineStyle.horizontalChar,
styleOpt);
target.putAt(
target.size().width() - 1,
target.size().height() - 1,
style,
corner(cornerStyle.bottomRightChar, rightLineStyle, bottomLineStyle));
corner(cornerStyle.bottomRightChar, rightLineStyle, bottomLineStyle),
styleOpt);
Draw.lineV(
target,
target.size().width() - 1,
1,
target.size().height() - 1,
style,
rightLineStyle.verticalChar);
rightLineStyle.verticalChar,
styleOpt);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
package org.codejive.twinkle.shapes.util;

import org.codejive.twinkle.ansi.Style;
import org.codejive.twinkle.text.RenderTarget;
import org.jspecify.annotations.NonNull;
import org.codejive.twinkle.text.RenderTarget.PrintOption;

public class Draw {

public static void lineH(
RenderTarget target, int x, int y, int x2, @NonNull Style style, char c) {
RenderTarget target, int x, int y, int x2, char c, PrintOption... options) {
for (int i = x; i < x2; i++) {
target.putAt(i, y, style, c);
target.putAt(i, y, c, options);
}
}

public static void lineV(
RenderTarget target, int x, int y, int y2, @NonNull Style style, char c) {
RenderTarget target, int x, int y, int y2, char c, PrintOption... options) {
for (int i = y; i < y2; i++) {
target.putAt(x, i, style, c);
target.putAt(x, i, c, options);
}
}
}
108 changes: 37 additions & 71 deletions twinkle-text/src/main/java/org/codejive/twinkle/text/Buffer.java
Original file line number Diff line number Diff line change
Expand Up @@ -338,82 +338,69 @@ private void graphemeAt_(@NonNull Appendable appendable, int x, int y) {
}
}

/**
* Get the style at the specified position in the buffer. If the position is out of bounds, an
* unstyled Style will be returned.
*
* @param x the x-coordinate of the style
* @param y the y-coordinate of the style
* @return the style at the specified position, or an unstyled Style
*/
public @NonNull Style styleAt(int x, int y) {
if (outside(x, y)) {
return Style.UNSTYLED;
}
return Style.of(buffers.styleBuffer[y][x]);
}

/**
* Print a character at the specified position in the buffer with the given style. If the
* position is out of bounds, the character will not be printed.
*
* @param x the x-coordinate of the character
* @param y the y-coordinate of the character
* @param style the style to apply to the character
* @param c the character to print
*/
@Override
public void putAt(int x, int y, @NonNull Style style, char c) {
public void putAt(int x, int y, char c, PrintOption... options) {
if (outside(x, y)) {
return;
}
if (Character.isSurrogate(c)) {
c = REPLACEMENT_CHAR;
}
Style style = opt(options, StylePrintOption.class, StylePrintOption.UNSTYLED).style();
setCharAt_(x, y, style.state(), c, null);
}

/**
* Print a codepoint at the specified position in the buffer with the given style. If the
* position is out of bounds, the codepoint will not be printed.
*
* @param x the x-coordinate of the codepoint
* @param y the y-coordinate of the codepoint
* @param style the style to apply to the codepoint
* @param cp the codepoint to print
*/
@Override
public void putAt(int x, int y, @NonNull Style style, int cp) {
public void putAt(int x, int y, int cp, PrintOption... options) {
if (outside(x, y)) {
return;
}
Style style = opt(options, StylePrintOption.class, StylePrintOption.UNSTYLED).style();
setCharAt_(x, y, style.state(), cp, null);
}

/**
* Print a grapheme at the specified position in the buffer with the given style. If the
* position is out of bounds, the grapheme will not be printed.
*
* @param x the x-coordinate of the grapheme
* @param y the y-coordinate of the grapheme
* @param style the style to apply to the grapheme
* @param grapheme the grapheme to print
*/
@Override
public void putAt(int x, int y, @NonNull Style style, @NonNull CharSequence grapheme) {
public void putAt(int x, int y, @NonNull CharSequence grapheme, PrintOption... options) {
if (outside(x, y)) {
return;
}
if (grapheme.length() == 0) {
return;
}
Style style = opt(options, StylePrintOption.class, StylePrintOption.UNSTYLED).style();
setCharAt_(x, y, style.state(), -1, grapheme.toString());
}

public enum SimplePrintOption implements PrintOption {
NOWRAP
}

public static class StylePrintOption implements PrintOption {
private final Style style;

public static final StylePrintOption DEFAULT = new StylePrintOption(Style.DEFAULT);
public static final StylePrintOption UNSTYLED = new StylePrintOption(Style.UNSTYLED);

public StylePrintOption(Style style) {
this.style = style;
}

public Style style() {
return style;
}
}

public static StylePrintOption styleOpt(Style style) {
return new StylePrintOption(style);
}

public static class TransparencyPrintOption implements PrintOption {
private final String transparentCharacters;

Expand All @@ -435,33 +422,19 @@ public String chars() {
}
}

/**
* Print a string at the specified position in the buffer with the given style. If the string is
* fully out of bounds, the string will not be printed.
*
* @param x the x-coordinate of the string
* @param y the y-coordinate of the string
* @param style the style to apply to the string
* @param str the string to print
* @param options the print options to apply
*/
public static TransparencyPrintOption transparencyOpt(String transparentCharacters) {
return new TransparencyPrintOption(transparentCharacters);
}

@Override
public void printAt(
int x, int y, @NonNull Style style, @NonNull CharSequence str, PrintOption... options) {
public void printAt(int x, int y, @NonNull CharSequence str, PrintOption... options) {
if (outside(x, y, str.length())) {
return;
}
Style style = opt(options, StylePrintOption.class, StylePrintOption.UNSTYLED).style();
printAt(x, y, StyledIterator.of(str, style), options);
}

/**
* Print a styled string at the specified position in the buffer.
*
* @param x the x-coordinate of the string
* @param y the y-coordinate of the string
* @param iter a StyledIterator
* @param options the print options to apply
*/
@Override
public void printAt(int x, int y, @NonNull StyledIterator iter, PrintOption... options) {
int curX = x;
Expand Down Expand Up @@ -541,13 +514,6 @@ private void setSkipAt(int x, int y) {
}
}

/**
* Clear the cell at the specified position in the buffer, setting it to the default state. If
* the position is out of bounds, no action will be taken.
*
* @param x the x-coordinate of the cell
* @param y the y-coordinate of the cell
*/
@Override
public void clearAt(int x, int y) {
if (outside(x, y)) {
Expand Down Expand Up @@ -611,7 +577,7 @@ private void setCellAt(int x, int y, long styleState, int cp, String grapheme) {
*
* @return a reference to this Buffer, for chaining
*/
public @NonNull RenderTarget clear() {
public @NonNull Buffer clear() {
for (int y = 0; y < rect.height(); y++) {
for (int x = 0; x < rect.width(); x++) {
clearAt_(x, y);
Expand All @@ -626,7 +592,7 @@ private void setCellAt(int x, int y, long styleState, int cp, String grapheme) {
*
* @return a reference to this Buffer, for chaining
*/
public @NonNull RenderTarget clear(int fromX, int fromY, int toX, int toY) {
public @NonNull Buffer clear(int fromX, int fromY, int toX, int toY) {
for (int x = fromX; x < rect.width(); x++) {
// Using clearAt instead of clearAt_ to handle wide character overlap
clearAt(x, fromY);
Expand All @@ -652,7 +618,7 @@ private void setCellAt(int x, int y, long styleState, int cp, String grapheme) {
* @param newSize the new size of the buffer
* @return a reference to this Buffer, for chaining
*/
public @NonNull RenderTarget resize(@NonNull Size newSize) {
public @NonNull Buffer resize(@NonNull Size newSize) {
buffers = buffers.resize(newSize);
rect = Rect.of(newSize);
return this;
Expand All @@ -671,7 +637,7 @@ private void setCellAt(int x, int y, long styleState, int cp, String grapheme) {
* @param targetY the y-coordinate on the target buffer
* @return a reference to this Buffer, for chaining
*/
public @NonNull RenderTarget overlayOn(@NonNull Buffer targetBuffer, int targetX, int targetY) {
public @NonNull Buffer overlayOn(@NonNull Buffer targetBuffer, int targetX, int targetY) {
buffers.copyTo(targetBuffer.buffers, rect, targetX, targetY, "\0");
return this;
}
Expand All @@ -690,7 +656,7 @@ private void setCellAt(int x, int y, long styleState, int cp, String grapheme) {
* @param transparantCharacters the characters to be treated as transparent
* @return a reference to this Buffer, for chaining
*/
public @NonNull RenderTarget overlayOn(
public @NonNull Buffer overlayOn(
@NonNull Buffer targetBuffer, int targetX, int targetY, String transparantCharacters) {
buffers.copyTo(targetBuffer.buffers, rect, targetX, targetY, transparantCharacters);
return this;
Expand All @@ -712,7 +678,7 @@ private void setCellAt(int x, int y, long styleState, int cp, String grapheme) {
* @param transparantCharacters the characters to be treated as transparent
* @return a reference to this Buffer, for chaining
*/
public @NonNull RenderTarget overlayOn(
public @NonNull Buffer overlayOn(
@NonNull Buffer targetBuffer,
Rect sourceRect,
int targetX,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package org.codejive.twinkle.text;

import org.codejive.twinkle.ansi.Style;
import org.codejive.twinkle.text.util.Size;
import org.codejive.twinkle.text.util.StyledIterator;
import org.jspecify.annotations.NonNull;
Expand All @@ -22,45 +21,43 @@ public interface PrintOption {}
*
* @param x the x-coordinate of the character
* @param y the y-coordinate of the character
* @param style the style to apply to the character
* @param c the character to print
* @param options the print options to apply
*/
void putAt(int x, int y, @NonNull Style style, char c);
void putAt(int x, int y, char c, PrintOption... options);

/**
* Print a codepoint at the specified position in the buffer with the given style. If the
* position is out of bounds, the codepoint will not be printed.
*
* @param x the x-coordinate of the codepoint
* @param y the y-coordinate of the codepoint
* @param style the style to apply to the codepoint
* @param cp the codepoint to print
* @param options the print options to apply
*/
void putAt(int x, int y, @NonNull Style style, int cp);
void putAt(int x, int y, int cp, PrintOption... options);

/**
* Print a grapheme at the specified position in the buffer with the given style. If the
* position is out of bounds, the grapheme will not be printed.
*
* @param x the x-coordinate of the grapheme
* @param y the y-coordinate of the grapheme
* @param style the style to apply to the grapheme
* @param grapheme the grapheme to print
* @param options the print options to apply
*/
void putAt(int x, int y, @NonNull Style style, @NonNull CharSequence grapheme);
void putAt(int x, int y, @NonNull CharSequence grapheme, PrintOption... options);

/**
* Print a string at the specified position in the buffer with the given style. If the string is
* fully out of bounds, the string will not be printed.
*
* @param x the x-coordinate of the string
* @param y the y-coordinate of the string
* @param style the style to apply to the string
* @param str the string to print
* @param options the print options to apply
*/
void printAt(
int x, int y, @NonNull Style style, @NonNull CharSequence str, PrintOption... options);
void printAt(int x, int y, @NonNull CharSequence str, PrintOption... options);

/**
* Print a styled string at the specified position in the buffer.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public void flush() {
cursorX = 0;
cursorY++;
}
buffer.putAt(cursorX, cursorY, curStyle, decoder.toString());
buffer.putAt(cursorX, cursorY, decoder.toString(), Buffer.styleOpt(curStyle));
cursorX += decoder.width();
}
}
Expand Down
Loading
Loading