--- a/XftFontDescription.st Tue Dec 24 12:16:04 2013 +0100
+++ b/XftFontDescription.st Sun Dec 29 12:03:28 2013 +0100
@@ -1,7 +1,8 @@
"{ Package: 'stx:libview' }"
FontDescription subclass:#XftFontDescription
- instanceVariableNames:'device fontId drawId'
+ instanceVariableNames:'device fontId drawId lasrFgColor lastFgColorId lastBgColor
+ lastBgColorId'
classVariableNames:''
poolDictionaries:''
category:'Graphics-Support'
@@ -20,13 +21,24 @@
#undef Time
#define Time XTime
+
#ifdef XFT
+# define __externalAddressValCasted(type, externalAddress) \
+ ((type)__externalAddressVal(externalAddress))
+# define DISPLAY(x) __externalAddressValCasted(Display*, x)
+# define SCREEN(x) ((int)(__intVal(x)))
+# define DRAWABLE(x) __externalAddressValCasted(Drawable, x)
+# define GC(x) __externalAddressValCasted(GC, x)
+# define VISUAL(x) __externalAddressValCasted(Visual*, x)
+# define COLORMAP(x) __externalAddressValCasted(Colormap, x)
+# define XFT_FONT(x) __externalAddressValCasted(XftFont*, x)
+# define XFT_PATTERN(x) __externalAddressValCasted(XftPattern*, x)
+# define XFT_DRAW(x) __externalAddressValCasted(XftDraw*, x)
+# define XFT_COLOR(x) __externalAddressValCasted(XftColor*, x)
+
# include <X11/Xft/Xft.h>
# include <X11/Xft/XftCompat.h>
-# define __XftFontVal(handle) ((XftFont*)__externalAddressVal(handle))
-# define __XftPatternVal(handle) ((XftPattern*)__externalAddressVal(handle))
-# define __XftDrawVal(handle) ((XftDraw*)__externalAddressVal(handle))
-# define __XftColorVal(handle) ((XftColor*)__externalAddressVal(handle))
+
#endif
%}
@@ -81,7 +93,7 @@
textView := EditTextView new.
textView origin:0.0 @ 0.0 corner:1.0 @ 1.0.
- textView basicFont: (XftFontDescription family: 'helvetica' size: 30).
+ textView basicFont: (XftFontDescription family: 'helvetica' size: 16).
top addSubView:textView.
@@ -90,6 +102,65 @@
top open.
"Created: / 20-12-2013 / 00:04:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 29-12-2013 / 10:28:41 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!XftFontDescription methodsFor:'displaying'!
+
+displayString:aString from:index1 to:index2 x:x y:y in:aGC opaque:opaque
+ "display a partial string at some position in aGC."
+
+ | y0 extents |
+
+ y0 := y - self ascent.
+
+ drawId isNil ifTrue:[
+ drawId := self xftDrawCreate: device displayId screen: device screen drawable: aGC id.
+ ] ifFalse:[
+ self xftDrawChange: drawId drawable: aGC id
+ ].
+ lasrFgColor ~= aGC paint ifTrue:[
+ lastFgColorId notNil ifTrue:[
+ self xftColorDestroy: device displayId screen: device screen color: lastFgColorId.
+ ].
+ lasrFgColor := aGC paint.
+ lastFgColorId := self xftColorCreate: device displayId screen: device screen color: lasrFgColor.
+ ].
+ extents := self xftTextExtents: device displayId font: fontId string: aString from: index1 to: index2.
+
+ opaque ifTrue:[
+
+ lastBgColor ~= aGC backgroundPaint ifTrue:[
+ lastBgColorId notNil ifTrue:[
+ self xftColorDestroy: device displayId screen: device screen color: lastBgColorId.
+ ].
+ lastBgColor := aGC backgroundPaint.
+ lastBgColorId := self xftColorCreate: device displayId screen: device screen color: lastBgColor.
+ ].
+ self xftDrawRect: drawId color: lastBgColorId x: x y:y0 width: extents first height: extents second
+
+ ].
+ "true"false ifTrue:[
+ | w p |
+
+ w := self widthOf: aString from: index1 to: index2.
+ p := aGC paint.
+ aGC paint: Color red.
+ aGC displayLineFromX: x y: y toX: x + w y: y.
+ aGC paint: Color blue.
+ aGC displayLineFromX: x y: y - self ascent toX: x + w y: y - self ascent.
+ aGC paint: Color yellow.
+ aGC displayLineFromX: x y: y + self descent toX: x + w y: y + self descent.
+
+
+ aGC paint: p.
+
+
+ ].
+ self xftDrawString: drawId color: lastFgColorId font: fontId x: x y: y string: aString from: index1 to: index2
+
+ "Created: / 21-12-2013 / 21:11:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 29-12-2013 / 11:38:43 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!XftFontDescription methodsFor:'error reporting'!
@@ -135,7 +206,7 @@
] ifFalse:[
self xftPatternAdd: myPatternId attribute: 'size' value: size.
].
- newFontId := self xftFontOpenPattern: aGraphicsDevice displayId pattern: myPatternId.
+ newFontId := self xftFontOpenPattern: aGraphicsDevice displayId pattern: myPatternId.
newFontId notNil ifTrue:[
"/ Good, this font exist!!
fontId := newFontId.
@@ -159,7 +230,7 @@
newFontId isNil ifTrue:[
self error: 'Pattern matched, but font could be open (should not happen)'.
].
- ^ self class new
+ ^ self class new
setDevice: aGraphicsDevice patternId: closestPatternId2 fontId: newFontId;
yourself.
].
@@ -194,7 +265,7 @@
device := deviceArg.
fontId := fontIdArg.
- family := self xftPatternGet: patternIdArg attribute: 'family' index: 0.
+ family := self xftPatternGet: patternIdArg attribute: 'family' index: 0.
size := self xftPatternGet: patternIdArg attribute: 'size' index: 0.
face := self xftPatternGet: patternIdArg attribute: 'slant' index: 0.
face == 0 ifTrue:[ face := 'roman'].
@@ -219,6 +290,251 @@
"Created: / 20-12-2013 / 21:10:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
!
+xftColorCreate: displayId screen: screen color: color
+
+ | error r g b a |
+
+ self primitiveFailedIfNoXft.
+
+ r := color scaledRed.
+ g := color scaledGreen.
+ b := color scaledBlue.
+ a := color alpha * 65535.
+%{
+#ifdef XFT
+ XRenderColor xrcolor;
+ XftColor *xftcolor;
+
+ if ( ! __isExternalAddressLike(displayId) ) {
+ error = @symbol(BadArg1);
+ goto err;
+ }
+ if ( ! __isSmallInteger(screen) ) {
+ error = @symbol(BadArg2);
+ goto err;
+ }
+ xrcolor.red = __intVal(r);
+ xrcolor.green = __intVal(g);
+ xrcolor.blue = __intVal(b);
+ xrcolor.alpha = __intVal(a);
+
+ xftcolor = (XftColor*) malloc( sizeof( XftColor ) );
+ XftColorAllocValue ( DISPLAY( displayId ) ,
+ DefaultVisual( DISPLAY( displayId), SCREEN (screen) ) ,
+ DefaultColormap( DISPLAY( displayId), SCREEN (screen) ),
+ &xrcolor,
+ xftcolor );
+ RETURN ( __MKEXTERNALADDRESS( xftcolor ) );
+ err:;
+#endif
+%}.
+ self primitiveFailed: error
+
+ "Created: / 28-12-2013 / 11:55:46 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+xftColorDestroy: displayId screen: screen color: xftColorId
+
+ | error |
+
+ self primitiveFailedIfNoXft.
+
+%{
+#ifdef XFT
+ XRenderColor xrcolor;
+ XftColor *xftcolor;
+
+ if ( ! __isExternalAddressLike(displayId) ) {
+ error = @symbol(BadArg1);
+ goto err;
+ }
+ if ( ! __isSmallInteger(screen) ) {
+ error = @symbol(BadArg2);
+ goto err;
+ }
+ if ( ! __isExternalAddressLike(xftColorId) ) {
+ error = @symbol(BadArg3);
+ goto err;
+ }
+
+ XftColorFree ( DISPLAY( displayId ) ,
+ DefaultVisual( DISPLAY( displayId), SCREEN (screen) ) ,
+ DefaultColormap( DISPLAY( displayId), SCREEN (screen) ),
+ XFT_COLOR( xftColorId ) );
+ free( __externalAddressVal( xftColorId ) );
+ __externalAddressVal( xftColorId ) = NULL;
+ RETURN ( self );
+ err:;
+#endif
+%}.
+ self primitiveFailed: error
+
+ "Created: / 28-12-2013 / 12:21:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+xftDrawChange: xftDrawId drawable: drawableId
+
+ | error |
+
+ self primitiveFailedIfNoXft.
+%{
+#ifdef XFT
+ if ( ! __isExternalAddressLike(xftDrawId) ) {
+ error = @symbol(BadArg1);
+ goto err;
+ }
+ 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 |
+
+ self primitiveFailedIfNoXft.
+%{
+#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 ( __MKEXTERNALADDRESS( 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>"
+!
+
+xftDrawRect: drawIdArg color: colorIdArg x: x y: y width: w height: h
+
+ | error extents |
+
+ self primitiveFailedIfNoXft.
+%{
+#ifdef XFT
+ if ( ! __isExternalAddressLike(drawIdArg) ) {
+ error = @symbol(BadArg1);
+ goto err;
+ }
+ if ( ! __isExternalAddressLike(colorIdArg) ) {
+ error = @symbol(BadArg2);
+ 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;
+ }
+ XftDrawRect(XFT_DRAW(drawIdArg), XFT_COLOR(colorIdArg),
+ __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>"
+!
+
+xftDrawString: drawIdArg color: colorIdArg font: fontIdArg x: x y: y string: text from: start to: stop
+
+ | error extents |
+
+ self primitiveFailedIfNoXft.
+%{
+#ifdef XFT
+ int _start, _stop;
+ int _x, _y;
+ if ( ! __isExternalAddressLike(drawIdArg) ) {
+ error = @symbol(BadArg1);
+ goto err;
+ }
+ if ( ! __isExternalAddressLike(colorIdArg) ) {
+ error = @symbol(BadArg2);
+ goto err;
+ }
+ if ( ! __isExternalAddressLike(fontIdArg) ) {
+ error = @symbol(BadArg3);
+ 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);
+
+ if ( __isString(text) ) {
+ XftDrawString8(XFT_DRAW(drawIdArg), XFT_COLOR(colorIdArg), 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: / 29-12-2013 / 11:29:57 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
xftFontGetAscent: fontIdArg
| error |
@@ -231,7 +547,7 @@
error = @symbol(BadArg1);
goto err;
}
- v = ((XftFont*)__externalAddressVal(fontIdArg))->ascent;
+ v = XFT_FONT(fontIdArg)->ascent;
RETURN ( __MKINT( v ) );
err:;
#endif
@@ -253,7 +569,7 @@
error = @symbol(BadArg1);
goto err;
}
- v = ((XftFont*)__externalAddressVal(fontIdArg))->descent;
+ v = XFT_FONT(fontIdArg)->descent;
RETURN ( __MKINT( v ) );
err:;
#endif
@@ -275,7 +591,7 @@
error = @symbol(BadArg1);
goto err;
}
- v = ((XftFont*)__externalAddressVal(fontIdArg))->height;
+ v = XFT_FONT(fontIdArg)->height;
RETURN ( __MKINT( v ) );
err:;
#endif
@@ -297,7 +613,7 @@
error = @symbol(BadArg1);
goto err;
}
- p = ((XftFont*)__externalAddressVal(fontIdArg))->pattern;
+ p = XFT_FONT(fontIdArg)->pattern;
if (p == NULL) {
RETURN ( nil );
} else {
@@ -334,7 +650,7 @@
goto err;
}
- p = XftFontMatch( __externalAddressVal(displayId) , __intVal( screen ), __externalAddressVal( patternId ), &r );
+ p = XftFontMatch( DISPLAY(displayId) , SCREEN( screen ), XFT_PATTERN( patternId ), &r );
if (r == XftResultMatch) {
RETURN ( __MKEXTERNALADDRESS ( p ) );
} else {
@@ -368,7 +684,7 @@
goto err;
}
- f = XftFontOpenPattern( __externalAddressVal(displayId) , __externalAddressVal( patternId ) );
+ f = XftFontOpenPattern( DISPLAY(displayId) , XFT_PATTERN( patternId ) );
if (f == NULL) {
RETURN ( nil );
} else {
@@ -438,7 +754,7 @@
error = @symbol(BadArg3);
goto err;
}
- b = XftPatternAdd( __externalAddressVal(pattern), __stringVal(attribute), v, append == true ? True : False );
+ b = XftPatternAdd( XFT_PATTERN(pattern), __stringVal(attribute), v, append == true ? True : False );
RETURN ( b == True ? true : false );
err:;
@@ -477,7 +793,7 @@
error = @symbol(BadArg2);
goto err;
}
- XftPatternDel( __externalAddressVal(pattern), __stringVal ( attribute ) );
+ XftPatternDel( XFT_PATTERN(pattern), __stringVal ( attribute ) );
RETURN ( self );
err:;
@@ -501,7 +817,7 @@
error = @symbol(BadArg1);
goto err;
}
- XftPatternDestroy( __externalAddressVal(addr) );
+ XftPatternDestroy( XFT_PATTERN(addr) );
RETURN ( self );
err:;
@@ -526,7 +842,7 @@
error = @symbol(BadArg1);
goto err;
}
- RETURN ( __MKEXTERNALADDRESS ( XftPatternDuplicate( __externalAddressVal(addr) ) ) );
+ RETURN ( __MKEXTERNALADDRESS ( XftPatternDuplicate( XFT_PATTERN(addr) ) ) );
err:;
#endif
%}.
@@ -559,7 +875,7 @@
error = @symbol(BadArg3);
goto err;
}
- r = XftPatternGet(__externalAddressVal( pattern ), __stringVal( attribute ), __intVal( index ), &v);
+ r = XftPatternGet(XFT_PATTERN(pattern), __stringVal( attribute ), __intVal( index ), &v);
if ( r != XftResultMatch) {
RETURN ( nil );
}
@@ -584,6 +900,61 @@
"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 |
+
+ self primitiveFailedIfNoXft.
+ extents := Array new: 6.
+%{
+#ifdef XFT
+ XGlyphInfo info;
+ int _start, _stop;
+ if ( ! __isExternalAddressLike(displayIdArg) ) {
+ error = @symbol(BadArg1);
+ goto err;
+ }
+ if ( ! __isExternalAddressLike(fontIdArg) ) {
+ error = @symbol(BadArg2);
+ goto err;
+ }
+ if ( ! __isSmallInteger(start) ) {
+ error = @symbol(BadArg4);
+ goto err;
+ }
+ _start = __intVal(start);
+ if ( ! __isSmallInteger(stop) ) {
+ error = @symbol(BadArg5);
+ goto err;
+ }
+ _stop = __intVal(stop);
+ if ( __isString(text) ) {
+ XftTextExtents8(DISPLAY(displayIdArg), XFT_FONT(fontIdArg),
+ __stringVal(text) + (_start - 1), _stop - _start + 1, &info);
+ } else {
+ error = @symbol(BadArg3);
+ goto err;
+ }
+ __ArrayInstPtr(extents)->a_element[0] = __MKSMALLINT(info.width);
+ __ArrayInstPtr(extents)->a_element[1] = __MKSMALLINT(info.height);
+ __ArrayInstPtr(extents)->a_element[2] = __MKSMALLINT(info.x);
+ __ArrayInstPtr(extents)->a_element[3] = __MKSMALLINT(info.y);
+ __ArrayInstPtr(extents)->a_element[4] = __MKSMALLINT(info.xOff);
+ __ArrayInstPtr(extents)->a_element[5] = __MKSMALLINT(info.yOff);
+ error = nil;
+ err:;
+#endif
+%}.
+ error notNil ifTrue:[
+ self primitiveFailed: error.
+ ^ nil.
+ ].
+ ^ extents
+
+ "Created: / 21-12-2013 / 10:42:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 21-12-2013 / 20:53:28 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!XftFontDescription methodsFor:'queries-dimensions'!
@@ -610,15 +981,36 @@
^ self xftFontGetHeight: fontId
"Created: / 21-12-2013 / 01:20:21 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+isFixedWidth
+ "return true, if this is a fixed pitch font (i.e. all characters
+ are of the same width)"
+
+ ^ false "/ How to check?
+
+ "Created: / 21-12-2013 / 10:38:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+widthOf:aString from:start to:stop
+ "return the width of a sub string"
+
+ | extents |
+
+ extents := self xftTextExtents: device displayId font: fontId string: aString from: start to: stop.
+ "/ extents --> #(width height x y xOff yOff)
+ ^ extents first.
+
+ "Created: / 21-12-2013 / 10:42:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
! !
!XftFontDescription class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libview/XftFontDescription.st,v 1.3 2013-12-21 00:21:22 vrany Exp $'
+ ^ '$Header: /cvs/stx/stx/libview/XftFontDescription.st,v 1.4 2013-12-29 11:03:28 vrany Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libview/XftFontDescription.st,v 1.3 2013-12-21 00:21:22 vrany Exp $'
+ ^ '$Header: /cvs/stx/stx/libview/XftFontDescription.st,v 1.4 2013-12-29 11:03:28 vrany Exp $'
! !