[Renderers/Tigr] Added text scaling and header file

This should make it easier to integrate into projects
This commit is contained in:
Noah Breedy 2026-06-24 14:14:16 -04:00
parent 4b12d41dd2
commit 43882c6994
4 changed files with 132 additions and 75 deletions

View file

@ -1,74 +1,7 @@
// Copyright (c) 2024 Justin Andreas Lacoste (@27justin)
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the
// use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software in a
// product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
// SPDX-License-Identifier: Zlib
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../../clay.h"
#include "tigr.h"
#include "utils.h" // for our rounded borders
// Render the command queue to the `Tigr*` instance provided
void Clay_Tigr_Render(Clay_RenderCommandArray commands, Tigr* ctx);
#include "clay_renderer_tigr.h"
#define CLAY_TO_TPIXEL(color) (TPixel){color.r, color.g, color.b, color.a}
/* Return a null-terminated copy of Clay_String `str`
* caller is required to free
* */
static inline char *Clay_to_Cstr(Clay_String *str) {
char* copy = (char*) malloc(str->length + 1);
if (!copy) {
fprintf(stderr, "Memory allocation failed\n");
return NULL;
}
memcpy(copy, str->chars, str->length);
copy[str->length] = '\0';
return copy;
}
// Measure text using built-in Tigr functions
static inline Clay_Dimensions Clay_Tigr_MeasureText(Clay_StringSlice str, Clay_TextElementConfig *config, void *userData) {
Clay_String toTerminate = (Clay_String){ .chars = str.chars, .length = str.length, .isStaticallyAllocated = false };
char* cstr = Clay_to_Cstr(&toTerminate);
int text_width = tigrTextWidth(tfont, cstr);
int text_height = tigrTextHeight(tfont, cstr);
free(cstr);
// Return dimensions
return (Clay_Dimensions){
.width = (float)text_width,
.height = (float)text_height
};
}
void Clay_Tigr_Render(Clay_RenderCommandArray commands, Tigr* ctx) {
for(size_t i = 0; i < commands.length; i++) {
Clay_RenderCommand *command = Clay_RenderCommandArray_Get(&commands, i);
@ -92,9 +25,19 @@ void Clay_Tigr_Render(Clay_RenderCommandArray commands, Tigr* ctx) {
Clay_BoundingBox bb = command->boundingBox;
Clay_Color color = config->textColor;
//cairo_set_font_size(cr, config->fontSize);
tigrPrint(ctx, tfont, bb.x, bb.y, CLAY_TO_TPIXEL(color), text);
float scale = config->fontSize / 8.0f; // tfont is roughly 8px high
Tigr* temp = tigrBitmap(
tigrTextWidth(tfont, text),
tfont->glyphs->h
);
tigrClear(temp, tigrRGBA(0,0,0,0));
tigrPrint(temp, tfont, 0, 0, CLAY_TO_TPIXEL(color), text);
tigrBlitScale(ctx, temp, bb.x, bb.y, 0, 0, temp->w, temp->h, temp->w * scale, temp->h * scale);
tigrFree(temp);
free(text);
break;
}
@ -105,7 +48,7 @@ void Clay_Tigr_Render(Clay_RenderCommandArray commands, Tigr* ctx) {
int box_radius = config->cornerRadius.topLeft;
tigrArcRect(ctx, bb.x, bb.y, bb.width, bb.height, box_radius, CLAY_TO_TPIXEL(config->color));
break;
}
case CLAY_RENDER_COMMAND_TYPE_IMAGE: {

View file

@ -0,0 +1,75 @@
// Copyright (c) 2026 Noah Arthur Breedy
//
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the
// use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it
// freely, subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented; you must not
// claim that you wrote the original software. If you use this software in a
// product, an acknowledgment in the product documentation would be
// appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such, and must not
// be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source
// distribution.
//
// SPDX-License-Identifier: Zlib
#ifndef __CLAY_TIGR_RENDERER_H__
#define __CLAY_TIGR_RENDERER_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "../../clay.h"
#include "tigr.h"
#include "tigr_utils.h" // for our rounded borders
#define CLAY_TO_TPIXEL(color) (TPixel){color.r, color.g, color.b, color.a}
/* Render the command queue to the `Tigr*` instance provided */
void Clay_Tigr_Render(Clay_RenderCommandArray commands, Tigr* ctx);
/* Return a null-terminated copy of Clay_String `str`
* caller is required to free
* */
static inline char *Clay_to_Cstr(Clay_String *str) {
char* copy = (char*) malloc(str->length + 1);
if (!copy) {
fprintf(stderr, "Memory allocation failed\n");
return NULL;
}
memcpy(copy, str->chars, str->length);
copy[str->length] = '\0';
return copy;
}
/* Measure text using built-in Tigr functions */
static inline Clay_Dimensions Clay_Tigr_MeasureText(Clay_StringSlice str, Clay_TextElementConfig *config, void *userData) {
Clay_String toTerminate = (Clay_String){ .chars = str.chars, .length = str.length, .isStaticallyAllocated = false };
char* cstr = Clay_to_Cstr(&toTerminate);
int text_width = tigrTextWidth(tfont, cstr);
int text_height = tigrTextHeight(tfont, cstr);
free(cstr);
// Return dimensions
return (Clay_Dimensions){
.width = (float)text_width,
.height = (float)text_height
};
}
#endif /* __CLAY_TIGR_RENDERER_H__ */

View file

@ -1,6 +1,4 @@
#include <math.h>
#include "utils.h"
#include "tigr_utils.h"
enum ARC_STATES {
NOT_DRAWN,
@ -172,6 +170,39 @@ void tigrFillArcRect(Tigr* ctx, int x, int y, int w, int h, int r, TPixel col) {
}
/* ChatGPT generated blitScale function */
void tigrBlitScale(Tigr* dst, Tigr* src, int dx, int dy, int sx, int sy, int sw, int sh, int dw, int dh) {
for(int y = 0; y < dh; y++)
{
int srcY = sy + (y * sh) / dh;
if(srcY < 0 || srcY >= src->h)
continue;
int dstY = dy + y;
if(dstY < 0 || dstY >= dst->h)
continue;
for(int x = 0; x < dw; x++)
{
int srcX = sx + (x * sw) / dw;
if(srcX < 0 || srcX >= src->w)
continue;
int dstX = dx + x;
if(dstX < 0 || dstX >= dst->w)
continue;
TPixel p = src->pix[srcY * src->w + srcX];
/* Skip transparent pixels */
if(p.a == 0)
continue;
tigrPlot(dst, dstX, dstY, p);
}
}
}

View file

@ -1,4 +1,7 @@
#pragma once
#ifndef __TIGR_UTILS_H__
#define __TIGR_UTILS_H__
#include <math.h>
#include "tigr.h"
@ -21,3 +24,8 @@ void tigrArcRect(Tigr* ctx, int x, int y, int w, int h, int r, TPixel col);
* This is the filled one
*/
void tigrFillArcRect(Tigr* ctx, int x, int y, int w, int h, int r, TPixel col);
/* ChatGPT generated blitScale function */
void tigrBlitScale(Tigr* dst, Tigr* src, int dx, int dy, int sx, int sy, int sw, int sh, int dw, int dh);
#endif /* __TIGR_UTILS_H__ */