Repository: cmiscm/leonsans
Branch: master
Commit: f8c03c92d805
Files: 48
Total size: 309.1 KB
Directory structure:
gitextract_04kbmd_5/
├── .gitignore
├── LICENSE
├── README.md
├── dist/
│ └── leon.js
├── examples/
│ ├── all.html
│ ├── canvas-basic.html
│ ├── color-pattern.html
│ ├── colorful.html
│ ├── gradient.html
│ ├── grid.html
│ ├── index.html
│ ├── js/
│ │ └── util.js
│ ├── mask-tiling-pixi.html
│ ├── metaball-pixi.html
│ ├── morphing-pixi.html
│ ├── pattern.html
│ ├── plants-pixi.html
│ ├── wave.html
│ └── webgl-basic-pixi.html
└── src/
├── core/
│ ├── align.js
│ ├── dispatcher.js
│ ├── group.js
│ ├── guide.js
│ ├── length.js
│ ├── model.js
│ ├── paths.js
│ ├── point.js
│ ├── util.js
│ └── vector.js
├── draw/
│ ├── canvas/
│ │ ├── color.js
│ │ ├── colorful.js
│ │ ├── grids.js
│ │ ├── lines.js
│ │ ├── pattern.js
│ │ ├── points.js
│ │ └── wave.js
│ └── pixi/
│ ├── color.js
│ └── lines.js
├── font/
│ ├── index.js
│ ├── latin.js
│ ├── latinutil.js
│ ├── lower.js
│ ├── number.js
│ ├── special.js
│ ├── upper.js
│ └── util.js
├── index.js
└── leonsans.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
examples/.DS_Store
examples/data/.DS_Store
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2019 Jongmin Kim
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: README.md
================================================
# Leon Sans
Leon Sans is a geometric sans-serif typeface made with code in 2019 by Jongmin Kim. It allows to change font weight dynamically and to create custom animations, effects or shapes in the Canvas element of HTML5. He designed the font to celebrate his newborn baby Leon.
There are live examples at https://leon-kim.com/examples/
And website at https://leon-kim.com/
[](https://youtu.be/sb7v-d-R11E?hl=en&fs=1&cc_load_policy=1)





## What is special?
The font is made with code, it has coordinate values of the drawing points for each glyph. With the coordinate values, you can create custom shapes, effects or animations.

- [Drawing animation](https://leon-kim.com/examples/#canvas-basic)

- [Weight change](https://leon-kim.com/examples/#canvas-basic)

- [Wave](https://leon-kim.com/examples/#wave)

- [Metaball](https://leon-kim.com/examples/#metaball-pixi)

- [Plant](https://leon-kim.com/examples/#plants-pixi)

- [Colorful](https://leon-kim.com/examples/#colorful)

- [Color pattern](https://leon-kim.com/examples/#color-pattern)
## Usage
Download the minified js file in dist folder and include it in your html.
```html
```
Generate LeonSans and draw it in the Canvas element of HTML5.
```javascript
let leon, canvas, ctx;
const sw = 800;
const sh = 600;
const pixelRatio = 2;
function init() {
canvas = document.createElement('canvas');
document.body.appendChild(canvas);
ctx = canvas.getContext("2d");
canvas.width = sw * pixelRatio;
canvas.height = sh * pixelRatio;
canvas.style.width = sw + 'px';
canvas.style.height = sh + 'px';
ctx.scale(pixelRatio, pixelRatio);
leon = new LeonSans({
text: 'The quick brown\nfox jumps over\nthe lazy dog',
color: ['#000000'],
size: 80,
weight: 200
});
requestAnimationFrame(animate);
}
function animate(t) {
requestAnimationFrame(animate);
ctx.clearRect(0, 0, sw, sh);
const x = (sw - leon.rect.w) / 2;
const y = (sh - leon.rect.h) / 2;
leon.position(x, y);
leon.draw(ctx);
}
window.onload = () => {
init();
};
```
For the drawing animation, include TweenMax (JS animation library) in your html.
```html
```
And update all the drawing values from 0 to 1
```javascript
let i, total = leon.drawing.length;
for (i = 0; i < total; i++) {
TweenMax.fromTo(leon.drawing[i], 1.6, {
value: 0
}, {
delay: i * 0.05,
value: 1,
ease: Power4.easeOut
});
}
```
### Option list
| Name | Type | Description |
| -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `text` | string | The text that needs to be shown. |
| `size` | integer | The size of the text. |
| `weight` | number | The weight of the font: `1 - 900`. [Default: `1`] |
| `color` | array | The colors of each characters. [Default: `['#000000']`] |
| `colorful` | array | The colors for colorful effect. [Default: `['#c5d73f', '#9d529c', '#49a9db', '#fec330', '#5eb96e', '#fc5356', '#f38f31']`] |
| `tracking` | integer | The spacing between the characters of a block of text. [Default: `0`] |
| `leading` | integer | The distance between each line of text. [Default: `0`] |
| `align` | string | How the text content of the element is horizontally aligned: `left, center, right`. [Default: `left`] |
| `pathGap` | number | The gap between each coordinate of the points on a line of each character: `0 - 1`. [Default: `0.5`] |
| `amplitude` | number | The amplitude of the wave effect: `0 - 1`. [Default: `0.5`] |
| `maxWidth` | number | The width of the text sentence. |
| `breakWord` | boolean | Words break when reaching the end of a line. [Default: `false`] |
| `fps` | number | The FPS for the wave effect. [Default: `30`] |
| `isPath` | boolean | `true` to get the coordinate values of the points on a line of each character. [Default: `false`] |
| `isWave` | boolean | `true` for the wave effect. [Default: `false`] |
### Properties
| Name | Type | Description |
| -------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `lineWidth` | number | The thickness of lines of the character. |
| `scale` | number | The scale of the character. `scale` is `1` when the font size is `500`. |
| `drawing` | array | The drawing object values for each character. `0` is the beginning of the animation, `1` is the end of the animation state. |
| `data` | array | An object of the raw data for the text. |
| `paths` | array | The coordinate values of the points on a line of each character. |
| `drawingPaths` | array | The coordinate values of the points on a line of each character to draw the drawing animation in WebGL. It has 1px distance of each path. |
| `wavePaths` | array | The coordinate values of the points on a line for the wave effect. |
| `rect` | Object | The size of the text and its position: `{x: x position, y: y position, w: width, h: height}`.|
### Methods
| Name | Description |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `on()` | Add `update` event. |
| `off()` | Remove `update` event. |
| `position(x, y)` | Set the position of the text. |
| `updateDrawingPaths()` | Update paths for drawing in WebGL (PIXI.js). It's very expensive, only call when it needs. |
| `drawPixi(graphics)` | Draw text in WebGL with PIXI.js. |
| `draw(ctx)` | Draw text in the Canvas element. |
| `drawColorful(ctx)` | Draw the colorful effect. |
| `wave(ctx, t)` | Draw the wave effect. |
| `pattern(ctx, w, h)` | Draw rectangle shapes at each path point |
| `grid(ctx)` | Draw grid for each type. |
| `point(ctx)` | Draw circles at each drawing point and lines for each type. |
| `box(ctx)` | Draw outline box for the text. |
| `reset()` | Reset all the values. |
| `dispose()` | Dispose. |
================================================
FILE: dist/leon.js
================================================
/*!
* VERSION: 1.6.5
* DATE: 2020-09-20
* https://leon-sans.com
*
* @license Copyright (c) 2019-2020, Jongmin Kim. All rights reserved.
**/
var LeonSans=function(t){var r={};function i(e){if(r[e])return r[e].exports;var a=r[e]={i:e,l:!1,exports:{}};return t[e].call(a.exports,a,a.exports,i),a.l=!0,a.exports}return i.m=t,i.c=r,i.d=function(t,r,e){i.o(t,r)||Object.defineProperty(t,r,{enumerable:!0,get:e})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,r){if(1&r&&(t=i(t)),8&r)return t;if(4&r&&"object"==typeof t&&t&&t.__esModule)return t;var e=Object.create(null);if(i.r(e),Object.defineProperty(e,"default",{enumerable:!0,value:t}),2&r&&"string"!=typeof t)for(var a in t)i.d(e,a,function(r){return t[r]}.bind(null,a));return e},i.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(r,"a",r),r},i.o=function(t,r){return Object.prototype.hasOwnProperty.call(t,r)},i.p="",i(i.s=0)}([function(t,r,i){var e=i(1).default;t.exports=e},function(t,r,i){"use strict";i.r(r),i.d(r,"default",(function(){return Zt}));var e=1,a=2*Math.PI;function s(t,r){var i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:0,e=arguments.length>3&&void 0!==arguments[3]?arguments[3]:0,a=.49*t.rect.w*r,s=.49*(t.rect.h+220)*r;return{x:i,y:e,w:a,h:s}}function n(t,r,i){return{x:t/2,y:(r-130*.49*i)/2}}function l(t,r,i){return{r:r,cr:i,fr1:1,fr2:.78,gx1:t.ratio.x1,gx2:t.ratio.x2,gy1:t.ratio.y1,gy2:t.ratio.y2}}function f(t,r,i,e,a){var s=(e-a)/(r-i)*(t-i)+a;return se&&(s=e),s}function o(t){var r,i,e,a,s,n,l,o,h,y,d,c=t.typo.p.length,p=[];for(r=0;r0)for(e=0;e{var i=f(r.drawing.value,r.maxDrawing,r.minDrawing,1,0);if(i>0&&"a"!=r.pos.type){var e=r.lengths*i;t.setLineDash([r.lengths]),t.lineDashOffset=r.direction*(e+r.lengths),t.stroke()}}})}return p}function h(t,r){var i,e,a=t.length,s=[];for(i=0;i0){var o=i*l;t.setLineDash([i]),t.lineDashOffset=r.direction*(o+i),t.stroke()}return n}function T(t,r,i,e){var a,s;if(1==r.drawing.value)for(a=r.lines.length,s=0;s0&&(p[0].start=1,Array.prototype.push.apply(c,p))}return c}function X(t,r,i){var e,a,s,n,l,o,h,y=t.length,d=[],c=1,p=1;for(r>-1&&(p=f(r,1,0,80,10)*i),e=0;e0&&null!=(h=E(l,A,n,o))&&(c&&(h.type="m",c=0),d.push(h)),A=new z(l);return d}function E(t,r,i,e){if(t.type=i.type,t.distance=i.distance,t.num=e,r&&null==t.rotation){var a=t.x-r.x,s=t.y-r.y,n=Math.atan2(a,s);t.rotation=-n}else t.rotation=t.rotation;return t.rotation==V?null:t}function B(t,r){var i=H(t.x1,t.x2,t.x3,t.x4,r),e=H(t.y1,t.y2,t.y3,t.y4,r),a=K(t.x1,t.x2,t.x3,t.x4,r),s=K(t.y1,t.y2,t.y3,t.y4,r);return new z({x:i,y:e,rotation:-Math.atan2(a,s)})}function H(t,r,i,e,a){var s=a*a;return t+(3*-t+a*(3*t-t*a))*a+(3*r+a*(-6*r+3*r*a))*a+(3*i-3*i*a)*s+e*(s*a)}function K(t,r,i,e,a){return 3*a*a*(3*r-t-3*i+e)+6*a*(t-2*r+i)+3*(-t+r)}var Q=Math.PI/180*180,U=Math.PI/180*90,V=-100;function Y(t,r,i,e,a,s,n,l){var f,o=[],h=l.length;for(f=0;f{for(var l=[],f=0;f":Y(423,90,352,0,0,0,0,[{d:-1,v:[["m",0,0,{x:-1,y:.3,r:$(0,0,90,176)}],["l",90,176,{r:Q,f:1}],["l",0,352,{x:-1,y:.3,f:1}]]}]),"/":Y(433,130,352,0,0,0,0,[{d:1,v:[["m",0,352,{r:$(0,352,130,0),f:1,y:0}],["l",130,0,{y:0}]]}]),"þ":Y(600,232,338,-10,-2,-117,-117,[{d:-1,v:[["m",0,-106,{y:0}],["l",0,116,{r:V}],["b",0,180.1,51.9,232,116,232,{r:U}],["b",180.1,232,232,180.1,232,116,{r:Q}],["b",232,51.9,180.1,0,116,0,{r:U}],["b",51.9,0,0,51.9,0,116,{r:Q}],["l",0,338,{y:0,f:1}]]}]),"Þ":Y(520,162,352,-5,-70,0,0,[{d:-1,v:[["m",0,0,{x:0,y:0,r:Q}],["l",0,352,{x:0,y:0,r:Q,f:1}]]},{d:1,v:[["m",0,281.6,{x:0,r:U,f:1,p:1}],["l",57,281.6,{x:-.5,r:U,f:1}],["b",115,281.6,162,233.4,162,175.4,{x:-.5,r:Q}],["b",162,117.4,115,70.4,57,70.4,{x:-.5,r:U}],["l",0,70.4,{x:0,r:U,f:1,p:1}]]}]),"ß":Y(596,209,352,-10,-10,0,0,[{d:1,v:[["m",0,348.3,{r:Q,f:1,x:0,y:0}],["l",0,104.3,{x:0}],["b",0,46,36,0,98.9,0,{x:0}],["b",145.2,0,191,27.9,191,81,{x:1}],["b",191,110.7,165.6,131.8,151.8,140.9],["l",140,148.8],["b",120.6,161.7,110.8,172.8,110.8,185.5],["b",110.8,206.7,131.6,213.8,140,217.5],["b",190.6,241.1,211,262.7,211,289.6],["b",211,329.5,174.8,352,142.5,352],["b",97.3,352,75.2,319.7,72.3,289.3]]}])};function kt(t,r){var i=t,e=-60+r;return[{d:-1,v:[["m",-40+i,e,{x:0,y:0,r:$(-40+i,e,0+i,60+e)}],["l",0+i,60+e,{x:0,y:0,f:1}]]}]}function Dt(t,r){var i=t,e=-60+r;return[{d:-1,v:[["m",40+i,e,{x:0,y:0,r:$(40+i,e,0+i,60+e)}],["l",0+i,60+e,{x:0,y:0,f:1}]]}]}function Tt(t,r){var i=-68+t,e=0+r;return[{d:-1,v:[["m",0+i,50+e,{r:$(0+i,50+e,66.5+i,0+e),y:0,x:0}],["l",66.5+i,0+e,{r:$(0+i,50+e,66.5+i,0+e),y:0,x:0,f:1}],["l",69.5+i,0+e,{r:$(69.5+i,0+e,136+i,50+e),y:0,x:0,f:1,v:1}],["l",136+i,50+e,{y:0,x:0,f:1}]]}]}function It(t,r){var i=t-76.24,e=r;return[{d:1,v:[["m",159.52+i,16.56+e,{x:-1,y:-.2,r:tt(159.52+i,16.56+e,150.08+i,29.28+e,134.56+i,37.68+e,118.56+i,37.68+e,0),f:1}],["b",150.08+i,29.28+e,134.56+i,37.68+e,118.56+i,37.68+e,{x:-1,y:-.2,r:U}],["b",103.28+i,37.68+e,89.68+i,29.28+e,76.24+i,20.4+e,{x:-1,y:-.2}],["b",61.44+i,10.56+e,47.28+i,0+e,31.68+i,0+e,{x:-1,y:-.2,r:U}],["b",17.84+i,0+e,8.72+i,7.12+e,0+i,16+e,{x:-1,y:-.2}]]}]}function Rt(t,r){return[{d:1,v:[["a",-50+t,r,{x:0,y:0}]]},{d:1,v:[["a",50+t,r,{x:0,y:0}]]}]}function Ft(t,r){var i=t-57,e=r;return[{d:1,v:[["m",112.7+i,0+e,{r:tt(112.7+i,0+e+i,10.1+e,110.1+i,19.3+e,105+i,27.7+e,0),x:0,y:0,f:1}],["b",112.7+i,10.1+e,110.1+i,19.3+e,105+i,27.7+e,{x:0,y:0}],["b",99.8+i,36.1+e,92.9+i,42.8+e,84.3+i,47.7+e,{x:0,y:0}],["b",75.7+i,52.6+e,66.7+i,55+e,57.3+i,55+e,{x:0,y:0}],["b",47.5+i,55+e,38.3+i,52.6+e,29.6+i,47.7+e,{x:0,y:0}],["b",20.8+i,42.8+e,13.8+i,36.1+e,8.5+i,27.7+e,{x:0,y:0}],["b",3.2+i,19.3+e,.5+i,10.1+e,.5+i,0+e,{x:0,y:0}]]}]}function Mt(t,r){var i=88+t,e=-116+r;return[{d:1,v:[["m",116+i,58+e,{r:Q,p:1,f:1}],["b",116+i,90.05+e,90.05+i,116+e,58+i,116+e,{r:U}],["b",25.95+i,116+e,0+i,90.05+e,0+i,58+e,{r:Q}],["b",0+i,25.95+e,25.95+i,0+e,58+i,0+e,{r:U}],["b",90.05+i,0+e,116+i,25.95+e,116+i,58+e,{r:Q,c:1}]]}]}function Gt(t,r){return[{d:1,v:[["m",t-40,r,{x:0,y:1,r:U}],["l",100+t,r,{x:0,y:1,f:1}]]}]}function zt(t,r){return[{d:-1,v:[["m",t,r,{p:1}],["b",9.3+t,11.6+r,15.6+t,27.1+r,15.6+t,40.9+r],["b",15.6+t,83.3+r,-18.2+t,107.8+r,-59.5+t,107.8+r],["b",-70.9+t,107.8+r,-82.9+t,106.2+r,-93.7+t,102.7+r,{x:.5,f:1}]]}]}function Lt(t,r){return[{d:-1,v:[["m",t,r,{p:1}],["b",-19.6+t,14.8+r,-42.2+t,37.9+r,-42.2+t,64.1+r],["b",-42.2+t,100.3+r,30.2-42.2+t,118.8+r,21.4+t,118.8+r],["b",68.3-42.2+t,118.8+r,72.9-42.2+t,118.4+r,35.2+t,117.6+r,{x:.5,f:1}]]}]}function jt(t,r){return[{d:1,v:[["a",t,r,{x:0,y:0}]]}]}function Ct(t,r){var i=-68+t,e=r;return[{d:-1,v:[["m",0+i,e,{r:$(0+i,e,66.5+i,50+e),y:0,x:0}],["l",66.5+i,50+e,{r:$(0+i,e,66.5+i,50+e),y:0,x:0,f:1}],["l",69.5+i,50+e,{r:$(69.5+i,50+e,136+i,e),y:0,x:0,f:1,v:1}],["l",136+i,e,{y:0,x:0,f:1}]]}]}function At(t,r){return[{d:1,v:[["m",t-50,r,{x:0,y:0}],["l",t+50,r,{x:0,y:0,f:1}]]}]}var qt,Xt,Et=[{d:1,v:[["m",0,352,{y:0,f:1}],["l",0,130,{y:-3}]]}],Bt=[{d:1,v:[["m",-115.9,444,{x:.4,y:.63,r:tt(-115.9,444,12.6-115.9,454.4,29.6-115.9,460.2,-70,461.2,0),f:1}],["b",12.6-115.9,454.4,29.6-115.9,460.2,-70,461.2,{x:.4,y:.63,r:U}],["b",84.5-115.9,463.5,0,435.1,0,396.4,{x:.4,y:.63,r:Q}],["l",0,130,{y:-3}]]}],Ht={"Æ":Y(996,426,352,0,0,0,0,[{d:-1,v:[["m",426,0,{x:0,r:U}],["l",234,0,{x:.5,f:1,r:$(234,0,0,352)}],["l",0,352,{x:.5,y:.5,f:1}]]},{d:-1,v:[["m",234,0,{x:.5,p:1}],["l",234,352,{f:1,x:.5}],["l",426,352,{f:1,x:0}]]},{d:-1,v:[["m",76.4,237,{r:U,p:1}],["l",234,237,{f:1,r:U,p:1}]]},{d:-1,v:[["m",234,164,{r:U,p:1,x:.5}],["l",414,164,{f:1,x:0}]]}]),"æ":Y(1e3,457.5,232,0,0,-64,-64,[{d:-1,v:[["m",232,8,{y:-3.4,r:Q}],["l",232,116,{r:V}],["b",232,180.1,180.1,232,116,232,{r:U}],["b",51.9,232,0,180.1,0,116,{r:Q}],["b",0,51.9,51.9,0,116,0,{r:U}],["b",180.1,0,232,51.9,232,116,{r:Q}],["l",232,224,{y:-.1,r:Q,f:1}]]},{d:1,v:[["m",443.6,182.9,{r:tt(443.6,182.9,423.1,213.2,388.1,233.1,348.5,233.1,0),f:1}],["b",423.1,213.2,388.1,233.1,348.5,233.1,{r:U}],["b",284.4,233.1,232.5,181.2,232.5,117.1,{r:Q}],["b",232.5,53,284.4,1.1,348.5,1.1,{r:U}],["b",408.4,1.1,456.9,47.2,457.5,106.1,{r:Q}],["l",232.5,106.1,{r:Q,p:1}]]}]),"À":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(kt(145,-50))),"Á":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Dt(145,-50))),"Â":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Tt(145,-100))),"Ã":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(It(145,-90))),"Ä":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Rt(145,-70))),"Å":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Mt(0,0))),"Ă":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Ft(145,-110))),"Ą":Y(620,290,352,0,0,0,0,JSON.parse(JSON.stringify(rt)).concat(Lt(290,352))),"à":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(kt(116,-60))),"á":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Dt(116,-60))),"â":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Tt(116,-110))),"ã":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(It(116,-100))),"ä":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Rt(116,-80))),"å":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Mt(-30,0))),"ă":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Ft(116,-120))),"ą":Y(600,232,232,10,2,-64,-64,JSON.parse(JSON.stringify(vt)).concat(Lt(232,224))),"Ć":Y(700,293.1,360,0,0,0,0,JSON.parse(JSON.stringify(it)).concat(kt(180,-60))),"Ĉ":Y(700,293.1,360,0,0,0,0,JSON.parse(JSON.stringify(it)).concat(Tt(180,-110))),"Ċ":Y(700,293.1,360,0,0,0,0,JSON.parse(JSON.stringify(it)).concat(jt(180,-80))),"Č":Y(700,293.1,360,0,0,0,0,JSON.parse(JSON.stringify(it)).concat(Ct(180,-110))),"Ç":Y(700,293.1,360,0,0,0,0,JSON.parse(JSON.stringify(it)).concat(zt(180,360))),"ć":Y(520,212.1,233.1,2,-10,-64,-64,JSON.parse(JSON.stringify(xt)).concat(kt(116.5,-68.9))),"ĉ":Y(520,212.1,233.1,2,-10,-64,-64,JSON.parse(JSON.stringify(xt)).concat(Tt(116.5,-118.9))),"ċ":Y(520,212.1,233.1,2,-10,-64,-64,JSON.parse(JSON.stringify(xt)).concat(jt(116.5,-88.9))),"č":Y(520,212.1,233.1,2,-10,-64,-64,JSON.parse(JSON.stringify(xt)).concat(Ct(116.5,-118.9))),"ç":Y(520,212.1,233.1,2,-10,-64,-64,JSON.parse(JSON.stringify(xt)).concat(zt(116.5,233.1))),"Đ":Y(721,270,352,-10,-10,0,0,JSON.parse(JSON.stringify(et)).concat(Gt(0,176))),"Ď":Y(721,270,352,-10,-10,0,0,JSON.parse(JSON.stringify(et)).concat(Ct(100,-110))),"ď":Y(600,232,352,10,2,0,0,JSON.parse(JSON.stringify(ut)).concat((qt=300,Xt=0,[{d:-1,v:[["m",qt,Xt,{x:0,y:0}],["l",qt,80+Xt,{x:0,y:0,f:1}]]}]))),"đ":Y(600,232,352,10,2,0,0,JSON.parse(JSON.stringify(ut)).concat(Gt(180,40))),"È":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(kt(96,-60))),"É":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(Dt(96,-60))),"Ê":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(Tt(96,-110))),"Ë":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(Rt(96,-80))),"Ē":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(At(96,-80))),"Ĕ":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(Ft(96,-120))),"Ė":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(jt(96,-80))),"Ě":Y(520,192,352,-5,-80,0,0,JSON.parse(JSON.stringify(at)).concat(Ct(96,-110))),"è":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(kt(112,-60))),"é":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(Dt(112,-60))),"ê":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(Tt(112,-110))),"ë":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(Rt(112,-80))),"ē":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(At(112,-80))),"ĕ":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(Ft(112,-120))),"ė":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(jt(112,-90))),"ě":Y(570,225.5,233.1,0,0,-64,-64,JSON.parse(JSON.stringify(gt)).concat(Ct(112,-120))),"Ĝ":Y(840,352,360,0,0,0,0,JSON.parse(JSON.stringify(st)).concat(Tt(180,-110))),"Ğ":Y(840,352,360,0,0,0,0,JSON.parse(JSON.stringify(st)).concat(Ft(180,-120))),"Ġ":Y(840,352,360,0,0,0,0,JSON.parse(JSON.stringify(st)).concat(jt(180,-80))),"Ģ":Y(840,352,360,0,0,0,0,JSON.parse(JSON.stringify(st)).concat(zt(180,360))),"ĝ":Y(600,232,338,10,2,-117,-117,JSON.parse(JSON.stringify(bt)).concat(Tt(116,-118.9))),"ğ":Y(600,232,338,10,2,-117,-117,JSON.parse(JSON.stringify(bt)).concat(Ft(116,-120))),"ġ":Y(600,232,338,10,2,-117,-117,JSON.parse(JSON.stringify(bt)).concat(jt(116,-90))),"ģ":Y(600,232,338,10,2,-117,-117,JSON.parse(JSON.stringify(bt)).concat(Dt(116,-70))),"Ĥ":Y(684,232,352,0,0,0,0,JSON.parse(JSON.stringify(nt)).concat(Tt(116,-110))),"ĥ":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(St)).concat(Tt(91,-110))),"Ì":Y(249,0,352,0,0,0,0,JSON.parse(JSON.stringify(lt)).concat(kt(0,-60))),"Í":Y(249,0,352,0,0,0,0,JSON.parse(JSON.stringify(lt)).concat(Dt(0,-60))),"Î":Y(249,0,352,0,0,0,0,JSON.parse(JSON.stringify(lt)).concat(Tt(0,-110))),"Ï":Y(249,0,352,0,0,0,0,JSON.parse(JSON.stringify(lt)).concat(Rt(0,-80))),"ì":Y(200,0,352,0,0,0,0,JSON.parse(JSON.stringify(Et)).concat(kt(0,70))),"í":Y(200,0,352,0,0,0,0,JSON.parse(JSON.stringify(Et)).concat(Dt(0,70))),"î":Y(200,0,352,0,0,0,0,JSON.parse(JSON.stringify(Et)).concat(Tt(0,10))),"ï":Y(200,0,352,0,0,0,0,JSON.parse(JSON.stringify(Et)).concat(Rt(0,50))),"Ĵ":Y(472,172.5,355.5,10,20,-2,-2,JSON.parse(JSON.stringify(ft)).concat(Tt(172.5,-110))),"ĵ":Y(220,115.9,352,-60,-60,0,0,JSON.parse(JSON.stringify(Bt)).concat(Tt(0,20))),"Ñ":Y(721,250,352,0,0,0,0,JSON.parse(JSON.stringify(ot)).concat(It(125,-100))),"ñ":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(mt)).concat(It(91,30))),"Ò":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat(kt(180,-60))),"Ó":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat(Dt(180,-60))),"Ô":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat(Tt(180,-110))),"Õ":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat(It(180,-100))),"Ö":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat(Rt(180,-80))),"Ø":Y(850,360,360,0,0,0,0,JSON.parse(JSON.stringify(ht)).concat([{d:1,v:[["m",0,360,{r:$(0,360,360,0),f:1,x:0,y:1}],["l",360,0,{x:0,y:1}]]}])),"ò":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat(kt(116,-60))),"ó":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat(Dt(116,-60))),"ô":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat(Tt(116,-110))),"õ":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat(It(116,-100))),"ö":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat(Rt(116,-80))),"ø":Y(580,232,232,0,0,-64,-64,JSON.parse(JSON.stringify(Ot)).concat([{d:1,v:[["m",0,232,{r:$(0,232,232,0),f:1,x:0,y:1}],["l",232,0,{x:0,y:1}]]}])),"Ŝ":Y(560,224,360,0,0,0,0,JSON.parse(JSON.stringify(yt)).concat(Tt(112.4,-110))),"ŝ":Y(400,143.808,231.12,0,0,-64,-64,JSON.parse(JSON.stringify(Jt)).concat(Tt(112.4*.642,-110))),"Ş":Y(560,224,360,0,0,0,0,JSON.parse(JSON.stringify(yt)).concat(zt(110.3,360))),"ş":Y(400,143.808,231.12,0,0,-64,-64,JSON.parse(JSON.stringify(Jt)).concat(zt(70.8126,231.12))),"Ù":Y(712,250,355,0,0,-.5,-.5,JSON.parse(JSON.stringify(dt)).concat(kt(125,-50))),"Ú":Y(712,250,355,0,0,-.5,-.5,JSON.parse(JSON.stringify(dt)).concat(Dt(125,-50))),"Û":Y(712,250,355,0,0,-.5,-.5,JSON.parse(JSON.stringify(dt)).concat(Tt(125,-100))),"Ŭ":Y(712,250,355,0,0,-.5,-.5,JSON.parse(JSON.stringify(dt)).concat(Ft(125,-110))),"Ü":Y(712,250,355,0,0,-.5,-.5,JSON.parse(JSON.stringify(dt)).concat(Rt(125,-70))),"ù":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(Nt)).concat(kt(91,70))),"ú":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(Nt)).concat(Dt(91,70))),"û":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(Nt)).concat(Tt(91,20))),"ŭ":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(Nt)).concat(Ft(91,10))),"ü":Y(520,182,352,0,0,0,0,JSON.parse(JSON.stringify(Nt)).concat(Rt(91,50))),"Ý":Y(673,270,352,0,0,0,0,JSON.parse(JSON.stringify(ct)).concat(Dt(135,-60))),"ý":Y(500,225.5,331.5,10,10,-119,-119,JSON.parse(JSON.stringify(_t)).concat(Dt(116.3,-60))),"ÿ":Y(500,225.5,331.5,10,10,-119,-119,JSON.parse(JSON.stringify(_t)).concat(Rt(116.3,-90)))},Kt=Object.assign({},pt,wt,Pt,Wt,Ht);function Qt(t){var r=(Kt[t]||Kt.tofu).clone();return r.v=t,r}function Ut(t,r,i,e){var a;return a=t.indexOf("\n")>0?t.split("\n"):t.indexOf("\\n")>0?t.split("\\n"):[t],0==i?function(t){var r,i=[],e=t.length;for(r=0;r=i&&(c+=1,d=o.w,p[c]=[]);c+=1}var v=[];for(n=p.length,a=0;a0&&(" "==e[0]&&e.shift()," "==e[e.length-1]&&e.pop(),e.length>0&&v.push(e));return v}(a,r,i):function(t,r,i){var e,a,n,l,f,o,h,y,d,c,p=0,v=0,x=0,u=[];for(y=t.length,f=0;fi&&(p=v,u[x+=1]=[]),u[x].push(a)}x+=1,p=0}y=u.length;var g=[];for(f=0;f0&&g.push(n);return g}(a,r,i)}function Vt(t,r){return{c:(t-r)/2,r:t-r,l:0}}class Yt{constructor(){this.lineWidth_=1,this.drawing_=[],this.data_=null,this.paths_=null,this.lines_=null,this.rect_={x:0,y:0,w:0,h:0},this.align_="left",this.scale_=1,this.fontRatio_=1}get data(){return this.data_}get paths(){return this.paths_}get lines(){return this.lines_}set lines(t){this.lines_=t}get lineWidth(){return this.lineWidth_}get fontRatio(){return this.fontRatio_}get scale(){return this.scale_}get rect(){return this.rect_}get drawing(){return this.drawing_}set align(t){this.align_!=t&&(this.align_=t,this.setPosition())}get align(){return this.align_}position(t,r){return(this.rect_.x!=t||this.rect_.y!=r)&&(this.rect_.x=t,this.rect_.y=r,this.setPosition(),!0)}setPosition(){var t,r,i,e,a=this.data_.length;for(t=0;tt.toString()!==r.toString())}dispatch(t,r){this.handlers_[t].listeners.forEach(t=>{t(r)})}}{constructor(){var{text:t="",size:r=500,weight:i=e,color:a=["#000000"],colorful:s=["#c5d73f","#9d529c","#49a9db","#fec330","#5eb96e","#fc5356","#f38f31"],tracking:n=0,leading:l=0,align:f="left",pathGap:o=.5,amplitude:h=.5,width:y=0,breakWord:d=!1,fps:c=30,isPath:p=!1,isWave:v=!1}=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};super(),this.size_=r,this.weight_=i,this.color_=a,this.colorful_=function(t){for(var r,i,e=t.slice(),a=e.length,s=a;s--;)r=Math.random()*a|0,i=e[s],e[s]=e[r],e[r]=i;return e}(s),this.tracking_=n,this.leading_=l,this.pathGap_=o,this.amplitude_=h,this.width_=y,this.breakWord_=d,this.fps_=c,this.fpsTime_=1e3/this.fps_,this.isPath_=p,this.isWave_=v,this.model=new Yt,this.str_=null,this.time_=null,this.isFps_=!1,this.isForceRander_=!1,this.updateID_=0,this.dPathsID_=null,this.pPathsID_=null,this.wPathsID_=null,this.guideID_=null,this.text=t,this.model.align=f}on(t,r){super.on(t,r),this.update()}off(t,r){super.off(t,r)}get text(){return this.str_}set text(t){this.str_!=t&&(this.str_=t,this.update())}get size(){return this.size_}set size(t){this.size_!=t&&(this.size_=t,this.update(),this.isForceRander_=!0)}get weight(){return this.weight_}set weight(t){t900&&(t=900),this.weight_!=t&&(this.weight_=t,this.update(),this.isForceRander_=!0)}get color(){return this.color_}set color(t){this.color_!=t&&(this.color_=t)}get tracking(){return this.tracking_}set tracking(t){this.tracking_!=t&&(this.tracking_=t,this.update(),this.isForceRander_=!0)}get leading(){return this.leading_}set leading(t){this.leading_!=t&&(this.leading_=t,this.update(),this.isForceRander_=!0)}get align(){return this.model.align}set align(t){this.model.align!=t&&(this.model.align=t,this.updateID_++,this.updateSignal())}get pathGap(){return this.pathGap_}set pathGap(t){this.pathGap_!=t&&(this.pathGap_=t,this.updatePatternPaths(!0),this.updateWavePaths(!0),this.isForceRander_=!0)}get amplitude(){return this.amplitude_}set amplitude(t){this.amplitude_=t}get rect(){return this.model.rect}set maxWidth(t){this.width_!=t&&(this.width_=t,this.update())}get maxWidth(){return this.width_}set breakWord(t){this.breakWord_!=t&&(this.breakWord_=t,this.update())}get breakWord(){return this.breakWord_}get isPath(){return this.isPath_}set isPath(t){this.isPath_=t,this.updatePatternPaths(!0)}get isWave(){return this.isWave_}set isWave(t){this.isWave_=t,this.updateWavePaths(!0)}get fps(){return this.fps_}set fps(t){this.fps_=t,this.fpsTime_=1e3/this.fps_}get lineWidth(){return this.model.lineWidth}get scale(){return this.model.scale}get drawing(){return this.model.drawing}get data(){return this.model.data}get paths(){return this.model.paths}get drawingPaths(){return this.model.drawingPaths}get wavePaths(){return this.model.wavePaths}position(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:0,r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0;this.model.position(t,r)&&(this.updateID_++,this.updateSignal())}update(){this.updateID_++,this.model.update(this.str_,this.width_,this.breakWord_,this.weight_,this.size_,this.tracking_,this.leading_),this.isPath_||this.isWave_?(this.updatePatternPaths(),this.updateWavePaths()):this.updateSignal()}updateGuide(){this.guideID_!=this.updateID_&&(this.guideID_=this.updateID_,this.model.updateGuide())}updateDrawingPaths(){this.dPathsID_!=this.updateID_&&(this.dPathsID_=this.updateID_,this.model.updateDrawingPaths())}updatePatternPaths(t){this.isPath_&&(t||this.pPathsID_!=this.updateID_)&&(this.pPathsID_=this.updateID_,this.model.updatePatternPaths(this.pathGap_),this.isForceRander_=!0,this.updateSignal())}updateWavePaths(t){this.isWave_&&(t||this.wPathsID_!=this.updateID_)&&(this.wPathsID_=this.updateID_,this.model.updateWavePaths(this.pathGap_),this.isForceRander_=!0,this.updateSignal())}updateSignal(){this.model.updateLinesForRect(),this.model.updatePathsForRect(),this.dispatch("update",this.model)}reset(){this.size_=500,this.weight_=e,this.color_=["#000000"],this.tracking_=0,this.leading_=0,this.pathGap_=.5,this.amplitude_=.5,this.width_=0,this.breakWord_=!1,this.fps_=30,this.fpsTime_=1e3/this.fps_,this.isPath_=!1,this.isWave_=!1,this.str_=null,this.time_=null,this.isFps_=!1,this.isForceRander_=!1,this.updateID_=0,this.dPathsID_=null,this.pPathsID_=null,this.wPathsID_=null,this.guideID_=null,this.model.reset()}dispose(){this.reset(),this.model=null}drawPixi(t){var r,i,e,a=this.model.data.length;for(r=0;r10&&(k(t),t.beginPath(),h&&t.moveTo(h.x,h.y),t.lineTo(o.x,o.y),c+=D(t,f,d,y,s,c)),h=o):"b"==o.type&&((d=N(h.x,h.y,o.x,o.y,o.x2,o.y2,o.x3,o.y3))/r.scale>10&&(k(t),t.beginPath(),h&&t.moveTo(h.x,h.y),t.bezierCurveTo(o.x,o.y,o.x2,o.y2,o.x3,o.y3),c+=D(t,f,d,y,s,c)),h={x:o.x3,y:o.y3})}(t,this.model,this.colorful_)}wave(t,r){(t.lineWidth=this.lineWidth,r)&&(this.time_||(this.time_=r),r-this.time_>this.fpsTime_||this.isForceRander_?(this.time_=r,this.isFps_=!0):this.isFps_=!1);this.isForceRander_=!1;var i,e,a=this.model.data.length;for(i=0;i
Leon Sans - All
================================================
FILE: examples/canvas-basic.html
================================================
Leon Sans - Canvas Basic
================================================
FILE: examples/color-pattern.html
================================================
LeonSans - Color Pattern
================================================
FILE: examples/colorful.html
================================================
Leon Sans - Colorful
================================================
FILE: examples/gradient.html
================================================
Leon Sans - Gradient
================================================
FILE: examples/grid.html
================================================
Leon Sans - Grids
================================================
FILE: examples/index.html
================================================
Leon Sans examples
================================================
FILE: examples/js/util.js
================================================
const pixelRatio = 2;
let isDown = false, moveX = 0, moveY = 0, offsetX = 0, offsetY = 0;
let canvas, ctx;
let renderer, stage;
let sw = document.body.clientWidth;
let sh = document.body.clientHeight;
function generateCanvas() {
canvas = document.createElement('canvas');
document.body.appendChild(canvas);
ctx = canvas.getContext("2d");
window.addEventListener('resize', canvasResize, false);
canvasResize();
moveEvent(canvas);
}
function canvasResize() {
sw = document.body.clientWidth;
sh = document.body.clientHeight;
canvas.width = sw * pixelRatio;
canvas.height = sh * pixelRatio;
canvas.style.width = sw + 'px';
canvas.style.height = sh + 'px';
ctx.scale(pixelRatio, pixelRatio);
}
function generatePixi(bgcolor) {
renderer = new PIXI.Renderer({
width: sw,
height: sh,
antialias: true,
transparent: false,
autoDensity: true,
resolution: pixelRatio,//window.devicePixelRatio > 1 ? 2 : 1,
powerPreference: "high-performance",
backgroundColor: bgcolor
});
document.body.appendChild(renderer.view);
stage = new PIXI.Container();
window.addEventListener('resize', pixiResize, false);
pixiResize();
moveEvent(renderer.view);
}
function pixiResize() {
sw = document.body.clientWidth;
sh = document.body.clientHeight;
renderer.resize(sw, sh);
}
function moveEvent(canvas) {
const hammer = new Hammer(canvas);
hammer.add(new Hammer.Pan({direction: Hammer.DIRECTION_ALL, threshold: 0}));
hammer.on("pan", (e) => {
moveX = e.deltaX + offsetX;
moveY = e.deltaY + offsetY;
if (e.isFinal) {
offsetX = moveX;
offsetY = moveY;
}
});
}
function getSize(size) {
let ratio = Math.sqrt(sw * sw + sh * sh) / 1800;
if (ratio > 1) ratio = 1;
else if (ratio < 0.5) ratio = 0.5;
return size * ratio;
}
================================================
FILE: examples/mask-tiling-pixi.html
================================================
Leon Sans - MASK + Tiling PIXI
================================================
FILE: examples/metaball-pixi.html
================================================
Leon Sans - Metaball PIXI
================================================
FILE: examples/morphing-pixi.html
================================================
Leon Sans - Morphing PIXI
================================================
FILE: examples/pattern.html
================================================
Leon Sans - Pattern
================================================
FILE: examples/plants-pixi.html
================================================
Leon Sans - Plants PIXI
================================================
FILE: examples/wave.html
================================================
Leon Sans - Wave
================================================
FILE: examples/webgl-basic-pixi.html
================================================
Leon Sans - WebGL Basic PIXI
================================================
FILE: src/core/align.js
================================================
export function setAlignGapX(sw, tw) {
return {
c: (sw - tw) / 2,
r: sw - tw,
l: 0
};
}
export function getAlignGapX(align, alignGapX) {
if (align == 'center') {
return alignGapX.c;
} else if (align == 'right') {
return alignGapX.r;
} else {
return alignGapX.l;
}
}
================================================
FILE: src/core/dispatcher.js
================================================
export class Dispatcher {
constructor() {
this.handlers_ = {
update: {
listeners: []
}
};
}
on(event, callback) {
if (typeof callback !== 'function') {
console.error(`The listener callback must be a function, the given type is ${typeof callback}`);
return false;
}
if (typeof event !== 'string') {
console.error(`The event name must be a string, the given type is ${typeof event}`);
return false;
}
if (this.handlers_[event] === undefined) {
this.handlers_[event] = {
listeners: []
};
}
this.handlers_[event].listeners.push(callback);
}
off(event, callback) {
if (this.handlers_[event] === undefined) {
console.error(`This event: ${event} does not exist`);
return false;
}
this.handlers_[event].listeners = this.handlers_[event].listeners.filter(listener => {
return listener.toString() !== callback.toString();
});
}
dispatch(event, data) {
this.handlers_[event].listeners.forEach((listener) => {
listener(data);
});
}
}
================================================
FILE: src/core/group.js
================================================
import {
getRect
} from './util.js';
import {
typo
} from '../font/index.js';
export function getTextGroup(text, scale, width, isBreakAll) {
let group;
if (text.indexOf('\n') > 0) {
group = text.split('\n');
} else if (text.indexOf('\\n') > 0) {
group = text.split('\\n');
} else {
group = [text];
}
if (width == 0) return keepAll(group);
else if (isBreakAll) return breakAll(group, scale, width);
else return breakWord(group, scale, width);
}
function keepAll(group) {
const textGroup = [];
const total = group.length;
let i;
for (i = 0; i < total; i++) {
textGroup[i] = group[i].split('');
}
return textGroup;
}
function breakWord(group, scale, width) {
let g2, g3, t, m_rect,
tw = 0,
tw2 = 0,
i, j, k,
total, j_total, k_total,
index = 0;
const tg = [];
total = group.length;
for (i = 0; i < total; i++) {
g2 = group[i].split(' ');
tg[index] = [];
j_total = g2.length;
for (j = 0; j < j_total; j++) {
tw2 = 0;
g3 = g2[j];
k_total = g3.length;
for (k = 0; k < k_total; k++) {
t = typo(g3[k]);
m_rect = getRect(t, scale);
tw2 += m_rect.w;
}
t = typo(' ');
m_rect = getRect(t, scale);
tw2 += m_rect.w;
tw += tw2;
if (tw > width) {
index += 1;
tw = tw2;
tg[index] = [];
}
tg[index].push(g3);
}
index += 1;
tw = 0;
}
total = tg.length;
const textGroup = [];
for (i = 0; i < total; i++) {
t = tg[i].join(' ').split('');
if (t.length > 0) {
textGroup.push(t);
}
}
return textGroup;
}
function breakAll(group, scale, width) {
let t,
i, total,
j, j_total,
m_rect,
g2, g3,
tw = 0,
index = 0,
tx = 0;
const tg = [];
total = group.length;
for (i = 0; i < total; i++) {
g2 = group[i];
tw = 0;
tx = 0;
tg[index] = [];
j_total = g2.length;
for (j = 0; j < j_total; j++) {
g3 = g2[j];
t = typo(g3);
m_rect = getRect(t, scale);
tw += m_rect.w;
tg[index].push(g3);
if (tw >= width) {
index += 1;
tw = m_rect.w;
tg[index] = [];
}
}
index += 1;
}
const textGroup = [];
total = tg.length;
for (i = 0; i < total; i++) {
t = tg[i];
if (t.length > 0) {
if (t[0] == ' ') t.shift();
if (t[t.length - 1] == ' ') t.pop();
if (t.length > 0) textGroup.push(t);
}
}
return textGroup;
}
================================================
FILE: src/core/guide.js
================================================
import {
RECT_RATIO
} from './util.js';
/**
* @name getGuide
* @property {Object} - typo data object from 'font/index.js'
* @property {Number} - scale
* @returns {Object} the guide pos array
* @description get a guide pos
*/
export function getGuide(d, scale) {
let guide = [],
ggap = 10,
i, gvx, gvy;
for (i = 0; i < 6; i++) {
gvx = (ggap * i) + 20;
gvy = (ggap * i) + 90;
guide[i] = {
x1: (gvx * RECT_RATIO) * scale,
x2: ((d.rect.w - (gvx * 2)) * RECT_RATIO) * scale,
y1: (gvy * RECT_RATIO) * scale,
y2: (((d.rect.h - gvy) * RECT_RATIO) * scale) - ((i * ggap * RECT_RATIO) * scale),
};
}
return guide;
}
/**
* @name getGuide
* @property {Object} - typo data object from 'font/index.js'
* @property {Number} - scale
* @returns {Object} the guide pos array
* @description get a guide pos
*/
export function getGrid(d, scale) {
let grid = [],
i, gvy = [98, 340, 815];
for (i = 0; i < 3; i++) {
grid[i] = (gvy[i] * RECT_RATIO) * scale;
}
return grid;
}
================================================
FILE: src/core/length.js
================================================
export function getLengths(item, model) {
const total = item.typo.p.length;
let c, p,
arr = [],
lt = [],
max = 0,
i;
for (i = 0; i < total; i++) {
p = item.typo.p[i];
c = getEachPath(item, p.v, model);
max += c.l;
arr.push(c.v);
lt.push(c.l);
}
return {
max: max,
lines: arr,
lengths: lt
};
}
function getEachPath(item, points, model) {
const total = points.length;
let i, p,
line, cp1, cp2, prev,
lines = [],
length = 0;
for (i = 0; i < total; i++) {
p = points[i];
line = {};
cp2 = p.convert(item, model);
if (i == 0 || p.type == 'a') {
line.x1 = cp2.x;
line.y1 = cp2.y;
line.distance = 0;
line.radius = cp2.radius;
} else {
cp1 = prev.convert(item, model);
if (prev.type == 'b') {
line.x1 = cp1.x3;
line.y1 = cp1.y3;
} else {
line.x1 = cp1.x;
line.y1 = cp1.y;
}
line.x2 = cp2.x;
line.y2 = cp2.y;
if (p.type == 'b') {
line.x3 = cp2.x2;
line.y3 = cp2.y2;
line.x4 = cp2.x3;
line.y4 = cp2.y3;
line.distance = cubicBezierLength(line.x1, line.y1, line.x2, line.y2, line.x3, line.y3, line.x4, line.y4);
} else {
line.distance = distance(line.x1, line.y1, line.x2, line.y2);
}
}
line.type = p.type;
line.rotation = p.ratio.r;
line.pat = p.ratio.p;
line.fix = p.ratio.f;
line.vt = p.ratio.v;
lines.push(line);
length += line.distance;
prev = p;
}
return {
v: lines,
l: length
};
}
export function cubicBezierLength(x1, y1, x2, y2, x3, y3, x4, y4, sampleCount) {
const ptCount = sampleCount || 40;
let totDist = 0;
let lastX = x1;
let lastY = y1;
let dx, dy, i, pt;
for (i = 1; i < ptCount; i++) {
pt = cubicQxy(i / ptCount, x1, y1, x2, y2, x3, y3, x4, y4);
dx = pt.x - lastX;
dy = pt.y - lastY;
totDist += Math.sqrt(dx * dx + dy * dy);
lastX = pt.x;
lastY = pt.y;
}
dx = x4 - lastX;
dy = y4 - lastY;
totDist += Math.sqrt(dx * dx + dy * dy);
return totDist;
}
function cubicQxy(t, x1, y1, x2, y2, x3, y3, x4, y4) {
x1 += (x2 - x1) * t;
x2 += (x3 - x2) * t;
x3 += (x4 - x3) * t;
x1 += (x2 - x1) * t;
x2 += (x3 - x2) * t;
y1 += (y2 - y1) * t;
y2 += (y3 - y2) * t;
y3 += (y4 - y3) * t;
y1 += (y2 - y1) * t;
y2 += (y3 - y2) * t;
return {
x: x1 + (x2 - x1) * t,
y: y1 + (y2 - y1) * t
};
}
export function distance(x1, y1, x2, y2) {
const a = (x2 - x1),
b = (y2 - y1);
return Math.sqrt(a * a + b * b);
}
================================================
FILE: src/core/model.js
================================================
import {
getFontW,
getWeightRatio,
getCircleRound,
getScale,
getTracking,
getLeading,
getFontRatio,
getLineW,
getRect,
getCenter,
getRange,
getLines,
addRectToPaths,
} from './util.js';
import {
getGuide,
getGrid
} from './guide.js';
import {
getTextGroup
} from './group.js';
import {
setAlignGapX,
getAlignGapX
} from './align.js';
import {
typo
} from '../font/index.js';
import {
getLengths
} from './length.js';
import {
getPaths
} from './paths.js';
export class Model {
constructor() {
this.lineWidth_ = 1;
this.drawing_ = [];
this.data_ = null;
this.paths_ = null;
this.lines_ = null;
this.rect_ = {
x: 0,
y: 0,
w: 0,
h: 0
};
this.align_ = 'left';
this.scale_ = 1;
this.fontRatio_ = 1;
}
get data() {
return this.data_;
}
get paths() {
return this.paths_;
}
get lines() {
return this.lines_;
}
set lines(v) {
this.lines_ = v;
}
get lineWidth() {
return this.lineWidth_;
}
get fontRatio() {
return this.fontRatio_;
}
get scale() {
return this.scale_;
}
get rect() {
return this.rect_;
}
get drawing() {
return this.drawing_;
}
set align(v) {
if (this.align_ != v) {
this.align_ = v;
this.setPosition();
}
}
get align() {
return this.align_;
}
position(x, y) {
if (this.rect_.x != x || this.rect_.y != y) {
this.rect_.x = x;
this.rect_.y = y;
this.setPosition();
return true;
} else {
return false;
}
}
setPosition() {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.rect.x = d.originPos.x + this.rect_.x + getAlignGapX(this.align_, d.alignGapX);
d.rect.y = d.originPos.y + this.rect_.y;
}
}
updateDrawingPaths() {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.drawingPaths = addRectToPaths(getPaths(this, d, -1, false), d);
}
}
updatePatternPaths(pathGap) {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.rawPaths = getPaths(this, d, pathGap, true);
}
}
updateWavePaths(pathGap) {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.rawWavePaths = getPaths(this, d, pathGap, false);
}
}
updateGuide() {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.guide = getGuide(d.typo, this.scale);
d.grid = getGrid(d.typo, this.scale);
}
}
update(text, width, breakWord, weight, size, tracking, leading) {
const fontW = getFontW(weight);
const weightRatio = getWeightRatio(fontW);
const circleRound = getCircleRound(fontW);
const scale = getScale(size);
const m_tracking = getTracking(tracking, scale);
const m_leading = getLeading(leading, scale);
const fontRatio = getFontRatio(weightRatio);
this.fontRatio_ = fontRatio;
this.scale_ = scale;
this.lineWidth_ = getLineW(fontW, scale);
const textGroup = getTextGroup(text, scale, width, breakWord);
let total = textGroup.length;
const total2 = total - 1;
let i, j, j_total, j_total2,
gt,
t, str,
m_rect,
s_pos,
tw = 0,
th = 0,
tx = 0,
ty = 0,
maxW = 0,
maxH = 0,
tmp = [];
for (i = 0; i < total; i++) {
gt = textGroup[i];
j_total = gt.length;
j_total2 = j_total - 1;
tw = 0;
tx = 0;
tmp[i] = {
tw: 0,
arr: []
};
for (j = 0; j < j_total; j++) {
str = gt[j];
t = typo(str);
m_rect = getRect(t, scale);
tw += m_rect.w;
th = m_rect.h;
if (j < j_total2) {
tw += m_tracking;
}
if (i < total2) {
th += m_leading;
}
m_rect.x = tx;
m_rect.y = ty;
s_pos = {
x: tx,
y: ty
};
tmp[i].arr[j] = {
str: str,
typo: t,
rect: m_rect,
originPos: s_pos,
center: getCenter(m_rect.w, m_rect.h, scale),
range: getRange(t, weightRatio, circleRound)
};
tx = tw;
}
ty += th;
tmp[i].tw = tw;
maxW = Math.max(maxW, tw);
maxH += th;
}
this.rect_.w = maxW;
this.rect_.h = maxH;
this.drawing_ = [];
const arr = [];
let aGapX, drawing;
for (const a of tmp) {
aGapX = setAlignGapX(maxW, a.tw);
for (const b of a.arr) {
b.alignGapX = aGapX;
b.pointsLength = getLengths(b, this);
arr.push(b);
drawing = {
value: 1
};
this.drawing_.push(drawing);
b.drawing = drawing;
// add converted Vector
for (const c of b.typo.p) {
c.cv = [];
for (const d of c.v) {
c.cv.push(d.convert(b, this));
}
}
}
}
this.data_ = arr;
this.setPosition();
}
updatePathsForRect() {
const total = this.data_.length;
const paths = [];
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
if (d.rawWavePaths) {
d.wavePaths = addRectToPaths(d.rawWavePaths, d);
}
if (d.rawPaths) {
d.paths = addRectToPaths(d.rawPaths, d);
Array.prototype.push.apply(paths, d.paths);
}
}
this.paths_ = paths;
}
updateLinesForRect() {
const total = this.data_.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.data_[i];
d.lines = getLines(d);
}
}
reset() {
this.lineWidth_ = 1;
this.drawing_ = [];
this.data_ = null;
this.paths_ = null;
this.lines_ = null;
this.rect_ = {
x: 0,
y: 0,
w: 0,
h: 0
};
this.align_ = 'left';
this.scale_ = 1;
this.fontRatio_ = 1;
}
}
================================================
FILE: src/core/paths.js
================================================
import {
getCurrent
} from './util.js';
import {
ROTATE_NONE
} from '../font/util.js';
import {
Point
} from './point.js';
let prevPoint = null;
/**
* @name getPaths
* @property {Model} model - mode.js
* @property {Object} data - data object
* @property {Number} pathGap
* @returns {Array} Returns paths array
* @description get a guide pos
*/
export function getPaths(model, data, pathGap, isPattern) {
const lines = data.pointsLength.lines;
const scale = model.scale;
let total = lines.length,
i, j_total, j,
line, lg, direction,
arr = [],
paths = [],
paths2 = [];
for (i = 0; i < total; i++) {
line = lines[i];
prevPoint = null;
arr.push(getDotPos(line, pathGap, scale));
}
total = arr.length;
for (i = 0; i < total; i++) {
lg = arr[i];
j_total = lg.length;
paths2 = [];
for (j = 0; j < j_total; j++) {
line = lg[j];
if (line.rotation != ROTATE_NONE) {
if (isPattern) {
// If the 'p' value of the font data is 1, it's not included in the pattern paths.
if (!line.pat) {
paths2.push(line);
}
} else {
paths2.push(line);
}
}
}
direction = data.typo.p[i].d;
if (direction == 1) {
paths2.reverse();
}
if (paths2.length > 0) {
paths2[0].start = 1;
Array.prototype.push.apply(paths, paths2);
}
}
return paths;
}
function getDotPos(lines, pathGap, scale) {
const total = lines.length;
let i, j, j_total;
let line;
let curPoint;
let num, pp;
let arr = [];
let isFirst = 1;
let pgap = 1;
if (pathGap > -1) pgap = getCurrent(pathGap, 1, 0, 80, 10) * scale;
for (i = 0; i < total; i++) {
line = lines[i];
if (line.type == 'a') {
arr.push(new Point({
x: line.x1,
y: line.y1,
rotation: 0,
type: 'a',
pat: line.pat,
fix: line.fix,
radius: line.radius
}));
} else if (line.distance == 0) {
// it should be type m
curPoint = new Point({
x: line.x1,
y: line.y1,
rotation: line.rotation,
type: line.type,
pat: line.pat,
fix: line.fix
});
pp = setPointValues(curPoint, prevPoint, line, 1);
if (pp != null) {
if (isFirst) {
pp.type = 'm';
isFirst = 0;
}
arr.push(pp);
}
prevPoint = new Point(curPoint); //Object.assign({}, curPoint)
} else {
j_total = Math.ceil(line.distance / pgap);
if (j_total < 3) j_total = 3;
if (line.vt) j_total = 2;
for (j = 1; j < j_total; j++) {
num = j / (j_total - 1);
if (line.type == 'b') {
curPoint = getCubicBezierXYatT(line, num);
} else {
curPoint = new Point({
x: line.x1 + ((line.x2 - line.x1) * num),
y: line.y1 + ((line.y2 - line.y1) * num),
type: line.type
});
}
if (line.rotation != 0 && num == 1) curPoint.rotation = line.rotation;
if (line.pat && num == 1) curPoint.pat = line.pat;
if (line.fix && num == 1) curPoint.fix = line.fix;
if (j_total > 0) {
pp = setPointValues(curPoint, prevPoint, line, num);
if (pp != null) {
if (isFirst) {
pp.type = 'm';
isFirst = 0;
}
arr.push(pp);
}
}
prevPoint = new Point(curPoint); //Object.assign({}, curPoint)
}
}
}
return arr;
}
function setPointValues(cur, prev, line, num) {
cur.type = line.type;
cur.distance = line.distance;
cur.num = num;
if (!prev || cur.rotation != null) {
cur.rotation = cur.rotation;
} else {
const dx = cur.x - prev.x;
const dy = cur.y - prev.y;
const rad = Math.atan2(dx, dy);
cur.rotation = -rad;
}
if (cur.rotation == ROTATE_NONE) {
return null;
} else {
return cur;
}
}
function getCubicBezierXYatT(line, t) {
const x = CubicN(line.x1, line.x2, line.x3, line.x4, t);
const y = CubicN(line.y1, line.y2, line.y3, line.y4, t);
const tx = bezierTangent(line.x1, line.x2, line.x3, line.x4, t);
const ty = bezierTangent(line.y1, line.y2, line.y3, line.y4, t);
const rotation = -Math.atan2(tx, ty);
return new Point({
x: x,
y: y,
rotation: rotation
});
}
function CubicN(a, b, c, d, t) {
const t2 = t * t;
const t3 = t2 * t;
return a + (-a * 3 + t * (3 * a - a * t)) * t + (3 * b + t * (-6 * b + b * 3 * t)) * t + (c * 3 - c * 3 * t) * t2 + d * t3;
}
//http://qaru.site/questions/10657973/quadratic-curve-with-rope-pattern
//https://stackoverflow.com/questions/32322966/quadratic-curve-with-rope-pattern
export function bezierTangent(a, b, c, d, t) {
return (3 * t * t * (-a + 3 * b - 3 * c + d) + 6 * t * (a - 2 * b + c) + 3 * (-a + b));
}
================================================
FILE: src/core/point.js
================================================
export function Point(mp) {
Object.assign(this, mp);
}
Object.assign(Point.prototype, {
addRect: function (rect) {
const vv = new Point(this);
vv.x = this.x + rect.x;
vv.y = this.y + rect.y;
vv.x2 = this.x2 + rect.x;
vv.y2 = this.y2 + rect.y;
vv.x3 = this.x3 + rect.x;
vv.y3 = this.y3 + rect.y;
vv.rx = this.rx + rect.x;
vv.ry = this.ry + rect.y;
vv.sx = this.sx + rect.x;
vv.sy = this.sy + rect.y;
if (vv.radius < 0.5) vv.radius = 0.5;
return vv;
}
});
================================================
FILE: src/core/util.js
================================================
const DEFAULT_FONT_SIZE = 500;
export const MIN_FONT_WEIGHT = 1;
export const MAX_FONT_WEIGHT = 900;
const MAX_LINE_WIDTH = 70;
const FONT_WEIGHT_LIMIT = 80;
const FR_1 = 1;
const FR_2 = 0.78;
export const RECT_RATIO = 0.49;
const MAX_SHAKE = 120;
export const PI2 = 2 * Math.PI;
export function getAmplitude(amplitude, scale) {
return (MAX_SHAKE * amplitude) * scale;
}
export function getFontW(weight) {
return (MAX_LINE_WIDTH - MIN_FONT_WEIGHT) / (MAX_FONT_WEIGHT - MIN_FONT_WEIGHT) * (weight - MIN_FONT_WEIGHT) + MIN_FONT_WEIGHT;
}
export function getWeightRatio(fontW) {
return (1) / (FONT_WEIGHT_LIMIT - MIN_FONT_WEIGHT) * (fontW - MIN_FONT_WEIGHT);
}
export function getCircleRound(fontW) {
return (58 - 4) / (FONT_WEIGHT_LIMIT - MIN_FONT_WEIGHT) * (fontW - MIN_FONT_WEIGHT) + 4;
}
export function getScale(size) {
return size / DEFAULT_FONT_SIZE;
}
export function getLineW(fontW, scale) {
let lw = fontW * scale;
if (lw < 1) lw = 1;
//if (weight == 1) lw = 1
return lw;
}
export function getTracking(tracking, scale) {
return tracking * 50 * scale;
}
export function getLeading(leading, scale) {
return leading * 50 * scale;
}
export function getFontRatio(weightRatio) {
return (FR_2 - FR_1) * weightRatio + FR_1;
}
export function getRect(d, scale, x = 0, y = 0) {
const w = (d.rect.w * RECT_RATIO) * scale;
const h = ((d.rect.h + 220) * RECT_RATIO) * scale;
return {
x: x,
y: y,
w: w,
h: h
};
}
/**
* @name getGap
* @property {Object} - typo data object from 'font/index.js'
* @property {Number} - weightRatio
* @returns {Object} the gap x and y
* @description get a typo gap from thin to bold weight
*/
/*
export function getGap(d, weightRatio) {
const gx1 = d.ratio.x1
const gx2 = d.ratio.x2
const gy1 = d.ratio.y1
const gy2 = d.ratio.y2
const x = (gx2 - gx1) * weightRatio + gx1
const y = (gy2 - gy1) * weightRatio + gy1
return {
x: x,
y: y
}
}
*/
/**
* @name getCenter
* @property {Number} - typo rect width
* @property {Number} - typo rect height
* @property {Number} - typo scale
* @returns {Object} center position x and y
* @description get a center position of a typo
*/
export function getCenter(w, h, scale) {
const x = w / 2;
const y = (h - ((220 - 90) * RECT_RATIO * scale)) / 2;
return {
x: x,
y: y
};
}
/**
* @name getRange
* @property {Object} - typo data object from 'font/index.js'
* @property {Number} - weightRatio
* @property {Number} - circleRound
* @returns {Object} ratio range
* @description save ratio range to control each line's coordinate
*/
export function getRange(d, weightRatio, circleRound) {
const gx1 = d.ratio.x1;
const gx2 = d.ratio.x2;
const gy1 = d.ratio.y1;
const gy2 = d.ratio.y2;
return {
r: weightRatio,
cr: circleRound,
fr1: FR_1,
fr2: FR_2,
gx1: gx1,
gx2: gx2,
gy1: gy1,
gy2: gy2,
};
}
export function getCurrent(v, vmax, vmin, max, min) {
let value = (max - min) / (vmax - vmin) * (v - vmin) + min;
if (value < min) value = min;
else if (value > max) value = max;
return value;
}
export function getLines(data) {
const total = data.typo.p.length;
const lines = [];
let i, j, k, j_total;
let d2, d3, cp, dir, lt, ltRatio, prevRatio;
for (i = 0; i < total; i++) {
d2 = data.typo.p[i];
j_total = d2.cv.length;
for (j = 0; j < j_total; j++) {
d3 = d2.cv[j];
// add current position to all points
cp = d3.addRect(data.rect);
dir = d2.d;
lt = data.pointsLength.lengths[i];
ltRatio = lt / data.pointsLength.max;
prevRatio = 0;
if (i > 0) {
for (k = 0; k < i; k++) {
prevRatio += (data.pointsLength.lengths[k] / data.pointsLength.max);
}
}
ltRatio += prevRatio;
lines.push({
pos: cp,
drawing: data.drawing,
direction: dir,
lengths: lt,
maxDrawing: ltRatio,
minDrawing: prevRatio,
closePath: d3.ratio.c,
stroke: (ctx, d) => {
let dv = getCurrent(d.drawing.value, d.maxDrawing, d.minDrawing, 1, 0);
//if (d.direction == 1) {
// dv = getCurrent(1 - d.drawing.value, d.minDrawing, d.maxDrawing, 1, 0);
//}
if (dv > 0 && d.pos.type != 'a') {
const frac = d.lengths * dv;
ctx.setLineDash([d.lengths]);
ctx.lineDashOffset = d.direction * (frac + d.lengths);
ctx.stroke();
}
},
});
}
}
return lines;
}
export function addRectToPaths(path, data) {
const total = path.length;
const arr = [];
let i, cp, p;
for (i = 0; i < total; i++) {
p = path[i];
cp = p.addRect(data.rect);
arr.push(cp);
}
return arr;
}
export function randomBrightColor() {
return "hsl(" + 360 * Math.random() + ',' +
'100%,' +
'50%)';
}
export function shuffle(oldArray) {
let newArray = oldArray.slice(),
len = newArray.length,
i = len,
p, t;
while (i--) {
p = (Math.random() * len) | 0;
t = newArray[i];
newArray[i] = newArray[p];
newArray[p] = t;
}
return newArray;
}
================================================
FILE: src/core/vector.js
================================================
import {
Point
} from './point.js';
export function Vector(mp) {
this.type = mp[0];
this.x = mp[1] || 0;
this.y = mp[2] || 0;
if (this.type == 'b') {
this.x2 = mp[3] || 0;
this.y2 = mp[4] || 0;
this.x3 = mp[5] || 0;
this.y3 = mp[6] || 0;
if (mp[7] == null) {
this.ratio = {
x: 1,
y: 1,
r: 0, // rotation : if the rotation is ROTATE_NONE, it will hide in the 'pattern' and 'paths'
p: 0, // 1 is hide the point in the pattern paths
f: 0, // 1 is fixed position for wave paths
c: 0, // 1 is close path for PIXI bug - graphics.closePath()
v: 0 // 1 is vertex, it's only for the vertex shape like V, W, A
};
} else {
this.ratio = {};
this.ratio.x = (mp[7].x == null) ? 1 : mp[7].x;
this.ratio.y = (mp[7].y == null) ? 1 : mp[7].y;
this.ratio.r = mp[7].r || 0;
this.ratio.p = mp[7].p || 0;
this.ratio.f = mp[7].f || 0;
this.ratio.c = mp[7].c || 0;
this.ratio.v = mp[7].v || 0;
}
} else {
if (mp[3] == null) {
this.ratio = {
x: 1,
y: 1,
r: 0,
p: 0,
f: 0,
c: 0,
v: 0
};
} else {
this.ratio = {};
this.ratio.x = (mp[3].x == null) ? 1 : mp[3].x;
this.ratio.y = (mp[3].y == null) ? 1 : mp[3].y;
this.ratio.r = mp[3].r || 0;
this.ratio.p = mp[3].p || 0;
this.ratio.f = mp[3].f || 0;
this.ratio.c = mp[3].c || 0;
this.ratio.v = mp[3].v || 0;
}
}
}
Object.assign(Vector.prototype, {
convert: function (pos, model) {
const x = convertX(this.x, pos, this.ratio, model);
const y = convertY(this.y, pos, this.ratio, model);
const x2 = convertX(this.x2, pos, this.ratio, model);
const y2 = convertY(this.y2, pos, this.ratio, model);
const x3 = convertX(this.x3, pos, this.ratio, model);
const y3 = convertY(this.y3, pos, this.ratio, model);
const rd = convertR(this.type, pos, model);
const vv = new Point(this);
vv.x = x;
vv.y = y;
vv.x2 = x2;
vv.y2 = y2;
vv.x3 = x3;
vv.y3 = y3;
vv.radius = rd;
return vv;
}
});
function convertR(type, pos, model) {
let rd = 0;
if (type == 'a') rd = pos.range.cr * model.scale * model.fontRatio;
return rd;
}
function convertX(x, pos, ratio, model) {
const rr = pos.range.r * ratio.x;
const gx = (pos.range.gx2 - pos.range.gx1) * rr + pos.range.gx1;
const fr = (pos.range.fr2 - pos.range.fr1) * rr + pos.range.fr1;
return pos.center.x + (((x - gx)) * model.scale * fr); // + pos.rect.x
}
function convertY(y, pos, ratio, model) {
const rr = pos.range.r * ratio.y;
const gy = (pos.range.gy2 - pos.range.gy1) * rr + pos.range.gy1;
const fr = (pos.range.fr2 - pos.range.fr1) * rr + pos.range.fr1;
return pos.center.y + (((y - gy)) * model.scale * fr); // + pos.rect.y
}
================================================
FILE: src/draw/canvas/color.js
================================================
export function Color(ctx, no, data, color) {
let c_total = color.length;
const cur = (no + (c_total * (Math.abs((no / 10) | 0) + 1))) % c_total;
if (Array.isArray(color[cur])) {
c_total = color[cur].length;
const vv = 1 / (c_total + 1);
const g = ctx.createLinearGradient(data.rect.x, data.rect.y, data.rect.x, data.rect.y + data.rect.h);
let i;
g.addColorStop(vv, color[cur][0]);
for (i = 0; i < c_total; i++) {
g.addColorStop(vv * (i + 1), color[cur][i]);
}
g.addColorStop(vv * (c_total + 1), color[cur][c_total - 1]);
ctx.strokeStyle = g;
ctx.fillStyle = g;
} else {
ctx.strokeStyle = color[cur];
ctx.fillStyle = color[cur];
}
}
================================================
FILE: src/draw/canvas/colorful.js
================================================
import {
PI2,
getCurrent
} from '../../core/util.js';
import {
cubicBezierLength,
distance
} from '../../core/length.js';
let colorArr;
let curColor = -1;
let colorTotal;
const MIN_DISTANCE = 10;
export function Colorful(ctx, model, colors) {
curColor = -1;
colorArr = colors;
colorTotal = colorArr.length;
const total = model.data.length;
let i, d, j, j_total, line, pos, prev;
let max, length, prevRatio;
for (i = 0; i < total; i++) {
d = model.data[i];
max = d.pointsLength.max;
prevRatio = 0;
j_total = d.lines.length;
prev = null;
for (j = 0; j < j_total; j++) {
line = d.lines[j];
pos = line.pos;
if (pos.type == 'a') {
setColor(ctx);
ctx.beginPath();
ctx.arc(pos.x, pos.y, pos.radius * d.drawing.value, 0, PI2);
ctx.fill();
ctx.closePath();
} else if (pos.type == 'm') {
prev = pos;
} else if (pos.type == 'l') {
length = distance(prev.x, prev.y, pos.x, pos.y);
if (length / model.scale > MIN_DISTANCE) {
// ignore short distance paths
setColor(ctx);
ctx.beginPath();
if (prev) ctx.moveTo(prev.x, prev.y);
ctx.lineTo(pos.x, pos.y);
prevRatio += draw(ctx, line, length, max, d, prevRatio);
}
prev = pos;
} else if (pos.type == 'b') {
length = cubicBezierLength(prev.x, prev.y, pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);
if (length / model.scale > MIN_DISTANCE) {
setColor(ctx);
ctx.beginPath();
if (prev) ctx.moveTo(prev.x, prev.y);
ctx.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);
prevRatio += draw(ctx, line, length, max, d, prevRatio);
}
prev = {
x: pos.x3,
y: pos.y3
};
}
}
}
}
function setColor(ctx) {
const color = getColor();
ctx.fillStyle = color;
ctx.strokeStyle = color;
}
function getColor() {
curColor++;
if (curColor == colorTotal) curColor = 0;
return colorArr[curColor];
}
function draw(ctx, line, length, max, d, prevRatio) {
const ltRatio = length / max;
let dv = getCurrent(d.drawing.value, prevRatio + ltRatio, prevRatio, 1, 0);
if (line.direction == 1) {
dv = getCurrent(1 - d.drawing.value, prevRatio, prevRatio + ltRatio, 1, 0);
}
if (dv > 0) {
const frac = length * dv;
ctx.setLineDash([length]);
ctx.lineDashOffset = line.direction * (frac + length);
ctx.stroke();
}
return ltRatio;
}
================================================
FILE: src/draw/canvas/grids.js
================================================
export function Grids(ctx, data) {
ctx.save();
ctx.beginPath();
ctx.lineWidth = 1;
ctx.strokeStyle = "#aaaaaa";
let i, total = data.guide.length,
grid;
for (i = 0; i < total; i++) {
grid = data.rect.y + data.grid[i];
ctx.moveTo(data.rect.x, grid);
ctx.lineTo(data.rect.x + data.rect.w, grid);
}
ctx.stroke();
ctx.lineWidth = 1;
ctx.beginPath();
ctx.strokeStyle = "#aaaaaa";
ctx.rect(data.rect.x, data.rect.y, data.rect.w, data.rect.h);
ctx.stroke();
ctx.restore();
}
================================================
FILE: src/draw/canvas/lines.js
================================================
import {
PI2
} from '../../core/util.js';
export function Lines(ctx, data) {
const total = data.lines.length;
let i, d, pos;
for (i = 0; i < total; i++) {
d = data.lines[i];
pos = d.pos;
if (pos.type == 'a') {
ctx.beginPath();
ctx.arc(pos.x, pos.y, pos.radius * d.drawing.value, 0, PI2);
ctx.fill();
ctx.closePath();
} else if (pos.type == 'm') {
ctx.beginPath();
ctx.moveTo(pos.x, pos.y);
} else if (pos.type == 'l') {
ctx.lineTo(pos.x, pos.y);
d.stroke(ctx, d);
} else if (pos.type == 'b') {
ctx.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);
d.stroke(ctx, d);
}
}
}
================================================
FILE: src/draw/canvas/pattern.js
================================================
import {
PI2
} from '../../core/util.js';
export function Pattern(ctx, data, w, h) {
const total = Math.round(data.paths.length * data.drawing.value);
const w2 = w / 2;
const w3 = w / 3;
const h2 = h / 2;
let i, p;
for (i = 0; i < total; i++) {
p = data.paths[i];
if (p.num == 1) {
ctx.fillStyle = "#ff00c5";
} else {
ctx.fillStyle = "#ff95f8";
}
if (p.type == 'a') {
ctx.beginPath();
ctx.arc(p.x, p.y, w3, 0, PI2);
ctx.fill();
} else {
ctx.beginPath();
ctx.save();
ctx.translate(p.x, p.y);
ctx.rotate(p.rotation);
ctx.fillRect(-w2, -h2, w, h);
ctx.restore();
}
}
}
================================================
FILE: src/draw/canvas/points.js
================================================
import {
PI2
} from '../../core/util.js';
export function Points(ctx, data) {
ctx.save();
ctx.lineWidth = 1;
let total = data.lines.length;
let i;
for (i = 0; i < total; i++) {
eachLine_(ctx, data.lines[i]);
}
ctx.restore();
ctx.save();
ctx.lineWidth = 1;
total = data.typo.p.length;
for (i = 0; i < total; i++) {
eachPoint_(ctx, data.typo.p[i], data);
}
ctx.restore();
}
function eachPoint_(ctx, p, data) {
const total = p.v.length;
let i, mp, cp;
for (i = 0; i < total; i++) {
mp = p.cv[i];
cp = mp.addRect(data.rect);
if (mp.type == 'b') {
ctx.fillStyle = "#ff2a00";
ctx.beginPath();
ctx.arc(cp.x3 + (cp.x3 - cp.x2), cp.y3 + (cp.y3 - cp.y2), 1.5, 0, PI2);
ctx.fill();
ctx.beginPath();
ctx.arc(cp.x2, cp.y2, 1.5, 0, PI2);
ctx.fill();
ctx.beginPath();
ctx.moveTo(cp.x2, cp.y2);
ctx.lineTo(cp.x3, cp.y3);
ctx.lineTo(cp.x3 + (cp.x3 - cp.x2), cp.y3 + (cp.y3 - cp.y2));
ctx.stroke();
ctx.beginPath();
ctx.fillStyle = "#ffffff";
ctx.arc(cp.x3, cp.y3, 2.5, 0, PI2);
ctx.fill();
ctx.stroke();
} else {
ctx.beginPath();
ctx.fillStyle = "#ffffff";
ctx.strokeStyle = "#ff2a00";
ctx.arc(cp.x, cp.y, 2.5, 0, PI2);
ctx.fill();
ctx.stroke();
}
}
}
function eachLine_(ctx, d) {
const pos = d.pos;
if (pos.type != 'a') {
if (pos.type == 'm') {
ctx.strokeStyle = "#ff2a00";
ctx.beginPath();
ctx.moveTo(pos.x, pos.y);
} else if (pos.type == 'l') {
ctx.lineTo(pos.x, pos.y);
} else if (pos.type == 'b') {
ctx.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);
}
ctx.stroke();
}
}
================================================
FILE: src/draw/canvas/wave.js
================================================
import {
PI2,
getAmplitude
} from '../../core/util.js';
const THIN_LIMIT = 110;
const COS = Math.cos;
const SIN = Math.sin;
export function Wave(ctx, data, scale, amplitude, weight, fps) {
const total = data.wavePaths.length;
const m_amplitude = getAmplitude(amplitude, scale);
let i, p, prev, qx, qy, saveDot = [];
ctx.beginPath();
for (i = 0; i < total; i++) {
p = data.wavePaths[i];
if (fps) {
const ranx = (Math.random() * m_amplitude) - (m_amplitude / 2);
const rany = (Math.random() * m_amplitude) - (m_amplitude / 2);
p.rx = p.x + ranx * COS(p.rotation);
p.ry = p.y + ranx * SIN(p.rotation);
p.sx = p.x + ranx;
p.sy = p.y + rany;
}
if (p.type == 'a') {
saveDot.push(p);
} else if (p.start == 1) {
ctx.moveTo(p.x, p.y);
} else if (p.fix) {
ctx.lineTo(p.x, p.y);
} else {
if (weight < THIN_LIMIT) {
prev = data.wavePaths[i - 1];
if (prev) {
qx = prev.x + ((p.x - prev.x) * 0.5);
qy = prev.y + ((p.y - prev.y) * 0.5);
ctx.quadraticCurveTo(qx, qy, p.rx, p.ry);
}
} else {
ctx.lineTo(p.rx, p.ry);
}
}
}
ctx.stroke();
for (i = 0; i < saveDot.length; i++) {
p = saveDot[i];
ctx.beginPath();
ctx.arc(p.x, p.y, p.radius, 0, PI2);
ctx.fill();
}
}
================================================
FILE: src/draw/pixi/color.js
================================================
export function PixiColor(no, data, color) {
let c_total = color.length;
const cur = (no + (c_total * (Math.abs((no / 10) | 0) + 1))) % c_total;
if (Array.isArray(color[cur])) {
/*
c_total = color[cur].length;
const vv = 1 / (c_total - 1);
const g = ctx.createLinearGradient(data.rect.x, data.rect.y, data.rect.x, data.rect.y + data.rect.h);
let i;
for (i = 0; i < c_total; i++) {
g.addColorStop(vv * i, color[cur][i]);
}
ctx.strokeStyle = g;
ctx.fillStyle = g;
*/
/*
c_total = color[cur].length;
const vv = 1 / (c_total - 1);
const c = document.createElement("canvas");
const ctx = c.getContext("2d");
const g = ctx.createLinearGradient(0, 0, data.rect.w, data.rect.h);
let i;
for (i = 0; i < c_total; i++) {
g.addColorStop(vv * i, color[cur][i]);
}
ctx.fillStyle = g;
ctx.fillRect(0, 0, data.rect.w, data.rect.h);
return new PIXI.Texture.from(c);
*/
} else {
return color[cur];
}
}
================================================
FILE: src/draw/pixi/lines.js
================================================
export function PixiLines(graphics, data, lineW, color) {
let total, i;
if (data.drawing.value == 1) {
total = data.lines.length;
for (i = 0; i < total; i++) {
eachLine_(graphics, data.lines[i], lineW, color);
}
} else {
total = data.drawingPaths.length * data.drawing.value;
for (i = 0; i < total; i++) {
eachPath_(graphics, data.drawingPaths[i], lineW, color, data.drawing.value);
}
}
}
function eachLine_(graphics, data, lineW, color) {
const pos = data.pos;
if (pos.type == 'a') {
graphics.lineStyle(0, color, 0);
graphics.beginFill(color);
graphics.drawCircle(pos.x, pos.y, pos.radius);
graphics.endFill();
} else if (pos.type == 'm') {
graphics.lineStyle(lineW, color, 1);
graphics.moveTo(pos.x, pos.y);
} else if (pos.type == 'l') {
graphics.lineTo(pos.x, pos.y);
} else if (pos.type == 'b') {
graphics.bezierCurveTo(pos.x, pos.y, pos.x2, pos.y2, pos.x3, pos.y3);
}
if (data.closePath) {
graphics.closePath();
}
}
function eachPath_(graphics, pos, lineW, color, dValue) {
if (pos.type == 'a') {
graphics.lineStyle(0, color, 0);
graphics.beginFill(color);
graphics.drawCircle(pos.x, pos.y, pos.radius * dValue);
graphics.endFill();
} else {
if (pos.start == 1) {
graphics.lineStyle(lineW, color, 1);
graphics.moveTo(pos.x, pos.y);
} else {
graphics.lineTo(pos.x, pos.y, 1);
}
}
}
================================================
FILE: src/font/index.js
================================================
import {
UPPER
} from './upper.js';
import {
LOWER
} from './lower.js';
import {
NUMBER
} from './number.js';
import {
SPECIAL
} from './special.js';
import {
LATIN
} from './latin.js';
import {
TOFU
} from './util.js';
const DATA = Object.assign({}, UPPER, LOWER, NUMBER, SPECIAL, LATIN);
export function typo(v) {
const t = DATA[v] || DATA[TOFU];
const clone = t.clone();
clone.v = v;
return clone;
}
================================================
FILE: src/font/latin.js
================================================
import {
generateFontData,
ROTATE_HORIZONTAL,
ROTATE_VERTICAL,
ROTATE_NONE,
getR,
getCurveR
} from './util.js';
import {
getLatin1,
getLatin2,
getLatin3,
getLatin4,
getLatin5,
getLatin6,
getLatin7,
getLatin8,
getLatin9,
getLatin10,
getLatin11,
getLatin12,
getLatin13,
getLatin14
} from './latinutil.js';
import {
DATA_UA,
DATA_UC,
DATA_UD,
DATA_UE,
DATA_UG,
DATA_UH,
DATA_UI,
DATA_UJ,
DATA_UN,
DATA_UO,
DATA_US,
DATA_UU,
DATA_UY
} from './upper.js';
import {
DATA_LA,
DATA_LC,
DATA_LD,
DATA_LE,
DATA_LG,
DATA_LH,
DATA_LN,
DATA_LO,
DATA_LS,
DATA_LU,
DATA_LY
} from './lower.js';
const DATA_LI = [{
d: 1,
v: [
['m', 0, 352, {
y: 0,
f: 1
}],
['l', 0, 130, {
y: -3
}],
]
}];
const DATA_LJ = [{
d: 1,
v: [
['m', 0 - 115.9, 317 + 127, {
x: 0.4,
y: 0.63,
r: getCurveR(0 - 115.9, 317 + 127, 12.6 - 115.9, 327.4 + 127, 29.6 - 115.9, 333.2 + 127, 45.9 - 115.9, 334.2 + 127, 0),
f: 1
}],
['b', 12.6 - 115.9, 327.4 + 127, 29.6 - 115.9, 333.2 + 127, 45.9 - 115.9, 334.2 + 127, {
x: 0.4,
y: 0.63,
r: ROTATE_VERTICAL
}],
['b', 84.5 - 115.9, 336.5 + 127, 0, 308.1 + 127, 0, 269.4 + 127, {
x: 0.4,
y: 0.63,
r: ROTATE_HORIZONTAL
}],
['l', 0, 0 + 127 + 3, {
y: -3
}],
]
}];
export const LATIN = {
'Æ': generateFontData(
996, 426, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 426.0, 0.0, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 234.0, 0.0, {
x: 0.5,
f: 1,
r: getR(234.0, 0.0, .0, 352.0),
}],
['l', 0.0, 352.0, {
x: 0.5,
y: 0.5,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 234.0, 0.0, {
x: 0.5,
p: 1,
}],
['l', 234.0, 352.0, {
f: 1,
x: 0.5
}],
['l', 426.0, 352.0, {
f: 1,
x: 0
}]
]
}, {
d: -1,
v: [
['m', 76.4, 237.0, {
r: ROTATE_VERTICAL,
p: 1,
}],
['l', 234.0, 237.0, {
f: 1,
r: ROTATE_VERTICAL,
p: 1,
}]
]
}, {
d: -1,
v: [
['m', 234.0, 164.0, {
r: ROTATE_VERTICAL,
p: 1,
x: 0.5
}],
['l', 414.0, 164.0, {
f: 1,
x: 0
}]
]
}]
),
'æ': generateFontData(
1000, 232 + 225.5, 232,
0, 0, -64, -64,
[{
d: -1,
v: [
['m', 232, 8, {
y: -3.4,
r: ROTATE_HORIZONTAL
}],
['l', 232, 116, {
r: ROTATE_NONE
}],
['b', 232, 180.1, 180.1, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 232, 0, 180.1, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 51.9, 51.9, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 0, 232, 51.9, 232, 116, {
r: ROTATE_HORIZONTAL
}],
['l', 232, 224, {
y: -0.1,
r: ROTATE_HORIZONTAL,
f: 1
}]
]
}, {
d: 1,
v: [
['m', 211.6 + 232, 182.9, {
r: getCurveR(211.6 + 232, 182.9, 191.1 + 232, 213.2, 156.1 + 232, 233.1, 116.5 + 232, 233.1, 0),
f: 1
}],
['b', 191.1 + 232, 213.2, 156.1 + 232, 233.1, 116.5 + 232, 233.1, {
r: ROTATE_VERTICAL
}],
['b', 52.4 + 232, 233.1, 0.5 + 232, 181.2, 0.5 + 232, 117.1, {
r: ROTATE_HORIZONTAL
}],
['b', 0.5 + 232, 53, 52.4 + 232, 1.1, 116.5 + 232, 1.1, {
r: ROTATE_VERTICAL
}],
['b', 176.4 + 232, 1.1, 224.9 + 232, 47.2, 225.5 + 232, 106.1, {
r: ROTATE_HORIZONTAL
}],
['l', 0.5 + 232, 106.1, {
r: ROTATE_HORIZONTAL,
p: 1
}],
]
}]
),
'À': generateFontData(
620, 290, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin1(145, -50))
),
'Á': generateFontData(
620, 290, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin2(145, -50))
),
'Â': generateFontData(
620, 290, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin3(145, -100))
),
'Ã': generateFontData(
620, 290, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin4(145, -90))
),
'Ä': generateFontData(
620, 290, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin5(145, -70))
),
'Å': generateFontData(
620, 290, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin7(0, 0))
),
'Ă': generateFontData(
620, 290, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin6(145, -110))
),
'Ą': generateFontData(
620, 290, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UA)).concat(getLatin10(290, 352))
),
'à': generateFontData(
600, 232, 232,
10, 2, -64, -64,
JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin1(116, -60))
),
'á': generateFontData(
600, 232, 232,
10, 2, -64, -64,
JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin2(116, -60))
),
'â': generateFontData(
600, 232, 232,
10, 2, -64, -64,
JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin3(116, -110))
),
'ã': generateFontData(
600, 232, 232,
10, 2, -64, -64,
JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin4(116, -100))
),
'ä': generateFontData(
600, 232, 232,
10, 2, -64, -64,
JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin5(116, -80))
),
'å': generateFontData(
600, 232, 232,
10, 2, -64, -64,
JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin7(-30, 0))
),
'ă': generateFontData(
600, 232, 232,
10, 2, -64, -64,
JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin6(116, -120))
),
'ą': generateFontData(
600, 232, 232,
10, 2, -64, -64,
JSON.parse(JSON.stringify(DATA_LA)).concat(getLatin10(232, 224))
),
'Ć': generateFontData(
700, 293.1, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UC)).concat(getLatin1(180, -60))
),
'Ĉ': generateFontData(
700, 293.1, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UC)).concat(getLatin3(180, -110))
),
'Ċ': generateFontData(
700, 293.1, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UC)).concat(getLatin11(180, -80))
),
'Č': generateFontData(
700, 293.1, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UC)).concat(getLatin12(180, -110))
),
'Ç': generateFontData(
700, 293.1, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UC)).concat(getLatin9(180, 360))
),
'ć': generateFontData(
520, 212.1, 233.1,
2, -10, -64, -64,
JSON.parse(JSON.stringify(DATA_LC)).concat(getLatin1(116.5, 1.1 - 70))
),
'ĉ': generateFontData(
520, 212.1, 233.1,
2, -10, -64, -64,
JSON.parse(JSON.stringify(DATA_LC)).concat(getLatin3(116.5, 1.1 - 120))
),
'ċ': generateFontData(
520, 212.1, 233.1,
2, -10, -64, -64,
JSON.parse(JSON.stringify(DATA_LC)).concat(getLatin11(116.5, 1.1 - 90))
),
'č': generateFontData(
520, 212.1, 233.1,
2, -10, -64, -64,
JSON.parse(JSON.stringify(DATA_LC)).concat(getLatin12(116.5, 1.1 - 120))
),
'ç': generateFontData(
520, 212.1, 233.1,
2, -10, -64, -64,
JSON.parse(JSON.stringify(DATA_LC)).concat(getLatin9(116.5, 233.1))
),
'Đ': generateFontData(
721, 270, 352,
-10, -10, 0, 0,
JSON.parse(JSON.stringify(DATA_UD)).concat(getLatin8(0, 352 / 2))
),
'Ď': generateFontData(
721, 270, 352,
-10, -10, 0, 0,
JSON.parse(JSON.stringify(DATA_UD)).concat(getLatin12(100, -110))
),
'ď': generateFontData(
600, 232, 352,
10, 2, 0, 0,
JSON.parse(JSON.stringify(DATA_LD)).concat(getLatin13(300, 0))
),
'đ': generateFontData(
600, 232, 352,
10, 2, 0, 0,
JSON.parse(JSON.stringify(DATA_LD)).concat(getLatin8(180, 40))
),
'È': generateFontData(
520, 192, 352,
-5, -80, 0, 0,
JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin1(96, -60))
),
'É': generateFontData(
520, 192, 352,
-5, -80, 0, 0,
JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin2(96, -60))
),
'Ê': generateFontData(
520, 192, 352,
-5, -80, 0, 0,
JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin3(96, -110))
),
'Ë': generateFontData(
520, 192, 352,
-5, -80, 0, 0,
JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin5(96, -80))
),
'Ē': generateFontData(
520, 192, 352,
-5, -80, 0, 0,
JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin14(96, -80))
),
'Ĕ': generateFontData(
520, 192, 352,
-5, -80, 0, 0,
JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin6(96, -120))
),
'Ė': generateFontData(
520, 192, 352,
-5, -80, 0, 0,
JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin11(96, -80))
),
'Ě': generateFontData(
520, 192, 352,
-5, -80, 0, 0,
JSON.parse(JSON.stringify(DATA_UE)).concat(getLatin12(96, -110))
),
'è': generateFontData(
570, 225.5, 233.1,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin1(112, -60))
),
'é': generateFontData(
570, 225.5, 233.1,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin2(112, -60))
),
'ê': generateFontData(
570, 225.5, 233.1,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin3(112, -110))
),
'ë': generateFontData(
570, 225.5, 233.1,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin5(112, -80))
),
'ē': generateFontData(
570, 225.5, 233.1,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin14(112, -80))
),
'ĕ': generateFontData(
570, 225.5, 233.1,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin6(112, -120))
),
'ė': generateFontData(
570, 225.5, 233.1,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin11(112, -90))
),
'ě': generateFontData(
570, 225.5, 233.1,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LE)).concat(getLatin12(112, -120))
),
'Ĝ': generateFontData(
840, 352, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UG)).concat(getLatin3(180, -110))
),
'Ğ': generateFontData(
840, 352, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UG)).concat(getLatin6(180, -120))
),
'Ġ': generateFontData(
840, 352, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UG)).concat(getLatin11(180, -80))
),
'Ģ': generateFontData(
840, 352, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UG)).concat(getLatin9(180, 360))
),
'ĝ': generateFontData(
600, 232, 338,
10, 2, -117, -117,
JSON.parse(JSON.stringify(DATA_LG)).concat(getLatin3(116, 1.1 - 120))
),
'ğ': generateFontData(
600, 232, 338,
10, 2, -117, -117,
JSON.parse(JSON.stringify(DATA_LG)).concat(getLatin6(116, -120))
),
'ġ': generateFontData(
600, 232, 338,
10, 2, -117, -117,
JSON.parse(JSON.stringify(DATA_LG)).concat(getLatin11(116, -90))
),
'ģ': generateFontData(
600, 232, 338,
10, 2, -117, -117,
JSON.parse(JSON.stringify(DATA_LG)).concat(getLatin2(116, -70))
),
'Ĥ': generateFontData(
684, 232, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UH)).concat(getLatin3(232 / 2, -110))
),
'ĥ': generateFontData(
520, 182, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LH)).concat(getLatin3(182 / 2, -110))
),
'Ì': generateFontData(
249, 0, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UI)).concat(getLatin1(0, -60))
),
'Í': generateFontData(
249, 0, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UI)).concat(getLatin2(0, -60))
),
'Î': generateFontData(
249, 0, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UI)).concat(getLatin3(0, -110))
),
'Ï': generateFontData(
249, 0, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UI)).concat(getLatin5(0, -80))
),
'ì': generateFontData(
200, 0, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LI)).concat(getLatin1(0, -60 + 130))
),
'í': generateFontData(
200, 0, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LI)).concat(getLatin2(0, -60 + 130))
),
'î': generateFontData(
200, 0, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LI)).concat(getLatin3(0, -120 + 130))
),
'ï': generateFontData(
200, 0, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LI)).concat(getLatin5(0, -80 + 130))
),
'Ĵ': generateFontData(
472, 172.5, 355.5,
10, 20, -2, -2,
JSON.parse(JSON.stringify(DATA_UJ)).concat(getLatin3(172.5, -110))
),
'ĵ': generateFontData(
220, 115.9, 352,
-60, -60, 0, 0,
JSON.parse(JSON.stringify(DATA_LJ)).concat(getLatin3(0, -110 + 130))
),
'Ñ': generateFontData(
721, 250, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UN)).concat(getLatin4(250 / 2, -100))
),
'ñ': generateFontData(
520, 182, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LN)).concat(getLatin4(182 / 2, -100 + 130))
),
'Ò': generateFontData(
850, 360, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UO)).concat(getLatin1(180, -60))
),
'Ó': generateFontData(
850, 360, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UO)).concat(getLatin2(180, -60))
),
'Ô': generateFontData(
850, 360, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UO)).concat(getLatin3(180, -110))
),
'Õ': generateFontData(
850, 360, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UO)).concat(getLatin4(180, -100))
),
'Ö': generateFontData(
850, 360, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UO)).concat(getLatin5(180, -80))
),
'Ø': generateFontData(
850, 360, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UO)).concat([{
d: 1,
v: [
['m', 0, 360, {
r: getR(0, 360, 360, 0),
f: 1,
x: 0,
y: 1
}],
['l', 360, 0, {
x: 0,
y: 1
}]
]
}])
),
'ò': generateFontData(
580, 232, 232,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LO)).concat(getLatin1(116, -60))
),
'ó': generateFontData(
580, 232, 232,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LO)).concat(getLatin2(116, -60))
),
'ô': generateFontData(
580, 232, 232,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LO)).concat(getLatin3(116, -110))
),
'õ': generateFontData(
580, 232, 232,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LO)).concat(getLatin4(116, -100))
),
'ö': generateFontData(
580, 232, 232,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LO)).concat(getLatin5(116, -80))
),
'ø': generateFontData(
580, 232, 232,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LO)).concat([{
d: 1,
v: [
['m', 0, 232, {
r: getR(0, 232, 232, 0),
f: 1,
x: 0,
y: 1
}],
['l', 232, 0, {
x: 0,
y: 1
}]
]
}])
),
'Ŝ': generateFontData(
560, 224, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_US)).concat(getLatin3(112.4, -110))
),
'ŝ': generateFontData(
400, 224 * 0.642, 360 * 0.642,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LS)).concat(getLatin3(112.4 * 0.642, -110))
),
'Ş': generateFontData(
560, 224, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_US)).concat(getLatin9(110.3, 360))
),
'ş': generateFontData(
400, 224 * 0.642, 360 * 0.642,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LS)).concat(getLatin9(110.3 * 0.642, 360 * 0.642))
),
'Ù': generateFontData(
712, 250, 355,
0, 0, -0.5, -0.5,
JSON.parse(JSON.stringify(DATA_UU)).concat(getLatin1(125, -50))
),
'Ú': generateFontData(
712, 250, 355,
0, 0, -0.5, -0.5,
JSON.parse(JSON.stringify(DATA_UU)).concat(getLatin2(125, -50))
),
'Û': generateFontData(
712, 250, 355,
0, 0, -0.5, -0.5,
JSON.parse(JSON.stringify(DATA_UU)).concat(getLatin3(125, -100))
),
'Ŭ': generateFontData(
712, 250, 355,
0, 0, -0.5, -0.5,
JSON.parse(JSON.stringify(DATA_UU)).concat(getLatin6(125, -110))
),
'Ü': generateFontData(
712, 250, 355,
0, 0, -0.5, -0.5,
JSON.parse(JSON.stringify(DATA_UU)).concat(getLatin5(125, -70))
),
'ù': generateFontData(
520, 182, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LU)).concat(getLatin1(91, -60 + 130))
),
'ú': generateFontData(
520, 182, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LU)).concat(getLatin2(91, -60 + 130))
),
'û': generateFontData(
520, 182, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LU)).concat(getLatin3(91, -110 + 130))
),
'ŭ': generateFontData(
520, 182, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LU)).concat(getLatin6(91, -120 + 130))
),
'ü': generateFontData(
520, 182, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LU)).concat(getLatin5(91, -80 + 130))
),
'Ý': generateFontData(
673, 270, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UY)).concat(getLatin2(135, -60))
),
'ý': generateFontData(
500, 225.5, 331.5,
10, 10, -119, -119,
JSON.parse(JSON.stringify(DATA_LY)).concat(getLatin2(116.3, -60))
),
'ÿ': generateFontData(
500, 225.5, 331.5,
10, 10, -119, -119,
JSON.parse(JSON.stringify(DATA_LY)).concat(getLatin5(116.3, -90))
),
};
================================================
FILE: src/font/latinutil.js
================================================
import {
ROTATE_HORIZONTAL,
ROTATE_VERTICAL,
VERTEX_GAP2,
getR,
getCurveR
} from './util.js';
//À
export function getLatin1(x, y) {
const tx = x;
const ty = -60 + y;
return [{
d: -1,
v: [
['m', -40 + tx, ty, {
x: 0,
y: 0,
r: getR(-40 + tx, ty, 0 + tx, 60 + ty)
}],
['l', 0 + tx, 60 + ty, {
x: 0,
y: 0,
f: 1
}],
]
}];
}
//Á
export function getLatin2(x, y) {
const tx = x;
const ty = -60 + y;
return [{
d: -1,
v: [
['m', 40 + tx, ty, {
x: 0,
y: 0,
r: getR(40 + tx, ty, 0 + tx, 60 + ty)
}],
['l', 0 + tx, 60 + ty, {
x: 0,
y: 0,
f: 1
}],
]
}];
}
//Â
export function getLatin3(x, y) {
const tx = -68 + x;
const ty = 0 + y;
return [{
d: -1,
v: [
['m', 0 + tx, 50 + ty, {
r: getR(0 + tx, 50 + ty, 68 - VERTEX_GAP2 + tx, 0 + ty),
y: 0,
x: 0
}],
['l', 68 - VERTEX_GAP2 + tx, 0 + ty, {
r: getR(0 + tx, 50 + ty, 68 - VERTEX_GAP2 + tx, 0 + ty),
y: 0,
x: 0,
f: 1,
}],
['l', 68 + VERTEX_GAP2 + tx, 0 + ty, {
r: getR(68 + VERTEX_GAP2 + tx, 0 + ty, 68 + 68 + tx, 50 + ty),
y: 0,
x: 0,
f: 1,
v: 1
}],
['l', 68 + 68 + tx, 50 + ty, {
y: 0,
x: 0,
f: 1
}]
]
}];
}
//Ã
export function getLatin4(x, y) {
const tx = x - 76.24;
const ty = y;
return [{
d: 1,
v: [
['m', 159.52 + tx, 16.56 + ty, {
x: -1,
y: -0.2,
r: getCurveR(159.52 + tx, 16.56 + ty, 150.08 + tx, 29.28 + ty, 134.56 + tx, 37.68 + ty, 118.56 + tx, 37.68 + ty, 0),
f: 1
}],
['b', 150.08 + tx, 29.28 + ty, 134.56 + tx, 37.68 + ty, 118.56 + tx, 37.68 + ty, {
x: -1,
y: -0.2,
r: ROTATE_VERTICAL
}],
['b', 103.28 + tx, 37.68 + ty, 89.68 + tx, 29.28 + ty, 76.24 + tx, 20.4 + ty, {
x: -1,
y: -0.2
}],
['b', 61.44 + tx, 10.56 + ty, 47.28 + tx, 0 + ty, 31.68 + tx, 0 + ty, {
x: -1,
y: -0.2,
r: ROTATE_VERTICAL
}],
['b', 17.84 + tx, 0 + ty, 8.72 + tx, 7.12 + ty, 0 + tx, 16 + ty, {
x: -1,
y: -0.2
}],
]
}];
}
//Ä
export function getLatin5(x, y) {
return [{
d: 1,
v: [
['a', -50 + x, y, {
x: 0,
y: 0
}],
]
}, {
d: 1,
v: [
['a', 50 + x, y, {
x: 0,
y: 0
}],
]
}];
}
//Ŭ
export function getLatin6(x, y) {
const tx = x - 57;
const ty = y;
return [{
d: 1,
v: [
['m', 112.7 + tx, 0.0 + ty, {
r: getCurveR(112.7 + tx, 0.0 + ty + tx, 10.1 + ty, 110.1 + tx, 19.3 + ty, 105.0 + tx, 27.7 + ty, 0),
x: 0,
y: 0,
f: 1
}],
['b', 112.7 + tx, 10.1 + ty, 110.1 + tx, 19.3 + ty, 105.0 + tx, 27.7 + ty, {
x: 0,
y: 0,
}],
['b', 99.8 + tx, 36.1 + ty, 92.9 + tx, 42.8 + ty, 84.3 + tx, 47.7 + ty, {
x: 0,
y: 0,
}],
['b', 75.7 + tx, 52.6 + ty, 66.7 + tx, 55.0 + ty, 57.3 + tx, 55.0 + ty, {
x: 0,
y: 0,
}],
['b', 47.5 + tx, 55.0 + ty, 38.3 + tx, 52.6 + ty, 29.6 + tx, 47.7 + ty, {
x: 0,
y: 0,
}],
['b', 20.8 + tx, 42.8 + ty, 13.8 + tx, 36.1 + ty, 8.5 + tx, 27.7 + ty, {
x: 0,
y: 0,
}],
['b', 3.2 + tx, 19.3 + ty, 0.5 + tx, 10.1 + ty, 0.5 + tx, 0.0 + ty, {
x: 0,
y: 0,
}],
]
}];
}
//Å
export function getLatin7(x, y) {
const tx = 88 + x;
const ty = -116 + y;
const scale = 0.5;
return [{
d: 1,
v: [
['m', 232 * scale + tx, 116 * scale + ty, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 232 * scale + tx, 180.1 * scale + ty, 180.1 * scale + tx, 232 * scale + ty, 116 * scale + tx, 232 * scale + ty, {
r: ROTATE_VERTICAL
}],
['b', 51.9 * scale + tx, 232 * scale + ty, 0 * scale + tx, 180.1 * scale + ty, 0 * scale + tx, 116 * scale + ty, {
r: ROTATE_HORIZONTAL
}],
['b', 0 * scale + tx, 51.9 * scale + ty, 51.9 * scale + tx, 0 * scale + ty, 116 * scale + tx, 0 * scale + ty, {
r: ROTATE_VERTICAL
}],
['b', 180.1 * scale + tx, 0 * scale + ty, 232 * scale + tx, 51.9 * scale + ty, 232 * scale + tx, 116 * scale + ty, {
r: ROTATE_HORIZONTAL,
c: 1
}],
]
}]
}
//Ð
export function getLatin8(x, y) {
return [{
d: 1,
v: [
['m', x - 40, y, {
x: 0,
y: 1,
r: ROTATE_VERTICAL
}],
['l', 100 + x, y, {
x: 0,
y: 1,
f: 1
}],
]
}]
}
//Ç
export function getLatin9(x, y) {
return [{
d: -1,
v: [
['m', x, y, {
p: 1
}],
['b', 9.3 + x, 11.6 + y, 15.6 + x, 27.1 + y, 15.6 + x, 40.9 + y],
['b', 15.6 + x, 83.3 + y, -18.2 + x, 107.8 + y, -59.5 + x, 107.8 + y],
['b', -70.9 + x, 107.8 + y, -82.9 + x, 106.2 + y, -93.7 + x, 102.7 + y, {
x: 0.5,
f: 1
}],
]
}]
}
//Ą
export function getLatin10(x, y) {
return [{
d: -1,
v: [
['m', x, y, {
p: 1
}],
['b', 22.6 - 42.2 + x, 14.8 + y, -42.2 + x, 37.9 + y, -42.2 + x, 64.1 + y],
['b', -42.2 + x, 100.3 + y, 30.2 - 42.2 + x, 118.8 + y, 63.6 - 42.2 + x, 118.8 + y],
['b', 68.3 - 42.2 + x, 118.8 + y, 72.9 - 42.2 + x, 118.4 + y, 77.4 - 42.2 + x, 117.6 + y, {
x: 0.5,
f: 1
}],
]
}]
}
//Ċ
export function getLatin11(x, y) {
return [{
d: 1,
v: [
['a', x, y, {
x: 0,
y: 0
}],
]
}];
}
//Č
export function getLatin12(x, y) {
const tx = -68 + x;
const ty = y;
return [{
d: -1,
v: [
['m', 0 + tx, ty, {
r: getR(0 + tx, ty, 68 - VERTEX_GAP2 + tx, 50 + ty),
y: 0,
x: 0
}],
['l', 68 - VERTEX_GAP2 + tx, 50 + ty, {
r: getR(0 + tx, ty, 68 - VERTEX_GAP2 + tx, 50 + ty),
y: 0,
x: 0,
f: 1,
}],
['l', 68 + VERTEX_GAP2 + tx, 50 + ty, {
r: getR(68 + VERTEX_GAP2 + tx, 50 + ty, 68 + 68 + tx, ty),
y: 0,
x: 0,
f: 1,
v: 1
}],
['l', 68 + 68 + tx, ty, {
y: 0,
x: 0,
f: 1
}]
]
}];
}
//ď
export function getLatin13(x, y) {
return [{
d: -1,
v: [
['m', x, y, {
x: 0,
y: 0
}],
['l', x, 80 + y, {
x: 0,
y: 0,
f: 1
}],
]
}];
}
//Ē
export function getLatin14(x, y) {
return [{
d: 1,
v: [
['m', x - 50, y, {
x: 0,
y: 0
}],
['l', x + 50, y, {
x: 0,
y: 0,
f: 1
}],
]
}];
}
================================================
FILE: src/font/lower.js
================================================
import {
generateFontData,
ROTATE_HORIZONTAL,
ROTATE_VERTICAL,
ROTATE_NONE,
VERTEX_GAP,
VERTEX_GAP2,
getR,
getCurveR
} from './util.js';
export const DATA_LA = [{
d: -1,
v: [
['m', 232, 8, {
y: -3.4,
r: ROTATE_HORIZONTAL
}],
['l', 232, 116, {
r: ROTATE_NONE
}],
['b', 232, 180.1, 180.1, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 232, 0, 180.1, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 51.9, 51.9, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 0, 232, 51.9, 232, 116, {
r: ROTATE_HORIZONTAL
}],
['l', 232, 224, {
y: -0.1,
r: ROTATE_HORIZONTAL,
f: 1
}]
]
}];
export const DATA_LC = [{
d: 1,
v: [
['m', 212.1, 182.9, {
r: getCurveR(212.1, 182.9, 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, 0),
f: 1
}],
['b', 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, {
r: ROTATE_VERTICAL
}],
['b', 52.4, 233.1, 0.5, 181.2, 0.5, 117.1, {
r: ROTATE_HORIZONTAL
}],
['b', 0.5, 53, 52.4, 1.1, 116.5, 1.1, {
r: ROTATE_VERTICAL
}],
['b', 156.1, 1.1, 191.1, 21, 212.1, 51.3],
]
}];
export const DATA_LD = [{
d: -1,
v: [
['m', 232, 0, {
y: 0
}],
['l', 232, 116 + 123, {
r: ROTATE_NONE
}],
['b', 232, 180.1 + 123, 180.1, 232 + 123, 116, 232 + 123, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 232 + 123, 0, 180.1 + 123, 0, 116 + 123, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 51.9 + 123, 51.9, 0 + 123, 116, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 0 + 123, 232, 51.9 + 123, 232, 116 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 232, 352, {
y: 0,
f: 1
}],
]
}];
export const DATA_LE = [{
d: 1,
v: [
['m', 211.6, 182.9, {
r: getCurveR(211.6, 182.9, 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, 0),
f: 1
}],
['b', 191.1, 213.2, 156.1, 233.1, 116.5, 233.1, {
r: ROTATE_VERTICAL
}],
['b', 52.4, 233.1, 0.5, 181.2, 0.5, 117.1, {
r: ROTATE_HORIZONTAL
}],
['b', 0.5, 53, 52.4, 1.1, 116.5, 1.1, {
r: ROTATE_VERTICAL
}],
['b', 176.4, 1.1, 224.9, 47.2, 225.5, 106.1, {
r: ROTATE_HORIZONTAL
}],
['l', 0.5, 106.1, {
r: ROTATE_HORIZONTAL,
p: 1
}],
]
}];
export const DATA_LG = [{
d: -1,
v: [
['m', 232, 5, {
y: -2.8
}],
['l', 232, 116, {
r: ROTATE_NONE
}],
['b', 232, 180.1, 180.1, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 232, 0, 180.1, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 51.9, 51.9, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 0, 232, 51.9, 232, 116, {
r: ROTATE_HORIZONTAL
}],
['l', 232, 222],
['b', 234.5, 300.3, 180.2, 338.5, 116, 338, {
y: 0.64,
r: ROTATE_VERTICAL
}],
['b', 76.2, 337.7, 36.6, 320.7, 15.7, 290.1, {
y: 0.64,
f: 1
}],
]
}];
export const DATA_LH = [{
d: -1,
v: [
['m', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 91 + 123, {
r: ROTATE_NONE
}],
['b', 0, 40.7 + 123, 40.7, 0 + 123, 91, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 141.3, 0 + 123, 182, 40.7 + 123, 182, 91 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 182, 352, {
y: 0,
f: 1
}],
]
}];
export const DATA_LN = [{
d: -1,
v: [
['m', 0, 130, {
y: -3.3
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 91 + 123, {
y: 0,
r: ROTATE_HORIZONTAL,
p: 1
}],
['b', 0, 40.7 + 123, 40.7, 0 + 123, 91, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 141.3, 0 + 123, 182, 40.7 + 123, 182, 91 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 182, 352, {
y: 0,
f: 1
}],
]
}];
export const DATA_LO = [{
d: 1,
v: [
['m', 232, 116, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 232, 180.1, 180.1, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 232, 0, 180.1, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 51.9, 51.9, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 0, 232, 51.9, 232, 116, {
r: ROTATE_HORIZONTAL,
c: 1
}],
]
}];
export const DATA_LS = [{
d: 1,
v: [
['m', 0 * 0.642, 295.4 * 0.642, {
r: getCurveR(0 * 0.642, 295.4 * 0.642, 17.6 * 0.642, 332.1 * 0.642, 58.3 * 0.642, 360 * 0.642, 110.3 * 0.642, 360 * 0.642, 0),
f: 1
}],
['b', 17.6 * 0.642, 332.1 * 0.642, 58.3 * 0.642, 360 * 0.642, 110.3 * 0.642, 360 * 0.642],
['b', 173.9 * 0.642, 360 * 0.642, 223.8 * 0.642, 329.6 * 0.642, 224 * 0.642, 271 * 0.642],
['b', 224.2 * 0.642, 214.7 * 0.642, 180.7 * 0.642, 189.6 * 0.642, 112.4 * 0.642, 173.3 * 0.642],
['b', 47.3 * 0.642, 157.7 * 0.642, 10.9 * 0.642, 130.6 * 0.642, 12 * 0.642, 84.4 * 0.642],
['b', 13.3 * 0.642, 29.8 * 0.642, 57.3 * 0.642, 0 * 0.642, 114.8 * 0.642, 0 * 0.642],
['b', 158.4 * 0.642, 0 * 0.642, 196.5 * 0.642, 20.5 * 0.642, 212 * 0.642, 51.3 * 0.642],
]
}];
export const DATA_LU = [{
d: -1,
v: [
['m', 0, 130, {
y: -3
}],
['l', 0, 0 + 265, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 50.3 + 265, 40.7, 91 + 265, 91, 91 + 265, {
r: ROTATE_VERTICAL
}],
['b', 141.3, 91 + 265, 182, 50.3 + 265, 182, 0 + 265, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1,
}],
]
},
{
d: -1,
v: [
['m', 182, 130, {
y: -3
}],
['l', 182, 352, {
y: 0,
f: 1
}],
]
}
];
export const DATA_LY = [{
d: -1,
v: [
['m', 225.5, 0, {
y: -3,
r: getR(225.5, 0, 116.3, 248.8)
}],
['l', 116.3, 248.8, {
x: 0.5,
y: 0.64
}],
['b', 71.8, 349.6, 0, 331.5, 0, 331.5, {
x: 0.5,
y: 0.64,
r: getCurveR(0, 331.5, 71.8, 349.6, 116.3, 248.8, 0, 331.5, 0),
f: 1
}],
]
},
{
d: -1,
v: [
['m', 3.2, 0, {
y: -3,
r: getR(3.2, 0, 125.7, 226.6)
}],
['l', 125.7, 226.6, {
p: 1,
f: 1
}],
]
}
];
export const LOWER = {
'a': generateFontData(
600, 232, 232,
10, 2, -64, -64,
JSON.parse(JSON.stringify(DATA_LA))
),
'b': generateFontData(
600, 232, 352,
-10, -2, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 116 + 123, {
r: ROTATE_NONE
}],
['b', 0, 180.1 + 123, 51.9, 232 + 123, 116, 232 + 123, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 232 + 123, 232, 180.1 + 123, 232, 116 + 123, {
r: ROTATE_HORIZONTAL
}],
['b', 232, 51.9 + 123, 180.1, 0 + 123, 116, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 0 + 123, 0, 51.9 + 123, 0, 116 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}]
]
}, ]
),
'c': generateFontData(
520, 212.1, 233.1,
2, -10, -64, -64,
JSON.parse(JSON.stringify(DATA_LC))
),
'd': generateFontData(
600, 232, 352,
10, 2, 0, 0,
JSON.parse(JSON.stringify(DATA_LD))
),
'e': generateFontData(
570, 225.5, 233.1,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LE))
),
'f': generateFontData(
356, 232, 352,
-40, -40, 0, 0,
[{
d: -1,
v: [
['m', 166.6, 33, {
x: 0.5,
r: getCurveR(166.6, 33, 159.3, 13.1, 139.2, 0, 116.9, 0, 0)
}],
['b', 159.3, 13.1, 139.2, 0, 116.9, 0, {
r: ROTATE_VERTICAL
}],
['b', 88.2, 0, 65, 23.2, 65, 51.9, {
r: ROTATE_HORIZONTAL
}],
['l', 65, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0, 130, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 154, 130, {
x: 0,
f: 1
}],
]
}
]
),
'g': generateFontData(
600, 232, 338,
10, 2, -117, -117,
JSON.parse(JSON.stringify(DATA_LG))
),
'h': generateFontData(
520, 182, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LH))
),
'i': generateFontData(
200, 0, 352,
0, 0, 0, 0,
[{
d: 1,
v: [
['a', 0, 90, {
y: -3
}],
]
}, {
d: 1,
v: [
['m', 0, 352, {
y: 0,
f: 1
}],
['l', 0, 130, {
y: -3
}],
]
}]
),
'j': generateFontData(
220, 115.9, 352,
-60, -60, 0, 0,
[{
d: 1,
v: [
['a', 0, 90, {
y: -3
}],
]
}, {
d: 1,
v: [
['m', 0 - 115.9, 317 + 127, {
x: 0.4,
y: 0.63,
r: getCurveR(0 - 115.9, 317 + 127, 12.6 - 115.9, 327.4 + 127, 29.6 - 115.9, 333.2 + 127, 45.9 - 115.9, 334.2 + 127, 0),
f: 1
}],
['b', 12.6 - 115.9, 327.4 + 127, 29.6 - 115.9, 333.2 + 127, 45.9 - 115.9, 334.2 + 127, {
x: 0.4,
y: 0.63,
r: ROTATE_VERTICAL
}],
['b', 84.5 - 115.9, 336.5 + 127, 115.9 - 115.9, 308.1 + 127, 115.9 - 115.9, 269.4 + 127, {
x: 0.4,
y: 0.63,
r: ROTATE_HORIZONTAL
}],
['l', 115.9 - 115.9, 0 + 127 + 3, {
y: -3
}],
]
}]
),
'k': generateFontData(
450, 164, 352,
-10, -10, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 160, 130, {
x: 0.7,
y: 0,
r: getR(164, 130, 0, 106 + 130 - VERTEX_GAP2),
f: 1
}],
['l', 0, 106 + 130 - VERTEX_GAP2, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 0, 106 + 130 + VERTEX_GAP2, {
r: ROTATE_VERTICAL,
p: 1,
v: 1
}],
['l', 164, 352, {
x: 0.7,
y: 0.7,
f: 1
}],
]
}
]
),
'l': generateFontData(
200, 0, 352,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 0, 352, {
y: 0,
f: 1
}],
['l', 0, 0, {
y: 0
}],
]
}]
),
'm': generateFontData(
740, 150 + 150, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 130, {
y: -3.6
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0, 75 + 123, {
y: 0,
r: ROTATE_HORIZONTAL,
p: 1
}],
['b', 0, 33.6 + 123, 33.6, 0 + 123, 75, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 116.4, 0 + 123, 150, 33.6 + 123, 150, 75 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 150, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0 + 150, 75 + 123, {
y: 0,
r: ROTATE_HORIZONTAL,
p: 1
}],
['b', 0 + 150, 33.6 + 123, 33.6 + 150, 0 + 123, 75 + 150, 0 + 123, {
r: ROTATE_VERTICAL
}],
['b', 116.4 + 150, 0 + 123, 150 + 150, 33.6 + 123, 150 + 150, 75 + 123, {
r: ROTATE_HORIZONTAL
}],
['l', 150 + 150, 352, {
y: 0,
f: 1
}],
]
}
]
),
'n': generateFontData(
520, 182, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LN))
),
'o': generateFontData(
580, 232, 232,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LO))
),
'p': generateFontData(
600, 232, 338,
-10, -2, -117, -117,
[{
d: -1,
v: [
['m', 0, 5, {
y: -2.8
}],
['l', 0, 116, {
r: ROTATE_NONE
}],
['b', 0, 180.1, 51.9, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 232, 232, 180.1, 232, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 232, 51.9, 180.1, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 0, 0, 51.9, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['l', 0, 338, {
y: 0,
f: 1
}],
]
}]
),
'q': generateFontData(
600, 232, 338,
10, 2, -117, -117,
[{
d: -1,
v: [
['m', 232, 5, {
y: -2.8
}],
['l', 232, 116, {
r: ROTATE_NONE
}],
['b', 232, 180.1, 180.1, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 232, 0, 180.1, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 51.9, 51.9, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 0, 232, 51.9, 232, 116, {
r: ROTATE_HORIZONTAL
}],
['l', 232, 338, {
y: 0,
f: 1
}],
]
}]
),
'r': generateFontData(
340, 119.2, 352,
-20, -20, 0, 0,
[{
d: -1,
v: [
['m', 0, 130, {
y: -3.3
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0, 57 + 124, {
r: ROTATE_HORIZONTAL,
p: 1,
}],
['b', 0, 57 + 124, 41.9, -22.8 + 124, 119.2, 4.5 + 124, {
x: 0,
y: 2,
r: getCurveR(119.2, 4.5 + 124, 41.9, -22.8 + 124, 0, 57 + 124, 119.2, 4.5 + 124, 0),
f: 1
}],
]
}
]
),
's': generateFontData(
400, 224 * 0.642, 360 * 0.642,
0, 0, -64, -64,
JSON.parse(JSON.stringify(DATA_LS))
),
't': generateFontData(
356, 232, 352,
-30, -30, 0, 0,
[{
d: -1,
v: [
['m', 65, 0, {
y: 0
}],
['l', 65, 298.2 + 6],
['b', 65, 326.9 + 6, 88.2, 350.1 + 6, 116.9, 350.1 + 6, {
r: ROTATE_VERTICAL
}],
['b', 139.2, 350.1 + 6, 159.3, 337 + 6, 166.6, 317.1, {
x: 0,
f: 1
}]
]
},
{
d: -1,
v: [
['m', 0, 130, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 154, 130, {
x: 0,
f: 1
}],
]
}
]
),
'u': generateFontData(
520, 182, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_LU))
),
'v': generateFontData(
500, 200, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 130, {
x: 0.6,
y: -3,
r: getR(0, 130, 100 - VERTEX_GAP2, 352)
}],
['l', 100 - VERTEX_GAP2, 352, {
r: getR(0, 130, 100 - VERTEX_GAP2, 352),
f: 1
}],
['l', 100 + VERTEX_GAP2, 352, {
r: getR(100 + VERTEX_GAP2, 352, 200, 130),
f: 1,
v: 1
}],
['l', 200, 130, {
x: 0.6,
y: -3,
f: 1
}],
]
}]
),
'w': generateFontData(
700, 310, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 130, {
x: 0.6,
y: -3,
r: getR(0, 130, 78 - VERTEX_GAP2, 352)
}],
['l', 78 - VERTEX_GAP2, 352, {
r: getR(0, 130, 78 - VERTEX_GAP2, 352),
f: 1
}],
['l', 78 + VERTEX_GAP2, 352, {
r: getR(78 + VERTEX_GAP2, 352, 155 - VERTEX_GAP2, 130),
f: 1,
v: 1
}],
['l', 155 - VERTEX_GAP2, 130, {
y: 1,
r: getR(78 + VERTEX_GAP2, 352, 155 - VERTEX_GAP2, 130),
f: 1
}],
['l', 155 + VERTEX_GAP2, 130, {
y: 1,
r: getR(155 + VERTEX_GAP2, 130, 233 - VERTEX_GAP2, 352),
f: 1,
v: 1
}],
['l', 233 - VERTEX_GAP2, 352, {
r: getR(155 + VERTEX_GAP2, 130, 233 - VERTEX_GAP2, 352),
f: 1
}],
['l', 233 + VERTEX_GAP2, 352, {
r: getR(233 + VERTEX_GAP2, 352, 310, 130),
f: 1,
v: 1
}],
['l', 310, 130, {
x: 0.6,
y: -3,
f: 1
}],
]
}]
),
'x': generateFontData(
490, 210, 352,
0, 0, 0, -7,
[{
d: -1,
v: [
['m', 10, 130, {
x: 0.5,
y: -1,
r: getR(10, 130, 210, 352)
}],
['l', 210, 352, {
x: 0.5,
y: 0.5,
f: 1
}]
]
},
{
d: -1,
v: [
['m', 200, 130, {
x: 0.5,
y: -1,
r: getR(200, 130, 0, 352)
}],
['l', 0, 352, {
x: 0.5,
y: 0.5,
f: 1
}]
]
}
]
),
'y': generateFontData(
500, 225.5, 331.5,
10, 10, -119, -119,
JSON.parse(JSON.stringify(DATA_LY))
),
'z': generateFontData( // 232, 224
420, 172, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 6, 130, {
x: -0.5,
y: 1,
r: ROTATE_VERTICAL,
}],
['l', 166, 130, {
x: 1.8,
y: 1,
r: ROTATE_VERTICAL,
f: 1
}],
['l', 166, 130 + VERTEX_GAP, {
x: 1.8,
y: 1,
r: ROTATE_HORIZONTAL,
p: 1,
v: 1
}],
['l', 0, 352 - VERTEX_GAP, {
x: 1.7,
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 0, 352, {
x: 1.7,
r: ROTATE_VERTICAL,
f: 1,
v: 1
}],
['l', 172, 352, {
x: -0.4,
r: ROTATE_VERTICAL,
f: 1
}]
]
}]
)
};
================================================
FILE: src/font/number.js
================================================
import {
generateFontData,
ROTATE_HORIZONTAL,
ROTATE_VERTICAL,
ROTATE_NONE,
VERTEX_GAP,
getR,
getCurveR
} from './util.js';
export const NUMBER = {
'0': generateFontData(
660, 270, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 270, 180, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 270, 279.4, 209.6, 360, 135, 360, {
r: ROTATE_VERTICAL
}],
['b', 60.4, 360, 0, 279.4, 0, 180, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 80.6, 60.4, 0, 135, 0, {
r: ROTATE_VERTICAL
}],
['b', 209.6, 0, 270, 80.6, 270, 180, {
r: ROTATE_HORIZONTAL,
c: 1
}],
]
}]
),
'1': generateFontData(
380, 76, 352,
15, 15, 0, 0,
[{
d: -1,
v: [
['m', 0, 51, {
x: -2,
y: 2,
r: getR(0, 51, 76 - VERTEX_GAP, 0)
}],
['l', 76 - VERTEX_GAP, 0, {
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 76, 0, {
r: ROTATE_HORIZONTAL,
f: 1,
v: 1
}],
['l', 76, 352, {
y: 0,
f: 1
}],
]
}]
),
'2': generateFontData(
580, 210, 356,
0, 0, 2, 2,
[{
d: -1,
v: [
['m', 3.9, 68.8, {
x: 1.2,
y: 1.2,
r: getCurveR(3.9, 68.8, 16.7, 29, 54.2, 3.1, 98.2, 0.2, 0)
}],
['b', 16.7, 29, 54.2, 3.1, 98.2, 0.2],
['b', 151.8, -3.3, 208.5, 38.3, 198.9, 100.1],
['b', 197.1, 111.8, 196.4, 142.4, 101.5, 235.2],
['b', 11.4, 323.2, 0, 356 - VERTEX_GAP, 0, 356 - VERTEX_GAP, {
r: ROTATE_NONE
}],
['l', 0, 356 - VERTEX_GAP, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 0, 356, {
r: ROTATE_VERTICAL,
f: 1,
v: 1
}],
['l', 210, 356, {
x: -0.5,
f: 1
}],
]
}]
),
'3': generateFontData(
580, 222.1, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 10.7, 66.3, {
r: getCurveR(10.7, 66.3, 11.2, 64.8, 11.7, 63.3, 12.3, 61.8, 0)
}],
['b', 11.2, 64.8, 11.7, 63.3, 12.3, 61.8, {
r: ROTATE_NONE
}],
['b', 25.8, 25.9, 64.5, 0, 110.1, 0, {
r: ROTATE_VERTICAL
}],
['b', 167, 0, 213.1, 40.3, 213.1, 90, {
r: ROTATE_HORIZONTAL
}],
['b', 213.1, 139.7, 167, 180, 110.1, 179.9, {
r: ROTATE_VERTICAL,
f: 1
}],
['l', 100.1, 179.9, {
x: -5,
y: 1,
r: ROTATE_VERTICAL,
f: 1
}],
['l', 110.1, 180, {
r: ROTATE_VERTICAL,
p: 1
}],
['b', 172, 180, 222.1, 220.3, 222.1, 270, {
r: ROTATE_HORIZONTAL
}],
['b', 222.1, 319.7, 172, 360, 110.1, 360, {
r: ROTATE_VERTICAL
}],
['b', 56.9, 360, 12.4, 330.2, 1, 290.3, {
f: 1
}],
]
}]
),
'4': generateFontData(
596, 236, 352,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 175, 352, {
y: 0,
f: 1
}],
['l', 175, 0, {
f: 1
}],
['l', 175 - VERTEX_GAP, 0, {
r: ROTATE_VERTICAL,
p: 1,
v: 1
}],
['l', 0, 276 - VERTEX_GAP, {
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 0, 276, {
r: ROTATE_VERTICAL,
f: 1,
v: 1
}],
['l', 236, 276, {
x: -0.5
}],
]
}]
),
'5': generateFontData(
596, 208.5, 356,
0, -5, -2, -2,
[{
d: 1,
v: [
['m', 0, 295.7, {
r: getCurveR(0, 295.7, 15.3, 333.8, 52.2, 356.2, 97.5, 356, 0),
f: 1
}],
['b', 15.3, 333.8, 52.2, 356.2, 97.5, 356, {
r: ROTATE_VERTICAL
}],
['b', 159.1, 355.7, 206.1, 306.9, 208.5, 240.8, {
r: ROTATE_HORIZONTAL
}],
['b', 210.9, 173.9, 162.7, 120.8, 97.5, 125.6, {
r: ROTATE_VERTICAL
}],
['b', 59.4, 128.4, 25.5, 145.8, 5.6, 176.4, {
f: 1
}],
['l', 5.6, 176.4, {
r: ROTATE_NONE
}],
['l', 5.6 - VERTEX_GAP, 176.4, {
r: ROTATE_HORIZONTAL,
p: 1,
v: 1
}],
['l', 11.5, 0, {
r: ROTATE_VERTICAL,
f: 1
}],
['l', 193.5, 0, {
x: -0.5
}],
]
}]
),
'6': generateFontData(
596, 215.8, 360,
0, -2, 0, 0,
[{
d: 1,
v: [
['m', 7.6, 272.3, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 6.4, 265.8, 5.8, 259.1, 5.8, 252.2, {
r: ROTATE_HORIZONTAL
}],
['b', 5.8, 192.6, 52.8, 144.2, 110.8, 144.2, {
r: ROTATE_VERTICAL
}],
['b', 168.7, 144.2, 215.8, 192.6, 215.8, 252.2, {
r: ROTATE_HORIZONTAL
}],
['b', 215.8, 311.9, 168.7, 360, 110.8, 360, {
r: ROTATE_VERTICAL
}],
['b', 59.5, 360, 16.8, 322.4, 7.6, 272.4, {
r: ROTATE_NONE
}],
['b', 7.6, 272.4, -44.1, 8.8, 122.2, 0.2],
['b', 165.5, -2.1, 193.8, 21, 212.1, 56.4],
]
}]
),
'7': generateFontData(
540, 213, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 213, 0, {
r: ROTATE_VERTICAL,
f: 1
}],
['l', 213, 0.1, {
r: ROTATE_NONE
}],
['l', 72.7, 352, {
y: 0.1,
f: 1
}],
]
}]
),
'8': generateFontData(
596, 224, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 112, 180, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 50.1, 180, 0, 220.3, 0, 270, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 319.7, 50.1, 360, 112, 360, {
r: ROTATE_VERTICAL
}],
['b', 173.9, 360, 224, 319.7, 224, 270, {
r: ROTATE_HORIZONTAL
}],
['b', 224, 220.3, 173.9, 180, 112, 180, {
r: ROTATE_VERTICAL
}],
['b', 55.1, 180, 9, 139.7, 9, 90, {
r: ROTATE_HORIZONTAL
}],
['b', 9, 40.3, 55.1, 0, 112, 0, {
r: ROTATE_VERTICAL
}],
['b', 168.9, 0, 215, 40.3, 215, 90, {
r: ROTATE_HORIZONTAL
}],
['b', 215, 139.7, 168.9, 180, 112, 180, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
]
}]
),
'9': generateFontData(
596, 215.8, 360,
0, -2, 0, 0,
[{
d: -1,
v: [
['m', 208.2, 88, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 209.4, 94.5, 210, 101.2, 210, 108, {
r: ROTATE_HORIZONTAL
}],
['b', 210, 167.6, 163, 216, 105, 216, {
r: ROTATE_VERTICAL
}],
['b', 47, 216, -0, 167.6, 0, 108, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 48.4, 47, -0, 105, 0, {
r: ROTATE_VERTICAL
}],
['b', 156.3, 0, 199, 37.8, 208.2, 87.8, {
r: ROTATE_NONE
}],
['b', 208.2, 87.8, 259.8, 351.4, 93.5, 360],
['b', 50.3, 362.3, 21.9, 339.2, 3.6, 303.8, {
f: 1
}],
]
}]
)
};
================================================
FILE: src/font/special.js
================================================
import {
generateFontData,
ROTATE_HORIZONTAL,
ROTATE_VERTICAL,
ROTATE_NONE,
getR,
getCurveR,
VERTEX_GAP2
} from './util.js';
export const SPECIAL = {
' ': generateFontData(
336, 0, 0,
0, 0, 0, 0,
[{
d: 1,
v: []
}]
),
'tofu': generateFontData(
672, 232, 352,
0, 0, 0, 0,
[{
//c: 'square',
d: -1,
v: [
['m', 0, 0, {
r: ROTATE_HORIZONTAL
}],
['l', 232, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 232, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1,
c: 1
}],
]
},
{
d: 1,
v: [
['m', 0, 0, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['l', 232, 352, {
r: ROTATE_NONE
}],
]
}
]
),
'?': generateFontData(
520, 190.348, 360,
0, -5, 0, 0,
[{
d: 1,
v: [
['a', 190.348 / 2 - 6, 356],
]
}, {
d: -1,
v: [
['m', 0, 87.8, {
r: getCurveR(0, 87.8, 12, -2.3, 99.1, 0, 0, 87.8, 0)
}],
['b', 0, 87.8, 12, -2.3, 99.1, 0, {
r: ROTATE_VERTICAL
}],
['b', 186.2, 2.4, 204.5, 75.2, 180.9, 121.4],
['b', 157.3, 167.6, 119.7, 178.3, 97.4, 223.2],
['b', 90.5, 237.1, 88.1, 249.8, 88, 260.8, {
r: ROTATE_HORIZONTAL,
f: 1
}],
]
}]
),
'¿': generateFontData(
520, 190.348, 360,
0, -5, 0, 0,
[{
d: 1,
v: [
['a', 190.348 / 2 + 6, 356 - 451 + 188],
]
}, {
d: -1,
v: [
['m', 190.3, 173.0 + 188, {
r: getCurveR(190.3, 173.0 + 188, 178.3, 263.1 + 188, 91.2, 260.8 + 188, 190.3, 173.0 + 188, 0)
}],
['b', 190.3, 173.0 + 188, 178.3, 263.1 + 188, 91.2, 260.8 + 188, {
r: ROTATE_VERTICAL
}],
['b', 4.1, 258.4 + 188, -14.2, 185.6 + 188, 9.4, 139.4 + 188],
['b', 33.0, 93.2 + 188, 70.6, 82.5 + 188, 92.9, 37.6 + 188],
['b', 99.8, 23.7 + 188, 102.2, 11.0 + 188, 102.3, 0.0 + 188, {
r: ROTATE_HORIZONTAL,
f: 1
}],
]
}]
),
'!': generateFontData(
465, 8, 355,
0, -5, 0, 0,
[{
d: 1,
v: [
['a', 8 / 2, 356],
]
}, {
d: -1,
v: [
['m', 4, 0, {
y: 0
}],
['l', 4, 260.8, {
f: 1
}],
]
}]
),
'¡': generateFontData(
465, 8, 355,
0, -5, 0, 0,
[{
d: 1,
v: [
['a', 8 / 2, 356 - 451 + 188],
]
}, {
d: -1,
v: [
['m', 4, 0 + 188],
['l', 4, 260.8 + 188, {
f: 1,
y: 0.3
}],
]
}]
),
'$': generateFontData(
568, 224, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 212, 51.3, {
r: getCurveR(0, 295.4, 17.6, 332.1, 58.3, 360, 110.3, 360, 0),
f: 1
}],
['b', 196.5, 20.5, 158.4, 0, 114.8, 0],
['b', 57.3, 0, 13.3, 29.8, 12, 84.4],
['b', 10.9, 130.6, 47.3, 157.7, 112.4, 173.3],
['b', 180.7, 189.6, 224.2, 214.7, 224, 271],
['b', 223.8, 329.6, 173.9, 360, 110.3, 360],
['b', 58.3, 360, 17.6, 332.1, 0, 295.4, {
f: 1
}],
]
}, {
d: -1,
v: [
['m', 112, 0 - 30, {
y: 0
}],
['l', 112, 360 + 30, {
y: 0,
f: 1
}],
]
}]
),
'@': generateFontData(
820, 343.425, 360,
0, 0, -30, -30,
[{
d: -1,
v: [
['m', 251.9, 92.9, {
r: getR(251.9, 92.9, 238.5, 181.7)
}],
['l', 238.5, 181.7, {
r: ROTATE_NONE
}],
['b', 227.8, 236, 194.7, 267.2, 143.7, 259.2],
['b', 99.1, 252.2, 87.7, 208.5, 90.1, 177.5],
['b', 92.5, 148.4, 118.1, 91, 183.3, 99.1],
['b', 251, 107.5, 238.5, 181.7, 238.5, 181.7, {
r: ROTATE_NONE
}],
['l', 232.5, 221.5],
['b', 232.5, 221.5, 227.2, 257.6, 256, 263.6],
['b', 284.9, 269.7, 309, 241.3, 309, 241.3, {
r: ROTATE_NONE
}],
['b', 309, 241.3, 343.4, 209, 343.4, 146.7],
['b', 343.4, 84.3, 297.4, 3.5, 178.6, 0.1],
['b', 59.7, -3.4, -5.3, 105.2, 0.3, 203.4],
['b', 6.1, 303.7, 93.2, 354.5, 175.5, 359.5],
['b', 175.5, 359.5, 246.5, 364.9, 302.7, 339.8, {
f: 1
}],
]
}]
),
'#': generateFontData(
760, 290 + 24, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 70 + 47, 0, {
y: 0,
r: getR(70 + 47, 0, 0 + 47, 352)
}],
['l', 0 + 47, 352, {
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 70 + 150 + 47, 0, {
y: 0,
r: getR(70 + 150 + 47, 0, 0 + 150 + 47, 352)
}],
['l', 0 + 150 + 47, 352, {
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0 + 24, 117, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 290 + 24, 117, {
x: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 352 - 117, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 290, 352 - 117, {
x: 0,
f: 1
}],
]
}]
),
'%': generateFontData(
920, 352 + 36, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 289.1 + 18, 5.1, {
x: 0,
y: 0,
r: getR(289.1 + 18, 5.1, 62.9 + 18, 354.9)
}],
['l', 62.9 + 18, 354.9, {
x: 0,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 146, 73, {
r: ROTATE_HORIZONTAL,
p: 1,
}],
['b', 146, 113.3, 113.3, 146, 73, 146, {
r: ROTATE_VERTICAL
}],
['b', 32.7, 146, 0, 113.3, 0, 73, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 32.7, 32.7, 0, 73, 0, {
r: ROTATE_VERTICAL
}],
['b', 113.3, 0, 146, 32.7, 146, 73, {
r: ROTATE_HORIZONTAL,
c: 1,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 352 + 36, 287, {
r: ROTATE_HORIZONTAL,
p: 1,
}],
['b', 352 + 36, 327.3, 319.3 + 36, 360, 279 + 36, 360, {
r: ROTATE_VERTICAL
}],
['b', 238.7 + 36, 360, 206 + 36, 327.3, 206 + 36, 287, {
r: ROTATE_HORIZONTAL
}],
['b', 206 + 36, 246.7, 238.7 + 36, 214, 279 + 36, 214, {
r: ROTATE_VERTICAL
}],
['b', 319.3 + 36, 214, 352 + 36, 246.7, 352 + 36, 287, {
r: ROTATE_HORIZONTAL,
c: 1,
f: 1
}],
]
}]
),
'^': generateFontData(
596, 88 + 88, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 150, {
r: getR(0, 150, 88 - VERTEX_GAP2, 0)
}],
['l', 88 - VERTEX_GAP2, 0, {
r: getR(0, 150, 88 - VERTEX_GAP2, 0),
f: 1
}],
['l', 88 + VERTEX_GAP2, 0, {
r: getR(88 + VERTEX_GAP2, 0, 88 + 88, 150),
f: 1,
v: 1
}],
['l', 88 + 88, 150, {
f: 1
}]
]
}]
),
'·': generateFontData(
231, 8, 355,
0, 0, 0, 0,
[{
d: 1,
v: [
['a', 8 / 2, 355 - 1.5 - 170],
]
}]
),
'×': generateFontData(
712, 176.8, 176.8,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
y: 0,
r: getR(0, 0, 176.8, 176.8),
}],
['l', 176.8, 176.8, {
x: 0,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 176.8, 0, {
x: 0,
y: 0,
r: getR(176.8, 0, 0, 176.88),
}],
['l', 0, 176.8, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
'÷': generateFontData(
712, 188, 0,
0, 0, 0, 0,
[{
d: 1,
v: [
['a', (188 / 2), 110],
]
}, {
d: 1,
v: [
['a', (188 / 2), -110],
]
},
{
d: -1,
v: [
['m', 0, 0, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['l', 188, 0, {
x: 0,
y: 0,
f: 1
}],
]
}
]
),
'«': generateFontData(
896, 310, 236,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 150, 236, {
r: getR(150, 236, 0, 118 + VERTEX_GAP2),
f: 1
}],
['l', 0, 118 + VERTEX_GAP2, {
r: getR(150, 236, 0, 118 + VERTEX_GAP2),
f: 1
}],
['l', 0, 118 - VERTEX_GAP2, {
r: getR(0, 118 - VERTEX_GAP2, 150, 0),
f: 1,
v: 1
}],
['l', 150, 0]
]
}, {
d: 1,
v: [
['m', 150 + 160, 236, {
r: getR(150 + 160, 236, 0 + 160, 118 + VERTEX_GAP2),
f: 1
}],
['l', 0 + 160, 118 + VERTEX_GAP2, {
r: getR(150 + 160, 236, 0 + 160, 118 + VERTEX_GAP2),
f: 1
}],
['l', 0 + 160, 118 - VERTEX_GAP2, {
r: getR(0 + 160, 118 - VERTEX_GAP2, 150 + 160, 0),
f: 1,
v: 1
}],
['l', 150 + 160, 0]
]
}]
),
'»': generateFontData(
896, 310, 236,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 0, 236, {
r: getR(0, 236, 150, 118 + VERTEX_GAP2),
f: 1
}],
['l', 150, 118 + VERTEX_GAP2, {
r: getR(0, 236, 0, 118 + VERTEX_GAP2),
f: 1
}],
['l', 150, 118 - VERTEX_GAP2, {
r: getR(150, 118 - VERTEX_GAP2, 0, 0),
f: 1,
v: 1
}],
['l', 0, 0]
]
}, {
d: 1,
v: [
['m', 0 + 160, 236, {
r: getR(0 + 160, 236, 150 + 160, 118 + VERTEX_GAP2),
f: 1
}],
['l', 150 + 160, 118 + VERTEX_GAP2, {
r: getR(0, 236, 0, 118 + VERTEX_GAP2),
f: 1
}],
['l', 150 + 160, 118 - VERTEX_GAP2, {
r: getR(150 + 160, 118 - VERTEX_GAP2, 0 + 160, 0),
f: 1,
v: 1
}],
['l', 0 + 160, 0]
]
}]
),
'&': generateFontData(
660, 259.191, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 257.9, 355, {
x: 0.5,
y: 0.5,
r: getR(257.9, 355, 52.8, 135.3),
f: 1
}],
['l', 52.8, 135.3],
['b', 52.8, 135.3, -2.2, 79.5, 46.6, 26.7],
['b', 46.6, 26.7, 68.1, 0, 101.8, 0, {
r: ROTATE_VERTICAL
}],
['b', 137.2, 0, 174.1, 21.1, 181.2, 65.3],
['b', 188.6, 111.7, 142.6, 142.9, 108.9, 162.9],
['b', 75.2, 182.8, 40.8, 211.4, 40.8, 211.4, {
r: ROTATE_NONE
}],
['b', 35, 217.1, -34.7, 273.7, 22.2, 330.5],
['b', 22.2, 330.5, 48.1, 360, 93.4, 360, {
r: ROTATE_VERTICAL
}],
['b', 138.6, 360, 212.2, 322, 259.2, 200.5],
]
}]
),
'*': generateFontData(
558, 183.597, 212,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 91.8, 0, {
x: 0,
y: 0
}],
['l', 91.8, 212, {
x: 0,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 53, {
x: 0,
y: 0,
r: getR(0, 53, 183.6, 159)
}],
['l', 183.6, 159, {
x: 0,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 159, {
x: 0,
y: 0,
r: getR(0, 159, 183.6, 53)
}],
['l', 183.6, 53, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
'+': generateFontData(
712, 250, 250,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 125, 0, {
x: 0,
y: 0,
}],
['l', 125, 250, {
x: 0,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 125, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['l', 250, 125, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
'=': generateFontData(
712, 216, 86,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['l', 216, 0, {
x: 0,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 0, 86, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['l', 216, 86, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
'-': generateFontData(
712, 188, 0,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['l', 188, 0, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
'_': generateFontData(
481, 235, 400,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 400, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['l', 235, 400, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
':': generateFontData(
231, 8, 355,
0, 0, 0, 0,
[{
d: 1,
v: [
['a', 8 / 2, 355 - 1.5 - 170],
]
},
{
d: 1,
v: [
['a', 8 / 2, 355 - 1.5],
]
}
]
),
';': generateFontData(
231, 8, 355,
0, 0, 0, 0,
[{
d: 1,
v: [
['a', 8 / 2, 355 - 1.5 - 170],
]
}, {
d: -1,
v: [
['m', 8 / 2, 350, {
x: 0,
y: 2,
r: getR(8 / 2, 350, 8 / 2 - 10, 80 + 350)
}],
['l', 8 / 2 - 10, 80 + 350, {
x: 0,
y: 0.5,
f: 1
}],
]
}]
),
'.': generateFontData(
231, 8, 355,
0, 0, 0, 0,
[{
d: 1,
v: [
['a', 8 / 2, 355 - 1.5],
]
}]
),
',': generateFontData(
231, 10, 355,
10, 10, 0, 0,
[{
d: -1,
v: [
['m', 10, 350, {
x: 0,
y: 2,
r: getR(10, 350, 0, 80 + 350)
}],
['l', 0, 80 + 350, {
x: 0,
y: 0.5,
f: 1
}],
]
}]
),
"'": generateFontData(
173, 0, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
y: 0
}],
['l', 0, 80, {
x: 0,
y: 0,
f: 1
}],
]
}]
),
'"': generateFontData(
297, 60, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: -1.5,
y: 0
}],
['l', 0, 80, {
x: -1.5,
y: 0,
f: 1
}],
]
}, {
d: -1,
v: [
['m', 60, 0, {
x: -1.5,
y: 0
}],
['l', 60, 80, {
x: -1.5,
y: 0,
f: 1
}],
]
}]
),
'~': generateFontData(
731, 199.391, 47.063,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 199.4, 20.7, {
x: 0,
y: 0,
r: getCurveR(199.4, 20.7, 187.6, 36.6, 168.2, 47.1, 148.2, 47.1, 0),
f: 1
}],
['b', 187.6, 36.6, 168.2, 47.1, 148.2, 47.1, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['b', 129.1, 47.1, 112.1, 36.6, 95.3, 25.5, {
x: 0,
y: 0
}],
['b', 76.8, 13.2, 59.1, 0, 39.6, 0, {
x: 0,
y: 0,
r: ROTATE_VERTICAL
}],
['b', 22.3, 0, 10.9, 8.9, 0, 20, {
x: 0,
y: 0
}],
]
}]
),
'(': generateFontData(
365, 107.865, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 107.9, 360, {
y: 0.8,
r: getCurveR(107.9, 360, 39.7, 321.1, 0, 259.8, 0, 182.9, 0),
f: 1
}],
['b', 39.7, 321.1, 0, 259.8, 0, 182.9, {
y: 0.8,
r: ROTATE_HORIZONTAL
}],
['b', 0, 100.2, 39.7, 38.9, 107.9, 0, {
y: 0.8
}],
]
}]
),
')': generateFontData(
365, 107.865, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0.8,
r: getCurveR(0, 0, 68.2, 38.9, 107.9, 100.2, 107.9, 177, 0)
}],
['b', 68.2, 38.9, 107.9, 100.2, 107.9, 177, {
y: 0.8,
r: ROTATE_HORIZONTAL
}],
['b', 107.9, 259.8, 68.2, 321.1, 0, 360, {
y: 0.8,
f: 1
}],
]
}]
),
'{': generateFontData(
385, 107.865, 360,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 94.5, 360, {
x: -0.5,
r: ROTATE_VERTICAL
}],
['l', 77.9, 360, {
x: -0.5
}],
['b', 57.4, 360, 37, 343, 37, 310.7, {
x: -0.5
}],
['l', 37, 233.4, {
x: -0.5
}],
['b', 37, 207.9, 24.3, 183.7, 3.8, 180.7, {
x: -0.5,
r: ROTATE_VERTICAL
}],
['l', 3.8, 179.8, {
x: -0.5,
r: ROTATE_VERTICAL,
p: 1
}],
['b', 24.3, 176.8, 37, 153.1, 37, 126.7, {
x: -0.5
}],
['l', 37, 49.4, {
x: -0.5
}],
['b', 37, 17.1, 57.4, 0.1, 77.9, 0.1, {
x: -0.5
}],
['l', 94.5, 0.1, {
x: -0.5,
}],
]
}]
),
'}': generateFontData(
385, 107.865, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 13.4, 0.1, {
x: -0.5,
r: ROTATE_VERTICAL
}],
['l', 30, 0.1, {
x: -0.5
}],
['b', 50.4, 0.1, 70.8, 17.1, 70.8, 49.4, {
x: -0.5
}],
['l', 70.8, 126.7, {
x: -0.5
}],
['b', 70.8, 153.1, 83.6, 176.8, 104, 179.8, {
x: -0.5,
r: ROTATE_VERTICAL
}],
['l', 104, 180.7, {
x: -0.5,
r: ROTATE_VERTICAL,
p: 1
}],
['b', 83.6, 183.7, 70.8, 207.9, 70.8, 233.4, {
x: -0.5
}],
['l', 70.8, 310.7, {
x: -0.5
}],
['b', 70.8, 343, 50.4, 360, 30, 360, {
x: -0.5
}],
['l', 13.4, 360, {
x: -0.5
}],
]
}]
),
'[': generateFontData(
365, 66, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 66, 0, {
x: -1,
r: ROTATE_VERTICAL
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 66, 352, {
x: -1,
f: 1
}],
]
}]
),
']': generateFontData(
365, 66, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: -1,
r: ROTATE_VERTICAL
}],
['l', 66, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 66, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
x: -1,
f: 1
}],
]
}]
),
'<': generateFontData(
423, 90, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 90, 0, {
x: -1,
y: 0.3,
r: getR(90, 0, 0, 176)
}],
['l', 0, 176, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 90, 352, {
x: -1,
y: 0.3,
f: 1
}],
]
}]
),
'>': generateFontData(
423, 90, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: -1,
y: 0.3,
r: getR(0, 0, 90, 176)
}],
['l', 90, 176, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
x: -1,
y: 0.3,
f: 1
}],
]
}]
),
'/': generateFontData(
433, 130, 352,
0, 0, 0, 0,
[{
d: 1,
v: [
['m', 0, 352, {
r: getR(0, 352, 130, 0),
f: 1,
y: 0
}],
['l', 130, 0, {
y: 0
}]
]
}]
),
'þ': generateFontData(
600, 232, 338,
-10, -2, -117, -117,
[{
d: -1,
v: [
['m', 0, -106, {
y: 0
}],
['l', 0, 116, {
r: ROTATE_NONE
}],
['b', 0, 180.1, 51.9, 232, 116, 232, {
r: ROTATE_VERTICAL
}],
['b', 180.1, 232, 232, 180.1, 232, 116, {
r: ROTATE_HORIZONTAL
}],
['b', 232, 51.9, 180.1, 0, 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 51.9, 0, 0, 51.9, 0, 116, {
r: ROTATE_HORIZONTAL
}],
['l', 0, 338, {
y: 0,
f: 1
}],
]
}]
),
'Þ': generateFontData(
520, 162, 352,
-5, -70, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
y: 0,
r: ROTATE_HORIZONTAL,
}],
['l', 0, 352, {
x: 0,
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
},
{
d: 1,
v: [
['m', 0, 281.6, {
x: 0,
r: ROTATE_VERTICAL,
f: 1,
p: 1
}],
['l', 57, 281.6, {
x: -0.5,
r: ROTATE_VERTICAL,
f: 1
}],
['b', 115.0, 281.6, 162.0, 233.4, 162.0, 175.4, {
x: -0.5,
r: ROTATE_HORIZONTAL
}],
['b', 162.0, 117.4, 115.0, 70.4, 57.0, 70.4, {
x: -0.5,
r: ROTATE_VERTICAL
}],
['l', 0, 70.4, {
x: 0,
r: ROTATE_VERTICAL,
f: 1,
p: 1
}],
]
}
]
),
'ß': generateFontData(
596, 209, 352,
-10, -10, 0, 0,
[{
d: 1,
v: [
['m', 0.0, 348.3, {
r: ROTATE_HORIZONTAL,
f: 1,
x: 0,
y: 0
}],
['l', 0.0, 104.3, {
x: 0
}],
['b', 0.0, 46.0, 36.0, 0.0, 98.9, 0.0, {
x: 0
}],
['b', 145.2, 0.0, 191.0, 27.9, 191.0, 81.0, {
x: 1
}],
['b', 191.0, 110.7, 165.6, 131.8, 151.8, 140.9],
['l', 140.0, 148.8],
['b', 120.6, 161.7, 110.8, 172.8, 110.8, 185.5],
['b', 110.8, 206.7, 131.6, 213.8, 140.0, 217.5],
//['l', 163.7, 228.6],
['b', 190.6, 241.1, 211.0, 262.7, 211.0, 289.6],
['b', 211.0, 329.5, 174.8, 352.0, 142.5, 352.0],
['b', 97.3, 352.0, 75.2, 319.7, 72.3, 289.3],
]
}]
),
};
================================================
FILE: src/font/upper.js
================================================
import {
generateFontData,
ROTATE_HORIZONTAL,
ROTATE_VERTICAL,
VERTEX_GAP,
VERTEX_GAP2,
getR,
getCurveR
} from './util.js';
export const DATA_UA = [{
d: -1,
v: [
['m', 0, 352, {
x: 0.55,
y: 0.3,
r: getR(0, 352, 145 - VERTEX_GAP2, 0),
}],
['l', 145 - VERTEX_GAP2, 0, {
r: getR(0, 352, 145 - VERTEX_GAP2, 0),
f: 1
}],
['l', 145 + VERTEX_GAP2, 0, {
r: getR(290, 352, 145 + VERTEX_GAP2, 0),
f: 1,
v: 1
}],
['l', 290, 352, {
x: 0.55,
y: 0.3,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 47, 237, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 243, 237, {
r: ROTATE_VERTICAL,
p: 1,
f: 1,
}],
]
}
];
export const DATA_UC = [{
d: 1,
v: [
['m', 293.1, 320.1, {
r: getCurveR(293.1, 320.1, 262.2, 345, 222.8, 360, 180, 360, 0),
f: 1
}],
['b', 262.2, 345, 222.8, 360, 180, 360],
['b', 80.6, 360, 0, 279.4, 0, 180],
['b', 0, 80.6, 80.6, 0, 180, 0],
['b', 222.8, 0, 262.2, 15, 293.1, 39.9],
]
}];
export const DATA_UD = [{
d: -1,
v: [
['m', 95, 352, {
r: ROTATE_VERTICAL,
f: 1
}],
['b', 191.6, 352, 270, 271.6, 270, 175, {
r: ROTATE_HORIZONTAL
}],
['b', 270, 78.4, 191.6, 0, 95, 0, {
r: ROTATE_VERTICAL
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 95, 352, {
r: ROTATE_VERTICAL,
f: 1
}],
]
}];
export const DATA_UE = [{
d: -1,
v: [
['m', 192, 0, {
x: 0,
r: ROTATE_VERTICAL,
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1,
x: 0.5
}],
['l', 0, 352, {
f: 1,
x: 0.5
}],
['l', 192, 352, {
x: 0,
r: ROTATE_VERTICAL,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0, 164, {
r: ROTATE_VERTICAL,
p: 1,
x: 0.5
}],
['l', 180, 164, {
x: 0,
r: ROTATE_VERTICAL,
f: 1
}],
]
}
];
export const DATA_UG = [{
d: 1,
v: [
['m', 202, 180, {
r: ROTATE_VERTICAL,
f: 1
}],
['l', 352, 180, {
f: 1
}],
['b', 352, 279.4, 279.4, 360, 180, 360, {
r: ROTATE_VERTICAL
}],
['b', 80.6, 360, 0, 279.4, 0, 180, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 80.6, 80.6, 0, 180, 0, {
r: ROTATE_VERTICAL
}],
['b', 222.8, 0, 262.1, 14.9, 293, 39.9],
]
}];
export const DATA_UH = [{
d: -1,
v: [
['m', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 232, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 232, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 0, 164, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 232, 164, {
r: ROTATE_VERTICAL,
f: 1,
p: 1
}],
]
}
];
export const DATA_UI = [{
d: 1,
v: [
['m', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
]
}];
export const DATA_UJ = [{
d: 1,
v: [
['m', 0, 310.5 + 0.5, {
r: getCurveR(0, 310.5 + 0.5, 16.2, 341.1 + 0.5, 49.3, 355.5 + 0.5, 86, 355.5 + 0.5, 0),
f: 1
}],
['b', 16.2, 341.1 + 0.5, 49.3, 355.5 + 0.5, 86, 355.5 + 0.5, {
r: ROTATE_VERTICAL
}],
['b', 133.5, 355.5 + 0.5, 172, 317 + 0.5, 172, 269.5 + 0.5],
['l', 172.5, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
]
}];
export const DATA_UN = [{
d: -1,
v: [
['m', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0 + VERTEX_GAP, 0, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1,
v: 1
}],
['l', 250 - VERTEX_GAP, 351, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['l', 250, 351, {
r: ROTATE_HORIZONTAL,
f: 1,
v: 1
}],
['l', 250, 0, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
}];
export const DATA_UO = [{
d: 1,
v: [
['m', 360, 180, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['b', 360, 279.4, 279.4, 360, 180, 360, {
r: ROTATE_VERTICAL
}],
['b', 80.6, 360, 0, 279.4, 0, 180, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 80.6, 80.6, 0, 180, 0, {
r: ROTATE_VERTICAL
}],
['b', 279.4, 0, 360, 80.6, 360, 180, {
r: ROTATE_HORIZONTAL,
c: 1
}],
]
}];
export const DATA_US = [{
d: 1,
v: [
['m', 0, 295.4, {
r: getCurveR(0, 295.4, 17.6, 332.1, 58.3, 360, 110.3, 360, 0),
f: 1
}],
['b', 17.6, 332.1, 58.3, 360, 110.3, 360],
['b', 173.9, 360, 223.8, 329.6, 224, 271],
['b', 224.2, 214.7, 180.7, 189.6, 112.4, 173.3],
['b', 47.3, 157.7, 10.9, 130.6, 12, 84.4],
['b', 13.3, 29.8, 57.3, 0, 114.8, 0],
['b', 158.4, 0, 196.5, 20.5, 212, 51.3],
]
}];
export const DATA_UU = [{
d: 1,
v: [
['m', 250, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 250, 230 + 1, {
r: ROTATE_HORIZONTAL
}],
['b', 250, 299 + 1, 194, 355 + 1, 125, 355 + 1, {
r: ROTATE_VERTICAL
}],
['b', 56, 355 + 1, 0, 299 + 1, 0, 230 + 1, {
r: ROTATE_HORIZONTAL
}],
['l', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
]
}];
export const DATA_UY = [{
d: -1,
v: [
['m', 0, 0, {
x: 0.6,
y: 0.3,
r: getR(0, 0, 135, 186),
}],
['l', 135, 186, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 270, 0, {
x: 0.6,
y: 0.3,
f: 1
}]
]
},
{
d: -1,
v: [
['m', 135, 186, {
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 135, 352, {
y: 0,
f: 1
}],
]
}
];
export const UPPER = {
'A': generateFontData(
620, 290, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UA))
),
'B': generateFontData(
596, 209, 352,
-10, -10, 0, 0,
[{
d: 1,
v: [
['m', 0, 164, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 116, 164, {
r: ROTATE_VERTICAL,
p: 1,
f: 1
}],
['b', 167.4, 164, 209, 205.6, 209, 257, {
r: ROTATE_HORIZONTAL
}],
['b', 209, 308.4, 167.4, 352, 116, 352, {
r: ROTATE_VERTICAL
}],
['l', 0, 352, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 116, 0, {
r: ROTATE_VERTICAL
}],
['b', 161.3, 0, 198, 36.7, 198, 82, {
r: ROTATE_HORIZONTAL
}],
['b', 198, 127.3, 161.3, 164, 116, 164, {
r: ROTATE_VERTICAL
}]
]
}]
),
'C': generateFontData(
700, 293.1, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UC))
),
'D': generateFontData(
721, 270, 352,
-10, -10, 0, 0,
JSON.parse(JSON.stringify(DATA_UD))
),
'E': generateFontData(
520, 192, 352,
-5, -80, 0, 0,
JSON.parse(JSON.stringify(DATA_UE))
),
'F': generateFontData(
510, 192, 352,
-5, -80, 0, 0,
[{
d: -1,
v: [
['m', 192, 0, {
x: 0,
r: ROTATE_VERTICAL,
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1,
x: 0.5
}],
['l', 0, 352, {
y: 0,
f: 1,
x: 0.5
}],
]
},
{
d: -1,
v: [
['m', 0, 164, {
r: ROTATE_VERTICAL,
p: 1,
x: 0.5
}],
['l', 180, 164, {
x: 0,
r: ROTATE_VERTICAL,
f: 1
}],
]
}
]
),
'G': generateFontData(
840, 352, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UG))
),
'H': generateFontData(
684, 232, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UH))
),
'I': generateFontData(
249, 0, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UI))
),
'J': generateFontData(
472, 172.5, 355.5,
10, 20, -2, -2,
JSON.parse(JSON.stringify(DATA_UJ))
),
'K': generateFontData(
616, 232, 352,
-10, -20, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 212, 0, {
x: 0.7,
y: 0.7,
r: getR(212, 0, 0, 164 - VERTEX_GAP2),
}],
['l', 0, 164 - VERTEX_GAP2, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 0, 164 + VERTEX_GAP2, {
r: ROTATE_VERTICAL,
p: 1,
v: 1
}],
['l', 232, 352, {
x: 0.7,
y: 0.7,
f: 1
}],
]
}
]
),
'L': generateFontData(
529, 192, 352,
-10, -20, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
y: 0
}],
['l', 0, 352, {
f: 1
}],
['l', 192, 352, {
x: 0,
f: 1
}],
]
}]
),
'M': generateFontData(
885, 330, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 352, {
y: 0,
r: ROTATE_HORIZONTAL
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0 + VERTEX_GAP, 0, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1,
v: 1
}],
['l', 165 - VERTEX_GAP2, 330, {
r: getR(165 - VERTEX_GAP2, 330, 165 - VERTEX_GAP2, 330),
f: 1
}],
['l', 165 + VERTEX_GAP2, 330, {
r: getR(165 + VERTEX_GAP2, 330, 330 - VERTEX_GAP, 0),
f: 1,
v: 1
}],
['l', 330 - VERTEX_GAP, 0, {
r: ROTATE_HORIZONTAL,
p: 1,
f: 1
}],
['l', 330, 0, {
r: ROTATE_HORIZONTAL,
f: 1,
v: 1
}],
['l', 330, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
}]
),
'N': generateFontData(
721, 250, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UN))
),
'O': generateFontData(
850, 360, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UO))
),
'P': generateFontData(
568, 210, 352,
-10, -10, -0.5, -0.5,
[{
d: 1,
v: [
['m', 0, 352, {
y: 0,
f: 1
}],
['l', 0, 0, {
f: 1
}],
['l', 117, 0, {
r: ROTATE_VERTICAL
}],
['b', 168.4, 0, 210, 41.6, 210, 93, {
r: ROTATE_HORIZONTAL
}],
['b', 210, 144.4, 168.4, 186, 117, 186, {
r: ROTATE_VERTICAL
}],
['l', 0, 186, {
r: ROTATE_VERTICAL,
p: 1
}],
]
}]
),
'Q': generateFontData(
850, 360, 360,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 360, 180, {
r: ROTATE_VERTICAL,
p: 1,
f: 1
}],
['b', 360, 80.6, 279.4, 0, 180, 0, {
r: ROTATE_VERTICAL
}],
['b', 80.6, 0, 0, 80.6, 0, 180, {
r: ROTATE_HORIZONTAL
}],
['b', 0, 279.4, 80.6, 360, 180, 360, {
r: ROTATE_VERTICAL
}],
['b', 279.4, 360, 360, 279.4, 360, 180, {
r: ROTATE_HORIZONTAL,
c: 1,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 222, 222, {
x: 0.5,
y: 0.5,
r: getR(222, 222, 360, 360),
}],
['l', 360, 360, {
x: 0.5,
y: 0.5,
f: 1
}]
]
}
]
),
'R': generateFontData(
634, 232, 352,
-10, -10, -0.5, -0.5,
[{
d: -1,
v: [
['m', 0, 186, {
r: ROTATE_VERTICAL,
p: 1
}],
['l', 139, 186, {
r: ROTATE_VERTICAL
}],
['b', 190.4, 186, 232, 144.4, 232, 93, {
r: ROTATE_HORIZONTAL
}],
['b', 232, 41.6, 190.4, 0, 139, 0, {
r: ROTATE_VERTICAL
}],
['l', 0, 0, {
r: ROTATE_HORIZONTAL,
f: 1
}],
['l', 0, 352, {
y: 0,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 139, 186, {
p: 1,
r: getR(139, 186, 232, 352),
}],
['l', 232, 352, {
x: 0.5,
y: 0.39,
f: 1
}],
]
}
]
),
'S': generateFontData(
560, 224, 360,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_US))
),
'T': generateFontData(
568, 232, 352,
0, 0, -0.5, -0.5,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 232, 0, {
x: 0,
r: ROTATE_VERTICAL,
f: 1
}],
]
},
{
d: -1,
v: [
['m', 116, 0, {
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 116, 352, {
y: 0,
r: ROTATE_HORIZONTAL,
f: 1
}],
]
}
]
),
'U': generateFontData(
712, 250, 355,
0, 0, -0.5, -0.5,
JSON.parse(JSON.stringify(DATA_UU))
),
'V': generateFontData(
650, 270, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0.6,
y: 0.1,
r: getR(0, 0, 135 - VERTEX_GAP2, 352),
}],
['l', 135 - VERTEX_GAP2, 352, {
r: getR(0, 0, 135 - VERTEX_GAP2, 352),
f: 1
}],
['l', 135 + VERTEX_GAP2, 352, {
r: getR(135 + VERTEX_GAP2, 352, 270, 0),
f: 1,
v: 1
}],
['l', 270, 0, {
x: 0.6,
y: 0.1,
f: 1
}],
]
}]
),
'W': generateFontData(
894, 390, 352,
0, 0, 0, 0,
[{
d: -1,
v: [
['m', 0, 0, {
x: 0.6,
y: 0.05,
r: getR(0, 0, 86 - VERTEX_GAP2, 352),
}],
['l', 86 - VERTEX_GAP2, 352, {
r: getR(0, 0, 86 - VERTEX_GAP2, 352),
f: 1
}],
['l', 86 + VERTEX_GAP2, 352, {
r: getR(86 + VERTEX_GAP2, 352, 195 - VERTEX_GAP2, 0),
f: 1,
v: 1
}],
['l', 195 - VERTEX_GAP2, 0, {
r: getR(86 + VERTEX_GAP2, 352, 195 - VERTEX_GAP2, 0),
f: 1
}],
['l', 195 + VERTEX_GAP2, 0, {
r: getR(195 + VERTEX_GAP2, 0, 304 - VERTEX_GAP2, 352),
f: 1,
v: 1
}],
['l', 304 - VERTEX_GAP2, 352, {
r: getR(195 + VERTEX_GAP2, 0, 304 - VERTEX_GAP2, 352),
f: 1
}],
['l', 304 + VERTEX_GAP2, 352, {
r: getR(304 + VERTEX_GAP2, 352, 390, 0),
f: 1,
v: 1
}],
['l', 390, 0, {
x: 0.6,
y: 0.05,
f: 1
}],
]
}]
),
'X': generateFontData(
660, 270, 352,
0, 0, 0, -7,
[{
d: -1,
v: [
['m', 10, 0, {
x: 0.5,
y: 0.3,
r: getR(10, 0, 270, 352),
}],
['l', 270, 352, {
x: 0.5,
y: 0.5,
f: 1
}]
]
},
{
d: -1,
v: [
['m', 260, 0, {
x: 0.5,
y: 0.3,
r: getR(260, 0, 0, 352),
}],
['l', 0, 352, {
x: 0.5,
y: 0.5,
f: 1
}]
]
}
]
),
'Y': generateFontData(
673, 270, 352,
0, 0, 0, 0,
JSON.parse(JSON.stringify(DATA_UY))
),
'Z': generateFontData(
558, 232, 352,
0, -5, 0, 0,
[{
d: -1,
v: [
['m', 8, 0, {
x: 0,
r: ROTATE_VERTICAL
}],
['l', 224, 0, {
r: ROTATE_VERTICAL,
f: 1
}],
['l', 224, 0 + VERTEX_GAP, {
r: ROTATE_HORIZONTAL,
p: 1,
v: 1
}],
['l', 0, 352 - VERTEX_GAP, {
r: ROTATE_HORIZONTAL,
p: 1
}],
['l', 0, 352, {
r: ROTATE_VERTICAL,
f: 1,
v: 1
}],
['l', 232, 352, {
x: 0,
r: ROTATE_VERTICAL,
f: 1
}]
]
}]
)
};
================================================
FILE: src/font/util.js
================================================
import {
Vector
} from '../core/vector.js';
import {
bezierTangent
} from '../core/paths.js';
export const ROTATE_HORIZONTAL = 180 * (Math.PI / 180);
export const ROTATE_VERTICAL = 90 * (Math.PI / 180);
export const ROTATE_NONE = -100;
export const VERTEX_GAP = 3;
export const VERTEX_GAP2 = VERTEX_GAP / 2;
export const TOFU = 'tofu';
const FONT_HEIGHT = 824;
export function generateFontData(w, fw, fh, x1, x2, y1, y2, path) {
const arr = [];
const total = path.length;
let i;
for (i = 0; i < total; i++) {
arr.push({
d: path[i].d,
v: setCenter(path[i].v, fw, fh)
});
}
return {
rect: {
w: w,
h: FONT_HEIGHT,
fw: fw,
fh: fh
},
ratio: {
x1: x1,
x2: x2,
y1: y1,
y2: y2,
},
p: arr,
clone: () => {
const arr2 = [];
for (let i = 0; i < arr.length; i++) {
arr2[i] = {
d: arr[i].d,
v: arr[i].v
};
}
const v = {
rect: {
w: w,
h: FONT_HEIGHT,
fw: fw,
fh: fh
},
ratio: {
x1: x1,
x2: x2,
y1: y1,
y2: y2,
},
p: arr2,
};
return v;
}
};
}
function setCenter(arr, fw, fh) {
const total = arr.length;
const cx = fw / 2;
const cy = fh / 2;
let mp, i, ct = [];
for (i = 0; i < total; i++) {
mp = arr[i];
mp[1] -= cx;
mp[2] -= cy;
if (mp[0] == 'b') {
mp[3] -= cx;
mp[4] -= cy;
mp[5] -= cx;
mp[6] -= cy;
}
ct.push(new Vector(mp));
}
return ct;
}
export function getR(x1, y1, x2, y2) {
const x = x1 - x2;
const y = y1 - y2;
return -Math.atan2(x, y);
}
export function getCurveR(x1, y1, x2, y2, x3, y3, x4, y4, t) {
const x = bezierTangent(x1, x2, x3, x4, t);
const y = bezierTangent(y1, y2, y3, y4, t);
return -Math.atan2(x, y);
}
================================================
FILE: src/index.js
================================================
const LeonSans = require('./leonsans').default;
module.exports = LeonSans;
================================================
FILE: src/leonsans.js
================================================
/*!
* VERSION: 1.6.3
* DATE: 2019-09-13
* https://leon-sans.com
*
* @license Copyright (c) 2019, Jongmin Kim. All rights reserved.
**/
import {
Dispatcher
} from './core/dispatcher.js';
import {
MIN_FONT_WEIGHT,
MAX_FONT_WEIGHT,
shuffle
} from './core/util.js';
import {
Lines
} from './draw/canvas/lines.js';
import {
Points
} from './draw/canvas/points.js';
import {
Grids
} from './draw/canvas/grids.js';
import {
Wave
} from './draw/canvas/wave.js';
import {
Pattern
} from './draw/canvas/pattern.js';
import {
Color
} from './draw/canvas/color.js';
import {
Colorful
} from './draw/canvas/colorful.js';
import {
PixiLines
} from './draw/pixi/lines.js';
import {
PixiColor
} from './draw/pixi/color.js';
import {
Model
} from './core/model.js';
export default class LeonSans extends Dispatcher {
constructor({
text = '',
size = 500,
weight = MIN_FONT_WEIGHT,
color = ['#000000'],
colorful = ['#c5d73f', '#9d529c', '#49a9db', '#fec330', '#5eb96e', '#fc5356', '#f38f31'],
tracking = 0,
leading = 0,
align = 'left',
pathGap = 0.5,
amplitude = 0.5,
width = 0,
breakWord = false,
fps = 30,
isPath = false,
isWave = false,
} = {}) {
super();
this.size_ = size;
this.weight_ = weight;
this.color_ = color;
this.colorful_ = shuffle(colorful);
this.tracking_ = tracking;
this.leading_ = leading;
this.pathGap_ = pathGap;
this.amplitude_ = amplitude;
this.width_ = width;
this.breakWord_ = breakWord;
this.fps_ = fps;
this.fpsTime_ = 1000 / this.fps_;
this.isPath_ = isPath;
this.isWave_ = isWave;
this.model = new Model();
this.str_ = null;
this.time_ = null;
this.isFps_ = false;
this.isForceRander_ = false;
this.updateID_ = 0;
this.dPathsID_ = null;
this.pPathsID_ = null;
this.wPathsID_ = null;
this.guideID_ = null;
this.text = text;
this.model.align = align;
}
on(event, callback) {
super.on(event, callback);
this.update();
}
off(event, callback) {
super.off(event, callback);
}
get text() {
return this.str_;
}
set text(str) {
if (this.str_ == str) return;
this.str_ = str;
this.update();
}
get size() {
return this.size_;
}
set size(v) {
if (this.size_ == v) return;
this.size_ = v;
this.update();
this.isForceRander_ = true;
}
get weight() {
return this.weight_;
}
set weight(v) {
if (v < MIN_FONT_WEIGHT) {
v = MIN_FONT_WEIGHT;
} else if (v > MAX_FONT_WEIGHT) {
v = MAX_FONT_WEIGHT;
}
if (this.weight_ == v) return;
this.weight_ = v;
this.update();
this.isForceRander_ = true;
}
get color() {
return this.color_;
}
set color(v) {
if (this.color_ == v) return;
this.color_ = v;
}
get tracking() {
return this.tracking_;
}
set tracking(v) {
if (this.tracking_ == v) return;
this.tracking_ = v;
this.update();
this.isForceRander_ = true;
}
get leading() {
return this.leading_;
}
set leading(v) {
if (this.leading_ == v) return;
this.leading_ = v;
this.update();
this.isForceRander_ = true;
}
get align() {
return this.model.align;
}
set align(v) {
if (this.model.align != v) {
this.model.align = v;
this.updateID_++;
this.updateSignal();
}
}
get pathGap() {
return this.pathGap_;
}
set pathGap(v) {
if (this.pathGap_ != v) {
this.pathGap_ = v;
this.updatePatternPaths(true);
this.updateWavePaths(true);
this.isForceRander_ = true;
}
}
get amplitude() {
return this.amplitude_;
}
set amplitude(v) {
this.amplitude_ = v;
}
get rect() {
return this.model.rect;
}
set maxWidth(v) {
if (this.width_ == v) return;
this.width_ = v;
this.update();
}
get maxWidth() {
return this.width_;
}
set breakWord(v) {
if (this.breakWord_ == v) return;
this.breakWord_ = v;
this.update();
}
get breakWord() {
return this.breakWord_;
}
get isPath() {
return this.isPath_;
}
set isPath(v) {
this.isPath_ = v;
this.updatePatternPaths(true);
}
get isWave() {
return this.isWave_;
}
set isWave(v) {
this.isWave_ = v;
this.updateWavePaths(true);
}
get fps() {
return this.fps_;
}
set fps(v) {
this.fps_ = v;
this.fpsTime_ = 1000 / this.fps_;
}
get lineWidth() {
return this.model.lineWidth;
}
get scale() {
return this.model.scale;
}
get drawing() {
return this.model.drawing;
}
get data() {
return this.model.data;
}
get paths() {
return this.model.paths;
}
get drawingPaths() {
return this.model.drawingPaths;
}
get wavePaths() {
return this.model.wavePaths;
}
position(x = 0, y = 0) {
if (this.model.position(x, y)) {
this.updateID_++;
this.updateSignal();
}
}
update() {
this.updateID_++;
this.model.update(
this.str_,
this.width_,
this.breakWord_,
this.weight_,
this.size_,
this.tracking_,
this.leading_
);
if (this.isPath_ || this.isWave_) {
this.updatePatternPaths();
this.updateWavePaths();
} else {
this.updateSignal();
}
}
updateGuide() {
if (this.guideID_ != this.updateID_) {
this.guideID_ = this.updateID_;
this.model.updateGuide();
}
}
/**
* Update paths for drawing in WebGL (PIXI.js). It's very expensive, only call when it needs.
*/
updateDrawingPaths() {
if (this.dPathsID_ != this.updateID_) {
this.dPathsID_ = this.updateID_;
this.model.updateDrawingPaths();
}
}
/**
* Update paths for pattern
* @param {boolean} force - Force execution
*/
updatePatternPaths(force) {
if (this.isPath_ && (force || this.pPathsID_ != this.updateID_)) {
this.pPathsID_ = this.updateID_;
this.model.updatePatternPaths(this.pathGap_);
this.isForceRander_ = true;
this.updateSignal();
}
}
/**
* Update paths for wave effect
* @param {boolean} force - Force execution
*/
updateWavePaths(force) {
if (this.isWave_ && (force || this.wPathsID_ != this.updateID_)) {
this.wPathsID_ = this.updateID_;
this.model.updateWavePaths(this.pathGap_);
this.isForceRander_ = true;
this.updateSignal();
}
}
updateSignal() {
this.model.updateLinesForRect();
this.model.updatePathsForRect();
this.dispatch('update', this.model);
}
reset() {
this.size_ = 500;
this.weight_ = MIN_FONT_WEIGHT;
this.color_ = ['#000000'];
this.tracking_ = 0;
this.leading_ = 0;
this.pathGap_ = 0.5;
this.amplitude_ = 0.5;
this.width_ = 0;
this.breakWord_ = false;
this.fps_ = 30;
this.fpsTime_ = 1000 / this.fps_;
this.isPath_ = false;
this.isWave_ = false;
this.str_ = null;
this.time_ = null;
this.isFps_ = false;
this.isForceRander_ = false;
this.updateID_ = 0;
this.dPathsID_ = null;
this.pPathsID_ = null;
this.wPathsID_ = null;
this.guideID_ = null;
this.model.reset();
}
dispose() {
this.reset();
this.model = null;
}
/**
* Draw text in WebGL with PIXI.js
* @param {PIXI.Graphics} graphics
*/
drawPixi(graphics) {
const total = this.model.data.length;
let i, d, color;
for (i = 0; i < total; i++) {
d = this.model.data[i];
color = PixiColor(i, d, this.color_);
PixiLines(graphics, d, this.lineWidth, color);
}
}
/**
* Draw text in the Canvas element.
* @param {CanvasRenderingContext2D} ctx
*/
draw(ctx) {
ctx.lineWidth = this.lineWidth;
const total = this.model.data.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.model.data[i];
Color(ctx, i, d, this.color_);
Lines(ctx, d);
}
}
/**
* Draw the colorful effect.
* @param {CanvasRenderingContext2D} ctx
*/
drawColorful(ctx) {
ctx.lineWidth = this.lineWidth;
Colorful(ctx, this.model, this.colorful_);
}
/**
* Draw the wave effect.
* @param {CanvasRenderingContext2D} ctx
* @param {DOMHighResTimeStamp} t time stemp from requestAnimationFrame()
*/
wave(ctx, t) {
ctx.lineWidth = this.lineWidth;
if (t) {
if (!this.time_) this.time_ = t;
const p = t - this.time_;
if (p > this.fpsTime_ || this.isForceRander_) {
this.time_ = t;
this.isFps_ = true;
} else {
this.isFps_ = false;
}
}
this.isForceRander_ = false;
const total = this.model.data.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.model.data[i];
Color(ctx, i, d, this.color_);
Wave(ctx, d, this.model.scale, this.amplitude_, this.weight_, this.isFps_);
}
}
/**
* Draw rectangle shapes at each path point.
* @param {CanvasRenderingContext2D} ctx
* @param {number} w pattern width
* @param {number} h pattern height
*/
pattern(ctx, w, h) {
const tw = w * this.model.scale;
const th = h * this.model.scale;
const total = this.model.data.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.model.data[i];
Pattern(ctx, d, tw, th);
}
}
/**
* Draw grid for each type.
* @param {CanvasRenderingContext2D} ctx
*/
grid(ctx) {
this.updateGuide();
const total = this.model.data.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.model.data[i];
Grids(ctx, d);
}
}
/**
* Draw circles at each drawing point and lines for each type.
* @param {CanvasRenderingContext2D} ctx
*/
point(ctx) {
const total = this.model.data.length;
let i, d;
for (i = 0; i < total; i++) {
d = this.model.data[i];
Points(ctx, d);
}
}
/**
* Draw outline box for the text.
* @param {CanvasRenderingContext2D} ctx
* @private
*/
box(ctx) {
ctx.lineWidth = 1;
ctx.beginPath();
ctx.strokeStyle = "#0b90dc";
ctx.rect(this.model.rect.x, this.model.rect.y, this.model.rect.w, this.model.rect.h);
ctx.stroke();
}
}