Add vendored SDL3_gfx and add header for clay SDL3 renderer

This commit is contained in:
LilyRose2798 2025-03-05 12:27:55 +11:00
parent e5e75feda6
commit cbd4068868
13 changed files with 16764 additions and 228 deletions

View file

@ -75,7 +75,13 @@ else()
message(STATUS "Unsupported platform")
endif()
target_include_directories(${PROJECT_NAME} PRIVATE "vendor")
target_include_directories(${PROJECT_NAME} PRIVATE vendor)
target_sources(${PROJECT_NAME} PRIVATE "vendor/SDL3_gfx/SDL3_framerate.c")
target_sources(${PROJECT_NAME} PRIVATE "vendor/SDL3_gfx/SDL3_gfxPrimitives.c")
target_sources(${PROJECT_NAME} PRIVATE "vendor/SDL3_gfx/SDL3_imageFilter.c")
target_sources(${PROJECT_NAME} PRIVATE "vendor/SDL3_gfx/SDL3_rotozoom.c")
target_sources(${PROJECT_NAME} PRIVATE "vendor/clay/clay_renderer_SDL3.c")
target_link_libraries(${PROJECT_NAME} PRIVATE
SDL3::SDL3-static
SDL3_ttf::SDL3_ttf-static

2
main.c
View file

@ -6,7 +6,7 @@
#define CLAY_IMPLEMENTATION
#include <clay/clay.h>
#include <clay/clay_renderer_SDL3.c>
#include <clay/clay_renderer_SDL3.h>
#include "ui/clay_video_demo.c"

189
vendor/SDL3_gfx/SDL3_framerate.c vendored Normal file
View file

@ -0,0 +1,189 @@
/*
SDL3_framerate.c: framerate manager
Copyright (C) 2012-2014 Andreas Schiffler
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.
Andreas Schiffler -- aschiffler at ferzkopp dot net
*/
#include "SDL3_framerate.h"
/*!
\brief Internal wrapper to SDL_GetTicks that ensures a non-zero return value.
\return The tick count.
*/
Uint64 _getTicks()
{
Uint64 ticks = SDL_GetTicks();
/*
* Since baseticks!=0 is used to track initialization
* we need to ensure that the tick count is always >0
* since SDL_GetTicks may not have incremented yet and
* return 0 depending on the timing of the calls.
*/
if (ticks == 0) {
return 1;
} else {
return ticks;
}
}
/*!
\brief Initialize the framerate manager.
Initialize the framerate manager, set default framerate of 30Hz and
reset delay interpolation.
\param manager Pointer to the framerate manager.
*/
void SDL_initFramerate(FPSmanager * manager)
{
/*
* Store some sane values
*/
manager->framecount = 0;
manager->rate = FPS_DEFAULT;
manager->rateticks = (1000.0f / (float) FPS_DEFAULT);
manager->baseticks = _getTicks();
manager->lastticks = manager->baseticks;
}
/*!
\brief Set the framerate in Hz
Sets a new framerate for the manager and reset delay interpolation.
Rate values must be between FPS_LOWER_LIMIT and FPS_UPPER_LIMIT inclusive to be accepted.
\param manager Pointer to the framerate manager.
\param rate The new framerate in Hz (frames per second).
\return 0 for sucess and -1 for error.
*/
int SDL_setFramerate(FPSmanager * manager, Uint32 rate)
{
if ((rate >= FPS_LOWER_LIMIT) && (rate <= FPS_UPPER_LIMIT)) {
manager->framecount = 0;
manager->rate = rate;
manager->rateticks = (1000.0f / (float) rate);
return (0);
} else {
return (-1);
}
}
/*!
\brief Return the current target framerate in Hz
Get the currently set framerate of the manager.
\param manager Pointer to the framerate manager.
\return Current framerate in Hz or -1 for error.
*/
int SDL_getFramerate(FPSmanager * manager)
{
if (manager == NULL) {
return (-1);
} else {
return ((int)manager->rate);
}
}
/*!
\brief Return the current framecount.
Get the current framecount from the framerate manager.
A frame is counted each time SDL_framerateDelay is called.
\param manager Pointer to the framerate manager.
\return Current frame count or -1 for error.
*/
int SDL_getFramecount(FPSmanager * manager)
{
if (manager == NULL) {
return (-1);
} else {
return ((int)manager->framecount);
}
}
/*!
\brief Delay execution to maintain a constant framerate and calculate fps.
Generate a delay to accomodate currently set framerate. Call once in the
graphics/rendering loop. If the computer cannot keep up with the rate (i.e.
drawing too slow), the delay is zero and the delay interpolation is reset.
\param manager Pointer to the framerate manager.
\return The time that passed since the last call to the function in ms. May return 0.
*/
Uint64 SDL_framerateDelay(FPSmanager * manager)
{
Uint64 current_ticks;
Uint64 target_ticks;
Uint64 the_delay;
Uint64 time_passed = 0;
/*
* No manager, no delay
*/
if (manager == NULL) {
return 0;
}
/*
* Initialize uninitialized manager
*/
if (manager->baseticks == 0) {
SDL_initFramerate(manager);
}
/*
* Next frame
*/
manager->framecount++;
/*
* Get/calc ticks
*/
current_ticks = _getTicks();
time_passed = current_ticks - manager->lastticks;
manager->lastticks = current_ticks;
target_ticks = manager->baseticks + (Uint64) ((float) manager->framecount * manager->rateticks);
if (current_ticks <= target_ticks) {
the_delay = target_ticks - current_ticks;
SDL_Delay(the_delay);
} else {
manager->framecount = 0;
manager->baseticks = _getTicks();
}
return time_passed;
}

100
vendor/SDL3_gfx/SDL3_framerate.h vendored Normal file
View file

@ -0,0 +1,100 @@
/*
SDL3_framerate.h: framerate manager
Copyright (C) 2012-2014 Andreas Schiffler
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.
Andreas Schiffler -- aschiffler at ferzkopp dot net
*/
#ifndef _SDL3_framerate_h
#define _SDL3_framerate_h
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/* --- */
#include <SDL3/SDL.h>
/* --------- Definitions */
/*!
\brief Highest possible rate supported by framerate controller in Hz (1/s).
*/
#define FPS_UPPER_LIMIT 200
/*!
\brief Lowest possible rate supported by framerate controller in Hz (1/s).
*/
#define FPS_LOWER_LIMIT 1
/*!
\brief Default rate of framerate controller in Hz (1/s).
*/
#define FPS_DEFAULT 30
/*!
\brief Structure holding the state and timing information of the framerate controller.
*/
typedef struct {
Uint32 framecount;
float rateticks;
Uint64 baseticks;
Uint64 lastticks;
Uint32 rate;
} FPSmanager;
/* ---- Function Prototypes */
#ifdef _MSC_VER
# if defined(DLL_EXPORT) && !defined(LIBSDL3_GFX_DLL_IMPORT)
# define SDL3_FRAMERATE_SCOPE __declspec(dllexport)
# else
# ifdef LIBSDL3_GFX_DLL_IMPORT
# define SDL3_FRAMERATE_SCOPE __declspec(dllimport)
# endif
# endif
#endif
#ifndef SDL3_FRAMERATE_SCOPE
# define SDL3_FRAMERATE_SCOPE extern
#endif
/* Functions return 0 or value for sucess and -1 for error */
SDL3_FRAMERATE_SCOPE void SDL_initFramerate(FPSmanager * manager);
SDL3_FRAMERATE_SCOPE int SDL_setFramerate(FPSmanager * manager, Uint32 rate);
SDL3_FRAMERATE_SCOPE int SDL_getFramerate(FPSmanager * manager);
SDL3_FRAMERATE_SCOPE int SDL_getFramecount(FPSmanager * manager);
SDL3_FRAMERATE_SCOPE Uint64 SDL_framerateDelay(FPSmanager * manager);
/* --- */
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* _SDL3_framerate_h */

3784
vendor/SDL3_gfx/SDL3_gfxPrimitives.c vendored Normal file

File diff suppressed because it is too large Load diff

241
vendor/SDL3_gfx/SDL3_gfxPrimitives.h vendored Normal file
View file

@ -0,0 +1,241 @@
/*
SDL3_gfxPrimitives.h: graphics primitives for SDL
Copyright (C) 2012-2014 Andreas Schiffler
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.
Andreas Schiffler -- aschiffler at ferzkopp dot net
*/
#ifndef _SDL3_gfxPrimitives_h
#define _SDL3_gfxPrimitives_h
#include <math.h>
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
#include <SDL3/SDL.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/* ----- Versioning */
#define SDL3_GFXPRIMITIVES_MAJOR 1
#define SDL3_GFXPRIMITIVES_MINOR 0
#define SDL3_GFXPRIMITIVES_MICRO 0
/* ---- Function Prototypes */
#ifdef _MSC_VER
# if defined(DLL_EXPORT) && !defined(LIBSDL3_GFX_DLL_IMPORT)
# define SDL3_GFXPRIMITIVES_SCOPE __declspec(dllexport)
# else
# ifdef LIBSDL3_GFX_DLL_IMPORT
# define SDL3_GFXPRIMITIVES_SCOPE __declspec(dllimport)
# endif
# endif
#endif
#ifndef SDL3_GFXPRIMITIVES_SCOPE
# define SDL3_GFXPRIMITIVES_SCOPE extern
#endif
/* Note: all ___Color routines expect the color to be in format 0xRRGGBBAA */
/* Pixel */
SDL3_GFXPRIMITIVES_SCOPE bool pixelColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool pixelRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Horizontal line */
SDL3_GFXPRIMITIVES_SCOPE bool hlineColor(SDL_Renderer * renderer, Sint16 x1, Sint16 x2, Sint16 y, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool hlineRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 x2, Sint16 y, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Vertical line */
SDL3_GFXPRIMITIVES_SCOPE bool vlineColor(SDL_Renderer * renderer, Sint16 x, Sint16 y1, Sint16 y2, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool vlineRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y1, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Rectangle */
SDL3_GFXPRIMITIVES_SCOPE bool rectangleColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool rectangleRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1,
Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Rounded-Corner Rectangle */
SDL3_GFXPRIMITIVES_SCOPE bool roundedRectangleColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool roundedRectangleRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1,
Sint16 x2, Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Filled rectangle (Box) */
SDL3_GFXPRIMITIVES_SCOPE bool boxColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool boxRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2,
Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Rounded-Corner Filled rectangle (Box) */
SDL3_GFXPRIMITIVES_SCOPE bool roundedBoxColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 rad, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool roundedBoxRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2,
Sint16 y2, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Line */
SDL3_GFXPRIMITIVES_SCOPE bool lineColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool lineRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1,
Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* AA Line */
SDL3_GFXPRIMITIVES_SCOPE bool aalineColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool aalineRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1,
Sint16 x2, Sint16 y2, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Thick Line */
SDL3_GFXPRIMITIVES_SCOPE bool thickLineColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,
Uint8 width, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool thickLineRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2,
Uint8 width, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Circle */
SDL3_GFXPRIMITIVES_SCOPE bool circleColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool circleRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Arc */
SDL3_GFXPRIMITIVES_SCOPE bool arcColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool arcRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Sint16 start, Sint16 end,
Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* AA Circle */
SDL3_GFXPRIMITIVES_SCOPE bool aacircleColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool aacircleRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y,
Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Filled Circle */
SDL3_GFXPRIMITIVES_SCOPE bool filledCircleColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 r, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool filledCircleRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y,
Sint16 rad, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Ellipse */
SDL3_GFXPRIMITIVES_SCOPE bool ellipseColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool ellipseRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y,
Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* AA Ellipse */
SDL3_GFXPRIMITIVES_SCOPE bool aaellipseColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool aaellipseRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y,
Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Filled Ellipse */
SDL3_GFXPRIMITIVES_SCOPE bool filledEllipseColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rx, Sint16 ry, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool filledEllipseRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y,
Sint16 rx, Sint16 ry, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Pie */
SDL3_GFXPRIMITIVES_SCOPE bool pieColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad,
Sint16 start, Sint16 end, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool pieRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad,
Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Filled Pie */
SDL3_GFXPRIMITIVES_SCOPE bool filledPieColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad,
Sint16 start, Sint16 end, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool filledPieRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, Sint16 rad,
Sint16 start, Sint16 end, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Trigon */
SDL3_GFXPRIMITIVES_SCOPE bool trigonColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool trigonRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* AA-Trigon */
SDL3_GFXPRIMITIVES_SCOPE bool aatrigonColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool aatrigonRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Filled Trigon */
SDL3_GFXPRIMITIVES_SCOPE bool filledTrigonColor(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool filledTrigonRGBA(SDL_Renderer * renderer, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, Sint16 x3, Sint16 y3,
Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Polygon */
SDL3_GFXPRIMITIVES_SCOPE bool polygonColor(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool polygonRGBA(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy,
int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* AA-Polygon */
SDL3_GFXPRIMITIVES_SCOPE bool aapolygonColor(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool aapolygonRGBA(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy,
int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Filled Polygon */
SDL3_GFXPRIMITIVES_SCOPE bool filledPolygonColor(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool filledPolygonRGBA(SDL_Renderer * renderer, const Sint16 * vx,
const Sint16 * vy, int n, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Textured Polygon */
SDL3_GFXPRIMITIVES_SCOPE bool texturedPolygon(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, SDL_Surface * texture,int texture_dx,int texture_dy);
/* Bezier */
SDL3_GFXPRIMITIVES_SCOPE bool bezierColor(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy, int n, int s, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool bezierRGBA(SDL_Renderer * renderer, const Sint16 * vx, const Sint16 * vy,
int n, int s, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Characters/Strings */
SDL3_GFXPRIMITIVES_SCOPE void gfxPrimitivesSetFont(const void *fontdata, Uint32 cw, Uint32 ch);
SDL3_GFXPRIMITIVES_SCOPE void gfxPrimitivesSetFontRotation(Uint32 rotation);
SDL3_GFXPRIMITIVES_SCOPE bool characterColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, char c, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool characterRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, char c, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
SDL3_GFXPRIMITIVES_SCOPE bool stringColor(SDL_Renderer * renderer, Sint16 x, Sint16 y, const char *s, Uint32 color);
SDL3_GFXPRIMITIVES_SCOPE bool stringRGBA(SDL_Renderer * renderer, Sint16 x, Sint16 y, const char *s, Uint8 r, Uint8 g, Uint8 b, Uint8 a);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* _SDL3_gfxPrimitives_h */

3106
vendor/SDL3_gfx/SDL3_gfxPrimitives_font.h vendored Normal file

File diff suppressed because it is too large Load diff

7371
vendor/SDL3_gfx/SDL3_imageFilter.c vendored Normal file

File diff suppressed because it is too large Load diff

166
vendor/SDL3_gfx/SDL3_imageFilter.h vendored Normal file
View file

@ -0,0 +1,166 @@
/*
SDL3_imageFilter.h: byte-image "filter" routines
Copyright (C) 2012-2014 Andreas Schiffler
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.
Andreas Schiffler -- aschiffler at ferzkopp dot net
*/
#ifndef _SDL3_imageFilter_h
#define _SDL3_imageFilter_h
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
/* ---- Function Prototypes */
#ifdef _MSC_VER
# if defined(DLL_EXPORT) && !defined(LIBSDL3_GFX_DLL_IMPORT)
# define SDL3_IMAGEFILTER_SCOPE __declspec(dllexport)
# else
# ifdef LIBSDL3_GFX_DLL_IMPORT
# define SDL3_IMAGEFILTER_SCOPE __declspec(dllimport)
# endif
# endif
#endif
#ifndef SDL3_IMAGEFILTER_SCOPE
# define SDL3_IMAGEFILTER_SCOPE extern
#endif
/* Comments: */
/* 1.) MMX functions work best if all data blocks are aligned on a 32 bytes boundary. */
/* 2.) Data that is not within an 8 byte boundary is processed using the C routine. */
/* 3.) Convolution routines do not have C routines at this time. */
// Detect MMX capability in CPU
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterMMXdetect(void);
// Force use of MMX off (or turn possible use back on)
SDL3_IMAGEFILTER_SCOPE void SDL_imageFilterMMXoff(void);
SDL3_IMAGEFILTER_SCOPE void SDL_imageFilterMMXon(void);
//
// All routines return:
// 0 OK
// -1 Error (internal error, parameter error)
//
// SDL_imageFilterAdd: D = saturation255(S1 + S2)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterAdd(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length);
// SDL_imageFilterMean: D = S1/2 + S2/2
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterMean(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length);
// SDL_imageFilterSub: D = saturation0(S1 - S2)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterSub(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length);
// SDL_imageFilterAbsDiff: D = | S1 - S2 |
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterAbsDiff(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length);
// SDL_imageFilterMult: D = saturation(S1 * S2)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterMult(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length);
// SDL_imageFilterMultNor: D = S1 * S2 (non-MMX)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterMultNor(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length);
// SDL_imageFilterMultDivby2: D = saturation255(S1/2 * S2)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterMultDivby2(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest,
unsigned int length);
// SDL_imageFilterMultDivby4: D = saturation255(S1/2 * S2/2)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterMultDivby4(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest,
unsigned int length);
// SDL_imageFilterBitAnd: D = S1 & S2
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterBitAnd(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length);
// SDL_imageFilterBitOr: D = S1 | S2
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterBitOr(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length);
// SDL_imageFilterDiv: D = S1 / S2 (non-MMX)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterDiv(unsigned char *Src1, unsigned char *Src2, unsigned char *Dest, unsigned int length);
// SDL_imageFilterBitNegation: D = !S
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterBitNegation(unsigned char *Src1, unsigned char *Dest, unsigned int length);
// SDL_imageFilterAddByte: D = saturation255(S + C)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterAddByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C);
// SDL_imageFilterAddUint: D = saturation255(S + (uint)C)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterAddUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned int C);
// SDL_imageFilterAddByteToHalf: D = saturation255(S/2 + C)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterAddByteToHalf(unsigned char *Src1, unsigned char *Dest, unsigned int length,
unsigned char C);
// SDL_imageFilterSubByte: D = saturation0(S - C)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterSubByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C);
// SDL_imageFilterSubUint: D = saturation0(S - (uint)C)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterSubUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned int C);
// SDL_imageFilterShiftRight: D = saturation0(S >> N)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterShiftRight(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N);
// SDL_imageFilterShiftRightUint: D = saturation0((uint)S >> N)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterShiftRightUint(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N);
// SDL_imageFilterMultByByte: D = saturation255(S * C)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterMultByByte(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char C);
// SDL_imageFilterShiftRightAndMultByByte: D = saturation255((S >> N) * C)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterShiftRightAndMultByByte(unsigned char *Src1, unsigned char *Dest, unsigned int length,
unsigned char N, unsigned char C);
// SDL_imageFilterShiftLeftByte: D = (S << N)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterShiftLeftByte(unsigned char *Src1, unsigned char *Dest, unsigned int length,
unsigned char N);
// SDL_imageFilterShiftLeftUint: D = ((uint)S << N)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterShiftLeftUint(unsigned char *Src1, unsigned char *Dest, unsigned int length,
unsigned char N);
// SDL_imageFilterShiftLeft: D = saturation255(S << N)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterShiftLeft(unsigned char *Src1, unsigned char *Dest, unsigned int length, unsigned char N);
// SDL_imageFilterBinarizeUsingThreshold: D = S >= T ? 255:0
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterBinarizeUsingThreshold(unsigned char *Src1, unsigned char *Dest, unsigned int length,
unsigned char T);
// SDL_imageFilterClipToRange: D = (S >= Tmin) & (S <= Tmax) 255:0
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterClipToRange(unsigned char *Src1, unsigned char *Dest, unsigned int length,
unsigned char Tmin, unsigned char Tmax);
// SDL_imageFilterNormalizeLinear: D = saturation255((Nmax - Nmin)/(Cmax - Cmin)*(S - Cmin) + Nmin)
SDL3_IMAGEFILTER_SCOPE int SDL_imageFilterNormalizeLinear(unsigned char *Src, unsigned char *Dest, unsigned int length, int Cmin,
int Cmax, int Nmin, int Nmax);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* _SDL3_imageFilter_h */

1636
vendor/SDL3_gfx/SDL3_rotozoom.c vendored Normal file

File diff suppressed because it is too large Load diff

123
vendor/SDL3_gfx/SDL3_rotozoom.h vendored Normal file
View file

@ -0,0 +1,123 @@
/*
SDL3_rotozoom.c: rotozoomer, zoomer and shrinker for 32bit or 8bit surfaces
Copyright (C) 2012-2014 Andreas Schiffler
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.
Andreas Schiffler -- aschiffler at ferzkopp dot net
*/
#ifndef _SDL3_rotozoom_h
#define _SDL3_rotozoom_h
#include <math.h>
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
#ifndef M_PI
#define M_PI 3.1415926535897932384626433832795
#endif
#include <SDL3/SDL.h>
/* ---- Defines */
/*!
\brief Disable anti-aliasing (no smoothing).
*/
#define SMOOTHING_OFF 0
/*!
\brief Enable anti-aliasing (smoothing).
*/
#define SMOOTHING_ON 1
/* ---- Function Prototypes */
#ifdef _MSC_VER
# if defined(DLL_EXPORT) && !defined(LIBSDL3_GFX_DLL_IMPORT)
# define SDL3_ROTOZOOM_SCOPE __declspec(dllexport)
# else
# ifdef LIBSDL3_GFX_DLL_IMPORT
# define SDL3_ROTOZOOM_SCOPE __declspec(dllimport)
# endif
# endif
#endif
#ifndef SDL3_ROTOZOOM_SCOPE
# define SDL3_ROTOZOOM_SCOPE extern
#endif
/*
Rotozoom functions
*/
SDL3_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurface(SDL_Surface * src, double angle, double zoom, int smooth);
SDL3_ROTOZOOM_SCOPE SDL_Surface *rotozoomSurfaceXY
(SDL_Surface * src, double angle, double zoomx, double zoomy, int smooth);
SDL3_ROTOZOOM_SCOPE void rotozoomSurfaceSize(int width, int height, double angle, double zoom, int *dstwidth,
int *dstheight);
SDL3_ROTOZOOM_SCOPE void rotozoomSurfaceSizeXY
(int width, int height, double angle, double zoomx, double zoomy,
int *dstwidth, int *dstheight);
/*
Zooming functions
*/
SDL3_ROTOZOOM_SCOPE SDL_Surface *zoomSurface(SDL_Surface * src, double zoomx, double zoomy, int smooth);
SDL3_ROTOZOOM_SCOPE void zoomSurfaceSize(int width, int height, double zoomx, double zoomy, int *dstwidth, int *dstheight);
/*
Shrinking functions
*/
SDL3_ROTOZOOM_SCOPE SDL_Surface *shrinkSurface(SDL_Surface * src, int factorx, int factory);
/*
Specialized rotation functions
*/
SDL3_ROTOZOOM_SCOPE SDL_Surface* rotateSurface90Degrees(SDL_Surface* src, int numClockwiseTurns);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#endif /* _SDL3_rotozoom_h */

View file

@ -1,247 +1,37 @@
#include "clay.h"
#include <SDL3/SDL_main.h>
#include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <SDL3_image/SDL_image.h>
#include "clay_renderer_SDL3.h"
typedef struct {
SDL_Renderer *renderer;
TTF_TextEngine *textEngine;
TTF_Font **fonts;
} Clay_SDL3RendererData;
/* Global for convenience. Even in 4K this is enough for smooth curves (low radius or rect size coupled with
* no AA or low resolution might make it appear as jagged curves) */
static int NUM_CIRCLE_SEGMENTS = 16;
//all rendering is performed by a single SDL call, avoiding multiple RenderRect + plumbing choice for circles.
static void SDL_Clay_RenderFillRoundedRect(Clay_SDL3RendererData *rendererData, const SDL_FRect rect, const float cornerRadius, const Clay_Color _color) {
const SDL_FColor color = { _color.r/255, _color.g/255, _color.b/255, _color.a/255 };
int indexCount = 0, vertexCount = 0;
const float minRadius = SDL_min(rect.w, rect.h) / 2.0f;
const float clampedRadius = SDL_min(cornerRadius, minRadius);
const int numCircleSegments = SDL_max(NUM_CIRCLE_SEGMENTS, (int) clampedRadius * 0.5f);
int totalVertices = 4 + (4 * (numCircleSegments * 2)) + 2*4;
int totalIndices = 6 + (4 * (numCircleSegments * 3)) + 6*4;
SDL_Vertex vertices[totalVertices];
int indices[totalIndices];
//define center rectangle
vertices[vertexCount++] = (SDL_Vertex){ {rect.x + clampedRadius, rect.y + clampedRadius}, color, {0, 0} }; //0 center TL
vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w - clampedRadius, rect.y + clampedRadius}, color, {1, 0} }; //1 center TR
vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w - clampedRadius, rect.y + rect.h - clampedRadius}, color, {1, 1} }; //2 center BR
vertices[vertexCount++] = (SDL_Vertex){ {rect.x + clampedRadius, rect.y + rect.h - clampedRadius}, color, {0, 1} }; //3 center BL
indices[indexCount++] = 0;
indices[indexCount++] = 1;
indices[indexCount++] = 3;
indices[indexCount++] = 1;
indices[indexCount++] = 2;
indices[indexCount++] = 3;
//define rounded corners as triangle fans
const float step = (SDL_PI_F/2) / numCircleSegments;
for (int i = 0; i < numCircleSegments; i++) {
const float angle1 = (float)i * step;
const float angle2 = ((float)i + 1.0f) * step;
for (int j = 0; j < 4; j++) { // Iterate over four corners
float cx, cy, signX, signY;
switch (j) {
case 0: cx = rect.x + clampedRadius; cy = rect.y + clampedRadius; signX = -1; signY = -1; break; // Top-left
case 1: cx = rect.x + rect.w - clampedRadius; cy = rect.y + clampedRadius; signX = 1; signY = -1; break; // Top-right
case 2: cx = rect.x + rect.w - clampedRadius; cy = rect.y + rect.h - clampedRadius; signX = 1; signY = 1; break; // Bottom-right
case 3: cx = rect.x + clampedRadius; cy = rect.y + rect.h - clampedRadius; signX = -1; signY = 1; break; // Bottom-left
default: return;
}
vertices[vertexCount++] = (SDL_Vertex){ {cx + SDL_cosf(angle1) * clampedRadius * signX, cy + SDL_sinf(angle1) * clampedRadius * signY}, color, {0, 0} };
vertices[vertexCount++] = (SDL_Vertex){ {cx + SDL_cosf(angle2) * clampedRadius * signX, cy + SDL_sinf(angle2) * clampedRadius * signY}, color, {0, 0} };
indices[indexCount++] = j; // Connect to corresponding central rectangle vertex
indices[indexCount++] = vertexCount - 2;
indices[indexCount++] = vertexCount - 1;
}
}
//Define edge rectangles
// Top edge
vertices[vertexCount++] = (SDL_Vertex){ {rect.x + clampedRadius, rect.y}, color, {0, 0} }; //TL
vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w - clampedRadius, rect.y}, color, {1, 0} }; //TR
indices[indexCount++] = 0;
indices[indexCount++] = vertexCount - 2; //TL
indices[indexCount++] = vertexCount - 1; //TR
indices[indexCount++] = 1;
indices[indexCount++] = 0;
indices[indexCount++] = vertexCount - 1; //TR
// Right edge
vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w, rect.y + clampedRadius}, color, {1, 0} }; //RT
vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w, rect.y + rect.h - clampedRadius}, color, {1, 1} }; //RB
indices[indexCount++] = 1;
indices[indexCount++] = vertexCount - 2; //RT
indices[indexCount++] = vertexCount - 1; //RB
indices[indexCount++] = 2;
indices[indexCount++] = 1;
indices[indexCount++] = vertexCount - 1; //RB
// Bottom edge
vertices[vertexCount++] = (SDL_Vertex){ {rect.x + rect.w - clampedRadius, rect.y + rect.h}, color, {1, 1} }; //BR
vertices[vertexCount++] = (SDL_Vertex){ {rect.x + clampedRadius, rect.y + rect.h}, color, {0, 1} }; //BL
indices[indexCount++] = 2;
indices[indexCount++] = vertexCount - 2; //BR
indices[indexCount++] = vertexCount - 1; //BL
indices[indexCount++] = 3;
indices[indexCount++] = 2;
indices[indexCount++] = vertexCount - 1; //BL
// Left edge
vertices[vertexCount++] = (SDL_Vertex){ {rect.x, rect.y + rect.h - clampedRadius}, color, {0, 1} }; //LB
vertices[vertexCount++] = (SDL_Vertex){ {rect.x, rect.y + clampedRadius}, color, {0, 0} }; //LT
indices[indexCount++] = 3;
indices[indexCount++] = vertexCount - 2; //LB
indices[indexCount++] = vertexCount - 1; //LT
indices[indexCount++] = 0;
indices[indexCount++] = 3;
indices[indexCount++] = vertexCount - 1; //LT
// Render everything
SDL_RenderGeometry(rendererData->renderer, NULL, vertices, vertexCount, indices, indexCount);
}
static void SDL_Clay_RenderArc(Clay_SDL3RendererData *rendererData, const SDL_FPoint center, const float radius, const float startAngle, const float endAngle, const float thickness, const Clay_Color color) {
SDL_SetRenderDrawColor(rendererData->renderer, color.r, color.g, color.b, color.a);
const float radStart = startAngle * (SDL_PI_F / 180.0f);
const float radEnd = endAngle * (SDL_PI_F / 180.0f);
const int numCircleSegments = SDL_max(NUM_CIRCLE_SEGMENTS, (int)(radius * 1.5f)); //increase circle segments for larger circles, 1.5 is arbitrary.
const float angleStep = (radEnd - radStart) / (float)numCircleSegments;
const float thicknessStep = 0.4f; //arbitrary value to avoid overlapping lines. Changing THICKNESS_STEP or numCircleSegments might cause artifacts.
for (float t = thicknessStep; t < thickness - thicknessStep; t += thicknessStep) {
SDL_FPoint points[numCircleSegments + 1];
const float clampedRadius = SDL_max(radius - t, 1.0f);
for (int i = 0; i <= numCircleSegments; i++) {
const float angle = radStart + i * angleStep;
points[i] = (SDL_FPoint){
SDL_roundf(center.x + SDL_cosf(angle) * clampedRadius),
SDL_roundf(center.y + SDL_sinf(angle) * clampedRadius) };
}
SDL_RenderLines(rendererData->renderer, points, numCircleSegments + 1);
}
}
SDL_Rect currentClippingRectangle;
static void SDL_Clay_RenderClayCommands(Clay_SDL3RendererData *rendererData, Clay_RenderCommandArray *rcommands)
{
void SDL_Clay_RenderClayCommands(Clay_SDL3RendererData *rendererData, Clay_RenderCommandArray *rcommands) {
for (size_t i = 0; i < rcommands->length; i++) {
Clay_RenderCommand *rcmd = Clay_RenderCommandArray_Get(rcommands, i);
const Clay_BoundingBox bounding_box = rcmd->boundingBox;
const SDL_FRect rect = { (int)bounding_box.x, (int)bounding_box.y, (int)bounding_box.width, (int)bounding_box.height };
switch (rcmd->commandType) {
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
Clay_RectangleRenderData *config = &rcmd->renderData.rectangle;
SDL_SetRenderDrawBlendMode(rendererData->renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(rendererData->renderer, config->backgroundColor.r, config->backgroundColor.g, config->backgroundColor.b, config->backgroundColor.a);
if (config->cornerRadius.topLeft > 0) {
SDL_Clay_RenderFillRoundedRect(rendererData, rect, config->cornerRadius.topLeft, config->backgroundColor);
} else {
SDL_RenderFillRect(rendererData->renderer, &rect);
}
roundedBoxRGBA(rendererData->renderer, bounding_box.x, bounding_box.y,
bounding_box.x + bounding_box.width, bounding_box.y + bounding_box.height, config->cornerRadius.topLeft,
config->backgroundColor.r, config->backgroundColor.g, config->backgroundColor.b, config->backgroundColor.a);
} break;
case CLAY_RENDER_COMMAND_TYPE_TEXT: {
Clay_TextRenderData *config = &rcmd->renderData.text;
TTF_Font *font = rendererData->fonts[config->fontId];
TTF_Text *text = TTF_CreateText(rendererData->textEngine, font, config->stringContents.chars, config->stringContents.length);
TTF_SetTextColor(text, config->textColor.r, config->textColor.g, config->textColor.b, config->textColor.a);
TTF_DrawRendererText(text, rect.x, rect.y);
TTF_DrawRendererText(text, bounding_box.x, bounding_box.y);
TTF_DestroyText(text);
} break;
case CLAY_RENDER_COMMAND_TYPE_BORDER: {
Clay_BorderRenderData *config = &rcmd->renderData.border;
const float minRadius = SDL_min(rect.w, rect.h) / 2.0f;
const Clay_CornerRadius clampedRadii = {
.topLeft = SDL_min(config->cornerRadius.topLeft, minRadius),
.topRight = SDL_min(config->cornerRadius.topRight, minRadius),
.bottomLeft = SDL_min(config->cornerRadius.bottomLeft, minRadius),
.bottomRight = SDL_min(config->cornerRadius.bottomRight, minRadius)
};
//edges
SDL_SetRenderDrawColor(rendererData->renderer, config->color.r, config->color.g, config->color.b, config->color.a);
if (config->width.left > 0) {
const float starting_y = rect.y + clampedRadii.topLeft;
const float length = rect.h - clampedRadii.topLeft - clampedRadii.bottomLeft;
SDL_FRect line = { rect.x, starting_y, config->width.left, length };
SDL_RenderFillRect(rendererData->renderer, &line);
}
if (config->width.right > 0) {
const float starting_x = rect.x + rect.w - (float)config->width.right;
const float starting_y = rect.y + clampedRadii.topRight;
const float length = rect.h - clampedRadii.topRight - clampedRadii.bottomRight;
SDL_FRect line = { starting_x, starting_y, config->width.right, length };
SDL_RenderFillRect(rendererData->renderer, &line);
}
if (config->width.top > 0) {
const float starting_x = rect.x + clampedRadii.topLeft;
const float length = rect.w - clampedRadii.topLeft - clampedRadii.topRight;
SDL_FRect line = { starting_x, rect.y, length, config->width.top };
SDL_RenderFillRect(rendererData->renderer, &line);
}
if (config->width.bottom > 0) {
const float starting_x = rect.x + clampedRadii.bottomLeft;
const float starting_y = rect.y + rect.h - (float)config->width.bottom;
const float length = rect.w - clampedRadii.bottomLeft - clampedRadii.bottomRight;
SDL_FRect line = { starting_x, starting_y, length, config->width.bottom };
SDL_SetRenderDrawColor(rendererData->renderer, config->color.r, config->color.g, config->color.b, config->color.a);
SDL_RenderFillRect(rendererData->renderer, &line);
}
//corners
if (config->cornerRadius.topLeft > 0) {
const float centerX = rect.x + clampedRadii.topLeft -1;
const float centerY = rect.y + clampedRadii.topLeft;
SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.topLeft,
180.0f, 270.0f, config->width.top, config->color);
}
if (config->cornerRadius.topRight > 0) {
const float centerX = rect.x + rect.w - clampedRadii.topRight -1;
const float centerY = rect.y + clampedRadii.topRight;
SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.topRight,
270.0f, 360.0f, config->width.top, config->color);
}
if (config->cornerRadius.bottomLeft > 0) {
const float centerX = rect.x + clampedRadii.bottomLeft -1;
const float centerY = rect.y + rect.h - clampedRadii.bottomLeft -1;
SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.bottomLeft,
90.0f, 180.0f, config->width.bottom, config->color);
}
if (config->cornerRadius.bottomRight > 0) {
const float centerX = rect.x + rect.w - clampedRadii.bottomRight -1; //TODO: why need to -1 in all calculations???
const float centerY = rect.y + rect.h - clampedRadii.bottomRight -1;
SDL_Clay_RenderArc(rendererData, (SDL_FPoint){centerX, centerY}, clampedRadii.bottomRight,
0.0f, 90.0f, config->width.bottom, config->color);
}
roundedRectangleRGBA(rendererData->renderer, bounding_box.x, bounding_box.y,
bounding_box.x + bounding_box.width, bounding_box.y + bounding_box.height, config->cornerRadius.topLeft,
config->color.r, config->color.g, config->color.b, config->color.a);
} break;
case CLAY_RENDER_COMMAND_TYPE_SCISSOR_START: {
Clay_BoundingBox boundingBox = rcmd->boundingBox;
currentClippingRectangle = (SDL_Rect) {
.x = boundingBox.x,
.y = boundingBox.y,
.w = boundingBox.width,
.h = boundingBox.height,
const SDL_Rect currentClippingRectangle = (SDL_Rect) {
.x = bounding_box.x,
.y = bounding_box.y,
.w = bounding_box.width,
.h = bounding_box.height,
};
SDL_SetRenderClipRect(rendererData->renderer, &currentClippingRectangle);
break;
@ -253,8 +43,12 @@ static void SDL_Clay_RenderClayCommands(Clay_SDL3RendererData *rendererData, Cla
case CLAY_RENDER_COMMAND_TYPE_IMAGE: {
SDL_Surface *image = (SDL_Surface *)rcmd->renderData.image.imageData;
SDL_Texture *texture = SDL_CreateTextureFromSurface(rendererData->renderer, image);
const SDL_FRect dest = { rect.x, rect.y, rect.w, rect.h };
const SDL_FRect dest = (SDL_FRect) {
.x = bounding_box.x,
.y = bounding_box.y,
.w = bounding_box.width,
.h = bounding_box.height,
};
SDL_RenderTexture(rendererData->renderer, texture, NULL, &dest);
SDL_DestroyTexture(texture);
break;

20
vendor/clay/clay_renderer_SDL3.h vendored Normal file
View file

@ -0,0 +1,20 @@
#ifndef _clay_renderer_SDL3_h
#define _clay_renderer_SDL3_h
#include <SDL3/SDL_main.h>
#include <SDL3/SDL.h>
#include <SDL3_ttf/SDL_ttf.h>
#include <SDL3_image/SDL_image.h>
#include <SDL3_gfx/SDL3_gfxPrimitives.h>
#include "clay.h"
typedef struct {
SDL_Renderer *renderer;
TTF_TextEngine *textEngine;
TTF_Font **fonts;
} Clay_SDL3RendererData;
void SDL_Clay_RenderClayCommands(Clay_SDL3RendererData *rendererData, Clay_RenderCommandArray *rcommands);
#endif