Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Italic #40

Merged
merged 46 commits into from
Sep 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
46 commits
Select commit Hold shift + click to select a range
b902de6
chore: allow building variants
mishamyrt Jul 30, 2024
2664ee5
feat: add minimal variable italic
mishamyrt Jul 30, 2024
8cc8a59
feat: normalize italic glyph names
mishamyrt Jul 31, 2024
d58599d
fix: use readable fraction names
mishamyrt Jul 31, 2024
690ebb4
chore: add glyphs porting utility
mishamyrt Jul 31, 2024
7df121f
ci: add italic reporter
mishamyrt Jul 31, 2024
6d40d72
feat: add some ligatures
mishamyrt Jul 31, 2024
b56a154
fix: update italic metrics
mishamyrt Jul 31, 2024
665339a
chore: fix names
mishamyrt Aug 1, 2024
0d5e185
feat: add yus
mishamyrt Aug 1, 2024
ce86127
feat: add replacement glyph
mishamyrt Aug 1, 2024
bbde49a
feat: add cedi glyph
mishamyrt Aug 1, 2024
29d37e4
feat: sync glyph set
mishamyrt Aug 1, 2024
7706dd8
chore: regenerate features
mishamyrt Aug 1, 2024
c9e0eaf
ci: add build before report
mishamyrt Aug 1, 2024
9d443a9
ci: add download url publishing
mishamyrt Aug 1, 2024
f46fe20
ci: publish download url
mishamyrt Aug 1, 2024
fb92af2
chore: use parallel build
mishamyrt Aug 1, 2024
bd523d2
chore: clean up
mishamyrt Aug 1, 2024
fbc6e50
chore: add porting filter
mishamyrt Aug 1, 2024
973c3dd
chore: format glyphs as checked list
mishamyrt Aug 2, 2024
ff1dfe9
chore: split glyphs by groups
mishamyrt Aug 2, 2024
6ab5f95
chore: sort glyph groups
mishamyrt Aug 2, 2024
1d77d4b
chore: add progress by category
mishamyrt Aug 2, 2024
66704a6
feat: add more italic ligatures
mishamyrt Aug 2, 2024
7f8806e
fix: correctly generate spacers
mishamyrt Aug 2, 2024
394621c
feat: finalize static ligatures
mishamyrt Aug 3, 2024
5e3664a
feat: add bgr forms
mishamyrt Aug 3, 2024
234769a
chore: improve porting progress format
mishamyrt Aug 3, 2024
dc6dbd1
feat: add miscellaneous glyphs
mishamyrt Aug 3, 2024
9b0157a
feat: add greek and germandbls to italic
mishamyrt Aug 3, 2024
f7fb6c6
feat: add sequences
mishamyrt Aug 3, 2024
e28c9a0
feat: rework build system, fix tables
mishamyrt Aug 3, 2024
e3ca70a
style: fix code-style problems
mishamyrt Aug 3, 2024
bfa0ed8
chore: print counts with progress
mishamyrt Aug 4, 2024
9a37f13
feat: add italic to preview
mishamyrt Aug 4, 2024
544676f
feat: add missing sequences
mishamyrt Aug 10, 2024
1dd405c
feat: add equal sequences
mishamyrt Aug 21, 2024
bf8e938
chore: update fontbakery to 0.12.10
mishamyrt Aug 21, 2024
39f8545
feat: add missing equal arrows
mishamyrt Sep 25, 2024
d32cd43
chore: remove progress
mishamyrt Sep 25, 2024
3159379
chore: enable all features for italic
mishamyrt Sep 25, 2024
81091c6
fix: correct broken `===` ordering
mishamyrt Sep 25, 2024
82fbfc5
docs: add info about italics
mishamyrt Sep 25, 2024
dd732fa
docs: clarify project subject
mishamyrt Sep 25, 2024
ee0b5e1
docs: simplify italics preview
mishamyrt Sep 25, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions .github/workflows/build.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
on:
workflow_call:
inputs:
download_url:
default: false
type: boolean
check:
default: false
type: boolean
Expand Down Expand Up @@ -56,6 +59,7 @@ jobs:
run: make build-preview

