--- a/XftFontDescription.st Thu Oct 01 14:00:15 2015 +0200
+++ b/XftFontDescription.st Fri Oct 02 19:17:42 2015 +0200
@@ -1,3 +1,5 @@
+"{ Encoding: utf8 }"
+
"{ Package: 'stx:libview' }"
"{ NameSpace: Smalltalk }"
@@ -75,19 +77,19 @@
#ifdef XFT
-extern OBJ __GLOBAL_GET_BY_NAME();
+extern OBJ __GLOBAL_GET_BY_NAME(char *);
# define __HANDLE_VAL(type, externalAddress) \
- ((type)__externalAddressVal(externalAddress))
+ ((type)__externalAddressVal(externalAddress))
-# define __HANDLE_NEW(ptr, __cls) \
- ({ \
- OBJ handle; \
- handle = __MKEXTERNALADDRESS(ptr); \
- __InstPtr(handle)->o_class = \
- __GLOBAL_GET_BY_NAME(__cls); \
- handle; \
- })
+# define __HANDLE_NEW(ptr, __cls) \
+ ({ \
+ OBJ handle = __MKEXTERNALADDRESS(ptr); \
+ OBJ clsObj = __GLOBAL_GET_BY_NAME(__cls);\
+ __InstPtr(handle)->o_class = clsObj; \
+ __STORE(handle, clsObj); \
+ handle; \
+ })
@@ -98,9 +100,6 @@
# define VISUAL(x) __HANDLE_VAL(Visual*, x)
# define COLORMAP(x) __HANDLE_VAL(Colormap, x)
-
-
-
/* FontConfig objects */
# define FC_PATTERN(x) __HANDLE_VAL(XftPattern*, x)
# define FC_PATTERN_HANDLE_NEW(x) __HANDLE_NEW(x, "XftFontDescription::FCPatternHandle")
@@ -420,6 +419,19 @@
"Created: / 30-12-2013 / 19:49:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
+!XftFontDescription class methodsFor:'primitives'!
+
+xftAvailable
+%{
+#ifdef XFT
+ RETURN ( true )
+#endif
+%}.
+ ^ false
+
+ "Created: / 20-12-2013 / 21:10:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
!XftFontDescription class methodsFor:'queries'!
listOfAvailableFonts
@@ -547,6 +559,23 @@
"Created: / 02-01-2014 / 23:29:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
+!XftFontDescription methodsFor:'change & update'!
+
+update:anAspect with:something from:changedObject
+ "I want to be informed when a view that printed something with me is destroyed.
+ Disassociate the view from the XFT drawable"
+
+ |drawableId|
+
+ anAspect == #aboutToDestroy ifTrue:[
+ drawableId := changedObject drawableId.
+ drawableId notNil ifTrue:[
+ self disassociateXftDrawableFrom:drawableId.
+ ].
+ changedObject removeDependent:self.
+ ].
+! !
+
!XftFontDescription methodsFor:'converting'!
asNonXftFont
@@ -576,38 +605,38 @@
"limit the string len, otherwise bad output is generated"
stringLen := index2Arg - index1 + 1.
stringLen > 8000 ifTrue:[
- index2 := index1 + 8000 - 1.
+ index2 := index1 + 8000 - 1.
] ifFalse:[
- stringLen <= 0 ifTrue:[^ self].
- index2 := index2Arg.
+ stringLen <= 0 ifTrue:[^ self].
+ index2 := index2Arg.
].
bytesPerCharacter := aString bitsPerCharacter // 8.
transformation := aGC transformation.
clipR := aGC clippingBoundsOrNil.
clipR notNil ifTrue:[
- clipX := clipR left.
- clipY := clipR top.
- clipW := clipR width.
- clipH := clipR height.
- "/ YES YES YES: this MUST be transformed!!
- "/ (see htmlView) fix the notebook, please.
- transformation notNil ifTrue:[
- clipPnt := transformation transformPoint:(clipX @ clipY).
- clipX := clipPnt x ceiling.
- clipY := clipPnt y ceiling.
+ clipX := clipR left.
+ clipY := clipR top.
+ clipW := clipR width.
+ clipH := clipR height.
+ "/ YES YES YES: this MUST be transformed!!
+ "/ (see htmlView) fix the notebook, please.
+ transformation notNil ifTrue:[
+ clipPnt := transformation transformPoint:(clipX @ clipY).
+ clipX := clipPnt x ceiling.
+ clipY := clipPnt y ceiling.
"/ clipX := (transformation applyToX:clipX) ceiling.
"/ clipY := (transformation applyToY:clipY) ceiling.
- ].
+ ].
].
transformation isNil ifTrue:[
- drawX := xArg.
- drawY := yArg.
+ drawX := xArg.
+ drawY := yArg.
] ifFalse:[
- drawPnt := transformation transformPoint:(xArg @ yArg).
- drawX := drawPnt x ceiling.
- drawY := drawPnt y ceiling.
+ drawPnt := transformation transformPoint:(xArg @ yArg).
+ drawX := drawPnt x ceiling.
+ drawY := drawPnt y ceiling.
"/ drawX := (transformation applyToX:xArg) ceiling.
"/ drawY := (transformation applyToY:yArg) ceiling.
].
@@ -615,151 +644,161 @@
fg := aGC paint.
fgPixel := fg colorId.
"/ fgPixel notNil ifTrue:[
- fgR := fg scaledRed.
- fgG := fg scaledGreen.
- fgB := fg scaledBlue.
- fgA := (fg alpha * 65535) rounded.
+ fgR := fg scaledRed.
+ fgG := fg scaledGreen.
+ fgB := fg scaledBlue.
+ fgA := (fg alpha * 65535) rounded.
"/].
fgR isNil ifTrue:[
- "/ when drawing into a pixmap...
- fg colorId == 0 ifTrue:[
- fgR := fgG := fgB := 0.
- ] ifFalse:[
- fgR := fgG := fgB := 16rFFFF.
- ]
+ "/ when drawing into a pixmap...
+ fg colorId == 0 ifTrue:[
+ fgR := fgG := fgB := 0.
+ ] ifFalse:[
+ fgR := fgG := fgB := 16rFFFF.
+ ]
].
opaque ifTrue:[
- bg := aGC backgroundPaint.
- bgPixel := bg colorId.
- "/bgPixel notNil ifTrue:[
- bgR := bg scaledRed.
- bgG := bg scaledGreen.
- bgB := bg scaledBlue.
- bgA := (bg alpha * 65535) rounded.
- "/].
- bgR isNil ifTrue:[
- "/ when drawing into a pixmap...
- bg colorId == 0 ifTrue:[
- bgR := bgG := bgB := 0.
- ] ifFalse:[
- bgR := bgG := bgB := 16rFFFF.
- ]
- ].
+ bg := aGC backgroundPaint.
+ bgPixel := bg colorId.
+ "/bgPixel notNil ifTrue:[
+ bgR := bg scaledRed.
+ bgG := bg scaledGreen.
+ bgB := bg scaledBlue.
+ bgA := (bg alpha * 65535) rounded.
+ "/].
+ bgR isNil ifTrue:[
+ "/ when drawing into a pixmap...
+ bg colorId == 0 ifTrue:[
+ bgR := bgG := bgB := 0.
+ ] ifFalse:[
+ bgR := bgG := bgB := 16rFFFF.
+ ]
+ ].
].
displayId := device displayIdOrErrorIfBroken.
displayId isNil ifTrue:[
- ^ self.
+ ^ self.
].
screen := device screen.
drawableId := aGC drawableId.
+ aGC addDependent:self. "I need to be informed, when the GC is destroyed"
%{
#ifdef XFT
- XftFont *font;
- XftDraw *draw;
XftColor color;
XGlyphInfo extents;
XRectangle clipRX;
- char* string;
+ char *string;
int len;
int __bytesPerCharacter;
+ XftDraw *__sharedDrawId;
+ XftFont *__xftFont = XFT_FONT(__INST(fontId));
if (!(__bothSmallInteger(drawX, drawY)
- && __bothSmallInteger(index1, index2)
- && __isSmallInteger(bytesPerCharacter)
- && (__isSmallInteger(fgPixel) || (__bothSmallInteger(fgR, fgG) && __bothSmallInteger(fgB, fgA)))
- && (opaque == false || __isSmallInteger(bgPixel) || (__bothSmallInteger(bgR, bgG) && __bothSmallInteger(bgB, bgA)))
- && __isNonNilObject(aString)
+ && __bothSmallInteger(index1, index2)
+ && __isSmallInteger(bytesPerCharacter)
+ && (__isSmallInteger(fgPixel) || (__bothSmallInteger(fgR, fgG) && __bothSmallInteger(fgB, fgA)))
+ && (opaque == false || __isSmallInteger(bgPixel) || (__bothSmallInteger(bgR, bgG) && __bothSmallInteger(bgB, bgA)))
+ && __isNonNilObject(aString)
)) {
- goto err;
+ goto err;
}
__bytesPerCharacter = __intVal(bytesPerCharacter);
- if ( __INST(sharedDrawId) == nil ) {
- __INST(sharedDrawId) = XFT_DRAW_HANDLE_NEW ( XftDrawCreate ( DISPLAY( displayId ) ,
- DRAWABLE( drawableId ) ,
- DefaultVisual( DISPLAY( displayId), SCREEN (screen) ) ,
- DefaultColormap( DISPLAY( displayId), SCREEN (screen) ) ) );
- __STORE(self, __INST(sharedDrawId));
+ if (__INST(sharedDrawId) == nil) {
+ __sharedDrawId = XftDrawCreate(DISPLAY(displayId),
+ DRAWABLE(drawableId),
+ DefaultVisual(DISPLAY(displayId), SCREEN(screen)),
+ DefaultColormap(DISPLAY(displayId), SCREEN(screen)));
+ __INST(sharedDrawId) = XFT_DRAW_HANDLE_NEW(__sharedDrawId);
+ __STORE(self, __INST(sharedDrawId));
+ } else if (XftDrawDrawable(__sharedDrawId = XFT_DRAW(__INST(sharedDrawId))) != DRAWABLE(drawableId)) {
+ XftDrawChange(__sharedDrawId, DRAWABLE(drawableId));
}
- if ( XftDrawDrawable ( XFT_DRAW ( __INST(sharedDrawId) ) ) != DRAWABLE( drawableId ) ) {
- XftDrawChange( XFT_DRAW( __INST(sharedDrawId) ) , DRAWABLE( drawableId ) );
- }
-
- string = __stringVal( aString ) + (( __intVal(index1) - 1 ) * __bytesPerCharacter);
+ string = __stringVal(aString) + ((__intVal(index1) - 1 ) * __bytesPerCharacter);
len = __intVal(index2) - __intVal(index1) + 1;
if (clipR != nil) {
- clipRX.x = __intVal(clipX);
- clipRX.y = __intVal(clipY);
- clipRX.width = __intVal(clipW);
- clipRX.height = __intVal(clipH);
- XftDrawSetClipRectangles( XFT_DRAW( __INST( sharedDrawId ) ) , 0, 0, &clipRX, 1);
+ clipRX.x = __intVal(clipX);
+ clipRX.y = __intVal(clipY);
+ clipRX.width = __intVal(clipW);
+ clipRX.height = __intVal(clipH);
+ XftDrawSetClipRectangles(__sharedDrawId, 0, 0, &clipRX, 1);
} else {
- XftDrawSetClip( XFT_DRAW( __INST( sharedDrawId ) ) , 0);
+ XftDrawSetClip(__sharedDrawId, 0);
}
if (opaque == true) {
- if (bgPixel != nil) {
- color.pixel = (unsigned long)__intVal(bgPixel);
- }
- // else {
- color.color.red = __intVal(bgR);
- color.color.green = __intVal(bgG);
- color.color.blue = __intVal(bgB);
- color.color.alpha = __intVal(bgA);
- // }
- switch (__bytesPerCharacter) {
- case 1:
- XftTextExtents8( DISPLAY( displayId ), XFT_FONT( __INST( fontId ) ), (FcChar8*)string, len, &extents);
- break;
- case 2:
- XftTextExtents16( DISPLAY( displayId ), XFT_FONT( __INST( fontId ) ), (FcChar16*)string, len, &extents);
- break;
- case 4:
- XftTextExtents32( DISPLAY( displayId ), XFT_FONT( __INST( fontId ) ), (FcChar32*)string, len, &extents);
- break;
- }
- XftDrawRect( XFT_DRAW ( __INST( sharedDrawId ) ), &color, __intVal(drawX) - extents.x, __intVal(drawY) - XFT_FONT( __INST( fontId ) )->ascent, extents.width, XFT_FONT(__INST (fontId ) )->height);
+ if (bgPixel != nil) {
+ color.pixel = (unsigned long)__intVal(bgPixel);
+ }
+ // else {
+ color.color.red = __intVal(bgR);
+ color.color.green = __intVal(bgG);
+ color.color.blue = __intVal(bgB);
+ color.color.alpha = __intVal(bgA);
+ // }
+ switch (__bytesPerCharacter) {
+ case 1:
+ XftTextExtents8(DISPLAY(displayId), __xftFont, (FcChar8*)string, len, &extents);
+ break;
+ case 2:
+ XftTextExtents16(DISPLAY(displayId), __xftFont, (FcChar16*)string, len, &extents);
+ break;
+ case 4:
+ XftTextExtents32(DISPLAY(displayId), __xftFont, (FcChar32*)string, len, &extents);
+ break;
+ }
+ XftDrawRect(__sharedDrawId, &color, __intVal(drawX) - extents.x, __intVal(drawY) - __xftFont->ascent, extents.width, __xftFont->height);
}
if (fgPixel != nil) {
- color.pixel = (unsigned long)__intVal(fgPixel);
+ color.pixel = (unsigned long)__intVal(fgPixel);
}
// else {
- color.color.red = __intVal(fgR);
- color.color.green = __intVal(fgG);
- color.color.blue = __intVal(fgB);
- color.color.alpha = __intVal(fgA);
+ color.color.red = __intVal(fgR);
+ color.color.green = __intVal(fgG);
+ color.color.blue = __intVal(fgB);
+ color.color.alpha = __intVal(fgA);
// }
switch (__bytesPerCharacter) {
case 1:
- XftDrawString8( XFT_DRAW ( __INST( sharedDrawId ) ), &color, XFT_FONT( __INST( fontId ) ),
- __intVal(drawX),
- __intVal(drawY),
- (FcChar8*)string,
- len);
- RETURN ( self );
- break;
+ XftDrawString8(__sharedDrawId, &color,__xftFont,
+ __intVal(drawX),
+ __intVal(drawY),
+ (FcChar8*)string,
+ len);
+ break;
+
case 2:
- XftDrawString16( XFT_DRAW ( __INST( sharedDrawId ) ), &color, XFT_FONT( __INST( fontId ) ),
- __intVal(drawX),
- __intVal(drawY),
- (FcChar16*)string,
- len);
- RETURN ( self );
- break;
+ XftDrawString16(__sharedDrawId, &color, __xftFont,
+ __intVal(drawX),
+ __intVal(drawY),
+ (FcChar16*)string,
+ len);
+ break;
+
case 4:
- XftDrawString32( XFT_DRAW ( __INST( sharedDrawId ) ), &color, XFT_FONT( __INST( fontId ) ),
- __intVal(drawX),
- __intVal(drawY),
- (FcChar32*)string,
- len);
- RETURN ( self );
- break;
+ XftDrawString32(__sharedDrawId, &color, __xftFont,
+ __intVal(drawX),
+ __intVal(drawY),
+ (FcChar32*)string,
+ len);
+ break;
+
+ default:
+ goto err;
}
+
+# if 0 // this has been superseeded by receiving change messages on view destroy
+ // Have to disassociate the drawableId - otherwise we get an X11 error 'RenderBadPicture (invalid Picture parameter)'
+ // when the drawable (the window) is destroyed.
+ XftDrawChange(__sharedDrawId, None);
+# endif
+ RETURN(self);
+
err:;
#endif
%}.
@@ -774,8 +813,8 @@
primitiveFailed
<resource: #skipInDebuggersWalkBack>
- self xftAvailable ifFalse:[
- super primitiveFailed:'Xft support is not configured'.
+ self class xftAvailable ifFalse:[
+ super primitiveFailed:'Xft support is not configured'.
].
super primitiveFailed
!
@@ -783,8 +822,8 @@
primitiveFailed:errorString
<resource: #skipInDebuggersWalkBack>
- self xftAvailable ifFalse:[
- super primitiveFailed:'Xft support is not configured'.
+ self class xftAvailable ifFalse:[
+ super primitiveFailed:'Xft support is not configured'.
].
super primitiveFailed:errorString
! !
@@ -941,35 +980,58 @@
!XftFontDescription methodsFor:'primitives'!
-xftAvailable
+disassociateXftDrawableFrom:drawableId
+ "Disassociate the XftDrawable from drawableId.
+ This mist be done before the drawable is destroyed,
+ otherwise the XftDrawable is destroyed together with the drawable,
+ and X11 errors will be signaled."
+
+ | error |
+
%{
#ifdef XFT
- RETURN ( true )
+ if (!__isExternalAddressLike(__INST(sharedDrawId))) {
+ // nothing to disasassociate from...
+ RETURN(self);
+ }
+ if (!__isExternalAddressLike(drawableId)) {
+ error = @symbol(BadArg);
+ goto err;
+ }
+ if (XftDrawDrawable(XFT_DRAW(__INST(sharedDrawId))) == DRAWABLE(drawableId)) {
+ XftDrawChange(XFT_DRAW(__INST(sharedDrawId)), None);
+ }
+ RETURN(self);
+err:;
#endif
%}.
- ^ false
+ self primitiveFailed: error
- "Created: / 20-12-2013 / 21:10:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Created: / 26-12-2013 / 12:17:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
-xftDrawChange: xftDrawId drawable: drawableId
+xftDrawChange:xftDrawId drawable:drawableId
| error |
%{
#ifdef XFT
if ( ! __isExternalAddressLike(xftDrawId) ) {
- error = @symbol(BadArg1);
- goto err;
+ error = @symbol(BadArg1);
+ goto err;
+ }
+ if (drawableId == nil) {
+ XftDrawChange(XFT_DRAW(xftDrawId), None);
+ RETURN (self);
}
if ( ! __isExternalAddressLike(drawableId) ) {
- error = @symbol(BadArg2);
- goto err;
+ error = @symbol(BadArg2);
+ goto err;
}
if (XftDrawDrawable( XFT_DRAW(xftDrawId) ) != DRAWABLE( drawableId ) ) {
- XftDrawChange( XFT_DRAW(xftDrawId) , DRAWABLE( drawableId ) );
+ XftDrawChange( XFT_DRAW(xftDrawId) , DRAWABLE( drawableId ) );
}
- RETURN ( self );
- err:;
+ RETURN (self);
+err:;
#endif
%}.
self primitiveFailed: error
@@ -1771,6 +1833,12 @@
!XftFontDescription methodsFor:'testing'!
+isScaledFont
+ "Xft fonts are always scaled"
+
+ ^ true
+!
+
isUsed
^ sharedDrawId notNil
!
@@ -2094,11 +2162,11 @@
!XftFontDescription class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview/XftFontDescription.st,v 1.70 2015-05-31 09:29:15 cg Exp $'
+ ^ '$Header$'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libview/XftFontDescription.st,v 1.70 2015-05-31 09:29:15 cg Exp $'
+ ^ '$Header$'
! !