1
1
namespace AngleSharp . Css . Parser
2
2
{
3
3
using AngleSharp . Css . Values ;
4
- using AngleSharp . Io ;
5
4
using AngleSharp . Text ;
6
5
using System ;
7
6
using System . Collections . Generic ;
@@ -227,30 +226,130 @@ static class ColorParser
227
226
228
227
private static Color ? ParseLab ( StringSource source )
229
228
{
230
- // lab(50% 40 59.5)
231
- // lab(50 % 40 59.5 / 0.5)
229
+ var l = ParseLabComponent ( source ) ;
230
+ source . SkipSpacesAndComments ( ) ;
231
+ var a = ParseLabComponent ( source ) ;
232
+ source . SkipSpacesAndComments ( ) ;
233
+ var b = ParseLabComponent ( source ) ;
234
+ source . SkipSpacesAndComments ( ) ;
235
+ var c = source . Current ;
236
+ var alpha = new Nullable < Double > ( 1.0 ) ;
237
+
238
+ if ( l != null && a != null && b != null )
239
+ {
240
+ source . SkipCurrentAndSpaces ( ) ;
241
+
242
+ if ( c == Symbols . Solidus )
243
+ {
244
+ alpha = ParseAlpha ( source ) ;
245
+ source . SkipSpacesAndComments ( ) ;
246
+ c = source . Current ;
247
+ source . SkipCurrentAndSpaces ( ) ;
248
+ }
249
+
250
+ if ( c == Symbols . RoundBracketClose )
251
+ {
252
+ return Color . FromLab ( l . Value , a . Value , b . Value , alpha . Value ) ;
253
+ }
254
+ }
255
+
232
256
return null ;
233
257
}
234
258
235
259
private static Color ? ParseLch ( StringSource source )
236
260
{
237
- // lch(52.2% 72.2 50)
238
- // lch(52.2 % 72.2 50 / 0.5)
261
+ var l = ParseLabComponent ( source ) ;
262
+ source . SkipSpacesAndComments ( ) ;
263
+ var c = ParseLabComponent ( source ) ;
264
+ source . SkipSpacesAndComments ( ) ;
265
+ var h = ParseAngle ( source ) ;
266
+ source . SkipSpacesAndComments ( ) ;
267
+ var chr = source . Current ;
268
+ var a = new Nullable < Double > ( 1.0 ) ;
269
+
270
+ if ( l != null && c != null && h != null )
271
+ {
272
+ source . SkipCurrentAndSpaces ( ) ;
273
+
274
+ if ( chr == Symbols . Solidus )
275
+ {
276
+ a = ParseAlpha ( source ) ;
277
+ source . SkipSpacesAndComments ( ) ;
278
+ chr = source . Current ;
279
+ source . SkipCurrentAndSpaces ( ) ;
280
+ }
281
+
282
+ if ( chr == Symbols . RoundBracketClose )
283
+ {
284
+ return Color . FromLch ( l . Value , c . Value , h . Value , a . Value ) ;
285
+ }
286
+ }
287
+
239
288
return null ;
240
289
}
241
290
242
291
243
292
private static Color ? ParseOklab ( StringSource source )
244
293
{
245
- // oklab(59% 0.1 0.1)
246
- // oklab(59 % 0.1 0.1 / 0.5)
294
+ var l = ParseLabComponent ( source ) ;
295
+ source . SkipSpacesAndComments ( ) ;
296
+ var a = ParseLabComponent ( source ) ;
297
+ source . SkipSpacesAndComments ( ) ;
298
+ var b = ParseLabComponent ( source ) ;
299
+ source . SkipSpacesAndComments ( ) ;
300
+ var c = source . Current ;
301
+ var alpha = new Nullable < Double > ( 1.0 ) ;
302
+
303
+ if ( l != null && a != null && b != null )
304
+ {
305
+ source . SkipCurrentAndSpaces ( ) ;
306
+
307
+ if ( c == Symbols . Solidus )
308
+ {
309
+ alpha = ParseAlpha ( source ) ;
310
+ source . SkipSpacesAndComments ( ) ;
311
+ c = source . Current ;
312
+ source . SkipCurrentAndSpaces ( ) ;
313
+ }
314
+
315
+ if ( c == Symbols . RoundBracketClose )
316
+ {
317
+ return Color . FromOklab ( l . Value , a . Value , b . Value , alpha . Value ) ;
318
+ }
319
+ }
320
+
247
321
return null ;
248
322
}
249
323
250
324
private static Color ? ParseOklch ( StringSource source )
251
325
{
252
- // oklch(60% 0.15 50)
253
- // oklch(60 % 0.15 50 / 0.5)
326
+ var l = ParseLabComponent ( source ) ;
327
+ source . SkipSpacesAndComments ( ) ;
328
+ var c = ParseLabComponent ( source ) ;
329
+ source . SkipSpacesAndComments ( ) ;
330
+ var h = ParseAngle ( source ) ;
331
+ source . SkipSpacesAndComments ( ) ;
332
+ var chr = source . Current ;
333
+ var a = new Nullable < Double > ( 1.0 ) ;
334
+
335
+ if ( l != null && c != null && h != null )
336
+ {
337
+ source . SkipCurrentAndSpaces ( ) ;
338
+
339
+ if ( chr == Symbols . Solidus )
340
+ {
341
+ a = ParseAlpha ( source ) ;
342
+ source . SkipSpacesAndComments ( ) ;
343
+ chr = source . Current ;
344
+ source . SkipCurrentAndSpaces ( ) ;
345
+ }
346
+
347
+ if ( chr == Symbols . RoundBracketClose )
348
+ {
349
+ return Color . FromOklch ( l . Value , c . Value , h . Value , a . Value ) ;
350
+ }
351
+ }
352
+
254
353
return null ;
255
354
}
256
355
@@ -285,6 +384,31 @@ static class ColorParser
285
384
return null ;
286
385
}
287
386
387
+ private static Double ? ParseLabComponent ( StringSource source )
388
+ {
389
+ var pos = source . Index ;
390
+ var unit = source . ParseUnit ( ) ;
391
+
392
+ if ( unit == null )
393
+ {
394
+ source . BackTo ( pos ) ;
395
+
396
+ if ( source . IsIdentifier ( CssKeywords . None ) )
397
+ {
398
+ return 0 ;
399
+ }
400
+
401
+ return null ;
402
+ }
403
+
404
+ if ( ( unit . Dimension == String . Empty || unit . Dimension == "%" ) && Double . TryParse ( unit . Value , NumberStyles . Float , CultureInfo . InvariantCulture , out var value ) )
405
+ {
406
+ return value ;
407
+ }
408
+
409
+ return null ;
410
+ }
411
+
288
412
private static Byte ? ParseRgbOrNoneComponent ( StringSource source )
289
413
{
290
414
var pos = source . Index ;
@@ -309,17 +433,19 @@ static class ColorParser
309
433
{
310
434
var unit = source . ParseUnit ( ) ;
311
435
312
- if ( unit != null &&
313
- Int32 . TryParse ( unit . Value , NumberStyles . Integer , CultureInfo . InvariantCulture , out var value ) )
436
+ if ( unit == null )
314
437
{
315
- if ( unit . Dimension == "%" )
316
- {
317
- return ( Byte ) Math . Round ( ( 255.0 * value ) / 100.0 ) ;
318
- }
319
- else if ( unit . Dimension == String . Empty )
320
- {
321
- return ( Byte ) Math . Max ( Math . Min ( value , 255f ) , 0f ) ;
322
- }
438
+ return null ;
439
+ }
440
+
441
+ if ( unit . Dimension == String . Empty && Int32 . TryParse ( unit . Value , NumberStyles . Integer , CultureInfo . InvariantCulture , out var num ) )
442
+ {
443
+ return ( Byte ) Math . Max ( Math . Min ( num , 255f ) , 0f ) ;
444
+ }
445
+
446
+ if ( unit . Dimension == "%" && Double . TryParse ( unit . Value , NumberStyles . Float , CultureInfo . InvariantCulture , out var val ) )
447
+ {
448
+ return ( Byte ) Math . Round ( ( 255.0 * val ) / 100.0 ) ;
323
449
}
324
450
325
451
return null ;
0 commit comments