class: DeviceGraphicsContext
changed: #displayString:from:to:x:y:opaque:
don't crash when an alien font (aka: an XftFont) wants to draw
with bg or fg being an image or form.
For now: ignore the draw; todo: fix and fill rectangle.
--- a/DeviceGraphicsContext.st Thu Nov 27 00:52:54 2014 +0100
+++ b/DeviceGraphicsContext.st Thu Nov 27 00:54:13 2014 +0100
@@ -1800,46 +1800,55 @@
this is a non-opaque draw
"
bgPaint isNil ifTrue:[
- opaque := false.
+ opaque := false.
].
(aString isString not or:[aString isText]) ifTrue:[
- "
- hook for non-strings (i.e. attributed text)
- that 'thing' should know how to display itself ...
- "
- aString displayOn:self x:x y:y from:index1 to:index2 opaque:opaque.
- ^ self
+ "
+ hook for non-strings (i.e. attributed text)
+ that 'thing' should know how to display itself ...
+ "
+ aString displayOn:self x:x y:y from:index1 to:index2 opaque:opaque.
+ ^ self
].
font isAlienFont ifTrue:[
- "
- hook for alien fonts
- that 'font' should know how to display the string...
- "
- font displayString:aString from:index1 to:index2 x:x rounded y:y rounded in:self opaque:opaque.
- ^ self
+ "
+ hook for alien fonts
+ that 'font' should know how to display the string...
+ "
+ self backgroundPaint isImage ifTrue:[
+ "/ #todo: fill background rectangle
+ font displayString:aString from:index1 to:index2 x:x rounded y:y rounded in:self opaque:false.
+ ] ifFalse:[
+ self paint isImage ifTrue:[
+ "/ #todo: fill mask rectangle
+ ] ifFalse:[
+ font displayString:aString from:index1 to:index2 x:x rounded y:y rounded in:self opaque:opaque.
+ ].
+ ].
+ ^ self
].
gcId isNil ifTrue:[
- self initGC
+ self initGC
].
fontUsed := font.
transformation notNil ifTrue:[
- pX := transformation applyToX:x.
- pY := transformation applyToY:y.
- transformation noScale ifFalse:[
- sz := font size.
- sz isNil ifTrue:[
- "/ oops - not a real font; use original font
- fontUsed := font
- ] ifFalse:[
- fontUsed := font asSize:(transformation applyScaleY:sz) rounded.
- ]
- ]
+ pX := transformation applyToX:x.
+ pY := transformation applyToY:y.
+ transformation noScale ifFalse:[
+ sz := font size.
+ sz isNil ifTrue:[
+ "/ oops - not a real font; use original font
+ fontUsed := font
+ ] ifFalse:[
+ fontUsed := font asSize:(transformation applyScaleY:sz) rounded.
+ ]
+ ]
] ifFalse:[
- pX := x.
- pY := y.
+ pX := x.
+ pY := y.
].
pX := pX rounded.
pY := pY rounded.
@@ -1850,20 +1859,20 @@
s := aString.
fontsEncoding := fontUsed encoding.
(characterEncoding ~~ fontsEncoding) ifTrue:[
- [
- s := CharacterEncoder encodeString:s from:characterEncoding into:fontsEncoding.
- ] on:CharacterEncoderError do:[:ex|
- "substitute a default value for codes that cannot be represented
- in the new character set"
- ex proceedWith:ex defaultValue.
- ].
+ [
+ s := CharacterEncoder encodeString:s from:characterEncoding into:fontsEncoding.
+ ] on:CharacterEncoderError do:[:ex|
+ "substitute a default value for codes that cannot be represented
+ in the new character set"
+ ex proceedWith:ex defaultValue.
+ ].
].
fontId := fontUsed fontId.
fontId isNil ifTrue:[
- "this should not happen, since #onDevice tries replacement fonts"
- 'STX[DeviceGraphicsContext] no font: ' errorPrint. fontUsed errorPrintCR.
- ^ self
+ "this should not happen, since #onDevice tries replacement fonts"
+ 'STX[DeviceGraphicsContext] no font: ' errorPrint. fontUsed errorPrintCR.
+ ^ self
].
"
@@ -1871,95 +1880,95 @@
"
easy := true.
paint isColor ifFalse:[
- easy := false
+ easy := false
] ifTrue:[
- fgId := paint colorId.
- fgId isNil ifTrue:[
- easy := false
- ]
+ fgId := paint colorId.
+ fgId isNil ifTrue:[
+ easy := false
+ ]
].
opaque ifTrue:[
- bgPaint isColor ifFalse:[
- easy := false
- ] ifTrue:[
- bgId := bgPaint colorId.
- bgId isNil ifTrue:[
- easy := false
- ]
- ].
+ bgPaint isColor ifFalse:[
+ easy := false
+ ] ifTrue:[
+ bgId := bgPaint colorId.
+ bgId isNil ifTrue:[
+ easy := false
+ ]
+ ].
].
deviceFont ~~ fontUsed ifTrue:[
- device setFont:fontId in:gcId.
- deviceFont := fontUsed
+ device setFont:fontId in:gcId.
+ deviceFont := fontUsed
].
"/ check if this string is too long and cut it into a managable size.
"/ this is due to win32 limitations which seems to be unable to handle strings
"/ which are drawn longer than 32k pixels.
(index2 - index1) > 500 ifTrue:[
- nSkipLeft := wSkipLeft := 0.
- wMax := self width.
-
- "/ if the draw starts to the left of the window start,
- "/ skip some characters at the beginning...
- pX < 0 ifTrue:[
+ nSkipLeft := wSkipLeft := 0.
+ wMax := self width.
+
+ "/ if the draw starts to the left of the window start,
+ "/ skip some characters at the beginning...
+ pX < 0 ifTrue:[
"/ ('x=%d wMax=%d l=%d i1=%d i2=%d' printfWith:x with:wMax with:aString size with:index1 with:index2) printCR.
- nSkipLeft := (pX negated // font width) min:index2. "/ estimate
- wSkipLeft := fontUsed widthOf:aString from:index1 to:index1+nSkipLeft-1. "/ actual number of pixels
- [ ((pX+wSkipLeft) > 0) and:[nSkipLeft > 0]] whileTrue:[ "/ too many
- nSkipLeft := (nSkipLeft * 0.9) rounded.
- wSkipLeft := fontUsed widthOf:aString from:index1 to:index1+nSkipLeft-1.
- ].
- index1 := index1 + nSkipLeft.
- pX := pX + wSkipLeft.
+ nSkipLeft := (pX negated // font width) min:index2. "/ estimate
+ wSkipLeft := fontUsed widthOf:aString from:index1 to:index1+nSkipLeft-1. "/ actual number of pixels
+ [ ((pX+wSkipLeft) > 0) and:[nSkipLeft > 0]] whileTrue:[ "/ too many
+ nSkipLeft := (nSkipLeft * 0.9) rounded.
+ wSkipLeft := fontUsed widthOf:aString from:index1 to:index1+nSkipLeft-1.
+ ].
+ index1 := index1 + nSkipLeft.
+ pX := pX + wSkipLeft.
"/ ('skip %d w=%d x=%d' printfWith:nSkipLeft with:wSkipLeft with:x) printCR.
- ].
-
- "/ if the draw ends to the right of the window ends,
- "/ skip some characters at the end...
- nChars := wMax // font width + 2. "/ estimate
- index2Guess := (index1+nChars-1) min:index2.
- wString := fontUsed widthOf:aString from:index1 to:index2Guess. "/ actual number of pixels
+ ].
+
+ "/ if the draw ends to the right of the window ends,
+ "/ skip some characters at the end...
+ nChars := wMax // font width + 2. "/ estimate
+ index2Guess := (index1+nChars-1) min:index2.
+ wString := fontUsed widthOf:aString from:index1 to:index2Guess. "/ actual number of pixels
"/ ('n=%d w=%d' printfWith:nChars with:wString) printCR.
- [ ((pX+wString) < wMax) and:[ index2Guess < index2] ] whileTrue:[ "/ not enough...
- nChars := (nChars * 1.1) rounded.
- index2Guess := (index1+nChars-1) min:index2.
- wString := fontUsed widthOf:aString from:index1 to:index2Guess.
- ].
+ [ ((pX+wString) < wMax) and:[ index2Guess < index2] ] whileTrue:[ "/ not enough...
+ nChars := (nChars * 1.1) rounded.
+ index2Guess := (index1+nChars-1) min:index2.
+ wString := fontUsed widthOf:aString from:index1 to:index2Guess.
+ ].
"/ ('n=%d w=%d' printfWith:nChars with:wString) printCR.
- index2 := index2Guess.
+ index2 := index2Guess.
].
easy ifTrue:[
- opaque ifTrue:[
- device setForeground:fgId background:bgId in:gcId.
- background := bgPaint.
- ] ifFalse:[
- device setForeground:fgId in:gcId.
- ].
- foreground := paint.
- device displayString:s from:index1 to:index2 x:pX y:pY in:drawableId with:gcId opaque:opaque.
- ^ self
+ opaque ifTrue:[
+ device setForeground:fgId background:bgId in:gcId.
+ background := bgPaint.
+ ] ifFalse:[
+ device setForeground:fgId in:gcId.
+ ].
+ foreground := paint.
+ device displayString:s from:index1 to:index2 x:pX y:pY in:drawableId with:gcId opaque:opaque.
+ ^ self
].
w := fontUsed widthOf:s from:index1 to:index2.
h := fontUsed height.
(fgId notNil and:[function == #copy]) ifTrue:[
- "
- only bg is dithered or a pattern; fill with bg first ...
- "
- savedPaint := paint.
- self paint:bgPaint.
- self fillDeviceRectangleX:pX y:(pY - fontUsed ascent) width:w height:h.
- self paint:savedPaint.
-
- "
- then draw using fgPaint (which is a real color)
- "
- device displayString:s from:index1 to:index2 x:pX y:pY in:drawableId with:gcId opaque:false.
- ^ self
+ "
+ only bg is dithered or a pattern; fill with bg first ...
+ "
+ savedPaint := paint.
+ self paint:bgPaint.
+ self fillDeviceRectangleX:pX y:(pY - fontUsed ascent) width:w height:h.
+ self paint:savedPaint.
+
+ "
+ then draw using fgPaint (which is a real color)
+ "
+ device displayString:s from:index1 to:index2 x:pX y:pY in:drawableId with:gcId opaque:false.
+ ^ self
].
"/ the very hard case (fg-dither)
@@ -4133,11 +4142,11 @@
!DeviceGraphicsContext class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview/DeviceGraphicsContext.st,v 1.143 2014-11-23 15:53:27 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview/DeviceGraphicsContext.st,v 1.144 2014-11-26 23:54:13 cg Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libview/DeviceGraphicsContext.st,v 1.143 2014-11-23 15:53:27 cg Exp $'
+ ^ '$Header: /cvs/stx/stx/libview/DeviceGraphicsContext.st,v 1.144 2014-11-26 23:54:13 cg Exp $'
! !