Page 2 of 3

Re: UseSVGImageDecoder/Encoder

Posted: Fri Sep 26, 2025 12:39 pm
by acreis
Hi Idle,

2.813 kb

Re: UseSVGImageDecoder/Encoder

Posted: Fri Sep 26, 2025 10:23 pm
by idle
That's quite large I'm aiming for under 200kb though that won't happen if I need freetype.
edit
I'm trying to fix the SVGmodule. just need to work out how to transform the X and Y

Re: UseSVGImageDecoder/Encoder

Posted: Sat Sep 27, 2025 10:34 pm
by idle
I fixed up the SVGmodule
viewtopic.php?p=645872#p645872

Re: UseSVGImageDecoder/Encoder

Posted: Mon Sep 29, 2025 12:58 pm
by acreis
That's great idle, thank you!

But rendering some files results only black shape o inteded drawing.

Same occurs with nanosvg.

I managed to compile a plutosvg.dll, seems more svgs are rendered right.

Old resvg.dll is very good but have some dependency I don't know so I can't use in another machine.

Thanks a lot, I'll stick to pluto.

Re: UseSVGImageDecoder/Encoder

Posted: Mon Sep 29, 2025 2:34 pm
by punak
I spoke with an AI, and it told me that the most complete and flawless library compatible with PureBasic is Skia, which offers full (100%) support for loading and rendering SVG files.

https://github.com/google/skia

Cpp

Code: Select all

#include "include/core/SkCanvas.h"
#include "include/core/SkSurface.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkData.h"
#include "include/core/SkStream.h"
#include "include/svg/SkSVGDOM.h"

