From 1361460db912495263dd3f3d3d132062c2b835c7 Mon Sep 17 00:00:00 2001 From: kekee000 Date: Sat, 18 Apr 2015 23:20:37 +0800 Subject: [PATCH] fix svg path cubic import remove optimize of ttfwriter add optimize ttf --- demo/drawCanvas.html | 31 +++++++++++ demo/js/drawCanvas.js | 63 ++++++++++++++++++++++ demo/js/svg2contours.js | 12 +++-- demo/svg2contours.html | 6 +-- index.html | 1 + src/fonteditor/controller/actions.js | 9 ++++ src/fonteditor/widget/exporter.js | 4 +- src/fonteditor/widget/loader.js | 1 - src/fonteditor/widget/previewer.js | 2 +- src/fonteditor/widget/ttfmanager.js | 29 ++++++++++ src/graphics/reducePath.js | 10 +++- src/math/bezierCubic2Q2.js | 13 +++++ src/ttf/svg/path2contours.js | 10 +++- src/ttf/ttf.js | 14 +++++ src/ttf/ttfreader.js | 1 - src/ttf/ttfwriter.js | 23 -------- src/ttf/util/optimizettf.js | 71 +++++++++++++++++++++++++ unittest/spec/ttf/reader-writer.spec.js | 32 +++++++++++ 18 files changed, 294 insertions(+), 38 deletions(-) create mode 100644 demo/drawCanvas.html create mode 100644 demo/js/drawCanvas.js create mode 100644 src/ttf/util/optimizettf.js diff --git a/demo/drawCanvas.html b/demo/drawCanvas.html new file mode 100644 index 0000000..5e2cef1 --- /dev/null +++ b/demo/drawCanvas.html @@ -0,0 +1,31 @@ + + + + + 绘制canvas曲线 + + + + + + + + + + + + + diff --git a/demo/js/drawCanvas.js b/demo/js/drawCanvas.js new file mode 100644 index 0000000..ed66737 --- /dev/null +++ b/demo/js/drawCanvas.js @@ -0,0 +1,63 @@ +/** + * @file 绘制canvas曲线 + * @author mengke01(kekee000@gmail.com) + */ + +define( + function (require) { + var canvas = document.getElementById('canvas'); + var ctx = canvas.getContext('2d'); + + + function drawBezier (val) { + var path = JSON.parse(val); + ctx.clearRect(0, 0, 1000, 1000); + ctx.beginPath(); + ctx.fillStyle = 'black'; + + for (var i = 0; i < path.length; i++) { + + var cubic = path[i].map(function (p) { + p.x = Math.round(p.x); + p.y = Math.round(p.y); + return p; + }); + if (i === 0) { + ctx.moveTo(cubic[0].x, cubic[0].y); + } + + // 退化成直线 + if (cubic[0].x == cubic[1].x && cubic[0].y == cubic[1].y && cubic[2].x == cubic[3].x && cubic[2].y == cubic[3].y) { + ctx.lineTo(cubic[2].x, cubic[2].y); + } + else { + ctx.bezierCurveTo(cubic[1].x, cubic[1].y, cubic[2].x, cubic[2].y,cubic[3].x, cubic[3].y); + } + } + ctx.fill(); + } + + + + + var entry = { + + /** + * 初始化 + */ + init: function () { + + + $('#textarea').on('change', function (e) { + drawBezier(e.target.value); + }); + + drawBezier($('#textarea').val()); + } + }; + + entry.init(); + + return entry; + } +); diff --git a/demo/js/svg2contours.js b/demo/js/svg2contours.js index 3f52854..f302a74 100644 --- a/demo/js/svg2contours.js +++ b/demo/js/svg2contours.js @@ -1,7 +1,7 @@ /** * @file svg2contours.js * @author mengke01 - * @date + * @date * @description * svg转ttfobject */ @@ -12,13 +12,14 @@ define( var path2contours = require('ttf/svg/path2contours'); var contours2svg = require('ttf/util/contours2svg'); - //var text = 'M890.88 748.512q28.672 0 52.736-10.752t41.984-29.184 28.16-43.52 10.24-53.76l0-620.544q0-28.672-10.24-53.76t-28.16-43.52-41.984-29.184-52.736-10.752l-689.152 0q-28.672 0-53.76 10.752t-43.52 29.184-29.184 43.52-10.752 53.76l0 620.544q0 28.672 10.752 53.76t29.184 43.52 43.52 29.184 53.76 10.752l689.152 0zM256 557.024q9.216 0 27.648-0.512t43.008-0.512l52.224 0 55.296 0q64.512 0 141.312 1.024l0 63.488-126.976 0 0 64.512-64.512 0 0-64.512-128 0 0-63.488zM377.856 451.552q-8.192 15.36-15.36 29.696-6.144 12.288-12.288 25.088t-9.216 20.992l-58.368-21.504 32.768-76.8zM254.976 55.264l101.376 143.36-66.56 26.624-98.304-145.408zM448.512 237.536l126.976 0 0 62.464-45.056 0-81.92 0 0 64.512q23.552 0 46.08-0.512t40.96-0.512l40.96 0 0 63.488-66.56 0q-19.456 0-40.96 1.024l68.608 65.536-68.608 32.768-20.48-98.304-257.024 0 0-63.488 35.84 0 47.104 0 53.248 0 56.32 0 0-64.512-128 0 0-62.464 40.96 0q18.432 0 40.96-0.512t46.08 0.512l0-129.024q0-16.384-2.048-27.136t-10.24-15.36-25.088-4.608-47.616 5.12q25.6-31.744 27.648-71.68 13.312 2.048 34.304 1.024t40.448 1.536 33.28 12.8 13.824 34.816l0 192.512zM568.32 126.944q-16.384 19.456-29.696 37.888-11.264 15.36-23.552 30.208t-18.432 23.04l-46.08-30.72 64.512-98.304zM896 432.096q-20.48 1.024-53.248 0.512t-63.488-1.536q-36.864-1.024-75.776-3.072l0 129.024q49.152 0 85.504 4.608t59.904 9.728q27.648 6.144 46.08 14.336-18.432 27.648-29.696 46.08-5.12 8.192-9.728 15.36t-7.68 11.264-3.584 4.608 1.536-4.608q-21.504-16.384-57.344-24.064t-69.632-10.752-57.344-3.072-21.504 0q1.024-16.384 1.536-44.032t0-77.824-1.024-129.024-0.512-196.608q0-13.312-3.072-33.28t-10.24-39.936-19.968-35.328-31.232-19.456q12.288-3.072 21.504-11.776t16.896-18.432 13.824-19.456 12.288-14.848q12.288 18.432 23.552 42.496t20.48 50.176 14.336 52.224 5.12 47.616l0 40.96 0 43.008 0 47.104 0 60.416 64.512 0 0-384 63.488 0 0 384q23.552-1.024 35.328-0.512t29.184-3.584l0 71.68z'; //var text = 'M398.548233 550.86533q0 11.73639-1.956065 22.983763t-6.846227 22.005731q-4.890162 6.846227-9.291309 7.335244t-8.313276-1.467049q-5.868195-2.934097-10.758357-12.714422t-4.890162-27.384909q0.978032-122.254059-1.467049-248.420248t-4.401146-247.442216l-158.441261 0 0 485.104107q0 33.253104-15.64852 57.2149t-57.703916 23.961796l-17.604585 0q26.406877 30.319007 55.258835 44.011461t71.885387 13.692455q28.362942 0 52.813754-10.269341t42.055396-28.851958l3.91213 2.934097 4.890162 3.91213q25.428844 19.560649 52.813754 25.917861t49.879656 6.357211q27.384909 0 51.835721-10.269341t43.033429-28.851958l2.934097 2.934097 4.890162 3.91213q25.428844 19.560649 52.813754 25.917861t49.879656 6.357211q25.428844 0 48.412607-8.802292t40.099331-24.450812 27.873926-37.165234 10.758357-47.923591q1.956065-60.638013 0-147.682904 5.868195 16.626552 14.670487 34.231137t21.027698 32.275072 27.873926 23.961796 36.187202 9.291309q16.626552 0 39.610315-4.401146t44.011461-30.319007 35.698185-81.665712 14.670487-157.463228q0-74.330468-17.115568-133.012416t-43.033429-103.182426-56.236867-76.286533-56.725883-52.324737q6.846227-2.934097 13.692455-3.91213t14.670487-0.978032q18.582617 0 34.231137 5.868195t28.362942 13.692455q13.692455 8.802292 26.406877 20.538682l0-55.747851q-5.868195-15.64852-23.472779-27.384909-14.670487-10.758357-42.055396-19.071633t-74.330468-8.313276q-51.835721 0-89.978988 16.626552-28.362942-9.780325-57.703916-16.626552t-53.791786-11.73639q-28.362942-5.868195-55.747851-9.780325l0 60.638013q13.692455 0 30.319007 3.91213 13.692455 2.934097 32.764088 7.82426t41.56638 14.670487q-13.692455 18.582617-22.494747 41.56638t-14.181471 47.434575-8.313276 50.368672-3.91213 51.346705l0 16.626552 0 468.477555q0 11.73639-1.956065 22.983763t-6.846227 22.005731q-3.91213 6.846227-8.313276 7.82426t-8.313276-0.978032q-4.890162-2.934097-10.269341-11.247373t-6.357211-23.961796q0.978032-55.747851 0.489016-120.787011t-1.467049-131.545368-2.445081-131.056351-2.445081-118.341929l-157.463228 0 0 485.104107zM765.310411 269.191977l0-3.91213 0-16.626552q-0.978032-54.769819-1.956065-101.715377t-0.978032-81.176695q0-32.275072 2.445081-58.192932t7.335244-45.47851q37.165234 42.055396 61.616046 107.094556t24.450812 159.908309q0 89.978988-6.846227 133.990449t-16.626552 55.747851-21.516714-1.956065-22.494747-39.121299-17.604585-56.236867-7.82426-52.324737z' //var text = 'M890.88 748.512q28.672 0 52.736-10.752t41.984-29.184 28.16-43.52 10.24-53.76l0-620.544q0-28.672-10.24-53.76t-28.16-43.52-41.984-29.184-52.736-10.752l-689.152 0q-28.672 0-53.76 10.752t-43.52 29.184-29.184 43.52-10.752 53.76l0 620.544q0 28.672 10.752 53.76t29.184 43.52 43.52 29.184 53.76 10.752l689.152 0zM256 557.024q9.216 0 27.648-0.512t43.008-0.512l52.224 0 55.296 0q64.512 0 141.312 1.024l0 63.488-126.976 0 0 64.512-64.512 0 0-64.512-128 0 0-63.488zM377.856 451.552q-8.192 15.36-15.36 29.696-6.144 12.288-12.288 25.088t-9.216 20.992l-58.368-21.504 32.768-76.8zM254.976 55.264l101.376 143.36-66.56 26.624-98.304-145.408zM448.512 237.536l126.976 0 0 62.464-45.056 0-81.92 0 0 64.512q23.552 0 46.08-0.512t40.96-0.512l40.96 0 0 63.488-66.56 0q-19.456 0-40.96 1.024l68.608 65.536-68.608 32.768-20.48-98.304-257.024 0 0-63.488 35.84 0 47.104 0 53.248 0 56.32 0 0-64.512-128 0 0-62.464 40.96 0q18.432 0 40.96-0.512t46.08 0.512l0-129.024q0-16.384-2.048-27.136t-10.24-15.36-25.088-4.608-47.616 5.12q25.6-31.744 27.648-71.68 13.312 2.048 34.304 1.024t40.448 1.536 33.28 12.8 13.824 34.816l0 192.512zM568.32 126.944q-16.384 19.456-29.696 37.888-11.264 15.36-23.552 30.208t-18.432 23.04l-46.08-30.72 64.512-98.304zM896 432.096q-20.48 1.024-53.248 0.512t-63.488-1.536q-36.864-1.024-75.776-3.072l0 129.024q49.152 0 85.504 4.608t59.904 9.728q27.648 6.144 46.08 14.336-18.432 27.648-29.696 46.08-5.12 8.192-9.728 15.36t-7.68 11.264-3.584 4.608 1.536-4.608q-21.504-16.384-57.344-24.064t-69.632-10.752-57.344-3.072-21.504 0q1.024-16.384 1.536-44.032t0-77.824-1.024-129.024-0.512-196.608q0-13.312-3.072-33.28t-10.24-39.936-19.968-35.328-31.232-19.456q12.288-3.072 21.504-11.776t16.896-18.432 13.824-19.456 12.288-14.848q12.288 18.432 23.552 42.496t20.48 50.176 14.336 52.224 5.12 47.616l0 40.96 0 43.008 0 47.104 0 60.416 64.512 0 0-384 63.488 0 0 384q23.552-1.024 35.328-0.512t29.184-3.584l0 71.68z' //var text = 'M117 419 L335 419 Q337 419 337 417 L337 383 Q337 381 335 381 L300 381 Q373 237 373 235 L375 235 L448 382 Q446 382 412 418 L414 419 L557 419 Q559 419 559 417 L559 383 Q559 381 557 381 L521 381 L338 13 L337 13 Q335 14 152 381 L117 381 Q115 381 115 383 L115 417 Q115 419 117 419 Z' //var text = 'M269.5,102V36.3c0-8,10-15.2,18-15.2s16.6,7.2,16.6,15.2v45.9h22.5V36.3C326.5,17.4,309.799,0,291,0 c-30.1,0-42.6,17.4-42.6,36.3v67.2c-29.701,5.7-54.602,26.1-67.701,52.3 -11.4-23-32-41.4-56.8-49.5v-70C123.8,17.4,111.3,0,81.2,0 C62.4,0,45.6,17.4,45.6,36.3v45.9h22.5V36.3c0-8,8.601-15.2,16.601-15.2s18,7.2,18,15.2v65.9c-2.2-0.2-4.5-0.3-6.8-0.3 C43.8,101.9,0,145.7,0,197.8c0,52.1,43.8,94.5,95.9,94.5h169.399c52.102,0,95.9-42.4,95.9-94.5 C361.299,147.1,319.799,104.2,269.5,102z M265.299,269.8H95.9c-41.301,0-73.4-30.801-73.4-72c0-41.3,32.2-74.1,73.4-74.1 c41.3,0,74.8,32.899,74.8,74.1h19.701c0-41.3,33.6-74.1,74.799-74.1c41.301,0,73.4,32.899,73.4,74.1 C338.7,239.099,306.6,269.8,265.299,269.8z M90.6,326.3h180.5v-11.6H90.6V326.3z' - var text = 'M216.501,199.847c-11.442,0-21.956,3.891-30.38,10.367l-86.92-52.15c0.436-2.668,0.722-5.389,0.722-8.178c0-2.793-0.286-5.509-0.722-8.177l86.92-52.153c8.424,6.478,18.938,10.368,30.38,10.368c27.589,0,49.962-22.372,49.962-49.962 C266.463,22.372,244.09,0,216.501,0c-27.59,0-49.961,22.372-49.961,49.961c0,2.792,0.286,5.511,0.728,8.178L80.349,110.29 c-8.425-6.476-18.941-10.367-30.387-10.367C22.372,99.923,0,122.295,0,149.886c0,27.59,22.372,49.961,49.962,49.961 c11.446,0,21.962-3.891,30.387-10.365l86.918,52.15c-0.441,2.666-0.728,5.383-0.728,8.178c0,27.588,22.371,49.961,49.961,49.961 c27.589,0,49.962-22.373,49.962-49.961C266.463,222.22,244.09,199.847,216.501,199.847Z' + //var text = 'M216.501,199.847c-11.442,0-21.956,3.891-30.38,10.367l-86.92-52.15c0.436-2.668,0.722-5.389,0.722-8.178c0-2.793-0.286-5.509-0.722-8.177l86.92-52.153c8.424,6.478,18.938,10.368,30.38,10.368c27.589,0,49.962-22.372,49.962-49.962 C266.463,22.372,244.09,0,216.501,0c-27.59,0-49.961,22.372-49.961,49.961c0,2.792,0.286,5.511,0.728,8.178L80.349,110.29 c-8.425-6.476-18.941-10.367-30.387-10.367C22.372,99.923,0,122.295,0,149.886c0,27.59,22.372,49.961,49.962,49.961 c11.446,0,21.962-3.891,30.387-10.365l86.918,52.15c-0.441,2.666-0.728,5.383-0.728,8.178c0,27.588,22.371,49.961,49.961,49.961 c27.589,0,49.962-22.373,49.962-49.961C266.463,222.22,244.09,199.847,216.501,199.847Z' //var text = 'M300,200 h-150 a150,150 0 1,0 150,-150 z'; + var text = 'M832 1024c-35.36 0-64-28.672-64-64 0 0 0-896.032 0-896.032 0-35.328 28.64-64 64-64 35.328 0 64 28.672 64 64 0 0 0 896.032 0 896.032 0 35.328-28.672 64-64 64z' + //var text = 'M647.5,1053.563c-35.36,0-64-28.672-64-64V93.532c0-35.328,28.64-64,64-64c35.327,0,64,28.672,64,64v896.031C711.5,1024.892,682.827,1053.563,647.5,1053.563z M64,1024.032c-35.36,0-64-28.672-64-64V64C0,28.672,28.64,0,64,0c35.328,0,64,28.672,64,64v896.032C128,995.36,99.328,1024.032,64,1024.032z' var entry = { /** @@ -27,6 +28,7 @@ define( init: function () { var contours = path2contours(text); + console.log(contours); var path = contours2svg(contours); $('#path').attr('d', path); @@ -34,7 +36,7 @@ define( }; entry.init(); - + return entry; } -); \ No newline at end of file +); diff --git a/demo/svg2contours.html b/demo/svg2contours.html index 374dd43..d37e9bc 100644 --- a/demo/svg2contours.html +++ b/demo/svg2contours.html @@ -11,8 +11,8 @@ - - + + @@ -32,4 +32,4 @@ - \ No newline at end of file + diff --git a/index.html b/index.html index 0d6e1c2..e98827c 100644 --- a/index.html +++ b/index.html @@ -58,6 +58,7 @@
  • 字体度量
  • 生成字形名称
  • 清除字形名称
  • +
  • 优化字体
  • 编辑器
  • 导入和导出
  • diff --git a/src/fonteditor/controller/actions.js b/src/fonteditor/controller/actions.js index c8eaa08..4b37670 100644 --- a/src/fonteditor/controller/actions.js +++ b/src/fonteditor/controller/actions.js @@ -266,6 +266,15 @@ define( } }, + 'setting-optimize': function () { + if (program.ttfManager.get()) { + var result = program.ttfManager.optimize(); + if (true !== result) { + alert(result.message); + } + } + }, + 'setting-editor': function () { var SettingEditor = settingSupport.editor; !new SettingEditor({ diff --git a/src/fonteditor/widget/exporter.js b/src/fonteditor/widget/exporter.js index 5e37c37..0ee5c92 100644 --- a/src/fonteditor/widget/exporter.js +++ b/src/fonteditor/widget/exporter.js @@ -145,11 +145,11 @@ define( } catch (e) { $(options.target).removeAttr('download'); - //alert(e.message); - throw e; if (options.error) { options.error(e); } + alert(e.message); + throw e; } } diff --git a/src/fonteditor/widget/loader.js b/src/fonteditor/widget/loader.js index 5e8add2..1041102 100644 --- a/src/fonteditor/widget/loader.js +++ b/src/fonteditor/widget/loader.js @@ -58,7 +58,6 @@ define( } catch (exp) { alert(exp.message); - throw exp; } loading.hide(); diff --git a/src/fonteditor/widget/previewer.js b/src/fonteditor/widget/previewer.js index 586530f..687c10f 100644 --- a/src/fonteditor/widget/previewer.js +++ b/src/fonteditor/widget/previewer.js @@ -92,8 +92,8 @@ define( } } catch (exp) { + alert(exp.message); throw exp; - //alert(exp.message); } } }; diff --git a/src/fonteditor/widget/ttfmanager.js b/src/fonteditor/widget/ttfmanager.js index 538693f..0341fd6 100644 --- a/src/fonteditor/widget/ttfmanager.js +++ b/src/fonteditor/widget/ttfmanager.js @@ -429,6 +429,35 @@ define( return this; }; + /** + * 优化字体 + * + * @return {true|Object} 优化成功,或者错误信息 + */ + Manager.prototype.optimize = function () { + + var result = this.ttf.optimize(); + + this.ttf.get().glyf.forEach(function (g) { + g.modify = 'edit'; + }); + + this.fireChange(true); + + if (true === result) { + return true; + } + + var message = ''; + if (result.repeat) { + message = '重复的unicode代码点,字形序号:' + result.repeat.join(','); + } + + return { + message: message + }; + }; + /** * 撤销 * @return {this} diff --git a/src/graphics/reducePath.js b/src/graphics/reducePath.js index a21716f..d7a6180 100644 --- a/src/graphics/reducePath.js +++ b/src/graphics/reducePath.js @@ -28,7 +28,7 @@ define( return true; } - // 三点同线 仅处理三个在直线上的点 + // 三点同线 检查直线点 if ( (p.onCurve && prev.onCurve && next.onCurve) && Math.abs((next.y - p.y) * (prev.x - p.x) - (prev.y - p.y) * (next.x - p.x)) <= 0.001 @@ -36,6 +36,14 @@ define( return true; } + // 三点同线 检查控制点 + if ( + (!p.onCurve && prev.onCurve && next.onCurve) + && Math.abs((next.y - p.y) * (prev.x - p.x) - (prev.y - p.y) * (next.x - p.x)) <= 0.001 + ) { + return true; + } + return false; } diff --git a/src/math/bezierCubic2Q2.js b/src/math/bezierCubic2Q2.js index 870fecb..ec31fdb 100644 --- a/src/math/bezierCubic2Q2.js +++ b/src/math/bezierCubic2Q2.js @@ -40,6 +40,19 @@ define(function (require) { */ function bezierCubic2Q2(p1, c1, c2, p2) { + // 判断极端情况,控制点和起止点一样 + if (p1.x === c1.x && p1.y === c1.y && c2.x === p2.x && c2.y === p2.y) { + return [[ + p1, + { + x: (p1.x + p2.x) / 2, + y: (p1.y + p2.y) / 2 + }, + p2 + ]]; + } + + var mx = p2.x - 3 * c2.x + 3 * c1.x - p1.x; var my = p2.y - 3 * c2.y + 3 * c1.y - p1.y; diff --git a/src/ttf/svg/path2contours.js b/src/ttf/svg/path2contours.js index 2fa9d88..5658393 100644 --- a/src/ttf/svg/path2contours.js +++ b/src/ttf/svg/path2contours.js @@ -8,6 +8,7 @@ define(function (require) { var bezierCubic2Q2 = require('math/bezierCubic2Q2'); var getArc = require('graphics/getArc'); var parseParams = require('./parseParams'); + var reducePath = require('graphics/reducePath'); /** * 三次贝塞尔曲线,转二次贝塞尔曲线 @@ -57,6 +58,11 @@ define(function (require) { x: q2[1].x, y: q2[1].y }); + contour.push({ + x: q2[2].x, + y: q2[2].y, + onCurve: true + }); } } @@ -445,7 +451,9 @@ define(function (require) { } } - return contours; + return contours.map(function (p) { + return reducePath(p); + }); } diff --git a/src/ttf/ttf.js b/src/ttf/ttf.js index 853243a..3d48000 100644 --- a/src/ttf/ttf.js +++ b/src/ttf/ttf.js @@ -17,6 +17,7 @@ define( var pathCeil = require('graphics/pathCeil'); var computeBoundingBox = require('graphics/computeBoundingBox'); var glyfAdjust = require('./util/glyfAdjust'); + var optimizettf = require('./util/optimizettf'); var config = require('./data/default'); /** @@ -788,6 +789,19 @@ define( }; }; + + /** + * 优化ttf字形信息 + * + * @param {Object} glyf glyfobject + * @param {string} index 需要替换的索引列表 + * @return {Array} 改变的glyf + */ + TTF.prototype.optimize = function () { + return optimizettf(this.ttf); + }; + + return TTF; } ); diff --git a/src/ttf/ttfreader.js b/src/ttf/ttfreader.js index df155d2..cfc8987 100644 --- a/src/ttf/ttfreader.js +++ b/src/ttf/ttfreader.js @@ -128,7 +128,6 @@ define( delete ttf.loca; delete ttf.post.glyphNameIndex; delete ttf.post.names; - delete ttf.cmap; if (!this.options.hinting) { delete ttf.fpgm; diff --git a/src/ttf/ttfwriter.js b/src/ttf/ttfwriter.js index 499e3fb..9e4fb23 100644 --- a/src/ttf/ttfwriter.js +++ b/src/ttf/ttfwriter.js @@ -16,9 +16,6 @@ define( var checkSum = require('./util/checkSum'); var error = require('./error'); - var reduceGlyf = require('./util/reduceGlyf'); - var pathCeil = require('graphics/pathCeil'); - // 支持写的表, 注意表顺序 var SUPPORT_TABLES = [ 'OS/2', @@ -101,26 +98,6 @@ define( }); } - - if (!glyf.compound && glyf.contours) { - - // 整数化 - glyf.contours.forEach(function (contour) { - pathCeil(contour); - }); - - // 缩减glyf - reduceGlyf(glyf); - } - - // 整数化 - glyf.xMin = Math.round(glyf.xMin || 0); - glyf.xMax = Math.round(glyf.xMax || 0); - glyf.yMin = Math.round(glyf.yMin || 0); - glyf.yMax = Math.round(glyf.yMax || 0); - glyf.leftSideBearing = Math.round(glyf.leftSideBearing || 0); - glyf.advanceWidth = Math.round(glyf.advanceWidth || 0); - }); } diff --git a/src/ttf/util/optimizettf.js b/src/ttf/util/optimizettf.js new file mode 100644 index 0000000..c30316f --- /dev/null +++ b/src/ttf/util/optimizettf.js @@ -0,0 +1,71 @@ +/** + * @file 对ttf对象进行优化,查找错误,去除冗余点 + * @author mengke01(kekee000@gmail.com) + */ + + +define( + function (require) { + + var reduceGlyf = require('./reduceGlyf'); + var pathCeil = require('graphics/pathCeil'); + + /** + * 对ttf对象进行优化 + * @param {Object} ttf ttf对象 + * @return {true|Object} 错误信息 + */ + function optimizettf(ttf) { + + var checkUnicodeRepeat = {}; // 检查是否有重复代码点 + var repeatList = []; + + // 将glyf的代码点按小到大排序 + ttf.glyf.forEach(function (glyf, index) { + if (glyf.unicode) { + glyf.unicode = glyf.unicode.sort(); + + glyf.unicode.forEach(function (u) { + if (checkUnicodeRepeat[u]) { + repeatList.push(index); + } + else { + checkUnicodeRepeat[u] = true; + } + }); + + } + + if (!glyf.compound && glyf.contours) { + + // 整数化 + glyf.contours.forEach(function (contour) { + pathCeil(contour); + }); + + // 缩减glyf + reduceGlyf(glyf); + } + + // 整数化 + glyf.xMin = Math.round(glyf.xMin || 0); + glyf.xMax = Math.round(glyf.xMax || 0); + glyf.yMin = Math.round(glyf.yMin || 0); + glyf.yMax = Math.round(glyf.yMax || 0); + glyf.leftSideBearing = Math.round(glyf.leftSideBearing || 0); + glyf.advanceWidth = Math.round(glyf.advanceWidth || 0); + }); + + if (!repeatList.length) { + return true; + } + + return { + repeat: repeatList + }; + } + + + return optimizettf; + } +); diff --git a/unittest/spec/ttf/reader-writer.spec.js b/unittest/spec/ttf/reader-writer.spec.js index afe2525..07dddcd 100644 --- a/unittest/spec/ttf/reader-writer.spec.js +++ b/unittest/spec/ttf/reader-writer.spec.js @@ -20,6 +20,10 @@ define( writer.writeUint16(2442); writer.writeUint32(5375673); + writer.writeUint8(55.45444444); + writer.writeUint16(55.45444444); + writer.writeUint32(55.45444444); + var reader = new Reader(buffer, 0, 100); expect(reader.readInt8()).toBe(10); @@ -28,6 +32,34 @@ define( expect(reader.readUint8()).toBe(10); expect(reader.readUint16()).toBe(2442); expect(reader.readUint32()).toBe(5375673); + + expect(reader.readUint8()).toBe(55); + expect(reader.readUint16()).toBe(55); + expect(reader.readUint32()).toBe(55); + }); + + it('test write decimals', function () { + var writer = new Writer(buffer, 0, 100); + + // 基本类型 + writer.writeInt8(-55.99999); + writer.writeInt16(-55.99999); + writer.writeInt32(-55.999999); + + writer.writeUint8(55.45444444); + writer.writeUint16(55.45444444); + writer.writeUint32(55.45444444); + + var reader = new Reader(buffer, 0, 100); + + + expect(reader.readInt8()).toBe(-55); + expect(reader.readInt16()).toBe(-55); + expect(reader.readInt32()).toBe(-55); + + expect(reader.readUint8()).toBe(55); + expect(reader.readUint16()).toBe(55); + expect(reader.readUint32()).toBe(55); });