fontist 3.0.1 → 3.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -78,6 +78,73 @@ fontist install "Roboto" --location=system
78
78
 
79
79
  ---
80
80
 
81
+ ## Windows Features on Demand (FOD) Fonts
82
+
83
+ Windows includes supplementary fonts that aren't pre-installed but can be enabled through **Features on Demand** (FOD). These include fonts for Japanese, Korean, Arabic, Pan-European, and other scripts.
84
+
85
+ ### What Are FOD Fonts?
86
+
87
+ Windows FOD fonts are installed using `Add-WindowsCapability`, which downloads font packages from Windows Update. Fontist automates this process — when a formula specifies `source: windows_fod`, Fontist calls the appropriate PowerShell command to install the capability.
88
+
89
+ ### Installing FOD Fonts
90
+
91
+ ```powershell
92
+ # Install a specific supplemental font
93
+ fontist install "Meiryo"
94
+
95
+ # Install Pan-European supplemental fonts
96
+ fontist install "Arial Nova"
97
+ ```
98
+
99
+ Fontist checks whether the capability is already installed. If not, it runs:
100
+
101
+ ```powershell
102
+ Add-WindowsCapability -Online -Name 'Language.Fonts.Jpan~~~und-JPAN~0.0.1.0'
103
+ ```
104
+
105
+ ### Requirements
106
+
107
+ | Requirement | Details |
108
+ |-------------|---------|
109
+ | Windows version | Windows 10 or later |
110
+ | Internet connection | Required (fonts download from Windows Update) |
111
+ | Administrator | Required on Windows 10 for system-wide installation |
112
+ | WSUS/SCCM | Must not block Features on Demand |
113
+
114
+ ### Available FOD Fonts
115
+
116
+ Fontist includes metadata for all Windows FOD font capabilities. Some common ones:
117
+
118
+ | Capability | Fonts Included |
119
+ |------------|---------------|
120
+ | Japanese Supplemental Fonts | Meiryo, MS Gothic, MS Mincho |
121
+ | Korean Supplemental Fonts | Batang, Dotum, Gulim |
122
+ | Arabic Script Supplemental Fonts | Sakkal Majalla, Simplified Arabic |
123
+ | Pan-European Supplemental Fonts | Arial Nova, Georgia Pro, Gill Sans Nova |
124
+ | Traditional Chinese Supplemental Fonts | MingLiU, DFKai-SB |
125
+
126
+ ### FOD Font Installation Flow
127
+
128
+ 1. Fontist looks up the font in the formula index
129
+ 2. Checks if the Windows FOD capability is already installed via `Get-WindowsCapability`
130
+ 3. If not installed, runs `Add-WindowsCapability` to download and install it
131
+ 4. Returns paths to the installed font files in `C:\Windows\Fonts`
132
+
133
+ ### Troubleshooting FOD Installation
134
+
135
+ If you see a `WindowsFodInstallError`:
136
+
137
+ 1. **No internet connection** — FOD fonts require Windows Update access
138
+ 2. **Insufficient permissions** — Run as Administrator on Windows 10
139
+ 3. **WSUS/SCCM policy** — Your organization may block FOD downloads; contact your IT administrator
140
+ 4. **Capability not found** — The capability name may differ on your Windows version; run `Get-WindowsCapability -Online -Name 'Language.Fonts.*'` to list available capabilities
141
+
142
+ ::: info Platform Restriction
143
+ Windows FOD fonts are only installable on Windows. Fontist will raise a `PlatformMismatchError` if you attempt to install them on macOS or Linux.
144
+ :::
145
+
146
+ ---
147
+
81
148
  ## Windows-Specific Considerations
82
149
 
83
150
  ### File Locking
@@ -165,6 +165,27 @@ module Fontist
165
165
  end
166
166
  end
167
167
 
