Make the shape weight blendable. Fixes #422

This commit is contained in:
Belleve Invis 2020-02-11 04:15:40 -08:00
parent 165161d039
commit 89e9436b53
10 changed files with 213 additions and 128 deletions

View file

@ -72,8 +72,8 @@ Since version 2.0, Iosevka would no longer support building via `makefile`. To i
# Override default building weights # Override default building weights
# When buildPlans.<plan name>.weights is absent # When buildPlans.<plan name>.weights is absent
# All weights would built and mapped to default shape/CSS # All weights would built and mapped to default shape/CSS
# IMPORTANT : Currently "shape" property only support 100, 200, 300, 400, 500, 600, 700, 800, 900. # IMPORTANT : Currently "menu" property only support 100, 200, 300, 400, 500, 600, 700, 800, 900.
[buildPlans.iosevka-custom.weights.regular] # and "shape" properly only supports number between 100 and 900 (inclusive).
shape = 400 # Weight for glyph shapes shape = 400 # Weight for glyph shapes
menu = 400 # Weight for menu name menu = 400 # Weight for menu name
css = 400 # Weight for WebFont CSS css = 400 # Weight for WebFont CSS

View file

@ -512,7 +512,8 @@ distinguishSlant = false
# Shape weight : affects the shape of the glyphs # Shape weight : affects the shape of the glyphs
# Menu weight : affects the font menu name # Menu weight : affects the font menu name
# CSS weight : affects the webfont CSS "font-weight" property # CSS weight : affects the webfont CSS "font-weight" property
# IMPORTANT : Currently "shape" property only support 100, 200, 300, 400, 500, 600, 700, 800, 900. # IMPORTANT : Currently "menu" property only support 100, 200, 300, 400, 500, 600, 700, 800, 900.
# and "shape" properly only supports number between 100 and 900 (inclusive).
[weights.thin] [weights.thin]
shape = 100 shape = 100
@ -573,6 +574,7 @@ italic = "italic"
# CSS stretch : affects the webfont CSS "font-stretch" property # CSS stretch : affects the webfont CSS "font-stretch" property
# #
# IMPORTANT : Currently "shape" property only support 3, 5, and 7 # IMPORTANT : Currently "shape" property only support 3, 5, and 7
# and "menu" only support 1, 2, 3, 4, 5, 6, 7, 8, 9
[widths.normal] [widths.normal]
shape = 5 shape = 5

View file

@ -1,4 +1,5 @@
* Made the curly-bar variant via OpenType tag `ss20`. * Made the curly-bar variant via OpenType tag `ss20`.
* Alias U+2B95 to U+27A1. * Alias U+2B95 to U+27A1.
* Add symbol U+22DA, U+22DB, U+23B0, U+23B1, etc. * Add symbol U+22DA, U+22DB, U+23B0, U+23B1, etc.
* Finished the unicode block that supports retro computer characters. * Finished the unicode block that supports retro computer characters.
* Building: The shape weight is now a continuous space.

View file

@ -39,7 +39,7 @@ function getParameters(argv) {
); );
const variantData = tryParseToml(VARIANTS_TOML); const variantData = tryParseToml(VARIANTS_TOML);
const para = parameters.build(parametersData, argv._); const para = parameters.build(parametersData, argv._, { "shape-weight": argv["shape-weight"] });
const variantsData = formVariantData(variantData, para); const variantsData = formVariantData(variantData, para);
para.variants = variantsData; para.variants = variantsData;
para.variantSelector = parameters.build(variantsData, ["default", ...argv._]); para.variantSelector = parameters.build(variantsData, ["default", ...argv._]);

View file

@ -603,7 +603,7 @@ export : define [apply] : begin
define { VShape VShapeOutline } : do "V, v and related ========================================" define { VShape VShapeOutline } : do "V, v and related ========================================"
define cornerdist : HALFSTROKE * HVCONTRAST * 1.15 define cornerdist : HALFSTROKE * HVCONTRAST * 1.15
define vcurviness : if (SLAB && !para.isItalic) 0.15 0.3 define vcurviness : if (SLAB && !para.isItalic) 0.15 0.3
define VShapeFine : STROKE * [fallback para.vtipfine : if SLAB 0.9 0.8] define VShapeFine : STROKE * [if SLAB para.vtipfineSlab para.vtipfine]
define VShapeFineStraight : Math.max [adviceBlackness 7] [STROKE * 0.66] define VShapeFineStraight : Math.max [adviceBlackness 7] [STROKE * 0.66]
define VShapeMiddleWidth : adviceBlackness 3 define VShapeMiddleWidth : adviceBlackness 3
define pInktrap 0.5 define pInktrap 0.5

