diff --git a/src/pixie/fontformats/opentype.nim b/src/pixie/fontformats/opentype.nim
index e34cce6..84d7f34 100644
--- a/src/pixie/fontformats/opentype.nim
+++ b/src/pixie/fontformats/opentype.nim
@@ -1,4 +1,4 @@
-import bitops, flatty/binny, math, pixie/common, pixie/paths, sets, tables,
+import flatty/binny, math, pixie/common, pixie/paths, sets, tables,
     unicode, vmath
 
 ## See https://docs.microsoft.com/en-us/typography/opentype/spec/
@@ -867,8 +867,15 @@ proc parseCoverage(buf: string, offset: int): Coverage =
     else:
       failUnsupported()
 
-proc valueFormatSize(valueFormat: uint16): int {.inline.} =
-  countSetBits(valueFormat) * 2
+proc valueFormatSize(valueFormat: uint16): int =
+  # countSetBits(valueFormat) * 2
+  var
+    n = valueFormat
+    bitsSet: int
+  while n > 0:
+    n = (n and (n - 1))
+    inc bitsSet
+  bitsSet * 2
 
 proc parseValueRecord(
   buf: string, offset: int, valueFormat: uint16
diff --git a/src/pixie/fonts.nim b/src/pixie/fonts.nim
index 73a257a..b7cfe73 100644
--- a/src/pixie/fonts.nim
+++ b/src/pixie/fonts.nim
@@ -413,7 +413,7 @@ proc parseOtf*(buf: string): Font =
   result.typeface.opentype = parseOpenType(buf)
   result.size = 12
   result.lineHeight = AutoLineHeight
-  result.paint = Paint(kind: pkSolid, color: rgbx(0, 0, 0, 255))
+  result.paint = rgbx(0, 0, 0, 255)
 
 proc parseTtf*(buf: string): Font =
   parseOtf(buf)
diff --git a/src/pixie/paths.nim b/src/pixie/paths.nim
index 39b8aff..a379113 100644
--- a/src/pixie/paths.nim
+++ b/src/pixie/paths.nim
@@ -500,6 +500,11 @@ proc roundedRect*(
   ## Adds a rounded rectangle.
   ## Clockwise param can be used to subtract a rect from a path when using
   ## even-odd winding rule.
+
+  if nw == 0 and ne == 0 and se == 0 and sw == 0:
+    path.rect(x, y, w, h, clockwise)
+    return
+
   let
     s = splineCircleK
 
@@ -992,7 +997,8 @@ proc computePixelBounds(segments: seq[(Segment, int16)]): Rect =
     xMax = float32.low
     yMin = float32.high
     yMax = float32.low
-  for (segment, _) in segments:
+  for i in 0 ..< segments.len: # For arc
+    let segment = segments[i][0]
     xMin = min(xMin, min(segment.at.x, segment.to.x))
     xMax = max(xMax, max(segment.at.x, segment.to.x))
     yMin = min(yMin, segment.at.y)
@@ -1089,14 +1095,14 @@ proc shouldFill(windingRule: WindingRule, count: int): bool {.inline.} =
   of wrEvenOdd:
     count mod 2 != 0
 
-template computeCoverages(
+proc computeCoverages(
   coverages: var seq[uint8],
   hits: var seq[(float32, int16)],
   size: Vec2,
   y: int,
   partitioning: Partitioning,
   windingRule: WindingRule
-) =
+) {.inline.} =
   const
     quality = 5 # Must divide 255 cleanly (1, 3, 5, 15, 17, 51, 85)
     sampleCoverage = (255 div quality).uint8
@@ -1106,15 +1112,20 @@ template computeCoverages(
   zeroMem(coverages[0].addr, coverages.len)
 
   # Do scanlines for this row
-  let partition = getIndexForY(partitioning, y)
+  let partitionIndex = partitioning.getIndexForY(y)
   var
     yLine = y.float32 + initialOffset - offset
+    scanline = line(vec2(0, yLine), vec2(size.x, yLine))
     numHits: int
   for m in 0 ..< quality:
     yLine += offset
-    let scanline = line(vec2(0, yLine), vec2(size.x, yLine))
+    scanline.a.y = yLine
+    scanline.b.y = yLine
     numHits = 0
-    for (segment, winding) in partitioning.partitions[partition]:
+    for i in 0 ..< partitioning.partitions[partitionIndex].len: # For arc
+      let
+        segment = partitioning.partitions[partitionIndex][i][0]
+        winding = partitioning.partitions[partitionIndex][i][1]
       if segment.at.y <= scanline.a.y and segment.to.y >= scanline.a.y:
         var at: Vec2
         if scanline.intersects(segment, at) and segment.to != at:
@@ -1198,7 +1209,7 @@ proc fillShapes(
     startX = max(0, bounds.x.int)
     startY = max(0, bounds.y.int)
     pathHeight = min(image.height, (bounds.y + bounds.h).int)
-    partitions = partitionSegments(segments, startY, pathHeight - startY)
+    partitioning = partitionSegments(segments, startY, pathHeight - startY)
 
   var
     coverages = newSeq[uint8](image.width)
@@ -1210,7 +1221,7 @@ proc fillShapes(
       hits,
       image.wh,
       y,
-      partitions,
+      partitioning,
       windingRule
     )
 
@@ -1308,7 +1319,7 @@ proc fillShapes(
     startY = max(0, bounds.y.int)
     stopY = min(mask.height, (bounds.y + bounds.h).int)
     pathHeight = stopY - startY
-    partitions = partitionSegments(segments, startY, pathHeight)
+    partitioning = partitionSegments(segments, startY, pathHeight)
 
   when defined(amd64) and not defined(pixieNoSimd):
     let maskerSimd = bmNormal.maskerSimd()
@@ -1323,7 +1334,7 @@ proc fillShapes(
       hits,
       mask.wh,
       y,
-      partitions,
+      partitioning,
       windingRule
     )
 
@@ -1551,9 +1562,10 @@ proc fillPath*(
 ) =
   ## Fills a path.
   if paint.kind == pkSolid:
-    var shapes = parseSomePath(path, transform.pixelScale())
-    shapes.transform(transform)
-    image.fillShapes(shapes, paint.color, windingRule, paint.blendMode)
+    if paint.color.a > 0:
+      var shapes = parseSomePath(path, transform.pixelScale())
+      shapes.transform(transform)
+      image.fillShapes(shapes, paint.color, windingRule, paint.blendMode)
     return
 
   let
@@ -1614,16 +1626,17 @@ proc strokePath*(
 ) =
   ## Strokes a path.
   if paint.kind == pkSolid:
-    var strokeShapes = strokeShapes(
-      parseSomePath(path, transform.pixelScale()),
-      strokeWidth,
-      lineCap,
-      lineJoin,
-      miterLimit,
-      dashes
-    )
-    strokeShapes.transform(transform)
-    image.fillShapes(strokeShapes, paint.color, wrNonZero, paint.blendMode)
+    if paint.color.a > 0:
+      var strokeShapes = strokeShapes(
+        parseSomePath(path, transform.pixelScale()),
+        strokeWidth,
+        lineCap,
+        lineJoin,
+        miterLimit,
+        dashes
+      )
+      strokeShapes.transform(transform)
+      image.fillShapes(strokeShapes, paint.color, wrNonZero, paint.blendMode)
     return
 
   let