2P by GN⁺ 3시간전 | ★ favorite | 댓글 1개
  • 모든 문자를 5픽셀 정사각형 안에 넣고 6x6 그리드에 안전하게 그릴 수 있게 맞춘 초소형 고정폭 폰트로, 작은 화면과 제한된 메모리 환경에 맞게 설계됨
  • 5x5 크기는 4x4에서 부족했던 E, M, W 표현 문제를 해결하고, 대부분의 소문자를 대문자보다 1픽셀 작게 그려 시각적 구분성도 확보함
  • 전체 폰트가 350바이트에 불과해 AVR128DA28 같은 8비트 마이크로컨트롤러에 잘 맞고, 160x128이나 128x64 OLED 같은 작은 화면에서 픽셀 효율이 커짐
  • 비슷한 크기로 렌더링한 벡터 폰트와 비교해도, 안티앨리어싱과 훨씬 큰 코드·폰트 데이터를 써도 350바이트 수제 폰트보다 결과가 떨어짐
  • 더 작은 3x5, 3x4, 3x3, 2x3, 3x2, 2x2까지 실험했으며, 3x5는 꽤 읽을 만하고 3x2는 2x3보다 낫지만 2x2는 사실상 비밀 코드에 가까운 수준까지 무너짐

5x5 픽셀 폰트

  • 모든 문자가 5픽셀 정사각형 안에 들어가고 6x6 그리드에 안전하게 그릴 수 있게 설계됨
    • 기반은 lcamtuf의 5x6 font-inline.h이며, 이 폰트는 ZX Spectrum의 8x8 폰트에서 영향을 받음
    • 5x5는 가독성을 해치지 않는 최소 크기로 잡힘
  • 2x2는 불가능하고 3x3은 기술적으로 가능하지만 읽기 어려우며, 4x4E, M, W를 제대로 그리기에 부족함
    • 5x5에서는 이 문제가 해결됨
  • 5x5는 대부분의 소문자를 대문자보다 1픽셀 작게 그릴 수 있어 시각적으로 구분 가능함
  • 더 좁은 4x53x5도 가능하지만, M, 점이 있는 0, 그리고 U/V/Y의 구분성을 희생해야 함
  • 모든 문자를 일정한 폭으로 맞추면 프로그래밍이 쉬워짐
    • 화면에서 문자열 길이는 항상 문자 수의 6배로 계산됨
    • "8978""1111"보다 길어져 레이아웃이 넘치는 문제를 걱정하지 않아도 됨
  • 폰트 전체 크기는 350바이트에 불과해 AVR128DA28 같은 8비트 마이크로컨트롤러에 잘 맞음
    • 본문에는 AVR128DA28이 RAM 16kB를 가진다고 적혀 있음
    • 이런 칩은 저렴하고 저전력이며 견고하지만 그래픽 처리 여유는 적음
  • 384x288 디스플레이도 픽셀이 약 11만 개라 AVR 메모리에 담기에는 너무 큼
    • 대신 160x128이나 128x64 OLED처럼 더 작은 화면이 더 실용적이고 저렴함
    • 이런 화면에서는 손으로 그린 픽셀 효율적 폰트가 유리함
  • 비슷한 크기로 렌더링한 벡터 폰트도 함께 비교됨
    • 해당 벡터 폰트는 실제로 높이 6픽셀이지만 글자는 더 좁음
    • 안티앨리어싱, 수 메가바이트 코드, 1MB 폰트 데이터를 써도 350바이트 수제 폰트보다 결과가 떨어짐

