fontisan 0.2.13 → 0.2.16

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.
Files changed (145) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop_todo.yml +56 -196
  3. data/Gemfile +1 -1
  4. data/docs/.gitignore +17 -0
  5. data/docs/.vitepress/config.ts +317 -0
  6. data/docs/.vitepress/theme/components/ApiMethod.vue +127 -0
  7. data/docs/.vitepress/theme/components/Badge.vue +51 -0
  8. data/docs/.vitepress/theme/components/FeatureComparison.vue +87 -0
  9. data/docs/.vitepress/theme/components/HeroCodeBlock.vue +98 -0
  10. data/docs/.vitepress/theme/components/WithinHero.vue +30 -0
  11. data/docs/.vitepress/theme/index.ts +22 -0
  12. data/docs/.vitepress/theme/style.css +330 -0
  13. data/docs/api/conversion-options.md +141 -0
  14. data/docs/api/converters/curve-converter.md +34 -0
  15. data/docs/api/converters/hint-converter.md +34 -0
  16. data/docs/api/converters/outline-converter.md +27 -0
  17. data/docs/api/font-loader.md +111 -0
  18. data/docs/api/font-writer.md +103 -0
  19. data/docs/api/index.md +79 -0
  20. data/docs/api/models/glyph-accessor.md +43 -0
  21. data/docs/api/models/glyph.md +40 -0
  22. data/docs/api/models/table-analyzer.md +35 -0
  23. data/docs/api/sfnt-font.md +53 -0
  24. data/docs/api/type1-font.md +43 -0
  25. data/docs/api/validators/font-validator.md +31 -0
  26. data/docs/api/validators/helper.md +36 -0
  27. data/docs/api/validators/profile.md +39 -0
  28. data/docs/cli/convert.md +87 -0
  29. data/docs/cli/dump-table.md +110 -0
  30. data/docs/cli/export.md +176 -0
  31. data/docs/cli/features.md +124 -0
  32. data/docs/cli/glyphs.md +90 -0
  33. data/docs/cli/index.md +208 -0
  34. data/docs/cli/info.md +254 -0
  35. data/docs/cli/instance.md +122 -0
  36. data/docs/cli/ls.md +95 -0
  37. data/docs/cli/optical-size.md +94 -0
  38. data/docs/cli/pack.md +125 -0
  39. data/docs/cli/scripts.md +105 -0
  40. data/docs/cli/subset.md +39 -0
  41. data/docs/cli/tables.md +84 -0
  42. data/docs/cli/unicode.md +101 -0
  43. data/docs/cli/validate.md +48 -0
  44. data/docs/cli/variable.md +126 -0
  45. data/docs/cli/version.md +46 -0
  46. data/docs/guide/cli/convert.md +108 -0
  47. data/docs/guide/cli/export.md +138 -0
  48. data/docs/guide/cli/index.md +99 -0
  49. data/docs/guide/cli/info.md +144 -0
  50. data/docs/guide/cli/pack.md +155 -0
  51. data/docs/guide/cli/subset.md +118 -0
  52. data/docs/guide/cli/validate.md +139 -0
  53. data/docs/guide/color-fonts/bitmaps.md +177 -0
  54. data/docs/guide/color-fonts/colr-cpal.md +175 -0
  55. data/docs/guide/color-fonts/index.md +140 -0
  56. data/docs/guide/color-fonts/svg.md +154 -0
  57. data/docs/guide/color.md +51 -0
  58. data/docs/guide/comparisons/font-validator.md +222 -0
  59. data/docs/guide/comparisons/fonttools.md +200 -0
  60. data/docs/guide/comparisons/index.md +83 -0
  61. data/docs/guide/comparisons/lcdf-typetools.md +205 -0
  62. data/docs/guide/contributing.md +279 -0
  63. data/docs/guide/conversion/collections.md +251 -0
  64. data/docs/guide/conversion/curves.md +246 -0
  65. data/docs/guide/conversion/index.md +157 -0
  66. data/docs/guide/conversion/options.md +251 -0
  67. data/docs/guide/conversion/ttf-otf.md +184 -0
  68. data/docs/guide/conversion/type1.md +208 -0
  69. data/docs/guide/conversion/web.md +240 -0
  70. data/docs/guide/conversion.md +39 -0
  71. data/docs/guide/formats/collections.md +147 -0
  72. data/docs/guide/formats/dfont.md +99 -0
  73. data/docs/guide/formats/index.md +65 -0
  74. data/docs/guide/formats/otf.md +103 -0
  75. data/docs/guide/formats/svg.md +97 -0
  76. data/docs/guide/formats/ttf.md +105 -0
  77. data/docs/guide/formats/type1.md +118 -0
  78. data/docs/guide/formats/woff.md +115 -0
  79. data/docs/guide/hinting/autohint.md +141 -0
  80. data/docs/guide/hinting/conversion.md +161 -0
  81. data/docs/guide/hinting/index.md +86 -0
  82. data/docs/guide/hinting/postscript.md +149 -0
  83. data/docs/guide/hinting/truetype.md +135 -0
  84. data/docs/guide/hinting.md +44 -0
  85. data/docs/guide/index.md +152 -0
  86. data/docs/guide/installation.md +116 -0
  87. data/docs/guide/migrations/extract-ttc.md +549 -0
  88. data/docs/guide/migrations/font-validator.md +260 -0
  89. data/docs/guide/migrations/fonttools.md +208 -0
  90. data/docs/guide/migrations/index.md +64 -0
  91. data/docs/guide/migrations/otfinfo.md +197 -0
  92. data/docs/guide/quick-start.md +204 -0
  93. data/docs/guide/type1.md +58 -0
  94. data/docs/guide/universal-outline.md +151 -0
  95. data/docs/guide/validation/custom.md +195 -0
  96. data/docs/guide/validation/helpers.md +188 -0
  97. data/docs/guide/validation/index.md +132 -0
  98. data/docs/guide/validation/profiles.md +156 -0
  99. data/docs/guide/validation.md +47 -0
  100. data/docs/guide/variable-fonts/advanced.md +231 -0
  101. data/docs/guide/variable-fonts/axes.md +209 -0
  102. data/docs/guide/variable-fonts/conversion.md +197 -0
  103. data/docs/guide/variable-fonts/index.md +84 -0
  104. data/docs/guide/variable-fonts/instances.md +187 -0
  105. data/docs/guide/variable-fonts/named-instances.md +194 -0
  106. data/docs/guide/variable-fonts/static.md +168 -0
  107. data/docs/guide/variable.md +58 -0
  108. data/docs/guide/woff.md +59 -0
  109. data/docs/index.md +136 -0
  110. data/docs/lychee.toml +37 -0
  111. data/docs/package-lock.json +2560 -0
  112. data/docs/package.json +15 -0
  113. data/docs/public/apple-touch-icon.png +0 -0
  114. data/docs/public/favicon-96x96.png +0 -0
  115. data/docs/public/favicon.ico +0 -0
  116. data/docs/public/favicon.svg +1 -0
  117. data/docs/public/logo-full.svg +1 -0
  118. data/docs/public/logo.svg +1 -0
  119. data/docs/public/site.webmanifest +21 -0
  120. data/docs/public/web-app-manifest-192x192.png +0 -0
  121. data/docs/public/web-app-manifest-512x512.png +0 -0
  122. data/fontisan.gemspec +1 -1
  123. data/lib/fontisan/commands/features_command.rb +0 -1
  124. data/lib/fontisan/commands/info_command.rb +5 -5
  125. data/lib/fontisan/commands/scripts_command.rb +0 -1
  126. data/lib/fontisan/converters/format_converter.rb +2 -1
  127. data/lib/fontisan/converters/type1_converter.rb +65 -60
  128. data/lib/fontisan/hints/hint_converter.rb +2 -1
  129. data/lib/fontisan/loading_modes.rb +0 -2
  130. data/lib/fontisan/open_type_font.rb +0 -40
  131. data/lib/fontisan/sfnt_font.rb +41 -22
  132. data/lib/fontisan/tables/glyf/compound_glyph.rb +0 -1
  133. data/lib/fontisan/true_type_collection.rb +8 -8
  134. data/lib/fontisan/true_type_font.rb +1 -59
  135. data/lib/fontisan/type1/afm_parser.rb +2 -1
  136. data/lib/fontisan/type1/cff_to_type1_converter.rb +24 -19
  137. data/lib/fontisan/type1/private_dict.rb +28 -7
  138. data/lib/fontisan/type1/seac_expander.rb +22 -17
  139. data/lib/fontisan/variable/delta_applicator.rb +3 -3
  140. data/lib/fontisan/variation/optimizer.rb +0 -1
  141. data/lib/fontisan/version.rb +1 -1
  142. data/lib/fontisan/woff2_font.rb +2 -2
  143. data/lib/fontisan/woff_font.rb +3 -3
  144. data/lib/fontisan.rb +3 -2
  145. metadata +122 -4
