# Export and Conversion

## Overview

cardargus provides two rendering engines for converting SVG to PNG/PDF:

Engine | Package | Fonts | Best For
--- | --- | --- | ---
rsvg | `rsvg`, `magick` | Embedded only | Speed, no Chrome dependency
Chrome | `chromote` | Web fonts + embedded | Perfect font rendering

## Saving as SVG

The simplest way to save a card:

    library(cardargus)

    card <- svg_card(
      title = "PROJECT",
      badges_data = list(list(label = "Status", value = "Active")),
      fields = list(list(list(label = "Name", value = "Test"))),
      bg_color = "#3498db"
    )

    # Save to file (with embedded fonts)
    save_svg(card, "my_card.svg")

## Converting to PNG

### Standard conversion (rsvg)

Uses librsvg/ImageMagick. Fast and reliable, but requires fonts to be embedded in the SVG:

    # Convert SVG string to PNG
    svg_to_png(card, "my_card.png")

    # With custom DPI (default is 300)
    svg_to_png(card, "my_card.png", dpi = 300)

### Chrome-based conversion (recommended for fonts)

Uses headless Chrome via the `chromote` package. Provides perfect font rendering, including Google Fonts loaded via `@import`:

    # Check if Chrome is available
    if (chrome_available()) {
      # High-quality PNG with Chrome
      svg_to_png_chrome(card, "my_card.png", dpi = 300)
    }

    # Convert to PDF (vector output)
    svg_to_pdf_chrome(card, "my_card.pdf")

#### Installing Chrome support

    # Install chromote package
    install.packages("chromote")

    # Check if Chrome is available
    chrome_available()

    # If Chrome is not installed, download it automatically
    ensure_chrome(download = TRUE)

    # This downloads "Chrome for Testing" (~150MB) to your user cache
    # No admin/root permissions required!

### Background options

    # Transparent background (preserves rounded corners)
    svg_to_png(card, "card_transparent.png", dpi = 300)

    # White background
    svg_to_png(card, "card_white.png", dpi = 300, background = "white")

    # Chrome also supports backgrounds
    svg_to_png_chrome(card, "card_white.png", dpi = 300, background = "white")

### PNG with margin

Add a margin around the card:

    # Add 20px margin with white background
    svg_to_png_with_margin(
      card,
      output_path = "card_with_margin.png",
      margin = 20,
      background = "white",
      dpi = 300
    )

## Converting to PDF

Both engines produce vector PDFs (text stays selectable and scales without pixelation).

### Standard conversion (rsvg)

`svg_to_pdf()` mirrors `svg_to_png()`: it sanitizes the SVG, embeds the required fonts, and writes a vector PDF via `rsvg::rsvg_pdf()`. No Chrome required.

    # Vector PDF (via rsvg)
    svg_to_pdf(card, "my_card.pdf")

### Chrome-based conversion

Use `svg_to_pdf_chrome()` when you rely on web fonts loaded via `@import`:

    if (chrome_available()) {
      svg_to_pdf_chrome(card, "my_card.pdf")
    }

PDF is also available from the knitr helper:

    # Saves card.pdf using Chrome when available, else rsvg
    save_card_for_knitr(card, format = "pdf")

## Multiple formats

Export to multiple formats at once:

    # Export to SVG, PNG and (vector) PDF
    svg_to_formats(
      card,
      output_base = "exports/my_card",  # Without extension
      formats = c("svg", "png", "pdf"),
      dpi = 300
    )
    # Creates: exports/my_card.svg, exports/my_card.png, exports/my_card.pdf

## Batch processing

Convert multiple cards efficiently:

    # Create multiple cards
    cards <- list(
      svg_card(title = "Card 1", badges_data = list(), fields = list()),
      svg_card(title = "Card 2", badges_data = list(), fields = list()),
      svg_card(title = "Card 3", badges_data = list(), fields = list())
    )

    # Batch convert to PNG
    batch_svg_to_png(
      svg_list = cards,
      output_dir = "output/cards",
      prefix = "card",
      dpi = 300,
      background = "white"
    )
    # Creates: output/cards/card_001.png, card_002.png, card_003.png

## Displaying in R Markdown / Quarto

### Choosing the rendering engine

All knitr functions support an `engine` parameter:

- `"auto"` (default): Uses Chrome if available, otherwise rsvg
- `"chrome"`: Forces Chrome (errors if unavailable)
- `"rsvg"`: Forces rsvg/magick

### Inline SVG display

    # Display card directly in document (HTML only)
    include_card(card)

    # With custom width
    include_card(card, width = "80%")

### PNG display (better compatibility)

    # Display as PNG with auto engine selection
    include_card_png(card, dpi = 150)

    # Force Chrome for best font rendering
    include_card_png(card, dpi = 300, engine = "chrome")

    # Force rsvg (faster, no Chrome dependency)
    include_card_png(card, dpi = 300, engine = "rsvg")

### Save for knitr

    # Save and get path for knitr::include_graphics
    path <- save_card_for_knitr(
      card,
      filename = "my_card",
      format = "png",
      dpi = 300,
      engine = "chrome"  # or "auto", "rsvg"
    )
    knitr::include_graphics(path)

### Custom knitr engine

    # Register the cardargus engine
    register_cardargus_knitr()

    # Then in a chunk with engine='cardargus':
    # ```{cardargus}
    # svg_card(title = "Dynamic Card", ...)
    # ```

## Integration with grid/ggplot2

Convert cards to grobs for use with grid graphics:

    library(grid)

    # Convert card to grob (auto-selects best engine)
    grob <- card_to_grob(card, dpi = 150)

    # Force Chrome rendering
    grob <- card_to_grob(card, dpi = 150, engine = "chrome")

    # Draw in a grid viewport
    grid.newpage()
    grid.draw(grob)

## Quality settings

### DPI recommendations

Use Case | DPI | Notes
--- | --- | ---
Screen/web | 72-96 | Smaller file size
Standard print | 150 | Good balance
High-quality print | 300 | Publication quality
Large format | 300+ | Posters, banners

### DPI and Chrome scaling

Chrome uses 96 DPI as its base resolution. When you set `dpi = 300`, cardargus calculates a scale factor:

    scale = dpi / 96 = 300 / 96 ≈ 3.125x

This means a 400×300 SVG becomes a 1250×938 PNG at 300 DPI.

### File size considerations

    # Smaller file (lower quality)
    svg_to_png_chrome(card, "card_web.png", dpi = 96)

    # Medium file (balanced)
    svg_to_png_chrome(card, "card_standard.png", dpi = 150)

    # Larger file (high quality)
    svg_to_png_chrome(card, "card_print.png", dpi = 300)

## Comparing engines

    # Same card, different engines
    svg_to_png(card, "card_rsvg.png", dpi = 300)
    svg_to_png_chrome(card, "card_chrome.png", dpi = 300)

    # Chrome generally produces better results for:
    # - Google Fonts and custom web fonts
    # - Complex CSS styling
    # - Font weights and variants

## Error handling

    # Safe conversion with fallback
    convert_card <- function(card, output_path, dpi = 300) {
      if (chrome_available()) {
        svg_to_png_chrome(card, output_path, dpi = dpi)
      } else {
        message("Chrome not available, using rsvg")
        svg_to_png(card, output_path, dpi = dpi)
      }
    }

    # With explicit error handling
    tryCatch({
      svg_to_png_chrome(card, "output.png", dpi = 300)
      message("Conversion successful!")
    }, error = function(e) {
      message("Chrome conversion failed: ", e$message)
      message("Falling back to rsvg...")
      svg_to_png(card, "output.png", dpi = 300)
    })

## Troubleshooting

### Fonts not rendering correctly with rsvg

This is expected behavior. librsvg cannot:

- Load fonts via `@import url(...)`
- Make HTTP requests for web fonts

Solution: Use `svg_to_png_chrome()` or ensure fonts are embedded with `save_svg()`.

### Chrome not found

    # Check Chrome availability
    chrome_available()

    # Option 1: Download Chrome for Testing automatically
    ensure_chrome(download = TRUE)

    # Option 2: Set path to existing Chrome manually
    Sys.setenv(CHROMOTE_CHROME = "/path/to/chrome")

    # Option 3: Find where Chrome is installed
    find_chrome_path()

### Slow Chrome conversion

Chrome has startup overhead. For batch processing, consider:

    # For many cards, rsvg may be faster if fonts are embedded
    svg_to_png(card, "output.png", dpi = 300)

    # Or accept the Chrome overhead for perfect rendering
    svg_to_png_chrome(card, "output.png", dpi = 300)

### Timeout errors

    # Increase timeout for complex SVGs
    svg_to_png_chrome(card, "output.png", timeout = 60)  # 60 seconds