이전에 라이브러리를 이용한 한글 폰트 선택하고 출력했는데

알고보니 유니코드에 매핑한 방식이라 폰트의 사이즈가 너무 크다보니

인터넷 검색하다보니 조합형 한글폰트라는 것이 있다는 걸 알았다.

그래서, 한 블로그 소스를 가져와서 생성형AI에게 분석 요청하니

소스의 수정 및 최적화가 필요하다고 해서 한 번 시켜보았다.

물론 수정된 소스로 제대로 표시하지 않았다.

그냥 참고용으로 남겨본다.

원본 블로그 사이트는 찾으니 안 보이는데 나중에라도 찾으며 링크 남기겠다.

 

※ 수정 소스 gfxhangul.h

#ifndef GFXHANGUL_H
#define GFXHANGUL_H

#include <Arduino.h>
#include <Adafruit_GFX.h>
#include "font_ascii.h"
#include "font_hangul.h"

struct Hangul {
  int8_t cho;
  int8_t jung;
  int8_t jong;
};

class hangul {
private:
  Adafruit_GFX* gfx = nullptr;

  // ===== UTF-8 decode =====
  uint16_t decodeUTF8(const char*& p) {
    uint8_t c = (uint8_t)*p++;
    if (c < 0x80) return c;
    if ((c & 0xE0) == 0xC0) return ((c & 0x1F) << 6) | (*p++ & 0x3F);
    if ((c & 0xF0) == 0xE0) return ((c & 0x0F) << 12) | ((*p++ & 0x3F) << 6) | (*p++ & 0x3F);
    return '?';
  }

  // ===== 한글 분해 =====
  Hangul decodeHangul(uint16_t code) {
    Hangul h = {-1, -1, -1};

    if (code >= 0xAC00 && code <= 0xD7A3) {
      uint16_t off = code - 0xAC00;
      h.cho  = off / 588;
      h.jung = (off % 588) / 28;
      h.jong = off % 28;
    } 
    else if (code >= 0x3131 && code <= 0x314E) h.cho = code - 0x3131;
    else if (code >= 0x314F && code <= 0x3163) h.jung = code - 0x314F;
    else if (code >= 0x3165 && code <= 0x318E) h.jong = code - 0x3165;

    return h;
  }

  uint8_t get_first_beol(uint8_t jung, uint8_t jong) {
    switch(jung) {
      case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 20: return jong == 0 ? 0 : 5;
      case 8: case 12: case 18: return jong == 0 ? 1 : 6;
      case 13: case 17: return jong == 0 ? 2 : 6;
      case 9: case 10: case 11: case 19: return jong == 0 ? 3 : 7;
      default: return jong == 0 ? 4 : 7;
    }
  }

  uint8_t get_second_beol(uint8_t cho, uint8_t jong) {
    if (cho == 0 || cho == 15) return jong == 0 ? 0 : 2;
    return jong == 0 ? 1 : 3;
  }

  uint8_t get_last_beol(uint8_t jung) {
    switch(jung) {
      case 0: case 2: case 9: return 0;
      case 4: case 6: case 11: case 14: case 16: case 19: case 20: return 1;
      case 3: case 5: case 7: case 10: case 15 : return 2;
      default: return 3;
    }
  }

  void render_beol_to_buf(uint8_t col, uint8_t line, byte buf[16][2]) {
    uint16_t off = 1024 * line + col * 2;
    for (uint8_t row = 0; row < 16; row++) {
      buf[row][0] |= font_hangul[off];
      buf[row][1] |= font_hangul[off + 1];
      off += 64;
    }
  }

  // ===== ASCII bitmap 출력 =====
  void drawAscii(char c, int x, int y, uint16_t color) {
    uint8_t bmp[16];
    int ptr = ((int)c) * 16;
    for (int i = 0; i < 16; i++) bmp[i] = font_ascii[ptr + i];
    gfx->drawBitmap(x, y, bmp, 8, 16, color);
  }

  // ===== 한글 bitmap 출력 (최적화 핵심) =====
  void drawHangul(uint16_t code, int x, int y, uint16_t color) {
    byte buf[16][2] = {0};
    uint8_t bmp[32];

    Hangul h = decodeHangul(code);

    if (h.cho >= 0) {
      uint8_t b1 = (h.jung >= 0) ? get_first_beol(h.jung, h.jong) : 0;
      render_beol_to_buf(h.cho, b1, buf);
    }
    if (h.jung >= 0) {
      uint8_t b2 = (h.cho >= 0) ? get_second_beol(h.cho, h.jong) : 0;
      render_beol_to_buf(h.jung, 8 + b2, buf);
    }
    if (h.jong > 0) {
      uint8_t b3 = (h.jung >= 0) ? get_last_beol(h.jung) : 0;
      render_beol_to_buf(h.jong, 12 + b3, buf);
    }

    for (int r = 0; r < 16; r++) {
      bmp[r * 2]     = buf[r][0];
      bmp[r * 2 + 1] = buf[r][1];
    }

    gfx->drawBitmap(x, y, bmp, 16, 16, color);
  }

public:
  void attachGFX(Adafruit_GFX* g) { gfx = g; }

  void print(const char* str, int x, int y, uint16_t color) {
    if (!gfx) return;

    int cx = x, cy = y;

    while (*str) {
      uint16_t ch = decodeUTF8(str);

      if (ch == '\n') { cy += 16; cx = x; continue; }
      if (ch == '\r') continue;

      if ((ch >= 0xAC00 && ch <= 0xD7A3) || (ch >= 0x3131 && ch <= 0x318E)) {
        drawHangul(ch, cx, cy, color);
        cx += 16;
      }
      else if (ch < 0x100) {
        drawAscii((char)ch, cx, cy, color);
        cx += 8;
      }
    }
  }
};

#endif

 

728x90

'Hardware > ESP32' 카테고리의 다른 글

ESP8266 + SH1106 조합형 한글 출력 #3  (0) 2026.02.04
ESP8266 + SH1106 조합형 한글 출력 #2(예제)  (0) 2026.02.04
ESP 기반 IoT  (0) 2026.01.30
Ollama + MCP + ESP32 2대 제어하기(1)  (0) 2026.01.28
ESP32 WebSocket 연습 1  (0) 2026.01.09

+ Recent posts