It is currently Sat Mar 06, 2021 5:57 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 5 posts ] 
Author Message
 Post subject: Help fix the code
PostPosted: Fri Mar 20, 2020 9:12 am 
Offline
Enthusiast
Enthusiast

Joined: Sat Jul 07, 2018 6:50 pm
Posts: 203
For educational purposes, I decided to try to rewrite some PB vector drawing code on a GDI+ Flat API
And there are several problems, first of all it's a very unpopular theme, and I could not find detailed descriptions and nuances of using the interface so most things is intuitively research.
My first attempt ended in a very strange result: (code itself is pretty small, most part is interface declarations)

Code:
; *Minimal working example*
; All error handling removed for better code readability (no errors btw)
; Drawing on the window output again for better code readability (simplify the code, we anyway see the result and that's enough here)

EnableExplicit

;{ GDI+ }

Enumeration ; CompositingMode
  #CompositingModeSourceOver = 0
  #CompositingModeSourceCopy = 1
EndEnumeration

Enumeration ; QualityMode
  #QualityModeInvalid   = -1
  #QualityModeDefault   =  0
  #QualityModeLow       =  1
  #QualityModeHigh      =  2 
EndEnumeration

Enumeration ; CompositingQuality
  #CompositingQualityInvalid          = #QualityModeInvalid
  #CompositingQualityDefault          = #QualityModeDefault
  #CompositingQualityHighSpeed        = #QualityModeLow
  #CompositingQualityHighQuality      = #QualityModeHigh
  #CompositingQualityGammaCorrected
  #CompositingQualityAssumeLinear
EndEnumeration

Enumeration ; SmoothingMode
  #SmoothingModeInvalid     = #QualityModeInvalid
  #SmoothingModeDefault     = #QualityModeDefault
  #SmoothingModeHighSpeed   = #QualityModeLow
  #SmoothingModeHighQuality = #QualityModeHigh
  #SmoothingModeNone
  #SmoothingModeAntiAlias
  ;#if (GDIPVER >= 0x0110)
  #SmoothingModeAntiAlias8x4 = #SmoothingModeAntiAlias
  #SmoothingModeAntiAlias8x8
  ;#endif //(GDIPVER >= 0x0110)
EndEnumeration

Enumeration ; InterpolationMode
  #InterpolationModeInvalid          = #QualityModeInvalid
  #InterpolationModeDefault          = #QualityModeDefault
  #InterpolationModeLowQuality       = #QualityModeLow
  #InterpolationModeHighQuality      = #QualityModeHigh
  #InterpolationModeBilinear
  #InterpolationModeBicubic
  #InterpolationModeNearestNeighbor
  #InterpolationModeHighQualityBilinear
  #InterpolationModeHighQualityBicubic
EndEnumeration

Structure GdiplusStartupInput
    GdiPlusVersion.l
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
    PB_Alignment.b[4]
  CompilerEndIf
    *DebugEventCallback.DebugEventProc
    SuppressBackgroundThread.i
    SuppressExternalCodecs.i
EndStructure

Structure GdiplusStartupOutput
    *NotificationHook.NotificationHookProc
    *NotificationUnhook.NotificationUnhookProc
EndStructure


Structure gdi_internal
  graphics.i
  initialized.b
  gdiplusToken.i
  drawingMode.l
  currentDC.i
  lineCapStart.i
  lineCapEnd.i
  lineCapStartScale.f
  lineCapEndScale.f
  currentPen.i
  currentBrush.i
  currentPenColor.l
  currentPenColor2.l
  currentPenPattern.l
  currentPenSize.f
  currentPenAlignment.i
  currentPenBrushStyle.i
  currentPenStyle.i
  currentPenImage.i
  currentPenImageWrapMode.i
  currentPenLineJoin.l
  currentPenMiterLimit.f
  currentPath.i
  currentFont.i
  currentTextAntialiasingMode.l
  drawTextFlags.l
  transformMatrix.i
EndStructure : Global gdi.gdi_internal

;{ Func list }
Macro GDIFuncList
  GdiplusStartup_.l(*token, *input.GdiplusStartupInput, *output.GdiplusStartupOutput)  As "GdiplusStartup"
  GdiplusShutdown_(token.i) As "GdiplusShutdown"
  GdipCreateFromHDC_.l(*hDC, *graphics) As "GdipCreateFromHDC"
  GdipDeleteGraphics_.l(*graphics) As "GdipDeleteGraphics"
  GdipCreatePath_.l(fillMode.l, *path) As "GdipCreatePath"
  GdipCreateSolidFill_.l(color.l, *brush) As "GdipCreateSolidFill"
  GdipDeleteBrush_.l(*brush) As "GdipDeleteBrush"
  GdipDeletePath_.l(path.i) As "GdipDeletePath"
  GdipFillPath_.l(*graphics, *brush, path.i) As "GdipFillPath"
  GdipAddPathLine_.l(*path, x1.f, y1.f, x2.f, y2.f) As "GdipAddPathLine"
  GdipSetSmoothingMode_.l(*graphics, smoothingMode.l) As "GdipSetSmoothingMode"
  GdipSetCompositingMode_.l(*graphics, compositingMode.l) As "GdipSetCompositingMode"
  GdipSetCompositingQuality_.l(*graphics, compositingQuality.l) As "GdipSetCompositingQuality"
  GdipSetInterpolationMode_.l(*graphics, interpolationMode.l) As "GdipSetInterpolationMode"   
  GdipCreateMatrix_.l(*matrix) As "GdipCreateMatrix"
  GdipDeleteMatrix_.l(matrix.i) As "GdipDeleteMatrix"
  GdipTranslateMatrix_.l(matrix.i, offsetX.f, offsetY.f, order) As "GdipTranslateMatrix"
  GdipSetWorldTransform_.l(*graphics, matrix.i) As "GdipSetWorldTransform"
  ;GdipStartPathFigure_.l(*path) As "GdipStartPathFigure"
EndMacro 
;}

CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
  Import "x:\gdiplus_x64.lib"
    GDIFuncList
  EndImport   
CompilerElse
  Import "x:\gdiplus_x86.lib"
    GDIFuncList
  EndImport   
CompilerEndIf
;}

Procedure iGdiplusStartup()
  ; Initialize GDI+.
  Protected gdiplusStartupInput.GdiplusStartupInput
  gdiplusStartupInput\GdiplusVersion              = 1
  gdiplusStartupInput\DebugEventCallback          = #Null
  gdiplusStartupInput\SuppressBackgroundThread    = #False
  gdiplusStartupInput\SuppressExternalCodecs      = #True
  If Not GdiplusStartup_(@gdi\gdiplusToken, @gdiplusStartupInput, #Null)
    gdi\initialized = #True
  Else
    ProcedureReturn #False
  EndIf
  ProcedureReturn #True
EndProcedure

Procedure gdi()
 
  Protected *hDC = GetDC_(WindowID(0))
 
  gdi\currentDC = *hDC
  GdipCreateFromHDC_(gdi\currentDC ,@gdi\graphics)
  gdi\drawingMode                 = #PB_2DDrawing_Default
  gdi\lineCapStartScale           = 2.0
  gdi\lineCapEndScale             = 2.0
  GdipCreateMatrix_(@gdi\transformMatrix)
  GdipCreatePath_(1, @gdi\currentPath)
  GdipSetSmoothingMode_     (gdi\graphics, #SmoothingModeAntiAlias)
  GdipSetCompositingMode_   (gdi\graphics, #CompositingModeSourceOver)
  GdipSetCompositingQuality_(gdi\graphics, #CompositingQualityGammaCorrected)
  GdipSetInterpolationMode_ (gdi\graphics, #InterpolationModeHighQualityBicubic) 
  GdipTranslateMatrix_(gdi\transformMatrix , 20, 0, 0)  ;Set Origin 20, 0
  GdipSetWorldTransform_(gdi\graphics, gdi\transformMatrix )
  ;GdipStartPathFigure_(gdi\currentPath)
  GdipAddPathLine_(gdi\currentPath, 9.9, 0, 5.5, 4.4)
  GdipAddPathLine_(gdi\currentPath, 1.1, 0,   0, 1.1)
  GdipAddPathLine_(gdi\currentPath, 4.4,4.4,  0, 9.9)
  GdipAddPathLine_(gdi\currentPath, 1.1, 11,  4.4,4.4)
  GdipAddPathLine_(gdi\currentPath, 9.9, 11,  11, 9.9)
  GdipAddPathLine_(gdi\currentPath, 6.6,5.5,  11,1.1)
  GdipCreateSolidFill_($FFFF0000, @gdi\currentBrush)
  GdipFillPath_(gdi\graphics, gdi\currentBrush, gdi\currentPath)
  GdipDeleteBrush_(gdi\currentBrush)
  GdipDeleteGraphics_(gdi\graphics) 
  GdipDeleteMatrix_(gdi\transformMatrix)
  GdipDeletePath_(gdi\currentPath)
 
  ReleaseDC_(WindowID(0), *hDC)
EndProcedure

Procedure PB() 
  If StartVectorDrawing(WindowVectorOutput(0, #PB_Unit_Pixel))
    AddPathSegments("M11,1.1 L9.9,0L5.5,4.4L1.1,0L0,1.1l4.4,4.4L0,9.9L1.1,11l4.4-4.4L9.9,11L11,9.9L6.6,5.5L11,1.1z")
    VectorSourceColor(RGBA(255, 0, 0, 255))
    FillPath()
    StopVectorDrawing()
  EndIf
EndProcedure

If OpenWindow(0, 0, 0, 80, 30, "", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
  If iGdiplusStartup() : gdi() : EndIf 
  PB()
  Repeat
    Define Event = WaitWindowEvent()
  Until Event = #PB_Event_CloseWindow
EndIf
; GdiplusShutdown_(gdi\gdiplusToken)


Image
First icon is PB vector drawing, second one is flat API.

What is wrong with this code and why?

P.S. gdilib (if you don't have one)


Top
 Profile  
Reply with quote  
 Post subject: Re: Help fix the code
PostPosted: Fri Mar 20, 2020 7:06 pm 
Offline
PureBasic Bullfrog
PureBasic Bullfrog
User avatar

Joined: Wed Jul 06, 2005 5:42 am
Posts: 8149
Location: Fort Nelson, BC, Canada
You don't need to supply your own gdiplus libs as PureBasic ships with those included in x86 and x64 versions. This is necessary because the Vector Drawing lib in PB maps gdiplus commands. So:
Code:
Import "gdiplus.lib"
is all the code you need for that.

As to the differences in the quality of the output, I suspect revisiting the number values you are passing to GdipAddPathLine would yield the desired result.

_________________
BERISHEET


Top
 Profile  
Reply with quote  
 Post subject: Re: Help fix the code
PostPosted: Fri Mar 20, 2020 10:28 pm 
Offline
Always Here
Always Here

Joined: Sun Sep 07, 2008 12:45 pm
Posts: 5293
Location: Germany
Code:
Import "gdiplus.lib"
  GdiplusStartup.l(*token, *input.GdiplusStartupInput, *output.GdiplusStartupOutput)
  GdiplusShutdown(token.i)
  GdipCreateFromHDC.l(*hDC, *graphics)
  GdipDeleteGraphics.l(*graphics)
  GdipCreatePath.l(fillMode.l, *path)
  GdipCreateSolidFill.l(color.l, *brush)
  GdipDeleteBrush.l(*brush)
  GdipDeletePath.l(path.i)
  GdipFillPath.l(*graphics, *brush, path.i)
  GdipAddPathLine.l(*path, x1.f, y1.f, x2.f, y2.f)
  GdipSetSmoothingMode.l(*graphics, smoothingMode.l)
  GdipSetCompositingMode.l(*graphics, compositingMode.l)
  GdipSetCompositingQuality.l(*graphics, compositingQuality.l)
  GdipSetInterpolationMode.l(*graphics, interpolationMode.l)
  GdipCreateMatrix.l(*matrix)
  GdipDeleteMatrix.l(matrix.i)
  GdipTranslateMatrix.l(matrix.i, offsetX.f, offsetY.f, order)
  GdipSetWorldTransform.l(*graphics, matrix.i)
  GdipStartPathFigure.l(*path)
  GdipCreatePen1(color.l, width.f, unit.l, *pen)
EndImport


I think you need to create a brush or a pen.


Top
 Profile  
Reply with quote  
 Post subject: Re: Help fix the code
PostPosted: Sat Mar 21, 2020 1:58 pm 
Offline
Enthusiast
Enthusiast

Joined: Sat Jul 07, 2018 6:50 pm
Posts: 203
netmaestro wrote:
I suspect revisiting the number values you are passing to GdipAddPathLine would yield the desired result.

Right.
I looked at the values in the debugger (when PB call GdipAddPathLine from AddPathSegments wrapper) and they are different from used one.

AddPathSegments("M11,1.1 L9.9,0 L5.5,4.4 L1.1,0 L0,1.1 l4.4,4.4 L0,9.9 L1.1,11 l4.4-4.4 L9.9,11 L11,9.9 L6.6,5.5 L11,1.1z")

in GdipAddPathLine we can use original values except highlighted
4.4,4.4 becomes 4.4,5.5
4.4,4.4 becomes 5.5,6.6

that's fix the code, unfortunately I don't understand yet how to calc right values...

By the way, I noticed that the letter "L" is lowercase for mismatched values (it's svg path originally) I think it is mean something.


Top
 Profile  
Reply with quote  
 Post subject: Re: Help fix the code
PostPosted: Sat Mar 21, 2020 3:23 pm 
Offline
Enthusiast
Enthusiast

Joined: Sat Jul 07, 2018 6:50 pm
Posts: 203
infratec wrote:
I noticed that the letter "L" is lowercase for mismatched values (it's svg path originally) I think it is mean something
I was right

Code:
M  x,y   Move to the absolute coordinates x,y
m  x,y   Move to the right x and down y (or left and up if negative values)
L  x,y   Draw a straight line to the absolute coordinates x,y
l  x,y   Draw a straight line to a point that is relatively right x and down y (or left and up if negative values)
H  x     Draw a line horizontally to the exact coordinate x
h  x     Draw a line horizontally relatively to the right x (or to the left if a negative value)
V  y     Draw a line vertically to the exact coordinate y
v  y     Draw a line vertically relatively down y (or up if a negative value)
Z  z     Draw a straight line back to the start of the path
'l' means relative coordinates and 'L' is absolute

now we just need to calc relative coordinates and that will fix the problem
and if we also comment GdipSetCompositingQuality (PB use lower quality by default) we'll get visual match.


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 5 posts ] 

All times are UTC + 1 hour


Who is online

Users browsing this forum: No registered users and 55 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye