2018년 9월 디자인과 코딩을 함께 다루는 유튜브 채널을 열었습니다. "타입과 미디어" 사이트는 당분간 유지할 계획이지만, 새로운 정보는 유튜브 비디오를 통해서 소개하겠습니다. 많은 관심 부탁드립니다! — 정대인

폰트 사용하기

세부 목차

프로세싱은 컴퓨터에 설치되어 있는 폰트를 이용해서 글을 쓸 수 있는 방법을 제공합니다. PFont 오브젝트를 사용해서 컴퓨터에 설치된 다양한 서체를 불러올 수 있습니다. PFont와 관련 함수를 사용해서 화면에 글자를 표시하는 방법을 알아봅시다.

내 컴퓨터의 모든 폰트

컴퓨터에 설치되어있는 폰트들만 프로세싱에서 사용가능합니다. 어떤 폰트들이 프로세싱에서 사용가능한지 알아봅시다.

printArray( PFont.list() );

위의 예제를 실행하면 현재 사용 중인 컴퓨터에 설치되어 있고, 프로세싱에서 사용가능한 폰트의 목록이 콘솔창에 출력됩니다.

이번에는 같은 목록을 pdf 파일로 저장해보겠습니다. 이 곳에서 소스코드를 다운로드하고, 압축을 푼 다음 실행합시다. 이 스케치는 따로 실행창이 열리지는 않고, 모든 과정을 마치면 pdf recording finished라는 메세지가 콘솔에 출력됩니다. 스케치가 저장된 폴더 안에 All my fonts.pdf가 생성된 것을 확인할 수 있습니다. 이 PDF 파일은 스케치가 실행된 컴퓨터에 설치되었고 프로세싱에서 사용가능한 모든 폰트의 이름을 알파벳 순서대로 여러 페이지에 걸쳐서 나열하고 있습니다.

all my fonts

폰트를 비트맵 방식으로 불러오기

설치되어있는 폰트들만 사용가능하다면, 우리가 만든 스케치를 다른 컴퓨터에서 실행해야 할 때는 어떡해야 할까요? 프로세싱은 고유의 폰트 파일 확장자 .vlw를 제공합니다. .vlw파일은 폰트의 각 글자를 비트맵(이미지) 방식으로 담고 있습니다. 그래서 폰트가 설치되지 않은 컴퓨터에서도 이미지를 표시하는 방식으로 글자들을 보여줄 수 있습니다. loadFont() 함수를 이용해서 화면에 글자를 표시하는 방법을 순서대로 알아보겠습니다.

  1. 새로운 프로세싱 창을 열고 적당한 곳에 스케치를 저장합니다.

  2. 프로세싱의 상단 메뉴에서 Tools > Create Font...를 선택합니다.

  3. 이 창에서 원하는 폰트를 선택하고, 사이즈를 정해줍니다. 생성될 파일의 이름도 설정해줄 수 있지만, 자동으로 만들어진 이름을 사용하는 것이 편리합니다. 영어 예문이 써져있는 박스를 클릭해서 다른 예문으로 바꿔줄 수도 있습니다.

  4. Characters... 버튼을 눌러서 생성할 .vlw 파일에 어떤 글자 영역을 포함시킬지 정할 수 있습니다. 기본으로는 라틴 문자가 포함되어 있습니다. 영어 알파벳만 사용할 경우에는, 이 옵션에 크게 신경쓸 필요가 없습니다. 하지만, 한글의 경우, 유니코드 블럭이 따로 있기 때문에, 한글을 지원하는 서체를 선택하고, Characters... 창에서 유니코드 블럭을 따로 지정해줘야 합니다.
  5. OK를 눌러서 파일을 생성합니다. 설정에 따라서 파일 생성에 시간이 꽤 걸릴 수 있습니다.

  6. 스케치가 저장된 폴더에 가면, data 폴더가 만들어져있고, 그 안에 우리가 방금 전 생성한 .vlw 파일이 있는 것을 볼 수 있습니다.

    주의할 점은, 한글 .vlw 파일의 경우, 그 사이즈가 무척 크다는 것입니다. 시스템 기본 제공 SansSerif-48.vlw 파일을 Create Font... 메뉴를 통해서 생성하자, 약 18.4MB 크기의 파일이 만들어졌습니다. 글자의 크기 또한, 파일의 크기에 큰 영향을 줍니다. .vlw 파일은 각 글자를 비트맵 방식으로 저장하기 때문에 글자의 크기가 커질수록 필요한 픽셀의 수가 늘어나고, 따라서 .vlw 파일의 크기 또한 커집니다.

이제 생성된 SansSerif-48.vlw 파일을 프로세싱으로 불러옵시다.

PFont font;

String s = "산모퉁이";

void setup() {
  size(600, 200);
  
  font = loadFont("SansSerif-48.vlw");
  textFont(font);
}

void draw() {
  background(255);
  fill(0);
  textSize(48);
  text(s, 20, 100);
}

위의 예제를 살펴보겠습니다.

PFont font;

