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
# When buildPlans.<plan name>.weights is absent
# 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.
[buildPlans.iosevka-custom.weights.regular]
# 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).
shape = 400 # Weight for glyph shapes
menu = 400 # Weight for menu name
css = 400 # Weight for WebFont CSS

View file

@ -512,7 +512,8 @@ distinguishSlant = false
# Shape weight : affects the shape of the glyphs
# Menu weight : affects the font menu name
# 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]
shape = 100
@ -573,6 +574,7 @@ italic = "italic"
# CSS stretch : affects the webfont CSS "font-stretch" property
#
# 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]
shape = 5

View file

@ -2,3 +2,4 @@
* Alias U+2B95 to U+27A1.
* Add symbol U+22DA, U+22DB, U+23B0, U+23B1, etc.
* 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 para = parameters.build(parametersData, argv._);
const para = parameters.build(parametersData, argv._, { "shape-weight": argv["shape-weight"] });
const variantsData = formVariantData(variantData, para);
para.variants = variantsData;
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 cornerdist : HALFSTROKE * HVCONTRAST * 1.15
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 VShapeMiddleWidth : adviceBlackness 3
define pInktrap 0.5

View file

@ -24,7 +24,6 @@ arrowSize = 1.50
pictSize = 1.10
contrast = 1.11111 # Stroke width contrast.
essx = 1.12 # Contrast of the middle of 'S'.
slantAngle = 0 # Slant angle, in degrees.
@ -35,42 +34,8 @@ overshootx = -8 # Horizontal overshoot for arcs.
oxhook = -2 # Horizontal overshoot for hook tips.
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
tbalance = 50
tbalance2 = 30
rbalance = 60
rbalance2 = 15
jbalance = 63
fbalance = 6
onebalance = 30
isItalic = false # Use italic shapes?
isOblique = false # Use oblique shapes?
@ -102,114 +67,175 @@ enableLigation = true
# Excluded code points
excludedCodePointRanges = []
[verbose]
verbose = true
[shape-weight.blend.400]
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
[w-100]
jut = 85 # Length of slab serif
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
sb = 72
dotsize = 53
periodsize = 55
cthin = 0.9
cthinb = 0.9
[shape-weight.blend.200]
jut = 85
vjut = 145
smooth = 195
barpos = 0.525
rhook = 110
rbalance = 60
rbalance2 = 15
cthin = 0.75
cthinb = 0.75
vtipfine = 1
[w-200]
vtipfineSlab = 1
stroke = 36
sb = 68
dotsize = 70
periodsize = 77
[shape-weight.blend.300]
jut = 85
vjut = 145
smooth = 195
barpos = 0.525
rhook = 110
rbalance = 60
rbalance2 = 15
cthin = 0.75
cthinb = 0.75
vtipfine = 1
[w-300]
cthinb = 0.5
vtipfine = 0.9
vtipfineSlab = 0.9
stroke = 56
sb = 64
dotsize = 100
periodsize = 115
vtipfine = 0.9
[w-400]
sb = 60 # Side bearing.
stroke = 72 # Stroke width of horizontal strokes.
dotsize = 125 # "Visual" size of dots in /i.
periodsize = 140 # "Visual" size of period.
[w-500]
sb = 57
[shape-weight.blend.500]
essx = 1.12
jut = 85
vjut = 157
smooth = 200
barpos = 0.525
rhook = 110
rbalance = 60
rbalance2 = 15
stroke = 84
sb = 57
dotsize = 135
periodsize = 160
smooth = 200
vjut = 157
[w-600]
sb = 54
stroke = 97
dotsize = 145
periodsize = 168
[shape-weight.blend.600]
essx = 1.07
jut = 85
vjut = 170
smooth = 203
barpos = 0.525
rhook = 110
rbalance = 55
rbalance2 = 20
smooth = 203
stroke = 97
sb = 54
dotsize = 145
periodsize = 168
[w-700]
sb = 50
stroke = 106
dotsize = 157
periodsize = 180
[shape-weight.blend.700]
essx = 1.06
essxq = 1.10
jut = 89
vjut = 179
smooth = 206
barpos = 0.51
fivebarpos = 0.64
rhook = 95
rbalance = 52
rbalance2 = 23
rhook = 95
smooth = 206
stroke = 106
sb = 50
dotsize = 157
periodsize = 180
[w-800]
sb = 45
stroke = 116
dotsize = 167
periodsize = 188
[shape-weight.blend.800]
essx = 1.05
essxq = 1.15
jut = 96
vjut = 189
smooth = 210
barpos = 0.51
fivebarpos = 0.64
rhook = 97
rbalance = 50
rbalance2 = 25
rhook = 97
smooth = 210
stroke = 116
sb = 45
dotsize = 167
periodsize = 188
[w-900]
sb = 42
stroke = 126
dotsize = 180
periodsize = 200
[shape-weight.blend.900]
essx = 1.03
essxq = 1.15
jut = 100
vjut = 199
smooth = 215
barpos = 0.51
fivebarpos = 0.64
rhook = 105
rbalance = 50
rbalance2 = 25
rhook = 105
smooth = 215
stroke = 126
sb = 42
dotsize = 180
periodsize = 200
[verbose]
verbose = true
### Slantness
[s-italic]

