Jelajahi Sumber

Added support for scaling images into a pixmap of a specified size.

Brucey 1 tahun lalu
induk
melakukan
c0dee32279
5 mengubah file dengan 153 tambahan dan 12 penghapusan
  1. 1 1
      svg.mod/common.bmx
  2. 45 0
      svg.mod/examples/example_02.bmx
  3. 17 0
      svg.mod/examples/planet.svg
  4. 1 1
      svg.mod/glue.c
  5. 89 10
      svg.mod/svg.bmx

+ 1 - 1
svg.mod/common.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2022-2023 Bruce A Henderson
+' Copyright (c) 2022-2024 Bruce A Henderson
 ' 
 ' 
 ' This software is provided 'as-is', without any express or implied
 ' This software is provided 'as-is', without any express or implied
 ' warranty. In no event will the authors be held liable for any damages
 ' warranty. In no event will the authors be held liable for any damages

+ 45 - 0
svg.mod/examples/example_02.bmx

@@ -0,0 +1,45 @@
+SuperStrict
+
+Framework SDL.SDLRenderMax2D
+Import Image.SVG
+
+Local w:Int = DesktopWidth() * .75
+Local h:Int = DeskTopHeight() * .75
+
+Graphics w, h, 0
+
+AutoMidHandle(True)
+
+Local svg:TSvgImage = TSvgImage.LoadImage("planet.svg")
+
+Local pix:TPixmap = svg.FitPixmap(DesktopWidth(), DesktopHeight())
+
+Local img:TImage = LoadImage(pix)
+
+
+If Not img Then
+	Throw "Failed to load image"
+End If
+
+Local image:Int
+
+Local scale:Float = 0.5
+
+While Not KeyDown(Key_ESCAPE)
+
+	Cls
+
+	If KeyDown(Key_UP) Then
+		scale = Min(1, scale + 0.01)
+	End If
+
+	If KeyDown(Key_DOWN) Then
+		scale = Max(0.1, scale - 0.01)
+	End If
+
+	SetScale scale, scale
+	DrawImage img, w / 2, h / 2
+
+	Flip
+
+Wend

+ 17 - 0
svg.mod/examples/planet.svg

@@ -0,0 +1,17 @@
+<svg width="200" height="200" xmlns="http://www.w3.org/2000/svg">
+  <!-- Background -->
+  <rect width="100%" height="100%" fill="black"/>
+  
+  <!-- Saturn's Rings -->
+  <ellipse cx="100" cy="100" rx="80" ry="30" fill="none" stroke="lightgrey" stroke-width="15"/>
+  <ellipse cx="100" cy="100" rx="80" ry="30" fill="none" stroke="darkgrey" stroke-width="5"/>
+  
+  <!-- Saturn's Body -->
+  <circle cx="100" cy="100" r="50" fill="gold" />
+
+  <!-- Ring Highlight (to give depth) -->
+  <ellipse cx="100" cy="100" rx="80" ry="30" fill="none" stroke="white" stroke-width="2" opacity="0.5"/>
+
+  <!-- Saturn's Shadow on Rings -->
+  <ellipse cx="100" cy="120" rx="60" ry="20" fill="black" opacity="0.2"/>
+</svg>

+ 1 - 1
svg.mod/glue.c

