cataract 0.1.0
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.
- checksums.yaml +7 -0
- data/.clang-tidy +30 -0
- data/.github/workflows/ci-macos.yml +12 -0
- data/.github/workflows/ci.yml +77 -0
- data/.github/workflows/test.yml +76 -0
- data/.gitignore +45 -0
- data/.overcommit.yml +38 -0
- data/.rubocop.yml +83 -0
- data/BENCHMARKS.md +201 -0
- data/CHANGELOG.md +1 -0
- data/Gemfile +27 -0
- data/LICENSE +21 -0
- data/RAGEL_MIGRATION.md +60 -0
- data/README.md +292 -0
- data/Rakefile +209 -0
- data/benchmarks/benchmark_harness.rb +193 -0
- data/benchmarks/benchmark_merging.rb +121 -0
- data/benchmarks/benchmark_optimization_comparison.rb +168 -0
- data/benchmarks/benchmark_parsing.rb +153 -0
- data/benchmarks/benchmark_ragel_removal.rb +56 -0
- data/benchmarks/benchmark_runner.rb +70 -0
- data/benchmarks/benchmark_serialization.rb +180 -0
- data/benchmarks/benchmark_shorthand.rb +109 -0
- data/benchmarks/benchmark_shorthand_expansion.rb +176 -0
- data/benchmarks/benchmark_specificity.rb +124 -0
- data/benchmarks/benchmark_string_allocation.rb +151 -0
- data/benchmarks/benchmark_stylesheet_to_s.rb +62 -0
- data/benchmarks/benchmark_to_s_cached.rb +55 -0
- data/benchmarks/benchmark_value_splitter.rb +54 -0
- data/benchmarks/benchmark_yjit.rb +158 -0
- data/benchmarks/benchmark_yjit_workers.rb +61 -0
- data/benchmarks/profile_to_s.rb +23 -0
- data/benchmarks/speedup_calculator.rb +83 -0
- data/benchmarks/system_metadata.rb +81 -0
- data/benchmarks/templates/benchmarks.md.erb +221 -0
- data/benchmarks/yjit_tests.rb +141 -0
- data/cataract.gemspec +34 -0
- data/cliff.toml +92 -0
- data/examples/color_conversion_visual_test/color_conversion_test.html +3603 -0
- data/examples/color_conversion_visual_test/generate.rb +202 -0
- data/examples/color_conversion_visual_test/template.html.erb +259 -0
- data/examples/css_analyzer/analyzer.rb +164 -0
- data/examples/css_analyzer/analyzers/base.rb +33 -0
- data/examples/css_analyzer/analyzers/colors.rb +133 -0
- data/examples/css_analyzer/analyzers/important.rb +88 -0
- data/examples/css_analyzer/analyzers/properties.rb +61 -0
- data/examples/css_analyzer/analyzers/specificity.rb +68 -0
- data/examples/css_analyzer/templates/report.html.erb +575 -0
- data/examples/css_analyzer.rb +69 -0
- data/examples/github_analysis.html +5343 -0
- data/ext/cataract/cataract.c +1086 -0
- data/ext/cataract/cataract.h +174 -0
- data/ext/cataract/css_parser.c +1435 -0
- data/ext/cataract/extconf.rb +48 -0
- data/ext/cataract/import_scanner.c +174 -0
- data/ext/cataract/merge.c +973 -0
- data/ext/cataract/shorthand_expander.c +902 -0
- data/ext/cataract/specificity.c +213 -0
- data/ext/cataract/value_splitter.c +116 -0
- data/ext/cataract_color/cataract_color.c +16 -0
- data/ext/cataract_color/color_conversion.c +1687 -0
- data/ext/cataract_color/color_conversion.h +136 -0
- data/ext/cataract_color/color_conversion_lab.c +571 -0
- data/ext/cataract_color/color_conversion_named.c +259 -0
- data/ext/cataract_color/color_conversion_oklab.c +547 -0
- data/ext/cataract_color/extconf.rb +23 -0
- data/ext/cataract_old/cataract.c +393 -0
- data/ext/cataract_old/cataract.h +250 -0
- data/ext/cataract_old/css_parser.c +933 -0
- data/ext/cataract_old/extconf.rb +67 -0
- data/ext/cataract_old/import_scanner.c +174 -0
- data/ext/cataract_old/merge.c +776 -0
- data/ext/cataract_old/shorthand_expander.c +902 -0
- data/ext/cataract_old/specificity.c +213 -0
- data/ext/cataract_old/stylesheet.c +290 -0
- data/ext/cataract_old/value_splitter.c +116 -0
- data/lib/cataract/at_rule.rb +97 -0
- data/lib/cataract/color_conversion.rb +18 -0
- data/lib/cataract/declarations.rb +332 -0
- data/lib/cataract/import_resolver.rb +210 -0
- data/lib/cataract/rule.rb +131 -0
- data/lib/cataract/stylesheet.rb +716 -0
- data/lib/cataract/stylesheet_scope.rb +257 -0
- data/lib/cataract/version.rb +5 -0
- data/lib/cataract.rb +107 -0
- data/lib/tasks/gem.rake +158 -0
- data/scripts/fuzzer/run.rb +828 -0
- data/scripts/fuzzer/worker.rb +99 -0
- data/scripts/generate_benchmarks_md.rb +155 -0
- metadata +135 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
// color_conversion.h - Shared types and macros for CSS color conversion
|
|
2
|
+
#ifndef COLOR_CONVERSION_H
|
|
3
|
+
#define COLOR_CONVERSION_H
|
|
4
|
+
|
|
5
|
+
#include "cataract.h"
|
|
6
|
+
|
|
7
|
+
// Intermediate representation for colors
|
|
8
|
+
// All colors are stored as sRGB (0-255) for compatibility.
|
|
9
|
+
// Optionally, high-precision linear RGB can be preserved to avoid quantization loss.
|
|
10
|
+
struct color_ir {
|
|
11
|
+
// sRGB representation (0-255) - always populated
|
|
12
|
+
int red; // 0-255
|
|
13
|
+
int green; // 0-255
|
|
14
|
+
int blue; // 0-255
|
|
15
|
+
double alpha; // 0.0-1.0, or -1.0 for "no alpha"
|
|
16
|
+
|
|
17
|
+
// Optional high-precision linear RGB (0.0-1.0)
|
|
18
|
+
// Set has_linear_rgb = 1 if linear_* fields contain valid data
|
|
19
|
+
// Formatters that support high precision (e.g., oklab) should check this flag
|
|
20
|
+
// and prefer linear RGB over sRGB to avoid quantization errors
|
|
21
|
+
int has_linear_rgb;
|
|
22
|
+
double linear_r; // 0.0-1.0 (linear RGB, not gamma-corrected)
|
|
23
|
+
double linear_g; // 0.0-1.0
|
|
24
|
+
double linear_b; // 0.0-1.0
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
// Initialize color_ir struct with default values
|
|
28
|
+
#define INIT_COLOR_IR(color) do { \
|
|
29
|
+
(color).red = 0; \
|
|
30
|
+
(color).green = 0; \
|
|
31
|
+
(color).blue = 0; \
|
|
32
|
+
(color).alpha = -1.0; \
|
|
33
|
+
(color).has_linear_rgb = 0; \
|
|
34
|
+
(color).linear_r = 0.0; \
|
|
35
|
+
(color).linear_g = 0.0; \
|
|
36
|
+
(color).linear_b = 0.0; \
|
|
37
|
+
} while(0)
|
|
38
|
+
|
|
39
|
+
// Macros for parsing color values
|
|
40
|
+
#define SKIP_WHITESPACE(p) while (*(p) == ' ') (p)++
|
|
41
|
+
#define SKIP_SEPARATOR(p) while (*(p) == ',' || *(p) == ' ') (p)++
|
|
42
|
+
#define PARSE_INT(p, var) do { \
|
|
43
|
+
int is_negative = 0; \
|
|
44
|
+
if (*(p) == '-') { \
|
|
45
|
+
is_negative = 1; \
|
|
46
|
+
(p)++; \
|
|
47
|
+
} \
|
|
48
|
+
(var) = 0; \
|
|
49
|
+
while (*(p) >= '0' && *(p) <= '9') { \
|
|
50
|
+
(var) = (var) * 10 + (*(p) - '0'); \
|
|
51
|
+
(p)++; \
|
|
52
|
+
} \
|
|
53
|
+
if (is_negative) (var) = -(var); \
|
|
54
|
+
} while(0)
|
|
55
|
+
|
|
56
|
+
// Find matching closing parenthesis
|
|
57
|
+
// Sets 'end' pointer to character after closing paren
|
|
58
|
+
#define FIND_CLOSING_PAREN(start, end) do { \
|
|
59
|
+
int paren_count = 0; \
|
|
60
|
+
(end) = (start); \
|
|
61
|
+
while (*(end)) { \
|
|
62
|
+
if (*(end) == '(') paren_count++; \
|
|
63
|
+
if (*(end) == ')') { \
|
|
64
|
+
paren_count--; \
|
|
65
|
+
if (paren_count == 0) { \
|
|
66
|
+
(end)++; \
|
|
67
|
+
break; \
|
|
68
|
+
} \
|
|
69
|
+
} \
|
|
70
|
+
(end)++; \
|
|
71
|
+
} \
|
|
72
|
+
} while(0)
|
|
73
|
+
|
|
74
|
+
// Detect color format at current position
|
|
75
|
+
#define STARTS_WITH_RGB(p, remaining) \
|
|
76
|
+
((remaining) >= 4 && (p)[0] == 'r' && (p)[1] == 'g' && (p)[2] == 'b' && ((p)[3] == '(' || (p)[3] == 'a'))
|
|
77
|
+
|
|
78
|
+
#define STARTS_WITH_HSL(p, remaining) \
|
|
79
|
+
((remaining) >= 4 && (p)[0] == 'h' && (p)[1] == 's' && (p)[2] == 'l' && ((p)[3] == '(' || (p)[3] == 'a'))
|
|
80
|
+
|
|
81
|
+
#define STARTS_WITH_HWB(p, remaining) \
|
|
82
|
+
((remaining) >= 4 && (p)[0] == 'h' && (p)[1] == 'w' && (p)[2] == 'b' && ((p)[3] == '(' || (p)[3] == 'a'))
|
|
83
|
+
|
|
84
|
+
#define STARTS_WITH_OKLAB(p, remaining) \
|
|
85
|
+
((remaining) >= 6 && (p)[0] == 'o' && (p)[1] == 'k' && (p)[2] == 'l' && \
|
|
86
|
+
(p)[3] == 'a' && (p)[4] == 'b' && (p)[5] == '(')
|
|
87
|
+
|
|
88
|
+
#define STARTS_WITH_OKLCH(p, remaining) \
|
|
89
|
+
((remaining) >= 6 && (p)[0] == 'o' && (p)[1] == 'k' && (p)[2] == 'l' && \
|
|
90
|
+
(p)[3] == 'c' && (p)[4] == 'h' && (p)[5] == '(')
|
|
91
|
+
|
|
92
|
+
#define STARTS_WITH_LAB(p, remaining) \
|
|
93
|
+
((remaining) >= 4 && (p)[0] == 'l' && (p)[1] == 'a' && (p)[2] == 'b' && (p)[3] == '(')
|
|
94
|
+
|
|
95
|
+
#define STARTS_WITH_LCH(p, remaining) \
|
|
96
|
+
((remaining) >= 4 && (p)[0] == 'l' && (p)[1] == 'c' && (p)[2] == 'h' && (p)[3] == '(')
|
|
97
|
+
|
|
98
|
+
// Macros for formatting color values
|
|
99
|
+
#define FORMAT_RGB_MODERN(buf, red, green, blue) \
|
|
100
|
+
snprintf(buf, sizeof(buf), "rgb(%d %d %d)", red, green, blue)
|
|
101
|
+
#define FORMAT_RGB_LEGACY(buf, red, green, blue) \
|
|
102
|
+
snprintf(buf, sizeof(buf), "rgb(%d, %d, %d)", red, green, blue)
|
|
103
|
+
#define FORMAT_RGBA_MODERN(buf, red, green, blue, alpha) \
|
|
104
|
+
snprintf(buf, sizeof(buf), "rgb(%d %d %d / %.10g)", red, green, blue, alpha)
|
|
105
|
+
#define FORMAT_RGBA_LEGACY(buf, red, green, blue, alpha) \
|
|
106
|
+
snprintf(buf, sizeof(buf), "rgba(%d, %d, %d, %.10g)", red, green, blue, alpha)
|
|
107
|
+
#define FORMAT_HEX(buf, red, green, blue) \
|
|
108
|
+
snprintf(buf, sizeof(buf), "#%02x%02x%02x", red, green, blue)
|
|
109
|
+
#define FORMAT_HEX_ALPHA(buf, red, green, blue, alpha_int) \
|
|
110
|
+
snprintf(buf, sizeof(buf), "#%02x%02x%02x%02x", red, green, blue, alpha_int)
|
|
111
|
+
#define FORMAT_HSL(buf, hue, sat, light) \
|
|
112
|
+
snprintf(buf, sizeof(buf), "hsl(%d, %d%%, %d%%)", hue, sat, light)
|
|
113
|
+
#define FORMAT_HSLA(buf, hue, sat, light, alpha) \
|
|
114
|
+
snprintf(buf, sizeof(buf), "hsl(%d, %d%%, %d%%, %.10g)", hue, sat, light, alpha)
|
|
115
|
+
#define FORMAT_HWB(buf, hue, white, black) \
|
|
116
|
+
snprintf(buf, sizeof(buf), "hwb(%d %d%% %d%%)", hue, white, black)
|
|
117
|
+
#define FORMAT_HWBA(buf, hue, white, black, alpha) \
|
|
118
|
+
snprintf(buf, sizeof(buf), "hwb(%d %d%% %d%% / %.10g)", hue, white, black, alpha)
|
|
119
|
+
#define FORMAT_OKLAB(buf, l, a, b) \
|
|
120
|
+
snprintf(buf, sizeof(buf), "oklab(%.4f %.4f %.4f)", l, a, b)
|
|
121
|
+
#define FORMAT_OKLAB_ALPHA(buf, l, a, b, alpha) \
|
|
122
|
+
snprintf(buf, sizeof(buf), "oklab(%.4f %.4f %.4f / %.10g)", l, a, b, alpha)
|
|
123
|
+
#define FORMAT_RGB_PERCENT(buf, r_pct, g_pct, b_pct) \
|
|
124
|
+
snprintf(buf, sizeof(buf), "rgb(%.3f%% %.3f%% %.3f%%)", r_pct, g_pct, b_pct)
|
|
125
|
+
#define FORMAT_RGB_PERCENT_ALPHA(buf, r_pct, g_pct, b_pct, alpha) \
|
|
126
|
+
snprintf(buf, sizeof(buf), "rgb(%.3f%% %.3f%% %.3f%% / %.10g)", r_pct, g_pct, b_pct, alpha)
|
|
127
|
+
#define FORMAT_LAB(buf, l, a, b) \
|
|
128
|
+
snprintf(buf, sizeof(buf), "lab(%.4f%% %.4f %.4f)", l, a, b)
|
|
129
|
+
#define FORMAT_LAB_ALPHA(buf, l, a, b, alpha) \
|
|
130
|
+
snprintf(buf, sizeof(buf), "lab(%.4f%% %.4f %.4f / %.10g)", l, a, b, alpha)
|
|
131
|
+
#define FORMAT_LCH(buf, l, c, h) \
|
|
132
|
+
snprintf(buf, sizeof(buf), "lch(%.4f%% %.4f %.3f)", l, c, h)
|
|
133
|
+
#define FORMAT_LCH_ALPHA(buf, l, c, h, alpha) \
|
|
134
|
+
snprintf(buf, sizeof(buf), "lch(%.4f%% %.4f %.3f / %.10g)", l, c, h, alpha)
|
|
135
|
+
|
|
136
|
+
#endif // COLOR_CONVERSION_H
|