Hello everybody,
I need some help from the graphics experts among you. In CairoGraphics-Wrappers, I want to be able to set the paint of a CairoGraphicsContext to a SymbolicPaint. However, for a CairoContext, I have to convert it into a ColorValue or a Pattern. The code I have written is: ------ CairoGraphicsContext>>paint: paintValue "Set the paint to paintValue." self flushPendingOutput. (paintValue isKindOf: SymbolicPaint) ifTrue: [| aPaint | aPaint := paintValue. [aPaint isKindOf: SymbolicPaint] whileTrue: [aPaint := self paintPreferencesMatchAt: aPaint ifAbsent: [^InappropriatePaintError raise]]. super paint: (aPaint isPattern ifTrue: [aPaint] ifFalse: [paintValue asColorValue])] ifFalse: [super paint: paintValue] ------ I know that it's ugly, but I wanted to understand what's happening before refactoring this into something prettier. It seems to work so far, except that sometimes when the SymbolicPaint should be resolved as a Pattern, it seems to result in a ColorValue instead. I see this relatively often when using the code above (see the attachment ws.png, where damage repair results in a solid line instead of a line drawn as a pattern). But it also happens in normal windows with normal GraphicsContexts (see the attachment ws2.png). This is on Windows XP, and it may be platform specific. However, I don't know if this is a side effect of switching between Cairo output and normal VM primitives (even if in this, they are not mixed in the same window). I have two questions: - Has somebody else observed the same graphical errors shown in my screenshots? Is there any reason why the resolution of a SymbolicPaint may change? If not, I will assume for the moment that this is a result of mixing Cairo and VM primitives. - Are there any obvious errors in the above method? - Is it possible that a SymbolicPaint results in a CoverageValue instead of a ColorValue? The class comment mentions ColorValue and Pattern only, but does not explicitly exclude CoverageValue. BTW, just in case you wonder about the gray backgrounds and somewhat unusual look of the separators and border in the toolbar, and the missing shortcut key indicators in the menubar in ws.png: Yes, this window is completely rendered with Cairo. Obviously, CairoGraphics-Wrappers isn't finished yet. :-) Thanks in advance, Joachim Geidel |
I don't know if it might help, but GraphicsContext>>paint: delegates to the argument a message #installOn: self, which in turn either comes back as #setPaintToColor:, #setDevicePattern: or #setDevicePaint: . If CairoGraphicsContext is a subclass of GraphicsContext, you perhaps should hook into these three methods instead of #paint:. Andre Joachim Geidel schrieb: Hello everybody, I need some help from the graphics experts among you. In CairoGraphics-Wrappers, I want to be able to set the paint of a CairoGraphicsContext to a SymbolicPaint. However, for a CairoContext, I have to convert it into a ColorValue or a Pattern. The code I have written is: ------ CairoGraphicsContext>>paint: paintValue "Set the paint to paintValue." self flushPendingOutput. (paintValue isKindOf: SymbolicPaint) ifTrue: [| aPaint | aPaint := paintValue. [aPaint isKindOf: SymbolicPaint] whileTrue: [aPaint := self paintPreferencesMatchAt: aPaint ifAbsent: [^InappropriatePaintError raise]]. super paint: (aPaint isPattern ifTrue: [aPaint] ifFalse: [paintValue asColorValue])] ifFalse: [super paint: paintValue] ------ I know that it's ugly, but I wanted to understand what's happening before refactoring this into something prettier. It seems to work so far, except that sometimes when the SymbolicPaint should be resolved as a Pattern, it seems to result in a ColorValue instead. I see this relatively often when using the code above (see the attachment ws.png, where damage repair results in a solid line instead of a line drawn as a pattern). But it also happens in normal windows with normal GraphicsContexts (see the attachment ws2.png). This is on Windows XP, and it may be platform specific. However, I don't know if this is a side effect of switching between Cairo output and normal VM primitives (even if in this, they are not mixed in the same window). I have two questions: - Has somebody else observed the same graphical errors shown in my screenshots? Is there any reason why the resolution of a SymbolicPaint may change? If not, I will assume for the moment that this is a result of mixing Cairo and VM primitives. - Are there any obvious errors in the above method? - Is it possible that a SymbolicPaint results in a CoverageValue instead of a ColorValue? The class comment mentions ColorValue and Pattern only, but does not explicitly exclude CoverageValue. BTW, just in case you wonder about the gray backgrounds and somewhat unusual look of the separators and border in the toolbar, and the missing shortcut key indicators in the menubar in ws.png: Yes, this window is completely rendered with Cairo. Obviously, CairoGraphics-Wrappers isn't finished yet. :-) Thanks in advance, Joachim Geidel -- Andre Schnoor Cognitone GmbH www.cognitone.com |
Andre,
Andre Schnoor schrieb am 12.09.2007 18:24: > I don't know if it might help, but GraphicsContext>>paint: delegates to the > argument a message #installOn: self, which in turn either comes back as > #setPaintToColor:, #setDevicePattern: or #setDevicePaint: . If > CairoGraphicsContext is a subclass of GraphicsContext, you perhaps should hook > into these three methods instead of #paint:. thanks! That's what I do, and why I call "super paint: paintValue" for everything other than a SymbolicPaint. The problem with SymbolicPaint is that they resolve into a DevicePaint, which only sends #setDevicePaint: to the GraphicsContext, and the argument can be a Pattern or an Integer. What's not immediately clear is the meaning of the Integer, and how I could possibly convert it into a ColorValue. That's why I tried to mimick the way SymbolicPaints are resolved, and replace the SymbolicPaint by the result. Joachim |
Joachim Geidel wrote:
Andre, Andre Schnoor schrieb am 12.09.2007 18:24:I don't know if it might help, but GraphicsContext>>paint: delegates to the argument a message #installOn: self, which in turn either comes back as #setPaintToColor:, #setDevicePattern: or #setDevicePaint: . If CairoGraphicsContext is a subclass of GraphicsContext, you perhaps should hook into these three methods instead of #paint:.thanks! That's what I do, and why I call "super paint: paintValue" for everything other than a SymbolicPaint. The problem with SymbolicPaint is that they resolve into a DevicePaint, which only sends #setDevicePaint: to the GraphicsContext, and the argument can be a Pattern or an Integer. What's not immediately clear is the meaning of the Integer, and how I could possibly convert it into a ColorValue. That's why I tried to mimick the way SymbolicPaints are resolved, and replace the SymbolicPaint by the result. IIRC, the integer is a packed ARGB pixel (32bit). But this is platform and device dependent (hence the name). The VM recognizes whether the device paint is an integer or a display surface (= Pattern) and configures the GC accordingly. Andre |
Free forum by Nabble | Edit this page |