168
+ class WindowsFodInstallError < GeneralError
169
+ attr_reader :capability_name
170
+
171
+ def initialize(capability_name, stderr_output = nil)
172
+ @capability_name = capability_name
173
+ super(build_message(capability_name, stderr_output))
174
+ end
175
+
176
+ private
177
+
178
+ def build_message(cap_name, stderr)
179
+ msg = "Failed to install Windows font capability '#{cap_name}'."
180
+ msg += "\n#{stderr}" if stderr && !stderr.strip.empty?
181
+ msg += "\n\nPossible causes:" \
182
+ "\n - No internet connection (Windows Update required)" \
183
+ "\n - Insufficient permissions (admin required on Windows 10)" \
184
+ "\n - WSUS/SCCM policy blocking Features on Demand"
185
+ msg
186
+ end
187
+ end
188
+
168
189
  class UnsupportedMacOSVersionError < GeneralError
169
190
  def initialize(detected_version, available_frameworks)
170
191
  super(build_message(detected_version, available_frameworks))
@@ -90,6 +90,8 @@ module Fontist
90
90
  Resources::GoogleResource
91
91
  elsif @formula.source == "apple_cdn"
92
92
  Resources::AppleCDNResource
93
+ elsif @formula.source == "windows_fod"
94
+ Resources::WindowsFodResource
93
95
  else
94
96
  Resources::ArchiveResource
95
97
  end
@@ -45,6 +45,7 @@ module Fontist
45
45
  "MacosImportSource",
46
46
  "GoogleImportSource",
47
47
  "SilImportSource",
48
+ "WindowsImportSource",
48
49
  ]
49
50
  attribute :font_version, :string
50
51
 
@@ -68,6 +69,7 @@ module Fontist
68
69
  files: :files,
69
70
  format: :format,
70
71
  variable_axes: :variable_axes,
72
+ capability_name: :capability_name,
71
73
  }
72
74
  map "digest", to: :digest
73
75
  map "instructions", to: :instructions
@@ -86,6 +88,7 @@ module Fontist
86
88
  "macos" => "Fontist::MacosImportSource",
87
89
  "google" => "Fontist::GoogleImportSource",
88
90
  "sil" => "Fontist::SilImportSource",
91
+ "windows" => "Fontist::WindowsImportSource",
89
92
  },
90
93
  }
91
94
  map "font_version", to: :font_version
@@ -233,10 +236,18 @@ module Fontist
233
236
  import_source.is_a?(SilImportSource)
234
237
  end
235
238
 
239
+ def windows_import?
240
+ import_source.is_a?(WindowsImportSource)
241
+ end
242
+
236
243
  def manual_formula?
237
244
  import_source.nil?
238
245
  end
239
246
 
247
+ def windows_fod?
248
+ source == "windows_fod" && platforms&.any? { |p| p == "windows" || p.start_with?("windows-") }
249
+ end
250
+
240
251
  def compatible_with_current_platform?
241
252
  return true unless macos_import?
242
253
 
@@ -47,6 +47,11 @@ module Fontist
47
47
  version: @options[:import_source].version,
48
48
  release_date: @options[:import_source].release_date,
49
49
  )
50
+ when WindowsImportSource
51
+ builder.set_windows_import_source(
52
+ capability_name: @options[:import_source].capability_name,
53
+ min_windows_version: @options[:import_source].min_windows_version,
54
+ )
50
55
  end
51
56
  else
52
57
  # Legacy support for backward compatibility
@@ -85,6 +85,15 @@ family_id:)
85
85
  )
86
86
  end
87
87
 
88
+ # Convenience method to set Windows import source
89
+ def set_windows_import_source(capability_name:, min_windows_version: "10.0")
90
+ @import_source = WindowsImportSource.new(
91
+ type: "windows",
92
+ capability_name: capability_name,
93
+ min_windows_version: min_windows_version,
94
+ )
95
+ end
96
+
88
97
  private
89
98
 
90
99
  def formula_attributes