1// sass.hpp must go before all system headers to get the
2// __EXTENSIONS__ fix on Solaris.
3#include "sass.hpp"
4
5#include <iomanip>
6#include "ast.hpp"
7#include "fn_utils.hpp"
8#include "fn_colors.hpp"
9#include "util.hpp"
10#include "util_string.hpp"
11
12namespace Sass {
13
14 namespace Functions {
15
16 bool string_argument(AST_Node_Obj obj) {
17 String_Constant* s = Cast<String_Constant>(ptr: obj);
18 if (s == nullptr) return false;
19 const sass::string& str = s->value();
20 return starts_with(str, prefix: "calc(") ||
21 starts_with(str, prefix: "var(");
22 }
23
24 void hsla_alpha_percent_deprecation(const SourceSpan& pstate, const sass::string val)
25 {
26
27 sass::string msg("Passing a percentage as the alpha value to hsla() will be interpreted");
28 sass::string tail("differently in future versions of Sass. For now, use " + val + " instead.");
29
30 deprecated(msg, msg2: tail, with_column: false, pstate);
31
32 }
33
34 Signature rgb_sig = "rgb($red, $green, $blue)";
35 BUILT_IN(rgb)
36 {
37 if (
38 string_argument(obj: env["$red"]) ||
39 string_argument(obj: env["$green"]) ||
40 string_argument(obj: env["$blue"])
41 ) {
42 return SASS_MEMORY_NEW(String_Constant, pstate, "rgb("
43 + env["$red"]->to_string()
44 + ", "
45 + env["$green"]->to_string()
46 + ", "
47 + env["$blue"]->to_string()
48 + ")"
49 );
50 }
51
52 return SASS_MEMORY_NEW(Color_RGBA,
53 pstate,
54 COLOR_NUM("$red"),
55 COLOR_NUM("$green"),
56 COLOR_NUM("$blue"));
57 }
58
59 Signature rgba_4_sig = "rgba($red, $green, $blue, $alpha)";
60 BUILT_IN(rgba_4)
61 {
62 if (
63 string_argument(obj: env["$red"]) ||
64 string_argument(obj: env["$green"]) ||
65 string_argument(obj: env["$blue"]) ||
66 string_argument(obj: env["$alpha"])
67 ) {
68 return SASS_MEMORY_NEW(String_Constant, pstate, "rgba("
69 + env["$red"]->to_string()
70 + ", "
71 + env["$green"]->to_string()
72 + ", "
73 + env["$blue"]->to_string()
74 + ", "
75 + env["$alpha"]->to_string()
76 + ")"
77 );
78 }
79
80 return SASS_MEMORY_NEW(Color_RGBA,
81 pstate,
82 COLOR_NUM("$red"),
83 COLOR_NUM("$green"),
84 COLOR_NUM("$blue"),
85 ALPHA_NUM("$alpha"));
86 }
87
88 Signature rgba_2_sig = "rgba($color, $alpha)";
89 BUILT_IN(rgba_2)
90 {
91 if (
92 string_argument(obj: env["$color"])
93 ) {
94 return SASS_MEMORY_NEW(String_Constant, pstate, "rgba("
95 + env["$color"]->to_string()
96 + ", "
97 + env["$alpha"]->to_string()
98 + ")"
99 );
100 }
101
102 Color_RGBA_Obj c_arg = ARG("$color", Color)->toRGBA();
103
104 if (
105 string_argument(obj: env["$alpha"])
106 ) {
107 sass::ostream strm;
108 strm << "rgba("
109 << (int)c_arg->r() << ", "
110 << (int)c_arg->g() << ", "
111 << (int)c_arg->b() << ", "
112 << env["$alpha"]->to_string()
113 << ")";
114 return SASS_MEMORY_NEW(String_Constant, pstate, strm.str());
115 }
116
117 Color_RGBA_Obj new_c = SASS_MEMORY_COPY(c_arg);
118 new_c->a(ALPHA_NUM("$alpha"));
119 new_c->disp(disp__: "");
120 return new_c.detach();
121 }
122
123 ////////////////
124 // RGB FUNCTIONS
125 ////////////////
126
127 Signature red_sig = "red($color)";
128 BUILT_IN(red)
129 {
130 Color_RGBA_Obj color = ARG("$color", Color)->toRGBA();
131 return SASS_MEMORY_NEW(Number, pstate, color->r());
132 }
133
134 Signature green_sig = "green($color)";
135 BUILT_IN(green)
136 {
137 Color_RGBA_Obj color = ARG("$color", Color)->toRGBA();
138 return SASS_MEMORY_NEW(Number, pstate, color->g());
139 }
140
141 Signature blue_sig = "blue($color)";
142 BUILT_IN(blue)
143 {
144 Color_RGBA_Obj color = ARG("$color", Color)->toRGBA();
145 return SASS_MEMORY_NEW(Number, pstate, color->b());
146 }
147
148 Color_RGBA* colormix(Context& ctx, SourceSpan& pstate, Color* color1, Color* color2, double weight) {
149 Color_RGBA_Obj c1 = color1->toRGBA();
150 Color_RGBA_Obj c2 = color2->toRGBA();
151 double p = weight/100;
152 double w = 2*p - 1;
153 double a = c1->a() - c2->a();
154
155 double w1 = (((w * a == -1) ? w : (w + a)/(1 + w*a)) + 1)/2.0;
156 double w2 = 1 - w1;
157
158 return SASS_MEMORY_NEW(Color_RGBA,
159 pstate,
160 Sass::round(w1*c1->r() + w2*c2->r(), ctx.c_options.precision),
161 Sass::round(w1*c1->g() + w2*c2->g(), ctx.c_options.precision),
162 Sass::round(w1*c1->b() + w2*c2->b(), ctx.c_options.precision),
163 c1->a()*p + c2->a()*(1-p));
164 }
165
166 Signature mix_sig = "mix($color1, $color2, $weight: 50%)";
167 BUILT_IN(mix)
168 {
169 Color_Obj color1 = ARG("$color1", Color);
170 Color_Obj color2 = ARG("$color2", Color);
171 double weight = DARG_U_PRCT("$weight");
172 return colormix(ctx, pstate, color1, color2, weight);
173
174 }
175
176 ////////////////
177 // HSL FUNCTIONS
178 ////////////////
179
180 Signature hsl_sig = "hsl($hue, $saturation, $lightness)";
181 BUILT_IN(hsl)
182 {
183 if (
184 string_argument(obj: env["$hue"]) ||
185 string_argument(obj: env["$saturation"]) ||
186 string_argument(obj: env["$lightness"])
187 ) {
188 return SASS_MEMORY_NEW(String_Constant, pstate, "hsl("
189 + env["$hue"]->to_string()
190 + ", "
191 + env["$saturation"]->to_string()
192 + ", "
193 + env["$lightness"]->to_string()
194 + ")"
195 );
196 }
197
198 return SASS_MEMORY_NEW(Color_HSLA,
199 pstate,
200 ARGVAL("$hue"),
201 ARGVAL("$saturation"),
202 ARGVAL("$lightness"),
203 1.0);
204
205 }
206
207 Signature hsla_sig = "hsla($hue, $saturation, $lightness, $alpha)";
208 BUILT_IN(hsla)
209 {
210 if (
211 string_argument(obj: env["$hue"]) ||
212 string_argument(obj: env["$saturation"]) ||
213 string_argument(obj: env["$lightness"]) ||
214 string_argument(obj: env["$alpha"])
215 ) {
216 return SASS_MEMORY_NEW(String_Constant, pstate, "hsla("
217 + env["$hue"]->to_string()
218 + ", "
219 + env["$saturation"]->to_string()
220 + ", "
221 + env["$lightness"]->to_string()
222 + ", "
223 + env["$alpha"]->to_string()
224 + ")"
225 );
226 }
227
228 Number* alpha = ARG("$alpha", Number);
229 if (alpha && alpha->unit() == "%") {
230 Number_Obj val = SASS_MEMORY_COPY(alpha);
231 val->numerators.clear(); // convert
232 val->value(value__: val->value() / 100.0);
233 sass::string nr(val->to_string(opt: ctx.c_options));
234 hsla_alpha_percent_deprecation(pstate, val: nr);
235 }
236
237 return SASS_MEMORY_NEW(Color_HSLA,
238 pstate,
239 ARGVAL("$hue"),
240 ARGVAL("$saturation"),
241 ARGVAL("$lightness"),
242 ARGVAL("$alpha"));
243
244 }
245
246 /////////////////////////////////////////////////////////////////////////
247 // Query functions
248 /////////////////////////////////////////////////////////////////////////
249
250 Signature hue_sig = "hue($color)";
251 BUILT_IN(hue)
252 {
253 Color_HSLA_Obj col = ARG("$color", Color)->toHSLA();
254 return SASS_MEMORY_NEW(Number, pstate, col->h(), "deg");
255 }
256
257 Signature saturation_sig = "saturation($color)";
258 BUILT_IN(saturation)
259 {
260 Color_HSLA_Obj col = ARG("$color", Color)->toHSLA();
261 return SASS_MEMORY_NEW(Number, pstate, col->s(), "%");
262 }
263
264 Signature lightness_sig = "lightness($color)";
265 BUILT_IN(lightness)
266 {
267 Color_HSLA_Obj col = ARG("$color", Color)->toHSLA();
268 return SASS_MEMORY_NEW(Number, pstate, col->l(), "%");
269 }
270
271 /////////////////////////////////////////////////////////////////////////
272 // HSL manipulation functions
273 /////////////////////////////////////////////////////////////////////////
274
275 Signature adjust_hue_sig = "adjust-hue($color, $degrees)";
276 BUILT_IN(adjust_hue)
277 {
278 Color* col = ARG("$color", Color);
279 double degrees = ARGVAL("$degrees");
280 Color_HSLA_Obj copy = col->copyAsHSLA();
281 copy->h(h__: absmod(n: copy->h() + degrees, r: 360.0));
282 return copy.detach();
283 }
284
285 Signature lighten_sig = "lighten($color, $amount)";
286 BUILT_IN(lighten)
287 {
288 Color* col = ARG("$color", Color);
289 double amount = DARG_U_PRCT("$amount");
290 Color_HSLA_Obj copy = col->copyAsHSLA();
291 copy->l(l__: clip(n: copy->l() + amount, lower: 0.0, upper: 100.0));
292 return copy.detach();
293
294 }
295
296 Signature darken_sig = "darken($color, $amount)";
297 BUILT_IN(darken)
298 {
299 Color* col = ARG("$color", Color);
300 double amount = DARG_U_PRCT("$amount");
301 Color_HSLA_Obj copy = col->copyAsHSLA();
302 copy->l(l__: clip(n: copy->l() - amount, lower: 0.0, upper: 100.0));
303 return copy.detach();
304 }
305
306 Signature saturate_sig = "saturate($color, $amount: false)";
307 BUILT_IN(saturate)
308 {
309 // CSS3 filter function overload: pass literal through directly
310 if (!Cast<Number>(ptr: env["$amount"])) {
311 return SASS_MEMORY_NEW(String_Quoted, pstate, "saturate(" + env["$color"]->to_string(ctx.c_options) + ")");
312 }
313
314 Color* col = ARG("$color", Color);
315 double amount = DARG_U_PRCT("$amount");
316 Color_HSLA_Obj copy = col->copyAsHSLA();
317 copy->s(s__: clip(n: copy->s() + amount, lower: 0.0, upper: 100.0));
318 return copy.detach();
319 }
320
321 Signature desaturate_sig = "desaturate($color, $amount)";
322 BUILT_IN(desaturate)
323 {
324 Color* col = ARG("$color", Color);
325 double amount = DARG_U_PRCT("$amount");
326 Color_HSLA_Obj copy = col->copyAsHSLA();
327 copy->s(s__: clip(n: copy->s() - amount, lower: 0.0, upper: 100.0));
328 return copy.detach();
329 }
330
331 Signature grayscale_sig = "grayscale($color)";
332 BUILT_IN(grayscale)
333 {
334 // CSS3 filter function overload: pass literal through directly
335 Number* amount = Cast<Number>(ptr: env["$color"]);
336 if (amount) {
337 return SASS_MEMORY_NEW(String_Quoted, pstate, "grayscale(" + amount->to_string(ctx.c_options) + ")");
338 }
339
340 Color* col = ARG("$color", Color);
341 Color_HSLA_Obj copy = col->copyAsHSLA();
342 copy->s(s__: 0.0); // just reset saturation
343 return copy.detach();
344 }
345
346 /////////////////////////////////////////////////////////////////////////
347 // Misc manipulation functions
348 /////////////////////////////////////////////////////////////////////////
349
350 Signature complement_sig = "complement($color)";
351 BUILT_IN(complement)
352 {
353 Color* col = ARG("$color", Color);
354 Color_HSLA_Obj copy = col->copyAsHSLA();
355 copy->h(h__: absmod(n: copy->h() - 180.0, r: 360.0));
356 return copy.detach();
357 }
358
359 Signature invert_sig = "invert($color, $weight: 100%)";
360 BUILT_IN(invert)
361 {
362 // CSS3 filter function overload: pass literal through directly
363 Number* amount = Cast<Number>(ptr: env["$color"]);
364 double weight = DARG_U_PRCT("$weight");
365 if (amount) {
366 // TODO: does not throw on 100% manually passed as value
367 if (weight < 100.0) {
368 error(msg: "Only one argument may be passed to the plain-CSS invert() function.", pstate, traces);
369 }
370 return SASS_MEMORY_NEW(String_Quoted, pstate, "invert(" + amount->to_string(ctx.c_options) + ")");
371 }
372
373 Color* col = ARG("$color", Color);
374 Color_RGBA_Obj inv = col->copyAsRGBA();
375 inv->r(r__: clip(n: 255.0 - inv->r(), lower: 0.0, upper: 255.0));
376 inv->g(g__: clip(n: 255.0 - inv->g(), lower: 0.0, upper: 255.0));
377 inv->b(b__: clip(n: 255.0 - inv->b(), lower: 0.0, upper: 255.0));
378 return colormix(ctx, pstate, color1: inv, color2: col, weight);
379 }
380
381 /////////////////////////////////////////////////////////////////////////
382 // Opacity functions
383 /////////////////////////////////////////////////////////////////////////
384
385 Signature alpha_sig = "alpha($color)";
386 Signature opacity_sig = "opacity($color)";
387 BUILT_IN(alpha)
388 {
389 String_Constant* ie_kwd = Cast<String_Constant>(ptr: env["$color"]);
390 if (ie_kwd) {
391 return SASS_MEMORY_NEW(String_Quoted, pstate, "alpha(" + ie_kwd->value() + ")");
392 }
393
394 // CSS3 filter function overload: pass literal through directly
395 Number* amount = Cast<Number>(ptr: env["$color"]);
396 if (amount) {
397 return SASS_MEMORY_NEW(String_Quoted, pstate, "opacity(" + amount->to_string(ctx.c_options) + ")");
398 }
399
400 return SASS_MEMORY_NEW(Number, pstate, ARG("$color", Color)->a());
401 }
402
403 Signature opacify_sig = "opacify($color, $amount)";
404 Signature fade_in_sig = "fade-in($color, $amount)";
405 BUILT_IN(opacify)
406 {
407 Color* col = ARG("$color", Color);
408 double amount = DARG_U_FACT("$amount");
409 Color_Obj copy = SASS_MEMORY_COPY(col);
410 copy->a(a__: clip(n: col->a() + amount, lower: 0.0, upper: 1.0));
411 return copy.detach();
412 }
413
414 Signature transparentize_sig = "transparentize($color, $amount)";
415 Signature fade_out_sig = "fade-out($color, $amount)";
416 BUILT_IN(transparentize)
417 {
418 Color* col = ARG("$color", Color);
419 double amount = DARG_U_FACT("$amount");
420 Color_Obj copy = SASS_MEMORY_COPY(col);
421 copy->a(a__: std::max(a: col->a() - amount, b: 0.0));
422 return copy.detach();
423 }
424
425 ////////////////////////
426 // OTHER COLOR FUNCTIONS
427 ////////////////////////
428
429 Signature adjust_color_sig = "adjust-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)";
430 BUILT_IN(adjust_color)
431 {
432 Color* col = ARG("$color", Color);
433 Number* r = Cast<Number>(ptr: env["$red"]);
434 Number* g = Cast<Number>(ptr: env["$green"]);
435 Number* b = Cast<Number>(ptr: env["$blue"]);
436 Number* h = Cast<Number>(ptr: env["$hue"]);
437 Number* s = Cast<Number>(ptr: env["$saturation"]);
438 Number* l = Cast<Number>(ptr: env["$lightness"]);
439 Number* a = Cast<Number>(ptr: env["$alpha"]);
440
441 bool rgb = r || g || b;
442 bool hsl = h || s || l;
443
444 if (rgb && hsl) {
445 error(msg: "Cannot specify HSL and RGB values for a color at the same time for `adjust-color'", pstate, traces);
446 }
447 else if (rgb) {
448 Color_RGBA_Obj c = col->copyAsRGBA();
449 if (r) c->r(r__: c->r() + DARG_R_BYTE("$red"));
450 if (g) c->g(g__: c->g() + DARG_R_BYTE("$green"));
451 if (b) c->b(b__: c->b() + DARG_R_BYTE("$blue"));
452 if (a) c->a(a__: c->a() + DARG_R_FACT("$alpha"));
453 return c.detach();
454 }
455 else if (hsl) {
456 Color_HSLA_Obj c = col->copyAsHSLA();
457 if (h) c->h(h__: c->h() + absmod(n: h->value(), r: 360.0));
458 if (s) c->s(s__: c->s() + DARG_R_PRCT("$saturation"));
459 if (l) c->l(l__: c->l() + DARG_R_PRCT("$lightness"));
460 if (a) c->a(a__: c->a() + DARG_R_FACT("$alpha"));
461 return c.detach();
462 }
463 else if (a) {
464 Color_Obj c = SASS_MEMORY_COPY(col);
465 c->a(a__: c->a() + DARG_R_FACT("$alpha"));
466 c->a(a__: clip(n: c->a(), lower: 0.0, upper: 1.0));
467 return c.detach();
468 }
469 error(msg: "not enough arguments for `adjust-color'", pstate, traces);
470 // unreachable
471 return col;
472 }
473
474 Signature scale_color_sig = "scale-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)";
475 BUILT_IN(scale_color)
476 {
477 Color* col = ARG("$color", Color);
478 Number* r = Cast<Number>(ptr: env["$red"]);
479 Number* g = Cast<Number>(ptr: env["$green"]);
480 Number* b = Cast<Number>(ptr: env["$blue"]);
481 Number* h = Cast<Number>(ptr: env["$hue"]);
482 Number* s = Cast<Number>(ptr: env["$saturation"]);
483 Number* l = Cast<Number>(ptr: env["$lightness"]);
484 Number* a = Cast<Number>(ptr: env["$alpha"]);
485
486 bool rgb = r || g || b;
487 bool hsl = h || s || l;
488
489 if (rgb && hsl) {
490 error(msg: "Cannot specify HSL and RGB values for a color at the same time for `scale-color'", pstate, traces);
491 }
492 else if (rgb) {
493 Color_RGBA_Obj c = col->copyAsRGBA();
494 double rscale = (r ? DARG_R_PRCT("$red") : 0.0) / 100.0;
495 double gscale = (g ? DARG_R_PRCT("$green") : 0.0) / 100.0;
496 double bscale = (b ? DARG_R_PRCT("$blue") : 0.0) / 100.0;
497 double ascale = (a ? DARG_R_PRCT("$alpha") : 0.0) / 100.0;
498 if (rscale) c->r(r__: c->r() + rscale * (rscale > 0.0 ? 255.0 - c->r() : c->r()));
499 if (gscale) c->g(g__: c->g() + gscale * (gscale > 0.0 ? 255.0 - c->g() : c->g()));
500 if (bscale) c->b(b__: c->b() + bscale * (bscale > 0.0 ? 255.0 - c->b() : c->b()));
501 if (ascale) c->a(a__: c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a()));
502 return c.detach();
503 }
504 else if (hsl) {
505 Color_HSLA_Obj c = col->copyAsHSLA();
506 double hscale = (h ? DARG_R_PRCT("$hue") : 0.0) / 100.0;
507 double sscale = (s ? DARG_R_PRCT("$saturation") : 0.0) / 100.0;
508 double lscale = (l ? DARG_R_PRCT("$lightness") : 0.0) / 100.0;
509 double ascale = (a ? DARG_R_PRCT("$alpha") : 0.0) / 100.0;
510 if (hscale) c->h(h__: c->h() + hscale * (hscale > 0.0 ? 360.0 - c->h() : c->h()));
511 if (sscale) c->s(s__: c->s() + sscale * (sscale > 0.0 ? 100.0 - c->s() : c->s()));
512 if (lscale) c->l(l__: c->l() + lscale * (lscale > 0.0 ? 100.0 - c->l() : c->l()));
513 if (ascale) c->a(a__: c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a()));
514 return c.detach();
515 }
516 else if (a) {
517 Color_Obj c = SASS_MEMORY_COPY(col);
518 double ascale = DARG_R_PRCT("$alpha") / 100.0;
519 c->a(a__: c->a() + ascale * (ascale > 0.0 ? 1.0 - c->a() : c->a()));
520 c->a(a__: clip(n: c->a(), lower: 0.0, upper: 1.0));
521 return c.detach();
522 }
523 error(msg: "not enough arguments for `scale-color'", pstate, traces);
524 // unreachable
525 return col;
526 }
527
528 Signature change_color_sig = "change-color($color, $red: false, $green: false, $blue: false, $hue: false, $saturation: false, $lightness: false, $alpha: false)";
529 BUILT_IN(change_color)
530 {
531 Color* col = ARG("$color", Color);
532 Number* r = Cast<Number>(ptr: env["$red"]);
533 Number* g = Cast<Number>(ptr: env["$green"]);
534 Number* b = Cast<Number>(ptr: env["$blue"]);
535 Number* h = Cast<Number>(ptr: env["$hue"]);
536 Number* s = Cast<Number>(ptr: env["$saturation"]);
537 Number* l = Cast<Number>(ptr: env["$lightness"]);
538 Number* a = Cast<Number>(ptr: env["$alpha"]);
539
540 bool rgb = r || g || b;
541 bool hsl = h || s || l;
542
543 if (rgb && hsl) {
544 error(msg: "Cannot specify HSL and RGB values for a color at the same time for `change-color'", pstate, traces);
545 }
546 else if (rgb) {
547 Color_RGBA_Obj c = col->copyAsRGBA();
548 if (r) c->r(DARG_U_BYTE("$red"));
549 if (g) c->g(DARG_U_BYTE("$green"));
550 if (b) c->b(DARG_U_BYTE("$blue"));
551 if (a) c->a(DARG_U_FACT("$alpha"));
552 return c.detach();
553 }
554 else if (hsl) {
555 Color_HSLA_Obj c = col->copyAsHSLA();
556 if (h) c->h(h__: absmod(n: h->value(), r: 360.0));
557 if (s) c->s(DARG_U_PRCT("$saturation"));
558 if (l) c->l(DARG_U_PRCT("$lightness"));
559 if (a) c->a(DARG_U_FACT("$alpha"));
560 return c.detach();
561 }
562 else if (a) {
563 Color_Obj c = SASS_MEMORY_COPY(col);
564 c->a(a__: clip(DARG_U_FACT("$alpha"), lower: 0.0, upper: 1.0));
565 return c.detach();
566 }
567 error(msg: "not enough arguments for `change-color'", pstate, traces);
568 // unreachable
569 return col;
570 }
571
572 Signature ie_hex_str_sig = "ie-hex-str($color)";
573 BUILT_IN(ie_hex_str)
574 {
575 Color* col = ARG("$color", Color);
576 Color_RGBA_Obj c = col->toRGBA();
577 double r = clip(n: c->r(), lower: 0.0, upper: 255.0);
578 double g = clip(n: c->g(), lower: 0.0, upper: 255.0);
579 double b = clip(n: c->b(), lower: 0.0, upper: 255.0);
580 double a = clip(n: c->a(), lower: 0.0, upper: 1.0) * 255.0;
581
582 sass::ostream ss;
583 ss << '#' << std::setw(2) << std::setfill('0');
584 ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(val: a, precision: ctx.c_options.precision));
585 ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(val: r, precision: ctx.c_options.precision));
586 ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(val: g, precision: ctx.c_options.precision));
587 ss << std::hex << std::setw(2) << static_cast<unsigned long>(Sass::round(val: b, precision: ctx.c_options.precision));
588
589 sass::string result = ss.str();
590 Util::ascii_str_toupper(s: &result);
591 return SASS_MEMORY_NEW(String_Quoted, pstate, result);
592 }
593
594 }
595
596}
597

source code of gtk/subprojects/libsass/src/fn_colors.cpp