add glyf adjust

This commit is contained in:
mkwiser 2014-10-08 23:48:41 +08:00
parent 8bb056c88c
commit 170ac9ad02
5 changed files with 245 additions and 93 deletions

View File

@ -9,6 +9,8 @@
define(
function(require) {
var lang = require('common/lang');
var tpl = ''
+ '<div class="input-group input-group-sm">'
+ '<span class="input-group-addon">左边轴</span>'
@ -18,16 +20,26 @@ define(
+ '<span class="input-group-addon">右边轴</span>'
+ '<input data-field="rightSideBearing" type="number" min="-16384" max="16384" step="1" class="form-control">'
+ '</div>'
+
+ '<div class="input-group input-group-sm">'
+ '<span class="input-group-addon">缩放字形到em框</span>'
+ '<span class="form-control">'
+ '<input data-field="ajdustToEmBox" type="checkbox">'
+ '</span>'
+ '<div class="form-inline">'
+ '<div class="form-group">'
+ '<div class="input-group input-group-sm">'
+ '<span class="input-group-addon">缩放字形到em框</span>'
+ '<span class="form-control">'
+ '<input data-field="ajdustToEmBox" type="checkbox" onclick="$(\'#setting-ajdustToEmPadding\')[this.checked ? \'removeClass\' : \'addClass\'](\'hide\')">'
+ '</span>'
+ '</div>'
+ '</div>'
+ ' '
+ '<div id="setting-ajdustToEmPadding" class="form-group hide">'
+ '<div class="input-group input-group-sm">'
+ '<span class="input-group-addon">顶部和底部留白</span>'
+ '<input data-field="ajdustToEmPadding" type="number" min="-16384" max="16384" step="1" class="form-control">'
+ '</div>'
+ '</div>'
+ '</div>'
+ '<div class="input-group input-group-sm">'
+ '<span class="input-group-addon">缩放留白</span>'
+ '<input data-field="ajdustToEmPadding" type="number" min="-16384" max="16384" step="1" class="form-control">'
+ '<span class="input-group-addon">基线偏移</span>'
+ '<input data-field="verticalAlign" type="number" min="-16384" max="16384" step="1" class="form-control">'
+ '</div>';
@ -48,15 +60,34 @@ define(
},
validate: function() {
var name = {};
var setting = {};
this.getDialog().find('[data-field]').each(function(i, item) {
item = $(item);
var val = item.val().trim();
if (val) {
name[item.attr('data-field')] = val;
if (item.type == 'checkbox') {
if (item.checked) {
setting[$(item).attr('data-field')] = true;
}
}
else {
item = $(item);
var val = item.val().trim();
if (val) {
setting[item.attr('data-field')] = Math.floor(+val);
}
}
});
return name;
if(setting.leftSideBearing == undefined
&& setting.rightSideBearing == undefined
&& setting.ajdustToEmBox == undefined
&& setting.verticalAlign == undefined
) {
alert('没有设置项目!');
return false;
}
else {
return setting;
}
}
});

View File

@ -10,7 +10,6 @@ define(
function(require) {
var tpl = ''
+ '<div class="col-lg-6">'
+ '<div class="input-group">'
+ '<div class="input-group-btn">'
+ '<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">起始代码点 <span class="caret"></span></button>'
@ -20,8 +19,7 @@ define(
+ '</ul>'
+ '</div>'
+ '<input id="setting-text-unicode" type="text" class="form-control" value="$E001">'
+ '</div>'
+ '</div>';
+ '</div>';
return require('./setting').derive({

View File

@ -30,27 +30,58 @@ define(
}
var actions = {
// 新建
'new': function() {
if (program.ttfmanager.isChanged() && !window.confirm('是否放弃保存当前项目?')) {
return;
}
newEmpty();
$.getJSON('./src/fonteditor/data/empty.json', function(imported) {
program.ttfmanager.set(imported);
});
},
// 打开
'open': function() {
$('#font-import').click();
},
// 导入
'import': function() {
$('#font-import').click();
},
// 导出
'export': function() {
},
// 导出文件
'export-file': function(e) {
if (program.ttfmanager.get()) {
var target = $(e.target);
exporter.export(program.ttfmanager.get(), {
type: target.attr('data-type'),
target: target
});
}
},
// 保存项目
'save': function() {
saveProj();
if (program.ttfmanager.get()) {
var name = '';
if(name = window.prompt('请输入项目名称:')) {
name = string.encodeHTML(name);
var list = project.add(name, program.ttfmanager.get());
program.projectViewer.show(list);
program.data.projectName = name;
program.ttfmanager.setState('new');
}
}
},
// 添加新字形
'add-new': function() {
program.ttfmanager.addGlyf({
name: '',
@ -58,12 +89,34 @@ define(
});
},
// 添加在线字形
'add-online': function() {
var dlg = new setting.online({
onChange: function(url) {
// 此处延迟处理
setTimeout(function(){
loadOnline(url);
ajaxBinaryFile({
url: url,
onSuccess: function(buffer) {
loader.load(buffer, {
type: 'ttf',
success: function(imported) {
if (program.ttfmanager.get()) {
program.ttfmanager.merge(imported, {
scale: true
});
}
else {
program.ttfmanager.set(imported);
}
}
});
},
onError: function() {
alert('加载文件错误!');
}
});
}, 20);
}
});
@ -71,12 +124,16 @@ define(
dlg.show();
},
// 设置unicode
'setting-unicode': function() {
var dlg = new setting.unicode({
onChange: function(unicode) {
// 此处延迟处理
setTimeout(function(){
setUnicode(unicode);
if (program.ttfmanager.get()) {
var glyfList = program.viewer.getSelected();
program.ttfmanager.setUnicode(unicode, glyfList);
}
}, 20);
}
});
@ -84,6 +141,7 @@ define(
dlg.show();
},
// 设置字体名称
'setting-name': function() {
var ttf = program.ttfmanager.get();
if (ttf) {
@ -95,14 +153,19 @@ define(
dlg.show(ttf.name);
}
},
// 调整字形
'setting-adjust': function() {
var ttf = program.ttfmanager.get();
if (ttf) {
var dlg = new setting.adjust({
onChange: function(setting) {
program.ttfmanager.adjustGlyf(setting);
setTimeout(function() {
program.ttfmanager.adjustGlyf(setting, selected);
}, 20);
}
});
// 如果仅选择一个字形,则填充现有值
var selected = program.viewer.getSelected();
if (selected.length === 1) {
@ -119,64 +182,6 @@ define(
}
};
// 加载在线字体
function loadOnline(url) {
ajaxBinaryFile({
url: url,
onSuccess: function(buffer) {
loader.load(buffer, {
type: 'ttf',
success: function(imported) {
if (program.ttfmanager.get()) {
program.ttfmanager.merge(imported, {
scale: true
});
}
else {
program.ttfmanager.set(imported);
}
}
});
},
onError: function() {
alert('加载文件错误!');
}
});
}
// 设置unicode
function setUnicode(unicode) {
if (program.ttfmanager.get()) {
var glyfList = program.viewer.getSelected();
program.ttfmanager.setUnicode(unicode, glyfList);
}
}
// 保存项目
function saveProj() {
if (program.ttfmanager.get()) {
var name = '';
if(name = window.prompt('请输入项目名称:')) {
name = string.encodeHTML(name);
var list = project.add(name, program.ttfmanager.get());
program.projectViewer.show(list);
program.data.projectName = name;
program.ttfmanager.setState('new');
}
}
}
// 新建空白
function newEmpty() {
$.getJSON('./src/fonteditor/data/empty.json', function(imported) {
program.ttfmanager.set(imported);
});
}
// 打开文件
function onUpFile(e) {
var file = e.target.files[0];
@ -208,16 +213,6 @@ define(
e.target.value = '';
}
function exportFile(e) {
if (program.ttfmanager.get()) {
var target = $(e.target);
exporter.export(program.ttfmanager.get(), {
type: target.attr('data-type'),
target: target
});
}
}
// 绑定组件
function bindEvent() {
$('.navbar').delegate('[data-action]', 'click', function(e) {
@ -228,9 +223,9 @@ define(
}
});
$('#export-btn').on('mouseup', exportFile);
$('#export-btn-woff').on('mouseup', exportFile);
$('#export-btn-svg').on('mouseup', exportFile);
$('#export-btn').on('mouseup', actions['export-file']);
$('#export-btn-woff').on('mouseup', actions['export-file']);
$('#export-btn-svg').on('mouseup', actions['export-file']);
document.getElementById('font-import').addEventListener('change', onUpFile);
}

View File

@ -12,7 +12,9 @@ define(
var lang = require('common/lang');
var postName = require('ttf/enum/postName');
var pathAdjust = require('graphics/pathAdjust');
var pathCeil = require('graphics/pathCeil');
var History = require('editor/util/History');
var computeBoundingBox = require('graphics/computeBoundingBox');
/**
* 清除glyf编辑状态
@ -57,6 +59,7 @@ define(
if (scale !== 1) {
g.contours.forEach(function(contour) {
pathAdjust(contour, scale, scale);
pathCeil(contour);
});
}
g.modify = 'new';
@ -242,6 +245,101 @@ define(
this.fireChange(true);
};
/**
* 调整glyf
*
* @param {Object} setting 选项
* @param {Array} indexList 索引列表
* @return {boolean}
*/
Manager.prototype.adjustGlyf = function(setting, indexList) {
var glyfList = indexList && indexList.length ? this.getGlyf(indexList) : this.ttf.glyf;
var changed = false;
// 缩放到embox
if (setting.ajdustToEmBox) {
changed = true;
var dencent = this.ttf.hhea.descent;
var unitsPerEm = this.ttf.head.unitsPerEm;
var ajdustToEmPadding = 2 * (setting.ajdustToEmPadding || 0);
glyfList.forEach(function(g) {
if (g.contours && g.contours.length) {
var bound = computeBoundingBox.computePath.apply(this, g.contours);
var scale = (unitsPerEm - ajdustToEmPadding) / bound.height;
if (scale != 1) {
var yOffset = (unitsPerEm / 2 + dencent) - (bound.y + bound.height / 2) * scale;
g.contours.forEach(function(contour) {
pathAdjust(contour, scale, scale);
pathAdjust(contour, 1, 1, 0, yOffset);
pathCeil(contour);
});
}
}
});
}
// 左右边轴
if (undefined !== setting.leftSideBearing || undefined !== setting.rightSideBearing) {
changed = true;
glyfList.forEach(function(g) {
// 设置左边轴
if (undefined !== setting.leftSideBearing && g.leftSideBearing != setting.leftSideBearing) {
var offset = setting.leftSideBearing - g.leftSideBearing;
g.xMax += offset;
g.advanceWidth += offset;
g.leftSideBearing = g.xMin = setting.leftSideBearing;
if (g.contours && g.contours.length) {
g.contours.forEach(function(contour) {
pathAdjust(contour, 1, 1, offset);
});
}
}
if (undefined !== setting.rightSideBearing) {
g.advanceWidth = g.xMax + setting.rightSideBearing;
}
});
}
// 基线高度
if (undefined !== setting.verticalAlign) {
changed = true;
verticalAlign = setting.verticalAlign || 0;
glyfList.forEach(function(g) {
if (g.contours && g.contours.length) {
var bound = computeBoundingBox.computePath.apply(this, g.contours);
var offset = verticalAlign - bound.y;
g.yMin += offset;
g.yMax += offset;
if (g.contours && g.contours.length) {
g.contours.forEach(function(contour) {
pathAdjust(contour, 1, 1, 0, offset);
});
}
}
});
}
if (changed) {
this.fireChange(true);
}
return this;
};
/**
* 获取glyfList
*

30
src/graphics/pathCeil.js Normal file
View File

@ -0,0 +1,30 @@
/**
* @file pathCeil.js
* @author mengke01
* @date
* @description
* 对路径进行四舍五入
*/
define(
function(require) {
/**
* 对path坐标进行调整
*
* @return {Object} contour 坐标点
*/
function pathCeil(contour) {
var p;
for (var i = 0, l = contour.length; i < l; i++) {
p = contour[i];
p.x = Math.round(p.x);
p.y = Math.round(p.y);
}
return contour;
}
return pathCeil;
}
);