add import auto scale

This commit is contained in:
kekee000 2014-12-16 23:53:30 +08:00
parent 9420c78826
commit 75ee3b22a5
10 changed files with 226 additions and 180 deletions

View File

@ -52,7 +52,6 @@
</button>
<ul class="dropdown-menu" role="menu">
<li><a data-action="setting-unicode">代码点</a></li>
<li><a data-action="setting-name">字体信息</a></li>
<li><a data-action="setting-metrics">字体度量</a></li>
<li><a data-action="setting-editor">编辑器</a></li>

View File

@ -181,23 +181,6 @@ define(
}
},
// 设置unicode
'setting-unicode': function() {
var dlg = new setting.unicode({
onChange: function(unicode) {
// 此处延迟处理
setTimeout(function(){
if (program.ttfManager.get()) {
var glyfList = program.viewer.getSelected();
program.ttfManager.setUnicode(unicode, glyfList);
}
}, 20);
}
});
dlg.show();
},
// 设置字体名称
'setting-name': function() {
var ttf = program.ttfManager.get();

View File

@ -14,6 +14,8 @@ define(
var string = require('common/string');
var setting = require('../widget/setting');
var actions = require('./actions');
var glyfAdjust = require('ttf/util/glyfAdjust');
var defaultProgram;
// 获取ttf的编辑选项
function getEditingOpt(ttf) {
@ -30,6 +32,68 @@ define(
return opt;
}
// 显示editor
function showEditor(glyfIndex) {
// 重置editor缩放
var ttf = defaultProgram.ttfManager.get();
if (ttf) {
$('.main').addClass('editing');
$('.editor').addClass('editing');
defaultProgram.viewer.setMode('editor');
defaultProgram.viewer.blur();
defaultProgram.editor.show();
// 调整显示级别
defaultProgram.editor.setAxis(getEditingOpt(ttf));
var font = ttf.glyf[glyfIndex];
if (font) {
if (font.compond) {
alert('暂不支持复合字形!');
}
else {
defaultProgram.editor.setFont(lang.clone(font));
}
}
defaultProgram.editor.focus();
}
}
// 隐藏editor
function hideEditor() {
$('.main').removeClass('editing');
$('.editor').removeClass('editing');
defaultProgram.editor && defaultProgram.editor.hide();
defaultProgram.viewer.clearEditing();
defaultProgram.viewer.setMode('list');
defaultProgram.viewer.focus();
}
// 显示ttf列表
function showTTF(ttf, page, selected) {
defaultProgram.viewer.setPage(page - 1);
defaultProgram.viewer.show(ttf, selected || defaultProgram.viewer.getSelected());
defaultProgram.viewer.focus();
// 设置翻页
var glyfTotal = ttf.glyf.length;
var pageSize = defaultProgram.setting.get('editor').viewer.pageSize;
if (glyfTotal > pageSize) {
defaultProgram.viewerPager.show(page, pageSize, glyfTotal);
}
else {
defaultProgram.viewerPager.hide();
}
}
return {
@ -40,48 +104,7 @@ define(
*/
init: function(program) {
// 显示editor
var showEditor = function(glyfIndex) {
// 重置editor缩放
var ttf = program.ttfManager.get();
if (ttf) {
$('.main').addClass('editing');
$('.editor').addClass('editing');
program.viewer.setMode('editor');
program.viewer.blur();
program.editor.show();
// 调整显示级别
program.editor.setAxis(getEditingOpt(ttf));
var font = ttf.glyf[glyfIndex];
if (font) {
if (font.compond) {
alert('暂不支持复合字形!');
}
else {
program.editor.setFont(lang.clone(font));
}
}
program.editor.focus();
}
};
// 隐藏editor
var hideEditor = function() {
$('.main').removeClass('editing');
$('.editor').removeClass('editing');
program.editor && program.editor.hide();
program.viewer.clearEditing();
program.viewer.setMode('list');
program.viewer.focus();
};
defaultProgram = program;
program.viewer.on('del', function(e) {
if (e.list) {
@ -98,16 +121,34 @@ define(
showEditor(e.list[0]);
}).on('copy', function(e) {
var list = program.ttfManager.getGlyf(e.list);
clipboard.set(list, 'glyf');
var clip = {
unitsPerEm: program.ttfManager.get().head.unitsPerEm,
glyf: list
};
clipboard.set(clip, 'glyf');
}).on('cut', function(e) {
var list = program.ttfManager.getGlyf(e.list);
clipboard.set(list, 'glyf');
var clip = {
unitsPerEm: program.ttfManager.get().head.unitsPerEm,
glyf: list
};
clipboard.set(clip, 'glyf');
program.ttfManager.removeGlyf(e.list);
}).on('paste', function(e) {
var glyfList = clipboard.get('glyf');
if (glyfList) {
program.ttfManager.appendGlyf(glyfList, program.viewer.getSelected());
var clip = clipboard.get('glyf');
if (clip && clip.glyf.length) {
// 根据 unitsPerEm 调整形状
if (program.ttfManager.get().head.unitsPerEm !== clip.unitsPerEm) {
var scale = program.ttfManager.get().head.unitsPerEm / (clip.unitsPerEm || 1024);
clip.glyf.forEach(function(g) {
glyfAdjust(g, scale, scale);
});
}
program.ttfManager.appendGlyf(clip.glyf, program.viewer.getSelected());
}
})
.on('undo', function(e) {
@ -151,7 +192,7 @@ define(
dlg.show();
}).on('fontsetting', function(e) {
}).on('setting-font', function(e) {
var ttf = program.ttfManager.get();
// 如果仅选择一个字形,则填充现有值
@ -188,6 +229,20 @@ define(
});
dlg.show();
}).on('setting-unicode', function() {
var dlg = new setting.unicode({
onChange: function(unicode) {
// 此处延迟处理
setTimeout(function(){
if (program.ttfManager.get()) {
var glyfList = program.viewer.getSelected();
program.ttfManager.setUnicode(unicode, glyfList);
}
}, 20);
}
});
dlg.show();
}).on('refresh', function() {
showTTF(program.ttfManager.get(), 1);
});
@ -213,26 +268,6 @@ define(
showTTF(program.ttfManager.get(), e.page);
});
// 显示ttf列表
var showTTF = function(ttf, page, selected) {
program.viewer.setPage(page - 1);
program.viewer.show(ttf, selected || program.viewer.getSelected());
program.viewer.focus();
// 设置翻页
var glyfTotal = ttf.glyf.length;
var pageSize = program.setting.get('editor').viewer.pageSize;
if (glyfTotal > pageSize) {
program.viewerPager.show(page, pageSize, glyfTotal);
}
else {
program.viewerPager.hide();
}
}
program.ttfManager.on('change', function(e) {
// 保存正在编辑的字形
var editing = program.viewer.getEditing();
@ -293,13 +328,13 @@ define(
}
}).on('paste', function(e) {
var glyfList = clipboard.get('glyf');
if (glyfList && glyfList.length) {
var clip = clipboard.get('glyf');
if (clip && clip.glyf.length) {
if (!program.editor.isEditing()) {
program.ttfManager.appendGlyf(glyfList, program.viewer.getSelected());
program.viewer.fire('paste');
}
else {
program.editor.addContours(glyfList[0].contours);
program.editor.addContours(clip.glyf[0].contours);
}
}
}).on('function', function(e) {

View File

@ -328,10 +328,10 @@ define(
if (selected.length) {
commandMenu.enableCommands(['copy', 'cut', 'del']);
commandMenu[selected.length === 1 ? 'enableCommands' : 'disableCommands'](['fontsetting']);
commandMenu[selected.length === 1 ? 'enableCommands' : 'disableCommands'](['setting-font']);
}
else {
commandMenu.disableCommands(['copy', 'cut', 'del', 'fontsetting']);
commandMenu.disableCommands(['copy', 'cut', 'del', 'setting-font']);
}
}, 100));

View File

@ -45,7 +45,7 @@ define(
title: '调整字形'
},
{
name: 'fontsetting',
name: 'setting-font',
title: '字形信息',
disabled: true
},
@ -55,6 +55,10 @@ define(
{
name: 'find-glyf',
title: '查找字形'
},
{
name: 'setting-unicode',
title: '设置代码点'
}
];
}

View File

@ -94,7 +94,7 @@ define(
glyf.advanceWidth = Math.round(glyf.advanceWidth * scale);
}
else {
glyf.advanceWidth = glyf.xMax + 10;
glyf.advanceWidth = glyf.xMax + Math.abs(glyf.xMin);
}
}
});

View File

@ -102,7 +102,7 @@ define(
var numberOfGlyphs = ttf.glyf.length;
var glyphNames = [];
var nameIndexs = [];
var size = 34 + numberOfGlyphs * 2; // header + nameIndex
var size = 34 + numberOfGlyphs * 2; // header + numberOfGlyphs * 2
var nameIndex = 0;
// 获取 name的大小
@ -120,12 +120,13 @@ define(
}
else {
// 这里需要注意,"" 有可能是"\3" length不为0但是是空字符串
if (!glyf.name || glyf.name.charCodeAt(0) < 32) {
glyf.name = string.getUnicodeName(unicode);
var name = glyf.name;
if (!name || name.charCodeAt(0) < 32) {
name = string.getUnicodeName(unicode);
}
nameIndexs.push(258 + nameIndex++);
var bytes = string.getPascalStringBytes(glyf.name || ''); //pascal string bytes
var bytes = string.getPascalStringBytes(name); //pascal string bytes
glyphNames.push(bytes);
size += bytes.length;
}

View File

@ -17,14 +17,9 @@ define(
'glyf': require('./glyf'),
'cmap': require('./cmap'),
'name': require('./name'),
//'gasp': require('./gasp'),
'hhea': require('./hhea'),
'hmtx': require('./hmtx'),
'post': require('./post'),
//'DSIG': require('./DSIG'),
//'GDEF': require('./GDEF'),
//'GPOS': require('./GPOS'),
//'GSUB': require('./GSUB'),
'OS/2': require('./OS2')
};

View File

@ -16,7 +16,7 @@ define(
var pathAdjust = require('graphics/pathAdjust');
var pathCeil = require('graphics/pathCeil');
var computeBoundingBox = require('graphics/computeBoundingBox');
var glyfAdjust = require('./util/glyfAdjust');
/**
* 合并两个ttfObject此处仅合并简单字形
@ -31,9 +31,8 @@ define(
function merge(ttf, imported, options) {
options = options || {};
// 调整glyf以适应打开的文件
var scale = 1;
// 对导入的轮廓进行缩放处理
// 调整glyf对导入的轮廓进行缩放处理
if (options.scale && imported.head.unitsPerEm && imported.head.unitsPerEm != ttf.head.unitsPerEm) {
scale = ttf.head.unitsPerEm / imported.head.unitsPerEm;
}
@ -45,41 +44,7 @@ define(
});
list.forEach(function(g) {
if (scale !== 1) {
g.contours.forEach(function(contour) {
pathAdjust(contour, scale, scale);
pathCeil(contour);
});
}
// 重新计算xminxmaxyminymax
if (
undefined === g.xMin
|| undefined === g.yMax
|| undefined === g.leftSideBearing
|| undefined === g.advanceWidth
) {
var bound = computeBoundingBox.computePathBox.apply(this, g.contours);
g.xMin = bound.x;
g.xMax = bound.x + bound.width;
g.yMin = bound.y;
g.yMax = bound.y + bound.height;
g.leftSideBearing = g.xMin;
// 如果设置了advanceWidth就是用默认的否则为10
g.advanceWidth = g.xMax + 10;
}
else {
g.xMin = Math.round(g.xMin * scale);
g.xMax = Math.round(g.xMax * scale);
g.yMin = Math.round(g.yMin * scale);
g.yMax = Math.round(g.yMax * scale);
g.leftSideBearing = Math.round(g.leftSideBearing * scale);
g.advanceWidth = Math.round(g.advanceWidth * scale);
}
glyfAdjust(g, scale, scale);
ttf.glyf.push(g);
});
@ -317,21 +282,9 @@ define(
changed = true;
glyfList.forEach(function(g) {
if (g.leftSideBearing != setting.leftSideBearing) {
var offset = setting.leftSideBearing - g.leftSideBearing;
g.leftSideBearing = g.xMin = setting.leftSideBearing;
g.xMax += offset;
g.advanceWidth += offset;
if (g.contours && g.contours.length) {
g.contours.forEach(function(contour) {
pathAdjust(contour, 1, 1, offset);
});
}
glyfAdjust(g, 1, 1, setting.leftSideBearing - g.leftSideBearing);
}
});
}
@ -339,7 +292,6 @@ define(
if (undefined !== setting.rightSideBearing) {
changed = true;
glyfList.forEach(function(g) {
g.advanceWidth = g.xMax + setting.rightSideBearing;
});
@ -355,15 +307,7 @@ define(
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);
});
}
glyfAdjust(g, 1, 1, 0, offset);
}
});
@ -409,23 +353,8 @@ define(
var scale = setting.scale;
glyfList.forEach(function(g) {
if (g.contours && g.contours.length) {
var rightSideBearing = g.advanceWidth - g.xMax;
g.contours.forEach(function(contour) {
pathAdjust(contour, scale, scale);
pathCeil(contour);
});
g.xMin = Math.round(g.xMin * scale);
g.xMax = Math.round(g.xMax * scale);
g.yMin = Math.round(g.yMin * scale);
g.yMax = Math.round(g.yMax * scale);
g.leftSideBearing = g.xMin;
g.advanceWidth = g.xMax + rightSideBearing;
glyfAdjust(g, scale, scale);
}
});
}
// 缩放到embox

100
src/ttf/util/glyfAdjust.js Normal file
View File

@ -0,0 +1,100 @@
/**
* @file glyfAdjust.js
* @author mengke01
* @date
* @description
* glyf调整
*/
define(
function(require) {
var pathAdjust = require('graphics/pathAdjust');
var pathCeil = require('graphics/pathCeil');
var computeBoundingBox = require('graphics/computeBoundingBox');
/**
* 简单字形的缩放和平移调整
*
* @param {Object} g glyf对象
* @param {number} scaleX x缩放比例
* @param {number} scaleY y缩放比例
* @param {number} offsetX x偏移
* @param {number} offsetY y偏移
* @return {Object} 调整后的glyf对象
*/
function glyfAdjust(g, scaleX, scaleY, offsetX, offsetY) {
scaleX = scaleX || 1;
scaleY = scaleY || 1;
offsetX = offsetX || 0;
offsetY = offsetY || 0
if (g.contours && g.contours.length) {
if (scaleX !== 1 || scaleY !== 1) {
g.contours.forEach(function(contour) {
pathAdjust(contour, scaleX, scaleY);
pathCeil(contour);
});
}
if (offsetX !== 0 || offsetY !== 0) {
g.contours.forEach(function(contour) {
pathAdjust(contour, 1, 1, offsetX, offsetY);
});
}
}
// 重新计算xminxmaxyminymax
var advanceWidth = g.advanceWidth;
if (
undefined === g.xMin
|| undefined === g.yMax
|| undefined === g.leftSideBearing
|| undefined === g.advanceWidth
) {
// 有的字形没有形状,需要特殊处理一下
var bound;
if (g.contours && g.contours.length) {
bound = computeBoundingBox.computePathBox.apply(this, g.contours);
}
else {
bound = {
x: 0,
y: 0,
width: 0,
height: 0
};
}
g.xMin = bound.x;
g.xMax = bound.x + bound.width;
g.yMin = bound.y;
g.yMax = bound.y + bound.height;
g.leftSideBearing = g.xMin;
// 如果设置了advanceWidth就是用默认的否则为xMax + abs(xMin)
if (undefined !== advanceWidth) {
g.advanceWidth = Math.round(advanceWidth * scaleX + offsetX);
}
else {
g.advanceWidth = g.xMax + Math.abs(g.xMin);
}
}
else {
g.xMin = Math.round(g.xMin * scaleX + offsetX);
g.xMax = Math.round(g.xMax * scaleX + offsetX);
g.yMin = Math.round(g.yMin * scaleY + offsetY);
g.yMax = Math.round(g.yMax * scaleY + offsetY);
g.leftSideBearing = Math.round(g.leftSideBearing * scaleX + offsetX);
g.advanceWidth = Math.round(advanceWidth * scaleX + offsetX);
}
return g;
}
return glyfAdjust;
}
);