XftFontDescription.st
changeset 7114 abb097ba7853
parent 7103 dd61650bbe26
child 7115 f03fcb541d90
--- a/XftFontDescription.st	Thu Jan 28 13:15:16 2016 +0100
+++ b/XftFontDescription.st	Tue Feb 02 12:42:33 2016 +0100
@@ -3,8 +3,7 @@
 "{ NameSpace: Smalltalk }"
 
 FontDescription subclass:#XftFontDescription
-	instanceVariableNames:'device fontId sharedDrawId closestFont minCode maxCode ascent
-		descent height'
+	instanceVariableNames:'device fontId sharedDrawId minCode maxCode ascent descent height'
 	classVariableNames:'FC_FAMILY FC_STYLE FC_SLANT FC_WEIGHT FC_SIZE FC_ASPECT
 		FC_PIXEL_SIZE FC_SPACING FC_FOUNDRY FC_ANTIALIAS FC_HINTING
 		FC_HINT_STYLE FC_VERTICAL_LAYOUT FC_AUTOHINT FC_WIDTH FC_FILE
@@ -110,12 +109,8 @@
 # define XFT_DRAW(x)            __HANDLE_VAL(XftDraw*, x)
 # define XFT_DRAW_HANDLE_NEW(x) __HANDLE_NEW(x, "XftFontDescription::XftDrawHandle")
 
-
 # include <X11/Xft/Xft.h>
-# include <X11/Xft/XftCompat.h>
-
 #endif
-
 %}
 ! !
 
@@ -168,7 +163,7 @@
     "Invoked at system start or when the class is dynamically loaded."
 
     Lobby isNil ifTrue:[
-        Lobby := Registry new.
+	Lobby := Registry new.
     ].
 
     " Taken from fontconfig,h "
@@ -278,28 +273,28 @@
     FC_LCD_LEGACY           := 3.
 
     StXFace2FCWeightMap := Dictionary withKeysAndValues:{
-        'thin'.       FC_WEIGHT_THIN.
-        'extralight'. FC_WEIGHT_EXTRALIGHT.
-        'ultralight'. FC_WEIGHT_ULTRALIGHT.
-        'light'.      FC_WEIGHT_LIGHT.
-        'book'.       FC_WEIGHT_BOOK.
-        'regular'.    FC_WEIGHT_REGULAR.
-        'normal'.     FC_WEIGHT_NORMAL.
-        'medium'.     FC_WEIGHT_MEDIUM.
-        'demibold'.   FC_WEIGHT_DEMIBOLD.
-        'semibold'.   FC_WEIGHT_SEMIBOLD.
-        'bold'.       FC_WEIGHT_BOLD.
-        'extrabold'.  FC_WEIGHT_EXTRABOLD.
-        'ultrabold'.  FC_WEIGHT_ULTRABOLD.
-        'black'.      FC_WEIGHT_BLACK.
-        'heavy'.      FC_WEIGHT_HEAVY.
-        'extrablack'. FC_WEIGHT_EXTRABLACK.
-        'ultrablack'. FC_WEIGHT_ULTRABLACK.
+	'thin'.       FC_WEIGHT_THIN.
+	'extralight'. FC_WEIGHT_EXTRALIGHT.
+	'ultralight'. FC_WEIGHT_ULTRALIGHT.
+	'light'.      FC_WEIGHT_LIGHT.
+	'book'.       FC_WEIGHT_BOOK.
+	'regular'.    FC_WEIGHT_REGULAR.
+	'normal'.     FC_WEIGHT_NORMAL.
+	'medium'.     FC_WEIGHT_MEDIUM.
+	'demibold'.   FC_WEIGHT_DEMIBOLD.
+	'semibold'.   FC_WEIGHT_SEMIBOLD.
+	'bold'.       FC_WEIGHT_BOLD.
+	'extrabold'.  FC_WEIGHT_EXTRABOLD.
+	'ultrabold'.  FC_WEIGHT_ULTRABOLD.
+	'black'.      FC_WEIGHT_BLACK.
+	'heavy'.      FC_WEIGHT_HEAVY.
+	'extrablack'. FC_WEIGHT_EXTRABLACK.
+	'ultrablack'. FC_WEIGHT_ULTRABLACK.
     }.
     StXStyle2FCSlantMap := Dictionary withKeysAndValues:{
-        'roman'.    FC_SLANT_ROMAN.
-        'italic'.   FC_SLANT_ITALIC.
-        'oblique'.  FC_SLANT_OBLIQUE.
+	'roman'.    FC_SLANT_ROMAN.
+	'italic'.   FC_SLANT_ITALIC.
+	'oblique'.  FC_SLANT_OBLIQUE.
     }.
 
     "Modified: / 30-12-2013 / 19:48:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
@@ -314,47 +309,47 @@
     |proto|
 
     RecentlyUsedFonts notNil ifTrue:[
-        proto := RecentlyUsedFonts
-                detect:[:fn |
-                    fn family = familyString
-                    and:[ fn size = size and:[fn sizeUnit = sizeUnit
-                    and:[ fn face = faceString
-                    and:[ (fn style = styleString
-                          or:[ (fn style = 'oblique' and:[styleString = 'italic'])
-                          or:[ (fn style = 'italic' and:[styleString = 'oblique']) ]]) ]]]]]
-                ifNone:nil.
-        proto notNil ifTrue:[
-            ^ proto
-        ].
+	proto := RecentlyUsedFonts
+		detect:[:fn |
+		    fn family = familyString
+		    and:[ fn size = size and:[fn sizeUnit = sizeUnit
+		    and:[ fn face = faceString
+		    and:[ (fn style = styleString
+			  or:[ (fn style = 'oblique' and:[styleString = 'italic'])
+			  or:[ (fn style = 'italic' and:[styleString = 'oblique']) ]]) ]]]]]
+		ifNone:nil.
+	proto notNil ifTrue:[
+	    ^ proto
+	].
     ].
 
     CachedFontList notNil ifTrue:[
-        proto := CachedFontList
-                detect:[:fn |
-                    fn family = familyString
-                    and:[ fn face = faceString
-                    and:[ (fn style = styleString
-                          or:[ (fn style = 'oblique' and:[styleString = 'italic'])
-                          or:[ (fn style = 'italic' and:[styleString = 'oblique']) ]]) ]]]
-                ifNone:nil.
-        proto notNil ifTrue:[
-            ^ (proto shallowCopy)
-                setDevice: nil patternId: nil fontId: nil;
-                family:familyString face:faceString style:styleString size:size sizeUnit:sizeUnit encoding:encoding
-        ].
+	proto := CachedFontList
+		detect:[:fn |
+		    fn family = familyString
+		    and:[ fn face = faceString
+		    and:[ (fn style = styleString
+			  or:[ (fn style = 'oblique' and:[styleString = 'italic'])
+			  or:[ (fn style = 'italic' and:[styleString = 'oblique']) ]]) ]]]
+		ifNone:nil.
+	proto notNil ifTrue:[
+	    ^ (proto shallowCopy)
+		setDevice: nil patternId: nil fontId: nil;
+		family:familyString face:faceString style:styleString size:size sizeUnit:sizeUnit encoding:encoding
+	].
     ].
     ^ super
-        family:familyString face:faceString style:styleString size:size sizeUnit:sizeUnit encoding:encoding
+	family:familyString face:faceString style:styleString size:size sizeUnit:sizeUnit encoding:encoding
 !
 
 for:aFontOrFontDescription
     ^ self
-        family:aFontOrFontDescription family
-        face:aFontOrFontDescription face 
-        style:aFontOrFontDescription style 
-        size:aFontOrFontDescription size 
-        sizeUnit:#pt 
-        encoding:aFontOrFontDescription encoding
+	family:aFontOrFontDescription family
+	face:aFontOrFontDescription face
+	style:aFontOrFontDescription style
+	size:aFontOrFontDescription size
+	sizeUnit:#pt
+	encoding:aFontOrFontDescription encoding
 !
 
 new
@@ -368,9 +363,9 @@
      Have to disassociate the XftDrawId from  the drawableId aWindowId"
 
     Lobby do:[:eachXftFont|
-        eachXftFont graphicsDevice == aDevice ifTrue:[
-            eachXftFont disassociateXftDrawableFrom:aWindowId.
-        ].
+	eachXftFont graphicsDevice == aDevice ifTrue:[
+	    eachXftFont disassociateXftDrawableFrom:aWindowId.
+	].
     ].
 ! !
 
@@ -573,6 +568,10 @@
     ^ fontId
 
     "Created: / 02-01-2014 / 23:29:04 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+setFontId:fontIdArg
+    fontId := fontIdArg.
 ! !
 
 !XftFontDescription methodsFor:'change & update'!
@@ -585,8 +584,8 @@
 
     anAspect == #aboutToDestroy ifTrue:[
         drawableId := changedObject drawableId.
-        drawableId notNil ifTrue:[
-            self disassociateXftDrawableFrom:drawableId.
+        (sharedDrawId notNil and:[drawableId notNil]) ifTrue:[
+            sharedDrawId disassociateFrom:drawableId.
         ].
         changedObject removeDependent:self.
     ].
