123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- #include "textbox.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #define ERROR(...) fprintf(stderr, __VA_ARGS__)
- TextBox *textBoxNew(const char *text, float x, float y, float textSize,
- SDL_Color color, SDL_Texture *background, TTF_Font *font,
- const Window *window) {
- TextBox *box = malloc(sizeof(TextBox));
- if (!box) {
- ERROR("error: out of memory\n");
- exit(EXIT_FAILURE);
- }
- box->text = strdup(text);
- if (!box->text) {
- ERROR("error: out of memory\n");
- free(box);
- exit(EXIT_FAILURE);
- }
- box->x = x;
- box->y = y;
- box->textColor = color;
- box->background = background;
- box->font = font;
- box->textSize = textSize;
- textBoxUpdate(box, window);
- return box;
- }
- void textBoxDelete(TextBox *textBox) {
- free(textBox->text);
- size_t i;
- for (i = 0; i < textBox->lineCount; ++i) {
- SDL_DestroyTexture(textBox->renderedText[i]);
- }
- free(textBox->renderedText);
- free(textBox);
- }
- static void getLineSizes(TextBox *textBox, int ww, int wh, int *widths,
- int *width, int *height) {
- int yInc = textBox->textSize * wh;
- *width = 0;
- size_t i;
- for (i = 0; i < textBox->lineCount; ++i) {
- int tw, th;
- SDL_QueryTexture(textBox->renderedText[i], NULL, NULL, &tw, &th);
- int lw = ((float)tw / (float)th) * (float)yInc;
- widths[i] = lw;
- if (lw > *width) {
- *width = lw;
- }
- }
- *width += ww * TEXT_BOX_PADDING;
- *height = yInc * textBox->lineCount;
- }
- void textBoxDraw(TextBox *textBox, const Window *window) {
- int ww, wh;
- SDL_GetWindowSize(window->obj, &ww, &wh);
- int widths[textBox->lineCount];
- int bw, bh;
- getLineSizes(textBox, ww, wh, widths, &bw, &bh);
- SDL_Rect backArea = {textBox->x * ww, textBox->y * wh, bw, bh};
- if (textBox->background != NULL) {
- SDL_RenderCopy(window->render, textBox->background, NULL, &backArea);
- }
- int yInc = textBox->textSize * wh;
- size_t i;
- for (i = 0; i < textBox->lineCount; ++i) {
- int th;
- SDL_QueryTexture(textBox->renderedText[i], NULL, NULL, NULL, &th);
- SDL_Rect area = {backArea.x * (1.0f + TEXT_BOX_PADDING),
- (backArea.y * (1.0f + TEXT_BOX_PADDING)) + (yInc * i),
- widths[i] * (1.0f - (2 * TEXT_BOX_PADDING)),
- yInc * (1.0f - (2 * TEXT_BOX_PADDING))};
- SDL_RenderCopy(window->render, textBox->renderedText[i], NULL, &area);
- }
- }
- static SDL_Texture *renderLine(const char *text, const TextBox *textBox,
- const Window *window) {
- SDL_Surface *surface =
- TTF_RenderText_Blended(textBox->font, text, textBox->textColor);
- if (!surface) {
- ERROR("error: sdl2: ttf: %s\n", TTF_GetError());
- exit(EXIT_FAILURE);
- }
- SDL_Texture *texture =
- SDL_CreateTextureFromSurface(window->render, surface);
- SDL_FreeSurface(surface);
- if (!texture) {
- ERROR("error: sdl2: %s\n", SDL_GetError());
- exit(EXIT_FAILURE);
- }
- return texture;
- }
- void textBoxUpdate(TextBox *textBox, const Window *window) {
- textBox->renderedText = malloc(1);
- if (!textBox->renderedText) {
- ERROR("error: out of memory\n");
- exit(EXIT_FAILURE);
- }
- char *savePtr;
- char *line = strtok_r(textBox->text, "\n", &savePtr);
- for (textBox->lineCount = 0; line != NULL; ++textBox->lineCount) {
- textBox->renderedText =
- realloc(textBox->renderedText,
- sizeof(SDL_Texture *) * (textBox->lineCount + 1));
- if (!textBox->renderedText) {
- ERROR("error: out of memory\n");
- exit(EXIT_FAILURE);
- }
- textBox->renderedText[textBox->lineCount] =
- renderLine(line, textBox, window);
- line = strtok_r(NULL, "\n", &savePtr);
- }
- }
|