CairoGraphicsContext.st
changeset 49 5218b606b6cf
parent 48 2a66aee0a9b3
child 50 239120c68187
--- a/CairoGraphicsContext.st	Thu Feb 25 11:08:35 2016 +0000
+++ b/CairoGraphicsContext.st	Fri Feb 26 11:05:14 2016 +0000
@@ -577,6 +577,151 @@
     "Modified: / 21-02-2016 / 15:35:35 / jv"
 ! !
 
+!CairoGraphicsContext methodsFor:'drawing in device coordinates'!
+
+displayDeviceForm:aForm x:x y:y
+    "draw a form or image non opaque (i.e. only foreground color is drawn);
+     If its a 1-plane bitmap, 1-bits are drawn in the
+     current paint-color, leaving pixels with 0-bits unchanged
+     (i.e. only 1-bits are drawn from the form).
+     If its a deep form (i.e. a pixmap) the current paint
+     settings are ignored and the form is drawn as-is;
+     however, the mask is applied if present.
+
+     The form should must have been allocated on the same device,
+     otherwise its converted here, which slows down the draw.
+     No transformation or scaling is done.
+     Care must be taken, that the paint color is correctly allocated
+     (by sending #on: to the color) before doing so.
+     Using functions other than #copy only makes sense if you are
+     certain, that the colors are real colors (actually, only for
+     noColor or allColor)."
+
+    cr notNil ifTrue:[ 
+        cr surface flush.
+    ].
+    super displayDeviceForm:aForm x:x y:y.
+    cr notNil ifTrue:[ 
+        cr surface markDirty.
+    ].
+
+    "Created: / 26-02-2016 / 10:47:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+displayDeviceLineFromX:x0 y:y0 toX:x1 y:y1
+    "draw a line (with current paint-color) in device coordinate space.
+     This ignores any transformations. The coordinates must be integers."
+
+    self deviceCoordinatesDo:[ 
+        self displayLineFromX:x0 y:y0 toX:x1 y:y1
+    ].
+
+    "Created: / 26-02-2016 / 10:32:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+displayDeviceOpaqueForm:aForm x:x y:y
+    "draw a form or image opaque (i.e. both fg and bg is drawn);
+     If its a 1-plane bitmap, 1-bits are drawn in the
+     current paint-color and 0-bits in the bgPaint color.
+     If its a deep form (i.e. a pixmap) the current paint/bgPaint
+     settings are ignored and the form drawn as-is.
+     Any mask is ignored.
+     In the 1-plane case, special care must be taken if paint and/or bgPaint
+     dithered colors or patterns, since are that the colors are correctly allocated (by sending #on:
+     to the colors) before doing so.
+     The form should have been allocated on the same device; otherwise,
+     its converted here, which slows down the draw.
+     Drawing is in device coordinates; no scaling is done."
+
+    cr notNil ifTrue:[ 
+        cr surface flush.
+    ].
+    super displayDeviceOpaqueForm:aForm x:x y:y.
+    cr notNil ifTrue:[ 
+        cr surface markDirty.
+    ].
+
+    "Created: / 26-02-2016 / 10:47:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+displayDeviceOpaqueString:aString from:index1 to:index2 in:fontToUse x:x y:y
+    "draw a substring at the coordinate x/y - draw foreground pixels in
+     paint-color and background pixels in bgPaint-color.
+     Assuming that device can only draw in device colors, we have to handle
+     the case where paint and/or bgPaint are dithered colors.
+     No translation or scaling is done."
+
+    | savedFont |
+
+    "
+     if backgroundPaint color is nil, we assume
+     this is a non-opaque draw
+    "
+    bgPaint isNil ifTrue:[
+        self displayDeviceString:aString from:index1 to:index2 x:x y:y.
+        ^ self
+    ].
+
+    aString isPlainString ifFalse:[
+        "
+         hook for non-strings (i.e. attributed text)
+         that 'thing' should know how to display itself ...
+        "
+        aString displayOpaqueOn:self x:x y:y from:index1 to:index2.
+        ^ self
+    ].
+
+    self deviceCoordinatesDo:[
+        savedFont := self font.
+        [  
+            self font:fontToUse.
+            self displayOpaqueString:aString from:index1 to:index2 x:x y:y
+        ] ensure:[ 
+            self font: savedFont
+        ].
+    ]
+
+    "Created: / 26-02-2016 / 10:44:55 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+displayDeviceString:aString from:index1 to:index2 in:fontToUse x:x y:y
+    "draw a substring at the coordinate x/y -
+     draw foreground-pixels only (in current paint-color), leaving background as-is.
+     No translation or scaling is done"
+
+    | savedFont |
+
+    "
+     hook for non-strings (i.e. attributed text)
+    "
+    aString isPlainString ifFalse:[
+        ^ aString displayOn:self x:x y:y from:index1 to:index2
+    ].
+
+    self deviceCoordinatesDo:[
+        savedFont := self font.
+        [  
+            self font:fontToUse.
+            self displayString:aString from:index1 to:index2 x:x y:y
+        ] ensure:[ 
+            self font: savedFont
+        ].
+    ]
+
+    "Created: / 26-02-2016 / 10:45:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+fillDeviceRectangleX:x y:y width:w height:h
+    "draw a filled rectangle in device coordinate space.
+     This ignores any transformations. The coordinates must be integers."
+
+    self deviceCoordinatesDo:[ 
+        self fillRectangleX:x y:y width:w height:h
+    ].
+
+    "Created: / 26-02-2016 / 10:29:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !CairoGraphicsContext methodsFor:'filling'!
 
 fillRoundRectangleX:x y:y width:w height:h wCorner:wCorn hCorner:hCorn
@@ -734,6 +879,21 @@
     "Created: / 12-02-2016 / 17:03:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
+!CairoGraphicsContext methodsFor:'private'!
+
+deviceCoordinatesDo: aBlock
+    "Evaluate a block using device coordinates (device 
+     space using Cairo terminology)"
+
+    | savedTransformation |
+
+    savedTransformation := transformation.
+    self transformation: nil.
+    aBlock ensure:[ self transformation: savedTransformation ].
+
+    "Created: / 26-02-2016 / 09:29:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !CairoGraphicsContext class methodsFor:'documentation'!
 
 version