@@ -0,0 +1,139 @@
1
+ ---
2
+ title: validate
3
+ ---
4
+
5
+ # validate
6
+
7
+ Validate fonts for correctness.
8
+
9
+ ## Usage
10
+
11
+ ```bash
12
+ fontisan validate FONT [options]
13
+ ```
14
+
15
+ ## Arguments
16
+
17
+ | Argument | Description |
18
+ |----------|-------------|
19
+ | `FONT` | Font file to validate |
20
+ | `FONT ...` | Multiple files |
21
+
22
+ ## Options
23
+
24
+ | Option | Description |
25
+ |--------|-------------|
26
+ | `-t, --profile PROFILE` | Validation profile |
27
+ | `-S, --summary` | Show summary only |
28
+ | `-T, --table` | Table format output |
29
+ | `--list` | List available profiles |
30
+
31
+ ## Profiles
32
+
33
+ | Profile | Description |
34
+ |---------|-------------|
35
+ | `indexability` | Fast font discovery |
36
+ | `usability` | Installation compatibility |
37
+ | `production` | Comprehensive quality (default) |
38
+ | `web` | Web embedding readiness |
39
+ | `spec_compliance` | Full spec compliance |
40
+
41
+ ## Examples
42
+
43
+ ### Basic Validation
44
+
45
+ ```bash
46
+ fontisan validate font.ttf
47
+
48
+ # Font: font.ttf
49
+ # Status: VALID
50
+ #
51
+ # Summary:
52
+ # Checks performed: 37
53
+ # Passed: 37
54
+ # Failed: 0
55
+ ```
56
+
57
+ ### With Profile
58
+
59
+ ```bash
60
+ fontisan validate font.ttf -t web
61
+
62
+ # Font: font.ttf
63
+ # Profile: web
64
+ # Status: INVALID
65
+ #
66
+ # Summary:
67
+ # Checks performed: 18
68
+ # Passed: 17
69
+ # Failed: 1
70
+ #
71
+ # Failed checks:
72
+ # web_font_tables - Missing required GSUB table
73
+ ```
74
+
75
+ ### Summary Only
76
+
77
+ ```bash
78
+ fontisan validate font.ttf -S
79
+
80
+ # font.ttf: VALID (37/37 checks passed)
81
+ ```
82
+
83
+ ### Table Format
84
+
85
+ ```bash
86
+ fontisan validate font.ttf -T
87
+
88
+ # CHECK_ID | STATUS | SEVERITY | TABLE
89
+ # --------------------------------------------------
90
+ # required_tables | PASS | error | N/A
91
+ # name_version | PASS | error | name
92
+ # family_name | PASS | error | name
93
+ # head_magic | PASS | error | head
94
+ # ...
95
+ ```
96
+
97
+ ### Multiple Files
98
+
99
+ ```bash
100
+ fontisan validate fonts/*.ttf
101
+
102
+ # fonts/regular.ttf: VALID
103
+ # fonts/bold.ttf: VALID
104
+ # fonts/italic.ttf: INVALID (1 error)
105
+ ```
106
+
107
+ ### List Profiles
108
+
109
+ ```bash
110
+ fontisan validate --list
111
+
112
+ # Available validation profiles:
113
+ # indexability - Fast validation for font discovery
114
+ # usability - Basic usability for installation
115
+ # production - Comprehensive quality checks
116
+ # web - Web embedding and optimization
117
+ # spec_compliance - Full OpenType spec compliance
118
+ ```
119
+
120
+ ## Exit Codes
121
+
122
+ | Code | Meaning |
123
+ |------|---------|
124
+ | 0 | Valid |
125
+ | 1 | Invalid (errors found) |
126
+ | 2 | Error (file not found, etc.) |
127
+
128
+ ## Use in Scripts
129
+
130
+ ```bash
131
+ # Validate before release
132
+ fontisan validate font.ttf -t production
133
+ if [ $? -eq 0 ]; then
134
+ echo "Ready for release"
135
+ else
136
+ echo "Validation failed"
137
+ exit 1
138
+ fi
139
+ ```
@@ -0,0 +1,177 @@
1
+ ---
2
+ title: Bitmap Color Fonts
3
+ ---
4
+
5
+ # Bitmap Color Fonts
6
+
7
+ Bitmap color fonts store pixel images at specific sizes.
8
+
9
+ ## Formats
10
+
11
+ | Format | Tables | Platform |
12
+ |--------|--------|----------|
13
+ | sbix | sbix | Apple |
14
+ | CBDT/CBLC | CBDT, CBLC | Google/Android |
15
+
16
+ ## sbix (Apple)
17
+
18
+ sbix stores bitmap images at multiple resolutions.
19
+
20
+ ### Structure
21
+
22
+ ```ruby
23
+ sbix = font.tables['sbix']
24
+
25
+ # Strikes (image sets at different sizes)
26
+ sbix.strikes.each do |strike|
27
+ puts "Strike at #{strike.ppem} ppem"
28
+
29
+ strike.glyphs.each do |glyph_id, image|
30
+ puts " Glyph #{glyph_id}: #{image.format}"
31
+ end
32
+ end
33
+ ```
34
+
35
+ ### Image Formats
36
+
37
+ - `png ` — PNG image
38
+ - `jpg ` — JPEG image
39
+ - `tiff` — TIFF image
40
+ - `dupe` — Duplicate of another glyph
41
+
42
+ ### Accessing Images
43
+
44
+ ```ruby
45
+ sbix = font.tables['sbix']
46
+ strike = sbix.strikes.first
47
+
48
+ glyph_id = 42
49
+ image = strike.image_for(glyph_id)
50
+
51
+ puts "Format: #{image.format}"
52
+ puts "Data size: #{image.data.length} bytes"
53
+ ```
54
+
55
+ ## CBDT/CBLC (Android)
56
+
57
+ CBDT/CBLC stores bitmap images for Android.
58
+
59
+ ### Structure
60
+
61
+ ```ruby
62
+ cbdt = font.tables['CBDT']
63
+ cblc = font.tables['CBLC']
64
+
65
+ # CBLC has location data
66
+ cblc.strikes.each do |strike|
67
+ puts "Strike at #{strike.ppem}x#{strike.ppem}"
68
+
69
+ strike.glyph_ranges.each do |range|
70
+ puts " Glyphs #{range.start}..#{range.end}"
71
+ end
72
+ end
73
+
74
+ # CBDT has actual bitmap data
75
+ ```
76
+
77
+ ### Bitmap Formats
78
+
79
+ - **Small metrics** — For small glyphs
80
+ - **Big metrics** — For larger glyphs
81
+ - **Bit aligned** — 1, 2, 4, or 8 bits per pixel
82
+
83
+ ### Accessing Bitmaps
84
+
85
+ ```ruby
86
+ cbdt = font.tables['CBDT']
87
+ cblc = font.tables['CBLC']
88
+
89
+ glyph_id = 42
90
+ strike_index = 0
91
+
92
+ # Get bitmap location
93
+ location = cblc.location(strike_index, glyph_id)
94
+
95
+ if location
96
+ # Get bitmap data
97
+ bitmap = cbdt.bitmap(location)
98
+ puts "Size: #{bitmap.width}x#{bitmap.height}"
99
+ puts "Data: #{bitmap.data.length} bytes"
100
+ end
101
+ ```
102
+
103
+ ## Working with Bitmaps
104
+
105
+ ### List Available Sizes
106
+
107
+ ```ruby
108
+ sbix = font.tables['sbix']
109
+
110
+ if sbix
111
+ puts "Available sizes:"
112
+ sbix.strikes.each do |strike|
113
+ puts " #{strike.ppem} ppem"
114
+ end
115
+ end
116
+ ```
117
+
118
+ ### Export Bitmaps
119
+
120
+ ```ruby
121
+ sbix = font.tables['sbix']
122
+ strike = sbix.strikes.first
123
+
124
+ sbix.glyphs.each do |glyph_id, image|
125
+ if image.format == 'png '
126
+ File.write("glyph-#{glyph_id}.png", image.data)
127
+ end
128
+ end
129
+ ```
130
+
131
+ ## Conversion
132
+
133
+ ### Preserve Bitmaps
134
+
135
+ ```bash
136
+ # Bitmaps preserved during same-format conversion
137
+ fontisan convert bitmap-font.ttf --to ttf --output bitmap-font.ttf
138
+ ```
139
+
140
+ ### Remove Bitmaps
141
+
142
+ ```bash
143
+ # Create outline-only version
144
+ fontisan convert bitmap-font.ttf --to ttf --no-bitmaps --output outline-only.ttf
145
+ ```
146
+
147
+ ## Comparison
148
+
149
+ | Feature | sbix | CBDT/CBLC |
150
+ |---------|------|-----------|
151
+ | Platform | Apple | Android |
152
+ | Image formats | PNG, JPEG, TIFF | Raw bitmap |
153
+ | Scalability | No | No |
154
+ | File size | Larger | Smaller |
155
+ | Quality | Photo-realistic | Limited |
156
+
157
+ ## Limitations
158
+
159
+ ### Bitmap Scaling
160
+
161
+ Bitmap fonts don't scale well:
162
+ - Each strike is designed for a specific ppem
163
+ - Scaling up causes pixelation
164
+ - Scaling down causes aliasing
165
+
166
+ ### Variable Fonts
167
+
168
+ Bitmap fonts don't work with variation:
169
+ - No interpolation possible
170
+ - Must provide strikes for each instance
171
+
172
+ ## Best Practices
173
+
174
+ 1. **Provide multiple strikes** — Cover common sizes
175
+ 2. **Use PNG for sbix** — Best quality/size tradeoff
176
+ 3. **Test on target platforms** — Rendering varies
177
+ 4. **Consider outline fallback** — For unavailable sizes
@@ -0,0 +1,175 @@
1
+ ---
2
+ title: COLR/CPAL Color Fonts
3
+ ---
4
+
5
+ # COLR/CPAL Color Fonts
6
+
7
+ COLR/CPAL is a modern color font format using layered vector glyphs.
8
+
9
+ ## Overview
10
+
11
+ - **COLR** — Defines glyph layers and their order
12
+ - **CPAL** — Defines color palettes
13
+
14
+ ## Structure
15
+
16
+ ### COLR Table
17
+
18
+ ```ruby
19
+ colr = font.tables['COLR']
20
+
21
+ # Base glyphs (color emoji)
22
+ base_glyphs = colr.base_glyphs
23
+
24
+ # Layers for a base glyph
25
+ layers = colr.layers_for(glyph_id)
26
+ # Returns array of { glyph_id:, palette_index: }
27
+ ```
28
+
29
+ ### CPAL Table
30
+
31
+ ```ruby
32
+ cpal = font.tables['CPAL']
33
+
34
+ # Number of palettes
35
+ num_palettes = cpal.num_palettes
36
+
37
+ # Colors in a palette
38
+ palette_colors = cpal.palette(0) # First palette
39
+
40
+ # Get specific color
41
+ color = cpal.color(palette_index)
42
+ # Returns { r:, g:, b:, a: }
43
+ ```
44
+
45
+ ## Working with COLR/CPAL
46
+
47
+ ### List Color Glyphs
48
+
49
+ ```ruby
50
+ font = Fontisan::FontLoader.load('color-font.ttf')
51
+ colr = font.tables['COLR']
52
+
53
+ colr.base_glyphs.each do |glyph_id|
54
+ glyph_name = font.glyph_name(glyph_id)
55
+ puts "#{glyph_name} (#{glyph_id})"
56
+ end
57
+ ```
58
+
59
+ ### Get Layer Colors
60
+
61
+ ```ruby
62
+ colr = font.tables['COLR']
63
+ cpal = font.tables['CPAL']
64
+
65
+ colr.base_glyphs.each do |glyph_id|
66
+ puts "Glyph #{glyph_id}:"
67
+
68
+ colr.layers_for(glyph_id).each do |layer|
69
+ color = cpal.color(layer[:palette_index])
70
+ layer_name = font.glyph_name(layer[:glyph_id])
71
+ puts " #{layer_name}: rgba(#{color[:r]}, #{color[:g]}, #{color[:b]}, #{color[:a]})"
72
+ end
73
+ end
74
+ ```
75
+
76
+ ## Color Palettes
77
+
78
+ ### Default Palette
79
+
80
+ ```ruby
81
+ cpal = font.tables['CPAL']
82
+
83
+ # First palette (default)
84
+ default_palette = cpal.palette(0)
85
+ puts "Default palette has #{default_palette.length} colors"
86
+ ```
87
+
88
+ ### Multiple Palettes
89
+
90
+ Some fonts have alternative color schemes:
91
+
92
+ ```ruby
93
+ cpal = font.tables['CPAL']
94
+
95
+ (0...cpal.num_palettes).each do |palette_index|
96
+ puts "Palette #{palette_index}:"
97
+ cpal.palette(palette_index).each_with_index do |color, i|
98
+ puts " Color #{i}: rgba(#{color[:r]}, #{color[:g]}, #{color[:b]}, #{color[:a]})"
99
+ end
100
+ end
101
+ ```
102
+
103
+ ## Conversion
104
+
105
+ ### Preserve COLR/CPAL
106
+
107
+ ```bash
108
+ # COLR/CPAL is preserved during same-format conversion
109
+ fontisan convert color-font.ttf --to otf --output color-font.otf
110
+ ```
111
+
112
+ ### Flatten to PNG
113
+
114
+ ```bash
115
+ # Export color glyphs as PNG images
116
+ fontisan export color-font.ttf --format png --output ./images/
117
+ ```
118
+
119
+ ## Creating COLR/CPAL
120
+
121
+ Currently Fontisan focuses on reading and preserving COLR/CPAL. For creation, consider:
122
+
123
+ 1. Design glyphs in layers
124
+ 2. Assign palette indices
125
+ 3. Define color palettes
126
+ 4. Use font editor (Glyphs, FontForge)
127
+
128
+ ## Browser Support
129
+
130
+ | Browser | Version |
131
+ |---------|---------|
132
+ | Chrome | 98+ |
133
+ | Firefox | 105+ |
134
+ | Safari | 15.4+ |
135
+ | Edge | 98+ |
136
+
137
+ ## Validation
138
+
139
+ ```bash
140
+ # Validate color font
141
+ fontisan validate color-font.ttf
142
+
143
+ # Check COLR structure
144
+ fontisan info color-font.ttf
145
+ ```
146
+
147
+ ## Example
148
+
149
+ ### Analyze Color Emoji Font
150
+
151
+ ```ruby
152
+ font = Fontisan::FontLoader.load('emoji.ttf')
153
+ colr = font.tables['COLR']
154
+ cpal = font.tables['CPAL']
155
+
156
+ puts "Color glyphs: #{colr.base_glyphs.length}"
157
+ puts "Palettes: #{cpal.num_palettes}"
158
+
159
+ # Find glyph for specific character
160
+ cmap = font.tables['cmap']
161
+ glyph_id = cmap.glyph_id_for('😀')
162
+
163
+ if colr.base_glyphs.include?(glyph_id)
164
+ puts "😀 is a color glyph"
165
+
166
+ layers = colr.layers_for(glyph_id)
167
+ puts "Composed of #{layers.length} layers:"
168
+
169
+ layers.each do |layer|
170
+ layer_name = font.glyph_name(layer[:glyph_id])
171
+ color = cpal.color(layer[:palette_index])
172
+ puts " #{layer_name}: rgba(#{color[:r]}, #{color[:g]}, #{color[:b]})"
173
+ end
174
+ end
175
+ ```
@@ -0,0 +1,140 @@
1
+ ---
2
+ title: Color Fonts Overview
3
+ ---
4
+
5
+ # Color Fonts Overview
6
+
7
+ Fontisan supports multiple color font formats for modern typography.
8
+
9
+ ## Supported Formats
10
+
11
+ | Format | Tables | Description |
12
+ |--------|--------|-------------|
13
+ | COLR/CPAL | COLR, CPAL | Layered vector glyphs |
14
+ | sbix | sbix | Bitmap images (Apple) |
15
+ | CBDT/CBLC | CBDT, CBLC | Bitmap images (Google) |
16
+ | SVG | SVG | SVG embedded in font |
17
+
18
+ ## COLR/CPAL
19
+
20
+ COLR/CPAL uses layered vector glyphs with palette-based coloring.
21
+
22
+ ### Advantages
23
+
24
+ - **Scalable** — Vectors scale to any size
25
+ - **Small file size** — Efficient compression
26
+ - **Variable support** — Works with variable fonts
27
+ - **Wide support** — Modern browsers and apps
28
+
29
+ ### Structure
30
+
31
+ ```
32
+ COLR table:
33
+ - Glyph layers (which glyphs make up each color glyph)
34
+ - Layer order (back to front)
35
+
36
+ CPAL table:
37
+ - Color palettes (sets of colors)
38
+ - Color values (RGBA for each palette entry)
39
+ ```
40
+
41
+ ## sbix
42
+
43
+ sbix stores bitmap images at multiple resolutions (Apple format).
44
+
45
+ ### Advantages
46
+
47
+ - **Photo-realistic** — Any image quality
48
+ - **Multiple sizes** — Different bitmaps for different sizes
49
+
50
+ ### Structure
51
+
52
+ ```
53
+ sbix table:
54
+ - Strikes (image sets at different sizes)
55
+ - Per-glyph images (PNG, JPG, etc.)
56
+ ```
57
+
58
+ ## CBDT/CBLC
59
+
60
+ CBDT/CBLC stores bitmap images (Google/Android format).
61
+
62
+ ### Advantages
63
+
64
+ - **Android support** — Primary Android bitmap format
65
+ - **Multiple sizes** — Different bitmaps per ppem
66
+
67
+ ### Structure
68
+
69
+ ```
70
+ CBLC table:
71
+ - Location data (where each bitmap is)
72
+ - Size information
73
+
74
+ CBDT table:
75
+ - Bitmap data (actual images)
76
+ ```
77
+
78
+ ## SVG Color Fonts
79
+
80
+ SVG fonts embed complete SVG documents.
81
+
82
+ ### Advantages
83
+
84
+ - **Full SVG features** — Gradients, effects, etc.
85
+ - **Standalone** — No external resources
86
+
87
+ ### Limitations
88
+
89
+ - **Large file size** — XML overhead
90
+ - **Limited support** — Not all browsers
91
+
92
+ ## Guides
93
+
94
+ - [COLR/CPAL](/guide/color-fonts/colr-cpal) — Vector layered color fonts
95
+ - [Bitmaps](/guide/color-fonts/bitmaps) — sbix and CBDT/CBLC
96
+ - [SVG Color](/guide/color-fonts/svg) — SVG-based color fonts
97
+
98
+ ## Quick Start
99
+
100
+ ### Check for Color Tables
101
+
102
+ ```ruby
103
+ font = Fontisan::FontLoader.load('font.ttf')
104
+
105
+ if font.tables['COLR']
106
+ puts "COLR/CPAL color font"
107
+ end
108
+
109
+ if font.tables['sbix']
110
+ puts "sbix bitmap font"
111
+ end
112
+
113
+ if font.tables['CBDT']
114
+ puts "CBDT/CBLC bitmap font"
115
+ end
116
+
117
+ if font.tables['SVG']
118
+ puts "SVG color font"
119
+ end
120
+ ```
121
+
122
+ ### Get Color Information
123
+
124
+ ```ruby
125
+ colr = font.tables['COLR']
126
+ cpal = font.tables['CPAL']
127
+
128
+ if colr && cpal
129
+ # Get base glyphs (color emoji)
130
+ colr.base_glyphs.each do |glyph_id|
131
+ puts "Base glyph: #{glyph_id}"
132
+ puts " Layers: #{colr.layers_for(glyph_id).length}"
133
+
134
+ colr.layers_for(glyph_id).each do |layer|
135
+ color = cpal.color(layer[:palette_index])
136
+ puts " Layer #{layer[:glyph_id]}: #{color}"
137
+ end
138
+ end
139
+ end
140
+ ```