diff options
author | bptato <nincsnevem662@gmail.com> | 2022-07-30 11:45:32 +0200 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2022-07-30 11:45:32 +0200 |
commit | ca81bbcecd3777e8b20e12332ef813b874dd7fa5 (patch) | |
tree | df1f6e6e7b9ff3822d26063a36bdda1eeff9f04a | |
parent | 0dfe2a310db3fb7492ed448235e0757042f0f5ca (diff) | |
download | chawan-ca81bbcecd3777e8b20e12332ef813b874dd7fa5.tar.gz |
Implement revert value
-rw-r--r-- | src/css/cascade.nim | 79 | ||||
-rw-r--r-- | src/css/stylednode.nim | 13 | ||||
-rw-r--r-- | src/css/values.nim | 333 | ||||
-rw-r--r-- | src/types/color.nim | 156 |
4 files changed, 327 insertions, 254 deletions
diff --git a/src/css/cascade.nim b/src/css/cascade.nim index 9d2e9d53..c9acfe4c 100644 --- a/src/css/cascade.nim +++ b/src/css/cascade.nim @@ -13,14 +13,8 @@ import html/dom import html/tags type - ApplyResult = object - normal: seq[CSSDeclaration] - important: seq[CSSDeclaration] DeclarationList* = array[PseudoElem, seq[CSSDeclaration]] -proc applyProperty(styledNode: StyledNode, parent: CSSComputedValues, d: CSSDeclaration) = - styledNode.computed.applyValue(parent, d) - func applies(mq: MediaQuery): bool = case mq.t of CONDITION_MEDIA: @@ -74,69 +68,34 @@ func calcRules(styledNode: StyledNode, sheet: CSSStylesheet): DeclarationList = for item in tosorts[i]: for dl in item[1]: dl - -proc applyNormal(ares: var ApplyResult, decls: seq[CSSDeclaration]) = - for decl in decls: - if not decl.important: - ares.normal.add(decl) - -proc applyImportant(ares: var ApplyResult, decls: seq[CSSDeclaration]) = - for decl in decls: - if decl.important: - ares.important.add(decl) - proc applyDeclarations(styledNode: StyledNode, parent: CSSComputedValues, ua, user: DeclarationList, author: seq[DeclarationList]) = let pseudo = PSEUDO_NONE - var ares: ApplyResult + var builder = newComputedValueBuilder(parent) - ares.applyNormal(ua[pseudo]) - ares.applyNormal(user[pseudo]) + builder.addValues(ua[pseudo], ORIGIN_USER_AGENT) + builder.addValues(user[pseudo], ORIGIN_USER) for rule in author: - ares.applyNormal(rule[pseudo]) - - for rule in author: - ares.applyImportant(rule[pseudo]) - + builder.addValues(rule[pseudo], ORIGIN_AUTHOR) if styledNode.node != nil: let style = Element(styledNode.node).attr("style") if style.len > 0: let inline_rules = newStringStream(style).parseListOfDeclarations2() - ares.applyNormal(inline_rules) - ares.applyImportant(inline_rules) - - ares.applyImportant(user[pseudo]) - ares.applyImportant(ua[pseudo]) + builder.addValues(inline_rules, ORIGIN_AUTHOR) - styledNode.computed = parent.inheritProperties() - for rule in ares.normal: - styledNode.applyProperty(parent, rule) - - for rule in ares.important: - styledNode.applyProperty(parent, rule) + styledNode.computed = builder.buildComputedValues() # Either returns a new styled node or nil. -proc applyDeclarations(pseudo: PseudoElem, parent: CSSComputedValues, ua, user: DeclarationList, author: seq[DeclarationList]): StyledNode = - var ares: ApplyResult - - ares.applyNormal(ua[pseudo]) - ares.applyNormal(user[pseudo]) - for rule in author: - ares.applyNormal(rule[pseudo]) +proc applyDeclarations(pseudo: PseudoElem, styledParent: StyledNode, ua, user: DeclarationList, author: seq[DeclarationList]): StyledNode = + var builder = newComputedValueBuilder(styledParent.computed) + builder.addValues(ua[pseudo], ORIGIN_USER_AGENT) + builder.addValues(user[pseudo], ORIGIN_USER) for rule in author: - ares.applyImportant(rule[pseudo]) - - ares.applyImportant(user[pseudo]) - ares.applyImportant(ua[pseudo]) + builder.addValues(rule[pseudo], ORIGIN_AUTHOR) - if ares.normal.len > 0 or ares.important.len > 0: - result = StyledNode(t: STYLED_ELEMENT, node: nil, computed: parent.inheritProperties(), pseudo: pseudo) - for rule in ares.normal: - result.applyProperty(parent, rule) - - for rule in ares.important: - result.applyProperty(parent, rule) + if builder.hasValues(): + result = styledParent.newStyledElement(pseudo, builder.buildComputedValues()) func applyMediaQuery(ss: CSSStylesheet): CSSStylesheet = result = ss @@ -193,6 +152,7 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN else: # Text styledChild = styledParent.newStyledText(cachedChild.text) + styledChild.pseudo = cachedChild.pseudo styledChild.node = cachedChild.node if styledParent == nil: # Root element @@ -205,7 +165,7 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN let (ua, user, authordecls) = styledParent.calcRules(ua, user, author) case pseudo of PSEUDO_BEFORE, PSEUDO_AFTER: - let styledPseudo = pseudo.applyDeclarations(styledParent.computed, ua, user, authordecls) + let styledPseudo = pseudo.applyDeclarations(styledParent, ua, user, authordecls) if styledPseudo != nil: styledParent.children.add(styledPseudo) let content = styledPseudo.computed{"content"} @@ -214,17 +174,18 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN of PSEUDO_INPUT_TEXT: let content = HTMLInputElement(styledParent.node).inputString() if content.len > 0: - styledChild = styledParent.newStyledText(content) - styledParent.children.add(styledChild) + let styledText = styledParent.newStyledText(content) + styledText.pseudo = pseudo + styledParent.children.add(styledText) of PSEUDO_NONE: discard else: assert child != nil if styledParent != nil: if child.nodeType == ELEMENT_NODE: styledChild = styledParent.newStyledElement(Element(child)) + styledParent.children.add(styledChild) let (ua, user, authordecls) = styledChild.calcRules(ua, user, author) applyStyle(styledParent, styledChild, ua, user, authordecls) - styledParent.children.add(styledChild) elif child.nodeType == TEXT_NODE: let text = Text(child) styledChild = styledParent.newStyledText(text) @@ -253,7 +214,7 @@ proc applyRules(document: Document, ua, user: CSSStylesheet, cachedTree: StyledN if cachedChild != nil: var cached: StyledNode for it in cachedChild.children: - if it.t == STYLED_ELEMENT and it.pseudo == ps: + if it.pseudo == ps: cached = it break # When calculating pseudo-element rules, their dependencies are added diff --git a/src/css/stylednode.nim b/src/css/stylednode.nim index f575d99a..52a13771 100644 --- a/src/css/stylednode.nim +++ b/src/css/stylednode.nim @@ -41,23 +41,21 @@ type DependencyType* = enum DEPEND_HOVER, DEPEND_CHECKED - InvalidationRegistry* = set[DependencyType] - DependencyInfo* = object # All nodes we depend on, for each dependency type d. nodes*: array[DependencyType, seq[StyledNode]] - # Previous value. Node is marked invalid when one of these no longer - # matches the DOM value. + # Previous value. The owner StyledNode is marked as invalid when one of + # these no longer matches the DOM value. prev: array[DependencyType, bool] StyledNode* = ref object parent*: StyledNode node*: Node + pseudo*: PseudoElem #TODO this should be in element only case t*: StyledType of STYLED_TEXT: text*: string of STYLED_ELEMENT: - pseudo*: PseudoElem computed*: CSSComputedValues children*: seq[StyledNode] depends*: DependencyInfo @@ -121,6 +119,11 @@ func newStyledElement*(element: Element): StyledNode = func newStyledElement*(parent: StyledNode, pseudo: PseudoElem, computed: CSSComputedValues, reg: sink DependencyInfo): StyledNode = result = StyledNode(t: STYLED_ELEMENT, computed: computed, pseudo: pseudo, parent: parent) result.depends = reg + result.parent = parent + +func newStyledElement*(parent: StyledNode, pseudo: PseudoElem, computed: CSSComputedValues): StyledNode = + result = StyledNode(t: STYLED_ELEMENT, computed: computed, pseudo: pseudo, parent: parent) + result.parent = parent func newStyledText*(parent: StyledNode, text: string): StyledNode = result = StyledNode(t: STYLED_TEXT, text: text, parent: parent) diff --git a/src/css/values.nim b/src/css/values.nim index 3fd8e38b..fa7bac8a 100644 --- a/src/css/values.nim +++ b/src/css/values.nim @@ -1,7 +1,4 @@ import tables -import sugar -import sequtils -import options import macros import strutils @@ -130,6 +127,22 @@ type CSSComputedValues* = ref array[CSSPropertyType, CSSComputedValue] + CSSOrigin* = enum + ORIGIN_USER_AGENT + ORIGIN_USER + ORIGIN_AUTHOR + + CSSComputedValueBuilder = object + global: CSSGlobalValueType + val: CSSComputedValue + + CSSComputedValueBuilders = seq[CSSComputedValueBuilder] + + CSSComputedValuesBuilder* = object + parent: CSSComputedValues + normalProperties: array[CSSOrigin, CSSComputedValueBuilders] + importantProperties: array[CSSOrigin, CSSComputedValueBuilders] + CSSValueError* = object of ValueError const PropertyNames = { @@ -277,157 +290,6 @@ func listMarker*(t: CSSListStyleType, i: int): string = of LIST_STYLE_TYPE_LOWER_ROMAN: return romanNumber_lower(i) & ". " of LIST_STYLE_TYPE_JAPANESE_INFORMAL: return japaneseNumber(i) & "、" -const ColorsRGB = { - "aliceblue": 0xf0f8ff, - "antiquewhite": 0xfaebd7, - "aqua": 0x00ffff, - "aquamarine": 0x7fffd4, - "azure": 0xf0ffff, - "beige": 0xf5f5dc, - "bisque": 0xffe4c4, - "black": 0x000000, - "blanchedalmond": 0xffebcd, - "blue": 0x0000ff, - "blueviolet": 0x8a2be2, - "brown": 0xa52a2a, - "burlywood": 0xdeb887, - "cadetblue": 0x5f9ea0, - "chartreuse": 0x7fff00, - "chocolate": 0xd2691e, - "coral": 0xff7f50, - "cornflowerblue": 0x6495ed, - "cornsilk": 0xfff8dc, - "crimson": 0xdc143c, - "cyan": 0x00ffff, - "darkblue": 0x00008b, - "darkcyan": 0x008b8b, - "darkgoldenrod": 0xb8860b, - "darkgray": 0xa9a9a9, - "darkgreen": 0x006400, - "darkgrey": 0xa9a9a9, - "darkkhaki": 0xbdb76b, - "darkmagenta": 0x8b008b, - "darkolivegreen": 0x556b2f, - "darkorange": 0xff8c00, - "darkorchid": 0x9932cc, - "darkred": 0x8b0000, - "darksalmon": 0xe9967a, - "darkseagreen": 0x8fbc8f, - "darkslateblue": 0x483d8b, - "darkslategray": 0x2f4f4f, - "darkslategrey": 0x2f4f4f, - "darkturquoise": 0x00ced1, - "darkviolet": 0x9400d3, - "deeppink": 0xff1493, - "deepskyblue": 0x00bfff, - "dimgray": 0x696969, - "dimgrey": 0x696969, - "dodgerblue": 0x1e90ff, - "firebrick": 0xb22222, - "floralwhite": 0xfffaf0, - "forestgreen": 0x228b22, - "fuchsia": 0xff00ff, - "gainsboro": 0xdcdcdc, - "ghostwhite": 0xf8f8ff, - "gold": 0xffd700, - "goldenrod": 0xdaa520, - "gray": 0x808080, - "green": 0x008000, - "greenyellow": 0xadff2f, - "grey": 0x808080, - "honeydew": 0xf0fff0, - "hotpink": 0xff69b4, - "indianred": 0xcd5c5c, - "indigo": 0x4b0082, - "ivory": 0xfffff0, - "khaki": 0xf0e68c, - "lavender": 0xe6e6fa, - "lavenderblush": 0xfff0f5, - "lawngreen": 0x7cfc00, - "lemonchiffon": 0xfffacd, - "lightblue": 0xadd8e6, - "lightcoral": 0xf08080, - "lightcyan": 0xe0ffff, - "lightgoldenrodyellow": 0xfafad2, - "lightgray": 0xd3d3d3, - "lightgreen": 0x90ee90, - "lightgrey": 0xd3d3d3, - "lightpink": 0xffb6c1, - "lightsalmon": 0xffa07a, - "lightseagreen": 0x20b2aa, - "lightskyblue": 0x87cefa, - "lightslategray": 0x778899, - "lightslategrey": 0x778899, - "lightsteelblue": 0xb0c4de, - "lightyellow": 0xffffe0, - "lime": 0x00ff00, - "limegreen": 0x32cd32, - "linen": 0xfaf0e6, - "magenta": 0xff00ff, - "maroon": 0x800000, - "mediumaquamarine": 0x66cdaa, - "mediumblue": 0x0000cd, - "mediumorchid": 0xba55d3, - "mediumpurple": 0x9370db, - "mediumseagreen": 0x3cb371, - "mediumslateblue": 0x7b68ee, - "mediumspringgreen": 0x00fa9a, - "mediumturquoise": 0x48d1cc, - "mediumvioletred": 0xc71585, - "midnightblue": 0x191970, - "mintcream": 0xf5fffa, - "mistyrose": 0xffe4e1, - "moccasin": 0xffe4b5, - "navajowhite": 0xffdead, - "navy": 0x000080, - "oldlace": 0xfdf5e6, - "olive": 0x808000, - "olivedrab": 0x6b8e23, - "orange": 0xffa500, - "orangered": 0xff4500, - "orchid": 0xda70d6, - "palegoldenrod": 0xeee8aa, - "palegreen": 0x98fb98, - "paleturquoise": 0xafeeee, - "palevioletred": 0xdb7093, - "papayawhip": 0xffefd5, - "peachpuff": 0xffdab9, - "peru": 0xcd853f, - "pink": 0xffc0cb, - "plum": 0xdda0dd, - "powderblue": 0xb0e0e6, - "purple": 0x800080, - "red": 0xff0000, - "rosybrown": 0xbc8f8f, - "royalblue": 0x4169e1, - "saddlebrown": 0x8b4513, - "salmon": 0xfa8072, - "sandybrown": 0xf4a460, - "seagreen": 0x2e8b57, - "seashell": 0xfff5ee, - "sienna": 0xa0522d, - "silver": 0xc0c0c0, - "skyblue": 0x87ceeb, - "slateblue": 0x6a5acd, - "slategray": 0x708090, - "slategrey": 0x708090, - "snow": 0xfffafa, - "springgreen": 0x00ff7f, - "steelblue": 0x4682b4, - "tan": 0xd2b48c, - "teal": 0x008080, - "thistle": 0xd8bfd8, - "tomato": 0xff6347, - "turquoise": 0x40e0d0, - "violet": 0xee82ee, - "wheat": 0xf5deb3, - "white": 0xffffff, - "whitesmoke": 0xf5f5f5, - "yellow": 0xffff00, - "yellowgreen": 0x9acd32, - "rebeccapurple": 0x663399, -}.map((a) => (a[0], RGBColor(a[1]))).toTable() - const Colors: Table[string, CSSColor] = ((func (): Table[string, CSSColor] = for name, rgb in ColorsRGB: result[name] = CSSColor(rgba: rgb) @@ -800,11 +662,10 @@ func getInitialTable(): array[CSSPropertyType, CSSComputedValue] = let defaultTable = getInitialTable() -func getDefault(t: CSSPropertyType): CSSComputedValue = {.cast(noSideEffect).}: - assert defaultTable[t] != nil - return defaultTable[t] +template getDefault(t: CSSPropertyType): CSSComputedValue = {.cast(noSideEffect).}: + defaultTable[t] -func getComputedValue(d: CSSDeclaration, parent: CSSComputedValues): tuple[a:CSSComputedValue,b:CSSGlobalValueType] = +func getComputedValue(d: CSSDeclaration): (CSSComputedValue, CSSGlobalValueType) = let name = d.name let ptype = propertyType(name) let vtype = valueType(ptype) @@ -839,60 +700,152 @@ func equals*(a, b: CSSComputedValue): bool = of VALUE_NONE: return true return false -proc applyValue(vals, parent: CSSComputedValues, t: CSSPropertyType, val: CSSComputedValue, global: CSSGlobalValueType) = +proc newComputedValueBuilder*(parent: CSSComputedValues): CSSComputedValuesBuilder = + result.parent = parent + +proc addValuesImportant*(builder: var CSSComputedValuesBuilder, decls: seq[CSSDeclaration], origin: CSSOrigin) = + for decl in decls: + if decl.important: + let (val, global) = getComputedValue(decl) + builder.importantProperties[origin].add(CSSComputedValueBuilder(val: val, global: global)) + +proc addValuesNormal*(builder: var CSSComputedValuesBuilder, decls: seq[CSSDeclaration], origin: CSSOrigin) = + for decl in decls: + if not decl.important: + let (val, global) = getComputedValue(decl) + builder.normalProperties[origin].add(CSSComputedValueBuilder(val: val, global: global)) + +proc addValues*(builder: var CSSComputedValuesBuilder, decls: seq[CSSDeclaration], origin: CSSOrigin) = + for decl in decls: + let (val, global) = getComputedValue(decl) + if decl.important: + builder.importantProperties[origin].add(CSSComputedValueBuilder(val: val, global: global)) + else: + builder.normalProperties[origin].add(CSSComputedValueBuilder(val: val, global: global)) + +proc applyValue(vals: CSSComputedValues, prop: CSSPropertyType, val: CSSComputedValue, global: CSSGlobalValueType, parent: CSSComputedValues, previousOrigin: CSSComputedValues) = + let parentVal = if parent != nil: + parent[prop] + else: + nil case global - of VALUE_INHERIT, VALUE_UNSET: - if inherited(t): - if parent[t] != nil: - vals[t] = parent[t] - vals[t] = getDefault(t) + of VALUE_INHERIT: + if parentVal != nil: + vals[prop] = parentVal + else: + vals[prop] = getDefault(prop) of VALUE_INITIAL: - vals[t] = getDefault(t) + vals[prop] = getDefault(prop) + of VALUE_UNSET: + if inherited(prop): + # inherit + if parentVal != nil: + vals[prop] = parentVal + else: + vals[prop] = getDefault(prop) + else: + # initial + vals[prop] = getDefault(prop) of VALUE_REVERT: - vals[t] = getDefault(t) #TODO + if previousOrigin != nil: + vals[prop] = previousOrigin[prop] + else: + vals[prop] = getDefault(prop) of VALUE_NOGLOBAL: - vals[t] = val + vals[prop] = val -proc applyValue*(vals, parent: CSSComputedValues, d: CSSDeclaration) = - let vv = getComputedValue(d, parent) - let val = vv.a +func inheritProperties*(parent: CSSComputedValues): CSSComputedValues = + new(result) + for prop in CSSPropertyType: + if inherited(prop) and parent[prop] != nil: + result[prop] = parent[prop] + else: + result[prop] = getDefault(prop) + +func copyProperties*(parent: CSSComputedValues): CSSComputedValues = + new(result) + for prop in CSSPropertyType: + result[prop] = parent[prop] + +func rootProperties*(): CSSComputedValues = + new(result) + for prop in CSSPropertyType: + result[prop] = getDefault(prop) + +proc buildComputedValue(vals, parent, previousOrigin: CSSComputedValues, build: CSSComputedValueBuilder) = + let global = build.global + let val = build.val case val.t of PROPERTY_ALL: - let global = cssGlobal(d) if global != VALUE_NOGLOBAL: for t in CSSPropertyType: - vals.applyValue(parent, t, nil, global) + vals.applyValue(t, nil, global, parent, previousOrigin) of PROPERTY_MARGIN: let left = CSSComputedValue(t: PROPERTY_MARGIN_LEFT, v: VALUE_LENGTH, length: val.length) let right = CSSComputedValue(t: PROPERTY_MARGIN_RIGHT, v: VALUE_LENGTH, length: val.length) let top = CSSComputedValue(t: PROPERTY_MARGIN_TOP, v: VALUE_LENGTH, length: val.length) let bottom = CSSComputedValue(t: PROPERTY_MARGIN_BOTTOM, v: VALUE_LENGTH, length: val.length) for val in [left, right, top, bottom]: - vals.applyValue(parent, val.t, val, vv.b) + vals.applyValue(val.t, val, global, parent, previousOrigin) of PROPERTY_PADDING: let left = CSSComputedValue(t: PROPERTY_PADDING_LEFT, v: VALUE_LENGTH, length: val.length) let right = CSSComputedValue(t: PROPERTY_PADDING_RIGHT, v: VALUE_LENGTH, length: val.length) let top = CSSComputedValue(t: PROPERTY_PADDING_TOP, v: VALUE_LENGTH, length: val.length) let bottom = CSSComputedValue(t: PROPERTY_PADDING_BOTTOM, v: VALUE_LENGTH, length: val.length) for val in [left, right, top, bottom]: - vals.applyValue(parent, val.t, val, vv.b) + vals.applyValue(val.t, val, global, parent, previousOrigin) else: - vals.applyValue(parent, val.t, vv.a, vv.b) - -func inheritProperties*(parent: CSSComputedValues): CSSComputedValues = - new(result) - for prop in CSSPropertyType: - if inherited(prop) and parent[prop] != nil: - result[prop] = parent[prop] - else: - result[prop] = getDefault(prop) - -func copyProperties*(parent: CSSComputedValues): CSSComputedValues = - new(result) - for prop in CSSPropertyType: - result[prop] = parent[prop] + vals.applyValue(val.t, val, global, parent, previousOrigin) + +func hasValues*(builder: CSSComputedValuesBuilder): bool = + for origin in CSSOrigin: + if builder.normalProperties[origin].len > 0: + return true + if builder.importantProperties[origin].len > 0: + return true + return false -func rootProperties*(): CSSComputedValues = +func buildComputedValues*(builder: CSSComputedValuesBuilder): CSSComputedValues = new(result) + var previousOrigins: array[CSSOrigin, CSSComputedValues] + block: + let origin = ORIGIN_USER_AGENT + for build in builder.normalProperties[origin]: + result.buildComputedValue(builder.parent, nil, build) + previousOrigins[origin] = result.copyProperties() + block: + let origin = ORIGIN_USER + let prevOrigin = ORIGIN_USER_AGENT + for build in builder.normalProperties[origin]: + result.buildComputedValue(builder.parent, previousOrigins[prevOrigin], build) + previousOrigins[origin] = result.copyProperties() # save user origins so author can use them + block: + let origin = ORIGIN_AUTHOR + let prevOrigin = ORIGIN_USER + for build in builder.normalProperties[origin]: + result.buildComputedValue(builder.parent, previousOrigins[prevOrigin], build) + # no need to save user origins + block: + let origin = ORIGIN_AUTHOR + let prevOrigin = ORIGIN_USER + for build in builder.importantProperties[origin]: + result.buildComputedValue(builder.parent, previousOrigins[prevOrigin], build) + # important, so no need to save origins + block: + let origin = ORIGIN_USER + let prevOrigin = ORIGIN_USER_AGENT + for build in builder.importantProperties[origin]: + result.buildComputedValue(builder.parent, previousOrigins[prevOrigin], build) + # important, so no need to save origins + block: + let origin = ORIGIN_USER_AGENT + for build in builder.importantProperties[origin]: + result.buildComputedValue(builder.parent, nil, build) + # important, so no need to save origins + # set defaults for prop in CSSPropertyType: - result[prop] = getDefault(prop) + if result[prop] == nil: + if inherited(prop) and builder.parent != nil and builder.parent[prop] != nil: + result[prop] = builder.parent[prop] + else: + result[prop] = getDefault(prop) diff --git a/src/types/color.nim b/src/types/color.nim index cb3b2f3f..e5f72158 100644 --- a/src/types/color.nim +++ b/src/types/color.nim @@ -1,3 +1,7 @@ +import sequtils +import sugar +import tables + type RGBColor* = distinct uint32 @@ -19,6 +23,158 @@ func `==`*(color1, color2: CellColor): bool = const defaultColor* = CellColor(rgb: false, color: 0) +const ColorsRGB* = { + "aliceblue": 0xf0f8ff, + "antiquewhite": 0xfaebd7, + "aqua": 0x00ffff, + "aquamarine": 0x7fffd4, + "azure": 0xf0ffff, + "beige": 0xf5f5dc, + "bisque": 0xffe4c4, + "black": 0x000000, + "blanchedalmond": 0xffebcd, + "blue": 0x0000ff, + "blueviolet": 0x8a2be2, + "brown": 0xa52a2a, + "burlywood": 0xdeb887, + "cadetblue": 0x5f9ea0, + "chartreuse": 0x7fff00, + "chocolate": 0xd2691e, + "coral": 0xff7f50, + "cornflowerblue": 0x6495ed, + "cornsilk": 0xfff8dc, + "crimson": 0xdc143c, + "cyan": 0x00ffff, + "darkblue": 0x00008b, + "darkcyan": 0x008b8b, + "darkgoldenrod": 0xb8860b, + "darkgray": 0xa9a9a9, + "darkgreen": 0x006400, + "darkgrey": 0xa9a9a9, + "darkkhaki": 0xbdb76b, + "darkmagenta": 0x8b008b, + "darkolivegreen": 0x556b2f, + "darkorange": 0xff8c00, + "darkorchid": 0x9932cc, + "darkred": 0x8b0000, + "darksalmon": 0xe9967a, + "darkseagreen": 0x8fbc8f, + "darkslateblue": 0x483d8b, + "darkslategray": 0x2f4f4f, + "darkslategrey": 0x2f4f4f, + "darkturquoise": 0x00ced1, + "darkviolet": 0x9400d3, + "deeppink": 0xff1493, + "deepskyblue": 0x00bfff, + "dimgray": 0x696969, + "dimgrey": 0x696969, + "dodgerblue": 0x1e90ff, + "firebrick": 0xb22222, + "floralwhite": 0xfffaf0, + "forestgreen": 0x228b22, + "fuchsia": 0xff00ff, + "gainsboro": 0xdcdcdc, + "ghostwhite": 0xf8f8ff, + "gold": 0xffd700, + "goldenrod": 0xdaa520, + "gray": 0x808080, + "green": 0x008000, + "greenyellow": 0xadff2f, + "grey": 0x808080, + "honeydew": 0xf0fff0, + "hotpink": 0xff69b4, + "indianred": 0xcd5c5c, + "indigo": 0x4b0082, + "ivory": 0xfffff0, + "khaki": 0xf0e68c, + "lavender": 0xe6e6fa, + "lavenderblush": 0xfff0f5, + "lawngreen": 0x7cfc00, + "lemonchiffon": 0xfffacd, + "lightblue": 0xadd8e6, + "lightcoral": 0xf08080, + "lightcyan": 0xe0ffff, + "lightgoldenrodyellow": 0xfafad2, + "lightgray": 0xd3d3d3, + "lightgreen": 0x90ee90, + "lightgrey": 0xd3d3d3, + "lightpink": 0xffb6c1, + "lightsalmon": 0xffa07a, + "lightseagreen": 0x20b2aa, + "lightskyblue": 0x87cefa, + "lightslategray": 0x778899, + "lightslategrey": 0x778899, + "lightsteelblue": 0xb0c4de, + "lightyellow": 0xffffe0, + "lime": 0x00ff00, + "limegreen": 0x32cd32, + "linen": 0xfaf0e6, + "magenta": 0xff00ff, + "maroon": 0x800000, + "mediumaquamarine": 0x66cdaa, + "mediumblue": 0x0000cd, + "mediumorchid": 0xba55d3, + "mediumpurple": 0x9370db, + "mediumseagreen": 0x3cb371, + "mediumslateblue": 0x7b68ee, + "mediumspringgreen": 0x00fa9a, + "mediumturquoise": 0x48d1cc, + "mediumvioletred": 0xc71585, + "midnightblue": 0x191970, + "mintcream": 0xf5fffa, + "mistyrose": 0xffe4e1, + "moccasin": 0xffe4b5, + "navajowhite": 0xffdead, + "navy": 0x000080, + "oldlace": 0xfdf5e6, + "olive": 0x808000, + "olivedrab": 0x6b8e23, + "orange": 0xffa500, + "orangered": 0xff4500, + "orchid": 0xda70d6, + "palegoldenrod": 0xeee8aa, + "palegreen": 0x98fb98, + "paleturquoise": 0xafeeee, + "palevioletred": 0xdb7093, + "papayawhip": 0xffefd5, + "peachpuff": 0xffdab9, + "peru": 0xcd853f, + "pink": 0xffc0cb, + "plum": 0xdda0dd, + "powderblue": 0xb0e0e6, + "purple": 0x800080, + "red": 0xff0000, + "rosybrown": 0xbc8f8f, + "royalblue": 0x4169e1, + "saddlebrown": 0x8b4513, + "salmon": 0xfa8072, + "sandybrown": 0xf4a460, + "seagreen": 0x2e8b57, + "seashell": 0xfff5ee, + "sienna": 0xa0522d, + "silver": 0xc0c0c0, + "skyblue": 0x87ceeb, + "slateblue": 0x6a5acd, + "slategray": 0x708090, + "slategrey": 0x708090, + "snow": 0xfffafa, + "springgreen": 0x00ff7f, + "steelblue": 0x4682b4, + "tan": 0xd2b48c, + "teal": 0x008080, + "thistle": 0xd8bfd8, + "tomato": 0xff6347, + "turquoise": 0x40e0d0, + "violet": 0xee82ee, + "wheat": 0xf5deb3, + "white": 0xffffff, + "whitesmoke": 0xf5f5f5, + "yellow": 0xffff00, + "yellowgreen": 0x9acd32, + "rebeccapurple": 0x663399, +}.map((a) => (a[0], RGBColor(a[1]))).toTable() + + func r*(c: RGBAColor): int = return int(c) shr 16 and 0xff |