Small text test.

This commit is contained in:
Kapendev 2025-03-17 06:00:46 +02:00
parent 73ce82bb93
commit 5cdc8b0bd4
4 changed files with 54 additions and 53 deletions

View file

@ -2,21 +2,23 @@
import parin;
auto infoText = "Press a number to select an option.\nPress space to continue.";
auto infoArea = Rect(0, 180 * 0.8, 320, 180 * 0.2);
auto story = Story();
auto script = "
# A comment.
* label
| Hello world!
| This is a text line and the next is a menu line.
^ Option 1 ^ Option 2 ^ Option 3
^ Pick one. ^ Pick two. ^ Skip.
$ MENU SKIP
*
| Text of option 1.
| Text of option one.
$ end JUMP
*
| Text of option 2.
| Text of option two.
$ end JUMP
* end
@ -35,7 +37,7 @@ void ready() {
bool update(float dt) {
// Update the story.
if (story.hasText || story.hasPause) {
if (Keyboard.enter.isPressed) story.update();
if (Keyboard.space.isPressed) story.update();
}
if (story.hasMenu) {
// Select an option based on a number.
@ -56,16 +58,9 @@ bool update(float dt) {
if (story.hasPause) {
drawDebugText("The story is paused.", Vec2(8));
}
// Draw some info.
auto w = resolutionWidth;
auto h = resolutionHeight;
auto text = "Press 1, 2 or 3 to select an option.\nPress enter to continue.";
auto textArea = Rect(0, h * 0.8, w, h * 0.2);
auto textPosition = textArea.centerPoint;
auto textOptions = DrawOptions(Alignment.left, w - 16);
textOptions.hook = Hook.center;
drawRect(textArea, gray1);
drawDebugText(text, textPosition, textOptions);
// Draw the info.
drawRect(infoArea, gray1);
drawDebugText(infoText, infoArea.centerPoint, DrawOptions(Hook.center), TextOptions(Alignment.left, 320 - 16));
return false;
}

View file

@ -9,19 +9,17 @@ void ready() {
}
bool update(float dt) {
auto options = DrawOptions();
auto options = TextOptions();
// Set the alignment of the text.
options.alignment = Alignment.center;
// Set the width of the aligned text. It is used as a hint and is not enforced.
options.alignmentWidth = 200;
// Set whether the content of the text flows in a right-to-left direction.
options.isRightToLeft = false;
// Update how many characters are visible this frame.
options.visibilityRatio = fmod(elapsedTime * 0.3, 1.5);
// Set whether the content of the text flows in a right-to-left direction.
options.isRightToLeft = false;
auto size = measureTextSize(engineFont, text, options);
auto size = measureTextSize(engineFont, text);
drawRect(Rect(Vec2(8), size), black);
drawText(engineFont, text, Vec2(8), options);
drawText(engineFont, text, Vec2(8), DrawOptions(), options);
return false;
}

View file

@ -185,18 +185,13 @@ enum Gamepad : ushort {
middle = rl.GAMEPAD_BUTTON_MIDDLE, /// The middle button.
}
/// A structure containing options for configuring drawing parameters.
struct DrawOptions {
Vec2 origin = Vec2(0.0f); /// The origin point of the drawn object. This value can be used to force a specific value when needed and is not used if it is set to zero.
Vec2 origin = Vec2(0.0f); /// The origin point of the drawn object. This value can be used to force a specific origin and is not used if it is set to zero.
Vec2 scale = Vec2(1.0f); /// The scale of the drawn object.
float rotation = 0.0f; /// The rotation of the drawn object, in degrees.
Color color = white; /// The color of the drawn object.
Hook hook = Hook.topLeft; /// A value representing the origin point of the drawn object when origin is set to zero.
Flip flip = Flip.none; /// A value representing flipping orientations.
Alignment alignment = Alignment.left; /// A value represeting alignment orientations.
int alignmentWidth = 0; /// The width of the aligned object. It is used as a hint and is not enforced. Usually used for text drawing.
float visibilityRatio = 1.0f; /// Controls the visibility ratio of the object, where 0.0 means fully hidden and 1.0 means fully visible. Usually used for text drawing.
bool isRightToLeft = false; /// Indicates whether the content of the object flows in a right-to-left direction, such as for Arabic or Hebrew text. Usually used for text drawing.
@safe @nogc nothrow:
@ -224,6 +219,19 @@ struct DrawOptions {
this(Flip flip) {
this.flip = flip;
}
}
pragma(msg, TextOptions.sizeof);
/// A structure containing options for configuring extra drawing parameters for text.
struct TextOptions {
float visibilityRatio = 1.0f; /// Controls the visibility ratio of the text, where 0.0 means fully hidden and 1.0 means fully visible.
int alignmentWidth = 0; /// The width of the aligned text. It is used as a hint and is not enforced.
ushort visibilityCount = 0; /// Controls the visibility count of the text. This value can be used to force a specific character count and is not used if it is set to zero.
Alignment alignment = Alignment.left; /// A value represeting alignment orientations.
bool isRightToLeft = false; /// Indicates whether the content of the text flows in a right-to-left direction.
@safe @nogc nothrow:
/// Initializes the options with the given alignment.
this(Alignment alignment, int alignmentWidth = 0) {
@ -440,6 +448,7 @@ struct FontId {
}
}
// TODO: Add looping variable and maybe change the loadSound function to something like `loadSound(path, volume, looping)`.
/// Represents a sound resource.
struct Sound {
Variant!(rl.Sound, rl.Music) data;
@ -1762,7 +1771,7 @@ float deltaWheel() {
/// Measures the size of the specified text when rendered with the given font and draw options.
@trusted
Vec2 measureTextSize(Font font, IStr text, DrawOptions options = DrawOptions()) {
Vec2 measureTextSize(Font font, IStr text, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) {
if (font.isEmpty || text.length == 0) return Vec2();
auto lineCodepointCount = 0;
@ -1792,7 +1801,7 @@ Vec2 measureTextSize(Font font, IStr text, DrawOptions options = DrawOptions())
textCodepointIndex += codepointByteCount;
}
if (textMaxWidth < textWidth) textMaxWidth = textWidth;
if (textMaxWidth < options.alignmentWidth) textMaxWidth = options.alignmentWidth;
if (textMaxWidth < extraOptions.alignmentWidth) textMaxWidth = extraOptions.alignmentWidth;
return Vec2(textMaxWidth * options.scale.x, textHeight * options.scale.y).floor();
}
@ -2270,7 +2279,7 @@ void drawRune(FontId font, dchar rune, Vec2 position, DrawOptions options = Draw
/// Draws the specified text with the given font at the given position using the provided draw options.
// NOTE: Text drawing needs to go over the text 3 times. This can be made into 2 times in the future if needed by copy-pasting the measureTextSize inside this function.
@trusted
void drawText(Font font, IStr text, Vec2 position, DrawOptions options = DrawOptions()) {
void drawText(Font font, IStr text, Vec2 position, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) {
static FixedList!(IStr, 128) linesBuffer = void;
static FixedList!(short, 128) linesWidthBuffer = void;
@ -2297,7 +2306,7 @@ void drawText(Font font, IStr text, Vec2 position, DrawOptions options = DrawOpt
}
textCodepointIndex += codepointSize;
}
if (textMaxLineWidth < options.alignmentWidth) textMaxLineWidth = options.alignmentWidth;
if (textMaxLineWidth < extraOptions.alignmentWidth) textMaxLineWidth = extraOptions.alignmentWidth;
}
// Prepare the the text for drawing.
@ -2313,28 +2322,30 @@ void drawText(Font font, IStr text, Vec2 position, DrawOptions options = DrawOpt
rl.rlTranslatef(-origin.x.floor(), -origin.y.floor(), 0.0f);
// Draw the text.
auto drawMaxCodepointCount = cast(int) (textCodepointCount * clamp(options.visibilityRatio, 0.0f, 1.0f));
auto drawMaxCodepointCount = extraOptions.visibilityCount
? extraOptions.visibilityCount
: textCodepointCount * extraOptions.visibilityRatio;
auto drawCodepointCounter = 0;
auto textOffsetY = 0;
foreach (i, line; linesBuffer) {
auto lineCodepointIndex = 0;
// Find the initial x offset for the text.
auto textOffsetX = 0;
if (options.isRightToLeft) {
final switch (options.alignment) {
if (extraOptions.isRightToLeft) {
final switch (extraOptions.alignment) {
case Alignment.left: textOffsetX = linesWidthBuffer[i]; break;
case Alignment.center: textOffsetX = textMaxLineWidth / 2 + linesWidthBuffer[i] / 2; break;
case Alignment.right: textOffsetX = textMaxLineWidth; break;
}
} else {
final switch (options.alignment) {
final switch (extraOptions.alignment) {
case Alignment.left: break;
case Alignment.center: textOffsetX = textMaxLineWidth / 2 - linesWidthBuffer[i] / 2; break;
case Alignment.right: textOffsetX = textMaxLineWidth - linesWidthBuffer[i]; break;
}
}
// Go over the characters and draw them.
if (options.isRightToLeft) {
if (extraOptions.isRightToLeft) {
lineCodepointIndex = cast(int) line.length;
while (lineCodepointIndex > 0) {
if (drawCodepointCounter >= drawMaxCodepointCount) break;
@ -2389,13 +2400,13 @@ void drawText(Font font, IStr text, Vec2 position, DrawOptions options = DrawOpt
}
/// Draws text with the given font at the given position using the provided draw options.
void drawText(FontId font, IStr text, Vec2 position, DrawOptions options = DrawOptions()) {
drawText(font.getOr(), text, position, options);
void drawText(FontId font, IStr text, Vec2 position, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) {
drawText(font.getOr(), text, position, options, extraOptions);
}
/// Draws debug text at the given position with the provided draw options.
void drawDebugText(IStr text, Vec2 position, DrawOptions options = DrawOptions()) {
drawText(engineFont, text, position, options);
void drawDebugText(IStr text, Vec2 position, DrawOptions options = DrawOptions(), TextOptions extraOptions = TextOptions()) {
drawText(engineFont, text, position, options, extraOptions);
}
/// Mixes in a game loop template with specified functions for initialization, update, and cleanup, and sets window size and title.

View file

@ -294,26 +294,27 @@ void updateUiText(Rect area, IStr text, UiOptions options = UiOptions()) {
// TODO SOME ALIGNEMENT SHIT WITH SCALING>>>>
void drawUiText(Rect area, IStr text, UiOptions options = UiOptions()) {
auto font = options.font.isValid ? options.font.get() : engineFont;
auto textOptions = DrawOptions(options.alignment, cast(int) (area.size.x / options.fontScale));
textOptions.color = options.fontColor;
textOptions.scale = Vec2(options.fontScale);
auto extraOptions = TextOptions(options.alignment, cast(int) (area.size.x / options.fontScale));
auto drawOptions = DrawOptions(options.fontColor);
drawOptions.scale = Vec2(options.fontScale);
auto textPosition = area.centerPoint;
final switch (options.alignment) {
case Alignment.left:
textOptions.hook = Hook.left;
drawOptions.hook = Hook.left;
textPosition.x = area.position.x + options.alignmentOffset; break;
case Alignment.center:
textOptions.hook = Hook.center;
drawOptions.hook = Hook.center;
break;
case Alignment.right:
textOptions.hook = Hook.right;
drawOptions.hook = Hook.right;
textPosition.x = area.position.x + area.size.x - options.alignmentOffset; break;
}
textPosition = textPosition.round();
if (options.isDisabled && textOptions.color.a >= options.fontAlphaOffset) {
textOptions.color.a -= options.fontAlphaOffset;
if (options.isDisabled && drawOptions.color.a >= options.fontAlphaOffset) {
drawOptions.color.a -= options.fontAlphaOffset;
}
drawText(font, text, textPosition, textOptions);
drawText(font, text, textPosition, drawOptions, extraOptions);
}
void uiText(Rect area, IStr text, UiOptions options = UiOptions()) {
@ -516,17 +517,13 @@ void drawUiTextField(Rect area, Str text, UiOptions options = UiOptions()) {
drawUiText(area, text, options);
// TODO: Make that text position thing a function bro!!!
// ---
auto textOptions = DrawOptions(options.alignment, cast(int) (area.size.x / options.fontScale));
auto textPosition = area.centerPoint;
final switch (options.alignment) {
case Alignment.left:
textOptions.hook = Hook.left;
textPosition.x = area.position.x + options.alignmentOffset; break;
case Alignment.center:
textOptions.hook = Hook.center;
break;
case Alignment.right:
textOptions.hook = Hook.right;
textPosition.x = area.position.x + area.size.x - options.alignmentOffset; break;
}
textPosition = textPosition.round();