Skip to content

Releases: Alipsa/gsvg

Ver 1.0.0

18 Jan 17:15

Choose a tag to compare

Version 1.0.0 - 2026-01-18

Added

  • gsvg-export module for rendering/optimization.
  • gsvg-examples module with example groovy script using the gsv library.
  • CSS selector queries (css, cssFirst) alongside XPath.
  • Rendering benchmarks and expanded performance documentation.

Changed

  • Parsing now preserves raw attribute strings; numeric precision formatting only applies to programmatic attribute setting.
  • Merge/cloning paths optimized for lower overhead.

Ver 0.9.0

16 Jan 08:25

Choose a tag to compare

Polish and Production Readiness

This release represents the final polish phase before v1.0, focusing on file size optimization, accessibility,
developer experience enhancements, and comprehensive documentation. All features are fully backward compatible
and production-ready.

Numeric Precision Control

  • Intelligent number formatting with configurable precision for 30-50% file size reduction
  • New NumberFormatter utility (se.alipsa.groovy.svg.utils.NumberFormatter):
    • Default precision: 3 decimals (matching SVGO and Adobe Illustrator industry standards)
    • Automatic removal of trailing zeros (12.120 → 12.12)
    • Clean integer output (50.0 → 50)
    • Thread-local global configuration: setDefaultPrecision(), resetPrecision()
    • Per-document precision: svg.setMaxPrecision(2)
  • Integrated at SvgElement.addAttribute() level - all numeric attributes automatically formatted
  • Full calculation precision maintained - rounding only applied at serialization
  • Benefits: 30-50% file size reduction for coordinate-heavy graphics, cleaner output, industry standard alignment
  • 100% backward compatible - no API changes, automatic optimization
// Automatic precision control:
circle.cx(12.123456789)      // Outputs: cx="12.123" (default 3 decimals)
rect.x(50.0)                 // Outputs: x="50" (no trailing zeros)
line.x1(10.12)               // Outputs: x1="10.12" (preserves existing precision)

// Configuration:
NumberFormatter.setDefaultPrecision(5)  // Global setting (thread-local)
svg.setMaxPrecision(2)                  // Per-document override
NumberFormatter.resetPrecision()        // Reset to default (3)

Accessibility Helpers

  • Complete ARIA support with helper methods and validation
  • 15 ARIA methods added to SvgElement (inherited by all elements):
    • role(role) / getRole() - Set/get ARIA role
    • ariaLabel(label) / getAriaLabel() - Accessible name
    • ariaLabelledBy(ids) / getAriaLabelledBy() - Reference to label elements
    • ariaDescribedBy(ids) / getAriaDescribedBy() - Reference to description elements
    • ariaHidden(hidden) / isAriaHidden() - Hide from screen readers
    • ariaLive(polite|assertive|off) / getAriaLive() - Live region updates
    • decorative() - Convenience: role='presentation' + aria-hidden='true'
    • accessibleImage(label) - Convenience: role='img' + ariaLabel(label)
  • New AccessibilityRule for validation (se.alipsa.groovy.svg.validation.rules.AccessibilityRule):
    • Validates root SVG has accessible name (WARNING)
    • Validates SVG with role='img' has label (WARNING)
    • Validates interactive elements have labels (WARNING)
    • Validates ARIA reference IDs exist (ERROR)
    • Validates decorative elements don't need labels
  • New validation factory: ValidationEngine.createAccessibility() for accessibility-only validation
  • Comprehensive documentation in new doc/accessibility.md guide
// Make SVG accessible:
svg.role('img').ariaLabel('Monthly revenue chart showing growth trend')

// Or use title/desc:
svg.addTitle('Revenue Dashboard')
svg.addDesc('Interactive chart showing monthly revenue from January to December')

// Interactive elements:
circle.ariaLabel('January sales: $50,000 - Click for details')
      .addAttribute('tabindex', '0')

// Decorative elements:
svg.addRect().decorative()  // Sets role='presentation' + aria-hidden='true'

// Validate accessibility:
ValidationEngine engine = ValidationEngine.createAccessibility()
ValidationReport report = engine.validate(svg)

Builder Pattern Enhancements

