Questions concerning SymbolicPaint

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Questions concerning SymbolicPaint

Joachim Geidel
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

ws.png (17K) Download Attachment
ws2.png (37K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Questions concerning SymbolicPaint

Andre Schnoor
Joachim,

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
Reply | Threaded
Open this post in threaded view
|

Re: Questions concerning SymbolicPaint

Joachim Geidel
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

Reply | Threaded
Open this post in threaded view
|

Re: Questions concerning SymbolicPaint

Andre Schnoor
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