실제 화면과 더 작은 크기 실험

  • 실제 픽셀은 완전한 정사각형이 아니라서 화면에서의 모습은 상단 렌더링과 정확히 같지 않음
    • 서브픽셀이 만드는 의사 드롭섀도우 효과는 긍정적으로 평가됨
    • 흑백 디스플레이에서는 이 효과가 없지만 그래도 예상보다 더 부드럽게 보임
  • 픽셀 사이의 간격은 eg를 더 그럴듯하게 보이게 만듦
    • 같은 효과를 바탕으로 더 작은 폰트 가능성도 이어서 탐색함
  • 3x5는 타협 없는 최소 해상도는 아니지만 꽤 괜찮은 수준으로 읽힘
    • 이 크기에서는 글리프가 32,768개 있고 그중 27,904개가 서로 구분됨
    • M, W, Q는 손해를 보지만 O0은 여전히 구분됨
    • 화면에 50% 더 많은 열을 넣어야 할 때 선택지가 될 수 있음
  • 3x4에서는 여전히 읽을 수 있지만 제약이 커짐
    • 글리프는 4,096개, 그중 3,392개가 서로 구분됨
    • 이 크기에서는 대문자와 소문자를 구분할 수 없어 제한된 공간에서 가장 잘 맞는 스타일 하나를 고름
    • 숫자 표현력도 나빠지지만 아직은 작동 가능함
  • 3x3에서는 숫자 손실이 가장 큼
    • 글리프는 512개, 그중 400개가 서로 구분됨
    • 글자는 중복 없이 어느 정도 알아볼 수 있음
    • 실제 하드웨어에 표시하면 이 폰트가 크게 개선됨
  • 2x3은 무리한 수준에 가까워짐
    • 글리프는 64개, 그중 44개가 서로 구분됨
    • 대부분의 글자를 알아보기 어렵고 중복도 많음
    • 맨 아래 줄은 "Hello World"
  • 가로세로 비율을 뒤집은 3x2는 2x3보다 훨씬 나아짐
    • 이 크기도 글리프는 64개, 그중 44개가 서로 구분됨
    • M, W, N, Q, G, P처럼 가로 디테일이 필요한 글자가 E, F 같은 세로 디테일보다 많아 더 유리함
    • 맨 아래 줄은 "you can probably read this"이며, 찡그려 보거나 축소해서 보면 읽을 수 있음
  • 2x2는 완성도를 위한 비교 대상으로만 남음
    • 가능한 2x2 이미지는 이론상 16개지만, 하나는 빈 칸이고 다섯 개는 다른 글리프를 이동해 복사한 형태라 실제로는 10개만 남음
    • 숫자 전체를 표현할 만큼은 되지만 원래 형태와 닮지 않아 폰트라기보다 비밀 코드에 가까움
Hacker News 의견들
  • 서브픽셀 렌더링을 활용하면 1x5도 충분히 가능함 https://www.msarnoff.org/millitext/

  • 5x5는 꽤 좋고 3x5도 나쁘지 않지만, 둘 다 ASCII 전체를 다 갖추진 못함
    실제 크기도 약간 착시가 있는데, 글자 간격까지 넣으면 사실상 6x6이나 4x6 그리드가 필요함
    그래서 나는 https://github.com/fcambus/spleenSpleen을 꽤 좋아함
    여기엔 ASCII 전체를 지원하는 5x8 폰트가 있고, 대부분 글리프는 사실상 4x8에 가로 간격이 포함된 형태임
    내 프로젝트에서는 이를 수정해서 모든 글리프를 4x8로 맞췄고, 결과적으로 5x9 그리드에서 각 글자 사이에 가로·세로 1픽셀 간격을 항상 보장하면서도 보기 좋게 렌더링할 수 있었음

    • 1980년대 초 Apple II용 워드프로세서 중에는 기본 40컬럼 화면에서 그래픽 모드 5x5 폰트를 써서 60컬럼을 구현한 것도 실제로 있었고, 그게 판매 포인트였음
      하드웨어로 해결하려면 80 column card를 사서 제대로 된 80컬럼 텍스트를 쓰면 됐고, 다만 모니터가 이를 받아줘야 했음
  • 대부분의 초소형 폰트는 1:1 배율에서 얼핏 읽기엔 정말 끔찍한 수준임
    예전에 게임 모드를 만들면서 아주 작고 촘촘한 폰트가 필요해서 3x3, 3x5, 심지어 2x5까지 많이 써봤는데 전부 읽기 너무 힘들었음
    결국 zephram이 만든 Gremlin-3x6를 찾았고, 높이가 1픽셀 더 크긴 해도 가로로는 여전히 매우 컴팩트했음
    무엇보다 표준 라틴 문자의 구분이 잘 되고, 크게 확대하지 않아도 읽을 만했음
    아쉽게도 zephram이 FontStruct 계정을 지우면서 폰트도 전부 사라졌지만, 내 모드 저장소에 사본과 CC0 라이선스를 남겨뒀고 실제 렌더링은 스크린샷에서 볼 수 있음
    [0] - https://fontstruct.com/fontstructions/show/1488093
    [1] - https://codeberg.org/janAkali/isaac-extended-icons-mod/src/branch/master/assets/fonts
    [2] - https://codeberg.org/janAkali/isaac-extended-icons-mod/media/branch/master/assets/screenshots/screenshot.png

    • [0]은 지금 404가 뜸
  • CJK 문자 쪽에서도 비슷한 논의가 있었음
    https://chinese.stackexchange.com/questions/16669/lowest-pixel-resolution-needed-to-support-chinese

  • 작성자가 이걸 본다면, 소문자 t는 가로획 위에 픽셀 하나를 더 올리는 편이 좋겠음
    지금 형태는 대문자 T와 너무 비슷하게 보임
    그래도 전체적으로는 아주 잘 만들었고 공유해줘서 고마움

    • 나라면 소문자 t를 이런 식으로 만들겠음
      x
      xxx
      x
      xx
    • 소문자 l도 더 이렇게 생기지 않을까 싶었음
      xx
      x
      x
      x
      xx
  • 4x4로는 E, M, W를 제대로 그리기 부족하다고 했는데, 사실 5x5도 e를 제대로 그리기엔 부족
    소문자를 대문자보다 낮게 만들고 싶다면 세로 픽셀이 최소 6개는 필요하고, 디센더까지 제대로 넣으려면 최소 7개는 있어야 함
    엄밀히는 g와 y가 베이스라인에 걸치면서도 수평 디센더를 구분하려면 8개가 더 낫지만, 여기선 타협 가능해 보임
    그리고 실제로는 글자 아래와 옆에 눈에 띄는 간격을 두려면 결국 문자당 최소 8x6 픽셀은 필요함

    • 폰트를 그렇게까지 작게 만들 수 있다면, 내가 가장 먼저 포기할 속성은 소문자 높이가 대문자보다 낮아야 한다는 규칙일 것 같음
    • 예시의 real pixels 쪽 e가 오히려 더 좋아 보임
      내 눈에는 윗부분 빈 공간이 어느 정도 메워져서 읽히고, 긴 문장 안에서는 문맥으로 충분히 파악될 듯함
      물론 완벽하진 않고, 위쪽의 확대된 깔끔한 픽셀 예시에선 어색함이 더 두드러지긴 함
  • 픽셀을 on/off 두 상태만 쓰지 않고 다단계 그레이스케일을 쓰면 더 작은 크기에서도 읽을 수 있는 텍스트를 만들 수 있음
    다만 여기서 중요한 건 letters가 아니라 text라는 점임
    글자 하나하나는 너무 흐려도, 사람이 문맥으로 추론해서 읽게 되는 방식임
    심지어 이 방법엔 특별히 설계된 폰트도 꼭 필요하지 않음
    예시: https://imgur.com/a/text-80-characters-per-line-240-pixels-wide-AlYrnSS
    여기선 글자 사이 간격까지 포함해도 문자당 가로 평균 3픽셀 정도밖에 안 됨

  • LINC 미니컴퓨터의 운영체제 LAP6에는 4x5 폰트가 들어 있었지만 소문자는 없었음

  • 예전에 C64에서 소프트웨어로 80컬럼을 구현하려는 작업이 떠오름
    3x7 픽셀 그리드를 쓰되 한 행과 한 열은 간격용으로 빼는 방식이었고, 실제 상용 제품에도 일부 들어갔음
    https://www.pagetable.com/?p=901
    4×8 문자셋을 읽기 좋고 보기 좋게 만드는 건 쉽지 않고, 글자 사이에 1픽셀 간격이 필요해서 실질적으로는 글자 폭이 3픽셀밖에 안 됨
    그래서 M이나 N 같은 문자가 특히 까다로움

  • M, dotted zero를 포기하고 U/V/Y 구분도 약해지면 4x5나 3x5도 가능하다고 했는데, 나는 3x5도 충분히 실용적이라고 봄
    https://robey.lag.net/2010/01/23/tiny-monospace-font.html