위 구문은 PFont 오브젝트를 만들어줍니다. 오브젝트를 생성하는 방법은 다른 변수를 생성하는 법과 크게 다르지 않습니다. 오브젝트의 이름은 꼭 font라고 짓지 않고, 다른 이름을 붙여줘도 됩니다.

font = loadFont("SansSerif-48.vlw");

위 구문은 생성한 font 오브젝트에 .vlw 파일을 담는 것입니다. data 폴더에 같은 이름의 파일이 존재하지 않는다면, 프로세싱은 에러 메시지를 표시할 것입니다.

textFont(font);

위 구문은 앞으로 사용할 텍스트는 font를 사용할 것이라고 지시하는 것입니다. 이 구문을 사용한 이후 사용하는 모든 text() 함수는 font를 사용하게 됩니다.

textSize(48);

위 구문은 사용할 폰트의 크기를 설정합니다. 단위는 픽셀입니다. .vlw 파일을 생성할 때에 이미 크기를 지정하였으므로, 여기서는 굳이 포함시키지 않아도 됩니다. 하지만 이후에 크기를 변경하고 싶을 때에는 text()를 사용하기 전에 먼저 textSize()를 사용해서 크기를 바꿔줘야 합니다.

우리는 .vlw 파일을 생성할 때, 글자의 크기를 명시했습니다. 다른 크기의 글자를 표시해야한다면, textSize() 함수를 이용해서 사용하고자 하는 크기를 설정해줄 수 있습니다.

text(s, 20, 100);

text()는 3개의 인수를 받습니다. 첫번째는 표시할 텍스트입니다. 함수 안에 text("한글", 20, 100);, 이런 식으로 직접 문자열을 적어줘도 되고, 위의 예제처럼 String 오브젝트를 사용해서 오브젝트 이름을 적어넣어도 됩니다. 두번째, 세번째 인수는 각각 x 와 y 죄표값입니다.

글자의 크기 설정과 관련해서 아래 예제를 살펴보겠습니다.

PFont font;

String s = "산모퉁이";

void setup() {
  size(600, 200);
  
  font = loadFont("SansSerif-48.vlw");
  textFont(font);
}

void draw() {
  background(255);
  
  textSize(48);
  fill(0);
  text(s, 20, 50);

  textSize(96);
  fill(0);
  text(s, 20, 150);
}

위의 예제를 실행하면, 크기 96을 가지는 글이 표시는 되지만, 블러 처리가 된 것처럼, 뿌옇게 나오는 것을 볼 수 있습니다. 이는, textSize()를 사용해주었다고 하더라도 애초에 생성했던 SansSerif-48.vlw의 크기가 48이기 때문에, 단지 크기를 늘려놓은 것이기 때문입니다. 만약, 깨끗하게 나오는 글자를 원한다면, 또 하나의 PFont 오브젝트를 생성하고, 크기 96SansSerif-96.vlw 파일 또한 생성해주어야 합니다.

폰트를 벡터 방식으로 생성하기

알파벳의 경우에는 기본 26자에 문장부호 등을 고려해도 수백자 안에서 해결되기 때문에 loadFont() 함수를 이용해서 .vlw 파일을 로드하는 것이 나쁜 선택은 아닙니다. 하지만, 우리 한글의 경우에는 수천 자에서 만 자에 이르는 고유의 글자들을 모두 이미지로 생성해야하기 때문에 .vlw 파일의 크기가 매우 커지게 됩니다. 뿐만 아니라, 다양한 크기의 글자들을 깨끗한 모양으로 사용하고 싶다면 그 수에 해당하는 .vlw 파일을 일일히 만들어주어야 합니다.

createFont()를 사용하면 그런 부담을 덜 수 있습니다. createFont()를 사용하면 폰트를 벡터 방식으로 불러올 수 있습니다. 따라서 처음 글자의 크기와 상관없이 textSize()를 이용한 글자의 크기 변동이 자유롭습니다. 아래의 예제를 살펴봅시다.

PFont font;

String s = "산모퉁이";

void setup() {
  size(600, 200);

  font = createFont("SansSerif", 48);
  textFont(font);
}

void draw() {
  background(255);

  textSize(48);
  fill(0);
  text(s, 20, 50);

  textSize(96);
  fill(0);
  text(s, 20, 150);
}
Your browser does not support canvas.

createFont()를 사용할 때 주의할 점은, 프로세싱 스케치가 실행될 때에 폰트를 생성하기 때문에, 실행 컴퓨터에 사용서체가 설치되어 있어야 한다는 것입니다. 사용폰트가 설치되어 있지 않은 컴퓨터에서 프로세싱 스케치를 실행 시에 글자가 어떻게 표시될지는 장담할 수 없습니다. 한가지 방법은 TTF 또는 OTF 폰트 파일을 data 폴더에 직접 첨부하는 것입니다. 스케치 폴더를 다른 사람과 공유할 때에는 폰트의 저작권에 주의해야 합니다. 대부분의 폰트는 이런 식으로 폰트 파일을 공유하는 것을 금지하고 있으니, 각 폰트의 라이센스를 확인해야 합니다.

