Page 2 of 2 FirstFirst 12
Results 41 to 50 of 50

Thread: VB6 Cairo-Paths and Projections

  1. #41
    PowerPoster Arnoutdv's Avatar
    Join Date
    Oct 2013
    Posts
    6,748

    Re: VB6 Cairo-Paths and Projections

    I'm sorry, but I'm not going to write the code for you.

    Maybe this thread can be of any help to you:
    https://www.vbforums.com/showthread....on-of-an-image

  2. #42
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: VB6 Cairo-Paths and Projections

    I experience something strange: Instead of transforming the image, the image slowly changes its color. It looks like a color animation.
    Does anybody see what I'm doing wrong in "pRotate"?

    Code:
    Option Explicit
    
    Private CC As cCairoContext ' the drawing-context (derived from a Cairo-Surface)
    Private m_img As c32bpp.c32bppDIB
    
    
    
    Public Function CreateDIB32FromSurface(Srf As cCairoSurface) As c32bppDIB
        Set CreateDIB32FromSurface = New c32bppDIB
        CreateDIB32FromSurface.InitializeDIB Srf.Width, Srf.Height
    
        Dim pSrc As Long: pSrc = Srf.DataPtr + (Srf.Height - 1) * Srf.Stride 'init Src-pointer to the last row
        Dim pDst As Long: pDst = CreateDIB32FromSurface.BitsPointer '... and Dst-Pointer to the first row
        'now we have to do Bottom-Up-row-copying from the Source (because c32bppDIB prefers a Bottom-Up memory-layout in its internal allocation)
        Do
            New_c.MemCopy pDst, pSrc, Srf.Stride
            pSrc = pSrc - Srf.Stride: pDst = pDst + Srf.Stride
        Loop Until pSrc < Srf.DataPtr
    End Function
    
    Private Sub Form_Load()
        Set m_img = New c32bpp.c32bppDIB
        m_img.LoadPicture_File App.Path & "\clock.png"
    End Sub
    
    Private Sub Form_Resize()
        Me.Cls
        
        Dim lWidth As Long
        Dim lHeight As Long
        
        If Me.ScaleWidth < Me.ScaleHeight Then
            lWidth = Me.ScaleWidth
            lHeight = Me.ScaleWidth ' Use the width as the height to create a square image
        Else
            lWidth = Me.ScaleHeight
            lHeight = Me.ScaleHeight ' Use the height as the width to create a square image
        End If
        
        Dim lLeft As Long
        Dim lTop As Long
        Dim lRight As Long
        Dim lBottom As Long
        
        ' Center the image
        lLeft = (Me.ScaleWidth - lWidth) \ 2
        lTop = (Me.ScaleHeight - lHeight) \ 2
        lRight = lLeft + lWidth
        lBottom = lTop + lHeight
        
        m_img.Render Me.hDC, lLeft, lTop, lWidth, lHeight
        
        Dim uClockSize& ' Global variable to store the size of the analog clock
        ' Calculate the size and position of the analog clock
        uClockSize = lRight - lLeft ' Size of the clock (diameter)
        Dim uClockLeft As Long
        uClockLeft = lLeft + (lWidth - uClockSize) \ 2
        Dim uClockTop As Long
        uClockTop = lTop + (lHeight - uClockSize) \ 2
        
        Dim lMinutesRemaining As Long
        lMinutesRemaining = 45
        
        ' Calculate the diameter of the clock based on the current image size
        Dim referenceImageSize As Long
        referenceImageSize = 256 ' Reference image size where the clock size is 80
    
        Dim lDiameterOfRemainingMinutesAtReferenzImageSize256px As Long
        lDiameterOfRemainingMinutesAtReferenzImageSize256px = 151 'pixels
        
        ' Calculate the size and position of the analog clock
        Dim clockSizeAtCurrentImageSize As Long
        clockSizeAtCurrentImageSize = (lRight - lLeft) * lDiameterOfRemainingMinutesAtReferenzImageSize256px / referenceImageSize  ' Calculate the proportional size of the clock
    
        Dim uHowMuchPercentIsCircleClosed As Long
        Dim bRecreate As Boolean
        bRecreate = False
    
        If CC Is Nothing Then
            bRecreate = True
        Else
            bRecreate = (CC.Surface.Width <> uClockSize) Or (CC.Surface.Height <> uClockSize)
        End If
    
        If bRecreate Then
            Set CC = Cairo.CreateSurface(uClockSize, uClockSize).CreateContext
        End If
    
        CC.Operator = CAIRO_OPERATOR_CLEAR
        CC.Paint
        CC.Operator = CAIRO_OPERATOR_OVER 'reset to the default-operator
    
        Dim centerX As Long
        Dim centerY As Long
        centerX = uClockSize \ 2
        centerY = uClockSize \ 2
    
    
        CC.Save 'store the current state (since we use a coordsystem-shift and a rotation below)
        CC.TranslateDrawings centerX, centerY 'the new coord(0,0) is now at the center
        CC.RotateDrawingsDeg -90 'to let the angle start at the top
    
        Dim startAngleRad As Double
        Dim endAngleRad As Double
        
        ' Calculate the start angle based on the remaining minutes
        startAngleRad = 180 * (Cairo.PI / 180)
        ' startAngleRad = BerechneGradzahl(lMinutesRemaining) * (Cairo.PI / 180)
        startAngleRad = ((60 - lMinutesRemaining) / 60) * 360 * (Cairo.PI / 180)
        endAngleRad = 360 * (Cairo.PI / 180) ' The end angle is fixed at 270 degrees
    
        CC.MoveTo 0, 0
        CC.Arc 0, 0, uHowMuchPercentIsCircleClosed, startAngleRad, endAngleRad
    
        CC.LineTo 0, 0 ' Connect the arc to the center
        CC.ClosePath
    
        CC.Fill , Cairo.CreateSolidPatternLng(Color, 0.9) ' Fill the cake slice with 40% alpha
        
        pRotate CC
    
        CC.Restore
    
    
        Dim DIB32 As c32bppDIB
        Set DIB32 = CreateDIB32FromSurface(CC.Surface)
        DIB32.Render Me.hDC, uClockLeft, uClockTop
    
        CC.Save
        
        Me.Refresh
    
    End Sub
    
    Private Sub pRotate(ByRef context As cCairoContext)
        '# Save the initial context state
        context.Save
    
        Dim lWidth As Long
        Dim lHeight As Long
        lWidth = context.Surface.Width
        lHeight = context.Surface.Height
    
        '# Apply the 2D transformation
        context.TranslateDrawings lWidth / 2, lHeight / 2   '# Translate to the center
        context.ScaleDrawings 0.8, 1  ' # Scale the image (width: 80%, height: 100%)
        context.RotateDrawingsDeg 5   '# Rotate the image by an angle in degrees
    
        '# Draw the transformed image
        context.Operator = CAIRO_OPERATOR_SOURCE ' Set the operator to SOURCE to overwrite the existing content
        context.Paint
    
        '# Restore the initial context state
        context.Restore
    
    End Sub

  3. #43

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: VB6 Cairo-Paths and Projections

    Quote Originally Posted by tmighty2 View Post
    Code:
        '# Apply the 2D transformation
        context.TranslateDrawings lWidth / 2, lHeight / 2   '# Translate to the center
        context.ScaleDrawings 0.8, 1  ' # Scale the image (width: 80%, height: 100%)
        context.RotateDrawingsDeg 5   '# Rotate the image by an angle in degrees
    Yep, such a transform-triple can be used, to "fit" a normal circle (arc) onto a perspective-wise "3D-ish" Base-Image.

    Here is a Demo-ZIP:
    HollowCircleTimer.zip

    And here a ScreenShot:
    Name:  TimerCircle.png
Views: 802
Size:  183.9 KB

    Olaf

  4. #44
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: VB6 Cairo-Paths and Projections

    This is really beautiful, thank you.

  5. #45
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: VB6 Cairo-Paths and Projections

    I am drawing a cairo surface (a png with transparency) onto a c32bppdib.

    First I draw the button (seen in blue with an orange) orange using gdi+.
    All looks fine. Then I draw the alpha png onto it, and it seems to overwrite what is currently here:

    Name:  trans2.png
Views: 732
Size:  66.0 KB

    What am I missing?

    Edit: Ok, I guess I have to use the helper class again:

    Code:
        Dim lThis&
        lThis = CairoImageListIndexByKey(sGUID)
        
        If lThis > -1 Then
           ' Cairo.ImageList.ItemByIndex(lThis).DrawToDC destinationDC, destX, destY, destWidth, destHeight
            
            Dim cc As cCairoSurface
            Set cc = Cairo.ImageList.ItemByIndex(lThis)
            
            Dim DIB32 As c32bppDIB
            Set DIB32 = CreateDIB32FromSurface(cc.CreateContext.Surface)
            DIB32.Render destinationDC, destX, destY
            
        Else
            Debug.Assert False
        End If
    
    Public Function CreateDIB32FromSurface(Srf As cCairoSurface) As c32bppDIB
        Set CreateDIB32FromSurface = New c32bppDIB
        CreateDIB32FromSurface.InitializeDIB Srf.Width, Srf.Height
    
        Dim pSrc As Long: pSrc = Srf.DataPtr + (Srf.Height - 1) * Srf.stride 'init Src-pointer to the last row
        Dim pDst As Long: pDst = CreateDIB32FromSurface.BitsPointer '... and Dst-Pointer to the first row
        'now we have to do Bottom-Up-row-copying from the Source (because c32bppDIB prefers a Bottom-Up memory-layout in its internal allocation)
        Do
           rc6.New_c.MemCopy pDst, pSrc, Srf.stride
            pSrc = pSrc - Srf.stride: pDst = pDst + Srf.stride
        Loop Until pSrc < Srf.DataPtr
    End Function
    Using an image list which is not limited in size is amazing. I mean that it allows any size (like 420x860 or 256x256).


    Is there any reason why something like c32bpp dib is not in RC6?

    I noticed that Olaf didn't say "You can just use this and this in RC6", but instead he wrote me a helper function so that I could keep using c32bppdib.
    Last edited by tmighty2; Jul 24th, 2023 at 11:34 PM.

  6. #46

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: VB6 Cairo-Paths and Projections

    Quote Originally Posted by tmighty2 View Post
    Is there any reason why something like c32bpp dib is not in RC6?
    Because everything it offers (and much more) can be accomplished with a cCairoSurface.

    Quote Originally Posted by tmighty2 View Post
    I noticed that Olaf didn't say "You can just use this and this in RC6", but instead he wrote me a helper function so that I could keep using c32bppdib.
    I wrote this helper-function for you, to allow you an easier "migration" ...
    (for the hopefully short phase, where you use both of the classes in parallel in your project).

    Your button-example above is "incomplete code" (I cannot run it here via simple Copy&Paste) -
    otherwise I'd have shown you how to do it with "only a cCairoSurface" (like in the many examples before, here in this thread).

    Olaf

  7. #47

    Thread Starter
    PowerPoster
    Join Date
    Jun 2013
    Posts
    7,454

    Re: VB6 Cairo-Paths and Projections

    FWIW - to make integration of a "Form-backing cCairoSurface" easier for "dozens of Forms"...

    Below is a generic Class, which can be integrated with few lines of code into any Form
    (to support Cairo-CC-based Drawings):

    cCairoBackBuf.cls
    Code:
    Option Explicit
    
    Event Paint(CC As cCairoContext)
     
    Private WithEvents Form As Form, BBuf As cCairoSurface, BGPat As cCairoPattern
    
    Public Sub BindTo(VBForm As Form, Optional BGPattern As cCairoPattern)
      Set Form = VBForm
          Form.AutoRedraw = False '<- save resources... (we don't need VBs own BackBuffering, since we provide our own BackBuffer here)
      If BGPattern Is Nothing Then
         Set BGPat = Cairo.CreateSolidPatternLng(Form.BackColor) 'use a plain, solid (Form.Background)-Color as the BGPattern
      Else
         Set BGPat = BGPattern 'use the optionally provided pattern (e.g. the one from Cairo.CreateCheckerPattern)
      End If
      Form_Resize
    End Sub
    
    Public Sub Refresh()
      Dim CC As cCairoContext
      Set CC = BBuf.CreateContext
          CC.Paint 1, BGPat 'clear the current BackGround with this Pattern (on the entire BBuf-area)
      RaiseEvent Paint(CC)  'raise a CC-based BBuf_Paint event to the outside (into the hosting Form)
      BBuf.DrawToDC Form.hDC
    End Sub
    
    Private Sub Form_Resize()
      Dim W: W = Form.ScaleX(Form.ScaleWidth, Form.ScaleMode, vbPixels)
      Dim H: H = Form.ScaleX(Form.ScaleHeight, Form.ScaleMode, vbPixels)
      Set BBuf = Cairo.CreateSurface(W, H)
      Refresh
    End Sub
    
    Private Sub Form_Paint() 'Form_Paint will only reflect the current content of the BBuf (and not refresh the entire scene)
      BBuf.DrawToDC Form.hDC
    End Sub
    The integration-efforts are now much easier, here's a "minimal-example":
    Code:
    Option Explicit
    
    Private WithEvents BBuf As cCairoBackBuf
    
    Private Sub Form_Load()
      Set BBuf = New cCairoBackBuf: BBuf.BindTo Me ', Cairo.CreateCheckerPattern
    End Sub
    
    Private Sub BBuf_Paint(CC As RC6.cCairoContext) 'do all your CC-based Form-drawings here...
      CC.TextOut 20, 20, "Hello World" 'produce some CC-based output on the Form
    End Sub

    A slightly larger example shows, hot to render "directly from an ImageList-Key":
    (without prior conversion of those ImgList-Keys to indexes, because it's just not needed)
    Code:
    Option Explicit
    
    Private WithEvents BBuf As cCairoBackBuf
    
    Private Sub Form_Load()
      Cairo.ImageList.AddIconFromResourceFile "GUID1", "shell32", 167 'add two res-images into the ImgList
      Cairo.ImageList.AddIconFromResourceFile "GUID2", "shell32", 169
      
      Set BBuf = New cCairoBackBuf: BBuf.BindTo Me, Cairo.CreateCheckerPattern 'ensure the binding (this time with a checker-pattern-bg)
    End Sub
    
    Private Sub BBuf_Paint(CC As RC6.cCairoContext) 
      If Cairo.ImageList.Exists("GUID1") Then CC.RenderSurfaceContent "GUID1", 20, 20
      If Cairo.ImageList.Exists("GUID2") Then CC.RenderSurfaceContent "GUID2", 100, 100
    End Sub
    Result of the last Form-example:
    Name:  BackBufSupport.png
Views: 765
Size:  41.8 KB

    HTH

    Olaf

  8. #48
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Question Re: VB6 Cairo-Paths and Projections

    ----
    Last edited by tmighty2; Dec 30th, 2023 at 09:29 PM.

  9. #49
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Re: VB6 Cairo-Paths and Projections

    -----
    Last edited by tmighty2; Dec 30th, 2023 at 09:28 PM.

  10. #50
    Fanatic Member
    Join Date
    Jul 2017
    Posts
    761

    Question Re: VB6 Cairo-Paths and Projections

    I would like to ask for advice how to render such an effect:

    https://www.youtube.com/watch?v=4kksKUdNBO8

    The closest I could find was the "perspective" sample:

    Name:  perspective.png
Views: 261
Size:  78.5 KB

    But I didn't find a way to flip only an edge.

Page 2 of 2 FirstFirst 12

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width