Effects Presets

  • New Effects utility (se.alipsa.groovy.svg.effects.Effects) with 7 preset filters:
    • dropShadow(defs, options) - Configurable drop shadow effect
    • glow(defs, options) - Glow/halo effect with color and strength
    • blur(defs, blur, id) - Gaussian blur filter
    • grayscale(defs, id) - Convert to grayscale
    • sepia(defs, id) - Sepia tone effect
    • brightness(defs, options) - Adjust brightness (0.0-2.0)
    • contrast(defs, options) - Adjust contrast (0.0-2.0)
    • applyFilter(element, filter) - Apply filter to element
  • Map-based configuration for flexibility and sensible defaults
  • Integrated with existing Filter API - returns configured Filter objects
Defs defs = svg.addDefs()

// Drop shadow:
Filter shadow = Effects.dropShadow(defs,
    id: 'shadow1', dx: 3, dy: 3, blur: 5, opacity: 0.6)
element.filter('url(#shadow1)')

// Glow effect:
Filter glow = Effects.glow(defs,
    id: 'glow1', color: 'yellow', blur: 5, strength: 3)

// Color adjustments:
Filter gray = Effects.grayscale(defs, 'gray1')
Filter bright = Effects.brightness(defs, amount: 1.5)

Shape Presets

  • New Shapes utility (se.alipsa.groovy.svg.presets.Shapes) with 5 common shape generators:
    • roundedRect(parent, options) - Rectangle with uniform corner radius
    • star(parent, options) - Multi-point star polygon
    • arrow(parent, options) - Arrow path with configurable head
    • regularPolygon(parent, options) - Regular polygons (triangle, hexagon, etc.)
    • speechBubble(parent, options) - Speech bubble with tail
  • Automatic path calculations for complex geometries
  • Uses PathBuilder for precise path construction
// 5-point star:
Polygon star = Shapes.star(svg,
    cx: 150, cy: 150, points: 5, outerRadius: 50, innerRadius: 25)

// Arrow:
Path arrow = Shapes.arrow(svg,
    x1: 10, y1: 50, x2: 100, y2: 50, headSize: 15, headAngle: 30)

// Speech bubble:
Path bubble = Shapes.speechBubble(svg,
    x: 10, y: 10, width: 100, height: 60, tailX: 50, tailY: 80)

Template System

  • New Template base class (se.alipsa.groovy.svg.templates.Template) for reusable SVG patterns:
    • abstract apply(parent, params) - Apply template with parameters
    • getDefaults() - Define default parameter values
    • mergeParams(params) - Merge user params with defaults
    • Extensible architecture for custom templates
  • ChartLegend example template (se.alipsa.groovy.svg.templates.ChartLegend):
    • Configurable chart legend with color swatches and labels
    • 12 configuration parameters (position, size, styling, border, etc.)
    • Production-ready for data visualization
// Use ChartLegend template:
ChartLegend legend = new ChartLegend()
legend.apply(svg, [
    x: 450, y: 50,
    items: [
        [color: 'red', label: 'Series 1'],
        [color: 'blue', label: 'Series 2'],
        [color: 'green', label: 'Series 3']
    ]
])

// Create custom templates:
class ButtonTemplate extends Template {
    SvgElement apply(AbstractElementContainer parent, Map params) {
        G button = parent.addG()
        button.addRect()
            .x(params.x).y(params.y)
            .width(100).height(50)
            .rx(5).fill('blue')
        button.addText(params.label)
            .x(params.x + 50).y(params.y + 30)
            .textAnchor('middle').fill('white')
        return button
    }
}

DSL Configuration Closures

  • Closure-based configuration for all common shapes:
    • Added 9 DSL methods to AbstractElementContainer: addCircle{}, addRect{}, addEllipse{}, addLine{}, addPath{}, addText{}, addG{}, addPolygon{}, addPolyline{}
    • Uses @DelegatesTo annotation for IDE autocomplete support
    • Groovy-idiomatic syntax for cleaner SVG construction
    • Method chaining still works within closures
// DSL-style configuration:
svg.addCircle {
    cx 100
    cy 100
    r 50
    fill 'red'
    stroke 'black'
    strokeWidth 2
}

