2005년 1월 16일 일요일

TrueTypeFont instruction set - instuction glyphs(2)


Determining distances

가장 낮은 레벨에서, glyph에 명령을 내리는 것은 두 점 사이의 간격을 다루는 것과 동일한 의미를 갖습니다. 간격을 다루는 첫 번째 단계는 흔히 그것의 크기를 결정하는 것입니다. 예를 들면, Control Value Table을 설정하는 첫 번째 단계는 폰트의 키 포인트 사이의 간격을 측정하는 것과 관계가 있습니다. Glyph의 외곽선에서 두 점의 사이의 간격을 측정하는 것은 어렵지는 않은 반면에 반드시 어떠한 요소들에 대하여 정확한 계산이 이루어져야 합니다.

모든 간격 측정은 원의 radius에 의해서 단위 벡터의 방향이 가리켜지는 projection_vector에 평행하게 만들어집니다. 간격들은 이 벡터들을 반영하며 이들에 따라 측정됩니다. 간격들은 벡터의 방향을 반영하는 방향을 가집니다.

측정은 오리지널 문자의 외곽선 안의 점들 사이의 간격 또는 그리드에 적합한(grid-fitted) 점들 사이의 간격이라 할 수 있습니다. 간격 측정(MD : measures distances) 명령은 간격이 오리지널 문자의 외곽선 또는 그리드에 적합한 외곽선에 의해 측정될 수 있는 간격인지 아닌지를 결정하는 불린 값을 가지고 있습니다.

이외에도, 트루타입 인터프리터는 간격에 대하여 세 개의 타입으로 구별됩니다. - 검정색, 흰색, 회색(black, white and grey). MDRP, MIRP, ROUND 같은 특정 명령어들은 어떠한 타입인지에 대한 명세를 필요로 합니다.

검정색 간격들은 오직 검정색 부분만을 연결할 수 있습니다. 흰색 간격은 흰색 부분만을, 회색 간격은 두 개의 조합 사이에서만 연결할 수 있습니다. 다음의 일러스트는 검정색, 흰색, 회색 간격을 보여줍니다. [2,1]은 검정색, [3,0]는 회색을 그리고 [4,6]은 흰색을 나타냅니다.

Figure 2-3. 흰색, 검정색, 그리고 회색 간격




간격 타입은 ROUND와 round_state를 사용하는 명령어가 다른 출력 디바이스에서 어떻게 작용해야 하는 지를 결정하는데 사용됩니다. 회색 간격들은 rounding에 영향을 받지 않습니다. 그러나 검정색 또는 흰색 간격들은 rounding이 발생하기 전에 보상 경계(compensation term)을 필요로 합니다. 보상의 양은 디바이스 드라이버에 의해서 설정될 필요가 있습니다. 예를 들자면, 출력 엔진이 큰 픽셀을 가지고 있다면, 인터프리터가 검정색 간격을 축소시키고 흰색 간격을 확대 시킴으로 보상합니다. 회색거리는 검정색과 흰색의 간격으로 구성되어 있기 때문에 변화가 없습니다.

두 개의 점들 사이를 결정할 때, 간격은 항상 projection_vector에 의해서 명세 된 방향으로 측정됩니다. 동일하게, 점이 이동했을 때, projection_vector에 따라서 측정되어진 거리로 움직일 것입니다. 어떻게 인터프리터가 거리를 반영할 것인지를 생각해볼 때, projection vector와 평행으로 되어 있는 규칙적인 선들에 의해서 반영이 된다는 것을 편리하게 발견할 수 있을 것입니다.

예에서 보여주는 것처럼, 간격은 projection_vector와 평행인 선에 의해 측정되어 집니다. 점1에서 점2에의 간격은 측정되기 전에 projection_vector에 의해서 투영되어야 합니다. (선은 projection_vector와 평행인 선입니다.) 점1에서 점3까지의 선은 벡터에 병행이기 때문에, 간격의 반영이 단순하게 1에서 3까지의 선으로 생각할 수 있습니다. 점4에서 점1까지의 투영된 선은 벡터에 수직이기 때문에 점들이 겹쳐있지 않음에도 불구하고 4에서 1의 간격은 0의 값을 갖습니다.




벡터는 원하는 어떠한 방향으로도 설정될 수 있습니다. Projection vector는 x 방향의 간격으로 설정될 수 있습니다. 이러한 경우에 벡터는 x축과 평행이 됩니다. 동일하게 y 방향의 간격을 측정하고 싶다면 projection_vector를 y축으로 설정해야 합니다.

projection_vector가 x축의 플러스 방향을 가리킬 때 두 개의 점들 사이의 간격을 결정하기 위해서는, 그들의 x축 방향 사이의 간격만을 가질 수 있습니다. 예로 들자면, (2,1)과 (7,5) 사이의 간격은 5이다. 동일하게, projection_vector가 y축 방향을 가리킨다면, 간격은 4가 될 것입니다.

projection_vector가 방향을 가지고 있기 때문에, 간격이 부호를 가질 수 있다는 것에 주의해야 합니다. 플러스 간격은 projection_vector와 같은 방향을 의미하고, 마이너스 간격은 점들이 projection_vector와 반대 방향으로 되어 있는 것을 의미합니다.