@@ -616,35 +615,35 @@
     |index2 bytesPerCharacter transformation
      clipOrg clipCorn clipRect clipX clipY clipW clipH clipPnt
      fg fgR fgG fgB fgA fgPixel bg bgR bgG bgB bgA bgPixel
-     drawX drawY drawPnt displayId screen drawableId error stringLen 
+     drawX drawY drawPnt displayId screen drawableId error stringLen
      newXftDrawId newDrawableAssociation pixmapDepth|
 
     "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.
 
     clipRect := aGC deviceClippingRectangle.
     clipRect notNil ifTrue:[
-        clipX := clipRect left.
-        clipY := clipRect top.
-        clipW := clipRect width.
-        clipH := clipRect height.
+	clipX := clipRect left.
+	clipY := clipRect top.
+	clipW := clipRect width.
+	clipH := clipRect height.
     ].
 
     transformation := aGC transformation.
     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.
     ].
 
     fg  := aGC paint.
@@ -654,45 +653,45 @@
     fgA := fg scaledAlpha.
 
     fgR isNil ifTrue:[
-        "/ when drawing into a pixmap...
-        fgPixel := fg colorId.
-        fgPixel == 0 ifTrue:[
-            fgR := fgG := fgB := 0.
-        ] ifFalse:[
-            fgR := fgG := fgB := 16rFFFF.
-        ]
+	"/ when drawing into a pixmap...
+	fgPixel := fg colorId.
+	fgPixel == 0 ifTrue:[
+	    fgR := fgG := fgB := 0.
+	] ifFalse:[
+	    fgR := fgG := fgB := 16rFFFF.
+	]
     ].
 
     opaque ifTrue:[
-        bg := aGC backgroundPaint.
-        bg isColor ifTrue:[
-            bgR := bg scaledRed.
-            bgG := bg scaledGreen.
-            bgB := bg scaledBlue.
-            bgA := bg scaledAlpha.
-        ] ifFalse:[
-            "images are not yet implemented"
-            "/ #todo: fill background rectangle
-            bgR := bgG := bgB := bgA := 16rFFFF.
-        ].
-        bgR isNil ifTrue:[
-            "/ when drawing into a pixmap...
-            bgPixel := bg colorId.
-            bgPixel == 0 ifTrue:[
-                bgR := bgG := bgB := 0.
-            ] ifFalse:[
-                bgR := bgG := bgB := 16rFFFF.
-            ]
-        ].
+	bg := aGC backgroundPaint.
+	bg isColor ifTrue:[
+	    bgR := bg scaledRed.
+	    bgG := bg scaledGreen.
+	    bgB := bg scaledBlue.
+	    bgA := bg scaledAlpha.
+	] ifFalse:[
+	    "images are not yet implemented"
+	    "/ #todo: fill background rectangle
+	    bgR := bgG := bgB := bgA := 16rFFFF.
+	].
+	bgR isNil ifTrue:[
+	    "/ when drawing into a pixmap...
+	    bgPixel := bg colorId.
+	    bgPixel == 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 isForm ifTrue:[
-        pixmapDepth := aGC depth.
+	pixmapDepth := aGC depth.
     ].
 
 %{
@@ -707,76 +706,76 @@
     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)
     )) {
-        error = @symbol(badArgument);
-        goto out;
+	error = @symbol(badArgument);
+	goto out;
     }
 
     __bytesPerCharacter = __intVal(bytesPerCharacter);
 
     if (pixmapDepth != nil) {
-        int __pixmapDepth = __intVal(pixmapDepth);
+	int __pixmapDepth = __intVal(pixmapDepth);
 
-        if (__pixmapDepth == 1) {
-            __sharedDrawId = XftDrawCreateBitmap(DISPLAY(displayId), DRAWABLE(drawableId));
-        } else {
-            __sharedDrawId = XftDrawCreateAlpha(DISPLAY(displayId), DRAWABLE(drawableId), __pixmapDepth);
-        }
+	if (__pixmapDepth == 1) {
+	    __sharedDrawId = XftDrawCreateBitmap(DISPLAY(displayId), DRAWABLE(drawableId));
+	} else {
+	    __sharedDrawId = XftDrawCreateAlpha(DISPLAY(displayId), DRAWABLE(drawableId), __pixmapDepth);
+	}
     } else {
-        if (__INST(sharedDrawId) == nil) {
-            __sharedDrawId = XftDrawCreate(DISPLAY(displayId),
-                                           DRAWABLE(drawableId),
-                                           DefaultVisual(DISPLAY(displayId), SCREEN(screen)),
-                                           DefaultColormap(DISPLAY(displayId), SCREEN(screen)));
-            __INST(sharedDrawId) = newXftDrawId = XFT_DRAW_HANDLE_NEW(__sharedDrawId);
-            __STORE(self, __INST(sharedDrawId));
-        } else if (XftDrawDrawable(__sharedDrawId = XFT_DRAW(__INST(sharedDrawId))) != DRAWABLE(drawableId)) {
-            XftDrawChange(__sharedDrawId, DRAWABLE(drawableId));
-        }
+	if (__INST(sharedDrawId) == nil) {
+	    __sharedDrawId = XftDrawCreate(DISPLAY(displayId),
+					   DRAWABLE(drawableId),
+					   DefaultVisual(DISPLAY(displayId), SCREEN(screen)),
+					   DefaultColormap(DISPLAY(displayId), SCREEN(screen)));
+	    __INST(sharedDrawId) = newXftDrawId = XFT_DRAW_HANDLE_NEW(__sharedDrawId);
+	    __STORE(self, __INST(sharedDrawId));
+	} else if (XftDrawDrawable(__sharedDrawId = XFT_DRAW(__INST(sharedDrawId))) != DRAWABLE(drawableId)) {
+	    XftDrawChange(__sharedDrawId, DRAWABLE(drawableId));
+	}
     }
 
     string = __stringVal(aString) + ((__intVal(index1) - 1 ) * __bytesPerCharacter);
     len = __intVal(index2) - __intVal(index1) + 1;
 
     if (clipRect != nil) {
-        clipRX.x = __intVal(clipX);
-        clipRX.y = __intVal(clipY);
-        clipRX.width = __intVal(clipW);
-        clipRX.height = __intVal(clipH);
-        XftDrawSetClipRectangles(__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(__sharedDrawId, 0);
+	XftDrawSetClip(__sharedDrawId, 0);
     }
 
     if (opaque == true) {
-        if (bgPixel != nil) {
-            color.pixel = (unsigned long)__intVal(bgPixel);
-        }
-        color.color.red = __intVal(bgR);
-        color.color.green = __intVal(bgG);
-        color.color.blue = __intVal(bgB);
-        color.color.alpha = __intVal(bgA);
+	if (bgPixel != nil) {
+	    color.pixel = (unsigned long)__intVal(bgPixel);
+	}
+	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);
+	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);
     }
     color.color.red = __intVal(fgR);
     color.color.green = __intVal(fgG);
@@ -785,36 +784,36 @@
 
     switch (__bytesPerCharacter) {
     case 1:
-        XftDrawString8(__sharedDrawId, &color,__xftFont,
-                        __intVal(drawX),
-                        __intVal(drawY),
-                        (FcChar8*)string,
-                        len);
-        break;
+	XftDrawString8(__sharedDrawId, &color,__xftFont,
+			__intVal(drawX),
+			__intVal(drawY),
+			(FcChar8*)string,
+			len);
+	break;
 
     case 2:
-        XftDrawString16(__sharedDrawId, &color, __xftFont,
-                        __intVal(drawX),
-                        __intVal(drawY),
-                        (FcChar16*)string,
-                        len);
-        break;
+	XftDrawString16(__sharedDrawId, &color, __xftFont,
+			__intVal(drawX),
+			__intVal(drawY),
+			(FcChar16*)string,
+			len);
+	break;
 
     case 4:
-        XftDrawString32(__sharedDrawId, &color, __xftFont,
-                        __intVal(drawX),
-                        __intVal(drawY),
-                        (FcChar32*)string,
-                        len);
-        break;
+	XftDrawString32(__sharedDrawId, &color, __xftFont,
+			__intVal(drawX),
+			__intVal(drawY),
+			(FcChar32*)string,
+			len);
+	break;
 
     default:
-        error = @symbol(invalidStringSize);
-        goto out;
+	error = @symbol(invalidStringSize);
+	goto out;
     }
 
     if (pixmapDepth != nil) {
-        XftDrawDestroy(__sharedDrawId);
+	XftDrawDestroy(__sharedDrawId);
     }
 
 # if 0 // this has been superseeded by receiving change messages on view destroy
@@ -826,10 +825,10 @@
 #endif
 %}.
     error notNil ifTrue:[
-        self primitiveFailed: error.
+	self primitiveFailed: error.
     ].
     newXftDrawId notNil ifTrue:[
-        Lobby register:self.
+	Lobby register:self.
     ].
     "Created: / 21-12-2013 / 21:11:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified: / 10-01-2014 / 11:13:56 / Jan Vrany <jan.vrany@fit.cvut.cz>"
