pharo-graphics / Alexandrie

FFI bindings and a 2D canvas for Pharo based on Cairo, Freetype and Harfbuzz
MIT License
5 stars 2 forks source link

API: focalPoint information is missing for canvas setSourceRadialPatternStops:center:radius:message #25

Closed rvillemeur closed 11 months ago

rvillemeur commented 1 year ago

Radial pattern should have 3 parameters:

The third one is missing in the API. As the API exist, It can only display circle with gradient color. The focal point allow to display something more like a half-ellipse with gradient color.

To illustrate this, here is a short example in Athens:

    | surface |
    surface := AthensCairoSurface extent: 200 @ 200.

    surface drawDuring: [ :canvas |
        surface clear: (Color purple alpha: 0.3).
        "linear gradient fill"
        canvas setPaint:
            ((LinearGradientPaint from: 0 @ 0 to: 100 @ 100) colorRamp: {
                     (0 -> Color white).
                     (1 -> Color black) }).
        canvas drawShape: (0 @ 0 extent: 100 @ 100).

        "plain color fill"
        canvas setPaint: (Color yellow alpha: 0.9).
        canvas drawShape: (100 @ 0 extent: 200 @ 100).

        "Bitmap fill"
        canvas setPaint:
            (PolymorphSystemSettings pharoLogoForm asAthensPaintOn: canvas).
        canvas paintTransform translateX: 0 Y: 135.
        canvas paintTransform scaleBy: 0.25.
        canvas drawShape: (0 @ 100 extent: 100 @ 200).

        "Radial gradient fill"
        canvas paintTransform loadIdentity.
        canvas setPaint: (RadialGradientPaint new
                 colorRamp: {
                         (0 -> Color white).
                         (1 -> Color black) };
                 center: 150 @ 150;
                 radius: 50;
                 focalPoint: 180 @ 180).
        canvas drawShape: (100 @ 100 extent: 200 @ 200) ].
    ^ surface asForm

A similar result in Alexandrie

    | canvas form |
    canvas := AeCanvas extent: 200 @ 200.

    canvas clear: (Color purple alpha: 0.3).
    "linear gradient fill"
    canvas pathFactory: [ :cairoContext |
        cairoContext rectangleTo: 100 @ 100 ].
    canvas setBackgroundWith: [
        canvas
            setSourceLinearPatternStops: {
                    (0 -> Color white).
                    (1 -> Color black) }
            start: 0 @ 0
            end: 100 @ 100 ].
    canvas setBorderOff.
    canvas drawFigure.

    "plain color fill"
    canvas pathFactory: [ :cairoContext |
        cairoContext rectangleTo: 100 @ 100 ].
    canvas pathTranslate: 100 @ 0.
    canvas setBackgroundWith: [
        canvas setSourceColor: (Color yellow alpha: 0.9) ].
    canvas setBorderOff.
    canvas drawFigure.

    "Bitmap fill"
    form := PolymorphSystemSettings pharoLogoForm.
    canvas pathFactory: [ :cairoContext |
        cairoContext rectangleTo: form extent ].
    canvas
        pathTranslate: -100 @ 0135;
        pathScale: 0.25 @ 0.25.
    canvas setBackgroundWithForm: form alpha: 1.0.
    canvas setBorderOff.
    canvas drawFigure.

    "Radial gradient fill"
    canvas pathFactory: [ :cairoContext |
        cairoContext rectangleTo: 100 @ 100 ].
    canvas setBackgroundWith: [
        canvas
            setSourceRadialPatternStops: {
                    (0 -> Color white).
                    (1 -> Color black) }
            center: 50 @ 50
            radius: 50 ].
    canvas
        pathTranslate: 400 @ -135;
        pathScale: 4 @ 4.
    canvas setBorderOff.
    canvas drawFigure.
    ^ canvas asForm

The radial pattern cannot be completed in its current API state...

Note Explanation how to do this explained here: discord example

tinchodias commented 1 year ago

I'm sorry, somehow I missed the notification about your issue. Thank you for you question. I hope my answer at Discord was useful. Don't hesitate to create more issues or ask at the channel. Martín

On 24-02-2023, at 13:26, RB @.***> wrote:

Closed #25 https://github.com/pharo-graphics/Alexandrie/issues/25 as completed.

— Reply to this email directly, view it on GitHub https://github.com/pharo-graphics/Alexandrie/issues/25#event-8603628651, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAXHHKIJVQUPWVEM3LECU6LWZDOJ5ANCNFSM6AAAAAAVDYLYYU. You are receiving this because you are subscribed to this thread.

rvillemeur commented 1 year ago

Hi

I feel I need to reopen this issue. Sure, I understand that AeCanvas is higher level than AeCairo. However, I can't understand why in AeCanvas >> setSourceRadialPatternStops: aCollection center: aPoint radius: aNumber, innerCenter is the same as outerCenter. That make a figure like the one attached impossible to draw.

RadialGradient

AeCanvas >> setSourceRadialPatternStops: aCollection center: aPoint radius: aNumber,
| aPattern |
  aPattern := AeCairoRadialGradientPattern
      **innerCenter: aPoint**
      innerRadius: 0
      **outerCenter: aPoint**
      outerRadius: aNumber
      addStopsFrom: aCollection.

  cairoContext source: aPattern.

It require one inner center and one outer center

| surface context gradient form |
surface := AeCairoImageSurface
               extent: 100 @ 100
               format: AeCairoSurfaceFormat argb32.
context := surface newContext.

"Radial gradient fill"
gradient := AeCairoRadialGradientPattern
                **innerCenter: 50 @ 50**
                innerRadius: 50
                **outerCenter: 80 @ 80**
                outerRadius: 0
                addStopsFrom: {
                        (0 -> Color black).
                        (1 -> Color white) }.

context
    rectangleTo: 100 @ 100;
    source: gradient.

context fill.

^ surface asForm

Linear Gradient is correctly available, and I can't find any good reason why radial gradient is limited to circle only.

tinchodias commented 1 year ago

+1 AeCanvas and all the codebase is in evolution.

Would you like to submit a PR? else, at some point I can do it, no problem.

tinchodias commented 1 year ago

Quite probably, this reduced API is driven by Bloc needs. Cairo allows much more than what's exposed in AeCanvas. For example https://github.com/pharo-graphics/Bloc/issues/191 requested conical layout (and @labordep also by email). This is supported by cairo patches as in AeCairoMigratedRenderTest>>#surfaceWithMeshPatternConical.

Another example, but it's not reported as issue AFAIR, is adding in Bloc image background the possibility to repeat, to create a pattern. Like:

image

Source: https://stackoverflow.com/questions/28755265/cairo-fill-a-polygon-with-a-hatch-pattern

labordep commented 1 year ago

@tinchodias your example interest me :D I would like to have this functionality in Bloc, this is available ?

tinchodias commented 1 year ago

@labordep the pattern? I reported it in https://github.com/pharo-graphics/Bloc/issues/334 we have to define what's the Bloc API to set it, and at low level it seems simple.

I just created also a separate issue in Bloc, for the conical gradient: https://github.com/pharo-graphics/Bloc/issues/333

Maybe somebody wants to pick them and push PRs 😜 okay or I do it at some point

labordep commented 1 year ago

Thanks for the issue !

rvillemeur commented 1 year ago

What would be the best: Change existing API (we're not stable yet), or extend it ?

tinchodias commented 1 year ago

@rvillemeur For AeCanvas in general I'd go for changing existing API, always that it doesn't imply any potential performance slowdown, like having to create new instances, doing extra maths.

rvillemeur commented 1 year ago

I wanted to update bloc as well, but It changed so many different things, I don't understand why. for example, changing from { #category : 'accessing' } to { #category : #accessing } in all Bloc :-(. Any hints ?

labordep commented 1 year ago

@rvillemeur this is due to pharo 12 changes in the code format. Use pharo 11 if you don't have these changes.

More details on the discord:

https://discord.com/channels/223421264751099906/278558427796602882/1152598669191819268

rvillemeur commented 1 year ago

I did the change in Pharo 11. I'll do it again. probably tomorrow.

tinchodias commented 1 year ago

Hm, I also suspect it can be related to the new Tonel v3 format. Dont know if this impacts in Pharo 11 too. Pierre, didn't you you have some issue with Windows and Iceberg?

labordep commented 1 year ago

No problem on Pharo 11. We had a problem with the EOL character but not with Tonel. The new Tonel format is concerning Pharo 12 only I think.

tinchodias commented 1 year ago

@rvillemeur how did you avoid the noise lines? I'm having that problem too in https://github.com/pharo-graphics/Bloc/pull/346

rvillemeur commented 1 year ago

Hi @tinchodias, Thanks for your update on Tonel V1 vs V3. That was really making a lot of noise in the commit. One quick question. My initial request was on AeCanvas. Should we do something as well for BlRadialGradientPaint ? As of today, it only accept center and radius, as it was in original AeCanvas API. Do you think it should better reflect the innerCenter, innerRadius, outerCenter, outerRadius parameters ?

tinchodias commented 1 year ago

Hi @rvillemeur good idea on adding that to BlRadialGradientPaint's API. The default values can be backwards compatible.

tinchodias commented 1 year ago

Should we close this issue @rvillemeur ?

rvillemeur commented 11 months ago

Thanks for taking in account this change.