diff --git a/css/bootstrap.less b/css/bootstrap.less
new file mode 100644
index 0000000..1811d91
--- /dev/null
+++ b/css/bootstrap.less
@@ -0,0 +1,44 @@
+
+// overwrite bootstrap themes
+
+
+.modal-dialog {
+ margin-top: 100px;
+}
+
+.modal-header {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ background: #327EC0;
+ color: #FFF;
+ .close {
+ margin-top: 3px;
+ }
+
+ .modal-title {
+ font-size: 14px;
+ line-height: 25px;
+ }
+}
+
+.modal-footer {
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+
+.modal-body {
+ min-height: 100px;
+}
+
+.modal-content {
+ border-color: rgba(0,0,0,.5);
+ -webkit-box-shadow: 0 2px 4px rgba(0,0,0,.2);
+ box-shadow: 0 2px 4px rgba(0,0,0,.2);
+ overflow: hidden;
+}
+
+.dropdown-menu {
+ a {
+ cursor: pointer;
+ }
+}
\ No newline at end of file
diff --git a/css/common.css b/css/common.css
index 03bb674..5cc9f70 100644
--- a/css/common.css
+++ b/css/common.css
@@ -1,3 +1,35 @@
+.modal-dialog {
+ margin-top: 100px;
+}
+.modal-header {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ background: #327EC0;
+ color: #FFF;
+}
+.modal-header .close {
+ margin-top: 3px;
+}
+.modal-header .modal-title {
+ font-size: 14px;
+ line-height: 25px;
+}
+.modal-footer {
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+.modal-body {
+ min-height: 100px;
+}
+.modal-content {
+ border-color: rgba(0, 0, 0, 0.5);
+ -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+ overflow: hidden;
+}
+.dropdown-menu a {
+ cursor: pointer;
+}
body,
html {
margin: 0;
@@ -28,6 +60,7 @@ html {
border-radius: 0;
margin: 0;
position: fixed;
+ z-index: 10;
width: 100%;
top: 0;
}
@@ -35,7 +68,7 @@ html {
margin-right: 10px;
margin-top: 10px;
}
-.navbar .btn:first-child {
+.navbar > .btn:first-child {
margin-left: 10px;
}
#export-btn {
@@ -74,3 +107,11 @@ html {
text-align: center;
display: none;
}
+.selection-range {
+ position: absolute;
+ z-index: 6;
+ display: none;
+ border: 1px solid #CCC;
+ background: rgba(222, 222, 222, 0.5);
+ pointer-events: none;
+}
diff --git a/css/common.less b/css/common.less
index 407b1e7..b9ea818 100644
--- a/css/common.less
+++ b/css/common.less
@@ -1,4 +1,6 @@
+@import './bootstrap.less';
+
body, html {
margin: 0;
padding: 0;
@@ -35,6 +37,7 @@ body, html {
border-radius: 0;
margin: 0;
position: fixed;
+ z-index: 10;
width: 100%;
top: 0;
@@ -43,7 +46,7 @@ body, html {
margin-top: 10px;
}
- .btn:first-child {
+ >.btn:first-child {
margin-left: 10px;
}
}
@@ -88,4 +91,14 @@ body, html {
line-height: 24px;
text-align: center;
display: none;
+}
+
+
+.selection-range {
+ position: absolute;
+ z-index: 6;
+ display: none;
+ border: 1px solid #CCC;
+ background: rgba(222, 222, 222, 0.5);
+ pointer-events: none;
}
\ No newline at end of file
diff --git a/css/ico.css b/css/ico.css
index 04229be..a7532cc 100644
--- a/css/ico.css
+++ b/css/ico.css
@@ -2,3 +2,23 @@
font-family: 'fonteditor';
src: url('../font/iconfont.ttf') format('truetype');
}
+.i-edit,
+.i-del {
+ display: inline-block;
+ font-family: 'fonteditor';
+ font-size: 12px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -webkit-text-stroke-width: 0.1px;
+}
+.i-edit:hover,
+.i-del:hover {
+ cursor: pointer;
+ color: blue;
+}
+.i-edit:before {
+ content: '\e605';
+}
+.i-del:before {
+ content: '\e611';
+}
diff --git a/css/ico.less b/css/ico.less
index 3f51604..00948e8 100644
--- a/css/ico.less
+++ b/css/ico.less
@@ -6,3 +6,25 @@
src: url('../font/iconfont.ttf') format('truetype');
}
+.i-edit,
+.i-del {
+ display: inline-block;
+ font-family: 'fonteditor';
+ font-size: 12px;
+ font-style:normal;
+ -webkit-font-smoothing: antialiased;
+ -webkit-text-stroke-width: 0.1px;
+
+ &:hover {
+ cursor: pointer;
+ color: blue;
+ }
+}
+
+.i-edit:before {
+ content: '\e605';
+}
+
+.i-del:before {
+ content: '\e611';
+}
\ No newline at end of file
diff --git a/css/ttf.css b/css/ttf.css
index c8ce816..d18a35e 100644
--- a/css/ttf.css
+++ b/css/ttf.css
@@ -1,3 +1,35 @@
+.modal-dialog {
+ margin-top: 100px;
+}
+.modal-header {
+ padding-top: 6px;
+ padding-bottom: 6px;
+ background: #327EC0;
+ color: #FFF;
+}
+.modal-header .close {
+ margin-top: 3px;
+}
+.modal-header .modal-title {
+ font-size: 14px;
+ line-height: 25px;
+}
+.modal-footer {
+ padding-top: 10px;
+ padding-bottom: 10px;
+}
+.modal-body {
+ min-height: 100px;
+}
+.modal-content {
+ border-color: rgba(0, 0, 0, 0.5);
+ -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
+ overflow: hidden;
+}
+.dropdown-menu a {
+ cursor: pointer;
+}
body,
html {
margin: 0;
@@ -28,6 +60,7 @@ html {
border-radius: 0;
margin: 0;
position: fixed;
+ z-index: 10;
width: 100%;
top: 0;
}
@@ -35,7 +68,7 @@ html {
margin-right: 10px;
margin-top: 10px;
}
-.navbar .btn:first-child {
+.navbar > .btn:first-child {
margin-left: 10px;
}
#export-btn {
@@ -74,26 +107,64 @@ html {
text-align: center;
display: none;
}
+.selection-range {
+ position: absolute;
+ z-index: 6;
+ display: none;
+ border: 1px solid #CCC;
+ background: rgba(222, 222, 222, 0.5);
+ pointer-events: none;
+}
@font-face {
font-family: 'fonteditor';
src: url('../font/iconfont.ttf') format('truetype');
}
+.i-edit,
+.i-del {
+ display: inline-block;
+ font-family: 'fonteditor';
+ font-size: 12px;
+ font-style: normal;
+ -webkit-font-smoothing: antialiased;
+ -webkit-text-stroke-width: 0.1px;
+}
+.i-edit:hover,
+.i-del:hover {
+ cursor: pointer;
+ color: blue;
+}
+.i-edit:before {
+ content: '\e605';
+}
+.i-del:before {
+ content: '\e611';
+}
.project .project-title {
font-weight: bold;
}
.project .project-list {
- line-height: 20px;
+ line-height: 24px;
}
.project .project-list div {
- padding-left: 10px;
+ padding: 0 10px;
}
.project .project-list div:hover {
- color: red;
- text-decoration: underline;
- cursor: pointer;
+ background: #EFEFEF;
+}
+.project .project-list div:hover .i-del {
+ display: block;
+}
+.project .project-list .i-del {
+ float: right;
+ display: none;
+}
+.glyf-list {
+ padding-bottom: 40px;
+ overflow: hidden;
}
.glyf-list > .glyf-item {
float: left;
+ position: relative;
margin: 10px;
width: 86px;
border: 1px solid #CCC;
@@ -123,12 +194,34 @@ html {
.glyf-list > .glyf-item .glyf .path {
fill: green;
}
+.glyf-list > .glyf-item .i-del,
+.glyf-list > .glyf-item .i-edit {
+ position: absolute;
+ right: 2px;
+ display: none;
+}
+.glyf-list > .glyf-item .i-edit {
+ right: 20px;
+}
.glyf-list > .glyf-item:hover {
background: #EFEFEF;
}
.glyf-list > .glyf-item:hover .path {
fill: darkgreen;
}
+.glyf-list > .glyf-item:hover .i-del,
+.glyf-list > .glyf-item:hover .i-edit {
+ display: block;
+}
+.glyf-list > .compound .path {
+ fill: lightgreen!important;
+}
.glyf-list > .new .path {
fill: blue!important;
}
+.glyf-list > .selected {
+ background: #EBFFC2!important;
+}
+.glyf-list.no-hover .glyf-item {
+ pointer-events: none;
+}
diff --git a/css/ttf.less b/css/ttf.less
index e00836e..d86c2d8 100644
--- a/css/ttf.less
+++ b/css/ttf.less
@@ -10,15 +10,23 @@
font-weight: bold;
}
.project-list {
- line-height: 20px;
+ line-height: 24px;
div {
- padding-left: 10px;
+ padding: 0 10px;
}
+
div:hover {
- color: red;
- text-decoration: underline;
- cursor: pointer;
+ background: #EFEFEF;
+
+ .i-del {
+ display: block;
+ }
+ }
+
+ .i-del {
+ float: right;
+ display: none;
}
}
}
@@ -27,9 +35,13 @@
.glyf-list {
+ padding-bottom: 40px;
+ overflow: hidden;
+
>.glyf-item {
float: left;
+ position: relative;
margin: 10px;
width: 86px;
border: 1px solid #CCC;
@@ -59,6 +71,17 @@
fill: green;
}
}
+
+ .i-del,
+ .i-edit {
+ position: absolute;
+ right: 2px;
+ display: none;
+ }
+
+ .i-edit {
+ right: 20px;
+ }
}
>.glyf-item:hover {
@@ -66,6 +89,17 @@
.path {
fill: darkgreen;
}
+
+ .i-del,
+ .i-edit {
+ display: block;
+ }
+ }
+
+ >.compound {
+ .path {
+ fill: lightgreen!important;
+ }
}
>.new {
@@ -73,4 +107,15 @@
fill: blue!important;
}
}
+
+ >.selected {
+ background: #EBFFC2!important;
+ }
}
+
+
+.glyf-list.no-hover {
+ .glyf-item {
+ pointer-events: none;
+ }
+}
\ No newline at end of file
diff --git a/font/iconfont.ttf b/font/iconfont.ttf
index 8d03301..e178ff5 100644
Binary files a/font/iconfont.ttf and b/font/iconfont.ttf differ
diff --git a/src/fonteditor/dialog/setting-unicode.js b/src/fonteditor/dialog/setting-unicode.js
new file mode 100644
index 0000000..0c340d1
--- /dev/null
+++ b/src/fonteditor/dialog/setting-unicode.js
@@ -0,0 +1,45 @@
+/**
+ * @file setting-unicode.js
+ * @author mengke01
+ * @date
+ * @description
+ * 设置代码点
+ */
+
+define(
+ function(require) {
+
+ var tpl = ''
+ + '
';
+
+ return require('./setting').derive({
+
+ getTpl: function() {
+ return tpl;
+ },
+ onConfirm: function() {
+ var unicode = $('#setting-text-unicode').val();
+ if (unicode.match(/^\$[A-E0-9]+$/i)) {
+ this.fire('change', {
+ unicode: unicode
+ });
+ }
+ else {
+ alert('代码点设置不正确');
+ return false;
+ }
+ }
+ });
+ }
+);
diff --git a/src/fonteditor/dialog/setting.js b/src/fonteditor/dialog/setting.js
new file mode 100644
index 0000000..5fc0359
--- /dev/null
+++ b/src/fonteditor/dialog/setting.js
@@ -0,0 +1,104 @@
+/**
+ * @file setting.js
+ * @author mengke01
+ * @date
+ * @description
+ * 设置框
+ */
+
+
+define(
+ function(require) {
+ var lang = require('common/lang');
+ var observable = require('common/observable');
+
+ /**
+ * 设置框函数
+ *
+ * @constructor
+ */
+ function Setting() {
+ }
+
+ /**
+ * 初始化绑定事件
+ */
+ Setting.prototype.preInit = function() {
+ var dlg = $('#model-dialog');
+ dlg.find('.modal-title').html(this.title);
+ dlg.find('.modal-body').html(this.getTpl());
+
+ dlg.on('hidden.bs.modal', lang.bind(function (e) {
+ if (dlg) {
+ this.un();
+ dlg.off('hidden.bs.modal');
+ dlg.find('.btn-confirm').off('click');
+ dlg = null;
+ }
+ }, this));
+
+ dlg.find('.btn-confirm').on('click', lang.bind(function() {
+ if (false !== this.onConfirm()) {
+ dlg.modal('hide');
+ }
+ }, this));
+ };
+
+ /**
+ * 获取模板
+ *
+ * @return {string} 模板字符串
+ */
+ Setting.prototype.getTpl = function() {
+ return '';
+ };
+
+ /**
+ * 确定事件
+ *
+ * @return {boolean=} 是否关闭对话框
+ */
+ Setting.prototype.onConfirm = function() {
+ };
+
+ /**
+ * 显示
+ */
+ Setting.prototype.show = function() {
+ $('#model-dialog').modal('show');
+ return this;
+ };
+
+ /**
+ * 注销
+ */
+ Setting.prototype.dispose = function() {
+ $('#model-dialog').modal('hide');
+ };
+
+
+ /**
+ * 派生一个setting
+ *
+ * @param {Object} proto 原型函数
+ * @return {Function} 派生类
+ */
+ Setting.derive = function(proto) {
+
+ function Class() {
+ Setting.apply(this, arguments);
+ this.preInit();
+ this.initialize && this.initialize();
+ }
+
+ Class.prototype = new Setting();
+ Class.prototype.constructor = Setting;
+ lang.extend(Class.prototype, proto);
+ observable.mixin(Class.prototype);
+
+ return Class;
+ };
+
+ return Setting;
+ }
+);
diff --git a/src/fonteditor/ttf/main.js b/src/fonteditor/ttf/main.js
index 9a7d9ae..c366af5 100644
--- a/src/fonteditor/ttf/main.js
+++ b/src/fonteditor/ttf/main.js
@@ -14,37 +14,72 @@ define(
var exporter = require('../widget/exporter');
var project = require('../widget/project');
var ProjectViewer = require('../widget/projectviewer');
- var ttfmanager = require('../widget/ttfmanager');
+ var TTFManager = require('../widget/ttfmanager');
var program = require('../program');
var string = require('common/string');
+ var setting = {
+ 'unicode': require('../dialog/setting-unicode')
+ }
+
var actions = {
- new: function() {
- if (program.data.ttf && !window.confirm('是否放弃保存当前项目?')) {
+ 'new': function() {
+ if (program.ttfmanager.get() && !window.confirm('是否放弃保存当前项目?')) {
return;
}
newEmpty();
- },
- open: function() {
+ },
+ 'open': function() {
$('#font-import').click();
},
- import: function() {
+
+ 'import': function() {
$('#font-import').click();
},
- export: function() {
+
+ 'export': function() {
},
- save: function() {
+
+ 'save': function() {
saveProj();
+ },
+
+ 'add-new': function() {
+ program.ttfmanager.addglyf({
+ name: '',
+ unicode:[]
+ });
+ },
+
+ 'setting-unicode': function(e) {
+ var dlg = new setting.unicode();
+
+ dlg.on('change', function(e) {
+ // 此处延迟处理
+ setTimeout(function(){
+ setUnicode(e.unicode);
+ }, 20);
+ });
+
+ dlg.show();
}
};
+ // 设置unicode
+ function setUnicode(unicode) {
+ if (program.ttfmanager.get()) {
+ var glyfList = program.viewer.getSelected();
+ program.ttfmanager.setUnicode(unicode, glyfList);
+ }
+
+ }
// 保存项目
function saveProj() {
- if (program.data.ttf) {
+ if (program.ttfmanager.get()) {
var name = '';
if(name = window.prompt('请输入项目名称:')) {
- var list = project.add(string.encodeHTML(name), program.data.ttf);
+ var list = project.add(string.encodeHTML(name), program.ttfmanager.get());
program.projectViewer.show(list);
}
}
@@ -53,8 +88,7 @@ define(
// 新建空白
function newEmpty() {
$.getJSON('./src/fonteditor/data/empty.json', function(imported) {
- program.data.ttf = imported;
- program.viewer.show(imported);
+ program.ttfmanager.set(imported);
})
}
@@ -63,23 +97,20 @@ define(
var file = e.target.files[0];
if (program.action == 'open' && file.name.match(/(\.ttf|\.woff)$/)) {
- program.data.file = file.name;
loader.load(file, {
type: file.name.slice(file.name.lastIndexOf('.') + 1),
success: function(imported) {
- program.data.ttf = imported;
- program.viewer.show(imported);
+ program.ttfmanager.set(imported);
}
});
}
else if (program.action == 'import' && file.name.match(/(\.ttf|\.woff|\.svg)$/)) {
- if (program.data.ttf) {
+ if (program.ttfmanager.get()) {
loader.load(file, {
type: file.name.slice(file.name.lastIndexOf('.') + 1),
success: function(imported) {
if (imported.glyf.length) {
- ttfmanager.combine(program.data.ttf, imported, {scale: true});
- program.viewer.show(program.data.ttf);
+ program.ttfmanager.combine(imported, {scale: true});
}
}
});
@@ -93,10 +124,9 @@ define(
}
function exportFile(e) {
- var ttf = program.data.ttf;
- if (ttf) {
+ if (program.ttfmanager.get()) {
var target = $(e.target);
- exporter.export(ttf, {
+ exporter.export(program.ttfmanager.get(), {
type: target.attr('data-type'),
target: target
});
@@ -128,21 +158,39 @@ define(
init: function () {
bindEvent();
+ // 查看器
program.viewer = new GLYFViewer($('#glyf-list'));
+ program.viewer.on('del', function(e) {
+ if (e.list) {
+ program.ttfmanager.delglyf(e.list);
+ }
+ });
+
+ // 项目管理
program.projectViewer = new ProjectViewer($('#project-list'));
program.projectViewer.on('open', function(e) {
var imported = project.get(e.projectName);
if (imported) {
- if (program.data.ttf && !window.confirm('是否放弃保存当前项目?')) {
+ if (program.ttfmanager.get() && !window.confirm('是否放弃保存当前项目?')) {
return;
}
- program.data.ttf = imported;
- program.viewer.show(imported);
+ program.ttfmanager.set(imported);
+ }
+ });
+ program.projectViewer.on('del', function(e) {
+ if (e.projectName && window.confirm('是否删除项目?')) {
+ program.projectViewer.show(project.remove(e.projectName));
}
});
program.projectViewer.show(project.items());
+ // ttf管理
+ program.ttfmanager = new TTFManager();
+ program.ttfmanager.on('change', function(e) {
+ program.viewer.show(e.ttf);
+ });
+
}
};
diff --git a/src/fonteditor/widget/glyfviewer.js b/src/fonteditor/widget/glyfviewer.js
index d2a1377..802c3e4 100644
--- a/src/fonteditor/widget/glyfviewer.js
+++ b/src/fonteditor/widget/glyfviewer.js
@@ -10,11 +10,15 @@ define(
function(require) {
var glyf2svg = require('ttf/util/glyf2svg');
var string = require('common/string');
-
+ var lang = require('common/lang');
+ var MouseCapture = require('render/capture/Mouse');
+ var isBoundingBoxCross = require('graphics/isBoundingBoxCross');
+
var GLYF_ITEM_TPL = ''
+ ''
+ + '
'
+ '
'
- + '
${unicode}
${name}
'
+ + '
${unicode}
${name}
'
+ '
';
@@ -46,6 +50,28 @@ define(
this.main.html(glyfStr);
}
+
+ // 点击item
+ function clickItem(e) {
+ $(this).toggleClass('selected');
+ }
+
+ // 点击item
+ function clickAction(e) {
+ e.stopPropagation();
+ var target = $(e.target);
+ var action = target.attr('data-action');
+
+ if (action == 'del' && !window.confirm('确定删除字形么?')) {
+ return;
+ }
+
+ var selected = [+target.parent().attr('data-index')];
+ this.fire(action, {
+ list: selected
+ });
+ }
+
/**
* glyf查看器
*
@@ -56,12 +82,129 @@ define(
function GlyfViewer(main, options) {
this.options = options || {};
this.main = $(main);
+
+ this.main.delegate('[data-index]', 'click', clickItem)
+ .delegate('[data-action]', 'click', lang.bind(clickAction, this));
+
+
+ var me = this;
+ // 绑定键盘事件
+ me.listener = function(e) {
+
+ // 删除
+ if (46 === e.keyCode) {
+ e.stopPropagation();
+ var selected = me.getSelected();
+ if (selected.length) {
+ me.fire('del', {
+ list: selected
+ });
+ }
+ }
+ // 取消选中
+ else if (27 === e.keyCode) {
+ me.main.children().removeClass('selected');
+ }
+
+ };
+
+
+ $(document.body).on('click', function(e) {
+ var focused = me.main.get(0) === e.target || me.main.get(0).contains(e.target);
+ if (focused && !me.listening) {
+ document.body.addEventListener('keyup', me.listener,false);
+ me.listening = true;
+ }
+ else if (!focused){
+ document.body.removeEventListener('keyup', me.listener);
+ me.listening = false;
+ }
+ });
+
+ // 选择范围内元素
+ function selectRangeItem(bound, toggle, remove) {
+ me.main.children().each(function(i, element) {
+ var item = $(element);
+ var pos = item.offset();
+ var b = {
+ x: pos.left,
+ y: pos.top,
+ width: item.width(),
+ height: item.height()
+ }
+ if (3 === isBoundingBoxCross(bound, b)) {
+ if (toggle) {
+ item.toggleClass('selected');
+ }
+ else if (remove) {
+ item.removeClass('selected')
+ }
+ else {
+ item.addClass('selected')
+ }
+ }
+ });
+ }
+
+
+ me.capture = new MouseCapture(me.main.get(0), {
+ events: {
+ dblclick: false,
+ mousewheel: false,
+ mouseover: false,
+ mouseout: false
+ }
+ });
+
+ me.capture.on('dragstart', function(e) {
+ $('#selection-range').show();
+ me.main.addClass('no-hover');
+ me.startX = e.originEvent.pageX;
+ me.startY = e.originEvent.pageY;
+ });
+
+ var dragging = function(e) {
+ var x = e.originEvent.pageX;
+ var y = e.originEvent.pageY;
+ $('#selection-range').css({
+ left: Math.min(me.startX, x),
+ top: Math.min(me.startY, y),
+ width: Math.abs(me.startX - x),
+ height: Math.abs(me.startY - y)
+ });
+ };
+ me.capture.on('drag', dragging);
+
+ me.capture.on('dragend', function(e) {
+ $('#selection-range').hide();
+ me.main.removeClass('no-hover');
+
+ var x = e.originEvent.pageX;
+ var y = e.originEvent.pageY;
+ var pos = me.main.offset();
+
+ selectRangeItem.call(me, {
+ x: Math.min(me.startX, x),
+ y: Math.min(me.startY, y),
+ width: Math.abs(me.startX - x),
+ height: Math.abs(me.startY - y)
+ }, e.ctrlKey, e.shiftKey);
+ });
+
}
GlyfViewer.prototype.show = function(ttf) {
showGLYF.call(this, ttf);
};
+ GlyfViewer.prototype.getSelected = function() {
+ var selected = [];
+ this.main.find('.selected').each(function(index, item) {
+ selected.push(+item.getAttribute('data-index'));
+ });
+ return selected;
+ };
+
require('common/observable').mixin(GlyfViewer.prototype);
return GlyfViewer;
diff --git a/src/fonteditor/widget/project.js b/src/fonteditor/widget/project.js
index e3f1038..f995204 100644
--- a/src/fonteditor/widget/project.js
+++ b/src/fonteditor/widget/project.js
@@ -33,11 +33,22 @@ define(
*/
add: function(projectName, ttf) {
var list = this.items();
- var id = Date.now();
- list.push({
- name: projectName,
- id: id
+ var exist = list.filter(function(l) {
+ return l.name == projectName;
});
+
+ var id;
+ if (exist.length) {
+ id = exist[0].id;
+ }
+ else {
+ id = Date.now();
+ list.push({
+ name: projectName,
+ id: id
+ });
+ }
+
storage.setItem('project-list', JSON.stringify(list));
storage.setItem(id, JSON.stringify(ttf));
return list;
@@ -58,6 +69,8 @@ define(
}
}
storage.setItem('project-list', JSON.stringify(list));
+
+ return list;
},
/**
diff --git a/src/fonteditor/widget/projectviewer.js b/src/fonteditor/widget/projectviewer.js
index a6f1cc2..4cce994 100644
--- a/src/fonteditor/widget/projectviewer.js
+++ b/src/fonteditor/widget/projectviewer.js
@@ -22,7 +22,18 @@ define(
this.main = $(main);
var me = this;
- this.main.delegate('[data-name]', 'click', function(e) {
+
+ me.main.delegate('[data-action]', 'click', function(e) {
+ e.stopPropagation();
+ var the = $(this);
+ me.fire(the.attr('data-action'), {
+ projectName: the.parent().attr('data-name')
+ });
+ });
+
+ me.main.delegate('[data-name]', 'click', function(e) {
+ e.preventDefault();
+ e.stopPropagation();
me.fire('open', {
projectName: $(this).attr('data-name')
});
@@ -32,7 +43,7 @@ define(
ProjectViewer.prototype.show = function(projects) {
var str = '';
(projects || []).forEach(function(proj) {
- str += '';
+ str += '';
});
this.main.html(str);
diff --git a/src/fonteditor/widget/ttfmanager.js b/src/fonteditor/widget/ttfmanager.js
index 278f7f1..5d84e80 100644
--- a/src/fonteditor/widget/ttfmanager.js
+++ b/src/fonteditor/widget/ttfmanager.js
@@ -10,49 +10,193 @@
define(
function(require) {
+ var postName = require('ttf/enum/postName');
var pathAdjust = require('graphics/pathAdjust');
- var manager = {
- /**
- * 合并两个ttfObject,此处仅合并简单字形
- *
- * @param {Object} ttf ttfObject
- * @param {Object} imported ttfObject
- * @param {Object} options 参数选项
- * @param {boolean} options.scale 是否自动缩放
- *
- * @return {Object} 合并后的ttfObject
- */
- combine: function(ttf, imported, options) {
- options = options || {};
- // 调整glyf以适应打开的文件
- var scale = 1;
- // 对导入的轮廓进行缩放处理
- if (options.scale && imported.head.unitsPerEm && imported.head.unitsPerEm != ttf.head.unitsPerEm) {
- scale = ttf.head.unitsPerEm / imported.head.unitsPerEm;
- }
+ /**
+ * 合并两个ttfObject,此处仅合并简单字形
+ *
+ * @param {Object} ttf ttfObject
+ * @param {Object} imported ttfObject
+ * @param {Object} options 参数选项
+ * @param {boolean} options.scale 是否自动缩放
+ *
+ * @return {Object} 合并后的ttfObject
+ */
+ function combine(ttf, imported, options) {
+ options = options || {};
- imported.glyf.filter(function(g, index) {
-
- return g.contours && g.contours.length //简单轮廓
- && g.name != '.notdef' && g.name != '.null' && g.name != 'nonmarkingreturn'; // 非预定义字形
-
- }).forEach(function(g) {
- if (scale !== 1) {
- g.contours.forEach(function(contour) {
- pathAdjust(contour, scale, scale);
- });
- }
- g.modify = 'new';
- ttf.glyf.push(g);
- });
-
- return ttf;
+ // 调整glyf以适应打开的文件
+ var scale = 1;
+ // 对导入的轮廓进行缩放处理
+ if (options.scale && imported.head.unitsPerEm && imported.head.unitsPerEm != ttf.head.unitsPerEm) {
+ scale = ttf.head.unitsPerEm / imported.head.unitsPerEm;
}
+
+ imported.glyf.filter(function(g, index) {
+ return g.contours && g.contours.length //简单轮廓
+ && g.name != '.notdef' && g.name != '.null' && g.name != 'nonmarkingreturn'; // 非预定义字形
+
+ }).forEach(function(g) {
+ if (scale !== 1) {
+ g.contours.forEach(function(contour) {
+ pathAdjust(contour, scale, scale);
+ });
+ }
+ g.modify = 'new';
+ ttf.glyf.push(g);
+ });
+
+ return ttf;
+ }
+
+ /**
+ * 构造函数
+ *
+ * @constructor
+ * @param {ttfObject} ttf ttf对象
+ */
+ function Manager(ttf) {
+ this.ttf = ttf;
+ }
+
+ /**
+ * 设置ttf
+ *
+ * @param {ttfObject} ttf ttf对象
+ * @return {this}
+ */
+ Manager.prototype.set = function(ttf) {
+
+ if (this.ttf !== ttf) {
+ this.ttf = ttf;
+ this.fire('change', {
+ ttf: this.ttf
+ });
+ }
+
+ return this;
};
- return manager;
+ /**
+ * 获取ttf对象
+ *
+ * @return {ttfObject} ttf ttf对象
+ */
+ Manager.prototype.get = function() {
+ return this.ttf;
+ };
+
+ /**
+ * 添加glyf
+ *
+ * @param {Object} glyf glyf对象
+ *
+ * @return {this}
+ */
+ Manager.prototype.addglyf = function(glyf) {
+ this.ttf.glyf.push(glyf);
+ this.fire('change', {
+ ttf: this.ttf
+ });
+ return this;
+ };
+
+ /**
+ * 合并两个ttfObject,此处仅合并简单字形
+ *
+ * @param {Object} imported ttfObject
+ * @param {Object} options 参数选项
+ * @param {boolean} options.scale 是否自动缩放
+ *
+ * @return {this}
+ */
+ Manager.prototype.combine = function(imported, options) {
+ combine(this.ttf, imported, options);
+ this.fire('change', {
+ ttf: this.ttf
+ });
+ return this;
+ };
+
+
+ /**
+ * 删除指定字形
+ *
+ * @param {Array} indexList 索引列表
+ * @return {this}
+ */
+ Manager.prototype.delglyf = function(indexList) {
+ var glyf = this.ttf.glyf, count = 0;
+ for(var i = glyf.length - 1; i >= 0; i--) {
+ if (indexList.indexOf(i) >= 0) {
+ glyf.splice(i, 1);
+ count++;
+ }
+ }
+
+ if (count) {
+ this.fire('change', {
+ ttf: this.ttf
+ });
+ }
+
+ return this;
+ };
+
+
+ /**
+ * 设置unicode代码
+ *
+ * @param {string} unicode unicode代码
+ * @param {Array} indexList 索引列表
+ * @return {this}
+ */
+ Manager.prototype.setUnicode = function(unicode, indexList) {
+ var glyf = this.ttf.glyf, list;
+ if (indexList && indexList.length) {
+ list = indexList.map(function(item) {
+ return glyf[item];
+ });
+ }
+ else {
+ list = glyf;
+ }
+
+ list = list.filter(function(g) {
+ return g.name != '.notdef' && g.name != '.null' && g.name != 'nonmarkingreturn';
+ });
+
+ if (list.length) {
+
+ unicode = Number('0x' + unicode.slice(1));
+
+ list.forEach(function(g) {
+ g.unicode = [unicode];
+ g.name = unicode - 29 < 258 ? postName[unicode - 29] : 'uni' + unicode.toString(16).toUpperCase();
+ unicode++;
+ });
+
+ this.fire('change', {
+ ttf: this.ttf
+ });
+ }
+
+ return this;
+ };
+
+ /**
+ * 注销
+ */
+ Manager.prototype.dispose = function() {
+ this.un();
+ delete this.ttf;
+ };
+
+ require('common/observable').mixin(Manager.prototype);
+
+ return Manager;
}
);
diff --git a/src/graphics/isBoundingBoxCross.js b/src/graphics/isBoundingBoxCross.js
index 4915723..1f2c2f9 100644
--- a/src/graphics/isBoundingBoxCross.js
+++ b/src/graphics/isBoundingBoxCross.js
@@ -21,7 +21,7 @@ define(
* @return {number} 包含关系
*
* 2 : b2 包含 b1
- * 3 : b2 包含 b3
+ * 3 : b1 包含 b2
* 1 : 有交点
*/
function isBoundingBoxCross(b1, b2) {
diff --git a/src/render/capture/Mouse.js b/src/render/capture/Mouse.js
index 6e3db00..378244a 100644
--- a/src/render/capture/Mouse.js
+++ b/src/render/capture/Mouse.js
@@ -48,7 +48,8 @@ define(
ctrlKey: e.ctrlKey,
metaKey: e.metaKey,
altKey: e.altKey,
- shiftKey: e.shiftKey
+ shiftKey: e.shiftKey,
+ originEvent: e
};
}
@@ -73,12 +74,13 @@ define(
*/
function mousedown(e) {
- prevent(e);
if(false === this.events.mousedown) {
return;
}
+ prevent(e);
+
var event = getEvent(e);
this.startX = event.x;
@@ -117,12 +119,13 @@ define(
* @param {Object} e 事件参数
*/
function mousemove(e) {
- prevent(e);
if(false === this.events.mousemove) {
return;
}
+ prevent(e);
+
var event = getEvent(e);
this.fire('move', event);
@@ -155,12 +158,13 @@ define(
*/
function mouseup(e) {
- prevent(e);
if(false === this.events.mouseup) {
return;
}
+ prevent(e);
+
var event = getEvent(e);
event.time = Date.now() - this.startTime;
@@ -193,12 +197,12 @@ define(
*/
function mousewheel(e) {
- prevent(e);
-
if(false === this.events.mousewheel) {
return;
}
+ prevent(e);
+
var delta = 0;
if (e.wheelDelta) {
delta = e.wheelDelta / 120;
@@ -220,10 +224,13 @@ define(
* @param {Object} e 事件参数
*/
function mouseover(e) {
- prevent(e);
+
if(false === this.events.mouseover) {
return;
}
+
+ prevent(e);
+
this.fire('over');
}
@@ -233,10 +240,13 @@ define(
* @param {Object} e 事件参数
*/
function mouseout(e) {
- prevent(e);
+
if(false === this.events.mouseout) {
return;
}
+
+ prevent(e);
+
this.fire('out');
}
diff --git a/ttf.html b/ttf.html
index 803f726..6f30d26 100644
--- a/ttf.html
+++ b/ttf.html
@@ -12,11 +12,39 @@
- 导出ttf
- 导出woff
- 导出svg
-
-
+
+
+
+
+
+
+
+ 导出ttf
+ 导出woff
+ 导出svg
+
+
+
+
+
+
+
+
+
+
+
正在加载...
+
+
+
+
@@ -47,6 +94,6 @@
define('jquery', $);
require(['fonteditor/ttf/main'])
-
+