들어가며

3개 시리즈에 걸쳐 UI 디자인 툴에서의 SVG 내보내기 최적화 이론에 대해 알아보았다.
정리할수록 SVG 자체에 대한 몰이해가 느껴져, 적당히 넘어갔던 부분을 기초부터 정리해보면서 노트한 내용을 적어보려 한다.

아래 내용은 MDN의 SVG 튜토리얼을 읽으면서 궁금증이 생긴 부분을 정리하고 중요한 부분을 노트한 것으로, 일반적으로 알려지지 않은 SVG의 특징들을 나열한 수준이다.

Scalable Vector Graphics

스케일러블 벡터 그래픽스(Scalable Vector Graphics, SVG)는 2차원 벡터 그래픽을 표현하기 위한 XML 기반의 파일 형식이다.
Wikipedia의 SVG 문서 첫번째 문장

SVG는 XML의 방언(dialect)이다.
HTML과 달리 요소명에 대소문자를 구분하는 것은 XML의 표준을 따르는 것이다.
XML은 데이터 데이터 교환을 위해 확장 가능성을 중시한 마크업 언어로, 1996년에 처음으로 제안되고 1998년 W3C(World Wide Web Consortium)에서 공개한 표준을 기원으로 한다.
단순하면서도 메타데이터를 자유롭게 기록하고, 웹상에서 데이터를 교환하기 위해 최적화된 XML 특성상 엄청나게 많은 방언이 난립하지만, 그중에서도 SVG는 W3C가 직접 표준을 개발하는 근본 언어이다.

SVG의 첫번째 버전은 2001년으로, 1996년부터 W3C는 향후 웹 발전에 따른 벡터 그래픽의 유용함을 예측하고, 요구 사항을 작성해두었다.
1998년부터 W3C로 제출된 위 요구사항을 따르는 여러 제안을 결합하여 승인된 표준이 바로 SVG이다.
2003년이 되어서야 권고 수준으로 승격되었고, 2022년이 끝나는 현재에도 2011년에 권고된 1.1 버전이 완벽한(논의중인 기능이 없는) 버전이다.

재미있는 부분은, 당시 제안에는 어도비, 오토데스크, 마이크로소프트 등 현재에도 그래픽 분야에서 쟁쟁한 기업들의 전문가들이 참여했는데,
어도비의 경우 제안 수준으로 제출하여 W3C측에서 자유롭게 수정하고 참고할 수 있다고 명시한 반면,
마이크로소프트와 오토데스크의 경우 완성된 제품으로 제출하여, 모든 권리를 제출한 기업이 가진다고 명시해두었다.
두 제안 모두 자사의 제품용 형식(PostScript와 PDF, Powerpoint와 IE의 Active X)을 위해 만들어졌지만, 기능적인 부분 외에도 그 권리에 대한 내용 덕분에 어도비의 PGML(Precision Graphics Markup Language)이 SVG 작성에 더 큰 영향력을 끼치고, 향후 어도비 자체 어플리케이션과의 유연한 호환을 가능하게 했다고 볼 수도 있겠다.

<canvas>와 SVG

HTML을 구조적 기반으로 하는 웹 환경에서, 텍스트로 이루어진 도형의 정보를 기반으로 렌더링하는 SVG는 HTML5의 canvas 요소와 비교되는 관계라고 할 수 있다.
간단하게 차이점을 비교해보자.

canvas는 API이다.

canvas 요소의 렌더링을 위해서는 자바스크립트의 자체 canvas API나 WebGL API를 사용한다.
그렇기 때문에 그려지는 도형의 정보는 스크립트를 통해 기록되고, 전달되어 렌더링 된 이후에는 버려진다.
결정적으로, 렌더링 시의 해상도로 픽셀 사이즈가 고정되는, 래스터 그래픽을 결과물로 그려낸다.

SVG는 마크업 언어이다.

XML의 방언으로서, SVG는 그 자체로 DOM(Document Object Model)을 가지며, 모든 요소는 문서 내의 객체가 된다.
마크업에서는 각 도형 요소를 의미하는 태그를 직관적으로 확인 가능하며, 스크립트 상에서도 DOM 메서드를 통해 요소에 접근하고, 이미 그려진 요소 역시 수정 가능하다.

뭔가 canvas는 비교적(?) 최신이라고 느껴지는 HTML5 표준이라 더 나은 것인가 싶을 수 있지만, 사실상 동적 컨텐츠의 실시간 렌더링을 위한 API에 가깝다.
웹 환경을 위한 벡터 그래픽에 대한 논의만큼이나 오랜 기간 세부내용을 확립해온 SVG가 일반적인 환경을 위해 최적화되어 있다고 할 수 있겠다.

Namespace

<svg version="1.1"
     baseProfile="full"
     width="100" height="100"
     viewbox="0 0 100 100"
     xmlns="http://www.w3.org/2000/svg">

  <!-- defs, 도형 등 영역 -->

</svg>