텍스트 박스

text() 함수를 사용할 때, 추가로 2개의 인수를 더해서 텍스트 박스의 크기를 설정해 줄 수 있습니다. 텍스트 박스를 사용하면, 자동으로 줄바꿈이 됩니다. 텍스트 박스를 사용하면, text()의 위치가 사각형을 그릴 때처럼 박스(사각형)의 왼쪽 위를 기준으로 한다는 점을 주의해야 합니다.

PFont font;

String s = "텍스트 박스의 크기를 설정하면 자동으로 줄바꿈이 됩니다.";

void setup() {
  size(600, 200);
  font = createFont("SansSerif", 24);
  textFont(font);
}

void draw() {
  background(255);
  
  // draw text
  fill(0);
  noStroke();
  text(s, 20, 50);
  text(s, 20, 80, 300, 100);

  // show guides
  fill(0, 255, 0);
  stroke(0, 255, 0);
  ellipse(20, 80, 5, 5);
  noFill();
  rect(20, 80, 300, 100);
}

Your browser does not support canvas.

행간 설정

여러 줄의 텍스트를 표시할 때, 행간을 변경하려면 textLeading() 함수를 사용해줍니다. 단위는 픽셀입니다.

PFont font;

String s = "텍스트 박스의 크기를 설정하면 자동으로 줄바꿈이 됩니다.";

void setup() {
  size(600, 200);
  font = createFont("SansSerif", 24);
  textFont(font);
}

void draw() {
  background(255);

  // draw text
  fill(0);
  noStroke();
  textLeading(24);
  text(s, 20, 20, 160, 160);

  // show guides
  fill(0, 255, 0);
  stroke(0, 255, 0);
  ellipse(20, 20, 5, 5);
  noFill();
  rect(20, 20, 160, 160);

  // draw text
  fill(0);
  noStroke();
  textLeading(40);
  text(s, 200, 20, 160, 160);

  // show guides
  fill(0, 255, 0);
  stroke(0, 255, 0);
  ellipse(200, 20, 5, 5);
  noFill();
  rect(200, 20, 160, 160);
}

Your browser does not support canvas.

글자의 정렬

textAlign()을 이용해서 글자를 정렬해줄 수 있습니다.

먼저, 가로 정렬을 알아봅시다. 가로정렬은 LEFT, CENTER, RIGHT 세 종류를 사용할 수 있습니다.

PFont font;

String s = "글의 가로 정렬";

void setup() {
  size(600, 200);
  font = createFont("SansSerif", 24);
  textFont(font);
}

void draw() {
  background(255);
  
  stroke(0, 255, 0);
  line(width/2, 0, width/2, height);
  
  fill(0);
  textAlign(LEFT);
  text(s, 300, 40);
  
  textAlign(CENTER);
  text(s, 300, 80);
  
  textAlign(RIGHT);
  text(s, 300, 120);

}
Your browser does not support canvas.

세로 정렬은 가로 정렬 다음에 인수를 하나 더 넣어줍니다. TOP, BOTTOM, CENTER, BASELINE 네 종류를 사용할 수 있습니다.

PFont font;

void setup() {
  size(600, 200);
  font = createFont("SansSerif", 24);
  textFont(font);
}

void draw() {
  background(255);
  
  stroke(0, 255, 0);
  line(0, 20, width, 20);
  line(0, 70, width, 70);
  line(0, 120, width, 120);
  line(0, 170, width, 170);
  
  fill(0);
  textAlign(LEFT, TOP);
  text("위로 정렬", 20, 20);
  
  textAlign(LEFT, CENTER);
  text("가운데로 정렬", 20, 70);
  
  textAlign(LEFT, BOTTOM);
  text("아래로 정렬", 20, 120);
  
  textAlign(LEFT, BASELINE);
  text("베이스라인 정렬", 20, 170);
}

Your browser does not support canvas.

위의 예제에서 BOTTOM 정렬의 경우, 알파벳의 디센더(descender)를 기준으로 하기 때문에 한글에 그대로 적용하기에는 무리가 있습니다.

글자의 너비 계산

textWidth()를 사용해서 한 글자 또는 여러 글자의 너비를 계산할 수 있습니다.

PFont font;

String s1 = "산";
String s2 = "산모퉁이";

void setup() {
  size(600, 200);
  font = createFont("SansSerif", 48);
  textFont(font);
}

void draw() {
  background(255);
  
  fill(0);
  textSize(48);
  text(s1, 20, 50);
  text(s2, 20, 100);
  
  float s1width = textWidth(s1);
  float s2width = textWidth(s2);
  fill(0, 200, 0);
  textSize(12);
  text(s1width + " px wide", 20 + s1width, 50);
  text(s2width + " px wide", 20 + s2width, 100);
}

Your browser does not support canvas.

글자의 높이 계산

textAscent()textDescent()를 사용하면 글자의 높이를 계산할 수 있습니다. 알파벳 글자의 높이를 계산할 때 유용하며, 둘의 값을 더하면 글자의 높이가 나옵니다.