svg.addRect {
    x 10
    y 10
    width 100
    height 50
    fill 'blue'
}

svg.addG {
    fill 'green'
    stroke 'darkgreen'

    // Add children within closure:
    addCircle().cx(50).cy(50).r(20)
    addRect().x(100).y(30).width(40).height(40)
}

Quick Wins (Developer Experience)

Clone with Modifications

  • New cloneWith(parent, modifications) method on SvgElement:
    • Clone element and apply attribute modifications in one operation
    • Map-based modifications for convenience
    • Useful for creating element variations
Circle original = svg.addCircle()
    .cx(100).cy(100).r(50).fill('red')

// Clone with modifications:
Circle blue = original.cloneWith(svg, [fill: 'blue', cx: 250])
Circle large = original.cloneWith(svg, [r: 75, fill: 'green', cx: 400])

Shape Factory Methods

  • 5 convenience factory methods added directly to Svg class:
    • createRoundedRect(options) - Rounded rectangle
    • createStar(options) - Star polygon
    • createArrow(options) - Arrow path
    • createRegularPolygon(options) - Regular polygons
    • createSpeechBubble(options) - Speech bubble
  • Delegates to Shapes utility but more discoverable on main Svg class
  • Fluent API integration - returns configured elements for method chaining
// More discoverable than Shapes.star():
Polygon star = svg.createStar(
    cx: 100, cy: 100, points: 5, outerRadius: 50)

Rect rounded = svg.createRoundedRect(
    x: 10, y: 10, width: 100, height: 60, radius: 10)

Path arrow = svg.createArrow(
    x1: 10, y1: 50, x2: 100, y2: 50, headSize: 15)

Null-Safe Attribute Access

  • 3 new getAttributeOrDefault() methods on SvgElement:
    • getAttributeOrDefault(name, defaultValue) - Simple string attribute
    • getAttributeOrDefault(qname, defaultValue) - Qualified name
    • getAttributeOrDefault(prefix, localName, defaultValue) - Namespaced
  • Prevents NullPointerException when accessing missing attributes
  • Cleaner code - no manual null checking needed
// Safe access with defaults:
String fill = circle.getAttributeOrD...
Read more

Ver 0.8.0

15 Jan 08:54

Choose a tag to compare

Advanced Features

This release implements three major features: CSS integration, validation helpers, and performance benchmarks. All features are fully backward compatible and opt-in.

CSS Integration

  • New CSS object model with ph-css 8.1.1 integration for robust parsing
  • CSS classes (se.alipsa.groovy.svg.css.CssRule, CssStyleSheet, CssParser)
  • Style element enhancements on Style:
    • addRule(selector, declarations) - Add CSS rules programmatically
    • removeRule(selector) - Remove rules by selector
    • getStyleSheet() - Get parsed CssStyleSheet object
    • setStyleSheet(CssStyleSheet) - Replace stylesheet
    • getRules() - Get all CSS rules
  • Inline style Map API on SvgElement:
    • style(Map<String, Object>) - Set inline styles from map
    • getStyleMap() - Parse inline style to map
    • getStyleProperty(property) - Get specific style property
  • CSS class management on SvgElement:
    • addClass(className) - Add CSS class
    • removeClass(className) - Remove CSS class
    • toggleClass(className) - Toggle CSS class
    • hasClass(className) - Check if class exists
    • getClasses() - Get all CSS classes as list
  • Full method chaining support for all CSS methods
  • Maintains backward compatibility - all string-based style/class APIs still work
// CSS object model:
def style = svg.addStyle()
style.addRule('.highlight', [fill: 'red', stroke: 'black', 'stroke-width': '2'])
style.addRule('#logo', [transform: 'scale(2)'])

// Inline style Map API:
rect.style([fill: 'red', stroke: 'blue', 'stroke-width': '2'])
def fillColor = rect.getStyleProperty('fill') // 'red'

// Class management:
rect.addClass('highlight').addClass('selected')
rect.removeClass('selected')
if (rect.hasClass('highlight')) { /* ... */ }

