about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/css/values.nim86
-rw-r--r--src/layout/engine.nim18
2 files changed, 87 insertions, 17 deletions
diff --git a/src/css/values.nim b/src/css/values.nim
index 6d92807a..36ea1a94 100644
--- a/src/css/values.nim
+++ b/src/css/values.nim
@@ -422,9 +422,9 @@ func cssColor(val: CSSComponentValue): RGBAColor =
 
 func isToken(d: CSSDeclaration): bool {.inline.} = d.value.len > 0 and d.value[0] of CSSToken
 
-func cssLength(d: CSSDeclaration): CSSLength =
-  if isToken(d):
-    let tok = CSSToken(d.value[0])
+func cssLength(val: CSSComponentValue): CSSLength =
+  if val of CSSToken:
+    let tok = CSSToken(val)
     case tok.tokenType
     of CSS_NUMBER_TOKEN:
       if tok.nvalue == 0:
@@ -589,7 +589,7 @@ func cssVerticalAlign(d: CSSDeclaration): CSSVerticalAlign =
       return result
     else:
       result.keyword = VERTICAL_ALIGN_BASELINE
-      result.length = cssLength(d)
+      result.length = cssLength(tok)
       return result
   raise newException(CSSValueError, "Invalid vertical align")
 
@@ -603,7 +603,7 @@ func cssLineHeight(d: CSSDeclaration): CSSLength =
       if tok.value == "normal":
         return CSSLength(auto: true)
     else:
-      return cssLength(d)
+      return cssLength(tok)
   raise newException(CSSValueError, "Invalid line height")
 
 func cssTextAlign(d: CSSDeclaration): CSSTextAlign =