다음의 예제를 보면 projection_vector가 동쪽 방향을 가리키고 있습니다(x 축의 양의방향). 점1과 2의 간격은 서쪽에서 동쪽 방향으로 측정할 때 양의 값을 갖게됩니다. 마찬가지로 동쪽에서 서쪽을 가리키는 경우(점2에서 점1)에는 음의 값을 갖게됩니다.

Figure 2-4. 두 개의 점들 사이의 간격 측정



많은 경우에서, 간격과 관련하여 부호를 고려하지 않는 것은 편리한 방법입니다. auto_flip Graphics State의 변수가 true로 설정이 되어있다면, CVT의 전체 기호는 실제 측정되는 부호와 일치할 때까지 변경될 것입니다. 이것은 간격을 측정하는 것을 통제할 수 있도록 하거나 반대로 single CVT entry에 의해 projection_vector가 측정되어 되어지는 것을 가능하게 합니다. (ㅡㅡ;; 이해가 안되는 부분이군요.)



Controlling movement

점들이 움직일 수 있는 방향을 결정하는 것은 Graphics State 변수인 freedom_vector에서 이루어집니다.

점이 움직였을 때, 점의 움직임은 freedom_vector의 방향과 평행하도록 제약을 받습니다. freedom_vector가 양의 x축 방향(동쪽)을 가리키고 있다고 가정한다면, 양의 x축 방향으로 움직이는 것은 양의 크기를 갖게 될 것입니다. 그러나 음의 x축 방향인 서쪽으로 움직였다면 음의 크기를 갖게 될 것입니다.

Moving points

WARNING: 점을 움직일 때, freedom-vector와 projection_vector가 직교가 되어서는 안 된다.

외곽의 선들을 이동시키는 명령어는 몇 가지가 있습니다. 이러한 명령어들은 레퍼런스 점들에 대해서 상대적으로 옮기거나(the relative instructions) 좌표 계에서 특정 위치로 점을 옮기는 것입니다.(the absolute instructions)

다음의 figure2-5는 상대적인 움직임을 설명합니다. 점 p는 레퍼런스 점인 rp로부터 d 만큼의 거리가 되도록 이동되었습니다.

Figure 2-5. 상대적인 이동




아래의 Figure 2-6은 절대적인 이동을 설명합니다. 여기의 점 p는 현재의 위치로부터 새 위치로 거리 p만큼 이동합니다. 간격은 projection-vector에 의해서, 이동은 freedom_vector에 의해서 측정됩니다.

Figure 2-6. 절대적인 이동



이동에 대해 좀 더 상세하게 말한다면, 특정 이동 명령은 외곽선의 거리(outline distance)를 사용합니다. (direct instructions) 반면에 다른 명령어들은 CVT상에서 언급되어 있는 값인 d의 값, 또는 스택 상의 값을 지정하기도 합니다.(indirect instructions)

점을 이동시키기로 결정하였다면 처음으로 결정해야 하는 것은 방향과 거리입니다. 이 외에는 점을 절대적 거리로 옮길 것인지 또는 상대적으로 다른 점으로 옮길 것인지를 결정하는 것입니다. 만약 이동이 상대적이라면, 명령어에 의해서 어떠한 레퍼런스 점이 사용될 것인지를 확인해야 합니다. 어떤 경우에는, 사용하기를 원했던 레퍼런스 점의 값을 변경해야 할 필요도 있을 것입니다. 최종적으로는 오리지널 외곽선의 거리를 사용할지 CVT의 거리를 언급할 것인지 또는 스택의 거리에 있는 거리를 사용해야 할 지를 결정해야 합니다.

오리지널 외곽선의 거리를 선택했다면, 두 점 사이의 오리지널 디자인 거리에 대해서 보호를 해야 합니다. 반대로, 간접적인 방법(CVT를 사용하는 것 같은)으로 거리를 명세했다면 당신은 폰트 또는 glyph을 위하여 중요한 값들을 거리에 일치시키는 것을 허락해야 합니다.

MSIRP 단 하나의 예외를 제외하고는 모든 이동 명령어들은 round_state에 의해 영향을 받습니다. 명령어들은 round_state 변수의 값을 기억해 두어야 할지 말지에 대해서 선택할 수 있게 해줍니다. 실제로는, rounding이 켜져 있는 경우에는 점이 실제로 움직이는 경우 rounding 타입에 의해서 영향을 받게 된 다는 것을 의미합니다.

아래의 예제를 보면, 점 p는 새로운 위치인 p’로 이동하기 위해서 거리 d만큼 움직인 다음에 가장 가까운 grid 경계로 이동하였습니다. (반올림)

Figure 2-7. grid로 반올림하기 위한 round_state를 사용한 절대 이동


댓글 2개:

  1. 이 글은 대략 인기가 없구려 ^^

    답글삭제
  2. 뭐 폰트 파싱하는 사람이나 폰트엔진 분석하거나 만드는 사람한테나 소용있을까요?

    답글삭제