Massively improved building stability; improved shapes of /eta.

This commit is contained in:
be5invis 2015-11-26 07:30:41 +08:00
parent 5115586fac
commit 50fdae2c96
16 changed files with 95 additions and 109 deletions

View File

@ -21,7 +21,7 @@ Quit your editor/program. Unzip and open the folder.
To build Iosevka you should:
1. Ensure that `node`, `FontForge`, `ttfautohint`, `ttx` and `make` are runnable in your terminal.
2. Install the newest `patel-c` (≥ 0.21.0) by `npm install patel -g`
2. Install the newest `patel-c` (≥ 0.25.0) by `npm install patel -g`
3. Install necessary libs by `npm install`
4. `make`.

View File

@ -1,12 +1,8 @@
define Glyph [require './support/glyph'].Glyph
define Stroke [require './support/stroke'].Stroke
define tp [require './support/transform'].transformPoint
define utp [require './support/transform'].untransform
define inverse [require './support/transform'].inverse
define unorm [require 'unorm']
define spirokit [require './support/spirokit']
import './support/glyph' as Glyph
import './support/stroke' as Stroke
import './support/spirokit' as spirokit
import './support/transform' as [object [transformPoint tp] [untransform utp] inverse]
import 'unorm' as unorm
### File inclusion macro
define-macro $$include : syntax-rules
@ -101,7 +97,7 @@ define [tagged tag fn] : lambda [] : begin
set this.defaultTag _tag
return nothing
define [buildFont para recursive] : begin
export as build : define [buildFont para recursive recursiveCodes] : begin
define variantSelector para.variantSelector
define font this
@ -426,7 +422,4 @@ define [buildFont para recursive] : begin
$$include 'glyphs/autobuilds.patel'
set font.glyfMap glyphs
return font
exports.build = buildFont
return font

View File

@ -3,7 +3,7 @@ var TTFWriter = require('node-sfnt').TTFWriter;
var TTF = require('node-sfnt').TTF;
var argv = require('yargs').argv;
var Glyph = require('./support/glyph').Glyph;
var Glyph = require('./support/glyph');
function toBuffer(arrayBuffer) {
var length = arrayBuffer.byteLength;

View File

@ -116,6 +116,8 @@ define customDecompositions {
."\u21AE" ""
}
define iotaBelowToLF : function [p] : if (p === glyphs.iotaBelow) glyphs.iotaLF p
define ogonekBelowToTR : function [p] : if (p === glyphs.ogonekBelow) glyphs.ogonekTR p
define [subParts parts] : begin
local hasMarkAbove false
foreach p [items-of parts] : if [isAboveMark p] : set hasMarkAbove true
@ -125,8 +127,8 @@ define [subParts parts] : begin
if (parts.0 === glyphs.j && hasMarkAbove) : parts.0 = glyphs.dotlessj
# replace below marks with trailing marks
if parts.0.anchors.lf : set parts : parts.map : function [p] : if (p === glyphs.iotaBelow) glyphs.iotaLF p
if parts.0.anchors.trailing : set parts : parts.map : function [p] : if (p === glyphs.ogonekBelow) glyphs.ogonekTR p
if parts.0.anchors.lf : set parts : parts.map iotaBelowToLF
if parts.0.anchors.trailing : set parts : parts.map ogonekBelowToTR
# composite greek overmarks
for [local j 0] (j < parts.length) [inc j] : piecewise
@ -153,7 +155,7 @@ define [pad s n] : begin
return s
set font.features.ccmp {}
#set font.features.ccmp {}
define [shorter x y] : if (x.length < y.length) x y
define [decideName namingParts parts code] : begin
local baseName namingParts.0.name
@ -168,32 +170,42 @@ define [decideName namingParts parts code] : begin
let : begin
local nComposed 0
foreach code [range 0x0000 0xFFFF] : if [not unicodeGlyphs.(code)] : begin
local foundDecompositions {}
local itsName : [part] -> part.name
local [buildForCode code] : if [not unicodeGlyphs.(code)] : begin
local str : String.fromCharCode code
local nfd : fallback customDecompositions.(str) : unorm.nfd str
if (nfd.length > 1) : begin
local parts {}
local allFound true
foreach j [range 0 nfd.length] : begin
set parts.(j) unicodeGlyphs.([nfd.charCodeAt j])
if [not parts.(j)] : set allFound false
local part unicodeGlyphs.([nfd.charCodeAt j])
if [not part] : then : set allFound false
: else : set parts.(j) unicodeGlyphs.([nfd.charCodeAt j])
if allFound : begin
local namingParts : parts.slice 0
set parts : subParts parts
local composition : namingParts.map ([part] -> part.name) :.join ' '
# local composition : namingParts.map itsName :.join ' '
local glyphName : decideName namingParts parts code
create-glyph glyphName : glyph-construction
assign-unicode code
include parts.0 AS_BASE
set-width parts.0.advanceWidth
foreach part [items-of : parts.slice 1] : begin
include part
# eject right-bottom serifs
if (part.name === 'rtailBR') : eject-contour 'serifRB'
if [not glyphs.(composition)] : begin
font.features.ccmp.push : 'sub ' + composition + ' by ' + glyphName
set glyphs.(composition) glyphs.(glyphName)
foundDecompositions.push {glyphName code parts}
inc nComposed
if recursiveCodes : recursiveCodes.forEach buildForCode
: else : foreach code [range 0x0000 0xFFFF] : buildForCode code
define construction : glyph-construction
assign-unicode code
include parts.0 AS_BASE
set-width parts.0.advanceWidth
foreach part [items-of : parts.slice 1] : begin
include part
# eject right-bottom serifs
if (part.name === 'rtailBR') : eject-contour 'serifRB'
# if [not glyphs.(composition)] : begin
# font.features.ccmp.push : 'sub ' + composition + ' by ' + glyphName
# set glyphs.(composition) glyphs.(glyphName)
foreach [{glyphName code parts} : items-of foundDecompositions] : begin
create-glyph glyphName construction
progress "Precomposed (\(nComposed) glyphs)"

View File

@ -381,13 +381,15 @@ define [WaveShape l r cy extendy tension sw] : glyph-construction
g4 r (cy + endwavey)
# Derived subfonts
define [Fork glyphs params] : begin
define [Fork gs params] : begin
local p : Object.create params
local shouldBuildList {}
foreach glyphid [items-of glyphs] : set shouldBuildList : shouldBuildList.concat {glyphid :: dependencyProfile.(glyphid)}
foreach glyphid [items-of gs] : set shouldBuildList : shouldBuildList.concat {glyphid :: dependencyProfile.(glyphid)}
set shouldBuildList : shouldBuildList.filter : [x] -> [not [not x]]
local shouldBuildUnicodes : shouldBuildList.map ([x] -> [if (glyphs.(x) && glyphs.(x).unicode) glyphs.(x).unicode.0 nothing])
:.filter ([x] -> [not [not x]])
try : begin
local forkFont : buildFont.call [TempFont] p shouldBuildList
local forkFont : buildFont.call [TempFont] p shouldBuildList shouldBuildUnicodes
: ex
: begin
if ex.glyfMap : return ex.glyfMap

View File

@ -255,7 +255,7 @@ create-glyph 'eta' : glyph-construction
include pMarks
set-anchor 'lf' BASE (SB + HALFSTROKE) 0
include : nShoulder (SB + STROKE * CORRECTION_HX) RIGHTSB (STROKE * 0.3) XH DESCENDER SMALLSMOOTHA SMALLSMOOTHB
include : nShoulder (SB + STROKE * CORRECTION_HX) RIGHTSB SHOULDERFINE XH DESCENDER SMALLSMOOTHA SMALLSMOOTHB
include : VBarLeft SB 0 XH
if SLAB : begin
include : LeftwardTopSerif SB XH SIDEJUT

View File

@ -379,7 +379,7 @@ create-glyph 'Eng' : glyph-construction
assign-unicode 0x14A
include capitalMarks
include : nShoulder (SB + STROKE) RIGHTSB (STROKE * 0.3) CAP (HOOK + HALFSTROKE + O) SMOOTHA SMOOTHB
include : nShoulder (SB + STROKE) RIGHTSB SHOULDERFINE CAP (HOOK + HALFSTROKE + O) SMOOTHA SMOOTHB
include : VerticalHook (RIGHTSB - HALFSTROKE * CORRECTION_HX) (HOOK + HALFSTROKE + O) [Math.max ((SB - RIGHTSB) / 2 + HALFSTROKE) (-HOOKX)] HOOK
include : VBar (SB + HALFSTROKE * CORRECTION_HX) 0 CAP
@ -741,7 +741,7 @@ create-glyph 'latinEta' : glyph-construction
include ifMarks
set-anchor 'lf' BASE (SB + HALFSTROKE) 0
include : nShoulder (SB + STROKE) RIGHTSB (STROKE * 0.3) CAP DESCENDER SMALLSMOOTHA SMALLSMOOTHB
include : nShoulder (SB + STROKE) RIGHTSB SHOULDERFINE CAP DESCENDER SMALLSMOOTHA SMALLSMOOTHB
include : VBar (SB + HALFSTROKE * CORRECTION_HX) 0 CAP
if SLAB : begin
include : LeftwardTopSerif SB CAP SIDEJUT
@ -758,7 +758,7 @@ create-glyph 'latineta' : glyph-construction
include pMarks
set-anchor 'lf' BASE (SB + HALFSTROKE) 0
include : nShoulder (SB + STROKE * CORRECTION_HX) RIGHTSB (STROKE * 0.3) XH DESCENDER SMALLSMOOTHA SMALLSMOOTHB
include : nShoulder (SB + STROKE * CORRECTION_HX) RIGHTSB SHOULDERFINE XH DESCENDER SMALLSMOOTHA SMALLSMOOTHB
include : VBarLeft SB 0 XH
if SLAB : begin
include : LeftwardTopSerif SB XH SIDEJUT

View File

@ -117,6 +117,7 @@ create-glyph 'tildeAbove' : glyph-construction
:.set-width markHalfStroke markHalfStroke
:.cubic-to [mix leftEnd rightEnd tildeWaveX] [mix bot top tildeWave] [mix leftEnd rightEnd (1 - tildeWaveX)] [mix bot top (1 - tildeWave)] rightEnd [mix tbot ttop (1 - tildeWaveEnd)]
:.set-samples 11
:.to-outline
include s

View File

@ -1,14 +1,20 @@
SUPPORT_FILES = support/glyph.js support/stroke.js support/spiroexpand.js support/spirokit.js parameters.js extract.js generate.js emptyfont.toml parameters.toml
SUPPORT_FILES_FROM_PATEL = support/glyph.js support/stroke.js support/spiroexpand.js support/spirokit.js parameters.js
SUPPORT_FILES = $(SUPPORT_FILES_FROM_PATEL) support/glyph.js support/stroke.js support/spiroexpand.js support/spirokit.js parameters.js extract.js generate.js emptyfont.toml parameters.toml
GLYPH_SEGMENTS = glyphs/common-shapes.patel glyphs/overmarks.patel glyphs/latin-basic-capital.patel glyphs/latin-basic-lower.patel glyphs/greek.patel glyphs/cyrillic-basic.patel glyphs/latin-extend-basis.patel glyphs/latin-extend-decorated.patel glyphs/cyrillic-extended.patel glyphs/numbers.patel glyphs/symbol-punctuation.patel glyphs/symbol-math.patel glyphs/symbol-geometric.patel glyphs/symbol-other.patel glyphs/symbol-letter.patel glyphs/autobuilds.patel
SCRIPTS = $(SUPPORT_FILES) buildglyphs.js
SCRIPTS_FROM_PATEL = $(SUPPORT_FILES_FROM_PATEL) buildglyphs.js
buildglyphs.js : buildglyphs.patel $(GLYPH_SEGMENTS)
patel-c --optimize --strict $< -o $@
$(SUPPORT_FILES) :
patel-c --strict $< -o $@
$(SUPPORT_FILES_FROM_PATEL) :
patel-c --optimize --strict $< -o $@
support/glyph.js : support/glyph.patel
support/stroke.js : support/stroke.patel
support/spirokit.js : support/spirokit.patel
support/spiroexpand.js : support/spiroexpand.patel
parameters.js : parameters.patel
parameters.js : parameters.patel
cleanscripts :
-@rm $(SCRIPTS_FROM_PATEL)
scripts : $(SCRIPTS)

View File

@ -1,4 +1,4 @@
define [build parametersData styles] : begin
export : define [build parametersData styles] : begin
local param {.}
local variantSelector {.}
foreach [style : items-of styles] : begin
@ -8,7 +8,4 @@ define [build parametersData styles] : begin
if hive.variantSelector : foreach [k : items-of : Object.keys hive.variantSelector] : begin
set variantSelector.(k) hive.variantSelector.(k)
param.variantSelector = variantSelector
return param
exports.build = build
return param

View File

@ -1,8 +1,7 @@
define bezierCubic2Q2 [require 'node-sfnt/lib/math/bezierCubic2Q2']
define tp [require './transform'].transformPoint
define utp [require './transform'].untransform
define Stroke [require './stroke'].Stroke
define Bezier [require 'bezier-js']
import 'node-sfnt/lib/math/bezierCubic2Q2' as bezierCubic2Q2
import './transform' as [object [transformPoint tp] [untransform utp] inverse]
import 'bezier-js' as Bezier
define [mix a b p] : a + (b - a) * p
define [ratio l r m] : if [l === r] 0 ((m - l) / (r - l))
@ -17,7 +16,7 @@ define id {
define [fallback] : for [local j 0] (j < arguments.length) [inc j] : if (arguments.(j) !== nothing) : return arguments.(j)
define aFunction {.unapply [function [obj arity] [if (obj <@ Function) {obj} null]]}
define [Glyph name] : begin
export default : define [Glyph name] : begin
set this.name name
set this.unicode {}
set this.contours {}
@ -80,24 +79,6 @@ define [Glyph.prototype.reverse-last] : begin
if [this.contours && this.contours.(this.contours.length - 1)] : begin
this.contours.(this.contours.length - 1) = [this.contours.(this.contours.length - 1).reverse]
define [Glyph.prototype.put-shapes contours] : begin
local t this.gizmo
set this.gizmo id
foreach contour [items-of contours] : if contour : begin
this.start-from contour.0.x contour.0.y
for [local j 1] (j < contour.length) [inc j] : begin
local point contour.(j)
if point.cubic
: then : begin
local p2 contour.((j + 1))
local p3 contour.((j + 2))
this.cubic-to point.x point.y p2.x p2.y p3.x p3.y
j = j + 2
: else : if point.onCurve [this.line-to point.x point.y] [this.curve-control point.x point.y]
this.tag-contour [fallback contour.tag this.defaultTag]
set this.gizmo t
return this
define [Glyph.prototype.tag-contour tag n] : begin
if this.contours : begin
local lastContour this.contours.(this.contours.length - 1)
@ -110,7 +91,6 @@ define [Glyph.prototype.eject-contour tag] : begin
define [Glyph.prototype.include component copyAnchors quenches] : begin
local glyph : match component
[aFunction it] : return : component.call this
[Stroke.is it] {.contours [component.to-outline]}
{:: contours} {.contours contours}
otherwise component
local contours glyph.contours
@ -123,14 +103,14 @@ define [Glyph.prototype.include component copyAnchors quenches] : begin
local anchorThat glyph.anchors.(markid)
if (anchorThis && (anchorThis.type === 'base' || anchorThis.mbx !== nothing && anchorThis.mby !== nothing) && anchorThat && anchorThat.type === 'mark') : begin
set {shiftx shifty} {
([fallback anchorThis.mbx anchorThis.x] - anchorThat.x)
([fallback anchorThis.mbx anchorThis.x] - anchorThat.x)
([fallback anchorThis.mby anchorThis.y] - anchorThat.y)
}
# we have a mark-to-mark position
if (anchorThat.mbx !== nothing && anchorThat.mby !== nothing) : if (anchorThis.type === 'base')
then
set this.anchors.(markid) {
.x (anchorThis.x + anchorThat.mbx - anchorThat.x)
.x (anchorThis.x + anchorThat.mbx - anchorThat.x)
.y (anchorThis.y + anchorThat.mby - anchorThat.y)
.type anchorThis.type
.mbx anchorThis.mbx
@ -138,7 +118,7 @@ define [Glyph.prototype.include component copyAnchors quenches] : begin
}
else
set this.anchors.(markid) {
.mbx (anchorThis.mbx + anchorThat.mbx - anchorThat.x)
.mbx (anchorThis.mbx + anchorThat.mbx - anchorThat.x)
.mby (anchorThis.mby + anchorThat.mby - anchorThat.y)
.type anchorThis.type
.x anchorThis.x
@ -147,13 +127,15 @@ define [Glyph.prototype.include component copyAnchors quenches] : begin
set transform.x : transform.x + shiftx
set transform.y : transform.y + shifty
if contours : begin
this.put-shapes : contours.map : function [contour] : begin
foreach [contour : items-of contours] : begin
local doput true
if quenches : foreach [tag : items-of quenches] : begin
if [contour.tag === tag] : return null
return : begin
local r : contour.map : function [point] : tp transform point
set r.tag contour.tag
* r
if [contour.tag === tag] : set doput false
if doput : begin
local c {}
foreach [point : items-of contour] : c.push : tp transform point
set c.tag contour.tag
this.contours.push c
if (([not contours] || copyAnchors) && glyph.anchors) : set this.anchors : let [a {.}] [anchors glyph.anchors] [keys : Object.keys glyph.anchors] : begin
foreach k [items-of keys] [set a.(k) anchors.(k)]
* a
@ -238,6 +220,4 @@ define [Glyph.prototype.cleanup t] : begin
if [oncurveRemovable p0 p1 p2 t] : set p1.unimportant true
foreach point [items-of contour] : if [not point.unimportant] : cleanedContour.push point
this.contours.(c) = cleanedContour
return this
exports.Glyph = Glyph
return this

View File

@ -1,4 +1,4 @@
exports.intersection = function (line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) {
module.exports = function (line1StartX, line1StartY, line1EndX, line1EndY, line2StartX, line2StartY, line2EndX, line2EndY) {
// if the lines intersect, the result contains the x and y of the intersection (treating the lines as infinite) and booleans for whether line segment 1 or line segment 2 contain the point
var denominator, a, b, numerator1, numerator2, result = {
x: null,

View File

@ -1,4 +1,4 @@
exports.createInterpolant = function(xs, ys) {
module.exports = function(xs, ys) {
var i, length = xs.length;
// Deal with length issues

View File

@ -1,11 +1,10 @@
define smooth [require './monotonic-interpolate'].createInterpolant
define tp [require './transform'].transformPoint
define utp [require './transform'].untransform
import './monotonic-interpolate' as smooth
import './transform' as [object [transformPoint tp] [untransform utp] inverse]
define [fallback] : for [local j 0] (j < arguments.length) [inc j] : if (arguments.(j) !== nothing) : return arguments.(j)
define [linreg x0 y0 x1 y1 x] : y0 + (x - x0) * (y1 - y0) / (x1 - x0)
define [SpiroExpansionContext] : begin
export default : define [SpiroExpansionContext] : begin
set this.gizmo {.xx 1 .yy 1 .xy 0 .yy 0 .x 0 .y 0}
set this.controlKnots {}
set this.defaultd1 0
@ -146,6 +145,4 @@ define [SpiroExpansionContext.prototype.expand contrast] : begin
"left" "right"
"right" "left"
type type
return {.lhs lhs .rhs rhs}
exports.SpiroExpansionContext = SpiroExpansionContext
return {.lhs lhs .rhs rhs}

View File

@ -1,9 +1,10 @@
define libspiro : require 'libspiro-js'
define SpiroExpansionContext [require './spiroexpand'].SpiroExpansionContext
import 'libspiro-js' as libspiro
import './spiroexpand' as SpiroExpansionContext
define [fallback] : for [local j 0] (j < arguments.length) [inc j] : if (arguments.(j) !== nothing) : return arguments.(j)
define [mix a b p] : a + (b - a) * p
define [SetupBuilders args] : begin
export : define [SetupBuilders args] : begin
define [object para Glyph CONTRAST globalTransform CONTRAST STROKE SUPERNESS] args
define [g4 x y f] {.x x .y y .type 'g4' .af f}
@ -170,6 +171,4 @@ define [SetupBuilders args] : begin
g4 g2 corner flat curl close end straight
widths heading unimportant important
alsothru alsothruthem bezcontrols quadcontrols archv arcvh complexThru
dispiro spiro-outline]
exports.SetupBuilders = SetupBuilders
dispiro spiro-outline]

View File

@ -1,8 +1,7 @@
define smooth [require './monotonic-interpolate'].createInterpolant
define intersection [require './intersection'].intersection
define Bezier [require 'bezier-js']
define tp [require './transform'].transformPoint
define utp [require './transform'].untransform
import './monotonic-interpolate' as smooth
import 'bezier-js' as Bezier
import './intersection' as intersection
import './transform' as [object [transformPoint tp] [untransform utp] inverse]
define [fallback] : for [local j 0] (j < arguments.length) [inc j] : if (arguments.(j) !== nothing) : return arguments.(j)
define [mix a b p] : a + (b - a) * p
@ -16,7 +15,7 @@ define KAPPA 0.51
define BKAPPA : KAPPA + 0.1
define CKAPPA BKAPPA
define [Stroke] : begin
export default : define [Stroke] : begin
this.points = {}
this.samples = SAMPLES
this.gizmo = {