View file

@ -24,7 +24,6 @@ arrowSize = 1.50
pictSize = 1.10 pictSize = 1.10
contrast = 1.11111 # Stroke width contrast. contrast = 1.11111 # Stroke width contrast.
essx = 1.12 # Contrast of the middle of 'S'.
slantAngle = 0 # Slant angle, in degrees. slantAngle = 0 # Slant angle, in degrees.
@ -35,42 +34,8 @@ overshootx = -8 # Horizontal overshoot for arcs.
oxhook = -2 # Horizontal overshoot for hook tips. oxhook = -2 # Horizontal overshoot for hook tips.
fovershoot = -40 # Overshoot of the top end of italic `f`. fovershoot = -40 # Overshoot of the top end of italic `f`.
longjut = 175 # Length of long serifs, like that in `i`.
jut = 85 # Length of short serifs, used in Slab only.
vjut = 145 # Length of vertical serifs, used in Slab only.
smooth = 195 # Vertical arc size in capital letters.
smallsmooth = 200 # Vertical arc size in lowercase letters.
smoothadjust = 120 # Parameter to balance arcs in slanted shapes.
superness = 2.2 # Superness of arcs.
tightHookSuperness = 2.3 # superness of tight hooks
barpos = 0.525 # Position of the middle bar in most letters, like `E`.
overlaypos = 0.52 # Position of the overlay mark.
ebarpos = 0.50 # Position of the middle bar in `e`.
gbarpos = 0.42
fivebarpos = 0.64
fbarpos = 0.91 # Position of the middle bar in `f`
fbarStrokeAdj = 0.25 # Portion of the fill above the f-bar position
hook = 155 # Hook depth in most letters.
ahook = 130
shook = 110
jhook = 135
fhook = 120
rhook = 110
hookx = 170
shoulderfineMin = 0.8 shoulderfineMin = 0.8
tbalance = 50
tbalance2 = 30
rbalance = 60
rbalance2 = 15
jbalance = 63
fbalance = 6
onebalance = 30
isItalic = false # Use italic shapes? isItalic = false # Use italic shapes?
isOblique = false # Use oblique shapes? isOblique = false # Use oblique shapes?
@ -102,114 +67,175 @@ enableLigation = true
# Excluded code points # Excluded code points
excludedCodePointRanges = [] excludedCodePointRanges = []
[verbose] [shape-weight.blend.400]
verbose = true stroke = 72 # Primary stroke width
sb = 60 # Primary sidebearings
essx = 1.12 # Proportion of widen of center of "S"
dotsize = 125 # Size of dots
periodsize = 140 # Size of period
### Weights jut = 85 # Length of slab serif
[w-100] vjut = 145 # Length of vertical slab serif
longjut = 175 # Length of long serifs, like that in `i`.
smooth = 195 # Vertical arc size in capital letters.
smallsmooth = 200 # Vertical arc size in lowercase letters.
smoothadjust = 120 # Parameter to balance arcs in slanted shapes.
superness = 2.2 # Superness of arcs.
tightHookSuperness = 2.3 # superness of tight hooks
barpos = 0.525 # Position of most crossbars
overlaypos = 0.52 # Position of the overlay mark.
ebarpos = 0.50 # Position of the middle bar in `e`.
gbarpos = 0.42
fivebarpos = 0.64
fbarpos = 0.91 # Position of the middle bar in `f`
fbarStrokeAdj = 0.25 # Portion of the fill above the f-bar position
rbalance = 60
rbalance2 = 15
tbalance = 50
tbalance2 = 30
jbalance = 63
fbalance = 6
onebalance = 30
hook = 155 # Hook depth in most letters.
ahook = 130
shook = 110
jhook = 135
fhook = 120
hookx = 170
rhook = 110
cthin = 0.75
cthinb = 0.5
vtipfine = 0.8
vtipfineSlab = 0.9
[shape-weight.blend.100]
jut = 85
vjut = 145
smooth = 195
barpos = 0.525
rhook = 110
rbalance = 60
rbalance2 = 15
cthin = 0.9
cthinb = 0.9
vtipfine = 1
vtipfineSlab = 1
stroke = 18 stroke = 18
sb = 72 sb = 72
dotsize = 53 dotsize = 53
periodsize = 55 periodsize = 55
cthin = 0.9 [shape-weight.blend.200]
cthinb = 0.9 jut = 85
vjut = 145
smooth = 195
barpos = 0.525
rhook = 110
rbalance = 60
rbalance2 = 15
cthin = 0.75
cthinb = 0.75
vtipfine = 1 vtipfine = 1
vtipfineSlab = 1
[w-200]
stroke = 36 stroke = 36
sb = 68 sb = 68
dotsize = 70 dotsize = 70
periodsize = 77 periodsize = 77
[shape-weight.blend.300]
jut = 85
vjut = 145
smooth = 195
barpos = 0.525
rhook = 110
rbalance = 60
rbalance2 = 15
cthin = 0.75 cthin = 0.75
cthinb = 0.75 cthinb = 0.5
vtipfine = 1 vtipfine = 0.9
vtipfineSlab = 0.9
[w-300]
stroke = 56 stroke = 56
sb = 64 sb = 64
dotsize = 100 dotsize = 100
periodsize = 115 periodsize = 115
vtipfine = 0.9 [shape-weight.blend.500]
essx = 1.12
[w-400] jut = 85
sb = 60 # Side bearing. vjut = 157
stroke = 72 # Stroke width of horizontal strokes. smooth = 200
dotsize = 125 # "Visual" size of dots in /i. barpos = 0.525
periodsize = 140 # "Visual" size of period. rhook = 110
rbalance = 60
[w-500] rbalance2 = 15
sb = 57
stroke = 84 stroke = 84
sb = 57
dotsize = 135 dotsize = 135
periodsize = 160 periodsize = 160
smooth = 200
vjut = 157
[w-600] [shape-weight.blend.600]
sb = 54
stroke = 97
dotsize = 145
periodsize = 168
essx = 1.07 essx = 1.07
jut = 85
vjut = 170 vjut = 170
smooth = 203
barpos = 0.525
rhook = 110
rbalance = 55 rbalance = 55
rbalance2 = 20 rbalance2 = 20
smooth = 203 stroke = 97
sb = 54
dotsize = 145
periodsize = 168
[w-700] [shape-weight.blend.700]
sb = 50
stroke = 106
dotsize = 157
periodsize = 180
essx = 1.06 essx = 1.06
essxq = 1.10
jut = 89 jut = 89
vjut = 179 vjut = 179
smooth = 206
barpos = 0.51 barpos = 0.51
fivebarpos = 0.64 rhook = 95
rbalance = 52 rbalance = 52
rbalance2 = 23 rbalance2 = 23
rhook = 95 stroke = 106
smooth = 206 sb = 50
dotsize = 157
periodsize = 180
[w-800] [shape-weight.blend.800]
sb = 45
stroke = 116
dotsize = 167
periodsize = 188
essx = 1.05 essx = 1.05
essxq = 1.15
jut = 96 jut = 96
vjut = 189 vjut = 189
smooth = 210
barpos = 0.51 barpos = 0.51
fivebarpos = 0.64 rhook = 97
rbalance = 50 rbalance = 50
rbalance2 = 25 rbalance2 = 25
rhook = 97 stroke = 116
smooth = 210 sb = 45
dotsize = 167
periodsize = 188
[w-900] [shape-weight.blend.900]
sb = 42
stroke = 126
dotsize = 180
periodsize = 200
essx = 1.03 essx = 1.03
essxq = 1.15
jut = 100 jut = 100
vjut = 199 vjut = 199
smooth = 215
barpos = 0.51 barpos = 0.51
fivebarpos = 0.64 rhook = 105
rbalance = 50 rbalance = 50
rbalance2 = 25 rbalance2 = 25
rhook = 105 stroke = 126
smooth = 215 sb = 42
dotsize = 180
periodsize = 200
[verbose]
verbose = true
### Slantness ### Slantness
[s-italic] [s-italic]