Validation Helpers

  • Complete opt-in validation system - library remains permissive by default
  • Validation infrastructure:
    • ValidationLevel enum (ERROR, WARNING, INFO)
    • ValidationIssue - Immutable issue objects with level, message, element path
    • ValidationReport - Aggregates issues with query methods
    • ValidationRule interface - Extensible validation rule system
    • ValidationEngine - Orchestrates validation with customizable rule sets
  • Six core validation rules:
    • RequiredAttributeRule - Validates required attributes (circle needs cx/cy/r, etc.)
    • AttributeValueRule - Validates attribute value domains and ranges
    • ElementNestingRule - Validates valid parent-child relationships
    • ViewBoxRule - Validates viewBox format and dimensions
    • HrefRule - Validates href/xlink:href references point to existing IDs
    • DuplicateIdRule - Detects duplicate element IDs
  • Validation methods on Svg and SvgElement:
    • validate() - Validate with default rules
    • validate(ValidationEngine) - Validate with custom rules
    • isValid() - Quick validation check (no errors)
  • Optimized performance - All rules run in O(N) time
  • No breaking changes - All invalid SVG creation continues to work, validation is purely opt-in
// Basic validation:
def report = svg.validate()
if (report.isValid()) {
    // No errors (warnings/info don't fail validation)
}

// Inspect issues:
report.getErrors().each { println "ERROR: ${it.message}" }
report.getWarnings().each { println "WARNING: ${it.message}" }
report.getInfo().each { println "INFO: ${it.message}" }

// Custom validation:
def engine = ValidationEngine.createDefault()
engine.removeRule("VIEWBOX_RULE") // Disable specific rule
svg.validate(engine)

Performance Benchmarks

  • Complete JMH benchmark suite (JMH 1.37)
  • 9 benchmark classes covering all major operations:
    • ParsingBenchmark - Parse simple/medium/large/complex SVGs
    • SerializationBenchmark - toXml() and toXmlPretty() performance
    • CreationBenchmark - Element creation and fluent API chaining
    • MergingBenchmark - Horizontal/vertical/on-top merge performance
    • CloningBenchmark - Deep copy operations
    • UtilityBenchmark - Color, PathBuilder, ViewBox utilities
    • SelectionBenchmark - Type filtering, XPath queries, descendants
    • RunAllBenchmarks - Convenience runner for all benchmarks
    • BenchmarkBase - Shared benchmark infrastructure
  • 4 test SVG files in src/test/resources/benchmarks/:
    • simple.svg (10 elements) - Basic operations
    • medium.svg (100 elements) - Typical documents
    • large.svg (1000 elements) - Stress testing
    • complex.svg - Real-world structure
  • Benchmark sanity tests - 8 tests ensuring benchmarks execute without errors
  • Comprehensive results documented in doc/benchmarks.md with performance analysis
  • Easy to run: mvn exec:java -Dexec.classpathScope=test -Dexec.mainClass="benchmarks.RunAllBenchmarks"

Tests

  • Added 146 new tests (28 CSS tests, 73 validation tests, 8 benchmark tests, 37 rule tests)
  • Total test count: 593 tests (was 447 in v0.7.0)
  • 100% pass rate
  • Comprehensive coverage of all new features

Bug Fixes

  • Fixed HrefRule performance issue (O(N²) → O(N) optimization)
  • Fixed HrefRule namespace exception when xlink namespace not bound
  • Added proper exception handling for namespace-prefixed attributes

Documentation

  • Updated kanban/in-progress/svgTodo.md marking Phase 3 complete
  • Added extensive inline documentation with usage examples
  • All new classes fully documented with Groovydoc
  • Library status updated to 593 tests

API additions/updates

  • se.alipsa.groovy.svg.css.CssRule: CSS rule value object
  • se.alipsa.groovy.svg.css.CssStyleSheet: CSS stylesheet management
  • se.alipsa.groovy.svg.css.CssParser: CSS parsing utilities (package-private)
  • Style: addRule(), removeRule(), getStyleSheet(), setStyleSheet(), getRules()
  • SvgElement: style(Map), getStyleMap(), getStyleProperty(), addClass(), removeClass(), toggleClass(), hasClass(), getClasses()
  • Svg: validate(), validate(ValidationEngine), isValid()
  • SvgElement: validate(), isValid()
  • se.alipsa.groovy.svg.validation.*: Complete validation infrastructure
  • se.alipsa.groovy.svg.validation.rules.*: Six validation rule implementations

