diff options
author | bptato <nincsnevem662@gmail.com> | 2025-01-16 19:44:21 +0100 |
---|---|---|
committer | bptato <nincsnevem662@gmail.com> | 2025-01-16 19:44:21 +0100 |
commit | 37bbe760b9b7c9c6aee8323c7766574a7ef55389 (patch) | |
tree | 16f39e0d75374621ec169db9b6a43939038130e7 /src | |
parent | 6db302e2a3c33f28f33c1044873f6bed958d2a37 (diff) | |
download | chawan-37bbe760b9b7c9c6aee8323c7766574a7ef55389.tar.gz |
cssvalues: serialize quotes, add font-size, opacity
font-size isn't very useful, but some scripts assume it exists. opacity: 0 for now is special cased: it inhibits rendering of further boxes. This isn't quite right, as it should just behave as a pseudo visibility: hidden... nonetheless it's quite effective at hiding garbage. (Also, remove incorrect comment - it can be nil if the branch has no variables.)
Diffstat (limited to 'src')
-rw-r--r-- | src/css/cssvalues.nim | 65 | ||||
-rw-r--r-- | src/css/render.nim | 11 | ||||
-rw-r--r-- | src/utils/twtstr.nim | 7 |
3 files changed, 49 insertions, 34 deletions
diff --git a/src/css/cssvalues.nim b/src/css/cssvalues.nim index d6763372..e16e51ed 100644 --- a/src/css/cssvalues.nim +++ b/src/css/cssvalues.nim @@ -50,6 +50,7 @@ type cptFlexBasis = "flex-basis" cptFlexGrow = "flex-grow" cptFlexShrink = "flex-shrink" + cptFontSize = "font-size" cptFontWeight = "font-weight" cptHeight = "height" cptLeft = "left" @@ -61,6 +62,7 @@ type cptMaxWidth = "max-width" cptMinHeight = "min-height" cptMinWidth = "min-width" + cptOpacity = "opacity" cptPaddingBottom = "padding-bottom" cptPaddingLeft = "padding-left" cptPaddingRight = "padding-right" @@ -399,7 +401,6 @@ type else: discard # Linked list of variable maps, except empty maps are skipped. - # Must not be nil for CSSValues, at least during cascade. CSSVariableMap* = ref object parent*: CSSVariableMap table*: Table[CAtom, CSSVariable] @@ -479,6 +480,7 @@ const ValueTypes = [ cptFlexBasis: cvtLength, cptFlexGrow: cvtNumber, cptFlexShrink: cvtNumber, + cptFontSize: cvtLength, cptFontWeight: cvtInteger, cptHeight: cvtLength, cptLeft: cvtLength, @@ -490,6 +492,7 @@ const ValueTypes = [ cptMaxWidth: cvtLength, cptMinHeight: cvtLength, cptMinWidth: cvtLength, + cptOpacity: cvtNumber, cptPaddingBottom: cvtLength, cptPaddingLeft: cvtLength, cptPaddingRight: cvtLength, @@ -570,7 +573,9 @@ func `$`*(content: CSSContent): string = func `$`(quotes: CSSQuotes): string = if quotes == nil: return "auto" - return "auto" #TODO + result = "" + for (s, e) in quotes.qs: + result &= "'" & s.cssEscape() & "' '" & e.cssEscape() & "'" func `$`(counterreset: seq[CSSCounterReset]): string = result = "" @@ -584,12 +589,11 @@ func serialize(val: CSSValue): string = of cvtImage: return $val.image of cvtLength2: return $val.length2.a & " " & $val.length2.b of cvtContent: - var s = "" + result = "" for x in val.content: - if s.len > 0: - s &= ' ' - s &= $x - return s + if result.len > 0: + result &= ' ' + result &= $x of cvtQuotes: return $val.quotes of cvtCounterReset: return $val.counterReset else: assert false @@ -1278,11 +1282,11 @@ func parseInteger(cval: CSSComponentValue; range: Slice[int32]): Opt[int32] = return ok(int32(tok.nvalue)) return err() -func cssNumber(cval: CSSComponentValue; positive: bool): Opt[float32] = +func parseNumber(cval: CSSComponentValue; range: Slice[float32]): Opt[float32] = if cval of CSSToken: let tok = CSSToken(cval) if tok.t in {cttNumber, cttINumber}: - if not positive or tok.nvalue >= 0: + if tok.nvalue in range: return ok(tok.nvalue) return err() @@ -1410,7 +1414,12 @@ proc parseValue(cvals: openArray[CSSComponentValue]; t: CSSPropertyType; of cvtFlexDirection: set_bit flexDirection, ?parseIdent[CSSFlexDirection](cval) of cvtFlexWrap: set_bit flexWrap, ?parseIdent[CSSFlexWrap](cval) - of cvtNumber: set_word number, ?cssNumber(cval, t == cptFlexGrow) + of cvtNumber: + case t + of cptFlexGrow, cptFlexShrink: + set_word number, ?parseNumber(cval, 0f32..float32.high) + of cptOpacity: set_word number, ?parseNumber(cval, 0f32..1f32) + else: assert false of cvtOverflow: set_bit overflow, ?parseIdent[CSSOverflow](cval) return ok() @@ -1424,6 +1433,8 @@ func getInitialLength(t: CSSPropertyType): CSSLength = of cptWidth, cptHeight, cptLeft, cptRight, cptTop, cptBottom, cptMaxWidth, cptMaxHeight, cptMinWidth, cptMinHeight, cptFlexBasis: return CSSLengthAuto + of cptFontSize: + return cssLength(16) else: return cssLength(0) @@ -1437,7 +1448,7 @@ func getInitialInteger(t: CSSPropertyType): int32 = return 0 func getInitialNumber(t: CSSPropertyType): float32 = - if t == cptFlexShrink: + if t in {cptFlexShrink, cptOpacity}: return 1 return 0 @@ -1507,6 +1518,11 @@ const PropertyPaddingSpec = [ cptPaddingTop, cptPaddingRight, cptPaddingBottom, cptPaddingLeft ] +proc addGlobals(res: var seq[CSSComputedEntry]; ps: openArray[CSSPropertyType]; + global: CSSGlobalType) = + for p in ps: + res.add(makeEntry(p, global)) + proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string; cvals: openArray[CSSComponentValue]; attrs: WindowAttributes; factory: CAtomFactory): Err[void] = @@ -1536,9 +1552,7 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string; hasAuto = false)) of cstBackground: if global.isSome: - let global = global.get - res.add(makeEntry(cptBackgroundColor, global)) - res.add(makeEntry(cptBackgroundImage, global)) + res.addGlobals([cptBackgroundColor, cptBackgroundImage], global.get) else: var bgcolor = makeEntry(cptBackgroundColor, getDefaultWord(cptBackgroundColor)) @@ -1563,13 +1577,11 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string; res.add(bgcolor) res.add(bgimage) of cstListStyle: - var typeVal = CSSValueBit() if global.isSome: - let global = global.get - res.add(makeEntry(cptListStylePosition, global)) - res.add(makeEntry(cptListStyleType, global)) + res.addGlobals([cptListStylePosition, cptListStyleType], global.get) else: var valid = true + var typeVal = CSSValueBit() var positionVal = CSSValueBit() for tok in cvals: if tok == cttWhitespace: @@ -1587,15 +1599,12 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string; res.add(makeEntry(cptListStyleType, typeVal)) of cstFlex: if global.isSome: - let global = global.get - res.add(makeEntry(cptFlexGrow, global)) - res.add(makeEntry(cptFlexShrink, global)) - res.add(makeEntry(cptFlexBasis, global)) + res.addGlobals([cptFlexGrow, cptFlexShrink, cptFlexBasis], global.get) else: var i = cvals.skipBlanks(0) if i >= cvals.len: return err() - if (let r = cssNumber(cvals[i], positive = true); r.isSome): + if (let r = parseNumber(cvals[i], 0f32..float32.high); r.isSome): # flex-grow let val = CSSValueWord(number: r.get) res.add(makeEntry(cptFlexGrow, val)) @@ -1603,7 +1612,7 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string; if i < cvals.len: if not (cvals[i] of CSSToken): return err() - if (let r = cssNumber(cvals[i], positive = true); r.isSome): + if (let r = parseNumber(cvals[i], 0f32..float32.high); r.isSome): # flex-shrink let val = CSSValueWord(number: r.get) res.add(makeEntry(cptFlexShrink, val)) @@ -1623,9 +1632,7 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string; res.add(makeEntry(cptFlexBasis, val)) of cstFlexFlow: if global.isSome: - let global = global.get - res.add(makeEntry(cptFlexDirection, global)) - res.add(makeEntry(cptFlexWrap, global)) + res.addGlobals([cptFlexDirection, cptFlexWrap], global.get) else: var i = cvals.skipBlanks(0) if i >= cvals.len: @@ -1641,9 +1648,7 @@ proc parseComputedValues*(res: var seq[CSSComputedEntry]; name: string; res.add(makeEntry(cptFlexWrap, val)) of cstOverflow: if global.isSome: - let global = global.get - res.add(makeEntry(cptOverflowX, global)) - res.add(makeEntry(cptOverflowY, global)) + res.addGlobals([cptOverflowX, cptOverflowY], global.get) else: var i = cvals.skipBlanks(0) if i >= cvals.len: diff --git a/src/css/render.nim b/src/css/render.nim index d79560ed..ebe0b1cc 100644 --- a/src/css/render.nim +++ b/src/css/render.nim @@ -446,7 +446,8 @@ proc renderBlockBox(grid: var FlexibleGrid; state: var RenderState; clipBox.start.y = max(offset.y, clipBox.start.y) clipBox.send.y = min(offset.y + box.state.size.h, clipBox.send.y) state.clipBoxes.add(clipBox) - if box.computed{"visibility"} == VisibilityVisible: + let opacity = box.computed{"opacity"} + if box.computed{"visibility"} == VisibilityVisible and opacity != 0: #TODO maybe blend with the terminal background? let bgcolor = box.computed{"background-color"}.cellColor() if bgcolor != defaultColor: @@ -473,13 +474,15 @@ proc renderBlockBox(grid: var FlexibleGrid; state: var RenderState; grid.setText(state, s, offset, box.computed.toFormat(), box.node) if box.inline != nil: assert box.children.len == 0 - if box.computed{"visibility"} == VisibilityVisible and + if box.computed{"visibility"} == VisibilityVisible and opacity != 0 and state.clipBox.start.x < state.clipBox.send.x and state.clipBox.start.y < state.clipBox.send.y: grid.renderInlineBox(state, box.inline, offset, rgba(0, 0, 0, 0)) else: - for child in box.children: - grid.renderBlockBox(state, child, offset) + #TODO this isn't right... + if opacity != 0: + for child in box.children: + grid.renderBlockBox(state, child, offset) if hasClipBox: discard state.clipBoxes.pop() if position != PositionStatic: diff --git a/src/utils/twtstr.nim b/src/utils/twtstr.nim index b646483a..7c905aa3 100644 --- a/src/utils/twtstr.nim +++ b/src/utils/twtstr.nim @@ -502,6 +502,13 @@ func dqEscape*(s: openArray[char]): string = result &= '\\' result &= c +func cssEscape*(s: openArray[char]): string = + result = "" + for c in s: + if c == '\'': + result &= '\\' + result &= c + #basically std join but with char func join*(ss: openArray[string]; sep: char): string = if ss.len == 0: |