@@ -841,7 +840,7 @@
     <resource: #skipInDebuggersWalkBack>
 
     self class xftAvailable ifFalse:[
-        super primitiveFailed:'Xft support is not configured'.
+	super primitiveFailed:'Xft support is not configured'.
     ].
     super primitiveFailed
 !
@@ -850,7 +849,7 @@
     <resource: #skipInDebuggersWalkBack>
 
     self class xftAvailable ifFalse:[
-        super primitiveFailed:'Xft support is not configured'.
+	super primitiveFailed:'Xft support is not configured'.
     ].
     super primitiveFailed:errorString
 ! !
@@ -862,7 +861,10 @@
 !
 
 finalize
-    self xftDrawDestroy
+    sharedDrawId notNil ifTrue:[
+        sharedDrawId destroy.
+        sharedDrawId := nil.
+    ].
 ! !
 
 !XftFontDescription methodsFor:'getting a device font'!
@@ -871,20 +873,24 @@
     "Create a new XftFont representing the closes font as
      myself on aDevice; if one already exists, return the one."
 
-    | myPatternId closestPatternId1 closestPatternId2 newFontId |
+    ^ self onDevice:aGraphicsDevice ifAbsent:nil
+!
+
+onDevice:aGraphicsDevice ifAbsent:aBlock
+    "Create a new XftFont representing the closes font as
+     myself on aDevice; if one already exists, return the one."
 
-    "if I am already assigned to that device ..."
-    (device == aGraphicsDevice) ifTrue:[^ self].
+    |displayId myPatternHandle closestPatternHandle newFontId|
 