@@ -649,6 +649,8 @@ proc getValueFromDecl(val: CSSComputedValue, d: CSSDeclaration, vtype: CSSValueT
   of VALUE_COLOR:
     if d.value.len > 0:
       val.color = cssColor(d.value[0])
+    else:
+      raise newException(CSSValueError, "Empty value")
   of VALUE_LENGTH:
     case ptype
     of PROPERTY_WORD_SPACING:
@@ -656,7 +658,10 @@ proc getValueFromDecl(val: CSSComputedValue, d: CSSDeclaration, vtype: CSSValueT
     of PROPERTY_LINE_HEIGHT:
       val.length = cssLineHeight(d)
     else:
-      val.length = cssLength(d)
+      if d.value.len > 0:
+        val.length = cssLength(d.value[0])
+      else:
+        raise newException(CSSValueError, "Empty value")
   of VALUE_FONT_STYLE: val.fontstyle = cssFontStyle(d)
   of VALUE_DISPLAY: val.display = cssDisplay(d)
   of VALUE_CONTENT: val.content = cssString(d)
@@ -689,7 +694,7 @@ func getInitialLength(t: CSSPropertyType): CSSLength =
      PROPERTY_BOTTOM:
     return CSSLength(auto: true)
   else:
-    return CSSLength()
+    return CSSLength(auto: false, unit: UNIT_PX, num: 0)
 
 func calcInitial(t: CSSPropertyType): CSSComputedValue =
   let v = valueType(t)
@@ -725,7 +730,56 @@ func getComputedValue(d: CSSDeclaration, ptype: CSSPropertyType, vtype: CSSValue
 
   return (val, cssGlobal(d))
 
-func getComputedValues(d: CSSDeclaration): seq[(CSSComputedValue, CSSGlobalValueType)] =
+func lengthShorthand(d: CSSDeclaration, props: array[4, CSSPropertyType]): seq[(CSSComputedValue, CSSGlobalValueType)] =
+  var i = 0
+  var cvals: seq[CSSComponentValue]
+  while i < d.value.len:
+    if d.value[i] != CSS_WHITESPACE_TOKEN:
+      cvals.add(d.value[i])
+    inc i
+  case cvals.len
+  of 1:
+    try:
+      for ptype in props:
+        let vtype = valueType(ptype)
+        let val = CSSComputedValue(t: ptype, v: vtype)
+        val.getValueFromDecl(d, vtype, ptype)
+        result.add((val, cssGlobal(d)))
+    except CSSValueError: discard
+  of 2:
+    try:
+      for i in 0 ..< props.len:
+        let ptype = props[i]
+        let vtype = valueType(ptype)
+        let val = CSSComputedValue(t: ptype, v: vtype)
+        val.length = cssLength(cvals[i div 2])
+        result.add((val, cssGlobal(d)))
+    except CSSValueError:
+      discard
+  of 3:
+    try:
+      for i in 0 ..< props.len:
+        let ptype = props[i]
+        let vtype = valueType(ptype)
+        let val = CSSComputedValue(t: ptype, v: vtype)
+        let j = if i == 0: 0 elif i == 3: 2 else: 1
+        val.length = cssLength(cvals[j])
+        result.add((val, cssGlobal(d)))
+    except CSSValueError:
+      discard
+  of 4:
+    try:
+      for i in 0 ..< props.len:
+        let ptype = props[i]
+        let vtype = valueType(ptype)
+        let val = CSSComputedValue(t: ptype, v: vtype)
+        val.length = cssLength(cvals[i])
+        result.add((val, cssGlobal(d)))
+    except CSSValueError:
+      discard
+  else: discard
+
+proc getComputedValues(d: CSSDeclaration): seq[(CSSComputedValue, CSSGlobalValueType)] =
   let name = d.name
   case shorthandType(name)
   of SHORTHAND_NONE:
@@ -740,15 +794,15 @@ func getComputedValues(d: CSSDeclaration): seq[(CSSComputedValue, CSSGlobalValue
         let val = CSSComputedValue(t: ptype, v: vtype)
         result.add((val, global))
   of SHORTHAND_MARGIN:
-    for ptype in [PROPERTY_MARGIN_TOP, PROPERTY_MARGIN_LEFT,
-                  PROPERTY_MARGIN_RIGHT, PROPERTY_MARGIN_BOTTOM]:
-      let vtype = valueType(ptype)
-      result.add(getComputedValue(d, ptype, vtype))
+    result.add(lengthShorthand(d, [PROPERTY_MARGIN_TOP,
+                                   PROPERTY_MARGIN_BOTTOM,
+                                   PROPERTY_MARGIN_LEFT,
+                                   PROPERTY_MARGIN_RIGHT]))
   of SHORTHAND_PADDING:
-    for ptype in [PROPERTY_PADDING_TOP, PROPERTY_PADDING_LEFT,
-                  PROPERTY_PADDING_RIGHT, PROPERTY_PADDING_BOTTOM]:
-      let vtype = valueType(ptype)
-      result.add(getComputedValue(d, ptype, vtype))
+    result.add(lengthShorthand(d, [PROPERTY_PADDING_TOP,
+                                   PROPERTY_PADDING_BOTTOM,
+                                   PROPERTY_PADDING_LEFT,
+                                   PROPERTY_PADDING_RIGHT]))
   of SHORTHAND_BACKGROUND:
     let global = cssGlobal(d)
     let bgcolorptype = PROPERTY_BACKGROUND_COLOR
diff --git a/src/layout/engine.nim b/src/layout/engine.nim
index 717ea900..69316406 100644
--- a/src/layout/engine.nim
+++ b/src/layout/engine.nim
@@ -663,9 +663,25 @@ proc positionBlocks(box: BlockBox) =
 
   template apply_child(child: BlockBox) =
     child.offset.y = y
-    child.offset.x = x + child.margin_left
+    child.offset.x = x
     if box.computed{"text-align"} == TEXT_ALIGN_CHA_CENTER:
       child.offset.x -= child.width div 2
+    elif not child.computed{"width"}.auto and child.compwidth < box.compwidth:
+      let margin_left = child.computed{"margin-left"}
+      let margin_right = child.computed{"margin-right"}
+      if margin_left.auto and margin_right.auto:
+        child.margin_left += box.compwidth div 2
+        child.margin_left -= child.compwidth div 2
+        child.margin_right += box.compwidth div 2
+        child.margin_right -= child.compwidth div 2
+      elif margin_left.auto:
+        child.margin_left += box.compwidth
+        child.margin_left -= child.compwidth
+      elif margin_right.auto:
+        child.margin_right += box.compwidth
+        child.margin_right -= child.compwidth
+    child.offset.x += child.margin_left
+
     if box.computed{"position"} == POSITION_RELATIVE:
       box.positionRelative(child)
     y += child.height