cvxx features now applies to accented letters.

This commit is contained in:
be5invis 2015-12-22 12:47:11 +08:00
parent 743ba744d9
commit 6754d24f60
13 changed files with 146 additions and 81 deletions

1
.gitignore vendored
View File

@ -34,6 +34,7 @@ node_modules
test/
preview/
build/
dist/
ref/
pages/
releases/

View File

@ -40,19 +40,23 @@ feature ccmp {
feature mark {
script latn;
language dflt;
lookup markAuto_letter;
lookup markAuto_letter1;
lookup markAuto_letter2;
lookup markAuto_overlay;
script grek;
language dflt;
lookup markAuto_letter;
lookup markAuto_letter1;
lookup markAuto_letter2;
lookup markAuto_overlay;
script cyrl;
language dflt;
lookup markAuto_letter;
lookup markAuto_letter1;
lookup markAuto_letter2;
lookup markAuto_overlay;
script dflt;
language dflt;
lookup markAuto_letter;
lookup markAuto_letter1;
lookup markAuto_letter2;
lookup markAuto_overlay;
} mark;
@ -70,38 +74,3 @@ feature mkmk {
language dflt;
lookup mkmkAuto;
} mkmk;
lookup slashzero {
sub zero by zero.slashed;
} slashzero;
lookup dotzero {
sub zero by zero.dotted;
} dotzero;
lookup blankzero {
sub zero by zero.unslashed;
} blankzero;
feature cv01 { script latn; sub a by a.upright; } cv01;
feature cv02 { script latn; sub a by a.italic; } cv02;
feature cv03 { script latn; sub i by i.serifed; } cv03;
feature cv04 { script latn; sub i by i.italic; } cv04;
feature cv05 { script latn; sub i by i.hooky; } cv05;
feature cv06 { script latn; sub i by i.zshaped; } cv06;
feature cv07 { script latn; sub l by l.serifed; } cv07;
feature cv08 { script latn; sub l by l.italic; } cv08;
feature cv09 { script latn; sub l by l.hooky; } cv09;
feature cv10 { script latn; sub l by l.zshaped; } cv10;
feature cv11 { script latn; sub g by g.doublestorey; } cv11;
feature cv12 { script latn; sub g by g.singlestorey; } cv12;
feature cv13 { script latn; lookup slashzero; script dflt; lookup slashzero; } cv13;
feature cv14 { script latn; lookup dotzero; script dflt; lookup dotzero; } cv14;
feature cv15 { script latn; lookup blankzero; script dflt; lookup blankzero; } cv15;
feature ss01 { script latn; sub [i l] by [i.serifed l.serifed]; } ss01;
feature ss02 { script latn; sub [i l] by [i.hooky l.hooky]; } ss02;
feature ss03 { script latn; sub [i l] by [i.zshaped l.zshaped]; } ss03;
feature ss04 { script latn; sub g by g.doublestorey; } ss04;
feature ss05 { script latn; sub g by g.singlestorey; } ss05;
feature ss06 { script latn; lookup slashzero; script dflt; lookup slashzero; } ss06;
feature ss07 { script latn; lookup dotzero; script dflt; lookup dotzero; } ss07;
feature ss08 { script latn; lookup blankzero; script dflt; lookup blankzero; } ss08;

View File

@ -20,6 +20,7 @@ var font = function(){
console.log(' Start build font ' + fontUniqueName);
var font = buildGlyphs.build.call(emptyFont, para);
console.log(' ' + fontUniqueName + " Successfully built.");
font.features.sscompose = para.sscompose
return font;
}();
@ -38,6 +39,20 @@ if(argv.feature) (function(){
console.log(' Writing feature file -> ' + argv.feature);
var featurefile = '\n\n';
// markGlyphs
for(var feature in font.features.cv) {
var base = [], replace = [];
for(var key in font.features.cv[feature]) {
base.push(key);
replace.push(font.features.cv[feature][key]);
};
var lookupName = feature + 'Auto';
featurefile += 'lookup ' + lookupName + ' { sub [' + base.join(' ') + '] by [' + replace.join(' ') + '];} ' + lookupName + ';\n\n';
featurefile += 'feature ' + feature + ' { script latn; lookup ' + lookupName + '; script grek; lookup ' + lookupName + '; script cyrl; lookup ' + lookupName + '; script dflt; lookup ' + lookupName + '; } ' + feature + ';\n\n';
}
for(var feature in font.features.sscompose) {
var stmt = font.features.sscompose[feature].map(function(lookup){ return 'lookup ' + lookup + 'Auto'}).join(';')
featurefile += 'feature ' + feature + ' { script latn; ' + stmt + '; script grek; ' + stmt + '; script cyrl; ' + stmt + '; script dflt; ' + stmt + '; } ' + feature + ';\n\n';
}
for(var key in font.features.markGlyphs){
featurefile += '@MG_' + key + '= [' + font.features.markGlyphs[key].join(' ') + '];\n'
}

View File

@ -2,6 +2,8 @@
# Build accented glyphs
define [isAboveMark mark] : mark && mark.anchors && mark.anchors.above && mark.anchors.above.type === MARK
set font.features {.}
set font.features.cv {.}
define customDecompositions {
# Latvians use comma instead of cedillas in several letters.
@ -160,7 +162,7 @@ define [pad s n] : begin
#set font.features.ccmp {}
define [shorter x y] : if (x.length < y.length) x y
let : begin
local {cfv} : let : begin
local nComposed 0
local foundDecompositions {.}
define [decideName namingParts parts code] : begin
@ -171,7 +173,7 @@ let : begin
local j 2
while foundDecompositions.(glyphName + j) [inc j]
set glyphName (glyphName + j)
if (glyphName.length > 30) : set glyphName ('uni' + [pad [[code.toString 16].toUpperCase] 4])
if (glyphName.length > 27) : set glyphName ('uni' + [pad [[code.toString 16].toUpperCase] 4])
return glyphName
local [buildForCode code] : if [not unicodeGlyphs.(code)] : begin
local str : String.fromCharCode code
@ -195,8 +197,9 @@ let : begin
#if (global && global.gc) : global.gc
progress "Composition Decision"
local {glyphName code parts} {}
define construction : glyph-construction
assign-unicode code
if code : assign-unicode code
include parts.0 AS_BASE
set-width parts.0.advanceWidth
@ -205,18 +208,40 @@ let : begin
include part
names.push part.name
if (part.name === 'rtailBR') : eject-contour 'serifRB'
#progress "Compose [\[names.join ' + ']] --> \(glyphName)"
define [cfv glyphName _pa] : if (!recursive && _pa.0.featureSelector) : begin
local h {.}
foreach [feature : items-of : Object.keys _pa.0.featureSelector] : begin
local variant _pa.0.featureSelector.(feature)
local variantRoot glyphs.(variant)
if variantRoot : begin
set parts {variantRoot :: [_pa.slice 1]}
set code null
create-glyph (glyphName + '.' + feature) construction
set h.(feature) (glyphName + '.' + feature)
if glyphs.(glyphName) : set glyphs.(glyphName).featureSelector h
foreach [_id : items-of : Object.keys foundDecompositions] : begin
local {glyphName code parts} foundDecompositions.(_id)
set {glyphName code parts} foundDecompositions.(_id)
create-glyph glyphName construction
cfv glyphName parts
progress "Unicode Precomposites (\(nComposed) glyphs)"
list cfv
symbol-block "Manual Precomposites"
composite 'i.serifed' glyphs.'dotlessi.serifed' glyphs.dotAbove
composite 'i.italic' glyphs.'dotlessi.italic' glyphs.dotAbove
composite 'i.hooky' glyphs.'dotlessi.hooky' glyphs.dotAbove
composite 'i.zshaped' glyphs.'dotlessi.zshaped' glyphs.dotAbove
symbol-block "Manual Precomposites and CV variants"
cfv 'i' {glyphs.dotlessi glyphs.dotAbove}
cfv 'cyrUkrainiani' {glyphs.i}
foreach [name : items-of : Object.keys glyphs] : begin
if glyphs.(name).featureSelector : begin
local fs glyphs.(name).featureSelector
foreach [feature : items-of : Object.keys fs] : begin
if [not font.features.cv.(feature)] : set font.features.cv.(feature) {.}
set font.features.cv.(feature).(name) fs.(feature)
local MarkZoom : glyph-construction
apply-transform : Upright
@ -231,7 +256,17 @@ symbol-block "Manual Precomposites"
composite 'latin1acute' glyphs.space glyphs.acuteAbove MarkZoom [into-unicode 0xB4]
composite 'degree' glyphs.space glyphs.ringAbove MarkZoom [into-unicode 0xB0]
composite 'asciitilde.centered' glyphs.asciitilde [Upright] [Translate 0 (parenMid - XH - ACCENT)] [Italify]
if [not recursive] : begin
composite 'asciitilde.centered' glyphs.asciitilde [Upright] [Translate 0 (parenMid - XH - ACCENT)] [Italify]
set glyphs.asciitilde.featureSelector {
.cv16 'asciitilde'
.cv17 'asciitilde.centered'
}
composite 'asterisk.centered' glyphs.asterisk [Upright] [Translate 0 (parenMid - glyphs.asterisk.centery)] [Italify]
set glyphs.asterisk.featureSelector {
.cv18 'asterisk'
.cv19 'asterisk.centered'
}
define [suggestName name] : begin
if glyphs.(name) : begin
@ -261,7 +296,14 @@ define [createCircledGlyphs records] : if [not recursive] : begin
apply-transform : Translate (width / 2) (CAP / 2 * dscale)
apply-transform : Italify
refair this
include : OShape (CAP * dscale + [Math.max (CAP * 0.175) (sw * 3)]) (-[Math.max (CAP * 0.175) (sw * 3)]) [Math.max (SB + O * 3) (width / 2 - CAP / 2 * dscale - sw * 2.5)] [Math.min (width - SB - O * 3) (width / 2 + CAP / 2 * dscale + sw * 2.5)] sw (SMALLSMOOTHA * width / WIDTH) (SMALLSMOOTHB * width / WIDTH)
include : OShape
* (CAP * dscale + [Math.max (CAP * 0.175) (sw * 3)])
* (-[Math.max (CAP * 0.175) (sw * 3)])
* [Math.max (SB + O * 3) (width / 2 - CAP / 2 * dscale - sw * 2.5)]
* [Math.min (width - SB - O * 3) (width / 2 + CAP / 2 * dscale + sw * 2.5)]
* sw
* (SMALLSMOOTHA * width / WIDTH)
* (SMALLSMOOTHB * width / WIDTH)
apply-transform : Upright
apply-transform : Translate 0 (parenMid - CAP * dscale / 2)
apply-transform : Italify
@ -724,7 +766,6 @@ if [not recursive] : begin
set font.glyf : font.glyf.filter [lambda [g] : g.advanceWidth <= WIDTH]
set glyphList font.glyf
set font.features {.}
set font.features.mark {.}
set font.features.mkmk {.marks {} .bases {}}
set font.features.markGlyphs {.}
@ -749,7 +790,8 @@ if [not recursive] : begin
then : lookup.marks.push : 'markClass ' + glyph.name + [buildAnchorDescription glyph '' 'x' 'y' 'mark' th]
else : lookup.bases.push : 'pos base ' + glyph.name + [buildAnchorDescription glyph 'mark' 'x' 'y' 'mark' th]
createMarkLookup 'letter' {'above' 'below' 'trailing' 'lf' 'topright' 'bottomright'}
createMarkLookup 'letter1' {'above' 'below'}
createMarkLookup 'letter2' {'trailing' 'lf' 'topright' 'bottomright'}
createMarkLookup 'overlay' {'overlay' 'slash'}
# mkmk and GDEF
foreach glyph [items-of glyphList] : if (glyph.anchors && [begin [local anchorKeys : Object.keys glyph.anchors] anchorKeys.length])

View File

@ -1,11 +1,12 @@
###### COMMON GLYPH CONSTRUCTIONS
define [select-variant name unicode default] : begin
define [select-variant name unicode default featureSelector] : begin
if (pickHash && [not pickHash.(name)]) : return nothing
local variant : variantSelector.(name) || default
local chosenGlyph glyphs.((name + '.' + variant))
create-glyph name : glyph-construction
include chosenGlyph AS_BASE
if unicode : assign-unicode unicode
if featureSelector : set currentGlyph.featureSelector featureSelector
define [italic-variant name unicode] : create-glyph name : glyph-construction
if para.isItalic
@ -13,10 +14,12 @@ define [italic-variant name unicode] : create-glyph name : glyph-construction
else : include glyphs.(name + '.upright') AS_BASE
if unicode : assign-unicode unicode
define [alias newid unicode oldid] : create-glyph newid : glyph-construction
if unicode : assign-unicode unicode
include glyphs.(oldid) AS_BASE
set-width glyphs.(oldid).advanceWidth
define [alias newid unicode oldid] : begin
create-glyph newid : glyph-construction
if unicode : assign-unicode unicode
include glyphs.(oldid) AS_BASE
set-width glyphs.(oldid).advanceWidth
set this.featureSelector glyphs.(oldid).featureSelector
define [composite newid] : let [parts : {}.slice.call arguments 1] : begin
create-glyph [fallback newid ('glyph' + [set nTemp (nTemp + 1)])] : glyph-construction

View File

@ -67,12 +67,17 @@ symbol-block 'i'
set-anchor 'above' BASE (left + HALFSTROKE * HVCONTRAST + [linreg 18 0.25 126 0 STROKE] * TANSLANT * WIDTH) XH
set-anchor 'below' BASE middle 0
select-variant 'dotlessi' 0x131 [if para.isItalic 'italic' 'serifed']
select-variant 'dotlessi' 0x131 [if para.isItalic 'italic' 'serifed'] {
.'cv03' 'dotlessi.serifed'
.'cv04' 'dotlessi.italic'
.'cv05' 'dotlessi.hooky'
.'cv06' 'dotlessi.zshaped'
}
create-glyph 'iogonek.dotless' : glyph-construction
include glyphs.dotlessi AS_BASE
include glyphs.ogonekBelow
create-glyph 'i' : glyph-construction
set-width WIDTH
assign-unicode 'i'
@ -291,7 +296,12 @@ symbol-block 'l'
set-anchor 'below' BASE middle 0
set this.barx (left + HALFSTROKE)
select-variant 'l' 'l' [if para.isItalic 'italic' 'serifed']
select-variant 'l' 'l' [if para.isItalic 'italic' 'serifed'] {
.'cv07' 'l.serifed'
.'cv08' 'l.italic'
.'cv09' 'l.hooky'
.'cv10' 'l.zshaped'
}
alias 'palochka' 0x4CF 'l'
turned 'turnl' 0xA781 'l' MIDDLE (XH / 2) pMarks
@ -526,13 +536,10 @@ symbol-block 'a'
include : RightwardBottomSerif RIGHTSB 0 SIDEJUT
tag-contour 'serifRB'
create-glyph 'a' : glyph-construction
set-width WIDTH
assign-unicode 'a'
if (para.isItalic)
then : include glyphs.'a.italic' AS_BASE
else : include glyphs.'a.upright' AS_BASE
select-variant 'a' 'a' [if para.isItalic 'italic' 'upright'] {
.'cv01' 'a.upright'
.'cv02' 'a.italic'
}
alias 'cyra' 0x430 'a'
create-glyph 'scripta' : glyph-construction
@ -1687,7 +1694,10 @@ symbol-block 'g'
include : RightwardTopSerif RIGHTSB XH SIDEJUT
tag-contour 'serifRT'
select-variant 'g' 'g' 'doublestorey'
select-variant 'g' 'g' 'doublestorey' {
.cv11 'g.doublestorey'
.cv12 'g.singlestorey'
}
alias 'scriptg' 0x261 'g.singlestorey'
turned nothing 0x1D77 'g' MIDDLE [mix DESCENDER XH 0.5]

View File

@ -21,7 +21,11 @@ symbol-block "Numbers"
local radius : Math.min DOTRADIUS ((RIGHTSB - SB - STROKE * 2) / 4)
include : Ring (CAPMIDDLE + radius) (CAPMIDDLE - radius) (MIDDLE + radius) (MIDDLE - radius)
select-variant 'zero' '0' 'slashed'
select-variant 'zero' '0' 'slashed' {
.cv13 'zero.slashed'
.cv14 'zero.dotted'
.cv15 'zero.unslashed'
}
create-glyph 'one' : glyph-construction

View File

@ -369,6 +369,8 @@ symbol-block 'Typographic Symbols'
include : dispiro
flat MIDDLE centery [widths fine fine]
curl (MIDDLE + radius * s) (centery + radius * c) [widths final final]
set currentGlyph.centery centery
create-glyph 'numbersign' : glyph-construction
set-width WIDTH
assign-unicode '#'

View File

@ -1,6 +1,5 @@
default: fonts
OBJDIR = build
include makesupport.mk
PARAM_DEFAULT = FAST='$(FAST)' SUFFIX='$(SUFFIX)' VARIANTNAME='$(VARIANTNAME)' STYLE_COMMON='$(STYLE_COMMON)' STYLE_UPRIGHT='$(STYLE_UPRIGHT)' STYLE_ITALIC='$(STYLE_ITALIC)' VERSION='$(VERSION)' ARCPREFIX='$(ARCPREFIX)'
PARAM_SLAB = FAST='$(FAST)' SUFFIX='$(SUFFIX)-slab' VARIANTNAME='$(VARIANTNAME)' STYLE_COMMON='$(STYLE_COMMON)' STYLE_SUFFIX='slab' STYLE_UPRIGHT='$(STYLE_UPRIGHT)' STYLE_ITALIC='$(STYLE_ITALIC)' VERSION='$(VERSION)' ARCPREFIX='$(ARCPREFIX)'
@ -14,20 +13,18 @@ test : test-default test-slab
pages : pages-default pages-slab
release : release-default release-slab
$(OBJDIR) :
@- mkdir $@
# svgs
svgs-default : $(SCRIPTS) | $(OBJDIR)
svgs-default : $(SCRIPTS) | $(OBJDIR) $(DISTDIR)
@$(MAKE) -f onegroup.mk svgs $(PARAM_DEFAULT)
svgs-slab : $(SCRIPTS) | $(OBJDIR)
svgs-slab : $(SCRIPTS) | $(OBJDIR) $(DISTDIR)
@$(MAKE) -f onegroup.mk svgs $(PARAM_SLAB)
# ttfs
fonts-default : $(SCRIPTS) | $(OBJDIR)
fonts-default : $(SCRIPTS) | $(OBJDIR) $(DISTDIR)
@$(MAKE) -f onegroup.mk fonts $(PARAM_DEFAULT)
fonts-slab : $(SCRIPTS) | $(OBJDIR)
fonts-slab : $(SCRIPTS) | $(OBJDIR) $(DISTDIR)
@$(MAKE) -f onegroup.mk fonts $(PARAM_SLAB)

View File

@ -1,3 +1,11 @@
OBJDIR = build
DISTDIR = dist
$(OBJDIR) :
@- mkdir $@
$(DISTDIR) :
@- mkdir $@
PATELC = node ./node_modules/patel/bin/patel-c
SUPPORT_FILES_FROM_aki = support/glyph.js support/spiroexpand.js support/spirokit.js parameters.js
SUPPORT_FILES = $(SUPPORT_FILES_FROM_aki) support/point.js generator.js emptyfont.toml parameters.toml support/fairify.js

View File

@ -1,7 +1,6 @@
default: fonts
TARGETUPM = 1000
OBJDIR = build
include makesupport.mk
PREFIX = $(VARIANTNAME)iosevka$(SUFFIX)
ARCPREFIXB = iosevka$(SUFFIX)
@ -38,7 +37,9 @@ PASS2 = $(subst $(OBJDIR)/,$(OBJDIR)/.pass2-,$(TARGETS))
PASS3 = $(subst $(OBJDIR)/,$(OBJDIR)/.pass3-,$(TARGETS))
PASS4 = $(subst $(OBJDIR)/,$(OBJDIR)/.pass4-,$(TARGETS))
fonts : $(TARGETS)
DISTTARGETS = $(subst $(OBJDIR)/,$(DISTDIR)/,$(TARGETS))
fonts : $(DISTTARGETS)
svgs : $(SVG0)
@ -116,8 +117,8 @@ $(PASS4) : $(OBJDIR)/.pass4-%.ttf : pass4-finalize.js $(OBJDIR)/.pass3-%.ttf
$(TARGETS) : $(OBJDIR)/%.ttf : $(OBJDIR)/.pass4-%.ttf
ttfautohint $< $@
$(OBJDIR) :
@- mkdir $@
$(DISTTARGETS) : $(DISTDIR)/%.ttf : $(OBJDIR)/%.ttf
cp $< $@
# releaseing
RELEASEDIR = releases

View File

@ -63,6 +63,18 @@ lllcrowdedness = 3.33333333
[iosevka.variantSelector]
[iosevka.sscompose]
ss01 = ['cv04', 'cv07']
ss02 = ['cv05', 'cv09']
ss03 = ['cv06', 'cv10']
ss04 = ['cv11']
ss05 = ['cv12']
ss06 = ['cv13']
ss07 = ['cv14']
ss08 = ['cv15']
ss09 = ['cv16', 'cv18']
ss10 = ['cv17', 'cv19']
# Spacings
[cjk]
cjk = true

View File

@ -39,6 +39,7 @@ function writettf(ttf, file){
}
var ttf = readttf(process.argv[2]);
delete ttf.FFTM
// Fixes xAvgCharWidth
var spacewidth = ttf.head.unitsPerEm / 2;
for(var j = 0; j < ttf.glyf.length; j++) if(ttf.glyf[j] && ttf.glyf[j].unicode && ttf.glyf[j].unicode[0] === 0x20) {