extern "C" __declspec(dllexport) SkSurface* CreateSurface(int width, int height) {
    SkImageInfo info = SkImageInfo::Make(width, height, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    return SkSurface::MakeRaster(info).release();
}

extern "C" __declspec(dllexport) SkSVGDOM* LoadSVG(const char* svgPath) {
    std::ifstream file(svgPath, std::ios::binary);
    if (!file) return nullptr;

    std::string svgData((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
    auto stream = SkMemoryStream::MakeDirect(svgData.data(), svgData.size());
    return SkSVGDOM::MakeFromStream(*stream).release();
}

extern "C" __declspec(dllexport) void RenderSVG(SkSurface* surface, SkSVGDOM* dom) {
    if (!surface || !dom) return;

    SkCanvas* canvas = surface->getCanvas();
    canvas->clear(SK_ColorWHITE);
    dom->render(canvas);
}

extern "C" __declspec(dllexport) const void* GetPixels(SkSurface* surface) {
    if (!surface) return nullptr;

    SkPixmap pixmap;
    if (surface->peekPixels(&pixmap)) {
        return pixmap.addr();
    }
    return nullptr;
}
Pb

Code: Select all

Import "SkiaWrapper.dll"
  CreateSurface(width.l, height.l)
  LoadSVG(path.p-ascii)
  RenderSVG(surface.l, dom.l)
  GetPixels(surface.l)
EndImport

Procedure DrawSVGOnCanvas(canvasID, svgPath$)
  width = 800
  height = 600

  surface = CreateSurface(width, height)
  dom = LoadSVG(svgPath$)
  RenderSVG(surface, dom)

  pixels = GetPixels(surface)
  If pixels
    If CreateImage(0, width, height, 32)
      StartDrawing(ImageOutput(0))
      CopyMemory(pixels, DrawingBuffer(), width * height * 4)
      StopDrawing()
      If OpenWindow(0, 0, 0, width, height, "SVG Viewer", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
        CanvasGadget(0, 0, 0, width, height)
        Repeat
          Event = WaitWindowEvent()
          If Event = #PB_Event_Gadget And EventGadget() = 0
            StartDrawing(CanvasOutput(0))
            DrawImage(ImageID(0), 0, 0)
            StopDrawing()
          EndIf
        Until Event = #PB_Event_CloseWindow
      EndIf
    EndIf
  EndIf
EndProcedure

Re: UseSVGImageDecoder/Encoder

Posted: Mon Sep 29, 2025 8:49 pm
by idle
acreis wrote: Mon Sep 29, 2025 12:58 pm That's great idle, thank you!

But rendering some files results only black shape o inteded drawing.

Same occurs with nanosvg.

I managed to compile a plutosvg.dll, seems more svgs are rendered right.

Old resvg.dll is very good but have some dependency I don't know so I can't use in another machine.

Thanks a lot, I'll stick to pluto.
Can you send me a link for a failed render either here or in private.

I've fixed a number of bugs in the pb module and am slowly transforming it with the intent to add more support and also adapt it to use display lists which will vastly improve rendering performance when it comes to redraw, resizing, animation and effects from timer, hover, clicks and callbacks. Rather than parsing the xml file each time it will foreach the display list which call the vector functions with updated parameters.

Ive looked at sika a while ago, might be good 👍

Re: UseSVGImageDecoder/Encoder

Posted: Mon Sep 29, 2025 9:40 pm
by acreis
Seems great................but where can I find the dll?

Re: UseSVGImageDecoder/Encoder

Posted: Mon Sep 29, 2025 10:26 pm
by idle
acreis wrote: Mon Sep 29, 2025 9:40 pm Seems great................but where can I find the dll?
it will all be native just using the pb vector lib. I'm still working through it and addressing the issues then I'll look at display lists
and then I can look at adding animations effects and events.

I looked at adding text support to PlutoSVG but it's also got the same problems as Thorsten's module as in to resize an svg it has to reparse the XML which isn't the best option. It literally tears it down and redoes it when it's not necessary but I guess when your source is from js based stuff what do you expect. There are some things I can condone but Shlemiel the painter’s algorithm isn't one of them.
No. This code uses the Shlemiel the painter’s algorithm. Who is Shlemiel? He’s the guy in this joke:

Shlemiel gets a job as a street painter, painting the dotted lines down the middle of the road. On the first day he takes a can of paint out to the road and finishes 300 yards of the road. “That’s pretty good!” says his boss, “you’re a fast worker!” and pays him a kopeck.

The next day Shlemiel only gets 150 yards done. “Well, that’s not nearly as good as yesterday, but you’re still a fast worker. 150 yards is respectable,” and pays him a kopeck.

The next day Shlemiel paints 30 yards of the road. “Only 30!” shouts his boss. “That’s unacceptable! On the first day you did ten times that much work! What’s going on?”

“I can’t help it,” says Shlemiel. “Every day I get farther and farther away from the paint can!”
https://www.joelonsoftware.com/2001/12/ ... to-basics/

So a cached rendering drawn when no change and a display list when there is a change

Re: UseSVGImageDecoder/Encoder

Posted: Tue Sep 30, 2025 2:23 am
by punak
❌ SVG Features That Are Difficult or Impossible to Implement with pb.

| SVG Feature | Status in VectorDrawing | Notes |
|-------------------------------------|------------------------------------------|-------|
| Filters (blur, drop shadow, feGaussianBlur) | ❌ Not supported | No API for image filters or effects |
| Animations (<animate>, <animateTransform>) | ❌ Impossible | VectorDrawing is designed for static rendering only |
| Custom or bitmap fonts | ❌ Limited | Only vector fonts are allowed; no font registration |
| Complex masks and clip-paths | ⚠️ Limited | ClipPath exists, but lacks full SVG complexity |
| Shape blending and blend modes | ❌ Not supported | No API for blend modes or compositing |
| DOM or interactivity | ❌ Impossible | PureBasic is not designed for interactive SVG |
| CSS styling within SVG | ❌ Impossible | No CSS parser or styling engine |

Re: UseSVGImageDecoder/Encoder

Posted: Tue Sep 30, 2025 3:17 am
by idle
punak wrote: Tue Sep 30, 2025 2:23 am ❌ SVG Features That Are Difficult or Impossible to Implement with pb.

| SVG Feature | Status in VectorDrawing | Notes |
|-------------------------------------|------------------------------------------|-------|
| Filters (blur, drop shadow, feGaussianBlur) | ❌ Not supported | No API for image filters or effects |
| Animations (<animate>, <animateTransform>) | ❌ Impossible | VectorDrawing is designed for static rendering only |
| Custom or bitmap fonts | ❌ Limited | Only vector fonts are allowed; no font registration |
| Complex masks and clip-paths | ⚠️ Limited | ClipPath exists, but lacks full SVG complexity |
| Shape blending and blend modes | ❌ Not supported | No API for blend modes or compositing |
| DOM or interactivity | ❌ Impossible | PureBasic is not designed for interactive SVG |
| CSS styling within SVG | ❌ Impossible | No CSS parser or styling engine |
The font's will be TTF only
Animation will be fine once switched to using display lists
masks and clipping, don't know yet
It will have a form of DOM
CSS yes

Re: UseSVGImageDecoder/Encoder

Posted: Tue Sep 30, 2025 6:46 am
by pf shadoko
For bitmap fonts, we can handle that.
Take it from my screen library.
viewtopic.php?t=84206&hilit=shader+sprite

Code: Select all

;============================================================================================ fastfont
Procedure SS_InitFont(num,name.s, height.f,style=0,brush=-1,chars.s="")
  Structure ssc
    sx.l
    sl.l
    cl.l
    co.l
  EndStructure
  
  Structure sscfont
    ns.i
    height.f
    Array c.ssc(255)
  EndStructure
  
  Global ScrennFont.sscfont
  
  Protected i,h,l,c.s,ca,im,bx,by,cx,co,cv,cl:Global nf
  If chars="":For i=32 To 128:chars+Chr(i):Next:EndIf
  
  nf=LoadFont(-1,name,height,style)
  If brush>=0:initIF(brush):bx=ImageWidth(brush):by=ImageHeight((brush)):EndIf
  IM=CreateImage(-1,1,1)
  StartDrawing(ImageOutput(im)):DrawingFont(FontID(nf))
  h=TextHeight(" ")+by
  l=TextWidth(chars)*1.3+Len(chars)*bx:cx=0
  StopDrawing()
  FreeImage(im)
  
  IM=CreateImage(-1,l,h,32,#PB_Image_Transparent):StartDrawing(ImageOutput(im)):DrawingMode(#PB_2DDrawing_AllChannels):Box(0,0,l,h,$00ffffff):StopDrawing()
  StartVectorDrawing(ImageVectorOutput(im)):VectorFont(FontID(nf))
  For i=1 To Len(chars)
    c=Mid(chars,i,1):ca=Asc(c)
    With ScrennFont\c(ca)
      co=VectorTextWidth(c,#PB_VectorText_Visible|#PB_VectorText_Offset):If ca=126:co=0:EndIf
      cv=VectorTextWidth(c,#PB_VectorText_Visible)
      cl=VectorTextWidth(c)
      \sx=cx
      \sl=cv+bx+2
      \cl=cl+bx/2
      \co=co
      ;AddPathBox(\sx,0,\sl,h):VectorSourceColor($8800ff00):FillPath()
      MovePathCursor(cx-co+1,0)
      VectorSourceColor($ffffffff):DrawVectorText(c)
      cx+\sl+1
    EndWith
  Next
  StopVectorDrawing()
  
  ScrennFont\ns=SS_CreateSprite(-1,#SHoverlay,im)
  ScrennFont\height=h
EndProcedure

Procedure SS_DrawText(x,y,t.s,size=-1,color=$ffffffff)
  Protected i,ca,cx,c.ssc,zoom.f
  With ScrennFont
    If size=-1:size=\height:EndIf
    zoom=size/\height
    For i=1 To Len(t)
      c=\c(Asc(Mid(t,i,1)))
      SS_ClipSprite(\ns,c\sx,0,c\sl,\height)
      SS_ZoomSprite(\ns,c\sl*zoom,\height*zoom,#SS_unit_Pixel)
      SS_DisplaySprite(\ns,x+c\co*zoom,y,255,color)
      x+c\cl*zoom
    Next
  EndWith
EndProcedure

Re: UseSVGImageDecoder/Encoder

Posted: Tue Sep 30, 2025 7:42 am
by idle
pf shadoko wrote: Tue Sep 30, 2025 6:46 am For bitmap fonts, we can handle that.
Take it from my screen library.
viewtopic.php?t=84206&hilit=shader+sprite

Code: Select all

;============================================================================================ fastfont
Procedure SS_InitFont(num,name.s, height.f,style=0,brush=-1,chars.s="")
  Structure ssc
    sx.l
    sl.l
    cl.l
    co.l
  EndStructure
  
  Structure sscfont
    ns.i
    height.f
    Array c.ssc(255)
  EndStructure
  
  Global ScrennFont.sscfont
  
  Protected i,h,l,c.s,ca,im,bx,by,cx,co,cv,cl:Global nf
  If chars="":For i=32 To 128:chars+Chr(i):Next:EndIf
  
  nf=LoadFont(-1,name,height,style)
  If brush>=0:initIF(brush):bx=ImageWidth(brush):by=ImageHeight((brush)):EndIf
  IM=CreateImage(-1,1,1)
  StartDrawing(ImageOutput(im)):DrawingFont(FontID(nf))
  h=TextHeight(" ")+by
  l=TextWidth(chars)*1.3+Len(chars)*bx:cx=0
  StopDrawing()
  FreeImage(im)
  
  IM=CreateImage(-1,l,h,32,#PB_Image_Transparent):StartDrawing(ImageOutput(im)):DrawingMode(#PB_2DDrawing_AllChannels):Box(0,0,l,h,$00ffffff):StopDrawing()
  StartVectorDrawing(ImageVectorOutput(im)):VectorFont(FontID(nf))
  For i=1 To Len(chars)
    c=Mid(chars,i,1):ca=Asc(c)
    With ScrennFont\c(ca)
      co=VectorTextWidth(c,#PB_VectorText_Visible|#PB_VectorText_Offset):If ca=126:co=0:EndIf
      cv=VectorTextWidth(c,#PB_VectorText_Visible)
      cl=VectorTextWidth(c)
      \sx=cx
      \sl=cv+bx+2
      \cl=cl+bx/2
      \co=co
      ;AddPathBox(\sx,0,\sl,h):VectorSourceColor($8800ff00):FillPath()
      MovePathCursor(cx-co+1,0)
      VectorSourceColor($ffffffff):DrawVectorText(c)
      cx+\sl+1
    EndWith
  Next
  StopVectorDrawing()
  
  ScrennFont\ns=SS_CreateSprite(-1,#SHoverlay,im)
  ScrennFont\height=h
EndProcedure

Procedure SS_DrawText(x,y,t.s,size=-1,color=$ffffffff)
  Protected i,ca,cx,c.ssc,zoom.f
  With ScrennFont
    If size=-1:size=\height:EndIf
    zoom=size/\height
    For i=1 To Len(t)
      c=\c(Asc(Mid(t,i,1)))
      SS_ClipSprite(\ns,c\sx,0,c\sl,\height)
      SS_ZoomSprite(\ns,c\sl*zoom,\height*zoom,#SS_unit_Pixel)
      SS_DisplaySprite(\ns,x+c\co*zoom,y,255,color)
      x+c\cl*zoom
    Next
  EndWith
EndProcedure
Thanks. I will try adding that.

Re: UseSVGImageDecoder/Encoder

Posted: Tue Sep 30, 2025 8:53 am
by pf shadoko
wait a moment, this not work on vectordrawing
i will adapt this

Re: UseSVGImageDecoder/Encoder

Posted: Tue Sep 30, 2025 10:30 am
by idle
pf shadoko wrote: Tue Sep 30, 2025 8:53 am wait a moment, this not work on vectordrawing
i will adapt this
no rush there's a lot for me to to do in the mean time but yes please if you can adapt it.

Re: UseSVGImageDecoder/Encoder

Posted: Tue Sep 30, 2025 10:52 am
by acreis
Hi idle,

I made a mistake, plutosvg and nanosvg was rendering some svg as a black shadow only. UseSvgImage is fine. Great to be true, I'm sticking to it to render toolbar and menu icons.