위 코드는 '모범적인' SVG 코드의 루트 요소 형식이다.
SVG의 버전과 프로필(full, basic, tiny 등이 있다.)이 추가된 것을 제외하면 자주 본 형식이지만, XML 형식이라 하면 유효성 검사를 위해 필수적이라고 생각되는 DTD(Document Type Definition)가 포함되어 있지 않다.
웹 표준인 SVG 1.1 버전의 DTD는 존재하지만, DTD는 사실 여러 방언이 혼합된 XML 문서에서 단위 문서(컨텐츠)를 식별하는 것을 염두에 둔 설계가 아니다.
(당장 DOCTYPE은 반드시 문서의 첫 줄에 명시해야 한다.)
그렇기 때문에 지금은 DTD를 통한 혼합 컨텐츠의 유효성 검사는 실패한 것으로 간주하며, W3C의 SVGDTD 문서 상에서도 올바른 네임스페이스를 바인딩하여 유효성을 검사하기를 권고하고 있고, SVG 1.2에서는 아예 DOCTYPE 선언 내용이 제외되었다.

여기서 이 '네임스페이스'가 바로 루트 요소의 XML NameSpace, 즉 xmlns="http://www.w3.org/2000/svg" 특성이다.
이 값을 기준으로 브라우저(XML 콘텐츠 파서)는 해당 요소 <svg>가 알 수 없는 임의의 요소가 아닌 단위 XML 파일이라는 것을 알 수 있으며, <title>과 같은 html과 svg에서 다른 의미로 사용되는 요소에 대한 구분을 할 수 있다.

대부분의 네임스페이스가 URI 형식이지만, 사실 유효성 검사를 위해 해당 URI에 연결하거나 하지는 않고 단순 문자열로만 인식한다.
그렇기 때문에 정확한 용어는 '네임스페이스 이름'이지만, 워낙 대부분의 이름이 URI 형식으로 정의되고 해당 주소의 URL에서 네임스페이스에 대한 정의를 찾을 수 있도록 준비되어 있어 일반적으로 '네임스페이스 URI'라는 용어를 사용하는 편이다.

위 코드에서 사용된 바와 같이 특정 요소에서 특성으로 정의된 네임스페이스는 해당 요소와 그 하위 요소에 대한 기본 네임스페이스로 선언되며,
쓸 일은 없겠지만 상위 요소에 xmlns:svg 형식으로 접미사 요소 <svg>에 대한 네임스페이스를 지정할 수 있다.
SVG파일에서 xmlns:xlink="http://www.w3.org/1999/xlink" 특성이 지정된 경우가 많은데, 이는 보통 xlink:href로 사용하는 xlink(XML 외부 링크)를 통해 외부의 파일이나 위치에 접근하기 위한 특성 접두사로서의 네임스페이스 선언이다.

혼합 XML에서의 스크립팅

스크립트에서 문서 구조에 접근하기 위한 DOM의 레벨 1 권장사항은 무려 1998년, XML 권장 사항의 네임스페이스가 정의되기도 전에 만들어졌다.
당연히 SVG와 같은 하위 XML 문서가 혼합된 DOM 구조에서 문제가 생겼고, 2000년 권고된 DOM 레벨 2에서 혼합 XML을 위한 DOM 메서드가 추가되었다.

보통 기존 DOM용 메서드(createAttribute, createElement 등) 뒤에 NS(NameSpace)가 붙은 형태(createAttributeNS, createElementNS 등)이고,
기존 메서드와 다르게 첫번째 매개변수로 해당 요소나 특성의 네임스페이스 이름을 지정해야 한다.
하지만 네임스페이스가 지정되어 있지 않은(정규화되지 않은) 특성의 경우 첫번째 매개변수 값이 null이어야 하며,
xlink:href와 같이 접두사에 대한 네임스페이스가 지정되어있는 특성인 경우에만 첫번째 매개변수에 네임스페이스 이름을 지정한다.

// svg 하위 도형 요소 생성
document.createElementNS("http://www.w3.org/2000/svg", "rect");

// 네임스페이스가 지정되지 않은 특성 x의 값
rect.getAttributeNS(null, "x");

// 네임스페이스가 지정된 특성 href의 값
image.getAttributeNS("http://www.w3.org/1999/xlink", "href");

마무리

처음에는 단순히 XML로서의 SVG를 정확히 알아보려고 시작했지만, 예상 외로 자바스크립트를 통한 하위 네임스페이스 XML 조작에 대한 내용까지 정리하게 되었다.
웹 상에서의 벡터 애니메이션은 개인적으로 언젠가는 구현해보고 싶은 부분이라, 정확한 이론을 짚어보고 넘어가는 기회가 되었다.
이전 SVG 최적화 방안을 정리하면서 쓴 내용에서 가볍게 넘어간 부분에서 오류가 발생한 부분도 확인하게 되어, 차후 시간이 된다면 해당 부분 역시 수정할 예정이다.

0개의 댓글