Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jul 29, 2025

This PR implements comprehensive SVG image decoding and rendering support in the client/canvas/image_codec module, with optional width and height parameters for flexible scaling, enabling richer image type support and improving canvas flexibility.

Changes Made

Core Implementation

  • Added nanosvg library: Integrated the lightweight, header-only nanosvg library for SVG parsing and rasterization
  • Extended ImageCodec::Decode: Enhanced the existing image decoding pipeline to detect and handle SVG files seamlessly with optional scaling parameters
  • SVG to SkBitmap conversion: Implemented complete SVG parsing and rasterization to SkBitmap, maintaining compatibility with the existing rendering pipeline

SVG Scaling Features

The ImageCodec::Decode method now accepts optional target_width and target_height parameters for SVG images:

  • Both dimensions specified: Scale to exact dimensions
  • Width only (height = -1): Scale width and maintain aspect ratio
  • Height only (width = -1): Scale height and maintain aspect ratio
  • Neither specified (both = -1): Use original SVG dimensions

Smart SVG Detection

The implementation includes intelligent format detection that:

  • Identifies pure SVG files (with or without XML declarations)
  • Correctly rejects HTML documents containing embedded SVG elements
  • Performs case-insensitive detection for robustness
  • Handles SVG files with leading whitespace or formatting variations

Size Constraint Handling

SVG images are subject to the same size constraints as other image formats:

  • Automatically scales down oversized SVGs to the maximum allowed size (1024px)
  • Maintains aspect ratio during scaling
  • Applies the same memory management principles as existing image codecs
  • Target dimensions are also subject to size constraints

Error Handling

Robust error handling for various edge cases:

  • Malformed SVG content
  • Invalid or corrupted data
  • Memory allocation failures
  • Graceful fallback for unsupported SVG features

Example Usage

std::string svg_content = R"(
<svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
  <rect x="10" y="10" width="80" height="80" fill="red"/>
</svg>
)";

std::vector<char> svg_data(svg_content.begin(), svg_content.end());
SkBitmap decoded_bitmap;

// Original size
bool success = ImageCodec::Decode(svg_data, decoded_bitmap, "test.svg");

// Scale to 200x300
bool success = ImageCodec::Decode(svg_data, decoded_bitmap, "test.svg", 200, 300);

// Scale width to 200, maintain aspect ratio
bool success = ImageCodec::Decode(svg_data, decoded_bitmap, "test.svg", 200, -1);

The implementation maintains full backward compatibility and integrates seamlessly with the existing image processing pipeline, requiring no changes to existing calling code.

Fixes #168.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits July 29, 2025 20:32
Co-authored-by: yorkie <1935767+yorkie@users.noreply.github.com>
Co-authored-by: yorkie <1935767+yorkie@users.noreply.github.com>
Copilot AI changed the title [WIP] Add SVG decoding and rendering support Add SVG decoding and rendering support to ImageCodec Jul 29, 2025
Copilot AI requested a review from yorkie July 29, 2025 20:39
Copy link
Collaborator

@yorkie yorkie left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SVG can be scaled to the expected width and height, you need to add optional parameters to the ImageCodec::Decode() as the expected width and height.

Copilot AI and others added 2 commits July 30, 2025 05:13
Copy link
Contributor Author

Copilot AI commented Jul 30, 2025

SVG can be scaled to the expected width and height, you need to add optional parameters to the ImageCodec::Decode() as the expected width and height.

Added optional width and height parameters to ImageCodec::Decode for SVG scaling. The method now supports:

  • Both dimensions: Scale to exact size
  • Width only (height = -1): Scale width, maintain aspect ratio
  • Height only (width = -1): Scale height, maintain aspect ratio
  • Neither specified: Use original SVG dimensions

Maintains full backward compatibility with existing code. Commit f18cd37

…aling

Co-authored-by: yorkie <1935767+yorkie@users.noreply.github.com>
Copilot AI changed the title Add SVG decoding and rendering support to ImageCodec Add SVG decoding and rendering support to ImageCodec with optional scaling Jul 30, 2025
Copilot AI requested a review from yorkie July 30, 2025 05:15
@yorkie yorkie requested a review from Copilot July 31, 2025 05:47

This comment was marked as outdated.

@yorkie yorkie requested a review from Copilot July 31, 2025 06:03
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds comprehensive SVG image decoding and rendering support to the ImageCodec module, enabling web content to display SVG images alongside existing raster formats. The implementation uses the nanosvg library for lightweight SVG parsing and rasterization with optional scaling parameters.

Key changes:

  • Integrates nanosvg library for SVG parsing and rasterization to SkBitmap format
  • Extends ImageCodec::Decode method with optional width/height parameters for SVG scaling
  • Implements intelligent SVG format detection and size constraint handling
  • Updates HTML image element to support dynamic SVG re-rendering based on layout changes

Reviewed Changes

Copilot reviewed 16 out of 18 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
thirdparty/headers/nanosvg/nanosvgrast.h Adds nanosvg rasterization library for SVG to bitmap conversion
src/client/canvas/image_codec.hpp Extends ImageCodec interface with SVG format support and optional scaling parameters
src/client/canvas/image_codec.cpp Implements SVG detection, parsing, and rasterization logic with size constraints
src/client/html/html_image_element.hpp Adds SVG-aware image decoding with layout-based re-rendering capabilities
src/client/html/html_image_element.cpp Implements dynamic SVG decoding based on element size changes
src/client/layout/layout_*.hpp/cpp Updates layout system to notify elements of size changes for SVG re-rendering
tests/client/svg_image_codec_tests.cpp Comprehensive test suite covering SVG decoding scenarios and edge cases
fixtures/html/images.html Demo page showcasing SVG image rendering with dynamic resizing
Comments suppressed due to low confidence (3)

src/client/canvas/image_codec.cpp:65

  • The SkEncodedImageFormat::kJPEGXL enum value may not exist in older versions of Skia. Consider adding version checks or conditional compilation to ensure compatibility.
    case SkEncodedImageFormat::kJPEGXL:

src/client/html/html_image_element.cpp:74

  • The function parameter should use std::shared_ptr<SkBitmap> instead of shared_ptr<SkBitmap> for consistency and clarity, or ensure the appropriate using declaration is present.
    {

tests/client/svg_image_codec_tests.cpp:25

  • The test passes nullptr for the image_format parameter but doesn't verify that the format is correctly detected as SVG. Consider adding a test that captures and validates the detected format.
    bool success = ImageCodec::Decode(svg_data, nullptr, decoded_bitmap, "test.svg");

@yorkie yorkie marked this pull request as ready for review July 31, 2025 06:05
@yorkie yorkie merged commit 247b16e into main Jul 31, 2025
2 checks passed
@yorkie yorkie deleted the copilot/fix-168 branch July 31, 2025 06:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add SVG decoding and rendering support

2 participants