View file

@ -7,7 +7,8 @@ hintParams = ["-a", "sss"] # Optional custom parameters
# Override default building weights # Override default building weights
# When buildPlans.<plan name>.weights is absent # When buildPlans.<plan name>.weights is absent
# All weights would built and mapped to default shape/CSS # All weights would built and mapped to default shape/CSS
# IMPORTANT : Currently "shape" property only support 100, 200, 300, 400, 500, 600, 700, 800, 900. # IMPORTANT : Currently "menu" property only support 100, 200, 300, 400, 500, 600, 700, 800, 900.
# and "shape" properly only supports number between 100 and 900 (inclusive).
[buildPlans.iosevka-custom.weights.regular] [buildPlans.iosevka-custom.weights.regular]
shape = 400 # Weight for glyph shapes shape = 400 # Weight for glyph shapes
menu = 400 # Weight for menu name menu = 400 # Weight for menu name

28
support/param-blend.js Normal file
View file

@ -0,0 +1,28 @@
const blend = require("./monotonic-interpolate");
module.exports = function(aspect, hive, params, sink) {
if (!hive || !hive.blend || !params) return;
const block = hive.blend;
let keys = new Set();
for (const grade in block) {
if (!isFinite(parseFloat(grade))) continue;
for (const key in block[grade]) {
if (block[grade][key] == null) continue;
keys.add(key);
}
}
for (const key of keys) {
let xs = [],
ys = [];
for (const grade in block) {
if (!isFinite(parseFloat(grade))) continue;
if (block[grade][key] == null) continue;
xs.push(grade);
ys.push(block[grade][key]);
}
const fn = blend(xs, ys);
sink[key] = fn(params[aspect]);
}
};

