## 책 정보 [밑바닥부터 시작하는 웹 브라우저](https://www.hanbit.co.kr/store/books/look.php?p_code=B6818199506) > [!NOTE] > 코드를 계속 수정하면서 기록했기 때문에 초반의 코드와 후반의 코드가 좀 다를 수 있습니다. ## 폰트(서체)란? 옛날에 금속 활자를 사용하던 시절에 문자들을 케이스에 담아서 보관했었다. 대문자용 활자 케이스를 upper-case, 소문자용 활자 케이스를 lower-case라고 불렀고, 이 케이스의 집합을 폰트라고 했다. (foundry에서 유래) 여러 사이즈의 문자를 인쇄하기 위해서 여러 폰트들이 필요했고, 이러한 폰트의 집합을 타입(type)이라고 불렀는데 타이핑이라는 말이 여기서 유래했다. 글자의 굵기나 기울기 같은 변형은 타입의 페이스(face)라고 불렀다. (ㄴ(°0°)ㄱ) 오늘날 폰트는 글꼴, 서체, 타입을 의미하고, 글자 두께나 스타일, 크기를 의미한다. Tk에는 폰트 객체가 있는데, 고정된 크기, 스타일, 글자 두께 같은 정보를 담을 수 있다. 이렇게 정의한 폰트 객체는 create_text에 전달해서 사용할 수 있다. ```python import tkinter.font window = tkinter.Tk() bi_times = tkinter.font.Font( family="Times", size=16, weight="bold", slant="italic" ) canvas = tkinter.Canvas(window, width=400, height=300) canvas.pack() canvas.create_text(200, 150, text="Hello World!", font=bi_times) window.mainloop() ``` ![[73846ae1-e21b-405b-9dcf-c19585b47e30.png]] ## 텍스트 측정하기 텍스트가 차지하는 공간은 폰트 객체의 metrics와 mesure 메서드로 측정할 수 있다. metrics 메서드로는 텍스트의 세로 축에 대한 정보를 알 수 있다. ![[2bfcc1c2-4222-4032-a56c-9e6a5c01f365.png]] 출처: [Formatting Text \| Web Browser Engineering](https://browser.engineering/text.html) - linespace : 텍스트의 높이 - ascent : 기준선(baseline) 윗부분의 높이 - descent : 기준선 아랫부분의 높이 ![[0b14251b-b775-4306-872b-7d5ec9effc1a.png]] bi_times의 폰트 크기를 16으로 설정했었는데 font.metrics로 출력해보니 linespace가 19로 나온다. 우선 우리가 설정한 font size 16은 16픽셀이 아니라 16포인트이다. 포인트는 1/72인치를 의미하는 단위이다. (포인트의 정의는 전세계적으로 다양하다. 참고 : [Point (typography) - Wikipedia](https://en.wikipedia.org/wiki/Point_(typography)))) 보통 모니터는 1인치에 100개 정도의 픽셀을 나타내는 것이 일반적이므로 1픽셀은 1/100인치정도 된다고 할 수 있다. 즉 포인트 !== 픽셀이라는 것이다. 폰트는 금속 활자 시대에서 유래한 용어라고 했다. font size에서 지정한 16포인트는 "글자의 크기"가 아닌 "글자를 인쇄하는 금속 활자의 크기"를 의미한다. 금속 활자는 글자 자체 외에도 줄간격 등을 위해서 일부 여백을 포함해야 했기 때문에 실제 글자 크기는 font size보다 좀 더 작았다. > [!tip] 근데 왜 linespace는 16보다 큰 값을 가질까 > linespace는 텍스트의 높이를 의미하고, 텍스트의 높이에는 ascent와 descent, 그리고 줄간격(leading)이 포함된다. 따라서 실제 글자 크기는 16보다 작더라도, 여백이 더해지면서 linespace는 16보다 더 커지는 것이다. > 실제로 폰트마다 이런 여백들이 조금씩 다르기 때문에 크기가 16인 폰트들의 linespace도 다양하다. > ![[fd8e29b5-2bd0-4844-9a0e-07363437c8ab.png]] measure 메서드는 텍스트가 차지하는 가로 공간의 크기를 알려준다. 글자마다 너비가 다르기 때문에 같은 폰트라도 텍스트에 따라 크기가 다르다. 책에서는 각 글자의 너비 합이 전체 너비의 합과 같았는데 내가 직접 해봤을때는 그렇지 않았다. Tk는 내부적으로 실수 형태로 값을 다루는데, measure를 호출했을 때는 반올림해서 반환한다. 이 과정에서 오차가 생길 수도 있다. ![[ce8ab270-fb24-4764-befa-3723230e2487.png]] 이 정보를 이용해서 페이지에 텍스트를 적절히 배치할 수 있다. ```python import tkinter.font window = tkinter.Tk() font1 = tkinter.font.Font(family="Times", size=16) font2 = tkinter.font.Font(family="Times", size=16, slant="italic") canvas = tkinter.Canvas(window, width=400, height=300) canvas.pack() x, y = 200, 200 canvas.create_text(x, y, text="Hello, ", font=font1) x += font1.measure("Hello, ") canvas.create_text(x, y, text="world!", font=font2) window.mainloop() ``` ![[7bc8bde0-e57b-4c4f-81e7-2de5e7dc190e.png]] "world!"를 "overlapping!"으로 변경하면 글자가 겹친다. 우리가 create_text에전달한 x, y값이 글자의 중심 좌표였기 때문인데, anchor ## 한 단어씩 처리하기 ## 텍스트에 스타일 주기 ## 레이아웃 객체 ## 다양한 크기의 텍스트