master
yutent 2024-02-04 18:46:04 +08:00
parent a064679ddf
commit eb4a0119e0
9 changed files with 155 additions and 1 deletions

View File

@ -5,3 +5,15 @@
*/ */
export { svg2ttf } from './lib/core.js' export { svg2ttf } from './lib/core.js'
export function createFont(opt = {}) {
//
}
/**
* @param input {StringBuffer, path} svg, ttf字体
* @return {Font} 字体对象
*/
export function transfer(input, opt = {}) {
//
}

25
src/lib/base.js Normal file
View File

@ -0,0 +1,25 @@
/**
* {基类}
* @author yutent<yutent.io@gmail.com>
* @date 2024/02/04 18:13:31
*/
export class Controller {
#options = {}
constructor(opt) {
this.setOptions(opt)
}
setOptions(opt = {}) {
Object.assign(this.#options, opt)
}
$get(k) {
return this.#options[k]
}
$set(k, v) {
this.#options[k] = v
}
}

81
src/lib/config.js Normal file
View File

@ -0,0 +1,81 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2024/02/04 18:18:04
*/
//导出svg的配置
export const DEFAULT_EXPORT_OPTIONS = {
width: '100px',
height: '100px'
}
//path 保留小数位
export const PATH_DECIMAL = 4
export const FONT_FAMILY = 'iconfont'
//默认的配置参数
export const DEFAULT_OPTIONS = {
font: {
id: FONT_FAMILY,
horizAdvX: 1024,
vertAdvY: 1024
},
fontface: {
fontFamily: FONT_FAMILY,
fontWeight: '400',
fontStretch: 'normal',
unitsPerEm: '1024',
ascent: '812',
descent: '-212'
},
glyph: {
unicode: '',
glyphName: '',
d: '',
horizAdvX: 1024,
vertAdvY: 1024
}
}
export const FONT_TMPL = `
<?xml version="1.0" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
<svg>
<metadata>
Created by font-carrier
</metadata>
<defs>
<font id="<%= font.id %>" horiz-adv-x="<%= font.horizAdvX %>" vert-adv-y="<%= font.horizAdvX %>" >
<font-face
<% for(var v in fontface){ %>
<% print(v + '="' + fontface[v] + '"') %>
<%} %>
/>
<missing-glyph />
<% if(!hasX){ %>
<glyph glyph-name="x" unicode="&#x78;" horiz-adv-x="100"
d="M20 20 L50 20 L50 -20 Z" />
<% } %>
<% for(var i in glyphs){
var glyph = glyphs[i].options;
%>
<glyph glyph-name="<%= glyph['glyphName'] %>" unicode="<%= glyph['unicode']%>" d="<%= glyph['d']%>" <% if (glyph['horizAdvX']) print('horiz-adv-x="'+ glyph['horizAdvX']+'"') %> <% if (glyph['vertAdvY']) print('vert-adv-y="'+ glyph['vertAdvY']+'"') %> />
<% } %>
</font>
</defs>
</svg>
`
export const SVG_TMPL = `
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" <% if(!options['skipViewport']){ %> x="0" y="0" width="<%= options['width'] %>" height="<%= options['height'] %>" <% } %> viewBox="0 0 <%= glyph['horizAdvX'] %> <%= glyph['vertAdvY'] %>">
<path d="<%= glyph['d'] %>"/>
</svg>
`

14
src/lib/font.js Normal file
View File

@ -0,0 +1,14 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2024/02/04 18:16:10
*/
import { Controller } from './base.js'
import { DEFAULT_OPTIONS } from './config.js'
export class Font extends Controller {
constructor(opt) {
super(Object.assign({}, DEFAULT_OPTIONS.font, opt))
}
}

14
src/lib/glyph.js Normal file
View File

@ -0,0 +1,14 @@
/**
* {}
* @author yutent<yutent.io@gmail.com>
* @date 2024/02/04 18:16:10
*/
import { Controller } from './base.js'
import { DEFAULT_OPTIONS } from './config.js'
export class Font extends Controller {
constructor(opt) {
super(Object.assign({}, DEFAULT_OPTIONS.glyph, opt))
}
}

View File

@ -91,6 +91,7 @@ export function load(str) {
fontElem = doc.getElementsByTagName('font')[0] fontElem = doc.getElementsByTagName('font')[0]
if (!fontElem) { if (!fontElem) {
console.log(doc)
throw new Error( throw new Error(
"Can't find <font> tag. Make sure you SVG file is font, not image." "Can't find <font> tag. Make sure you SVG file is font, not image."
) )

1
test/game.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><path d="M483.13 245.38C461.92 149.49 430 98.31 382.65 84.33A107.13 107.13 0 00352 80c-13.71 0-25.65 3.34-38.28 6.88C298.5 91.15 281.21 96 256 96s-42.51-4.84-57.76-9.11C185.6 83.34 173.67 80 160 80a115.74 115.74 0 00-31.73 4.32c-47.1 13.92-79 65.08-100.52 161C4.61 348.54 16 413.71 59.69 428.83a56.62 56.62 0 0018.64 3.22c29.93 0 53.93-24.93 70.33-45.34 18.53-23.1 40.22-34.82 107.34-34.82 59.95 0 84.76 8.13 106.19 34.82 13.47 16.78 26.2 28.52 38.9 35.91 16.89 9.82 33.77 12 50.16 6.37 25.82-8.81 40.62-32.1 44-69.24 2.57-28.48-1.39-65.89-12.12-114.37zM208 240h-32v32a16 16 0 01-32 0v-32h-32a16 16 0 010-32h32v-32a16 16 0 0132 0v32h32a16 16 0 010 32zm84 4a20 20 0 1120-20 20 20 0 01-20 20zm44 44a20 20 0 1120-19.95A20 20 0 01336 288zm0-88a20 20 0 1120-20 20 20 0 01-20 20zm44 44a20 20 0 1120-20 20 20 0 01-20 20z"/></svg>

After

Width:  |  Height:  |  Size: 900 B

1
test/home.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" class="ionicon" viewBox="0 0 512 512"><path d="M261.56 101.28a8 8 0 00-11.06 0L66.4 277.15a8 8 0 00-2.47 5.79L63.9 448a32 32 0 0032 32H192a16 16 0 0016-16V328a8 8 0 018-8h80a8 8 0 018 8v136a16 16 0 0016 16h96.06a32 32 0 0032-32V282.94a8 8 0 00-2.47-5.79z"/><path d="M490.91 244.15l-74.8-71.56V64a16 16 0 00-16-16h-48a16 16 0 00-16 16v32l-57.92-55.38C272.77 35.14 264.71 32 256 32c-8.68 0-16.72 3.14-22.14 8.63l-212.7 203.5c-6.22 6-7 15.87-1.34 22.37A16 16 0 0043 267.56L250.5 69.28a8 8 0 0111.06 0l207.52 198.28a16 16 0 0022.59-.44c6.14-6.36 5.63-16.86-.76-22.97z"/></svg>

After

Width:  |  Height:  |  Size: 612 B

View File

@ -5,5 +5,10 @@
*/ */
import { svg2ttf } from '../src/index.js' import { svg2ttf } from '../src/index.js'
import fs from 'iofs'
console.log(svg2ttf) let svg = fs.cat('test/game.svg').toString()
let ttf = svg2ttf(svg)
console.log(ttf)