//--- // SDL interface: for rendering tests on computer //--- #ifdef TEX_PLATFORM_SDL #include #include #include #include /* 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; } } //--- // 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>}" "{\\left\\{\\frac{a_k+b_k}{k!}\\right\\}^5}" " + \\int_a^b\\frac{\\left(b-t\\right)^{n+1}}{n!\\sqrt{n^3}}dt" " + \\left(\\begin{matrix}" "\\frac{1}{2}&\\sqrt{5}\\\\" "-1&a+b" "\\end{matrix}\\right)"; /* Much harder matrix test. formula = "\\left\\{\\begin{matrix}" "\\frac{-1}{ab}+7&\\sum_{i=1}^{k+\\int f} \\frac{in}{4!}\\\\" "\\left(\\begin{matrix}" "cos(t)&-sin(t)\\\\sin(t)&cos(t)" "\\end{matrix}\\right)\\\\" "x&y&\\left[\\begin{matrix}\\end{matrix}\\right]" "\\end{matrix}\\right\\}"; */ struct TeX_Env *env = TeX_parse(formula); if(!env) { puts("parsing error!"); return 1; } TeX_print_env(env, 0); SDL_SetRenderDrawColor(r, 0xff, 0xff, 0xff, 0xff); SDL_RenderClear(r); TeX_draw(env, 10, 10, 0x000000); SDL_RenderPresent(r); SDL_Event e; while(1) { SDL_WaitEvent(&e); if(e.type == SDL_QUIT) break; } TeX_free(env); return 0; } #endif /* TEX_PLATFORM_SDL */