Dependency updates

  • Added ph-css 8.1.1 for css management
  • Added JMH 1.37 for benchmarking (test scope)

Breaking changes

  • None - all additions are backward compatible and opt-in

Ver 0.7.0

14 Jan 10:39

Choose a tag to compare

This release implements features focusing on advanced path manipulation, coordinate system utilities, and powerful element selection methods.

Path Data Manipulation

  • New PathBuilder class (se.alipsa.groovy.svg.utils.PathBuilder) for fluent path construction
  • All SVG path commands supported:
    • MoveTo: moveTo(x, y), moveToRel(dx, dy), M(), m()
    • LineTo: lineTo(x, y), lineToRel(dx, dy), L(), l()
    • Horizontal/Vertical: horizontalTo(x), verticalTo(y), H(), V(), h(), v()
    • Cubic bezier: curveTo(), curveToRel(), smoothCurveTo(), C(), S(), c(), s()
    • Quadratic bezier: quadTo(), quadToRel(), smoothQuadTo(), Q(), T(), q(), t()
    • Arcs: arc(), arcRel(), A(), a()
    • Close path: closePath(), Z(), z()
  • Fluent API: Full method chaining support for building complex paths
  • Path parsing: PathBuilder.parse(pathString) to parse and extend existing paths
  • Path integration: Path.d(PathBuilder) accepts PathBuilder objects directly
  • Utility methods: copy(), getCommands(), isEmpty(), toString()

ViewBox / Coordinate Helpers

  • New ViewBox class (se.alipsa.groovy.svg.utils.ViewBox) for viewport management
  • Creation methods:
    • ViewBox.of(minX, minY, width, height) - Create viewBox
    • ViewBox.parse(string) - Parse viewBox strings
  • Transformations (all immutable, return new ViewBox):
    • scale(factor), scale(scaleX, scaleY) - Scale dimensions
    • translate(dx, dy) - Shift coordinates
    • expand(margin) - Add margins
    • centerAt(cx, cy) - Center at point
    • withAspectRatio(ratio) - Set aspect ratio
    • fitToContain(other) - Fit viewBox to contain another
  • Query methods:
    • getCenterX(), getCenterY(), getMaxX(), getMaxY(), getAspectRatio()
    • contains(x, y), contains(viewBox), intersects(viewBox)
  • Integration with Svg, Symbol, and View elements:
    • svg.viewBox(ViewBox) - Accept ViewBox objects
    • svg.viewBox(minX, minY, width, height) - Four-parameter convenience
    • svg.getViewBoxObject() - Parse and return ViewBox object
  • Output: toString() produces SVG-compatible viewBox strings, toMap() for data access

Enhanced Element Selection

  • Filter and find methods:
    • filter(predicate) - Filter elements by closure
    • findAll(Class, predicate) - Find all of a type, optionally filtered
    • findFirst(predicate) - Find first matching element
    • findFirst(Class) - Find first of a type
  • Recursive search:
    • descendants() - Get all descendant elements recursively
    • descendants(Class) - Get all descendants of a specific type
  • XPath queries:
    • xpath(query) - Execute XPath queries on the SVG DOM
    • Full XPath 1.0 support via dom4j/Jaxen
  • Aggregate operations:
    • count(predicate) - Count matching elements
    • any(predicate) - Check if any element matches
    • all(predicate) - Check if all elements match
    • collect(transform) - Transform and collect values from elements

Tests

  • Added 113 new tests (29 PathBuilder tests, 54 ViewBox tests, 30 enhanced selection tests)
  • Total test count: 447 tests (all passing)
  • 100% pass rate
  • Comprehensive coverage of new utilities
  • XPath namespace handling fully functional with transparent query transformation

Documentation

  • Updated kanban/in-progress/svgTodo.md marking Phase 2 complete
  • Added extensive inline documentation with usage examples
  • All new classes fully documented with Groovydoc

API additions/updates

  • se.alipsa.groovy.svg.utils.PathBuilder: Complete path building utility
  • se.alipsa.groovy.svg.utils.ViewBox: ViewBox manipulation and coordinate helpers
  • Path: d(PathBuilder), builder(PathBuilder) methods
  • Svg, Symbol, View: viewBox(ViewBox), viewBox(minX, minY, width, height), getViewBoxObject() methods
  • ElementContainer: filter(), findAll(), findFirst(), descendants(), xpath(), count(), any(), all(), collect() methods

Breaking changes

  • None - all additions are backward compatible

Ver 0.6.0

13 Jan 15:36
5525c7f

Choose a tag to compare

Ease of Use Enhancements

This release focuses on improving API ergonomics and developer experience with new utilities for common SVG operations.

Transform Utilities

  • Fluent transform API: Added transform methods to AbstractShape for all SVG transformations
    • rotate(angle) and rotate(angle, cx, cy) - rotation with optional center point
    • translate(tx, ty) and translate(tx) - translation (dual-axis or x-axis only)
    • scale(sx, sy) and scale(s) - scaling (non-uniform or uniform)
    • skewX(angle) and skewY(angle) - skewing transformations
    • matrix(a, b, c, d, e, f) - direct matrix transform
    • transform(string) - backward-compatible string setter
  • Chaining support: All transform methods return this for method chaining
  • Append behavior: Transforms append to existing transform attribute (e.g., rect.rotate(45).translate(10, 20))
  • Backward compatible: String-based transform API still works (rect.transform('rotate(45)'))