- name: Upload build
id: build-upload-step
uses: actions/upload-artifact@v4
with:
name: Lilex
Expand All @@ -74,3 +78,14 @@ jobs:
with:
name: Preview
path: preview/dist

- name: Output download URL
if: inputs.download_url
run: echo "${{ steps.build-upload-step.outputs.artifact-url }}" > download_url.txt

- name: Upload URL
if: inputs.download_url
uses: actions/upload-artifact@v4
with:
name: URL
path: download_url.txt
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,21 @@
# Changelog
All notable changes to this project will be documented in this file.

## Next

### Added

* Italic variant.
* Cyrillic yus (`ѫ`, `Ѫ`).
* Spaces. (enspace, emspace, enquad, emquad, threeperemspace, fourperemspace, sixperemspace, figurespace, thinspace, mediumspace-math)
* Replacement glyph. (`�`)
* Cedi glyph. (`₵`)
* Guarani glyph. (`₲`)

### Fixed

* Bar-hyphen alignment. (`||-`)

## [2.530] — July 27, 2024

### Added
Expand Down
39 changes: 15 additions & 24 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
# Project paths
# BUNDLE_DIR = bundle
BUILD_DIR = build
REPORTS_DIR = reports
SCRIPTS_DIR = scripts
GLYPHS_FILE = sources/Lilex.glyphs
# Project directories
BUILD_DIR := build
REPORTS_DIR := reports
SCRIPTS_DIR := scripts
SOURCES_DIR := sources

# Font sources
LILEX_ROMAN_SOURCE = $(SOURCES_DIR)/Lilex.glyphs
LILEX_ITALIC_SOURCE = $(SOURCES_DIR)/Lilex-Italic.glyphs

# Internal build variables
OS := $(shell uname)
VENV_DIR = ./venv
VENV = . $(VENV_DIR)/bin/activate;

define build-font
@$(VENV) python $(SCRIPTS_DIR)/lilex.py build $(1)
@$(VENV) python $(SCRIPTS_DIR)/font.py \
--config "sources/family_config.yaml" \
build $(1)
endef

define check-font
Expand Down Expand Up @@ -80,7 +85,9 @@ preview: ## show CLI special symbols preview

.PHONY: generate
generate: ## regenerate the font sources with classes and features
@$(VENV) python $(SCRIPTS_DIR)/lilex.py generate
@$(VENV) python $(SCRIPTS_DIR)/font.py \
--config "sources/family_config.yaml" \
generate

.PHONY: build
build: ## build the font
Expand All @@ -95,22 +102,6 @@ build-preview: ## build the preview
run-preview: ## run the preview
cd preview; pnpm run dev

# .PHONY: pack-bundle
# pack-bundle: ## pack the bundle
# rm -rf "$(BUNDLE_DIR)"
# mkdir "$(BUNDLE_DIR)"
# # Copy fonts
# cp -r "$(BUILD_DIR)/"* "$(BUNDLE_DIR)/"
# # Copy reports
# cp "$(REPORTS_DIR)/"* "$(BUNDLE_DIR)/"
# cd "$(BUNDLE_DIR)"; zip -r Lilex.zip ./*

# .PHONY: bundle
# bundle: ## build the bundle
# @make build
# @make check
# @make pack-bundle

.PHONY: release
release:
@make build
Expand Down
10 changes: 8 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
<p>
<hr>

