2025年7月25日 星期五

簡單利用 sdl2 載入 jpeg 檔, 描繪中文字, 點線圓繪圖

// sudo apt install libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev
// g++ sdldraw.cpp -lSDL2 -lSDL2_image -lSDL2_ttf && ./a.out
// sdldraw.cpp
#include <unistd.h>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <SDL2/SDL_ttf.h>
int main(int argc, char** argv) {
  if (SDL_Init(SDL_INIT_EVERYTHING) == 0) {
    SDL_Window *xwin = SDL_CreateWindow("SDL JPG 中文繪圖程式", 0, 0, 800, 600, SDL_WINDOW_RESIZABLE);
    if (xwin) {
      SDL_Renderer *renderer = SDL_CreateRenderer(xwin, -1, SDL_RENDERER_ACCELERATED);
      if (renderer) {
        SDL_Texture *bgPicture = IMG_LoadTexture(renderer, "snap.jpg");
        SDL_RenderCopy(renderer, bgPicture, NULL, NULL); // fill with bgPicture
        SDL_RenderPresent(renderer);// show current image        
        SDL_SetRenderDrawColor(renderer, 255, 0, 0, 255);
        const char *message = "中文字";
        const SDL_Color colorGreen = {.r=0, .g=255, .b=0, .a=255};
        TTF_Font *ukai = (TTF_Init() == 0) ? TTF_OpenFont("./fonts/ukai.ttc", 64) : nullptr;
        SDL_Surface *msgSurface = ukai ? TTF_RenderUTF8_Blended(ukai, message, colorGreen) : nullptr;
        auto drawcircle = [renderer](float cx, float cy, float r) {
          const int max_segments = 32;// large enough to smooth circle
          const double d_theta = M_PI * 2 / max_segments;
          int lines = max_segments;// lines to draw
          int px = cx + r;// 1st θ = 0
          int py = cy    ;// 1st θ = 0
          lines --;
          double theta = d_theta;// 2nd θ
          while (lines -- > 0) {
            int nx = cx + r*cosf(theta);// next θ
            int ny = cy + r*sinf(theta);// next θ
            SDL_RenderDrawLine(renderer, px, py, nx , ny);
            theta += d_theta;
            px = nx;
            py = ny;
          }
          SDL_RenderDrawLine(renderer, px, py, cx + r , cy);// close loop
        };
        SDL_Event event;
        while (true) { // event loop begin
          usleep(1000);// to run next thread
          SDL_PollEvent(&event);
          if (event.type == SDL_QUIT) break;
          if (event.type == SDL_MOUSEBUTTONDOWN) {
            if (event.button.button == SDL_BUTTON_LEFT) {
              SDL_RenderCopy(renderer, bgPicture, NULL, NULL);
              int px = event.button.x;
              int py = event.button.y;
              SDL_RenderDrawLine(renderer, 0, 0, px, py); // draw a new line
              drawcircle(px, py, 64 * 3);
              if (msgSurface) {
                SDL_Rect destination = {px, py, msgSurface->w, msgSurface->h};
                SDL_RenderCopy(renderer, SDL_CreateTextureFromSurface(renderer, msgSurface), NULL, &destination);
              }
              SDL_RenderPresent(renderer);// show current image
              // printf("Left mouse is down @(%d,%d)\n", px, py);
            }
          } else if (event.type == SDL_WINDOWEVENT) {
            if (event.window.event == SDL_WINDOWEVENT_RESIZED) {
              SDL_RenderCopy(renderer, bgPicture, NULL, NULL);
              SDL_RenderPresent(renderer);// show current image
            }
          }
        }
        if (bgPicture) SDL_DestroyTexture(bgPicture);
        if (msgSurface) SDL_FreeSurface(msgSurface);
        if (ukai) TTF_CloseFont(ukai);
        SDL_DestroyRenderer(renderer);
      }
      SDL_DestroyWindow(xwin);
      TTF_Quit();
    }
    SDL_Quit();
  }
  return 0;
}

簡單利用 sdl2 載入 jpeg 檔, 描繪中文字, 點線圓繪圖

// sudo apt install libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev // g++ sdldraw.cpp -lSDL2 -lSDL2_image -lSDL2_ttf && ./a.out // sd...