@@ -1,5 +1,5 @@
 /*
 /*
-  Copyright (c) 2022-2023 Bruce A Henderson
+  Copyright (c) 2022-2024 Bruce A Henderson
   
   
   This software is provided 'as-is', without any express or implied
   This software is provided 'as-is', without any express or implied
   warranty. In no event will the authors be held liable for any damages
   warranty. In no event will the authors be held liable for any damages

+ 89 - 10
svg.mod/svg.bmx

@@ -1,4 +1,4 @@
-' Copyright (c) 2022-2023 Bruce A Henderson
+' Copyright (c) 2022-2024 Bruce A Henderson
 ' 
 ' 
 ' This software is provided 'as-is', without any express or implied
 ' This software is provided 'as-is', without any express or implied
 ' warranty. In no event will the authors be held liable for any damages
 ' warranty. In no event will the authors be held liable for any damages
@@ -25,11 +25,13 @@ The SVG loader module provides the ability to load SVG format #pixmaps.
 End Rem
 End Rem
 Module Image.SVG
 Module Image.SVG
 
 
-ModuleInfo "Version: 1.01"
+ModuleInfo "Version: 1.02"
 ModuleInfo "Author: 2013-14 Mikko Mononen"
 ModuleInfo "Author: 2013-14 Mikko Mononen"
 ModuleInfo "License: ZLib/PNG License"
 ModuleInfo "License: ZLib/PNG License"
 ModuleInfo "Credit: Adapted for BlitzMax by Bruce A Henderson"
 ModuleInfo "Credit: Adapted for BlitzMax by Bruce A Henderson"
 
 
+ModuleInfo "History: 1.02"
+ModuleInfo "History: Added support for scaling images into a pixmap of a specified size."
 ModuleInfo "History: 1.01"
 ModuleInfo "History: 1.01"
 ModuleInfo "History: Update to nanosvg 706eb06"
 ModuleInfo "History: Update to nanosvg 706eb06"
 ModuleInfo "History: 1.00"
 ModuleInfo "History: 1.00"
@@ -39,6 +41,9 @@ Import BRL.Pixmap
 
 
 Import "common.bmx"
 Import "common.bmx"
 
 
+Rem
+bbdoc: An SVG image.
+End Rem
 Type TSvgImage
 Type TSvgImage
 
 
 	Field svgImage:SNSVGimage Ptr
 	Field svgImage:SNSVGimage Ptr
@@ -54,9 +59,6 @@ Type TSvgImage
 		Free()
 		Free()
 	End Method
 	End Method
 
 
-	Rem
-	bbdoc: 
-	End Rem
 	Method Load:TPixmap(stream:TStream, units:String, dpi:Float)
 	Method Load:TPixmap(stream:TStream, units:String, dpi:Float)
 		Local data:Byte[] = LoadByteArray( stream )
 		Local data:Byte[] = LoadByteArray( stream )
 		Local u:Byte Ptr = units.ToCString()
 		Local u:Byte Ptr = units.ToCString()
@@ -67,15 +69,92 @@ Type TSvgImage
 			Return Null
 			Return Null
 		End If
 		End If
 
 
-		Local pix:TPixmap = CreatePixmap( Int(svgImage.width), Int(svgImage.height), PF_RGBA8888, 4 )
+		Return GetPixmap(Int(svgImage.width), Int(svgImage.height))
+	End Method
 
 
-		Local raster:Byte Ptr = nsvgCreateRasterizer()
+	Rem
+	bbdoc: Loads the SVG image from the specified object.
+	about: The units and DPI are used to determine the size of the image.
+	End Rem
+	Function LoadImage:TSvgImage(obj:Object, units:String = "px", dpi:Float = 96)
+		Local image:TSvgImage = New TSvgImage()
 
 
-		nsvgRasterize(raster, svgImage, 0, 0, 1, pix.pixels, pix.width, pix.height, pix.pitch);
+		Local data:Byte[] = LoadByteArray( obj )
+		Local u:Byte Ptr = units.ToCString()
+		image.svgImage = nsvgParse(data, u, dpi)
+		MemFree(u)
 
 
-		nsvgDeleteRasterizer(raster)
+		Return image
+	End Function
 
 
-		Return pix
+	Rem
+	bbdoc: Returns the dimensions of the SVG image.
+	about: The width and height are in the units specified when the SVG image was loaded.
+	End Rem
+	Method Dimensions(width:Float Var, height:Float Var)
+		If svgImage Then
+			width = svgImage.width
+			height = svgImage.height
+		End If
+	End Method
+
+	Rem
+	bbdoc: Returns the width of the SVG image.
+	about: The width is in the units specified when the SVG image was loaded.
+	End Rem
+	Method Width:Float()
+		If svgImage Then
+			Return svgImage.width
+		End If
+		Return 0
+	End Method
+
+	Rem
+	bbdoc: Returns the height of the SVG image.
+	about: The height is in the units specified when the SVG image was loaded.
+	End Rem
+	Method Height:Float()
+		If svgImage Then
+			Return svgImage.height
+		End If
+		Return 0
+	End Method
+
+	Rem
+	bbdoc: Gets a rasterized representation of the SVG image of the specified size and scale.
+	about: A scale of 1 will render the image at the original size - which can be determined by calling the #Width, #Height or #Dimensions methods.
+	End Rem
+	Method GetPixmap:TPixmap(width:Int, height:Int, scale:Float = 1.0)
+		If svgImage Then
+			Local pix:TPixmap = CreatePixmap( width, height, PF_RGBA8888, 4 )
+
+			Local raster:Byte Ptr = nsvgCreateRasterizer()
+
+			nsvgRasterize(raster, svgImage, 0, 0, scale, pix.pixels, pix.width, pix.height, pix.pitch);
+
+			nsvgDeleteRasterizer(raster)
+
+			Return pix
+		End If
+	End Method
+
+	Rem
+	bbdoc: Gets a rasterized representation of the SVG image that fits within the specified maximum width and height.
+	about: The aspect ratio of the image is maintained.
+	If the height is not specified, it will be the same as the width.
+	End Rem
+	Method FitPixmap:TPixmap(maxWidth:Int, maxHeight:Int = 0)
+		Local width:Float
+		Local height:Float
+		Dimensions(width, height)
+
+		If maxHeight = 0 Then
+			maxHeight = maxWidth
+		End If
+
+		Local ratio:Float = Min(maxWidth / width, maxHeight / height)
+
+		Return GetPixmap(Int(width * ratio), Int(height * ratio), ratio)
 	End Method
 	End Method
 
 
 End Type
 End Type