drawtext doesn't work with customfilters?

Just starting out? Need help? Post your questions and find answers here.
deathmx
User
User
Posts: 27
Joined: Mon Feb 26, 2018 3:14 am

drawtext doesn't work with customfilters?

Post by deathmx »

Hmm thought this was working at one point am I missing something?

Code: Select all


Global Window = OpenWindow(#PB_Any,0,0,100,100,"test")
Global Canvas = CanvasGadget(#PB_Any,0,0,100,100)

Procedure Endprogram()
End  
EndProcedure

Procedure FilterCallback(x, y, SourceColor, TargetColor)
  
  ProcedureReturn SourceColor
EndProcedure

StartDrawing(CanvasOutput(Canvas))

DrawingMode(#PB_2DDrawing_CustomFilter)      
CustomFilterCallback(@FilterCallback())

DrawText(0,0,"Hello",RGB(255,0,0))
StopDrawing()




BindEvent(#PB_Event_CloseWindow,@Endprogram())
Repeat:WaitWindowEvent():ForEver
User avatar
STARGÅTE
Addict
Addict
Posts: 2067
Joined: Thu Jan 10, 2008 1:30 pm
Location: Germany, Glienicke
Contact:

Re: drawtext doesn't work with customfilters?

Post by STARGÅTE »

That's strange. Even with additional #PB_2DDrawing_Transparent it doesn't work. It seems like, it's a bug.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Lizard - Script language for symbolic calculations and moreTypeface - Sprite-based font include/module
RASHAD
PureBasic Expert
PureBasic Expert
Posts: 4636
Joined: Sun Apr 12, 2009 6:27 am

Re: drawtext doesn't work with customfilters?

Post by RASHAD »

Hi
Result = DrawText(x, y, Text$ [, FrontColor [, BackColor]])
Return value:(Result)
Returns the new x position of the text cursor (ie the location just after the printed text).

I think the problem comes from this situation(The return value)
With Windows API TextOut_() or DrawText_() no problem because the return value is differ from PB
For now you can use :
# 1:

Code: Select all


Global Window = OpenWindow(#PB_Any,0,0,100,100,"test")
Global Canvas = CanvasGadget(#PB_Any,0,0,100,100)

Procedure Endprogram()
End  
EndProcedure

Procedure FilterCallback(x, y, SourceColor, TargetColor)
  
  ProcedureReturn SourceColor
EndProcedure

StartDrawing(CanvasOutput(Canvas))

DrawingMode(#PB_2DDrawing_CustomFilter)      
CustomFilterCallback(@FilterCallback())
Circle(50,50,30,RGB(28, 251, 61))
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(0,0,"Hello",RGB(255,0,0))
StopDrawing()

BindEvent(#PB_Event_CloseWindow,@Endprogram())
Repeat:WaitWindowEvent():ForEver

#2 :

Code: Select all

Global Window = OpenWindow(#PB_Any,0,0,100,100,"test")
Global Canvas = CanvasGadget(#PB_Any,0,0,100,100)

Procedure Endprogram()
End  
EndProcedure

Procedure FilterCallback(x, y, SourceColor, TargetColor)  
  ProcedureReturn SourceColor
EndProcedure

hdc = StartDrawing(CanvasOutput(Canvas))

DrawingMode(#PB_2DDrawing_CustomFilter)      
CustomFilterCallback(@FilterCallback())
Circle(50,50,30,RGB(28, 251, 61))
SetTextColor_(hdc,#Red)
TextOut_(hdc, 0,0,"Hellow", 6)
StopDrawing()

BindEvent(#PB_Event_CloseWindow,@Endprogram())
Repeat:WaitWindowEvent():ForEver
Egypt my love
User avatar
Demivec
Addict
Addict
Posts: 4086
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: drawtext doesn't work with customfilters?

Post by Demivec »

I didn't seem to have any problems, aside from 'feature-creep' in my test code. :D

Here's a short bit of test code:

Code: Select all

Global Window = OpenWindow(#PB_Any,0,0,100,100,"test")
Global Canvas = CanvasGadget(#PB_Any,0,0,100,100)

Procedure Endprogram()
End  
EndProcedure

Procedure FilterCallback(x, y, SourceColor, TargetColor)
If Alpha(SourceColor) > 1
    ProcedureReturn SourceColor
  Else
    ProcedureReturn TargetColor
  EndIf
EndProcedure

StartDrawing(CanvasOutput(Canvas))

DrawingMode(#PB_2DDrawing_CustomFilter)      
CustomFilterCallback(@FilterCallback())

DrawText(0,0,"Hello",RGBA(255,0,0, 255), RGBA(0, 0, 0, 0))
StopDrawing()


BindEvent(#PB_Event_CloseWindow,@Endprogram())
Repeat:WaitWindowEvent():ForEver

Here's a lengthier bit of test code (and not thoroughly tested nor necessarily complete but full of possibilities and certainly good enough):

Code: Select all

EnableExplicit
Global Window = OpenWindow(#PB_Any,0,0,300,350,"test")
Global Canvas = CanvasGadget(#PB_Any,0,0,300,350)

Procedure Endprogram()
  End  
EndProcedure

Structure color_RGBA
  StructureUnion
    c.l
    s.RGBQUAD
  EndStructureUnion
EndStructure

Structure color_RGBA_arr
  arr.color_RGBA[0]
EndStructure

Structure image_pattern
  *bitmap.color_RGBA_arr ;memory = w * ([A}[B][G][R]) * h;contains color pattern data
  w.i                    ;width
  h.i                    ;height
EndStructure

Structure filterPattern
  *foreground.image_pattern
  *background.image_pattern
  foregroundTint.i
  backgroundTint.i
EndStructure

Global filterPattern.filterPattern, *pattern_blank.image_pattern

Declare createPattern(w, h, imageNum, hasAlpha = #False)
Declare freePattern(*pattern.image_pattern)
Declare setFilterPattern(*foreground, *background, foregroundTint = #PB_Default, backgroundTint = #PB_Default)

;blank pattern
CreateImage(0, 2, 2, 32, #Black)
If StartDrawing(ImageOutput(0))
  Box(0, 0, 2, 2)
  StopDrawing()
  *pattern_blank = createPattern(2, 2, 0, #True)
  If *pattern_blank = #Null: End: EndIf
EndIf

Define.image_pattern *pattern_diagstripe, *pattern_checker, *pattern_spot

;create and return a image_pattern structure from an image
Procedure createPattern(w, h, imageNum, hasAlpha = #False)
  Protected *bitmap.color_RGBA_arr, *pattern.image_pattern, x, y, pix
  
  ;it is possible to reuse an existing pattern structure
  If *pattern = #Null
    *pattern = AllocateStructure(image_pattern)
    If *pattern = #Null
      ProcedureReturn #False
    EndIf
  EndIf
  
  If w = 0 And h = 0
    ProcedureReturn #False ;error width and height must be > 0
  EndIf
  
  *pattern\w = w
  *pattern\h = h
  
  ;check for reuse of pattern
  If *pattern\bitmap And MemorySize(*pattern\bitmap) <> (*pattern\w * *pattern\h * SizeOf(RGBQUAD))
    FreeMemory(*pattern\bitmap)
  EndIf  
  
  *bitmap.color_RGBA_arr = AllocateMemory(*pattern\w * *pattern\h * SizeOf(RGBQUAD))
  If *bitmap 
    If StartDrawing(ImageOutput(imageNum))
      If hasAlpha
        For x = 0 To *pattern\w - 1
          For y = 0 To *pattern\h - 1
            pix = Point(x, y)
            *bitmap\arr[y * *pattern\w + x]\c = RGBA(Red(pix), Green(pix), Blue(pix), Alpha(pix))
          Next
        Next
      Else
        For x = 0 To *pattern\w - 1
          For y = 0 To *pattern\h - 1
            pix = Point(x, y)
            *bitmap\arr[y * *pattern\w + x]\c = RGBA(Red(pix), Green(pix), Blue(pix), 255)
          Next
        Next
      EndIf
      
      StopDrawing()
    EndIf
  EndIf
  
  *pattern\bitmap = *bitmap
  ProcedureReturn *pattern
EndProcedure

;free memory used in image_pattern structure
Procedure freePattern(*pattern.image_pattern)
  If *pattern
    If *pattern\bitmap
      FreeMemory(*pattern\bitmap)
    EndIf
    FreeStructure(*pattern)
    *pattern = #Null
  EndIf
EndProcedure

Procedure setFilterPattern(*foreground, *background, foregroundTint = #PB_Default, backgroundTint = #PB_Default)
  If *foreground = #Null
    filterPattern\foreground = *pattern_blank
  Else
    filterPattern\foreground = *foreground
  EndIf
  
  If foregroundTint = #PB_Default
    filterPattern\foregroundTint = RGBA(255, 255, 255, 255)
  ElseIf foregroundTint <> #PB_Ignore
    filterPattern\foregroundTint = foregroundTint
  EndIf
  
  If *background = #Null
    filterPattern\background = *pattern_blank
  Else
    filterPattern\background = *background
  EndIf
  
  If backgroundTint = #PB_Default
    filterPattern\backgroundTint = RGBA(255, 255, 255, 255)
  ElseIf backgroundTint <> #PB_Ignore
    filterPattern\backgroundTint = backgroundTint
  EndIf

EndProcedure

Procedure FilterCallback(x, y, SourceColor, TargetColor)
  If Alpha(SourceColor) > 0
    ProcedureReturn RGBA(Red(SourceColor), 0, Blue(SourceColor), Alpha(SourceColor))
  Else
    ProcedureReturn RGBA(Red(TargetColor), Green(TargetColor), Blue(TargetColor), Alpha(TargetColor))
  EndIf
EndProcedure

Procedure FilterCallback_pattern(x, y, SourceColor, TargetColor)
  If Alpha(SourceColor) > 0
    With filterPattern\foreground
      Sourcecolor = \bitmap\arr[(y % \h) * \w + (x % \w)]\c
    EndWith
    ProcedureReturn RGBA(Red(SourceColor) & Red(filterPattern\foregroundTint),
                         Green(SourceColor) & Green(filterPattern\foregroundTint),
                         Blue(SourceColor) & Blue(filterPattern\foregroundTint),
                         Alpha(SourceColor) & Alpha(filterPattern\foregroundTint))
    
  Else
    With filterPattern\background
      TargetColor = \bitmap\arr[(y % \h) * \w + (x % \w)]\c
    EndWith
    ProcedureReturn RGBA(Red(TargetColor) & Red(filterPattern\backgroundTint),
                         Green(TargetColor) & Green(filterPattern\backgroundTint),
                         Blue(TargetColor) & Blue(filterPattern\backgroundTint),
                         Alpha(TargetColor) & Alpha(filterPattern\backgroundTint))
  EndIf
EndProcedure

;checkered pattern
CreateImage(0, 2, 2, 32, #Black)
If StartDrawing(ImageOutput(0))
  Plot(0, 0, #White)
  Plot(1, 1, #White)
  StopDrawing()
  *pattern_checker = createPattern(2, 2, 0)
  If *pattern_checker = #Null: End: EndIf
EndIf

;diagonal stripe pattern
CreateImage(0, 4, 4, 32, #Black)
If StartDrawing(ImageOutput(0))
  Plot(2, 0, #White)
  Plot(3, 1, #White)
  Plot(0, 2, #White)
  Plot(1, 3, #White)
  StopDrawing()
  *pattern_diagstripe = createPattern(4, 4, 0)
  If *pattern_diagstripe = #Null: End: EndIf
EndIf

;spot pattern
CreateImage(0, 16, 16, 32, #Yellow)
If StartDrawing(ImageOutput(0))
  Circle(0, 0, 3, RGB(10, 90, 128))
  Circle(OutputWidth() - 1, 0, 3, RGB(10, 90, 128))
  Circle(0, OutputHeight() - 1, 3, RGB(10, 90, 128))
  Circle(OutputWidth() - 1, OutputHeight() - 1, 3, RGB(10, 90, 128))
  Circle(OutputWidth() / 2 - 1, OutputHeight() / 2 - 1, 5, RGB(10, 90, 128))
  StopDrawing()
  *pattern_spot = createPattern(ImageWidth(0), ImageHeight(0), 0)
  If *pattern_spot = #Null: End: EndIf
EndIf

LoadFont(0, "Times New Roman", 100)
LoadFont(1, "Times New Roman", 48)
StartDrawing(CanvasOutput(Canvas))
  DrawingMode(#PB_2DDrawing_CustomFilter)  
  DrawingFont(FontID(0))
  setFilterPattern(*pattern_checker, *pattern_spot, RGB(255, 0, 255), RGB(128, 128, 128))
  CustomFilterCallback(@FilterCallback_pattern())
  DrawText(0, 0, "Hello")
  
  setFilterPattern(*pattern_diagstripe, *pattern_blank, RGB(0, 255, 0))
  Box(0, TextHeight("Hello") - 5, TextWidth("Hello"), 10)
  
  DrawingFont(FontID(1))
  setFilterPattern(*pattern_spot, *pattern_checker, #PB_Default, RGB(200, 255, 200))
  DrawText(0, 200, "123456789", RGBA(0, 255, 0, 15), RGBA(0, 0, 0, 255))
StopDrawing()


BindEvent(#PB_Event_CloseWindow,@Endprogram())
Repeat:WaitWindowEvent():ForEver
Last edited by Demivec on Thu Jun 09, 2022 12:22 am, edited 1 time in total.
deathmx
User
User
Posts: 27
Joined: Mon Feb 26, 2018 3:14 am

Re: drawtext doesn't work with customfilters?

Post by deathmx »

Thank you guys for the help :)

I came up with something similar Demivec but, but didn't commit to the full rgba lol. I was trying to check for alpha colors but, set it up incorrectly.
I ended up using your smaller solution. I also really appreciate the eye candy bits and effort on the longer solution it was a great bonus :) Thanks!
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: drawtext doesn't work with customfilters?

Post by Michael Vogel »

Maybe there's something I didn't see so far, but why the DrawText doesn't work for images? The following example works fine for Canvas but shows a white rectangle for the image...

Code: Select all

Procedure FilterCallback(x, y,Source,Destination)
	
	If Alpha(Source)
		ProcedureReturn #Green
	Else
		ProcedureReturn #Red
	EndIf

	ProcedureReturn Destination

EndProcedure


Macro CustomDrawTest(target)

	StartDrawing(target)
	DrawingFont(FontID(0))
	DrawingMode(#PB_2DDrawing_CustomFilter)
	CustomFilterCallback(@FilterCallback())
	DrawText(0,0,"HELLO",$ffffffff,$0)
	StopDrawing()

EndMacro

LoadFont(0,"Arial",32)

OpenWindow(0,0,0,400,200, "x", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
CanvasGadget(0,0,0,200,200)
ImageGadget(1,200,0,200,200,0)
CreateImage(1,200,200,32,#Blue)


CustomDrawTest(CanvasOutput(0))
CustomDrawTest(ImageOutput(1))

SetGadgetState(1,ImageID(1))

Repeat
	Event = WaitWindowEvent()
Until Event = #PB_Event_CloseWindow
User avatar
Demivec
Addict
Addict
Posts: 4086
Joined: Mon Jul 25, 2005 3:51 pm
Location: Utah, USA

Re: drawtext doesn't work with customfilters?

Post by Demivec »

Michael Vogel wrote: Sat Jul 09, 2022 7:53 pm Maybe there's something I didn't see so far, but why the DrawText doesn't work for images? The following example works fine for Canvas but shows a white rectangle for the image...
The colors #Green and #Red don't have alpha. Use RGBA(0, 255, 0, 255) and RGBA(255, 0, 0, 255) or $FF00FF00 or $FF0000FF instead.

The custom callback always deals with colors as RGBA which I interpret as it not assumimg the alpha values.

I am in the process of creating a module implementing the examples and methods I posted earlier in this thread. It suffers from feature creep. When the features are implemented I will tune it for speed (possibly pruning off features) and ease of use. As part of my regular tests I run examples on an image and a canvas and when something doesn't show up on an image it always relates to the alpha not being included in the color.
User avatar
Michael Vogel
Addict
Addict
Posts: 2666
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Re: drawtext doesn't work with customfilters?

Post by Michael Vogel »

Thanks, forgot that :shock:

Played around with something like...

Code: Select all

CreateImage(0,200,200,24,#Blue) : CatchImage(1,EncodeImage(0,#PB_ImagePlugin_BMP,0,4))
...before everything went weird (see also here). As there was nothing on my screen, I tried combined drawing modes (like #PB_2DDrawing_CustomFilter | #PB_2DDrawing_AlphaBlend) before I gave up and searched for help here.

Which worked as usual, cheers! :lol:
Post Reply