Save SVG

Partagez votre expérience de PureBasic avec les autres utilisateurs.
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Save SVG

Message par blendman »

salut

j'ai trouvé des codes pour ouvrir un SVGavec purebasic et l'afficher avec la vectorlib, mais je n'ai pas trouvé pour enregister une svg, donc, j'ai commencé une procédure pour ça.

ça ne couvre pas toutes les possibilités du svg, car il y a trop de trucs ^^. Mais on a déjà les principales fonctions de la vectorlib :
- shape : box, circle, ellipse, line, curve, text
- Paint : fill, stroke (not dash or point for the moment)
- color + alpha (fill and stroke)
- Stroke flag : #PB_Path_RoundEnd, #PB_Path_SquareEnd, #PB_Path_RoundCorner

On peut déjà faire pas mal de choses rien qu'avec ça en fait :).

Voici le code, dès que j'aurais un peu de temps, j'essaierai d'ajouter les dégradés et d'autres bricoles.
Je vais intégrer cette fonction dans mon application open 2D vectordrawing "Cartoon".

A+

Code : Tout sélectionner

; Save SVG from vectorlib
; blendman 2021

Enumeration 
  ; shape typ
  #ShapeTypBox = 0
  #ShapeTypCircle
  #ShapeTypLine
  #ShapeTypCurve
  #ShapeTypEllipse
  #ShapeTypText
  ; stroketyp
  #StrokeTypFill = 0
  #StrokeTypStroke
  #StrokeTypDash
  #StrokeTypPoint
EndEnumeration

Structure sShape
  Startx.w
  Starty.w
  x.w
  y.w
  w.w
  h.w
  text$
  ; for curve
  x1.w
  y1.w
  x2.w
  y2.w
EndStructure

Structure sSVG_line
  Segment$ ; infos about the shape 
  shapetyp.a ; 0 = rect,1=circle,2=line,3=curve
  shape.sShape
  Strokecolor.i
  strokesize.w
  strokeColorTyp.a ; 0=Color, 1 = gradient linear, 2= gradient circular, 3= texture
  strokeTyp.a ; 0=fill, 1=stroke, 2= dash, 3=point
  strokeflag.a
  strokeAlpha.a
EndStructure
Global NewList SVGLine.sSvg_Line()

Procedure VD_AddShape(typ.a,startx.d,starty.d,x.d,y.d,w.d,h.d,color,stroketyp.a,size.w,
                      alpha.a=255,txt$="",strokeflag=#PB_Path_RoundEnd,x1=0,y1=0,x2=0,y2=0)
  
  ;MovePathCursor(x, y)
  
  Select typ
      
    Case #ShapeTypBox
      AddPathBox(x,y,w,h)
      
    Case #ShapeTypCircle 
      AddPathCircle(x,y,w)
      
    Case #ShapeTypEllipse 
      AddPathEllipse(x,y,w,h)
      
    Case #ShapeTypLine
      MovePathCursor(startx, starty)
      AddPathLine(x,y)
      
    Case #ShapeTypCurve
       MovePathCursor(startx,starty)
       AddPathCurve(x,y,x1,y1,x2,y2)
       
     Case #ShapeTypText
       VectorFont(FontID(0),size)
       VectorSourceColor(RGBA(Red(color),Green(color),Blue(color), alpha))
       MovePathCursor(startx,starty)
       DrawVectorText(txt$)
       
   EndSelect
   
   If typ <> #ShapeTypText
     VectorSourceColor(RGBA(Red(color),Green(color),Blue(color), alpha))
     If stroketyp = #StrokeTypFill
       FillPath()
     ElseIf stroketyp = #StrokeTypStroke
       StrokePath(size, strokeflag)
     EndIf
   EndIf

  
  ; then save the shape
  AddElement(SVGLine())
  SVGLine()\Segment$ = PathSegments()
  SVGLine()\shapetyp = typ ; ellipse
  SVGLine()\Strokecolor = color
  SVGLine()\strokesize = size
  SVGLine()\strokeTyp = stroketyp ; stroke
  SVGLine()\strokeColorTyp = 0 ; for the moment only color (not gradient...)
  SVGLine()\strokeflag = strokeflag
  SVGLine()\strokeAlpha = alpha
  SVGLine()\shape\startx = startx
  SVGLine()\shape\starty = starty
  SVGLine()\shape\x = x
  SVGLine()\shape\y = y
  SVGLine()\shape\w = w
  SVGLine()\shape\h = h
  SVGLine()\shape\text$ = txt$
  ; for curve
  SVGLine()\shape\x1 = x1
  SVGLine()\shape\y1 = y1
  SVGLine()\shape\x2 = x2
  SVGLine()\shape\y2 = y2
  
EndProcedure

Procedure Save_SVG(Title$="",desc$="",w=1200,h=400,zoom=100)
  
  ;date$ = FormatDate("%yyyy%mm%dd%hh%ii%ss", Date())
  date$ = FormatDate("%yyyy%mm%dd", Date())
  z.d = zoom*0.01
  file$ = "TestSVG"+date$+".svg"
  
  If CreateFile(0,GetCurrentDirectory()+file$)
    
    d$ = Chr(34)
    
    ; save infos for svg
    WriteStringN(0, "<?xml version="+d$+"1.0"+d$+" encoding="+d$+"utf-8"+d$+" ?>")
    WriteStringN(0, "<!-- Created with Purebasic -->")
    WriteStringN(0, "")
    WriteStringN(0, "<svg xmlns="+d$+"http://www.w3.org/2000/svg"+d$+" version="+d$+"1.1"+d$+" width="+d$+Str(w*z)+d$+" height="+d$+Str(h*z)+d$+">")
    WriteStringN(0, "  <title>"+Title$+"</title>")
    WriteStringN(0, "  <desc>"+desc$+"</desc>")
     
    ; Here, save the informations about shape, color...
    ForEach SVGLine()
      With SVGLine()
        text$= "  "
        
        ; color
        color$ = d$+"rgb("+Str(Red(\Strokecolor))+","+Str(Green(\Strokecolor))+","+Str(Blue(\Strokecolor))+")"+d$
        ; fill-opacity="0.5" stroke-opacity="0.8"
            stroketyp$ = "fill="+color$
            If \strokeTyp = #StrokeTypStroke And \shapetyp <> #ShapeTypText
              stroketyp$ = "fill="+d$+"none"+d$+" stroke="+color$+" stroke-width="+d$+Str(\strokesize)+d$+" stroke-opacity="+d$+StrD(\strokeAlpha/255,2)+d$
              If \strokeflag =#PB_Path_RoundEnd Or \strokeflag = #PB_Path_RoundCorner
                stroketyp$ + " stroke-linecap="+d$+ "round"+d$ + " stroke-linejoin="+d$+ "round"+d$
              ElseIf \strokeflag =#PB_Path_SquareEnd
                stroketyp$ + " stroke-linecap="+d$+ "square"+d$+ " stroke-linejoin="+d$+ "square"+d$
              EndIf
            ElseIf \strokeTyp = #StrokeTypFill
              stroketyp$ +" fill-opacity="+d$+StrD(\strokeAlpha/255,2)+d$
              If \shapetyp <> #ShapeTypText
                If \strokeflag =#PB_Path_RoundEnd      
                  stroketyp$ + " stroke-linejoin="+d$+ "round"+d$
                ElseIf \strokeflag =#PB_Path_SquareEnd
                  stroketyp$ + " stroke-linejoin="+d$+ "square"+d$
                EndIf
              EndIf
            EndIf
            
        
            Select \shapetyp
              Case #ShapeTypBox
                text$ +"<rect x="+d$+Str(\shape\x)+d$+" y="+d$+Str(\shape\y)+d$+" width="+d$+Str(\shape\w)+d$+" height="+d$+Str(\shape\h)+d$+
                       " "+stroketyp$+" />"
                WriteStringN(0, text$)
                
              Case #ShapeTypCircle
                text$ +"<circle cx="+d$+Str(\shape\x)+d$+" cy="+d$+Str(\shape\y)+d$+" r="+d$+Str(\shape\w)+d$+" "+stroketyp$+" />"
                WriteStringN(0, text$)
                
              Case #ShapeTypLine
                text$ +"<line x1="+d$+Str(\shape\startx)+d$+" x2="+d$+Str(\shape\x)+d$+" y1="+d$+Str(\shape\Starty)+d$+" y2="+d$+Str(\shape\y)+
                       d$+" "+stroketyp$+" />"
                 WriteStringN(0, text$)
                 
              Case #ShapeTypCurve
                ; <path d="M 10 10 C 20 20, 40 20, 50 10"/>
                text$ +"<path d="+d$+"M "+Str(\shape\startx)+" "+Str(\shape\Starty)+" C "+Str(\shape\x)+" "+Str(\shape\y)+" "+
                       Str(\shape\x1)+" "+Str(\shape\y1)+" "+Str(\shape\x2)+" "+Str(\shape\y2)+d$
                text$+" "+stroketyp$+" />"
                WriteStringN(0, text$)
                
              Case #ShapeTypText
                ; <text x="10" y="10">Hello World!</text>
                text$ +"<text dominant-baseline="+d$+"hanging"+d$+" x="+d$+Str(\shape\startx)+d$+" y="+d$+Str(\shape\starty)+d$+" font-size="+d$+Str(\strokesize)+d$+" "+stroketyp$+" >"+\shape\text$+"</text>"
                WriteStringN(0, text$)
               
              Case #ShapeTypEllipse
                ; text$ ="  <g transform="+d$+"translate("+Str(\shape\x)+" "+Str(\shape\y)+")"+d$+">"
                ; WriteStringN(0, text$)
                text$ +"<ellipse cx="+d$+Str(\shape\x)+d$+" cy="+d$+Str(\shape\y)+d$+" rx="+d$+Str(\shape\w)+d$+" ry="+d$+Str(\shape\h)+d$+" "+stroketyp$+"  />"
                WriteStringN(0, text$)
                ; WriteStringN(0, "   </g>") 
        EndSelect
      EndWith
    Next
      
    WriteStringN(0, "</svg>")
    CloseFile(0)
  EndIf
  
  ; RunProgram(file$)
  
EndProcedure

winw = 1000
winh = 600
If OpenWindow(0, 0, 0, winw, winh, "SaveSVG", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
    CanvasGadget(0, 0, 0, winw, winh)
      LoadFont(0, "Times new roman", 20)
      
    If StartVectorDrawing(CanvasVectorOutput(0))
      
      ; ellipse
      VD_AddShape(#ShapeTypEllipse,0,0,112,116,34,45,RGB(255, 0, 0),#StrokeTypStroke,10,255)
      ; box with rounded stroke
      VD_AddShape(#ShapeTypBox,0,0,50,50,200,100,RGB(210,150,130),#StrokeTypStroke,40,220,"",#PB_Path_RoundCorner)
      VD_AddShape(#ShapeTypBox,0,0,70,150,260,120,RGB(20,240,230),#StrokeTypFill,10,90,"",#PB_Path_SquareEnd)
      ; circle
      VD_AddShape(#ShapeTypCircle,0,0,80,60,50,100,RGB(0,150,130),#StrokeTypStroke,30,120)
      ; Line
      VD_AddShape(#ShapeTypLine,10,30,80,60,0,0,RGB(0,0,130),#StrokeTypStroke,15,120)
      VD_AddShape(#ShapeTypCurve,510,130,580,160,0,0,RGB(0,220,130),#StrokeTypStroke,25,190,"",#PB_Path_RoundEnd,710,170,680,50)
      
      ; VD_AddShape(#ShapeTypBox,0,0,50,100,30,30,RGB(160,160,160),#StrokeTypFill,40,255)
      
      ; text should be improved (there is an offset in y in browser)
      VD_AddShape(#ShapeTypText,50,100,0,0,0,0,RGB(0,20,10),#StrokeTypFill,60,190,"Purebasic SVG !")
      
      
      StopVectorDrawing()
    EndIf
    
    Save_SVG("SVG purebasic", "a SVG example made with purebasic" )
    
    Repeat
      Event = WaitWindowEvent()
    Until Event = #PB_Event_CloseWindow
  EndIf
Avatar de l’utilisateur
Thyphoon
Messages : 2697
Inscription : mer. 25/août/2004 6:31
Localisation : Eragny
Contact :

Re: Save SVG

Message par Thyphoon »

Super travail blendman. Et merci de ton partage :mrgreen:
Avatar de l’utilisateur
venom
Messages : 3072
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: Save SVG

Message par venom »

Bonsoir,

Je vois que ça boss dur par ici. Bravo pour les avancées blendman. 8)






@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
G-Rom
Messages : 3627
Inscription : dim. 10/janv./2010 5:29

Re: Save SVG

Message par G-Rom »

cc blendman , voici une méthode pour sauvegardé et lire des données structurés très facilement en mode "binaire" ( ne marche pas avec des pointeurs , inclus les string )

Code : Tout sélectionner

Structure mes_donnees
  taille.l
  largeur.f
  couleur.l
  quelque_chose.w
EndStructure

Fichier.mes_donnees
Fichier\taille = 512
Fichier\largeur = 3.1415
Fichier\couleur = RGB(255,128,64)
Fichier\quelque_chose = $FF

; ECRITURE
;
If CreateFile(0,"test.bin")
  WriteData(0,@Fichier,SizeOf(mes_donnees))
  CloseFile(0)
EndIf 


; LECTURE
;
If ReadFile(0,"test.bin")
  lecture.mes_donnees
  ReadData(0,@lecture,SizeOf(mes_donnees))
  CloseFile(0)
  
  Debug lecture\taille
  Debug lecture\largeur
  Debug lecture\couleur
  Debug lecture\quelque_chose
  
  DeleteFile("test.bin")
EndIf
Avatar de l’utilisateur
blendman
Messages : 2017
Inscription : sam. 19/févr./2011 12:46

Re: Save SVG

Message par blendman »

Thyphoon a écrit : sam. 28/août/2021 13:27 Super travail blendman. Et merci de ton partage :mrgreen:
De rien, je trouve que c'est important de partager des fonctions qui nous manquent comme elles-ci.
venom a écrit : sam. 28/août/2021 20:44 Je vois que ça boss dur par ici. Bravo pour les avancées blendman. 8)
merci ;)
voici une méthode pour sauvegardé et lire des données structurés très facilement en mode "binaire" ( ne marche pas avec des pointeurs , inclus les string )
Merci, je ne connaissais pas du tout cette technique, c'est top.

Il y a moyen de sauver une structure simplement comme ton exemple (par exemple, sauvegarder Fichier.mes_donnees), mais sous forme texte lisible ?
J'ai trouvé un exemple en JSon, mais je me demander s'il existait une autre technique pour sauvegarder facilement les données d'un array ou une variable comme Ficher.mes_donnees
Avatar de l’utilisateur
ChrisR
Messages : 222
Inscription : sam. 14/févr./2015 16:20

Re: Save SVG

Message par ChrisR »

J'ai jamais jouer avec le format SVG mais ton super code donne envie d'aller plus loin.

Image

Bravo et merci pour le partage :)
Daorven
Messages : 1
Inscription : jeu. 04/nov./2021 14:31

Re: Save SVG

Message par Daorven »

Bonjour,

Voici un test de rendu avec 'VectorDrawing' en 'Path' uniquement, ne pas tenir compte du code non optimisé.
Image
̶S̶V̶G̶p̶a̶t̶h̶T̶e̶s̶t̶D̶r̶a̶w̶.̶z̶i̶p̶

[Modération by falsam]
Bienvenue. Premier message, premier fichier à télécharger. Ca peut faire peur :mrgreen:

■ Voir le code (Trop long pour être afficher dans le commentaire)
SVGpathTestDraw.pb

■ Télécharger le zip.
SVGpathTestDraw.zip

■ Test antivirus.
https://www.virustotal.com/gui/file/828 ... ?nocache=1
Répondre