//--- // 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 */ #ifndef LARGE_FONT /* Small font */ #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 #else /* Large font */ #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 /* Font size */ //--- // 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, 256, 128, 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+3\\left<\\frac{A}{B}\\right>}{" "\\left\\{\\frac{\\frac{2}{3}}{27}\\right\\}^2" "}"; 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 */