Skip to content

Releases: Macawls/ogre

v1.4.0

12 Apr 21:59

Choose a tag to compare

Performance

Major rendering speed improvements across the PNG/JPEG pipeline.

Gradient Strip Precomputation

Instead of computing color interpolation per-pixel, gradients now build a 1D color lookup table along the gradient line and sample from it. This eliminates redundant srgbToLinear/linearToSrgb conversions and interpolateLinearStops calls.

  • Linear gradients: 8x faster (49ms β†’ 6ms at component level)
  • Radial gradients: 7x faster (54ms β†’ 8ms at component level)

Buffer Pooling (sync.Pool)

Temporary full-viewport RGBA images (3MB+ each at 1200Γ—630) used for opacity compositing, border-radius clipping, overflow:hidden, and border rendering are now pooled and reused instead of allocated fresh each time.

  • Up to 56% memory reduction per render

Rounded Mask Cache

Supersampled anti-aliased border-radius masks are cached by (width, height, tl, tr, br, bl). Elements sharing the same dimensions and border-radius reuse a single cached mask instead of recomputing.

Parallel Box Blur

Shadow blur passes now split rows/columns across goroutines with direct Pix slice access, eliminating method call overhead.

  • Shadow blur: 4.3x faster (5ms β†’ 1.15ms at component level)

End-to-End Results

Benchmarked on AMD Ryzen 5 5600H, 1200Γ—630 PNG output:

Fixture Before After Improvement
Linear gradient 145ms 100ms 31% faster
Radial gradient 319ms 266ms 17% faster
Box shadow 33ms 24ms 28% faster
Product pricing 129ms 83ms 36% faster
Blog card 73ms 53ms 27% faster
Dashboard stat 24ms / 12MB 19ms / 5MB 22% faster, 58% less memory

Component-level benchmarks added in render/bench_test.go for ongoing tracking.

v1.3.0

12 Apr 20:28

Choose a tag to compare

Layout Engine Fixes

Text overflow in column-direction flex containers

determineFlexBaseSize and determineCrossSize in the flexbox engine passed the main-axis size as maxWidth to the text measure function. In column layouts (main axis = height), text received the container height as its width constraint and never wrapped. Fixed by swapping Measure() arguments when isRow is false.

Containers grow to fit content height

Containers without explicit CSS height now shrink to fit their content. Previously, computeNode() set Layout.Height from availableHeight and never updated it after children were laid out. Now recalculates from line cross sizes (row) or item main sizes (column) after layout completes.

Performance

sRGB lookup tables for gradient rendering

Replaced per-pixel math.Pow calls in gradient interpolation with precomputed lookup tables β€” 256-entry decode table and 4096-entry encode table (32KB, fits L1 cache). Eliminates millions of transcendental function calls per gradient render.

Docs & Site

  • Updated design goals to emphasize output quality over raw benchmarks
  • Added comparison tool commands to AGENTS.md
  • Cache busting for example images via Astro asset pipeline
  • Dark mode default, emoji card layout fixes

Full Changelog: v1.2.0...v1.3.0

v1.2.0

10 Apr 11:02

Choose a tag to compare

What's New

SVG Rasterization & Inline SVGs

  • SVG data URIs in <img> tags now render in PNG and JPEG output (previously SVG-only)
  • Inline <svg> elements are fully supported in all output formats
  • Minimal SVG rasterizer with path, rect, circle, ellipse, polygon, stroke, and translate transform support
  • Even-odd fill rule via sub-path XOR compositing

Gradient Rendering Overhaul

  • Fixed gradient direction (was reversed vs CSS spec in PNG/JPEG)
  • Linear RGB color interpolation with ordered dithering eliminates visible banding
  • SVG gradients now use color-interpolation="linearRGB" to match PNG output

Tailwind Gradient Utilities

  • bg-gradient-to-{t,tr,r,br,b,bl,l,tl} direction classes
  • from-*, via-*, to-* gradient stop color classes
  • Composes into background-image: linear-gradient(...) automatically

PNG/JPEG Rendering Fixes

  • Fixed premultiplied alpha compositing β€” eliminates bright-edge artifacts on semi-transparent rounded rects
  • Sub-pixel text positioning for better SVG/PNG parity
  • 2x supersampled rounded corner masks for smoother curves
  • Rounded borders now clip through the mask (fixes angular corners on small elements)
  • RTL text shaping in PNG via ShapedTextToPath + vector.Rasterizer
  • 4:4:4 chroma JPEG encoder prevents color shifts on dark backgrounds

Other Fixes

  • HTML width/height attributes now map to CSS styles (like browsers)
  • font-family CSS parsing correctly extracts first family from comma-separated fallback lists
  • Open SVG subpaths implicitly closed for fill operations

Docs & Site

  • Shared template constants between playground and examples
  • Fullscreen image viewer with zoom, pan, and SVG/PNG/JPEG format switching
  • New RTL (Arabic) and Tailwind gradient examples
  • Fixed dependency claims β€” go-text/typesetting now listed
  • Rate limit warning on playground
  • curl example in rendering guide

Full Changelog: v1.1.0...v1.2.0

v1.1.0

09 Apr 23:54

Choose a tag to compare

Changelog

Features

  • 4c4ace0 feat: add client-side navigation + external links open in new tab
  • 0695507 feat: environment variable configuration for server

Bug Fixes

  • 3173ba2 fix: add site URL for sitemap generation
  • e8296b9 fix: light mode accent color, simplify CLAUDE.md, docs commit scope
  • 744e44d fix: remove redundant Docs link from header, reorder nav

Performance

  • bf200ff perf: aggressive prefetch + client prerendering + fast transitions

Other

  • ef471d0 revert: remove client-side navigation, prefetch, and view transitions

v1.0.0

09 Apr 23:10

Choose a tag to compare

Changelog

Features

  • fa0c535 feat: initial release v1.0.0

Bug Fixes

  • a0fafd8 fix: CI β€” use golangci-lint-action v7, relax perf test timeout for race detector
  • ce2f89d fix: add .node-version for Nixpacks (Node 22 required by Astro)
  • fe027bf fix: add version field to golangci-lint config for v2 compatibility
  • d19a92f fix: gitignore was blocking cmd/ogre/ β€” change 'ogre' to '/ogre'
  • 4b0fb7a fix: install golangci-lint from source for Go 1.25 compat
  • 51126b8 fix: pin golangci-lint to v2.1 for Go 1.25 compatibility
  • 1863f18 fix: remove gosimple linter (merged into staticcheck in v2)
  • e9ea8bc fix: use golangci-lint v2.11.4 for Go 1.25 support