View file

@ -7,7 +7,8 @@ hintParams = ["-a", "sss"] # Optional custom parameters
# Override default building weights
# When buildPlans.<plan name>.weights is absent
# 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]
shape = 400 # Weight for glyph shapes
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,4 +1,6 @@
export : define [build parametersData styles] : begin
import "./param-blend" as paramBlend
export : define [build parametersData styles blendParams] : begin
local param {.}
define [introStyle style] : begin
@ -12,6 +14,7 @@ export : define [build parametersData styles] : begin
set param.(k) : param.(k) + hive.adds.(k)
if hive.appends : foreach [k : items-of : Object.keys hive.appends] : begin
set param.(k) : (param.(k) || {}).concat(hive.appends.(k))
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) {
const mapping = {};
for (const w in weights) {
@ -135,13 +154,15 @@ function getSuffixSet(weights, slants, widths) {
for (const wd in widths) {
const suffix = makeSuffix(w, wd, s, "regular");
mapping[suffix] = {
hives: [`w-${weights[w].shape}`, `s-${s}`, `wd-${widths[wd].shape}`],
hives: [`shape-weight`, `s-${s}`, `wd-${widths[wd].shape}`],
weight: w,
cssWeight: weights[w].css || w,
menuWeight: weights[w].menu || weights[w].css || w,
shapeWeight: nValidate("Shape weight of " + w, weights[w].shape, vlShapeWeight),
cssWeight: nValidate("CSS weight of " + w, weights[w].css),
menuWeight: nValidate("Menu weight of " + w, weights[w].menu, vlMenuWeight),
width: wd,
shapeWidth: nValidate("Shape width of " + wd, widths[wd].shape, vlShapeWidth),
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,
cssStyle: slants[s] || s,
menuStyle: slants[s] || s
@ -184,6 +205,8 @@ const FontBuildingParameters = computed(`metadata:font-building-parameters`, asy
name: fileName,
family,
hives: ["iosevka", ...preHives, ...suffixMapping[suffix].hives, ...postHives],
shapeWeight: suffixMapping[suffix].shapeWeight,
shapeWidth: suffixMapping[suffix].shapeWidth,
menuWeight: suffixMapping[suffix].menuWeight,
menuWidth: suffixMapping[suffix].menuWidth,
menuStyle: suffixMapping[suffix].menuStyle,
@ -289,10 +312,10 @@ const CollectionPartsOf = computed.group("metadata:collection-parts-of", async (
const BuildTTF = file.make(
(gr, fn) => `${BUILD}/${gr}/${fn}.ttf`,
async (target, output, _gr, fn) => {
const [{ hives, family, menuWeight, menuStyle, menuWidth }, version] = await target.need(
HivesOf(fn),
Version
);
const [
{ hives, family, shapeWeight, menuWeight, menuStyle, menuWidth },
version
] = await target.need(HivesOf(fn), Version);
const otd = output.dir + "/" + output.name + ".otd";
const ttfTmp = output.dir + "/" + output.name + ".tmp.ttf";
const otdTmp = output.dir + "/" + output.name + ".tmp.otd";
@ -304,6 +327,7 @@ const BuildTTF = file.make(
["--charmap", charmap],
["--family", family],
["--ver", version],
["--shape-weight", shapeWeight],
["--menu-weight", menuWeight],
["--menu-slant", menuStyle],
["--menu-width", menuWidth],