Color Utilities

  • New Color class (se.alipsa.groovy.svg.utils.Color) for color creation and manipulation
  • Multiple creation methods:
    • Color.rgb(r, g, b) - RGB values (0-255)
    • Color.rgba(r, g, b, a) - RGBA with alpha (0.0-1.0)
    • Color.hex(string) - Hex colors (#RGB, #RRGGBB, #RRGGBBAA)
    • Color.hsl(h, s, l) and Color.hsla(h, s, l, a) - HSL/HSLA values
    • Color.named(name) - Named colors (147 SVG color names supported)
    • Color.parse(string) - Auto-detect and parse any color format
  • Color manipulation:
    • withAlpha(a) - Create new color with different alpha
    • darken(amount) - Darken by percentage (0.0-1.0)
    • lighten(amount) - Lighten by percentage
    • interpolate(other, t) - Mix two colors (t=0.0 to 1.0)
  • Multiple output formats:
    • toHex(includeAlpha) - Hex string representation
    • toRgb() - RGB/RGBA string
    • toHsl() - HSL/HSLA string
    • toString() - SVG-compatible format (hex for opaque, rgba for transparent)
  • 147 named SVG colors: All standard SVG color names (red, blue, crimson, etc.)
  • Type safety: Proper value clamping, equals/hashCode support

Quick Wins

  • hasAttribute(name): Check if an SVG attribute exists on an element
  • attrs(map): Convenient alias for addAttributes(map) for batch attribute setting

Debugging

  • toString() implementation: Added toString() for all SVG elements showing element name, attributes, and parent information for easier debugging

Tests

  • Added 45 new tests (12 transform tests, 30 color tests, 3 utility tests)
  • Total test count: 303 tests (all passing)
  • Comprehensive coverage of new utilities

Ver 0.5.0

09 Jan 21:34

Choose a tag to compare

  • Merging: new SvgMerger utility to merge SVGs horizontally, vertically, or layered on top using pure object-oriented copying (no XML serialization).
  • Cloning support: added SvgElementFactory and adopting constructors across all SVG element types to enable deep copies that preserve DOM and children lists.
  • API ergonomics: SvgElement.clone(AbstractElementContainer) for deep cloning of element trees.
  • Documentation: new doc/merging.md, updated doc/overview.md, and comprehensive sprint summaries.
  • Tests: added SvgMergerTest and SvgElementFactoryTest for merge/copy behavior and coverage.
  • Build cleanup: upgraded JUnit, JaCoCo, and central-publishing plugins; removed legacy Gradle artifacts.

API additions/updates

  • SvgMerger.mergeHorizontally, SvgMerger.mergeVertically, SvgMerger.mergeOnTop.
  • SvgElementFactory.fromElement, SvgElementFactory.deepCopy, SvgElementFactory.copyChildren.
  • SvgElement.clone(AbstractElementContainer) deep clone helper.

Ver 0.4.0

05 Jan 19:20

Choose a tag to compare

  • API ergonomics: property-style attribute access on SvgElement, addAttributes(Map), and Map-based addX(Map) helpers across element containers (filters, gradients, defs, text, etc.).
  • Attribute coverage: expanded fluent setters/getters across shapes, text, gradients, filters, and animation elements (Phase 1-3 convenience methods).
  • Animation/text improvements: more complete Animate/AnimateMotion/AnimateTransform/Set attribute helpers plus additional Text/Tspan/TextPath conveniences.
  • Bug fixes: AbstractPoly.addPoint() and addPoints() now handle missing points attributes correctly.
  • Build & tests: @CompileStatic across core classes, JaCoCo coverage reporting, Gradle wrapper removal, and expanded unit tests (filters, gradients, text, shapes, script/switch, polygon/polyline).

API additions/updates

  • Property-style attribute read/write fallback when no explicit getter/setter exists.
  • Map-based attributes in element factory methods (for example, addRect([x: 1, y: 2])) plus addAttributes(Map).
  • Additional attribute setters for gradients, stops (stop-opacity), filter primitives, and text positioning/typography.

Ver 0.3.0

30 Dec 18:37

Choose a tag to compare

  • Documentation overhaul: new docs in doc/creating.md, doc/parsing.md, and doc/overview.md, plus expanded Groovydoc across the public API and readme tweaks.
  • API ergonomics: added many String overloads for numeric SVG attributes to allow unit/percent values across shapes, text, filters, patterns, markers, symbols, and foreignObject; plus new paint helpers
    (dash array/offset, opacity, miterlimit) on shapes.
  • Build fix: Maven sources JAR now includes Groovy sources (build-helper source roots + source plugin includes).
  • Test coverage: added tests for parsing docs examples and expanded filter/FeComposite coverage.

API additions/updates

  • New convenience setters for SVG attributes across shapes and filters (String overloads for unit/percent values).
  • Additional stroke/fill presentation helpers on shapes (dasharray/dashoffset, opacity, miterlimit).
  • Animation and filter helper extensions (e.g., String overloads for from/k1‑k4, etc.).

Ver 0.2.0

20 Dec 17:19

Choose a tag to compare

  • Security/Parsing
    • Hardened SAX parser against XXE/DTD and enabled secure processing in SvgReader (prevents external entity resolution).
    • Improved element dispatch for prefixed SVG tags and nested handling; namespace declarations now captured before attribute parsing and foreign/default namespaces preserved (e.g. foreignObject/metadata).
    • Safer QName handling and null-safe attribute removal in SvgElement.
  • SVG 1.1 / SVG 2 Coverage
    • Added missing elements: color-profile, cursor, solidcolor, mesh gradients (meshGradient, mesh, meshrow, meshpatch), hatching (hatch, hatchpath), media (audio, video), discard, and font module elements (font, font-face*, glyph, missing-glyph, hkern, vkern, glyphRef, altGlyph*, tref).
    • Added href parity for SVG2: use, image, mpath, feImage, textPath, script accept href with xlink fallback; getters normalized.
  • Attribute/API Enhancements
    • Gradients gain gradientTransform and spreadMethod; filters gain colour-interpolation-filters and filterRes.
    • Markers add markerUnits and orient.
    • Shapes add fill-rule, stroke-linejoin, stroke-linecap.
    • Text adds baseline-shift, dominant-baseline, text-decoration, word-spacing, letter-spacing.
    • Fluent chaining fixed across new setters; Use.getHref() aligned with other elements.
  • Build & Publishing
    • Removed Gradle and added Maven POM with SCM, license, developer, and OSSRH distribution metadata; Groovy groupId corrected to org.apache.groovy.
    • Dependency updates and documentation tweaks.
  • Tests
    • New regression tests for security (XXE block), namespace preservation, href support, and new element parsing;

Ver 0.1.0

16 Feb 16:01

Choose a tag to compare

Initial release