View file

@ -1,17 +1,20 @@
export : define [build parametersData styles] : begin import "./param-blend" as paramBlend
local param {.}
export : define [build parametersData styles blendParams] : begin
define [introStyle style] : begin local param {.}
local hive parametersData.(style)
if (!hive) : return nothing define [introStyle style] : begin
if hive.inherits : foreach [h : items-of hive.inherits] : introStyle h local hive parametersData.(style)
foreach [k : items-of : Object.keys hive] : set param.(k) hive.(k) if (!hive) : return nothing
if hive.multiplies : foreach [k : items-of : Object.keys hive.multiplies] : begin if hive.inherits : foreach [h : items-of hive.inherits] : introStyle h
set param.(k) : param.(k) * hive.multiplies.(k) foreach [k : items-of : Object.keys hive] : set param.(k) hive.(k)
if hive.adds : foreach [k : items-of : Object.keys hive.adds] : begin if hive.multiplies : foreach [k : items-of : Object.keys hive.multiplies] : begin
set param.(k) : param.(k) + hive.adds.(k) set param.(k) : param.(k) * hive.multiplies.(k)
if hive.appends : foreach [k : items-of : Object.keys hive.appends] : begin if hive.adds : foreach [k : items-of : Object.keys hive.adds] : begin
set param.(k) : (param.(k) || {}).concat(hive.appends.(k)) set param.(k) : param.(k) + hive.adds.(k)
if hive.appends : foreach [k : items-of : Object.keys hive.appends] : begin
foreach [style : items-of styles] : introStyle style set param.(k) : (param.(k) || {}).concat(hive.appends.(k))
return param paramBlend style hive blendParams param
foreach [style : items-of styles] : introStyle style
return param

View file

@ -128,6 +128,25 @@ function makeSuffix(w, wd, s, fallback) {
); );
} }
function nValidate(key, v, f) {
if (typeof v !== "number" || !isFinite(v) || (f && !f(v))) {
throw new TypeError(`${key} = "${v}" is not a valid number.`);
}
return v;
}
function vlShapeWeight(x) {
return x >= 100 && x <= 900;
}
function vlMenuWeight(x) {
return x >= 100 && x <= 900 && x % 100 === 0;
}
function vlShapeWidth(x) {
return x === 3 || x === 5 || x === 7;
}
function vlMenuWidth(x) {
return x >= 1 && x <= 9 && x % 1 === 0;
}
function getSuffixSet(weights, slants, widths) { function getSuffixSet(weights, slants, widths) {
const mapping = {}; const mapping = {};
for (const w in weights) { for (const w in weights) {
@ -135,13 +154,15 @@ function getSuffixSet(weights, slants, widths) {
for (const wd in widths) { for (const wd in widths) {
const suffix = makeSuffix(w, wd, s, "regular"); const suffix = makeSuffix(w, wd, s, "regular");
mapping[suffix] = { mapping[suffix] = {
hives: [`w-${weights[w].shape}`, `s-${s}`, `wd-${widths[wd].shape}`], hives: [`shape-weight`, `s-${s}`, `wd-${widths[wd].shape}`],
weight: w, weight: w,
cssWeight: weights[w].css || w, shapeWeight: nValidate("Shape weight of " + w, weights[w].shape, vlShapeWeight),
menuWeight: weights[w].menu || weights[w].css || w, cssWeight: nValidate("CSS weight of " + w, weights[w].css),
menuWeight: nValidate("Menu weight of " + w, weights[w].menu, vlMenuWeight),
width: wd, width: wd,
shapeWidth: nValidate("Shape width of " + wd, widths[wd].shape, vlShapeWidth),
cssStretch: widths[wd].css || wd, cssStretch: widths[wd].css || wd,
menuWidth: widths[wd].menu || widths[wd].css || wd, menuWidth: nValidate("Menu width of " + wd, widths[wd].menu, vlMenuWidth),
slant: s, slant: s,
cssStyle: slants[s] || s, cssStyle: slants[s] || s,
menuStyle: slants[s] || s menuStyle: slants[s] || s
@ -184,6 +205,8 @@ const FontBuildingParameters = computed(`metadata:font-building-parameters`, asy
name: fileName, name: fileName,
family, family,
hives: ["iosevka", ...preHives, ...suffixMapping[suffix].hives, ...postHives], hives: ["iosevka", ...preHives, ...suffixMapping[suffix].hives, ...postHives],
shapeWeight: suffixMapping[suffix].shapeWeight,
shapeWidth: suffixMapping[suffix].shapeWidth,
menuWeight: suffixMapping[suffix].menuWeight, menuWeight: suffixMapping[suffix].menuWeight,
menuWidth: suffixMapping[suffix].menuWidth, menuWidth: suffixMapping[suffix].menuWidth,
menuStyle: suffixMapping[suffix].menuStyle, menuStyle: suffixMapping[suffix].menuStyle,
@ -289,10 +312,10 @@ const CollectionPartsOf = computed.group("metadata:collection-parts-of", async (
const BuildTTF = file.make( const BuildTTF = file.make(
(gr, fn) => `${BUILD}/${gr}/${fn}.ttf`, (gr, fn) => `${BUILD}/${gr}/${fn}.ttf`,
async (target, output, _gr, fn) => { async (target, output, _gr, fn) => {
const [{ hives, family, menuWeight, menuStyle, menuWidth }, version] = await target.need( const [
HivesOf(fn), { hives, family, shapeWeight, menuWeight, menuStyle, menuWidth },
Version version
); ] = await target.need(HivesOf(fn), Version);
const otd = output.dir + "/" + output.name + ".otd"; const otd = output.dir + "/" + output.name + ".otd";
const ttfTmp = output.dir + "/" + output.name + ".tmp.ttf"; const ttfTmp = output.dir + "/" + output.name + ".tmp.ttf";
const otdTmp = output.dir + "/" + output.name + ".tmp.otd"; const otdTmp = output.dir + "/" + output.name + ".tmp.otd";
@ -304,6 +327,7 @@ const BuildTTF = file.make(
["--charmap", charmap], ["--charmap", charmap],
["--family", family], ["--family", family],
["--ver", version], ["--ver", version],
["--shape-weight", shapeWeight],
["--menu-weight", menuWeight], ["--menu-weight", menuWeight],
["--menu-slant", menuStyle], ["--menu-slant", menuStyle],
["--menu-width", menuWidth], ["--menu-width", menuWidth],