B4J Question B4X Canvas path differences between B4A and B4J

labcold

Member
Licensed User
Longtime User
I am porting an application from B4A to B4J which uses a number of CustomView XUI objects for the main display interfaces.
While most things work OK I have a problem with the way B4J renders a path vs B4A method.

In B4A I use a path to draw a rotated series of line segments.
It is possible for these line segments of the path to all fall in a straight line.
In B4A the line is still rendered correctly when the lines are straight.

By way of demonstration this much simplified code renders a straight line in B4A:
B4A line using path:
    Dim sl As B4XPath
    sl.Initialize(cl-100dip,drcy)
    sl.LineTo(cl+0dip,dlcy)
    sl.LineTo(cl+100dip,dlcy)
    sl.LineTo(cl-100dip,drcy)
    cvs.Drawpathrotated(sl,xui.Color_ARGB(255,180,180,180), False,2,rot,cx,cy)
When dlcy = drcy a line is drawn.

In B4J the same code draws the path when the lines are not in a single line.
BUT when they all fall in a line then no path is actually drawn.
In order to get B4J to render the path it seems I need to do the following:
B4J version to render path:
    Dim sl As B4XPath
    sl.Initialize(cl-100dip,drcy)
    sl.LineTo(cl+0dip,dlcy)
    sl.LineTo(cl+100dip,dlcy+2dip)
    sl.LineTo(cl-100dip,drcy+2dip)
    cvs.Drawpathrotated(sl,xui.Color_ARGB(255,180,180,180), False,2,rot,cx,cy)
When dlcy = drcy NO line is drawn unless I offset the path as above and by the stroke width as a minimum.

I understand there are differences between the position of the drawing line between B4A and B4J but I cannot see why the B4J line does not show when the points make a path that draw over itself. The same thing happens if you use filled as well as outline.
Does anyone know if this is just a javafx standard or is there a setting or something I have missed?
It appears as if the path is rendered but the return stroke erases the original stroke. Could this be an XOR operation or something? Antialiasing?
I cannot see why it would be logical for the path not to be drawn even if it completely overlaps itself.
The CustomViews I have written contain a lot of paths to be drawn so to go through and specifically extract straight lines and render (and rotate) these as exceptions is not viable as its already rendering much more slowly than on Android.
 

William Lancee

Well-Known Member
Licensed User
Longtime User
Note that there is a not-so subtle difference in the way the stroke width affects the drawing between B4J and the other platforms.
In B4J the path defines the stroke EDGE. In B4A and B4i it defines the stroke CENTER. This is a JavaFX thing, not a B4J flaw.

In B4XPath, when the line path closes, the interior of the line path is empty. You need to create a thin rectangle by adding two points.
The additional first point is the first point, offset by the width of the line you want, similarly for the additional last point.
Edit: The two points can also be added to the end of the Path. The drawPath will close the last little segment.

While BitmapCreator has a second method that doesn't close the Path, you'll still have to rotate the bitmap, which I found to be non-trivial. Therefore I used the method above.
I understand that you have many instances of this behaviour of B4XCanvas, so you may have to do some systematic replacements.
Once the thin rectangle path is defined, DrawPathRotated works the same in both B4J and B4A

In case you are interested, the BitmapCreator code is shown below.
B4X:
bmcGraph.DrawPath2(pthNeedle, bmcGraph.CreateBrushFromColor(xui.Color_Black), False, 2)
 
Last edited:
Upvote 0

labcold

Member
Licensed User
Longtime User
Thanks for your time and the reply.
I did try rendering to a bitmap and rotating but the quality of the image is not as good - perhaps there are better ways to improve the resolution - but it also takes longer and its already slow in comparison to B4A.
Purely from a logical viewpoint I still cannot see the benefit in path not drawing anything if the segments all fall in a line - especially if the path is filled with the stroke colour - however thats apparently the way its supposed to work.
I have decided that I cannot use the same B4A XUI cross platform code and I will re-write the way it works to be faster and compliant with the B4J versions of canvas.
 
Upvote 0
Top