mirror of
https://github.com/nicbarker/clay.git
synced 2025-09-18 12:36:17 +00:00
updated to simulate setup with multiple fonts
This commit is contained in:
parent
749d1bb7de
commit
b06f5ec400
|
@ -1,5 +1,6 @@
|
||||||
|
|
||||||
#include "pd_api.h"
|
#include "pd_api.h"
|
||||||
|
#include "pd_api/pd_api_gfx.h"
|
||||||
#define CLAY_IMPLEMENTATION
|
#define CLAY_IMPLEMENTATION
|
||||||
#include "../../clay.h"
|
#include "../../clay.h"
|
||||||
|
|
||||||
|
@ -7,28 +8,27 @@
|
||||||
#include "clay-video-demo-playdate.c"
|
#include "clay-video-demo-playdate.c"
|
||||||
|
|
||||||
static int update(void *userdata);
|
static int update(void *userdata);
|
||||||
const char *fontpath = "/System/Fonts/Asheville-Sans-14-Bold.pft";
|
const char *fontPath = "/System/Fonts/Asheville-Sans-14-Bold.pft";
|
||||||
LCDFont *font = NULL;
|
|
||||||
|
|
||||||
void HandleClayErrors(Clay_ErrorData errorData) {}
|
void HandleClayErrors(Clay_ErrorData errorData) {}
|
||||||
|
|
||||||
struct TextUserData {
|
struct TextUserData {
|
||||||
LCDFont *font;
|
LCDFont *font[1];
|
||||||
PlaydateAPI *pd;
|
PlaydateAPI *pd;
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct TextUserData testUserData = {.font = NULL, .pd = NULL};
|
static struct TextUserData textUserData = {.font = {NULL, NULL}, .pd = NULL};
|
||||||
|
|
||||||
static Clay_Dimensions PlayDate_MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, void *userData) {
|
static Clay_Dimensions PlayDate_MeasureText(Clay_StringSlice text, Clay_TextElementConfig *config, void *userData) {
|
||||||
struct TextUserData *textUserData = userData;
|
struct TextUserData *textUserData = userData;
|
||||||
int width = textUserData->pd->graphics->getTextWidth(
|
int width = textUserData->pd->graphics->getTextWidth(
|
||||||
textUserData->font,
|
textUserData->font[config->fontId],
|
||||||
text.chars,
|
text.chars,
|
||||||
utf8_count_codepoints(text.chars, text.length),
|
utf8_count_codepoints(text.chars, text.length),
|
||||||
kUTF8Encoding,
|
kUTF8Encoding,
|
||||||
0
|
0
|
||||||
);
|
);
|
||||||
int height = textUserData->pd->graphics->getFontHeight(textUserData->font);
|
int height = textUserData->pd->graphics->getFontHeight(textUserData->font[config->fontId]);
|
||||||
return (Clay_Dimensions){
|
return (Clay_Dimensions){
|
||||||
.width = (float)width,
|
.width = (float)width,
|
||||||
.height = (float)height,
|
.height = (float)height,
|
||||||
|
@ -42,14 +42,13 @@ int eventHandler(PlaydateAPI* pd, PDSystemEvent event, uint32_t eventArg)
|
||||||
{
|
{
|
||||||
if (event == kEventInit) {
|
if (event == kEventInit) {
|
||||||
const char *err;
|
const char *err;
|
||||||
font = pd->graphics->loadFont(fontpath, &err);
|
textUserData.font[0] = pd->graphics->loadFont(fontPath, &err);
|
||||||
|
|
||||||
if (font == NULL) {
|
if (textUserData.font[0] == NULL) {
|
||||||
pd->system->error("%s:%i Couldn't load font %s: %s", __FILE__, __LINE__, fontpath, err);
|
pd->system->error("%s:%i Couldn't load font %s: %s", __FILE__, __LINE__, fontPath, err);
|
||||||
}
|
}
|
||||||
|
|
||||||
testUserData.pd = pd;
|
textUserData.pd = pd;
|
||||||
testUserData.font = font;
|
|
||||||
pd->system->setUpdateCallback(update, pd);
|
pd->system->setUpdateCallback(update, pd);
|
||||||
|
|
||||||
uint64_t totalMemorySize = Clay_MinMemorySize();
|
uint64_t totalMemorySize = Clay_MinMemorySize();
|
||||||
|
@ -59,7 +58,7 @@ int eventHandler(PlaydateAPI* pd, PDSystemEvent event, uint32_t eventArg)
|
||||||
(Clay_Dimensions){(float)pd->display->getWidth(), (float)pd->display->getHeight()},
|
(Clay_Dimensions){(float)pd->display->getWidth(), (float)pd->display->getHeight()},
|
||||||
(Clay_ErrorHandler){HandleClayErrors}
|
(Clay_ErrorHandler){HandleClayErrors}
|
||||||
);
|
);
|
||||||
Clay_SetMeasureTextFunction(PlayDate_MeasureText, &testUserData);
|
Clay_SetMeasureTextFunction(PlayDate_MeasureText, &textUserData);
|
||||||
ClayVideoDemo_Initialize();
|
ClayVideoDemo_Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +80,6 @@ static int update(void *userdata) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pd->graphics->clear(kColorWhite);
|
pd->graphics->clear(kColorWhite);
|
||||||
pd->graphics->setFont(font);
|
|
||||||
|
|
||||||
// A bit hacky, setting the cursor on to the document view so it can be
|
// A bit hacky, setting the cursor on to the document view so it can be
|
||||||
// scrolled..
|
// scrolled..
|
||||||
|
@ -97,7 +95,7 @@ static int update(void *userdata) {
|
||||||
);
|
);
|
||||||
Clay_RenderCommandArray renderCommands = ClayVideoDemo_CreateLayout(selectedDocumentIndex);
|
Clay_RenderCommandArray renderCommands = ClayVideoDemo_CreateLayout(selectedDocumentIndex);
|
||||||
|
|
||||||
Clay_Playdate_Render(pd, renderCommands, font);
|
Clay_Playdate_Render(pd, renderCommands, textUserData.font);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,15 @@
|
||||||
#include "../../clay.h"
|
|
||||||
#include "pd_api.h"
|
#include "pd_api.h"
|
||||||
|
|
||||||
#define MIN(a, b) ((a) < (b) ? (a) : (b))
|
#include "../../clay.h"
|
||||||
#define MAX(a, b) ((a) > (b) ? (a) : (b))
|
|
||||||
|
|
||||||
struct Rect {
|
struct Clay_Playdate_Rect {
|
||||||
float x;
|
float x;
|
||||||
float y;
|
float y;
|
||||||
float w;
|
float w;
|
||||||
float h;
|
float h;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Playdate drawText function expects the number of codepoints to draw, not byte length
|
||||||
static size_t utf8_count_codepoints(const char *str, size_t byte_len) {
|
static size_t utf8_count_codepoints(const char *str, size_t byte_len) {
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
@ -27,38 +26,37 @@ static size_t utf8_count_codepoints(const char *str, size_t byte_len) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// As the playdate can only display black and white, we need to resolve Clay_color to either black or white
|
||||||
|
// for both color and draw mode.
|
||||||
|
// TODO: Convert to grayscale and then map the grayscale value to different dithering patterns
|
||||||
static LCDColor clayColorToLCDColor(Clay_Color color) {
|
static LCDColor clayColorToLCDColor(Clay_Color color) {
|
||||||
// Convert the RGB to grayscale using the standard luminance formula
|
if (color.r > 0 || color.g > 0 || color.b > 0) {
|
||||||
unsigned char grayscale_value = (unsigned char)(0.299 * color.r + 0.587 * color.g + 0.114 * color.b);
|
|
||||||
|
|
||||||
if (grayscale_value > 128) {
|
|
||||||
return kColorWhite;
|
return kColorWhite;
|
||||||
}
|
}
|
||||||
return kColorBlack;
|
return kColorBlack;
|
||||||
}
|
}
|
||||||
|
|
||||||
static LCDBitmapDrawMode clayColorToDrawMode(Clay_Color color) {
|
static LCDBitmapDrawMode clayColorToDrawMode(Clay_Color color) {
|
||||||
|
if (color.r > 0 || color.g > 0 || color.b > 0) {
|
||||||
if (color.r == 255 && color.g == 255 && color.b == 255) {
|
|
||||||
return kDrawModeFillWhite;
|
return kDrawModeFillWhite;
|
||||||
}
|
}
|
||||||
return kDrawModeCopy;
|
return kDrawModeCopy;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Clay_Playdate_Render(PlaydateAPI *pd, Clay_RenderCommandArray renderCommands, LCDFont *fonts) {
|
static void Clay_Playdate_Render(PlaydateAPI *pd, Clay_RenderCommandArray renderCommands, LCDFont **fonts) {
|
||||||
|
|
||||||
for (uint32_t i = 0; i < renderCommands.length; i++) {
|
for (uint32_t i = 0; i < renderCommands.length; i++) {
|
||||||
Clay_RenderCommand *renderCommand = Clay_RenderCommandArray_Get(&renderCommands, i);
|
Clay_RenderCommand *renderCommand = Clay_RenderCommandArray_Get(&renderCommands, i);
|
||||||
Clay_BoundingBox boundingBox = renderCommand->boundingBox;
|
Clay_BoundingBox boundingBox = renderCommand->boundingBox;
|
||||||
switch (renderCommand->commandType) {
|
switch (renderCommand->commandType) {
|
||||||
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
|
case CLAY_RENDER_COMMAND_TYPE_RECTANGLE: {
|
||||||
Clay_RectangleRenderData *config = &renderCommand->renderData.rectangle;
|
Clay_RectangleRenderData *config = &renderCommand->renderData.rectangle;
|
||||||
struct Rect rect = (struct Rect){
|
struct Clay_Playdate_Rect rect = (struct Clay_Playdate_Rect){
|
||||||
.x = boundingBox.x,
|
.x = boundingBox.x,
|
||||||
.y = boundingBox.y,
|
.y = boundingBox.y,
|
||||||
.w = boundingBox.width,
|
.w = boundingBox.width,
|
||||||
.h = boundingBox.height,
|
.h = boundingBox.height,
|
||||||
};
|
};
|
||||||
|
// TODO: support different radius for each corner like clay API allows
|
||||||
if (config->cornerRadius.topLeft > 0) {
|
if (config->cornerRadius.topLeft > 0) {
|
||||||
pd->graphics->fillRoundRect(
|
pd->graphics->fillRoundRect(
|
||||||
rect.x, rect.y, rect.w, rect.h,
|
rect.x, rect.y, rect.w, rect.h,
|
||||||
|
@ -66,18 +64,18 @@ static void Clay_Playdate_Render(PlaydateAPI *pd, Clay_RenderCommandArray render
|
||||||
clayColorToLCDColor(config->backgroundColor)
|
clayColorToLCDColor(config->backgroundColor)
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
pd->graphics->fillRect(rect.x, rect.y, rect.w, rect.h,
|
pd->graphics->fillRect(
|
||||||
clayColorToLCDColor(config->backgroundColor));
|
rect.x, rect.y, rect.w, rect.h,
|
||||||
|
clayColorToLCDColor(config->backgroundColor)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CLAY_RENDER_COMMAND_TYPE_TEXT: {
|
case CLAY_RENDER_COMMAND_TYPE_TEXT: {
|
||||||
Clay_TextRenderData *config = &renderCommand->renderData.text;
|
Clay_TextRenderData *config = &renderCommand->renderData.text;
|
||||||
// LCDFont *font = fonts[config->fontId];
|
LCDFont *font = fonts[config->fontId];
|
||||||
// TODO: support loading more than 1 font and use the fonts that clay
|
pd->graphics->setFont(font);
|
||||||
// layout has..
|
struct Clay_Playdate_Rect destination = (struct Clay_Playdate_Rect){
|
||||||
LCDFont *font = fonts;
|
|
||||||
struct Rect destination = (struct Rect){
|
|
||||||
.x = boundingBox.x,
|
.x = boundingBox.x,
|
||||||
.y = boundingBox.y,
|
.y = boundingBox.y,
|
||||||
.w = boundingBox.width,
|
.w = boundingBox.width,
|
||||||
|
@ -98,7 +96,7 @@ static void Clay_Playdate_Render(PlaydateAPI *pd, Clay_RenderCommandArray render
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CLAY_RENDER_COMMAND_TYPE_SCISSOR_START: {
|
case CLAY_RENDER_COMMAND_TYPE_SCISSOR_START: {
|
||||||
struct Rect currentClippingRectangle = (struct Rect){
|
struct Clay_Playdate_Rect currentClippingRectangle = (struct Clay_Playdate_Rect){
|
||||||
.x = boundingBox.x,
|
.x = boundingBox.x,
|
||||||
.y = boundingBox.y,
|
.y = boundingBox.y,
|
||||||
.w = boundingBox.width,
|
.w = boundingBox.width,
|
||||||
|
@ -117,7 +115,7 @@ static void Clay_Playdate_Render(PlaydateAPI *pd, Clay_RenderCommandArray render
|
||||||
case CLAY_RENDER_COMMAND_TYPE_IMAGE: {
|
case CLAY_RENDER_COMMAND_TYPE_IMAGE: {
|
||||||
Clay_ImageRenderData *config = &renderCommand->renderData.image;
|
Clay_ImageRenderData *config = &renderCommand->renderData.image;
|
||||||
LCDBitmap *texture = config->imageData;
|
LCDBitmap *texture = config->imageData;
|
||||||
struct Rect destination = (struct Rect){
|
struct Clay_Playdate_Rect destination = (struct Clay_Playdate_Rect){
|
||||||
.x = boundingBox.x,
|
.x = boundingBox.x,
|
||||||
.y = boundingBox.y,
|
.y = boundingBox.y,
|
||||||
.w = boundingBox.width,
|
.w = boundingBox.width,
|
||||||
|
@ -128,7 +126,7 @@ static void Clay_Playdate_Render(PlaydateAPI *pd, Clay_RenderCommandArray render
|
||||||
}
|
}
|
||||||
case CLAY_RENDER_COMMAND_TYPE_BORDER: {
|
case CLAY_RENDER_COMMAND_TYPE_BORDER: {
|
||||||
Clay_BorderRenderData *config = &renderCommand->renderData.border;
|
Clay_BorderRenderData *config = &renderCommand->renderData.border;
|
||||||
struct Rect rect = (struct Rect){
|
struct Clay_Playdate_Rect rect = (struct Clay_Playdate_Rect){
|
||||||
.x = boundingBox.x,
|
.x = boundingBox.x,
|
||||||
.y = boundingBox.y,
|
.y = boundingBox.y,
|
||||||
.w = boundingBox.width,
|
.w = boundingBox.width,
|
||||||
|
|
Loading…
Reference in a new issue