Graphics: What users need today - Part II

This topic should serve Xojo (@Geoff_Perlman, @William_Yu, @Greg_O_Lone, @Javier_Menendez) to get an overview which requirements we users have today to the Graphics object.

This topic is a continuation of “https://forum.xojo.com/t/graphics-what-users-need-today/54071”. I know that there are dozens of feature requests in the feedback. Maybe the overview will help the company better.

The suggestions mentioned here have been standard in the graphics libraries of macOS / iOS, Windows, Linux, Android and Web 2.0 (when switching to jCanvas) for years. I have added the links to the API’s of all platforms supported by Xojo (in the future): macOS, Window, Linux, iOS, Android, Web 2.0.

I have tried to specify my requirements for Xojo so that the team can easily implement them in Xojo for all available desktop platforms. We can already do some things with Declares itself, but it is extremely difficult to address the Direct2D context on Windows at this time. And if it works, it breaks with the Xojo implementation and you have to rebuild all the drawing routines that are already built into Xojo (the explanation would go too far here).

I ask Xojo to read this post carefully. I have really tried to collect all information completely and also think that it is the right places within the API’s, so that an adaptation of the Graphics object to today’s standards should not be so difficult.

I ask for detailed additions from other users.

Topic

This time it is about the “AffineTransform Matrix”. The “old” iOS Framework contains parts of this already. And this matrix is extremely helpful, e.g. when it comes to scaling the graphics context. Therefore the wish would be to make the function available in the Graphics object on desktop platforms.

Feedback: <https://xojo.com/issue/22602> (Add Support For Drawing With A Transformation Matrix)
Please give this feedback case a few points. Thank you very much.

It would also be wonderful to get access to the matrix itself to manipulate its points, for example to change the rotation point!

I know Object2D exists, but that requires a lot of writing, and simple methods inside the Graphics object, like in iOSGraphics, would keep the code much clearer.

We want the following methods in the Desktop Graphics object, which already exist in iOSGraphics:

Graphics.Rotate

This is already available in iOS.

macOS / iOS: CGAffineTransform
Windows: Matrix3x2F::Rotation, Direct2D Transforms Overview
Linux: cairo_rotate
Android: CanvasTransform.Rotate
Web 2.0 (jCanvas): rotateCanvas

Rotate

Graphics.Scale

This is already available in iOS.
Graphics.ScaleX/ScaleY already exists, maybe you should make a method out of it like in the iOS Framework.

macOS / iOS: CGAffineTransform
Windows: Matrix3x2F::Scale, Direct2D Transforms Overview
Linux: cairo_scale
Android: CanvasTransform.Scale
Web 2.0 (jCanvas): scaleCanvas

Scale

Graphics.Translate

This is already available in iOS.

macOS / iOS: CGAffineTransform
Windows: Matrix3x2F::Translation, Direct2D Transforms Overview
Linux: cairo_translate
Android: CanvasTransform.Translate
Web 2.0 (jCanvas): translateCanvas

Translate

Please note that these functions must also be integrated into PDFGraphics.

Graphics.SaveState

This is already available in iOS & PDFGraphics.

macOS / iOS: saveGState
Windows: SaveDrawingState
Linux: cairo_save
Android: CanvasState.Save

Graphics.RestoreState

This is already available in iOS & PDFGraphics.

macOS / iOS: restoreGState
Windows: RestoreDrawingState
Linux: cairo_restore
Android: CanvasState.Restore


If Rotate, Scale and Translate could be included in the Graphics object, Object2D would be almost superfluous.

5 Likes

Moved to General because there’s nothing about this that’s specific to any prerelease.

Add Graphics.Scale

The confusing thing about Graphic.ScaleX/ScaleY seems to me to be that it also does a translation of the coordinates.

Example: If I want to stretch or compress a Text (using Graphics.DrawText), its X/Y coordinates are automatically changed, which is not the case with the scale methods of the API’s above. If I now draw another text before this text, which is not stretched/compressed, there will be an unwanted gap between the texts.

Continuing the discussion from Graphics: What users need today - Part II:

Hello,
Martin T.
I’ve been using flexible image display with the for years
object2D element Pixmapshape

  1. Create image / new Picture(w,h)
  2. transfer to pixmapshape ()
  3. edit pixmapshape.image.graphics … all function calls
    or with rotation, scale, FillOpacity
  4. Draw on a new picture
  5. Put in canvas.paint or show canvas.backdrop

everything works as you imagine it

I never use Graphic.scaleX / ScaleY
but draw directly on the picture
and adjust the picture with drawpicture0,0, w, h, 0,0, w, h
on canvas to size

I have up to 300 Pixmapshaps on my drawing area and I can control each one as I want
redrawing is very quick

Thank you @RudolfJ for your contribution.

I know that some things are possible with PixmapShape (subclass of Object2D). However, as mentioned above, I am interested in bringing the functionality of the iOS framework into line with the desktop framework and with the information I have gathered, this should be relatively easy for the Xojo engineers to implement.

Use scale with translate to get the desired result. For me personally, I translate the co-ordinates to the center of what I want to draw, then apply scale/rotate then minus the center of the object/text.

Since editing those two Properties manipulates Scale and Translation, I did a small workaround for my Text Drawing Sample above, as long Xojo hasn’t implemented the recommended methods.

Const kText As String = "Hello World today!"
Const kTopPosition As Double = 75

Var dResolution As Double = If(AppSupportsHiDPI, 2, 1)
Var arsWords() As String = kText.Split
Var dTextWidth, dLeftPosition, dValue, dFactor As Double

dLeftPosition = 50

g.Bold = True
g.FontSize = 24

dValue = 4 * dResolution // Try experimenting with the value

Var isWorld As Boolean

For Each sWord As String In arsWords
  
  isWorld = sWord = "World"
  g.ScaleX = If(isWorld, dValue, dResolution)

  If isWorld Then
  
    dFactor = g.ScaleX / dResolution
    dLeftPosition = dLeftPosition / dFactor
  
  End If
  
  dTextWidth = g.TextWidth(sWord + " ")
  g.DrawText(sWord, dLeftPosition, kTopPosition)
  
  dLeftPosition = (dLeftPosition + dTextWidth) * If(isWorld, dFactor, 1)
  
Next
1 Like

7 posts were split to a new topic: Hardware Accelerated OpenGLSurface

My suggestions for the implementation are the following:

Graphics.Rotate(angle As Double)
Graphics.Scale(x As Double, y As Double)
Graphics.Translate(x As Double, y As Double)
Graphics.SaveState
Graphics.RestoreState

I have linked the wrong pages for macOS / iOS. Here are the right links.

Graphics.Rotate

macOS / iOS: CGContext.rotate(by:)

Graphics.Scale

macOS / iOS: CGContext.scaleBy(x:y:)

Graphics.Translate

macOS / iOS: CGContext.translateBy(x:y:)

as you can extend the graphics with your own methods, why don’t you write all of these yourself ?

sub Rotate( extends g as Graphics, angle as double)
end sub

Because it is a core feature in all graphics libraries that Xojo uses, and as I wrote above, Windows implementation is very difficult. Android could also be difficult, as Paul said, it could be difficult to implement declarations in Android.

The iOS framework already supports this. So it is only a matter of bringing these methods to all platforms. They are important when doing graphics programming and have been part of the graphics libraries (CoreGraphics, Cairo and Direct2D) for more than a decade.

2 Likes

Mainly because of the tremendous performance loss introduced by calculating everything on your own. With the AffineTransform, everything is handled hardware-accelerated.

I updated Roger Meier’s dataplot classes once to use Accelerate framework on Mac, and I changed the part of drawing code that could be changed easily to use a declared transform matrix. That made it possible to do almost real-time audio graphics – and if I had updated the parts that are not easy to change, it would have become fully real-time capable. You cannot do that with Xojo code doing the calculations as you proposed.
And because the title of the thread is “What users need today” (well, would have needed yesterday already) – users should have high performance methods on a RAD IDE compiling to native apps, don’t you think?

4 Likes

To be very pedantic here: CoreGraphics is flat API.
So it should be CGContextRotateCTM( context, angle ) not [CGContext rotateBy:]. At least that is what the docs show for me anyway.

Edit: Oh… You’re seeing Apple’s API 2.0…

3 Likes