TeX/src/platform/sdl2.c

198 lines
4.1 KiB
C

//---
// SDL interface: for rendering tests on computer
//---
#ifdef TEX_PLATFORM_SDL
#include <SDL2/SDL.h>
#include <stdlib.h>
#include <TeX/TeX.h>
#include <TeX/parser.h>
/* Rendering window and renderer */
static SDL_Window *w = NULL;
static SDL_Renderer *r = NULL;
/* Font surface */
static SDL_Texture *font = NULL;
/* Font configuration */
#define FONT_SIZE 1
#if FONT_SIZE==1
#define FONT_FILE "font5x7.bmp"
#define FONT_WIDTH 5
#define FONT_HEIGHT 7
#define FONT_OUTER 1
#define FONT_INNER 2
#define FONT_OFFSET 0
#endif
#if FONT_SIZE==2
#define FONT_FILE "font8x9.bmp"
#define FONT_WIDTH 8
#define FONT_HEIGHT 9
#define FONT_OUTER 2
#define FONT_INNER 2
#define FONT_OFFSET 32
#endif
#if FONT_SIZE==3
#define FONT_FILE "font10x12.bmp"
#define FONT_WIDTH 10
#define FONT_HEIGHT 12
#define FONT_OUTER 3
#define FONT_INNER 3
#define FONT_OFFSET 32
#endif
//---
// Interface functions
//---
/* intf_pixel() - Set a single pixel */
void intf_pixel(int x, int y, int color)
{
int R = color >> 16;
int G = (color >> 8) & 0xff;
int B = color & 0xff;
SDL_SetRenderDrawColor(r, R, G, B, 255);
SDL_RenderDrawPoint(r, x, y);
}
/* intf_line() - Draw a line */
void intf_line(int x1, int y1, int x2, int y2, int color)
{
int R = color >> 16;
int G = (color >> 8) & 0xff;
int B = color & 0xff;
SDL_SetRenderDrawColor(r, R, G, B, 255);
SDL_RenderDrawLine(r, x1, y1, x2, y2);
}
/* intf_size() - Get the dimensions of a string */
void intf_size(char const *str, int *width, int *height)
{
*width = (FONT_WIDTH + 1) * strlen(str) - 1;
*height = FONT_HEIGHT;
}
/* intf_text() - Draw variable-width text */
void intf_text(char const *str, int x, int y, int color)
{
int R = color >> 16;
int G = (color >> 8) & 0xff;
int B = color & 0xff;
SDL_SetRenderDrawColor(r, R, G, B, 255);
int c;
while((c = *str++))
{
int row = (c - FONT_OFFSET) >> 4;
int col = (c - FONT_OFFSET) & 15;
SDL_Rect src = {
.x = FONT_OUTER + (FONT_WIDTH + FONT_INNER) * col,
.y = FONT_OUTER + (FONT_HEIGHT + FONT_INNER) * row,
.w = FONT_WIDTH,
.h = FONT_HEIGHT,
};
SDL_Rect dst = { .x = x, .y = y, .w = src.w, .h = src.h };
SDL_RenderCopy(r, font, &src, &dst);
x += FONT_WIDTH + 1;
}
// SDL_Rect rect = { .x = x, .y = y };
// intf_size(str, &rect.w, &rect.h);
// SDL_RenderDrawRect(r, &rect);
}
//---
// Initialization and finalization
//---
__attribute__((constructor))
static void init(void)
{
#define fail(msg) { \
fprintf(stderr, "error: " msg ": %s\n", SDL_GetError()); \
exit(1); \
}
if(SDL_Init(SDL_INIT_VIDEO) < 0) fail("failed to initialize SDL");
int c = SDL_WINDOWPOS_CENTERED;
w = SDL_CreateWindow("2D rendering", c, c, 320, 240, 0);
if(!w) fail("cannot create SDL window");
r = SDL_CreateRenderer(w, -1, SDL_RENDERER_ACCELERATED);
if(!r) fail("cannot create SDL renderer");
SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
/* Load the font */
SDL_Surface *font_surf = SDL_LoadBMP(FONT_FILE);
if(!font_surf) fail("cannot load font");
font = SDL_CreateTextureFromSurface(r, font_surf);
SDL_FreeSurface(font_surf);
if(!font) fail("cannot convert font to texture");
/* Make the window visible */
SDL_RenderPresent(r);
/* Set interface functions */
TeX_intf_pixel(intf_pixel);
TeX_intf_line(intf_line);
TeX_intf_size(intf_size);
TeX_intf_text(intf_text);
#undef fail
}
__attribute__((destructor))
static void fini(void)
{
if(font) SDL_DestroyTexture(font);
if(r) SDL_DestroyRenderer(r);
if(w) SDL_DestroyWindow(w);
SDL_Quit();
}
//---
// Backend example
//---
int main(void)
{
char const * formula =
"\\frac{x^7\\left[X,Y\\right]+3\\left|\\frac{A}{B}\\right>}"
"{\\prod_{k=1}^n\\left\\{\\frac{a_k+b_k}{k!}\\right\\}^5}"
" + \\sum_{k=1}^n\\frac{(b-a)^k}{k!}"
"+\\int_a^b\\frac{(b-t)^{n+1}}{n!}dt";
struct TeX_Flow *flow = TeX_parse(formula);
if(!flow) { puts("parsing error!"); return 1; }
TeX_debug_flow(flow, 0);
SDL_SetRenderDrawColor(r, 0xff, 0xff, 0xff, 0xff);
SDL_RenderClear(r);
TeX_draw(flow, 10, 10, 0x000000);
SDL_RenderPresent(r);
SDL_Event e;
while(1)
{
SDL_WaitEvent(&e);
if(e.type == SDL_QUIT) break;
}
TeX_free(flow);
return 0;
}
#endif /* TEX_PLATFORM_SDL */