-    (aGraphicsDevice isNil and:[device notNil]) ifTrue:[
+    (device == aGraphicsDevice) ifTrue:[
+        "I am already assigned to that device ..."
+        ^ self
+    ].
+    aGraphicsDevice isNil ifTrue:[
         ^ self
     ].
     aGraphicsDevice supportsXFTFonts ifFalse:[
-        ^ super onDevice:aGraphicsDevice
-    ].
-
-    (closestFont notNil and:[closestFont graphicsDevice == aGraphicsDevice]) ifTrue:[
-        ^ closestFont onDevice: aGraphicsDevice.
+        ^ super onDevice:aGraphicsDevice ifAbsent:aBlock.
     ].
 
     RecentlyUsedFonts isNil ifTrue:[
@@ -894,7 +900,7 @@
     RecentlyUsedFonts keysAndValuesDo:[:index :aFont |
         ((aFont class == self class) and:[(self sameDeviceFontAs:aFont) and:[aFont getFontId notNil]]) ifTrue:[
             "/ Transcript showCR:'hit'.
-            RecentlyUsedFonts 
+            RecentlyUsedFonts
                 removeIndex:index;
                 addFirst:aFont.
             ^ aFont
@@ -912,70 +918,40 @@
         ].
     ].
 
+"/    ^ self asNonXftFont onDevice:aGraphicsDevice.
     [
-        Error handle:[:ex |
-            ^ self asNonXftFont onDevice:aGraphicsDevice
-        ] do:[
-            myPatternId := self xftPatternCreate.
-        ].
-        self xftPatternAdd: myPatternId attribute: FC_FAMILY  value: family.
+        myPatternHandle := FCPatternHandle create.
+        myPatternHandle
+            add:FC_FOUNDRY value:manufacturer ? 'unknown';
+            add:FC_FAMILY value:family;
+            add:FC_WEIGHT value:(StXFace2FCWeightMap at:(face ? 'regular') asLowercase);
+            add:FC_SLANT value:(StXStyle2FCSlantMap at:(style ? 'roman') asLowercase).
         sizeUnit = #px ifTrue:[
-            self xftPatternAdd: myPatternId attribute: FC_PIXEL_SIZE value: (pixelSize isNil ifTrue:[nil] ifFalse:[pixelSize rounded]).
-        ] ifFalse:[
-            self xftPatternAdd: myPatternId attribute: FC_SIZE value: (size isNil ifTrue:[nil] ifFalse:[size rounded]).
-        ].
-        self 
-            xftPatternAdd: myPatternId attribute: FC_WEIGHT value: (StXFace2FCWeightMap at: (face ? 'regular'));
-            xftPatternAdd: myPatternId attribute: FC_SLANT value: (StXStyle2FCSlantMap at: (style ? 'roman') ifAbsent:[StXStyle2FCSlantMap at: (style ? 'roman') asLowercase]).
-
-        newFontId := self xftFontOpenPattern: aGraphicsDevice displayId pattern: myPatternId.
-        newFontId notNil ifTrue:[
-            "/ Good, this font exists!!
-            myPatternId := nil.
-            fontId := newFontId.
-            device := aGraphicsDevice.
-            aGraphicsDevice registerFont:self.
-            RecentlyUsedFonts addFirst:self.
-            ^ self.
+            myPatternHandle add:FC_PIXEL_SIZE value:(pixelSize isNil ifTrue:[nil] ifFalse:[pixelSize rounded]).
         ] ifFalse:[
-            closestPatternId1 := self xftFontMatch: aGraphicsDevice displayId screen: aGraphicsDevice screen pattern: myPatternId.
-            closestPatternId1 isNil ifTrue:[
-                self error: 'No font matches'.
-            ].
-            "
-            self xftPatternGet: closestPatternId attribute: 'family' index: 0.
-            self xftPatternGet: closestPatternId attribute: 'size' index: 0.
-            "
-            closestPatternId2 := self xftPatternDuplicate: closestPatternId1.
-            newFontId := self xftFontOpenPattern: aGraphicsDevice displayId pattern: closestPatternId1.
-            "/ !!!!!!!! closestPatternId is no longer valid !!!!!!!!
-            closestPatternId1 :=  nil.
-            newFontId isNil ifTrue:[
-                self error: 'Pattern matched, but font could not be opened (should not happen)'.
-            ].
+            myPatternHandle add:FC_SIZE value:(size isNil ifTrue:[nil] ifFalse:[size rounded]).
+        ].
+
+        displayId := aGraphicsDevice displayId.
 
-            "/ Search for existing registered font. Note, that XftFont instances
-            "/ are shared (and refcounted) so newFontId = aFont getFontId is enough
-            "/ to check whether some other font instance represents the same font...
-            aGraphicsDevice deviceFonts do:[:aFont |
-                ((self class == aFont class) and:[newFontId = aFont getFontId]) ifTrue:[
-                    closestFont := aFont.
-                    ^ closestFont
-                ].
+        closestPatternHandle := myPatternHandle matchFontOnDisplayId:displayId screen:aGraphicsDevice screen.
+        closestPatternHandle notNil ifTrue:[
+            newFontId := closestPatternHandle getFontOnDisplayId:displayId.
+            newFontId notNil ifTrue:[
+                "/ Good, this font exists!!
+                closestPatternHandle := nil.
+                fontId := newFontId.
+                device := aGraphicsDevice.
+                aGraphicsDevice registerFont:self.
+                RecentlyUsedFonts addFirst:self.
+                ^ self.
             ].
-
-            closestFont := self shallowCopy
-                                setDevice: aGraphicsDevice patternId: closestPatternId2 fontId: newFontId;
-                                yourself.
-            aGraphicsDevice registerFont: closestFont.
-            RecentlyUsedFonts addFirst:closestFont.
-            ^ closestFont
         ].
     ] ensure:[
-        myPatternId notNil ifTrue:[self xftPatternDestroy: myPatternId].
-        closestPatternId1 notNil ifTrue:[self xftPatternDestroy: closestPatternId1].
-        closestPatternId2 notNil ifTrue:[self xftPatternDestroy: closestPatternId2].
+        myPatternHandle notNil ifTrue:[myPatternHandle destroy].
+        closestPatternHandle notNil ifTrue:[closestPatternHandle destroy].
     ].
+    ^ aBlock value
 
     "
      (XftFontDescription family:'monospace' size:16) onDevice:Screen current
@@ -983,17 +959,6 @@
 
     "Modified: / 14-04-1997 / 18:22:31 / cg"
     "Modified: / 02-01-2014 / 23:43:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-onDevice:aWorkstation ifAbsent:aBlock
-    "Create a new XftFont representing the same font as
-     myself on aWorkstation. This does NOT try to look for existing
-     or replacement fonts (i.e. can be used to get physical fonts)."
-
-    ^ self onDevice:aWorkstation
-
-    "Modified: / 02-01-2014 / 23:15:27 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified (comment): / 04-01-2014 / 02:06:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 ! !
 
 !XftFontDescription methodsFor:'initialization'!
@@ -1014,22 +979,21 @@
     device := deviceArg.
     fontId := fontIdArg.
     patternIdArg notNil ifTrue:[
-        family  := self xftPatternGet: patternIdArg attribute: FC_FAMILY index: 0.
-        size    := self xftPatternGet: patternIdArg attribute: FC_SIZE index: 0.
-        face    := self xftPatternGet: patternIdArg attribute: FC_WEIGHT index: 0.
-        face    := StXFace2FCWeightMap keyAtValue: face.
-        style   := self xftPatternGet: patternIdArg attribute: FC_SLANT index: 0.
-        style   := StXStyle2FCSlantMap keyAtValue: style.
+	family  := patternIdArg get: FC_FAMILY index: 0.
+	size    := patternIdArg get: FC_SIZE index: 0.
+	face    := patternIdArg get: FC_WEIGHT index: 0.
+	face    := StXFace2FCWeightMap keyAtValue: face.
+	style   := patternIdArg get: FC_SLANT index: 0.
+	style   := StXStyle2FCSlantMap keyAtValue: style.
 
-        name:= self xftPatternGet: patternIdArg attribute: 'fullname' index: 0.
-
-        encoding:= self xftPatternGet: patternIdArg attribute: 'encoding' index: 0.
+"/        name:= patternIdArg get: 'fullname' index: 0.
+"/        encoding:= patternIdArg get: 'encoding' index: 0.
     ].
     size isNil ifTrue:[
-        size := 0.
+	size := 0.
     ].
     encoding isNil ifTrue:[
-        encoding := #'iso10646-1'.
+	encoding := #'iso10646-1'.
     ].
 
     "Created: / 21-12-2013 / 00:46:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
@@ -1038,293 +1002,37 @@
 
 !XftFontDescription methodsFor:'primitives'!
 
-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."
-
+xftFontClose:fontIdArg displayId:displayId
     | error |
 
-%{
+%{ /* STACK: 64000 */
 #ifdef XFT
-    if (!__isExternalAddressLike(__INST(sharedDrawId))) {
-        // nothing to disasassociate from...
-        RETURN(self);
-    }
-    if (!__isExternalAddressLike(drawableId)) {
-        error = @symbol(BadArg);
+    int v;
+    if ( ! __isExternalAddressLike(fontIdArg) ) {
+        error = @symbol(BadArg1);
         goto err;
     }
-    if (XftDrawDrawable(XFT_DRAW(__INST(sharedDrawId))) == DRAWABLE(drawableId)) {
-        XftDrawChange(XFT_DRAW(__INST(sharedDrawId)), None);
+    if ( ! __isExternalAddressLike(displayId) ) {
+        error = @symbol(BadArg2);
+        goto err;
     }
+    XftFontClose (DISPLAY(displayId), XFT_FONT(fontIdArg));
     RETURN(self);
 err:;
 #endif
 %}.
     self primitiveFailed: error
-
-    "Created: / 26-12-2013 / 12:17:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftDrawChange:xftDrawId drawable:drawableId
-    | error |
-
-%{
-#ifdef XFT
-    if ( ! __isExternalAddressLike(xftDrawId) ) {
-        error = @symbol(BadArg1);
-        goto err;
-    }
-    if (drawableId == nil) {
-        XftDrawChange(XFT_DRAW(xftDrawId), None);
-        RETURN (self);
-    }
-    if ( ! __isExternalAddressLike(drawableId) ) {
-        error = @symbol(BadArg2);
-        goto err;
-    }
-    if (XftDrawDrawable( XFT_DRAW(xftDrawId) ) != DRAWABLE( drawableId ) ) {
-        XftDrawChange( XFT_DRAW(xftDrawId) , DRAWABLE( drawableId ) );
-    }
-    RETURN (self);
-err:;
-#endif
-%}.
-    self primitiveFailed: error
-
-    "Created: / 26-12-2013 / 12:17:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftDrawCreate: displayId screen: screen drawable: drawableId
-    | error |
-
-%{
-#ifdef XFT
-    if ( ! __isExternalAddressLike(displayId) ) {
-	error = @symbol(BadArg1);
-	goto err;
-    }
-    if ( ! __isSmallInteger(screen) ) {
-	error = @symbol(BadArg2);
-	goto err;
-    }
-    if ( ! __isExternalAddressLike(drawableId) ) {
-	error = @symbol(BadArg3);
-	goto err;
-    }
-    RETURN ( XFT_DRAW_HANDLE_NEW (  XftDrawCreate ( DISPLAY( displayId ) ,
-						   DRAWABLE( drawableId ) ,
-						   DefaultVisual( DISPLAY( displayId), SCREEN (screen) ) ,
-						   DefaultColormap( DISPLAY( displayId), SCREEN (screen) ) ) ) );
-    err:;
-#endif
-%}.
-    self primitiveFailed: error
-
-    "Created: / 21-12-2013 / 21:12:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftDrawDestroy
-%{
-#ifdef XFT
-    if (__INST(sharedDrawId) != nil) {
-        XftDraw *xftDrawable = XFT_DRAW(__INST(sharedDrawId));
-        __INST(sharedDrawId) = nil;
-        XftDrawDestroy(xftDrawable);
-    }
-    RETURN (self);
-#endif
-%}.
-    self primitiveFailed.
-!
-
-xftDrawRect: drawIdArg color: aColor x: x y: y width: w height: h
-    | error r g b a pix |
-
-    aColor isColor ifFalse:[^self primitiveFailed: #BadArg2].
-
-    r := aColor scaledRed.
-    g := aColor scaledGreen.
-    b := aColor scaledBlue.
-    a := aColor alpha * 65535.
-    r isNil ifTrue:[
-	"/ when drawing into a pixmap...
-	aColor colorId == 0 ifTrue:[
-	    r := g := b := 0.
-	] ifFalse:[
-	    r := g := b := 16rFFFF.
-	]
-    ].
-    pix := aColor colorId.
-%{
-#ifdef XFT
-    XftColor clr;
-    if ( ! __isExternalAddressLike(drawIdArg) ) {
-	error = @symbol(BadArg1);
-	goto err;
-    }
-    if ( ! __isSmallInteger(pix) ) {
-	error = @symbol(BadColorId);
-	goto err;
-    }
-    if ( ! __isSmallInteger(x) ) {
-	error = @symbol(BadArg3);
-	goto err;
-    }
-    if ( ! __isSmallInteger(y) ) {
-	error = @symbol(BadArg4);
-	goto err;
-    }
-    if ( ! __isSmallInteger(w) ) {
-	error = @symbol(BadArg5);
-	goto err;
-    }
-    if ( ! __isSmallInteger(h) ) {
-	error = @symbol(BadArg6);
-	goto err;
-    }
-    clr.pixel = (unsigned long)__intVal(pix);
-    clr.color.red = __intVal(r);
-    clr.color.green = __intVal(g);
-    clr.color.blue = __intVal(b);
-    clr.color.alpha = __intVal(a);
-
-    XftDrawRect(XFT_DRAW(drawIdArg), &clr,
-			__intVal(x), __intVal(y), __intVal(w) ,__intVal(h));
-
-    RETURN ( self );
-    err:;
-#endif
-%}.
-    self primitiveFailed: error.
-
-    "Created: / 28-12-2013 / 23:35:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 31-12-2013 / 00:37:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftDrawSetClip: drawIdArg rectangle: rect
-    | error xObj yObj wObj hObj  |
-
-    rect notNil ifTrue:[
-	xObj := rect left.
-	yObj := rect top.
-	wObj := rect width.
-	hObj := rect height.
-    ].
-%{
-#ifdef XFT
-    XRectangle r;
-    if ( ! __isExternalAddressLike(drawIdArg) ) {
-	error = @symbol(BadArg1);
-	goto err;
-    }
-    if (rect != nil) {
-	r.x = __intVal(xObj);
-	r.y = __intVal(yObj);
-	r.width = __intVal(wObj);
-	r.height = __intVal(hObj);
-	XftDrawSetClipRectangles( XFT_DRAW(drawIdArg) , 0, 0, &r, 1);
-    } else {
-	XftDrawSetClipRectangles( XFT_DRAW(drawIdArg) , 0, 0, (XRectangle*)NULL, 0);
-    }
-    RETURN ( self );
-    err:;
-#endif
-%}.
-    self primitiveFailed: error.
-
-    "Created: / 31-12-2013 / 01:24:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftDrawString: drawIdArg color: aColor font: fontIdArg x: x y: y string: text from: start to: stop
-    | error r g b a pix |
-
-    aColor isColor ifFalse:[^self primitiveFailed: #BadArg2].
-
-    r := aColor scaledRed.
-    g := aColor scaledGreen.
-    b := aColor scaledBlue.
-    a := aColor alpha * 65535.
-    r isNil ifTrue:[
-	"/ when drawing into a pixmap...
-	aColor colorId == 0 ifTrue:[
-	    r := g := b := 0.
-	] ifFalse:[
-	    r := g := b := 16rFFFF.
-	]
-    ].
-    pix := aColor colorId.
-%{
-#ifdef XFT
-    int _start, _stop;
-    int __x, __y;
-    XftColor clr;
-    if ( ! __isExternalAddressLike(drawIdArg) ) {
-	error = @symbol(BadArg1);
-	goto err;
-    }
-    if ( ! __isSmallInteger(pix) ) {
-	error = @symbol(BadColorId);
-	goto err;
-    }
-    if ( ! __isSmallInteger(x) ) {
-	error = @symbol(BadArg4);
-	goto err;
-    }
-    __x = __intVal(x);
-    if ( ! __isSmallInteger(y) ) {
-	error = @symbol(BadArg5);
-	goto err;
-    }
-    __y = __intVal(y);
-
-
-    if ( ! __isSmallInteger(start) ) {
-	error = @symbol(BadArg6);
-	goto err;
-    }
-    _start = __intVal(start);
-    if ( ! __isSmallInteger(stop) ) {
-	error = @symbol(BadArg7);
-	goto err;
-    }
-    _stop = __intVal(stop);
-
-    clr.pixel = (unsigned long)__intVal(pix);
-    clr.color.red = __intVal(r);
-    clr.color.green = __intVal(g);
-    clr.color.blue = __intVal(b);
-    clr.color.alpha = __intVal(a);
-
-    if ( __isStringLike(text) ) {
-	XftDrawString8(XFT_DRAW(drawIdArg), &clr, XFT_FONT(fontIdArg),
-			__x, __y,
-			__stringVal(text) + (_start - 1), _stop - _start + 1);
-	RETURN ( self );
-    } else {
-	error = @symbol(BadArg5);
-	goto err;
-    }
-    err:;
-#endif
-%}.
-    self primitiveFailed: error.
-
-    "Created: / 28-12-2013 / 12:32:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 30-12-2013 / 20:00:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
 xftFontGetAscent: fontIdArg
     | error |
 
-%{
+%{ /* STACK: 64000 */
 #ifdef XFT
     int v;
     if ( ! __isExternalAddressLike(fontIdArg) ) {
-	error = @symbol(BadArg1);
-	goto err;
+        error = @symbol(BadArg1);
+        goto err;
     }
     v = XFT_FONT(fontIdArg)->ascent;
     RETURN ( __MKINT( v ) );
@@ -1339,12 +1047,12 @@
 xftFontGetDescent:fontIdArg
     | error |
 
-%{
+%{ /* STACK: 64000 */
 #ifdef XFT
     int v;
     if ( ! __isExternalAddressLike(fontIdArg) ) {
-	error = @symbol(BadArg1);
-	goto err;
+        error = @symbol(BadArg1);
+        goto err;
     }
     v = XFT_FONT(fontIdArg)->descent;
     RETURN ( __MKINT( v ) );
@@ -1359,12 +1067,12 @@
 xftFontGetHeight: fontIdArg
     | error |
 
-%{
+%{ /* STACK: 64000 */
 #ifdef XFT
     int v;
     if ( ! __isExternalAddressLike(fontIdArg) ) {
-	error = @symbol(BadArg1);
-	goto err;
+        error = @symbol(BadArg1);
+        goto err;
     }
     v = XFT_FONT(fontIdArg)->height;
     RETURN ( __MKINT( v ) );
@@ -1379,12 +1087,12 @@
 xftFontGetMaxAdvanceWidth: fontIdArg
     | error |
 
-%{
+%{ /* STACK: 64000 */
 #ifdef XFT
     int v;
     if ( ! __isExternalAddressLike(fontIdArg) ) {
-	error = @symbol(BadArg1);
-	goto err;
+        error = @symbol(BadArg1);
+        goto err;
     }
     v = XFT_FONT(fontIdArg)->max_advance_width;
     RETURN ( __MKINT( v ) );
@@ -1399,18 +1107,18 @@
 xftFontGetPattern: fontIdArg
     | error |
 
-%{
+%{ /* STACK: 64000 */
 #ifdef XFT
     XftPattern* p;
     if ( ! __isExternalAddressLike(fontIdArg) ) {
-	error = @symbol(BadArg1);
-	goto err;
+        error = @symbol(BadArg1);
+        goto err;
     }
     p = XFT_FONT(fontIdArg)->pattern;
     if (p == NULL) {
-	RETURN ( nil );
+        RETURN ( nil );
     } else {
-	RETURN ( FC_PATTERN_HANDLE_NEW ( p ) );
+        RETURN ( FC_PATTERN_HANDLE_NEW ( p ) );
     }
     err:;
 #endif
@@ -1420,311 +1128,49 @@
     "Created: / 21-12-2013 / 00:55:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
-xftFontMatch: displayId screen: screen pattern: patternId
-    | error |
-
-%{ /* UNLIMITEDSTACK */
-#ifdef XFT
-    XftPattern* p;
-    XftResult r;
-
-    if ( ! __isExternalAddressLike(displayId) ) {
-	error = @symbol(BadArg1);
-	goto err;
-    }
-    if ( ! __isSmallInteger( screen ) ) {
-	error = @symbol(BadArg2);
-	goto err;
-    }
-    if ( ! __isExternalAddressLike(patternId) ) {
-	error = @symbol(BadArg3);
-	goto err;
-    }
-
-    XftConfigSubstitute(FC_PATTERN( patternId ));
-    XftDefaultSubstitute(DISPLAY(displayId) , SCREEN( screen ), FC_PATTERN( patternId ));
-    p = XftFontMatch( DISPLAY(displayId) , SCREEN( screen ), FC_PATTERN( patternId ), &r );
-    if (p) {
-	RETURN ( FC_PATTERN_HANDLE_NEW ( p ) );
-    } else {
-	error = @symbol(XftFontMatchReturnedNull);
-    }
-    err:;
-#endif
-%}.
-    self primitiveFailed: error
-
-    "Created: / 21-12-2013 / 00:08:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftFontOpenPattern: displayId pattern: patternId
-    "Note: the pattern is destroyed when the font is closed"
-
-    | error |
-
-%{
-#ifdef XFT
-    XftFont* f;
-    if ( ! __isExternalAddressLike(displayId) ) {
-        error = @symbol(BadArg1);
-        goto err;
-    }
-    if ( ! __isExternalAddressLike(patternId) ) {
-        error = @symbol(BadArg2);
-        goto err;
-    }
-
-    f = XftFontOpenPattern( DISPLAY(displayId) , FC_PATTERN( patternId ) );
-    if (f == NULL) {
-        RETURN ( nil );
-    } else {
-        RETURN ( XFT_FONT_HANDLE_NEW ( f ) );
-    }
-    err:;
-#endif
-%}.
-    self primitiveFailed: error
-
-    "Created: / 20-12-2013 / 23:53:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftPatternAdd: pattern attribute: attribute value: value
-    "Add a value to the specified pattern element after existing values"
-
-    ^ self xftPatternAdd: pattern attribute: attribute value: value append: true.
-
-    "Created: / 20-12-2013 / 23:43:31 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftPatternAdd: pattern attribute: attribute value: value append: append
-    "Add a value to the specified pattern element.  If 'append' is true, the value
-     is added after existing values, otherwise it is added before them."
-
-    | error |
-
-%{
-#ifdef XFT
-    XftValue v;
-    Bool b;
-
-    if ( ! __isExternalAddressLike ( pattern ) ) {
-	error = @symbol(BadArg1);
-	goto err;
-    }
-    if ( ! __isStringLike ( attribute ) ) {
-	error = @symbol(BadArg2);
-	goto err;
-    }
-    if ( append != true && append != false ) {
-	error = @symbol(BadArg4);
-	goto err;
-    }
-    if ( __isStringLike ( value ) ) {
-	v.type = FcTypeString;
-	/* Passing pointer inside Smalltalk should be safe,
-	 * Xft/FontConfig libraries seem to allocate and store
-	 * a __copy__ of the string (if I understood the code correctly)
-	 */
-	v.u.s = __stringVal( value);
-    } else if ( __isSmallInteger( value ) ) {
-	v.type = XftTypeInteger;
-	v.u.i = (int)__intVal( value );
-    } else if ( value == true || value == false ) {
-	v.type = XftTypeBool;
-	v.u.b = value == true ? True : False;
-    } else if ( __isFloat ( value ) ) {
-	v.type = XftTypeDouble;
-	v.u.d = __floatVal( value );
-    } else if ( value == nil ) {
-	v.type = XftTypeVoid;
-	v.u.f = NULL;
-    } else {
-	error = @symbol(BadArg3);
-	goto err;
-    }
-    b = XftPatternAdd( FC_PATTERN(pattern), __stringVal(attribute), v, append == true ? True : False );
-    RETURN ( b == True ? true : false );
-
-    err:;
-#endif
-%}.
-    self primitiveFailed: error
-
-    "Created: / 20-12-2013 / 21:50:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftPatternCreate
-%{
-#ifdef XFT
-    RETURN ( FC_PATTERN_HANDLE_NEW ( XftPatternCreate() ) );
-#endif
-%}.
-    self primitiveFailed.
-
-    "Created: / 20-12-2013 / 21:19:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftPatternDel: pattern attribute: attribute
-    | error |
-%{
-#ifdef XFT
-    if ( ! __isExternalAddressLike ( pattern ) ) {
-	error = @symbol(BadArg1);
-	goto err;
-    }
-    if ( ! __isStringLike ( attribute ) ) {
-	error = @symbol(BadArg2);
-	goto err;
-    }
-    XftPatternDel( FC_PATTERN(pattern), __stringVal ( attribute ) );
-    RETURN ( self );
-
-    err:;
-#endif
-%}.
-    self primitiveFailed: error
-
-    "Created: / 20-12-2013 / 21:33:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftPatternDestroy: addr
-    | error |
-
-    addr isNil ifTrue:[ ^ self ].
-
-%{
-#ifdef XFT
-    if ( ! __isExternalAddressLike(addr) ) {
-	error = @symbol(BadArg1);
-	goto err;
-    }
-    XftPatternDestroy( FC_PATTERN(addr) );
-    RETURN ( self );
-
-    err:;
-#endif
-%}.
-    self primitiveFailed: error
-
-    "Created: / 20-12-2013 / 21:33:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 20-12-2013 / 23:48:45 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftPatternDuplicate: addr
-    | error |
-
-    addr isNil ifTrue:[ ^ self ].
-
-%{
-#ifdef XFT
-    if ( ! __isExternalAddressLike(addr) ) {
-	error = @symbol(BadArg1);
-	goto err;
-    }
-    RETURN ( FC_PATTERN_HANDLE_NEW ( XftPatternDuplicate( FC_PATTERN(addr) ) ) );
-    err:;
-#endif
-%}.
-    self primitiveFailed: error
-
-    "Created: / 21-12-2013 / 01:14:03 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
-xftPatternGet: pattern attribute: attribute index: index
-    "Return a value from the specified element -- multiple values can be indexed
-     with 'index' starting at zero."
-
-    | error |
-
-%{
-#ifdef XFT
-    XftValue v;
-    XftResult r;
-
-    if ( ! __isExternalAddressLike ( pattern ) ) {
-	error = @symbol(BadArg1);
-	goto err;
-    }
-    if ( ! __isStringLike ( attribute ) ) {
-	error = @symbol(BadArg2);
-	goto err;
-    }
-    if ( ! __isSmallInteger( index ) ) {
-	error = @symbol(BadArg3);
-	goto err;
-    }
-    r = XftPatternGet(FC_PATTERN(pattern), __stringVal( attribute ), __intVal( index ), &v);
-    if ( r != XftResultMatch) {
-	RETURN ( nil );
-    }
-    if ( v.type == XftTypeString) {
-	RETURN ( __MKSTRING(v.u.s) );
-    } else if ( v.type == XftTypeInteger ) {
-	RETURN ( __MKINT (v.u.i) );
-    } else if ( v.type == XftTypeBool ) {
-	RETURN ( v.u.b == True ? true : false );
-    } else if ( v.type == XftTypeDouble ) {
-	RETURN ( __MKFLOAT (v.u.d) );
-    } else if ( v.type == XftTypeVoid ) {
-	RETURN ( nil );
-    } else {
-	error = @symbol(UnssuportedTypeValue);
-	goto err;
-    }
-    err:;
-#endif
-%}.
-    self primitiveFailed: error
-
-    "Created: / 20-12-2013 / 21:50:44 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-    "Modified: / 21-12-2013 / 01:06:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
-!
-
 xftTextExtents: displayIdArg font: fontIdArg string: text from: start to: stop
     | error extents bitsPerCharacter |
 
     extents :=  Array new: 6.
     bitsPerCharacter := text bitsPerCharacter.
-%{
+
+%{ /* STACK: 64000 */
 #ifdef XFT
     XGlyphInfo info;
-    int bytesPerCharacter;
     char *string;
     int len;
-
-    bytesPerCharacter = __intVal(bitsPerCharacter) / 8;
+    int bytesPerCharacter = __intVal(bitsPerCharacter) / 8;
 
     if ( ! __isExternalAddressLike(displayIdArg) ) {
-	error = @symbol(BadArg1);
-	goto err;
+        error = @symbol(BadArg1);
+        goto err;
     }
     if ( ! __isExternalAddressLike(fontIdArg) ) {
-	error = @symbol(BadArg2);
-	goto err;
+        error = @symbol(BadArg2);
+        goto err;
     }
     if ( ! __isSmallInteger(start) ) {
-	error = @symbol(BadArg4);
-	goto err;
+        error = @symbol(BadArg4);
+        goto err;
     }
     if ( ! __isSmallInteger(stop) ) {
-	error = @symbol(BadArg5);
-	goto err;
+        error = @symbol(BadArg5);
+        goto err;
     }
 
     string = __stringVal( text ) + (( __intVal(start) - 1 ) * bytesPerCharacter);
     len = __intVal(stop) - __intVal(start) + 1;
 
-
     switch (bytesPerCharacter) {
     case 1:
-	XftTextExtents8(DISPLAY(displayIdArg), XFT_FONT(fontIdArg), (FcChar8*)string, len, &info);
-	break;
+        XftTextExtents8(DISPLAY(displayIdArg), XFT_FONT(fontIdArg), (FcChar8*)string, len, &info);
+        break;
     case 2:
-	XftTextExtents16(DISPLAY(displayIdArg), XFT_FONT(fontIdArg), (FcChar16*)string, len, &info);
-	break;
+        XftTextExtents16(DISPLAY(displayIdArg), XFT_FONT(fontIdArg), (FcChar16*)string, len, &info);
+        break;
     case 4:
-	XftTextExtents32(DISPLAY(displayIdArg), XFT_FONT(fontIdArg), (FcChar32*)string, len, &info);
-	break;
+        XftTextExtents32(DISPLAY(displayIdArg), XFT_FONT(fontIdArg), (FcChar32*)string, len, &info);
+        break;
     }
     __ArrayInstPtr(extents)->a_element[0] = __MKSMALLINT(info.width);
     __ArrayInstPtr(extents)->a_element[1] = __MKSMALLINT(info.height);
@@ -1737,8 +1183,8 @@
 #endif
 %}.
     error notNil ifTrue:[
-	self primitiveFailed: error.
-	^ nil.
+        self primitiveFailed: error.
+        ^ nil.
     ].
     ^ extents
 
@@ -1857,6 +1303,29 @@
     "Created: / 30-12-2013 / 20:02:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
 !
 
+patternStringForId:patternIdArg
+    |name family size pixelSize face style encoding foundry width|
+
+    patternIdArg notNil ifTrue:[
+	foundry  := patternIdArg get: FC_FOUNDRY index: 0.
+	family  := patternIdArg get: FC_FAMILY index: 0.
+	size    := patternIdArg get: FC_SIZE index: 0.
+	pixelSize := patternIdArg get: FC_PIXEL_SIZE index: 0.
+	face    := patternIdArg get: FC_WEIGHT index: 0.
+	face    := StXFace2FCWeightMap keyAtValue: face.
+	style   := patternIdArg get: FC_SLANT index: 0.
+	style   := StXStyle2FCSlantMap keyAtValue: style.
+	width   := patternIdArg get: FC_WIDTH index: 0.
+
+	name:= patternIdArg get: 'fullname' index: 0.
+
+	encoding:= patternIdArg get: 'encoding' index: 0.
+    ].
+
+    ^ '%8-%1-%2-%3-%4pt/%5px-%6-%9 (%7)' bindWith:family with:face with:style with:size with:pixelSize with:encoding with:name
+					 with:foundry with:width.
+!
+
 widthOf:aString from:start to:stop
     "return the width of a sub string"
 
@@ -1873,6 +1342,17 @@
 
 !XftFontDescription methodsFor:'release'!
 
+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."
+
+    sharedDrawId notNil ifTrue:[
+        sharedDrawId disassociateFrom:drawableId.
+    ].
+!
+
 releaseDrawIfAssociatedWith: view
     | drawableId |
 
@@ -1910,7 +1390,6 @@
     device := nil.
     fontId := nil.
     sharedDrawId := nil.
-    closestFont := nil.
 ! !
 
 !XftFontDescription methodsFor:'testing'!
@@ -1949,51 +1428,51 @@
     list := OrderedCollection new.
 
     readEntry :=
-        [
-            |key|
+	[
+	    |key|
 
-            [l startsWith:'Pattern has'] whileFalse:[
-              l := pipeStream nextLine. Transcript showCR:l.
-            ].
+	    [l startsWith:'Pattern has'] whileFalse:[
+	      l := pipeStream nextLine. Transcript showCR:l.
+	    ].
 
-            currentDescription := XftFontDescription new.
-            [ l := pipeStream nextLine. l notEmptyOrNil ] whileTrue:[
-                "/ Transcript showCR:l.
-                lineStream := l readStream. lineStream skipSeparators.
-                key := lineStream upToSeparator.
-                (
-                    #('family:' 'style:' 'slant:' 'weight:' 'width:'
-                      'pixelsize:' 'spacing:' 'foundry:' 'antialias:'
-                      'file:' 'outline:' 'scalable:' 'charset:' 'lang:'
-                      'fontversion:' 'fontformat:' 'decorative:' 'index:'
-                      'outline:' 'familylang:' 'stylelang:' 'fullname:'
-                      'fullnamelang:' 'capability:' 'hash:' 'postscriptname:'
-                    ) includes:key
-                ) ifTrue:[
-                    self perform:('fc_', (key allButLast)) asSymbol
-                ] ifFalse:[
-                    Transcript show:'Xft ignored line: '; showCR:l.
-                    self breakPoint:#cg.
-                ].
-            ].
-            list add:currentDescription
-        ].
+	    currentDescription := XftFontDescription new.
+	    [ l := pipeStream nextLine. l notEmptyOrNil ] whileTrue:[
+		"/ Transcript showCR:l.
+		lineStream := l readStream. lineStream skipSeparators.
+		key := lineStream upToSeparator.
+		(
+		    #('family:' 'style:' 'slant:' 'weight:' 'width:'
+		      'pixelsize:' 'spacing:' 'foundry:' 'antialias:'
+		      'file:' 'outline:' 'scalable:' 'charset:' 'lang:'
+		      'fontversion:' 'fontformat:' 'decorative:' 'index:'
+		      'outline:' 'familylang:' 'stylelang:' 'fullname:'
+		      'fullnamelang:' 'capability:' 'hash:' 'postscriptname:'
+		    ) includes:key
+		) ifTrue:[
+		    self perform:('fc_', (key allButLast)) asSymbol
+		] ifFalse:[
+		    Transcript show:'Xft ignored line: '; showCR:l.
+		    self breakPoint:#cg.
+		].
+	    ].
+	    list add:currentDescription
+	].
 
     fcListProg := #('/usr/bin/fc-list' '/usr/X11/bin/fc-list') detect:[:eachProg|
-                        eachProg asFilename isExecutableProgram
-                    ] ifNone:[
-                        'XftFontDescription [warning]: fc-list program not found - no XFT fonts' errorPrintCR.
-                        ^ list.
-                    ].
+			eachProg asFilename isExecutableProgram
+		    ] ifNone:[
+			'XftFontDescription [warning]: fc-list program not found - no XFT fonts' errorPrintCR.
+			^ list.
+		    ].
 
     pipeStream := PipeStream readingFrom:fcListProg, ' -v'.
     [
-        [pipeStream atEnd] whileFalse:[
-            l := pipeStream nextLine.
-            readEntry value.
-        ]
+	[pipeStream atEnd] whileFalse:[
+	    l := pipeStream nextLine.
+	    readEntry value.
+	]
     ] ensure:[
-        pipeStream close
+	pipeStream close
     ].
     ^ list
 
@@ -2220,8 +1699,8 @@
     ^ (s indexOfSubCollection:'True') ~~ 0.     "/ match at least 'True' and 'FCTrue'
 
     "
-        'xxFalse' indexOfSubCollection:'True'
-        'FcTrue' indexOfSubCollection:'True'
+	'xxFalse' indexOfSubCollection:'True'
+	'FcTrue' indexOfSubCollection:'True'
     "
 !
 
@@ -2240,6 +1719,538 @@
     ^ (lineStream upTo:$").
 ! !
 
+!XftFontDescription::FCPatternHandle class methodsFor:'instance creation'!
+
+create
+    ^ self new create
+
+    "
+	self new create destroy
+    "
+! !
+
+!XftFontDescription::FCPatternHandle methodsFor:'primitives'!
+
+add:attribute value: value
+    "Add a value to the specified pattern element after existing values"
+
+    ^ self add: attribute value: value append: true.
+!
+
+add:attribute value: value append: append
+    "Add a value to the specified pattern element.  If 'append' is true, the value
+     is added after existing values, otherwise it is added before them."
+
+    | error |
+
+%{
+#ifdef XFT
+    XftValue v;
+    Bool b;
+
+    if (__INST(address_) == 0) {
+	error = @symbol(NullReceiver);
+	goto err;
+    }
+    if ( ! __isStringLike ( attribute ) ) {
+	error = @symbol(BadArg1);
+	goto err;
+    }
+    if ( append != true && append != false ) {
+	error = @symbol(BadArg3);
+	goto err;
+    }
+    if ( __isStringLike ( value ) ) {
+	v.type = FcTypeString;
+	/* Passing pointer inside Smalltalk should be safe,
+	 * Xft/FontConfig libraries seem to allocate and store
+	 * a __copy__ of the string (if I understood the code correctly)
+	 */
+	v.u.s = __stringVal( value);
+    } else if ( __isSmallInteger( value ) ) {
+	v.type = XftTypeInteger;
+	v.u.i = (int)__intVal( value );
+    } else if ( value == true || value == false ) {
+	v.type = XftTypeBool;
+	v.u.b = value == true ? True : False;
+    } else if ( __isFloat ( value ) ) {
+	v.type = XftTypeDouble;
+	v.u.d = __floatVal( value );
+    } else if ( value == nil ) {
+	v.type = XftTypeVoid;
+	v.u.f = NULL;
+    } else {
+	error = @symbol(BadArg2);
+	goto err;
+    }
+    b = XftPatternAdd((XftPattern*)__INST(address_), __stringVal(attribute), v, append == true ? True : False );
+    RETURN ( b == True ? true : false );
+
+    err:;
+#endif
+%}.
+    self primitiveFailed: error
+
+    "Created: / 20-12-2013 / 21:50:00 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+create
+%{
+#ifdef XFT
+    __INST(address_) = (void *)XftPatternCreate();
+#endif
+%}.
+!
+
+delete: pattern attribute: attribute
+    | error |
+%{
+#ifdef XFT
+    if (__INST(address_) == 0) {
+        error = @symbol(BadHandle);
+        goto err;
+    }
+    if ( ! __isStringLike ( attribute ) ) {
+        error = @symbol(BadArg1);
+        goto err;
+    }
+    XftPatternDel( (XftPattern*)__INST(address_), __stringVal ( attribute ) );
+    RETURN ( self );
+
+    err:;
+#endif
+%}.
+    self primitiveFailed: error
+!
+
+destroy
+%{
+#ifdef XFT
+    if (__INST(address_) != 0) {
+	XftPatternDestroy((XftPattern*)__INST(address_));
+	__INST(address_) = 0;
+	RETURN ( self );
+    }
+#endif
+%}.
+    self primitiveFailed.
+!
+
+duplicate
+    | error |
+
+%{
+#ifdef XFT
+    if (__INST(address_) != 0) {
+	RETURN (FC_PATTERN_HANDLE_NEW((XftPattern*)__INST(address_)));
+	RETURN ( self );
+    }
+#endif
+%}.
+    self primitiveFailed
+!
+
+get:attribute index: index
+    "Return a value from the specified element -- multiple values can be indexed
+     with 'index' starting at zero."
+
+    | error |
+
+%{
+#ifdef XFT
+    XftValue v;
+    XftResult r;
+
+    if (__INST(address_) == 0) {
+	error = @symbol(NullReceiver);
+	goto err;
+    }
+    if ( ! __isStringLike ( attribute ) ) {
+	error = @symbol(BadArg1);
+	goto err;
+    }
+    if ( ! __isSmallInteger( index ) ) {
+	error = @symbol(BadArg2);
+	goto err;
+    }
+    r = XftPatternGet((XftPattern*)__INST(address_), __stringVal( attribute ), __intVal( index ), &v);
+    if ( r != XftResultMatch) {
+	RETURN ( nil );
+    }
+    if ( v.type == XftTypeString) {
+	RETURN ( __MKSTRING(v.u.s) );
+    } else if ( v.type == XftTypeInteger ) {
+	RETURN ( __MKINT (v.u.i) );
+    } else if ( v.type == XftTypeBool ) {
+	RETURN ( v.u.b == True ? true : false );
+    } else if ( v.type == XftTypeDouble ) {
+	RETURN ( __MKFLOAT (v.u.d) );
+    } else if ( v.type == XftTypeVoid ) {
+	RETURN ( nil );
+    } else {
+	error = @symbol(UnssuportedTypeValue);
+	goto err;
+    }
+    err:;
+#endif
+%}.
+    self primitiveFailed: error
+!
+
+getFontOnDisplayId:displayId
+    "Note: the pattern is destroyed when the font is closed"
+
+    | error |
+
+%{ /* STACK: 64000 */
+#ifdef XFT
+    XftFont* f;
+    if (!__isExternalAddressLike(displayId) ) {
+        error = @symbol(BadArg1);
+        goto err;
+    }
+    if (__INST(address_) == 0) {
+        error = @symbol(BadHandle);
+        goto err;
+    }
+
+    f = XftFontOpenPattern(DISPLAY(displayId), (XftPattern*)__INST(address_));
+    if (f == NULL) {
+        RETURN (nil);
+    } else {
+        RETURN (XFT_FONT_HANDLE_NEW(f));
+    }
+    err:;
+#endif
+%}.
+    self primitiveFailed: error
+
+    "Created: / 20-12-2013 / 23:53:59 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+matchFontOnDisplayId:displayId screen:screen
+    | error |
+
+%{ /* STACK: 64000 */
+#ifdef XFT
+    XftPattern *p;
+    XftResult r;
+
+    if (!__isExternalAddressLike(displayId)) {
+        error = @symbol(BadArg1);
+        goto err;
+    }
+    if (!__isSmallInteger( screen) ) {
+        error = @symbol(BadArg2);
+        goto err;
+    }
+    if (__INST(address_) == 0) {
+        error = @symbol(BadHandle);
+        goto err;
+    }
+
+// Already done in match:
+//    XftConfigSubstitute(FC_PATTERN( patternId ));
+//    XftDefaultSubstitute(DISPLAY(displayId), SCREEN( screen ), FC_PATTERN( patternId ));
+    p = XftFontMatch(DISPLAY(displayId), SCREEN(screen), (XftPattern*)__INST(address_), &r);
+    if (p) {
+        RETURN (FC_PATTERN_HANDLE_NEW(p) );
+    } else {
+        error = @symbol(XftFontMatchReturnedNull);
+    }
+    err:;
+#endif
+%}.
+    self primitiveFailed: error
+
+    "Created: / 21-12-2013 / 00:08:48 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!XftFontDescription::XftDrawHandle class methodsFor:'instance creation'!
+
+createForDisplayId:displayId screen:screen drawable:drawableId
+    ^ self new createForDisplayId:displayId screen:screen drawable:drawableId
+! !
+
+!XftFontDescription::XftDrawHandle methodsFor:'primitives'!
+
+createForDisplayId:displayId screen:screen drawable:drawableId
+    | error |
+
+%{ /* STACK: 64000 */
+#ifdef XFT
+    if ( ! __isExternalAddressLike(displayId) ) {
+        error = @symbol(BadArg1);
+        goto err;
+    }
+    if ( ! __isSmallInteger(screen) ) {
+        error = @symbol(BadArg2);
+        goto err;
+    }
+    if ( ! __isExternalAddressLike(drawableId) ) {
+        error = @symbol(BadArg3);
+        goto err;
+    }
+    __INST(address_) = (void *) XftDrawCreate ( DISPLAY(displayId) ,
+                                                   DRAWABLE(drawableId) ,
+                                                   DefaultVisual(DISPLAY(displayId), SCREEN (screen)) ,
+                                                   DefaultColormap(DISPLAY(displayId), SCREEN (screen)));
+    err:;
+#endif
+%}.
+    self primitiveFailed: error
+
+    "Created: / 21-12-2013 / 21:12:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+destroy
+%{ /* STACK: 64000 */
+#ifdef XFT
+    if (__INST(address_) != 0) {
+        XftDrawDestroy((XftDraw*)__INST(address_));
+        __INST(address_) = 0;
+        RETURN ( self );
+    }
+#endif
+%}.
+    self primitiveFailed.
+!
+
+disassociateFrom: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 |
+
+%{ /* STACK: 64000 */
+#ifdef XFT
+    if (__INST(address_) == 0) {
+        // nothing to disasassociate from...
+        RETURN(self);
+    }
+    if (!__isExternalAddressLike(drawableId)) {
+        error = @symbol(BadArg);
+        goto err;
+    }
+    if (XftDrawDrawable((XftDraw*)__INST(address_)) == DRAWABLE(drawableId)) {
+        XftDrawChange((XftDraw*)__INST(address_), None);
+    }
+    RETURN(self);
+err:;
+#endif
+%}.
+    self primitiveFailed: error
+
+    "Created: / 26-12-2013 / 12:17:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+drawChange:drawableId
+    | error |
+
+%{ /* STACK: 64000 */
+#ifdef XFT
+    if (drawableId == nil) {
+        XftDrawChange((XftDraw*)__INST(address_), None);
+        RETURN (self);
+    }
+    if (!__isExternalAddressLike(drawableId)) {
+        error = @symbol(BadArg1);
+        goto err;
+    }
+    if (XftDrawDrawable((XftDraw*)__INST(address_)) != DRAWABLE( drawableId)) {
+        XftDrawChange((XftDraw*)__INST(address_), DRAWABLE( drawableId));
+    }
+    RETURN (self);
+err:;
+#endif
+%}.
+    self primitiveFailed: error
+
+    "Created: / 26-12-2013 / 12:17:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+drawRectWithColor:aColor x:x y:y width:w height:h
+    | error r g b a pix |
+
+    aColor isColor ifFalse:[^self primitiveFailed: #BadArg1].
+
+    r := aColor scaledRed.
+    g := aColor scaledGreen.
+    b := aColor scaledBlue.
+    a := aColor alpha * 65535.
+    r isNil ifTrue:[
+        "/ when drawing into a pixmap...
+        aColor colorId == 0 ifTrue:[
+            r := g := b := 0.
+        ] ifFalse:[
+            r := g := b := 16rFFFF.
+        ]
+    ].
+    pix := aColor colorId.
+%{ /* STACK: 64000 */
+#ifdef XFT
+    XftColor clr;
+
+    if (__INST(address_) == 0) {
+        error = @symbol(BadHandle);
+        goto err;
+    }
+    if (!__isSmallInteger(pix)) {
+        error = @symbol(BadColorId);
+        goto err;
+    }
+    if (!__isSmallInteger(x)) {
+        error = @symbol(BadArg2);
+        goto err;
+    }
+    if (! __isSmallInteger(y)) {
+        error = @symbol(BadArg3);
+        goto err;
+    }
+    if (!__isSmallInteger(w)) {
+        error = @symbol(BadArg4);
+        goto err;
+    }
+    if (!__isSmallInteger(h)) {
+        error = @symbol(BadArg5);
+        goto err;
+    }
+    clr.pixel = (unsigned long)__intVal(pix);
+    clr.color.red = __intVal(r);
+    clr.color.green = __intVal(g);
+    clr.color.blue = __intVal(b);
+    clr.color.alpha = __intVal(a);
+
+    XftDrawRect((XftDraw*)__INST(address_), &clr,
+                        __intVal(x), __intVal(y), __intVal(w) ,__intVal(h));
+
+    RETURN (self);
+    err:;
+#endif
+%}.
+    self primitiveFailed: error.
+
+    "Created: / 28-12-2013 / 23:35:42 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 31-12-2013 / 00:37:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+drawString:aString color:aColor font:fontIdArg x:x y:y from:start to:stop
+    | error r g b a pix |
+
+    aColor isColor ifFalse:[^self primitiveFailed: #BadArg2].
+
+    pix := aColor colorId.
+    r := aColor scaledRed.
+    r isNil ifTrue:[
+        "/ when drawing into a pixmap...
+        pix == 0 ifTrue:[
+            r := g := b := a := 0.
+        ] ifFalse:[
+            r := g := b := a := 16rFFFF.
+        ]
+    ] ifFalse:[
+        g := aColor scaledGreen.
+        b := aColor scaledBlue.
+        a := aColor alpha * 65535.
+    ].
+%{ /* STACK: 64000 */
+#ifdef XFT
+    int _start, _stop;
+    int __x, __y;
+    XftColor clr;
+
+    if (__INST(address_) == 0) {
+        error = @symbol(BadHandle);
+        goto err;
+    }
+    if ( ! __isSmallInteger(pix) ) {
+        error = @symbol(BadColorId);
+        goto err;
+    }
+    if ( ! __isSmallInteger(x) ) {
+        error = @symbol(BadArg4);
+        goto err;
+    }
+    __x = __intVal(x);
+    if ( ! __isSmallInteger(y) ) {
+        error = @symbol(BadArg5);
+        goto err;
+    }
+    __y = __intVal(y);
+
+
+    if ( ! __isSmallInteger(start) ) {
+        error = @symbol(BadArg6);
+        goto err;
+    }
+    _start = __intVal(start);
+    if ( ! __isSmallInteger(stop) ) {
+        error = @symbol(BadArg7);
+        goto err;
+    }
+    _stop = __intVal(stop);
+
+    clr.pixel = (unsigned long)__intVal(pix);
+    clr.color.red = __intVal(r);
+    clr.color.green = __intVal(g);
+    clr.color.blue = __intVal(b);
+    clr.color.alpha = __intVal(a);
+
+    if ( __isStringLike(aString) ) {
+        XftDrawString8((XftDraw*)__INST(address_), &clr, XFT_FONT(fontIdArg),
+                        __x, __y,
+                        __stringVal(aString) + (_start - 1), _stop - _start + 1);
+        RETURN ( self );
+    } else {
+        error = @symbol(BadArg1);
+        goto err;
+    }
+    err:;
+#endif
+%}.
+    self primitiveFailed: error.
+
+    "Created: / 28-12-2013 / 12:32:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+    "Modified: / 30-12-2013 / 20:00:49 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+setClipRect:rect
+    | error xObj yObj wObj hObj  |
+
+    rect notNil ifTrue:[
+        xObj := rect left.
+        yObj := rect top.
+        wObj := rect width.
+        hObj := rect height.
+    ].
+%{ /* STACK: 64000 */
+#ifdef XFT
+    if (__INST(address_) == 0) {
+        error = @symbol(BadHandle);
+        goto err;
+    }
+    if (rect != nil) {
+        XRectangle r;
+
+        r.x = __intVal(xObj);
+        r.y = __intVal(yObj);
+        r.width = __intVal(wObj);
+        r.height = __intVal(hObj);
+        XftDrawSetClipRectangles((XftDraw*)__INST(address_), 0, 0, &r, 1);
+    } else {
+        XftDrawSetClipRectangles((XftDraw*)__INST(address_), 0, 0, (XRectangle*)NULL, 0);
+    }
+    RETURN ( self );
+    err:;
+#endif
+%}.
+    self primitiveFailed: error.
+
+    "Created: / 31-12-2013 / 01:24:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
 !XftFontDescription class methodsFor:'documentation'!
 
 version