Skip to content

Instantly share code, notes, and snippets.

@johan
Forked from johan/github-logo.svg
Created June 25, 2012 00:20
Show Gist options
  • Save johan/2985682 to your computer and use it in GitHub Desktop.
Save johan/2985682 to your computer and use it in GitHub Desktop.
SVG font exposition
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<!DOCTYPE html>
<html><head>
<title>Embedded SVG Fonts: a hands-on/view-source example</title>
</head><body>
<p>This whole page is a kind of "view source" hands-on exposition on how embedded (or not embedded, for that matter) SVG fonts work, if you feel up to a little cross-referencing of the data in the logo and in this break-down of its glyph paths. The tidy github logo plays the role of example:</p>
<svg width="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10000 4419">
<defs><font horiz-adv-x="535">
<font-face font-family="Futura Heavy" panose-1="2 11 9 2 2 2 4 2 2 3" ascent="1002" descent="-264" units-per-em="1000" alphabetic="0"/>
<glyph unicode=" " horiz-adv-x="289"/>
<glyph unicode="S" horiz-adv-x="526" d="m409 588q-21 29-48 45t-65 17q-18 0-34-6t-29-18-21-27-8-34q0-32 22-51t55-34 72-31 72-42 56-66 22-103q0-57-17-104t-49-81-78-54-104-19q-78 0-135 40t-97 107l95 93q7-22 20-42t32-35 39-24 45-9q22 0 40 9t31 24 19 34 7 42q0 29-12 49t-31 33-42 23-46 18q-36 15-67 32t-53 42-35 56-13 76q0 47 16 88t46 72 70 48 88 18q25 0 54-6t57-17 53-26 42-35l-69-102"/>
<glyph unicode="O" horiz-adv-x="782" d="m764 378q0-83-26-155t-74-127-118-85-155-31q-86 0-155 31t-117 85-75 126-26 156q0 84 26 156t76 126 118 83 153 31q84 0 153-30t118-84 75-125 27-157zm-152 6q0 46-15 90t-43 78-70 56-93 21q-52 0-93-21t-69-55-44-79-15-90q0-44 11-89t38-84 69-62 103-24q61 0 103 24t68 62 38 83 12 90"/>
<glyph unicode="C" horiz-adv-x="601" d="m558 554q-31 38-74 59t-92 21q-53 0-94-22t-69-59-44-83-15-96q0-48 15-93t44-81 70-58 92-22q48 0 92 22t75 58v-175q-42-20-83-32t-88-13q-80 0-147 32t-117 85-77 125-28 149q0 80 27 153t76 128 117 89 152 33q45 0 87-11t81-33"/>
<glyph unicode="I" horiz-adv-x="254" d="m201 0h-147v754h147"/>
<glyph unicode="A" horiz-adv-x="676" d="m208 159l-62-159h-155l294 774h114l286-774h-157l-58 159h-262zm127 394h-2l-83-274h179l-94 274"/>
<glyph unicode="L" horiz-adv-x="402" d="m201 128h208v-128h-355v754h147"/>
<glyph unicode="D" horiz-adv-x="646" d="m54 754h210q82 0 149-29t115-79 74-120 26-150q0-80-27-148t-75-119-115-80-148-29h-209v754zm147-626h24q68 0 115 18t78 50 44 79 14 102q0 124-62 186t-189 63h-24"/>
<glyph unicode="N" horiz-adv-x="759" d="m54 774h106l397-527h2v507h147v-769h-106l-397 527h-2v-512h-147"/>
<glyph unicode="G" horiz-adv-x="739" d="m720 401v-19q0-80-20-152t-63-128-107-89-153-33q-83 0-149 32t-113 87-72 125-25 150q0 81 26 153t74 127 116 87 152 33q97 0 175-46t123-134l-130-70q-23 51-68 85t-104 35q-53 0-93-24t-66-64-40-87-13-95q0-47 13-94t40-85 67-61 93-24q34 0 65 14t54 37 38 55 15 65h-160v120"/>
<hkern u1="C" u2="O" k="6"/>
</font></defs>
<g class="collegiate-regular">
<path d="m1281 1189c155 0 334-39 537-116v498c-45 16-110 34-193 53 26 74 39 143 39 208 0 206-62 386-186 539s-285 244-481 273c-129 19-193 89-193 208 0 42 21 84 63 126 55 61 135 100 242 116 461 71 691 263 691 575 0 500-298 749-894 749-245 0-447-44-604-131-200-109-300-282-300-517 0-271 150-456 450-556v-10c-110-68-164-171-164-310 0-181 52-293 155-338v-10c-103-35-195-116-276-242-90-135-135-281-135-435 0-232 82-426 247-580 158-145 347-218 566-218 158 0 305 39 440 116zm19 2543c0-164-135-247-406-247-261 0-392 85-392 256 0 168 142 251 426 251 248 0 372-87 372-261zm-745-1857c0 222 102 334 305 334 197 0 295-113 295-339 0-94-23-174-68-242-55-74-131-111-227-111-203 0-305 119-305 358"/>
<circle cx="2331" cy="360" r="360"/>
<path d="m2055 3244c6-65 10-174 10-329v-1504c0-152-3-256-10-314h546c-7 61-10 163-10 305v1484c0 164 3 284 10 358"/>
<path d="m3602 1098h421v469c-16 0-46-2-90-5s-85-5-123-5h-208v899c0 216 71 324 213 324 100 0 190-27 271-82v484c-119 65-263 97-430 97-235 0-398-84-488-251-68-126-102-324-102-595v-865h5v-10l-73-5c-42 0-97 5-164 15v-469h237v-189c0-90-5-163-15-218h561c-10 61-15 131-15 208"/>
<path d="m5300 1083c-139 0-284 48-435 145v-846c0-184 3-305 10-363h-551c10 52 15 172 15 363v2558c0 148-5 250-15 305h561c0-10-3-49-10-118-6-69-10-131-10-186v-1189c113-106 222-160 329-160 123 0 216 61 280 184 48 97 73 218 73 363l-5 653c0 110-8 261-24 455h585c-13-81-19-229-19-445v-662c0-280-63-519-189-716-142-226-340-339-594-339"/>
<path d="m7012 3264c-255 0-443-113-566-339-97-184-145-424-145-720v-662c0-219-6-367-19-445h580c-10 71-16 222-19 455l-5 653c0 184 21 316 63 396 48 100 137 150 266 150 90 0 192-53 305-160v-1189c0-55-3-118-10-189s-10-110-10-116h561c-6 55-10 156-10 305v1480c0 190 3 311 10 363h-527v-174c-148 129-306 193-474 193"/>
<path d="m9188 3259c-174 0-319-63-435-189v174h-513c10-55 15-156 15-305v-2558c0-190-5-311-15-363h551c-7 58-10 179-10 363v841c148-94 293-140 435-140 255 0 455 113 600 339 122 197 184 435 184 716 0 287-65 537-193 749-155 248-362 372-619 372zm-73-1668c-106 0-218 53-334 160v836c103 100 205 150 305 150 126 0 221-69 285-208 52-110 77-240 77-392 0-364-111-546-334-546"/>
</g>
<text x="1984" y="4352" font-family="Futura Heavy" font-size="1096">SOCIAL CODING</text>
</svg>
<p>In this SVG version of it, the "SOCIAL CODING" part is actually encoded as human- and machine readable, web-spider indexable, user-selectable plain text, rendered as the logo font (<a href="http://www.fonts.com/font/linotype/futura/heavy/web-font">Futura Heavy</a>) would, since the glyphs used are actually embedded in the file itself (don't pay too much attention to the font size; I've set a huge <code>viewBox</code>):</p>
<pre><code>&lt;text x="1984" y="4352" font-family="Futura Heavy" font-size="1096"&gt;SOCIAL CODING&lt;/text&gt;
</code></pre>
<p>At present time of writing (2012-06-24, Chrome 19 era), not all browsers grok SVG font kern tables, but Opera does. (Typesetter points to you if you can tell which character pair gets miskerned without looking at the source, if your browser doesn't! :-)</p>
<svg width="100%" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 9000 1266">
<defs>
<marker id="dot" viewBox="-2 -2 4 4" markerUnits="userSpaceOnUse" markerWidth="12" markerHeight="12">
<circle r="2"></circle>
</marker>
</defs>
<g id="font" transform="translate(100 1002)scale(1 -1)">
<circle fill="red" cx="409" cy="588" r="20"/>
<circle fill="red" cx="1764" cy="378" r="20"/>
<circle fill="red" cx="2558" cy="554" r="20"/>
<circle fill="red" cx="3201" cy="0" r="20"/>
<circle fill="red" cx="4208" cy="159" r="20"/>
<circle fill="red" cx="5201" cy="128" r="20"/>
<circle fill="red" cx="6054" cy="754" r="20"/>
<circle fill="red" cx="7054" cy="774" r="20"/>
<circle fill="red" cx="8720" cy="401" r="20"/>
<path unicode="S" horiz-adv-x="526" marker-mid="url(#dot)" transform="translate(0000 0)" d="M409 588Q388 617 361 633T296 650Q278 650 262 644T233 626T212 599T204 565Q204 533 226 514T281 480T353 449T425 407T481 341T503 238Q503 181 486 134T437 53T359 -1T255 -20Q177 -20 120 20T23 127L118 220Q125 198 138 178T170 143T209 119T254 110Q276 110 294 119T325 143T344 177T351 219Q351 248 339 268T308 301T266 324T220 342Q184 357 153 374T100 416T65 472T52 548Q52 595 68 636T114 708T184 756T272 774Q297 774 326 768T383 751T436 725T478 690L409 588Z"/>
<path unicode="O" horiz-adv-x="782" marker-mid="url(#dot)" transform="translate(1000 0)" d="M764 378Q764 295 738 223T664 96T546 11T391 -20Q305 -20 236 11T119 96T44 222T18 378Q18 462 44 534T120 660T238 743T391 774Q475 774 544 744T662 660T737 535T764 378ZM612 384Q612 430 597 474T554 552T484 608T391 629Q339 629 298 608T229 553T185 474T170 384Q170 340 181 295T219 211T288 149T391 125Q452 125 494 149T562 211T600 294T612 384Z"/>
<path unicode="C" horiz-adv-x="601" marker-mid="url(#dot)" transform="translate(2000 0)" d="M558 554Q527 592 484 613T392 634Q339 634 298 612T229 553T185 470T170 374Q170 326 185 281T229 200T299 142T391 120Q439 120 483 142T558 200V25Q516 5 475 -7T387 -20Q307 -20 240 12T123 97T46 222T18 371Q18 451 45 524T121 652T238 741T390 774Q435 774 477 763T558 730V554Z"/>
<path unicode="I" horiz-adv-x="254" marker-mid="url(#dot)" transform="translate(3000 0)" d="M201 0H54V754H201V0Z"/>
<path unicode="A" horiz-adv-x="676" marker-mid="url(#dot)" transform="translate(4000 0)" d="M208 159L146 0H-9L285 774H399L685 0H528L470 159H208ZM335 553H333L250 279H429L335 553Z"/>
<path unicode="L" horiz-adv-x="402" marker-mid="url(#dot)" transform="translate(5000 0)" d="M201 128H409V0H54V754H201V128Z"/>
<path unicode="D" horiz-adv-x="646" marker-mid="url(#dot)" transform="translate(6000 0)" d="M54 754H264Q346 754 413 725T528 646T602 526T628 376Q628 296 601 228T526 109T411 29T263 0H54V754ZM201 128H225Q293 128 340 146T418 196T462 275T476 377Q476 501 414 563T225 626H201V128Z"/>
<path unicode="N" horiz-adv-x="759" marker-mid="url(#dot)" transform="translate(7000 0)" d="M54 774H160L557 247H559V754H706V-15H600L203 512H201V0H54V774Z"/>
<path unicode="G" horiz-adv-x="739" marker-mid="url(#dot)" transform="translate(8000 0)" d="M720 401V382Q720 302 700 230T637 102T530 13T377 -20Q294 -20 228 12T115 99T43 224T18 374Q18 455 44 527T118 654T234 741T386 774Q483 774 561 728T684 594L554 524Q531 575 486 609T382 644Q329 644 289 620T223 556T183 469T170 374Q170 327 183 280T223 195T290 134T383 110Q417 110 448 124T502 161T540 216T555 281H395V401H720Z"/>
</g>
<script>
var g = [].slice.call(document.querySelectorAll('#font path'))
, h = g.map(rectify)
, m = Math.max.apply(Math, h)
, r = g.map(charbox)
;
function rectify(p) {
var b = p.getBBox()
, r = document.createElementNS(p.namespaceURI, 'rect')
;
['x', 'y', 'width', 'height'].forEach(function(a) {
r.setAttribute(a, b[a]);
});
r.setAttribute('fill', 'rgba(0,0,0,0)');
r.setAttribute('stroke', 'rgba(0,0,0,0.4)');
r.setAttribute('stroke-width', '2');
r.setAttribute('transform', p.getAttribute('transform'));
p.parentNode.insertBefore(r, p);
return b.height;
}
function charbox(p, i) {
var b = p.getBBox()
, r = document.createElementNS(p.namespaceURI, 'rect')
, c = document.createElementNS(p.namespaceURI, 'circle')
, g = p.parentNode
;
c.setAttribute('cx', i * 1000);
c.setAttribute('cy', 0);
c.setAttribute('r', 10);
c.setAttribute('fill', 'rgba(255,0,0,0.5)');
r.setAttribute('x', 0);
r.setAttribute('y', -264); // descent
r.setAttribute('width', p.getAttribute('horiz-adv-x'));
r.setAttribute('height', 1002 + 264); // ascent
r.setAttribute('fill', 'rgba(0,0,0,0)');
r.setAttribute('stroke', 'rgba(0,0,0,0.2)');
r.setAttribute('stroke-width', '2');
r.setAttribute('transform', p.getAttribute('transform'));
g.insertBefore(r, p);
g.insertBefore(c, p);
}
</script>
</svg>
<p>Since SVG fonts, like other font standards, measure coordinates with the baseline at 0,0 of the coordinate system, increasing numbers moving upwards, unlike how SVG coordinates work in general, I've applied a vertical flip transform (<code>scale(1 -1)</code>) to make it look right. For reference, I also painted the "total glyph size" and "glyph used space" outlines, and marked the location of 0,0 and the beginning of each path with little red dots. Enjoy!</p>
</body></html>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment