Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
rvillemeur opened this issue Feb 22, 2023 · 19 comments

Comments

@rvillemeur
Copy link
Contributor

rvillemeur commented Feb 22, 2023

Radial pattern should have 3 parameters:

  • center
  • radius
  • focalPoint.

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

@rvillemeur rvillemeur changed the title focalPoint is missing for Radial Pattern. API: focalPoint information is missing for canvas setSourceRadialPatternStops:center:radius:message Feb 23, 2023
@tinchodias
Copy link
Contributor

tinchodias commented Feb 27, 2023 via email

@rvillemeur
Copy link
Contributor Author

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.

@rvillemeur rvillemeur reopened this Oct 18, 2023
@tinchodias
Copy link
Contributor

+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
Copy link
Contributor

tinchodias commented Oct 18, 2023

Quite probably, this reduced API is driven by Bloc needs. Cairo allows much more than what's exposed in AeCanvas. For example pharo-graphics/Bloc#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
Copy link

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

@tinchodias
Copy link
Contributor

@labordep the pattern? I reported it in pharo-graphics/Bloc#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: pharo-graphics/Bloc#333

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

@labordep
Copy link

Thanks for the issue !

@rvillemeur
Copy link
Contributor Author

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

@tinchodias
Copy link
Contributor

@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
Copy link
Contributor Author

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
Copy link

labordep commented Oct 20, 2023

@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
Copy link
Contributor Author

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

@tinchodias
Copy link
Contributor

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
Copy link

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
Copy link
Contributor

@rvillemeur how did you avoid the noise lines? I'm having that problem too in pharo-graphics/Bloc#346

@rvillemeur
Copy link
Contributor Author

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
Copy link
Contributor

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

@tinchodias
Copy link
Contributor

Should we close this issue @rvillemeur ?

@rvillemeur
Copy link
Contributor Author

Thanks for taking in account this change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants