Diff
diff --git a/cstyle/main.go b/cstyle/main.go
index 378e0db..6c058ca 100644
--- a/cstyle/main.go
+++ b/cstyle/main.go
@@ -7 +6,0 @@ import (
- "gui/utils"
@@ -11 +10,2 @@ import (
- "strings"
+
+ "gui/utils"
@@ -30 +30 @@ type Mapped struct {
- Document *Node
+ Document *html.Node
@@ -36,41 +36,2 @@ type Node struct {
- Node *html.Node
- Parent *Node
- Children []Node
- Styles map[string]string
- Id string
- X float32
- Y float32
- Width float32
- Height float32
- Margin Margin
- Padding Padding
- Border Border
- EM float32
-}
-
-type Margin struct {
- Top float32
- Right float32
- Bottom float32
- Left float32
-}
-
-type Padding struct {
- Top float32
- Right float32
- Bottom float32
- Left float32
-}
-
-type Border struct {
- Top BorderSide
- Right BorderSide
- Bottom BorderSide
- Left BorderSide
-}
-
-type BorderSide struct {
- Width float32
- Style string
- Color string
- Radius float32
+ Node *html.Node
+ Id string
@@ -119,27 +80,6 @@ func (c *CSS) Map(doc *html.Node) Mapped {
- println(c.Width, c.Height)
- fId := dom.GetAttribute(doc.FirstChild, "DOMNODEID")
- node := Node{
- Node: doc.FirstChild,
- Parent: &Node{
- Id: "ROOT",
- X: 0,
- Y: 0,
- Width: c.Width,
- Height: c.Height,
- Styles: map[string]string{
- "width": strconv.FormatFloat(float64(c.Width), 'f', -1, 32) + "px",
- "height": strconv.FormatFloat(float64(c.Height), 'f', -1, 32) + "px",
- },
- },
- Id: fId,
- X: 0,
- Y: 0,
- Width: c.Width,
- Height: c.Height,
- Styles: styleMap[fId],
- }
- fmt.Printf("%#v\n", node.Id)
- initNodes(&node, styleMap)
-
- ComputeNodeStyle(node)
- Print(&node, 0)
+ // Calculate the width and height
+ println("size")
+ size(doc, styleMap, c.Width, c.Height)
+ // Calculate the X and Y values
+ println("position")
+ position(doc, styleMap, 0, 0, c.Width, c.Height)
@@ -147 +87 @@ func (c *CSS) Map(doc *html.Node) Mapped {
- renderLine := flatten(&node)
+ renderLine := flatten(doc)
@@ -150 +90 @@ func (c *CSS) Map(doc *html.Node) Mapped {
- Document: &node,
+ Document: doc,
@@ -157,9 +97,17 @@ func (c *CSS) Map(doc *html.Node) Mapped {
-func ComputeNodeStyle(n Node) {
- // Need to make a function that builds a Node tree from a *html.Node
- // Kind of a chicken and the egg problem.. I need to have these styles to make the Node
- // Maybe make this function a function like inherit (circular i know lol) but just go ahead
- // and compute all styles so it can be passed directly to the renderer
- // but
- // its still the same issue. I need the Node tree to make compute the styles
- // unless the tree I create basic child nodes that have the parent node mapped and computed???
- // anything above should already be computed so it should work
+func flatten(n *html.Node) []Node {
+ var nodes []Node
+ id := dom.GetAttribute(n, "DOMNODEID")
+ nodes = append(nodes, Node{
+ Node: n,
+ Id: id,
+ })
+
+ children := dom.Children(n)
+ if len(children) > 0 {
+ for _, ch := range children {
+ chNodes := flatten(ch)
+ nodes = append(nodes, chNodes...)
+ }
+ }
+ return nodes
+}
@@ -167 +115,7 @@ func ComputeNodeStyle(n Node) {
- styleMap := n.Styles
+func position(n *html.Node, styleMap map[string]map[string]string, x1, y1, windowWidth, windowHeight float32) (float32, float32) {
+ id := dom.GetAttribute(n, "DOMNODEID")
+ println(dom.TagName(n))
+ if len(id) == 0 {
+ id = dom.TagName(n) + fmt.Sprint(rand.Int63())
+ dom.SetAttribute(n, "DOMNODEID", id)
+ }
@@ -169 +123 @@ func ComputeNodeStyle(n Node) {
- x, y := n.Parent.X, n.Parent.Y
+ fs := font.GetFontSize(styleMap[id])
@@ -171,3 +125,4 @@ func ComputeNodeStyle(n Node) {
- width, _ := utils.ConvertToPixels(styleMap["width"], n.EM, n.Parent.Width)
- height, _ := utils.ConvertToPixels(styleMap["height"], n.EM, n.Parent.Width)
- println(n.Id, width, height)
+ rawWidth, _ := strconv.ParseFloat(styleMap[id]["width"], 32)
+ rawHeight, _ := strconv.ParseFloat(styleMap[id]["height"], 32)
+ width := float32(rawWidth)
+ height := float32(rawHeight)
@@ -175 +130,2 @@ func ComputeNodeStyle(n Node) {
- var top, left, right, bottom bool = false, false, false, false
+ x2 := x1 + width
+ y2 := y1 + height
@@ -177 +133 @@ func ComputeNodeStyle(n Node) {
- if styleMap["position"] == "absolute" {
+ if styleMap[id]["position"] == "absolute" {
@@ -180,6 +136,3 @@ func ComputeNodeStyle(n Node) {
- base := GetPositionOffsetNode(&n)
-
- if styleMap["top"] != "" {
- v, _ := utils.ConvertToPixels(styleMap["top"], float32(n.EM), n.Parent.Width)
- x = v + base.X
- top = true
+ if styleMap[id]["top"] != "" {
+ v, _ := utils.ConvertToPixels(styleMap[id]["top"], float32(fs), windowWidth)
+ x1 = v
@@ -187,4 +140,3 @@ func ComputeNodeStyle(n Node) {
- if styleMap["left"] != "" {
- v, _ := utils.ConvertToPixels(styleMap["left"], float32(n.EM), n.Parent.Width)
- y = v + base.Y
- left = true
+ if styleMap[id]["left"] != "" {
+ v, _ := utils.ConvertToPixels(styleMap[id]["left"], float32(fs), windowWidth)
+ y1 = v
@@ -192,4 +144,3 @@ func ComputeNodeStyle(n Node) {
- if styleMap["right"] != "" {
- v, _ := utils.ConvertToPixels(styleMap["right"], float32(n.EM), n.Parent.Width)
- x = (base.Width - width) - v
- right = true
+ if styleMap[id]["right"] != "" {
+ v, _ := utils.ConvertToPixels(styleMap[id]["right"], float32(fs), windowWidth)
+ x1 = (windowWidth - width) - v
@@ -197,4 +148,3 @@ func ComputeNodeStyle(n Node) {
- if styleMap["bottom"] != "" {
- v, _ := utils.ConvertToPixels(styleMap["bottom"], float32(n.EM), n.Parent.Width)
- y = (base.Height - height) - v
- bottom = true
+ if styleMap[id]["bottom"] != "" {
+ v, _ := utils.ConvertToPixels(styleMap[id]["bottom"], float32(fs), windowWidth)
+ y1 = (windowHeight - height) - v
@@ -201,0 +152,11 @@ func ComputeNodeStyle(n Node) {
+
+ relX, relY := utils.FindRelative(n, styleMap)
+
+ if relX != 0 && relY != 0 {
+ fmt.Println(relX, relY)
+ x1 += relX
+ y1 += relY
+ }
+
+ x2 = x1 + width
+ y2 = y1 + height
@@ -204 +165 @@ func ComputeNodeStyle(n Node) {
- // Make a Node.Color that the color library can use to output node.Color.Background node.Color.Border.Left etc including font
+ var btmOS float32 = 0
@@ -206 +167,11 @@ func ComputeNodeStyle(n Node) {
- // Display modes need to be calculated here
+ if styleMap[id]["margin-left"] != "" {
+ v, _ := utils.ConvertToPixels(styleMap[id]["margin-left"], float32(fs), windowWidth)
+ x1 += v
+ x2 += v
+ }
+ if styleMap[id]["margin-top"] != "" {
+ v, _ := utils.ConvertToPixels(styleMap[id]["margin-top"], float32(fs), windowHeight)
+ y1 += v
+ y2 += v
+ btmOS += v
+ }
@@ -208 +179,4 @@ func ComputeNodeStyle(n Node) {
- relPos := !top && !left && !right && !bottom
+ if styleMap[id]["margin-bottom"] != "" {
+ v, _ := utils.ConvertToPixels(styleMap[id]["margin-top"], float32(fs), windowHeight)
+ btmOS += v
+ }
@@ -210,2 +184,3 @@ func ComputeNodeStyle(n Node) {
- if left || relPos {
- x += n.Margin.Left
+ // Set the position before calling children so they can see where the parent is
+ if styleMap[id] == nil {
+ styleMap[id] = make(map[string]string)
@@ -213,2 +188,11 @@ func ComputeNodeStyle(n Node) {
- if top || relPos {
- y += n.Margin.Top
+ styleMap[id]["x"] = fmt.Sprintf("%g", x1)
+ styleMap[id]["y"] = fmt.Sprintf("%g", y1)
+
+ children := dom.Children(n)
+ oY := btmOS
+ if len(children) > 0 {
+ for _, ch := range children {
+ _, h := position(ch, styleMap, x1, y1+oY, width, height)
+
+ oY += h
+ }
@@ -216,2 +200,9 @@ func ComputeNodeStyle(n Node) {
- if right {
- x -= n.Margin.Right
+
+ return x2 - x1, (y2 + btmOS) - y1
+}
+
+func size(n *html.Node, styleMap map[string]map[string]string, windowWidth, windowHeight float32) (float32, float32) {
+ id := dom.GetAttribute(n, "DOMNODEID")
+ if len(id) == 0 {
+ id = dom.TagName(n) + fmt.Sprint(rand.Int63())
+ dom.SetAttribute(n, "DOMNODEID", id)
@@ -219,2 +210,7 @@ func ComputeNodeStyle(n Node) {
- if bottom {
- y -= n.Margin.Bottom
+
+ fs := font.GetFontSize(styleMap[id])
+
+ var width, height float32
+
+ if styleMap[id]["width"] != "" {
+ width, _ = utils.ConvertToPixels(styleMap[id]["width"], float32(fs), windowWidth)
@@ -223,4 +219,3 @@ func ComputeNodeStyle(n Node) {
- n.X = x
- n.Y = y
- n.Width = width
- n.Height = height
+ if styleMap[id]["height"] != "" {
+ height, _ = utils.ConvertToPixels(styleMap[id]["height"], float32(fs), windowHeight)
+ }
@@ -228 +223,23 @@ func ComputeNodeStyle(n Node) {
- // Call children here
+ children := dom.Children(n)
+ if len(children) > 0 {
+ for _, ch := range children {
+ var wW, wH float32 = width, height
+ if n.Type != html.ElementNode {
+ wW = windowWidth
+ wH = windowHeight
+ }
+ w, h := size(ch, styleMap, wW, wH)
+
+ width = utils.Max(width, w)
+
+ height += h
+
+ }
+ } else if styleMap[id]["display"] != "none" {
+ text := dom.InnerText(n)
+ if len(text) > 0 {
+ if styleMap[id]["font-size"] == "" {
+ styleMap[id]["font-size"] = "1em"
+ }
+ fs2, _ := utils.ConvertToPixels(styleMap[id]["font-size"], fs, width)
+ styleMap[id]["fontSize"] = fmt.Sprintf("%f", fs2)
@@ -230,2 +247,18 @@ func ComputeNodeStyle(n Node) {
- for _, v := range n.Children {
- ComputeNodeStyle(v)
+ _, h := utils.GetTextBounds(text, fs2, width, height)
+
+ height = h
+
+ }
+
+ }
+ var (
+ wMarginWidth float32
+ wMarginHeight float32
+ )
+
+ utils.SetMP(id, styleMap)
+
+ width, height, wMarginWidth, wMarginHeight = utils.AddMarginAndPadding(styleMap, id, width, height)
+
+ if styleMap[id] == nil {
+ styleMap[id] = make(map[string]string)
@@ -232,0 +266,6 @@ func ComputeNodeStyle(n Node) {
+
+ _, right, _, left := utils.GetMarginOffset(n, styleMap, windowWidth, windowHeight)
+
+ styleMap[id]["width"] = fmt.Sprintf("%g", width-(left+right))
+ styleMap[id]["height"] = fmt.Sprintf("%g", height)
+ return wMarginWidth, wMarginHeight
@@ -276 +314,0 @@ func inherit(n *html.Node, styleMap map[string]map[string]string) {
- utils.SetMP(id, styleMap)
@@ -283,241 +320,0 @@ func inherit(n *html.Node, styleMap map[string]map[string]string) {
-
-func initNodes(n *Node, styleMap map[string]map[string]string) {
- println("###$$$####")
- println(n.Id)
- border, err := CompleteBorder(n.Styles)
- if err == nil {
- n.Border = border
- }
-
- fs := font.GetFontSize(n.Styles)
- n.EM = fs
-
- mt, _ := utils.ConvertToPixels(n.Styles["margin-top"], n.EM, n.Parent.Width)
- mr, _ := utils.ConvertToPixels(n.Styles["margin-right"], n.EM, n.Parent.Width)
- mb, _ := utils.ConvertToPixels(n.Styles["margin-bottom"], n.EM, n.Parent.Width)
- ml, _ := utils.ConvertToPixels(n.Styles["margin-left"], n.EM, n.Parent.Width)
- n.Margin = Margin{
- Top: mt,
- Right: mr,
- Bottom: mb,
- Left: ml,
- }
-
- pt, _ := utils.ConvertToPixels(n.Styles["padding-top"], n.EM, n.Parent.Width)
- pr, _ := utils.ConvertToPixels(n.Styles["padding-right"], n.EM, n.Parent.Width)
- pb, _ := utils.ConvertToPixels(n.Styles["padding-bottom"], n.EM, n.Parent.Width)
- pl, _ := utils.ConvertToPixels(n.Styles["padding-left"], n.EM, n.Parent.Width)
- n.Padding = Padding{
- Top: pt,
- Right: pr,
- Bottom: pb,
- Left: pl,
- }
-
- for _, c := range dom.ChildNodes(n.Node) {
- if c.Type == html.ElementNode {
- id := dom.GetAttribute(c, "DOMNODEID")
- println(id)
- node := Node{
- Node: c,
- Parent: n,
- Id: id,
- Styles: styleMap[id],
- }
- initNodes(&node, styleMap)
- n.Children = append(n.Children, node)
- }
- }
-}
-
-func GetPositionOffsetNode(n *Node) *Node {
- pos := n.Styles["position"]
-
- if pos == "relative" {
- return n
- } else {
- if n.Parent.Node != nil {
- return GetPositionOffsetNode(n.Parent)
- } else {
- return nil
- }
- }
-}
-
-func parseBorderShorthand(borderShorthand string) (BorderSide, error) {
- // Split the shorthand into components
- borderComponents := strings.Fields(borderShorthand)
-
- // Ensure there are at least 1 component (width or style or color)
- if len(borderComponents) >= 1 {
- width := "0px" // Default width
- style := "solid"
- color := "#000000" // Default color
-
- // Extract numeric part for width
- if strings.ContainsAny(borderComponents[0], "0123456789") {
- width = strings.TrimRightFunc(borderComponents[0], func(r rune) bool {
- return !strings.ContainsRune("0123456789.", r)
- })
- }
-
- // Extract style and color if available
- if len(borderComponents) >= 2 {
- style = borderComponents[1]
- }
- if len(borderComponents) >= 3 {
- color = borderComponents[2]
- }
-
- // Parse width to float
- widthFloat, err := strconv.ParseFloat(width, 32)
- if err != nil {
- return BorderSide{}, fmt.Errorf("failed to parse border width: %v", err)
- }
-
- return BorderSide{
- Width: float32(widthFloat),
- Style: style,
- Color: color,
- Radius: 0.0, // Default radius
- }, nil
- }
-
- return BorderSide{}, fmt.Errorf("invalid border shorthand format")
-}
-
-func CompleteBorder(cssProperties map[string]string) (Border, error) {
- borderShorthand, hasBorder := cssProperties["border"]
-
- var border Border
-
- if hasBorder {
- side, err := parseBorderShorthand(borderShorthand)
- if err != nil {
- return Border{}, err
- }
-
- border.Top = side
- border.Right = side
- border.Bottom = side
- border.Left = side
-
- // Remove the shorthand border property from the map
- delete(cssProperties, "border")
- }
-
- // Map individual border properties
- borderProperties := map[string]string{
- "top": "border-top",
- "right": "border-right",
- "bottom": "border-bottom",
- "left": "border-left",
- }
-
- for side, property := range borderProperties {
- width := cssProperties[property+"-width"]
- style := cssProperties[property+"-style"]
- color := cssProperties[property+"-color"]
-
- if width == "" {
- width = "1px" // Default width
- }
-
- if style == "" {
- style = "solid" // Default style
- }
-
- if color == "" {
- color = "#000000" // Default color
- }
-
- radius := cssProperties[property+"-radius"]
- radiusValue, err := strconv.ParseFloat(radius, 32)
- if err != nil || radius == "" {
- radiusValue = 0.0 // Default radius
- }
-
- borderSide, err := parseBorderShorthand(fmt.Sprintf("%s %s %s", width, style, color))
- if err != nil {
- return Border{}, err
- }
-
- borderSide.Radius = float32(radiusValue)
-
- switch side {
- case "top":
- border.Top = borderSide
- case "right":
- border.Right = borderSide
- case "bottom":
- border.Bottom = borderSide
- case "left":
- border.Left = borderSide
- }
- }
-
- return border, nil
-}
-
-func Print(n *Node, indent int) {
- pre := strings.Repeat("\t", indent)
- fmt.Printf(pre+"%s\n", n.Id)
- fmt.Printf(pre+"-- Parent: %d\n", n.Parent.Id)
- fmt.Printf(pre+"\t-- Width: %f\n", n.Parent.Width)
- fmt.Printf(pre+"\t-- Height: %f\n", n.Parent.Height)
- fmt.Printf(pre+"-- Children: %d\n", len(n.Children))
- fmt.Printf(pre+"-- EM: %f\n", n.EM)
- fmt.Printf(pre+"-- X: %f\n", n.X)
- fmt.Printf(pre+"-- Y: %f\n", n.Y)
- fmt.Printf(pre+"-- Width: %f\n", n.Width)
- fmt.Printf(pre+"-- Height: %f\n", n.Height)
- fmt.Printf(pre+"-- Styles: %#v\n", n.Styles)
-
- for _, v := range n.Children {
- Print(&v, indent+1)
- }
-}
-
-func InheritProp(n *Node, prop string) string {
- value := n.Styles[prop]
-
- if value != "" {
- return value
- } else {
- if n.Parent.Node != nil {
- v := InheritProp(n.Parent, prop)
- return v
- } else {
- return ""
- }
- }
-}
-
-func InheritPropWithNode(n *Node, prop string) (string, *Node) {
- value := n.Styles[prop]
-
- if value != "" {
- return value, n
- } else {
- if n.Parent != nil {
- v, p := InheritPropWithNode(n.Parent, prop)
- return v, p
- } else {
- return "", &Node{}
- }
- }
-}
-
-func flatten(n *Node) []Node {
- var nodes []Node
- nodes = append(nodes, *n)
-
- children := n.Children
- if len(children) > 0 {
- for _, ch := range children {
- chNodes := flatten(&ch)
- nodes = append(nodes, chNodes...)
- }
- }
- return nodes
-}