Lilex is the modern programming font containing a set of ligatures for common programming multi-character combinations.
Lilex is an extended font on top of [IBM Plex Mono](https://github.com/IBM/plex) designed for developers. It contains ligatures, special characters (e.g. PowerLine), Greek and exists in a variable format.

This is just a font rendering feature: underlying code remains ASCII-compatible. This makes it easier to read and understand the code. In some cases, the ligatures connect closely related characters (`==`, `---`), while in others they optically align the glyphs (`..`, `??`).
Ligatures is just a font rendering feature: underlying code remains ASCII-compatible. This makes it easier to read and understand the code. In some cases, the ligatures connect closely related characters (`==`, `---`), while in others they optically align the glyphs (`..`, `??`).

Compiled versions are available under [releases](https://github.com/mishamyrt/Lilex/releases). Bleeding edge builds can be downloaded in the [build](https://github.com/mishamyrt/Lilex/actions/workflows/build.yaml) workflow artifacts.

Expand Down Expand Up @@ -50,6 +50,12 @@ There are 6 font weights available in Lilex, ranging from Thin to Bold. In addit

<img src="./images/[email protected]">

## Italics

Lilex comes with a full set of italics: all weights, ligatures, PowerLine. Lilex Italic can do everything that Lilex does.

<img src="./images/[email protected]">

## Character Set

The font has support for Latin, Cyrillic and Greek. It also includes ligatures and powerline symbols.
Expand Down
Binary file added images/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions preview/src/app.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
@font-face {
font-family: "LilexVF";
src: url('./variable/Lilex[wght].ttf');
font-style: normal;
}

@font-face {
font-family: "LilexVF";
src: url('./variable/Lilex-Italic[wght].ttf');
font-style: italic;
}

:root {
Expand Down
61 changes: 16 additions & 45 deletions preview/src/blocks/GlyphsTable/GlyphsTable.svelte
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
<script lang="ts">
import { onMount } from 'svelte'
import { load, Font } from 'opentype.js'
import { RangeSlider, Block } from '$components'
import { RangeSlider, Block, SegmentSelect } from '$components'
import { renderGlyphs } from './render'
import Glyph from './Glyph.svelte'
import { loadFamily, FONT_STYLES, FONT_WEIGHTS, type FontMap, type FontWeight, type FontStyle } from './fonts'

const VARIANTS = ['Thin', 'Regular', 'Bold']
let fonts: FontMap = {} as FontMap
let selectedWeight: FontWeight = 'Regular'
let selectedStyle: FontStyle = 'Roman'

const fonts: Font[] = []
let selectedVariant = 1
let loading = true

let fontSize = 70
Expand Down Expand Up @@ -43,10 +43,9 @@
}

onMount(() => {
const requests = VARIANTS.map(v => load(`./ttf/Lilex-${v}.ttf`))
Promise.all(requests)
loadFamily('Lilex', './ttf')
.then(masters => {
fonts.push(...masters)
fonts = masters
loading = false
})

Expand All @@ -56,27 +55,20 @@
}
})

$: glyphs = loading || !(selectedVariant in fonts)
$: glyphs = loading || !(selectedStyle in fonts && selectedWeight in fonts[selectedStyle])
? []
: renderGlyphs(fonts[selectedVariant])
: renderGlyphs(fonts[selectedStyle][selectedWeight])
</script>


{#if !loading}
<Block title="Glyphs" dark={true}>
<svelte:fragment slot="toolbar">
<RangeSlider bind:value={fontSize} min={50} max={150} />
<ul class="variants">
{#each VARIANTS as variant, i}
<li class="variants-item">
<button
class:active="{selectedVariant === i}"
on:click={() => { selectedVariant = i }}>
{variant}
</button>
</li>
{/each}
</ul>
<div class="accessor">
<RangeSlider bind:value={fontSize} min={50} max={150} />
<SegmentSelect options={FONT_STYLES} bind:value={selectedStyle} />
</div>
<SegmentSelect options={FONT_WEIGHTS} bind:value={selectedWeight} />
</svelte:fragment>
<div
style:--glyph-width="{width}px"
Expand All @@ -93,25 +85,7 @@
{/if}

<style>
.variants-item button {
appearance: none;
font-size: 15px;
line-height: 15px;
background-color: transparent;
border: none;
background-color: transparent;
color: var(--color-content);
font-family: var(--font-family);
border-radius: 16px;
padding: 6px 15px 5px;
cursor: pointer;
}

.variants-item button.active {
pointer-events: none;
background-color: var(--color-content);
color: var(--color-background);
}

.glyphs {
--card-padding: 16px;
Expand All @@ -133,11 +107,8 @@
transition: opacity 0s;
}

ul {
list-style: none;
.accessor {
display: flex;
padding: 0;
gap: 8px;
margin: 0;
gap: var(--space-2xl);
}
</style>
60 changes: 60 additions & 0 deletions preview/src/blocks/GlyphsTable/fonts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { load, Font } from 'opentype.js'

export const FONT_WEIGHTS = ['Thin', 'Regular', 'Bold'] as const
export const FONT_STYLES = ['Roman', 'Italic'] as const

export type FontWeight = typeof FONT_WEIGHTS[number]
export type FontStyle = typeof FONT_STYLES[number]
export type FontMap = Record<FontStyle, Record<FontWeight, Font>>

type FontVariant = {
font: Font
weight: FontWeight
style: FontStyle
}

function getFontName (
family: string,
style: FontStyle,
weight: FontWeight
): string {
if (style !== 'Roman' && weight === 'Regular') {
return `${family}-${style}`
}
if (style === 'Roman') {
return `${family}-${weight}`
}
return `${family}-${weight}${style}`
}

function getFontUrl (name: string, path: string): string {
return `${path}/${name}.ttf`
}

async function loadVariant (
familyName: string,
weight: FontWeight,
style: FontStyle,
path: string
): Promise<FontVariant> {
const name = getFontName(familyName, style, weight)
const url = getFontUrl(name, path)
const font = await load(url)
return { font, weight, style }
}

export async function loadFamily (name: string, path: string): Promise<FontMap> {
const requests = FONT_WEIGHTS.map(weight =>
FONT_STYLES.map(style =>
loadVariant(name, weight, style, path))
).flat()
const fonts = await Promise.all(requests)
const map = fonts.reduce<FontMap>((map, variant) => {
if (!map[variant.style]) {
map[variant.style] = {} as Record<FontWeight, Font>
}
map[variant.style][variant.weight] = variant.font
return map
}, {} as FontMap)
return map
}
11 changes: 7 additions & 4 deletions preview/src/blocks/TypeTester/TypeTester.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { RangeSlider, SchemeSelect, FeatureSelector, FontPreview, Block } from '$components'
import { RangeSlider, SchemeSelect, FeatureSelector, FontPreview, Block, SegmentSelect } from '$components'
import { isDark } from '$utils'
import { INITIAL_TEXT, MAX_WEIGHT, MIN_WEIGHT } from './constants'

Expand All @@ -10,6 +10,7 @@
let dark = isDark()
let size = 70
let features: string[] = []
let selectedStyle: string

function handleMouseMove (e: MouseEvent) {
const position = e.clientX
Expand All @@ -20,25 +21,27 @@
function handleFeaturesChange (e: CustomEvent<string[]>) {
features = e.detail
}

$: italic = selectedStyle === 'Italic'
</script>

<Block on:mousemove={handleMouseMove} bind:dark>
<svelte:fragment slot="toolbar">
<div class="left-accessor">
<RangeSlider bind:value={size} min={12} max={200} />
<SegmentSelect bind:value={selectedStyle} options={['Roman', 'Italic']} />
<span class="weight">{weight.toFixed(0)}</span>
</div>
<SchemeSelect bind:dark />
</svelte:fragment>
<div class="layout">
<div class="preview">
<FontPreview {weight} {size} {features} bind:value />
<FontPreview {italic} {weight} {size} {features} bind:value />
</div>
<div class="sidebar">
<div class="feature-wrapper">
<FeatureSelector on:change={handleFeaturesChange} />
<FeatureSelector {italic} on:change={handleFeaturesChange} />
</div>

</div>
</div>
</Block>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import FeatureToggle from './FeatureToggle.svelte'
import { createFeaturesContext } from './context'

export let italic: boolean

let unsubscribeFeatures: () => void

const dispatch = createEventDispatcher()
Expand All @@ -19,7 +21,7 @@
})
</script>

<div class="container">
<div class="container" style:--selector-font-style={italic ? 'italic' : 'normal' }>
<FeatureToggle title="Alt g" symbols="g" variants={['cv02', 'cv03']} />
<FeatureToggle title="Alt zero" symbols="0" variants={['zero', 'cv04']} />
<FeatureToggle title="Barless units" symbols="$¢" variants={['cv09']} />
Expand All @@ -42,5 +44,6 @@
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: var(--space-s) var(--space-m);
font-style: var(--selector-font-style);
}
</style>
Loading
Loading