forked from Unity-Technologies/UnityCsReference
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathStyleCatalog.cs
More file actions
2220 lines (1935 loc) · 85.3 KB
/
Copy pathStyleCatalog.cs
File metadata and controls
2220 lines (1935 loc) · 85.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// Unity C# reference source
// Copyright (c) Unity Technologies. For terms of use, see
// https://unity3d.com/legal/licenses/Unity_Reference_Only_License
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using Unity.Collections.LowLevel.Unsafe;
using UnityEditor.Experimental;
using UnityEngine;
using UnityEngine.UIElements;
using Debug = UnityEngine.Debug;
namespace UnityEditor.StyleSheets
{
[Flags]
internal enum StyleState : long
{
none = 0L,
all = 0x7FFFFFFFFFFFFFFF,
normal = 1L << 0,
active = 1L << 1,
anyLink = 1L << 2,
@checked = 1L << 3,
@default = 1L << 4,
defined = 1L << 5,
disabled = 1L << 6,
empty = 1L << 7,
enabled = 1L << 8,
first = 1L << 9,
firstChild = 1L << 10,
firstOfType = 1L << 11,
fullscreen = 1L << 12,
focus = 1L << 13,
focusVisible = 1L << 14,
host = 1L << 15,
hover = 1L << 16,
indeterminate = 1L << 17,
inRange = 1L << 18,
invalid = 1L << 19,
lastChild = 1L << 20,
lastOfType = 1L << 21,
link = 1L << 22,
onlyChild = 1L << 23,
onlyOfType = 1L << 24,
optional = 1L << 25,
outOfRange = 1L << 26,
readOnly = 1L << 27,
readWrite = 1L << 28,
required = 1L << 29,
scope = 1L << 30,
target = 1L << 31,
valid = 1L << 32,
visited = 1L << 33,
root = 1L << 34,
any = 1L << 63
}
internal static class StyleCatalogKeyword
{
public readonly static int root = "".GetHashCode();
public readonly static int left = "left".GetHashCode();
public readonly static int right = "right".GetHashCode();
public readonly static int top = "top".GetHashCode();
public readonly static int bottom = "bottom".GetHashCode();
public readonly static int background = "background".GetHashCode();
public readonly static int backgroundAttachment = "background-attachment".GetHashCode();
public readonly static int backgroundColor = "background-color".GetHashCode();
public readonly static int backgroundImage = "background-image".GetHashCode();
public readonly static int scaledBackgroundImage = "-unity-scaled-backgrounds".GetHashCode();
public readonly static int backgroundPosition = "background-position".GetHashCode();
public readonly static int backgroundPositionX = "background-position-x".GetHashCode();
public readonly static int backgroundPositionY = "background-position-y".GetHashCode();
public readonly static int contentImageOffsetX = "-unity-content-image-offset-x".GetHashCode();
public readonly static int contentImageOffsetY = "-unity-content-image-offset-y".GetHashCode();
public readonly static int backgroundRepeat = "background-repeat".GetHashCode();
public readonly static int backgroundSize = "background-size".GetHashCode();
public readonly static int border = "border".GetHashCode();
public readonly static int borderBottom = "border-bottom".GetHashCode();
public readonly static int borderBottomColor = "border-bottom-color".GetHashCode();
public readonly static int borderBottomStyle = "border-bottom-style".GetHashCode();
public readonly static int borderBottomWidth = "border-bottom-width".GetHashCode();
public readonly static int borderColor = "border-color".GetHashCode();
public readonly static int borderLeft = "border-left".GetHashCode();
public readonly static int borderLeftColor = "border-left-color".GetHashCode();
public readonly static int borderLeftStyle = "border-left-style".GetHashCode();
public readonly static int borderLeftWidth = "border-left-width".GetHashCode();
public readonly static int borderRadius = "border-radius".GetHashCode();
public readonly static int borderRight = "border-right".GetHashCode();
public readonly static int borderRightColor = "border-right-color".GetHashCode();
public readonly static int borderRightStyle = "border-right-style".GetHashCode();
public readonly static int borderRightWidth = "border-right-width".GetHashCode();
public readonly static int borderStyle = "border-style".GetHashCode();
public readonly static int borderTop = "border-top".GetHashCode();
public readonly static int borderTopColor = "border-top-color".GetHashCode();
public readonly static int borderTopStyle = "border-top-style".GetHashCode();
public readonly static int borderTopWidth = "border-top-width".GetHashCode();
public readonly static int borderWidth = "border-width".GetHashCode();
public readonly static int borderTopLeftRadius = "border-top-left-radius".GetHashCode();
public readonly static int borderTopRightRadius = "border-top-right-radius".GetHashCode();
public readonly static int borderBottomLeftRadius = "border-bottom-left-radius".GetHashCode();
public readonly static int borderBottomRightRadius = "border-bottom-right-radius".GetHashCode();
public readonly static int clear = "clear".GetHashCode();
public readonly static int clip = "clip".GetHashCode();
public readonly static int color = "color".GetHashCode();
public readonly static int cursor = "cursor".GetHashCode();
public readonly static int display = "display".GetHashCode();
public readonly static int filter = "filter".GetHashCode();
public readonly static int cssFloat = "float".GetHashCode();
public readonly static int font = "font".GetHashCode();
public readonly static int fontFamily = "font-family".GetHashCode();
public readonly static int fontSize = "font-size".GetHashCode();
public readonly static int fontVariant = "font-variant".GetHashCode();
public readonly static int fontWeight = "font-weight".GetHashCode();
public readonly static int height = "height".GetHashCode();
public readonly static int letterSpacing = "letter-spacing".GetHashCode();
public readonly static int lineHeight = "line-height".GetHashCode();
public readonly static int listStyle = "list-style".GetHashCode();
public readonly static int listStyleImage = "list-style-image".GetHashCode();
public readonly static int listStylePosition = "list-style-position".GetHashCode();
public readonly static int listStyleType = "list-style-type".GetHashCode();
public readonly static int margin = "margin".GetHashCode();
public readonly static int marginBottom = "margin-bottom".GetHashCode();
public readonly static int marginLeft = "margin-left".GetHashCode();
public readonly static int marginRight = "margin-right".GetHashCode();
public readonly static int marginTop = "margin-top".GetHashCode();
public readonly static int opacity = "opacity".GetHashCode();
public readonly static int overflow = "overflow".GetHashCode();
public readonly static int overflowX = "overflow-x".GetHashCode();
public readonly static int overflowY = "overflow-y".GetHashCode();
public readonly static int padding = "padding".GetHashCode();
public readonly static int paddingBottom = "padding-bottom".GetHashCode();
public readonly static int paddingLeft = "padding-left".GetHashCode();
public readonly static int paddingRight = "padding-right".GetHashCode();
public readonly static int paddingTop = "padding-top".GetHashCode();
public readonly static int pageBreakAfter = "page-break-after".GetHashCode();
public readonly static int pageBreakBefore = "page-break-before".GetHashCode();
public readonly static int position = "position".GetHashCode();
public readonly static int size = "size".GetHashCode();
public readonly static int strokeDasharray = "stroke-dasharray".GetHashCode();
public readonly static int strokeDashoffset = "stroke-dashoffset".GetHashCode();
public readonly static int strokeWidth = "stroke-width".GetHashCode();
public readonly static int textAlign = "text-align".GetHashCode();
public readonly static int textDecoration = "text-decoration".GetHashCode();
public readonly static int textDecorationColor = "text-decoration-color".GetHashCode();
public readonly static int textIndent = "text-indent".GetHashCode();
public readonly static int textTransform = "text-transform".GetHashCode();
public readonly static int verticalAlign = "vertical-align".GetHashCode();
public readonly static int visibility = "visibility".GetHashCode();
public readonly static int width = "width".GetHashCode();
public readonly static int minWidth = "min-width".GetHashCode();
public readonly static int maxWidth = "max-width".GetHashCode();
public readonly static int zIndex = "z-index".GetHashCode();
}
[DebuggerDisplay("{value}")]
internal class SVC<T>
{
protected T m_Value;
protected int m_Key;
protected int m_Prop;
protected StyleState[] m_States;
protected bool m_Initialized;
protected Func<T> m_LateInitHandler;
public SVC(int key, int property, T defaultValue = default(T), params StyleState[] states)
{
m_Key = key;
m_Prop = property;
m_States = states;
m_Value = defaultValue;
m_Initialized = false;
m_LateInitHandler = () => m_Value;
}
public SVC(string name, string property, T defaultValue = default(T), params StyleState[] states) : this(name.GetHashCode(), property.GetHashCode(), defaultValue, states) {}
public SVC(string name, int property, T defaultValue = default(T), params StyleState[] states) : this(name.GetHashCode(), property, defaultValue, states) {}
public SVC(int name, string property, T defaultValue = default(T), params StyleState[] states) : this(name, property.GetHashCode(), defaultValue, states) {}
public SVC(string name, int property, Func<T> lateInitHandler, params StyleState[] states) : this(name.GetHashCode(), property, default(T), states)
{
m_LateInitHandler = lateInitHandler;
}
// Root access, i.e. :root {...}
public SVC(int property, T defaultValue = default(T)) : this(StyleCatalogKeyword.root, property, defaultValue, StyleState.root) {}
public SVC(string property, T defaultValue = default(T)) : this(StyleCatalogKeyword.root, property.GetHashCode(), defaultValue, StyleState.root) {}
public static implicit operator T(SVC<T> sc) { return sc.value; }
public T value
{
get
{
if (!m_Initialized)
{
m_Value = ReadValue(m_LateInitHandler());
m_Initialized = true;
}
return m_Value;
}
}
private T ReadValue(T defaultValue)
{
var block = EditorResources.GetStyle(m_Key, m_States);
if (!block.IsValid())
return defaultValue;
if (!block.HasValue(m_Prop))
return defaultValue;
var valueType = block.GetValueType(m_Prop);
if (valueType == StyleValue.Type.Number)
return (T)(object)block.GetFloat(m_Prop);
if (valueType == StyleValue.Type.Color)
return (T)(object)block.GetColor(m_Prop);
if (valueType == StyleValue.Type.Keyword)
{
if (typeof(T) == typeof(bool))
return (T)(object)(block.GetKeyword(m_Prop) == StyleValue.Keyword.True);
return (T)(object)block.GetKeyword(m_Prop);
}
if (valueType == StyleValue.Type.Rect)
return (T)(object)block.GetRect(m_Prop);
if (valueType == StyleValue.Type.Text)
return (T)(object)block.GetText(m_Prop);
Debug.LogWarning($"Style constant value conversion of type {valueType} not supported.");
return defaultValue;
}
}
[DebuggerDisplay("topleft = ({top}, {left}), bottomright = ({bottom}, {right}), size = ({width} x {height})")]
[StructLayout(LayoutKind.Explicit)]
internal struct StyleRect : IEquatable<StyleRect>
{
public static readonly StyleRect Nil = new StyleRect { left = float.NaN, right = float.NaN, top = float.NaN, bottom = float.NaN };
public static readonly StyleRect Zero = new StyleRect { left = 0f, right = 0f, top = 0f, bottom = 0f };
public static StyleRect Size(float width, float height)
{
return new StyleRect {width = width, height = height, bottom = width, left = height};
}
public StyleRect(float top, float right, float bottom, float left)
{
width = height = 0;
this.top = top;
this.right = right;
this.bottom = bottom;
this.left = left;
}
public StyleRect(RectOffset offset)
{
width = height = 0;
top = offset.top;
right = offset.right;
bottom = offset.bottom;
left = offset.left;
}
public float this[int index]
{
get
{
switch (index)
{
case 0: return top;
case 1: return right;
case 2: return bottom;
case 3: return left;
default:
throw new IndexOutOfRangeException("invalid rect index");
}
}
}
public bool incomplete => top == float.MaxValue || right == float.MaxValue || bottom == float.MaxValue || left == float.MaxValue;
internal StyleRect @fixed => new StyleRect
{
top = top == float.MaxValue ? 0 : top,
right = right == float.MaxValue ? 0 : right,
bottom = bottom == float.MaxValue ? 0 : bottom,
left = left == float.MaxValue ? 0 : left
};
[FieldOffset(0)] public float top;
[FieldOffset(4)] public float right;
[FieldOffset(8)] public float bottom;
[FieldOffset(12)] public float left;
[FieldOffset(0)] public float width;
[FieldOffset(4)] public float height;
public bool Equals(StyleRect other)
{
return top.Equals(other.top) && right.Equals(other.right) && bottom.Equals(other.bottom) && left.Equals(other.left) && width.Equals(other.width) && height.Equals(other.height);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is StyleRect && Equals((StyleRect)obj);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = top.GetHashCode();
hashCode = (hashCode * 397) ^ right.GetHashCode();
hashCode = (hashCode * 397) ^ bottom.GetHashCode();
hashCode = (hashCode * 397) ^ left.GetHashCode();
hashCode = (hashCode * 397) ^ width.GetHashCode();
hashCode = (hashCode * 397) ^ height.GetHashCode();
return hashCode;
}
}
}
internal struct StyleFunction : IEquatable<StyleFunction>
{
public string name;
public List<StyleValue[]> args;
public bool Equals(StyleFunction other)
{
if (name != other.name)
return false;
if (args.Count != other.args.Count)
return false;
int argListIndex = 0;
foreach (var argList in args)
{
if (argList.Length != other.args[argListIndex].Length)
return false;
int argIndex = 0;
foreach (var arg in argList)
{
if (!arg.Equals(other.args[argListIndex][argIndex]))
return false;
}
argListIndex++;
}
return true;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is StyleFunction && Equals((StyleFunction)obj);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = name.GetHashCode();
foreach (var argList in args)
foreach (var arg in argList)
hashCode = (hashCode * 397) ^ arg.GetHashCode();
return hashCode;
}
}
}
[DebuggerDisplay("{width} {style} {color}")]
internal struct StyleLine
{
public StyleLine(float width, string style, Color color)
{
this.width = width;
this.style = style;
this.color = color;
}
public float width;
public string style;
public Color color;
}
[DebuggerDisplay("count = {count}")]
internal struct StyleValueGroup : IEquatable<StyleValueGroup>
{
public const int k_MaxValueCount = 5;
public StyleValueGroup(int key, int count)
{
this.count = count;
v1 = v2 = v3 = v4 = v5 = StyleValue.Undefined(key);
}
public StyleValue this[int i]
{
get { return GetValueAt(i); }
set { SetValueAt(i, value); }
}
public StyleValue GetValueAt(int i)
{
switch (i)
{
case 0: return v1;
case 1: return v2;
case 2: return v3;
case 3: return v4;
case 4: return v5;
default:
throw new ArgumentOutOfRangeException(nameof(i), $"Index must be between [0, {k_MaxValueCount - 1}]");
}
}
internal void SetValueAt(int i, StyleValue value)
{
switch (i)
{
case 0: v1 = value; break;
case 1: v2 = value; break;
case 2: v3 = value; break;
case 3: v4 = value; break;
case 4: v5 = value; break;
default:
throw new ArgumentOutOfRangeException(nameof(i), $"Index must be between [0, {k_MaxValueCount - 1}]");
}
}
public int count;
public StyleValue v1;
public StyleValue v2;
public StyleValue v3;
public StyleValue v4;
public StyleValue v5;
public bool Equals(StyleValueGroup other)
{
return count == other.count && v1.Equals(other.v1) && v2.Equals(other.v2) && v3.Equals(other.v3) && v4.Equals(other.v4) && v5.Equals(other.v5);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is StyleValueGroup && Equals((StyleValueGroup)obj);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = count;
hashCode = (hashCode * 397) ^ v1.GetHashCode();
hashCode = (hashCode * 397) ^ v2.GetHashCode();
hashCode = (hashCode * 397) ^ v3.GetHashCode();
hashCode = (hashCode * 397) ^ v4.GetHashCode();
hashCode = (hashCode * 397) ^ v5.GetHashCode();
return hashCode;
}
}
}
[DebuggerDisplay("key = {key}, type = {type}, index = {index}, state = {state}")]
internal struct StyleValue : IEquatable<StyleValue>
{
public static StyleValue Undefined(int key, StyleState state = StyleState.none) { return new StyleValue { key = key, state = state, type = Type.Undefined, index = 0 }; }
public static StyleValue Undefined(string name, StyleState state = StyleState.none) { return Undefined(name.GetHashCode(), state); }
public enum Type
{
Undefined = -1,
Keyword = StyleValueType.Keyword,
Number = StyleValueType.Float,
Color = StyleValueType.Color,
Text = StyleValueType.String,
Rect,
Group,
Function,
Any = 0x7FFFFFFF
}
public enum Keyword
{
Invalid = -1,
None = 0,
False = 0,
True,
Inherit,
Auto,
Unset
}
public bool IsValid()
{
return type != Type.Undefined && index != -1;
}
internal static Keyword ConvertKeyword(StyleValueKeyword svk)
{
switch (svk)
{
case StyleValueKeyword.Inherit: return Keyword.Inherit;
case StyleValueKeyword.Auto: return Keyword.Auto;
case StyleValueKeyword.Unset: return Keyword.Unset;
case StyleValueKeyword.True: return Keyword.True;
case StyleValueKeyword.False: return Keyword.False;
case StyleValueKeyword.None: return Keyword.None;
default:
return Keyword.Invalid;
}
}
public int key;
public Type type;
public int index;
public StyleState state;
public bool Equals(StyleValue other)
{
return key == other.key && type == other.type && index == other.index && state == other.state;
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is StyleValue && Equals((StyleValue)obj);
}
public override int GetHashCode()
{
unchecked
{
var hashCode = key;
hashCode = (hashCode * 397) ^ (int)type;
hashCode = (hashCode * 397) ^ index;
hashCode = (hashCode * 397) ^ state.GetHashCode();
return hashCode;
}
}
}
internal struct StyleFunctionCall
{
private readonly StyleBlock block;
public readonly string name;
public readonly int valueKey;
public readonly List<StyleValue[]> args;
public int blockKey => block.name;
public StyleFunctionCall(StyleBlock block, int valueKey, string name, List<StyleValue[]> args)
{
this.block = block;
this.valueKey = valueKey;
this.name = name;
this.args = args;
}
public StyleValue.Type GetValueType(int argIndex, int valueIndex = -1)
{
if (valueIndex == -1 && args[argIndex].Length == 1)
valueIndex = 0;
return args[argIndex][valueIndex].type;
}
public Color GetColor(int argIndex, int valueIndex = -1)
{
if (valueIndex == -1 && args[argIndex].Length == 1)
valueIndex = 0;
return block.catalog.buffers.colors[args[argIndex][valueIndex].index];
}
public float GetNumber(int argIndex, int valueIndex = -1)
{
if (valueIndex == -1 && args[argIndex].Length == 1)
valueIndex = 0;
return block.catalog.buffers.numbers[args[argIndex][valueIndex].index];
}
public string GetString(int argIndex, int valueIndex = -1)
{
if (valueIndex == -1 && args[argIndex].Length == 1)
valueIndex = 0;
return block.catalog.buffers.strings[args[argIndex][valueIndex].index];
}
}
[DebuggerDisplay("name = {name}")]
internal readonly struct StyleBlock
{
public readonly int name;
public readonly StyleState[] states;
public readonly StyleValue[] values;
public readonly StyleCatalog catalog;
public StyleBlock(int name, StyleState[] states, StyleValue[] values, StyleCatalog catalog)
{
this.name = name;
this.states = states;
this.values = values;
this.catalog = catalog;
}
public bool IsValid()
{
return name != -1;
}
public bool HasKeyword(int key)
{
return GetValueIndex(key, StyleValue.Type.Keyword) > 0;
}
public bool HasKeyword(string key)
{
return GetValueIndex(key, StyleValue.Type.Keyword) > 0;
}
public StyleValue.Keyword GetKeyword(int key, StyleValue.Keyword defaultValue = StyleValue.Keyword.Invalid)
{
var bufferIndex = GetValueIndex(key, StyleValue.Type.Keyword);
if (bufferIndex == -1)
return defaultValue;
return (StyleValue.Keyword)bufferIndex;
}
public StyleValue.Keyword GetKeyword(string key, StyleValue.Keyword defaultValue = StyleValue.Keyword.Invalid)
{
return GetKeyword(key.GetHashCode(), defaultValue);
}
public bool GetBool(int key, bool defaultValue = false)
{
var bufferIndex = GetValueIndex(key, StyleValue.Type.Keyword);
if (bufferIndex == -1)
return defaultValue;
return (StyleValue.Keyword)bufferIndex == StyleValue.Keyword.True;
}
public bool GetBool(string key, bool defaultValue = false)
{
return GetBool(key.GetHashCode(), defaultValue);
}
public float GetFloat(int key, float defaultValue = 0.0f)
{
var bufferIndex = GetValueIndex(key, StyleValue.Type.Number);
if (bufferIndex == -1)
return defaultValue;
return catalog.buffers.numbers[bufferIndex];
}
public float GetFloat(string key, float defaultValue = 0.0f)
{
return GetFloat(key.GetHashCode(), defaultValue);
}
public Color GetColor(int key, Color defaultValue = default(Color))
{
var bufferIndex = GetValueIndex(key, StyleValue.Type.Color);
if (bufferIndex == -1)
return defaultValue;
return catalog.buffers.colors[bufferIndex];
}
public Color GetColor(string key, Color defaultValue = default(Color))
{
return GetColor(key.GetHashCode(), defaultValue);
}
public string GetText(int key, string defaultValue = "")
{
var bufferIndex = GetValueIndex(key, StyleValue.Type.Text);
if (bufferIndex == -1)
return defaultValue;
return catalog.buffers.strings[bufferIndex];
}
public string GetText(string key, string defaultValue = "")
{
return GetText(key.GetHashCode(), defaultValue);
}
public StyleRect GetRect(int key, StyleRect defaultValue = default(StyleRect))
{
var bufferIndex = GetValueIndex(key, StyleValue.Type.Rect);
if (bufferIndex == -1)
return defaultValue;
return catalog.buffers.rects[bufferIndex];
}
public StyleRect GetRect(string key, StyleRect defaultValue = default(StyleRect))
{
return GetRect(key.GetHashCode(), defaultValue);
}
public int GetInt(int key, int defaultValue = 0)
{
return (int)GetFloat(key, defaultValue);
}
public int GetInt(string key, int defaultValue = 0)
{
return (int)GetFloat(key, defaultValue);
}
public T GetResource<T>(int key, T defaultValue = null) where T : UnityEngine.Object
{
var resourceStr = GetText(key);
if (string.IsNullOrEmpty(resourceStr))
{
return defaultValue;
}
var resource = EditorResources.Load<UnityEngine.Object>(resourceStr, false) as T;
if (resource == null)
{
resource = Resources.Load<UnityEngine.Object>(resourceStr) as T;
}
return resource;
}
public T GetResource<T>(string key, T defaultValue = null) where T : UnityEngine.Object
{
return GetResource<T>(key.GetHashCode(), defaultValue);
}
static class TexturesByDPIScale
{
private static Dictionary<int, Dictionary<string, Texture2D>> s_TexturesByDPIScale = new Dictionary<int, Dictionary<string, Texture2D>>();
static TexturesByDPIScale()
{
for (int i = 1; i < 4; ++i)
s_TexturesByDPIScale[i] = new Dictionary<string, Texture2D>();
}
public static Texture2D GetTextureByDPIScale(string resourcePath, bool autoScale, float systemScale)
{
Texture2D tex = null;
int scale = Mathf.CeilToInt(systemScale);
if (autoScale && systemScale > 1f)
{
if (TryGetTexture(scale, resourcePath, out tex))
return tex;
string dirName = Path.GetDirectoryName(resourcePath).Replace('\\', '/');
string fileName = Path.GetFileNameWithoutExtension(resourcePath);
string fileExt = Path.GetExtension(resourcePath);
for (int s = scale; scale > 1; --scale)
{
string scaledResourcePath = $"{dirName}/{fileName}@{s}x{fileExt}";
var scaledResource = StoreTextureByScale(scale, scaledResourcePath, resourcePath, false);
if (scaledResource != null)
return scaledResource;
}
}
if (TryGetTexture(scale, resourcePath, out tex))
return tex;
return StoreTextureByScale(scale, resourcePath, resourcePath, true);
}
private static Texture2D StoreTextureByScale(int scale, string scaledPath, string resourcePath, bool logError)
{
var tex = EditorResources.Load<Texture2D>(scaledPath, false);
if (tex)
{
if (!s_TexturesByDPIScale.ContainsKey(scale))
s_TexturesByDPIScale[scale] = new Dictionary<string, Texture2D>();
s_TexturesByDPIScale[scale][resourcePath] = tex;
}
else if (logError)
{
Debug.LogFormat(LogType.Warning, LogOption.NoStacktrace, null, $"Failed to store {resourcePath} > {scaledPath}");
}
return tex;
}
private static bool TryGetTexture(int scale, string path, out Texture2D tex)
{
tex = null;
if (s_TexturesByDPIScale.ContainsKey(scale) && s_TexturesByDPIScale[scale].TryGetValue(path, out tex) && tex != null)
return true;
return false;
}
}
public Texture2D GetTexture(int key, bool autoScale = false)
{
var resourcePath = GetText(key);
if (String.IsNullOrEmpty(resourcePath))
return null;
return TexturesByDPIScale.GetTextureByDPIScale(resourcePath, autoScale, GUIUtility.pixelsPerPoint);
}
public Texture2D GetTexture(string key)
{
return GetTexture(key.GetHashCode());
}
public Tuple<T1, T2> GetTuple<T1, T2>(int key)
{
return new Tuple<T1, T2>(
GetTupleElementValue(key, 0, default(T1)),
GetTupleElementValue(key, 1, default(T2)));
}
public Tuple<T1, T2, T3> GetTuple<T1, T2, T3>(int key)
{
return new Tuple<T1, T2, T3>(
GetTupleElementValue(key, 0, default(T1)),
GetTupleElementValue(key, 1, default(T2)),
GetTupleElementValue(key, 2, default(T3)));
}
public Tuple<T1, T2, T3, T4> GetTuple<T1, T2, T3, T4>(int key)
{
return new Tuple<T1, T2, T3, T4>(
GetTupleElementValue(key, 0, default(T1)),
GetTupleElementValue(key, 1, default(T2)),
GetTupleElementValue(key, 2, default(T3)),
GetTupleElementValue(key, 3, default(T4)));
}
public Tuple<T1, T2, T3, T4, T5> GetTuple<T1, T2, T3, T4, T5>(int key)
{
return new Tuple<T1, T2, T3, T4, T5>(
GetTupleElementValue(key, 0, default(T1)),
GetTupleElementValue(key, 1, default(T2)),
GetTupleElementValue(key, 2, default(T3)),
GetTupleElementValue(key, 3, default(T4)),
GetTupleElementValue(key, 4, default(T5)));
}
public Tuple<T1, T2> GetTuple<T1, T2>(string key) { return GetTuple<T1, T2>(key.GetHashCode()); }
public Tuple<T1, T2, T3> GetTuple<T1, T2, T3>(string key) { return GetTuple<T1, T2, T3>(key.GetHashCode()); }
public Tuple<T1, T2, T3, T4> GetTuple<T1, T2, T3, T4>(string key) { return GetTuple<T1, T2, T3, T4>(key.GetHashCode()); }
public Tuple<T1, T2, T3, T4, T5> GetTuple<T1, T2, T3, T4, T5>(string key) { return GetTuple<T1, T2, T3, T4, T5>(key.GetHashCode()); }
private T GetTupleElementValue<T>(int key, int elementIndex, T defaultValue)
{
var groupIndex = GetValueIndex(key, StyleValue.Type.Group);
if (groupIndex == -1)
return defaultValue;
return GetItemValue(elementIndex, defaultValue, groupIndex, catalog.buffers.groups, catalog.buffers.strings, catalog.buffers.numbers, catalog.buffers.colors, catalog.buffers.rects);
}
public unsafe T GetStruct<T>(int key, T defaultValue = default(T)) where T : struct
{
var groupIndex = GetValueIndex(key, StyleValue.Type.Group);
if (groupIndex == -1)
return defaultValue;
var s = defaultValue;
int structSize = UnsafeUtility.SizeOf<T>();
byte* sptr = (byte*)UnsafeUtility.AddressOf(ref s);
int offset = 0;
var group = catalog.buffers.groups[groupIndex];
for (int i = 0; i < group.count; ++i)
{
var sv = group.GetValueAt(i);
switch (sv.type)
{
case StyleValue.Type.Keyword:
{
var v = sv.index;
UnsafeUtility.MemCpy(sptr + offset, &v, 4);
offset += 4;
break;
}
case StyleValue.Type.Text:
{
var v = catalog.buffers.strings[sv.index].GetHashCode();
UnsafeUtility.MemCpy(sptr + offset, &v, 4);
offset += 4;
break;
}
case StyleValue.Type.Number:
{
var v = catalog.buffers.numbers[sv.index];
UnsafeUtility.MemCpy(sptr + offset, &v, 4);
offset += 4;
break;
}
case StyleValue.Type.Color:
{
var v = catalog.buffers.colors[sv.index];
UnsafeUtility.MemCpy(sptr + offset, &v, 16);
offset += 16;
break;
}
case StyleValue.Type.Rect:
{
var v = catalog.buffers.rects[sv.index];
UnsafeUtility.MemCpy((sptr + offset), &v, 16);
offset += 16;
break;
}
default:
throw new NotSupportedException("group struct value type not supported");
}
if (offset >= structSize)
return s;
}
return s;
}
internal static T GetItemValue<T>(int elementIndex, T defaultValue, int groupIndex, IList<StyleValueGroup> groups, IList<string> strings, IList<float> numbers, IList<Color> colors, IList<StyleRect> rects)
{
var sv = groups[groupIndex][elementIndex];
if (typeof(T) == typeof(string) && sv.type == StyleValue.Type.Text)
return (T)(object)strings[sv.index];
if ((typeof(T) == typeof(float) || typeof(T) == typeof(double)) && sv.type == StyleValue.Type.Number)
return (T)(object)numbers[sv.index];
if (typeof(T) == typeof(Color) && sv.type == StyleValue.Type.Color)
return (T)(object)colors[sv.index];
if (typeof(T) == typeof(StyleRect) && sv.type == StyleValue.Type.Rect)
return (T)(object)rects[sv.index];
if (typeof(T) == typeof(int))
{
if (sv.type == StyleValue.Type.Number)
return (T)(object)numbers[sv.index];
if (sv.type == StyleValue.Type.Text)
return (T)(object)strings[sv.index].GetHashCode();
if (sv.type == StyleValue.Type.Keyword)
return (T)(object)sv.index;
return defaultValue;
}
return defaultValue;
}
public bool IsFunction(int key)
{
return GetValueIndex(key, StyleValue.Type.Function) != -1;
}
public T Execute<T>(int key, Func<StyleFunctionCall, T> callback)
{
var index = GetValueIndex(key, StyleValue.Type.Function);
if (index == -1)
return default(T);
var func = catalog.buffers.functions[index];
var callInfo = new StyleFunctionCall(this, key, func.name, func.args);
return callback(callInfo);
}
public T Execute<T, C>(int key, Func<StyleFunctionCall, C, T> callback, C c)
{
var index = GetValueIndex(key, StyleValue.Type.Function);
if (index == -1)
return default(T);
var func = catalog.buffers.functions[index];
var callInfo = new StyleFunctionCall(this, key, func.name, func.args);
return callback(callInfo, c);
}
public bool HasValue(int key, StyleValue.Type type = StyleValue.Type.Any)
{
return GetValueIndex(key, type) != -1;
}
public bool HasValue(string key, StyleValue.Type type = StyleValue.Type.Any)
{
return HasValue(key.GetHashCode(), type);
}
public StyleValue.Type GetValueType(int key)
{
StyleValue.Type type = StyleValue.Type.Any;
int vindex = GetValueIndex(key, ref type);
if (vindex == -1)
return StyleValue.Type.Undefined;