As I've mentioned in a previous email to the list, I've been working on
Xft support for Linux as a way to get nicer rendered fonts. So far I
have the Xft primitives implemented so that you can render Xft fonts
using the API. I don't yet have it hooked up with the Self font system
to display in the outliners though. I'm not sure if I'll get time to
work on that over the next couple of weeks so I've made the current
progress available on github in case anyone wants to hack on it:
<http://github.com/doublec/self/tree/linux_fonts>
Clone with:
$ git clone git://github.com/doublec/self
$ cd self
$ git checkout -b linux_fonts origin/linux_fonts
The steps I take to display a font using the primitives are:
1) Create this object, drag it to the desktop and open an evaluator on it:
(| parent* = traits oddball.
window <- desktop w anyWindowCanvas.
draw <- nil.
font <- nil.
xftcolor <- nil.
xrcolor <- nil.
|)
2) In the evaluator of the above object, create a draw object:
draw: window display
xftDrawCreate: window platformWindow
Visual: window display screen defaultVisualOfScreen
Colormap: window display screen defaultColormapOfScreen
3) Create the color objects:
xftcolor: xlib xftColor new.
xrcolor: xlib xRenderColor new.
4) Set the alpha of the xRenderColor:
xrcolor alpha: 16rffff
5) Set the xftColor:
window display
xftColorAllocValue: window display screen defaultVisualOfScreen
Colormap: window display screen defaultColormapOfScreen
RenderColor: xrcolor
XftColor: xftcolor
6) Load a font:
font: window display
xftFontOpenNameOnScreen: window display screen number
Name: 'verdana-18'
7) Display a string using the given font:
draw xftDrawString8: xftcolor
Font: font X: 100 Y: 100
String: 'Hello World!'
I've added support to the cmake files to look for Xft and Freetype. It
works on my system but I'm not entirely sure it's accurate.
Any thoughts on how best to plug this into the Self font system?
Chris.
--
http://www.bluishcoder.co.nz
I'm attempting to add some types and functions to xlibTemplates.self. It
took me a while to understand how some things work and am hopeful that
someone can help me see if I'm on the right path.
I'm adding a type, 'XftFont' and some functions that operate on it. In
xlib_glue.cpp I added the 'template(XftFont). In xlibTemplates.self I
added a test accessor:
traits: traits xlib xftFont
visibility: publicSlot
XftFont ascent = int getMember ascent
For this to work I needed to add a 'traits xlib xftFont' object in my
world. Running the template script successfully added the 'ascent'
method to the trait so I think I understand that area ok.
Next step was to add a method to the template that created an XftFont
object:
Display xftFontOpenOnScreen: int \
Name: string \
= XftFont {xlib xftFont deadCopy} \
call XftFontOpenName canAWS
I see some template definitions use something like:
= proxy XftFont* XftFont_seal \
{xlib xftFont deadCopy} \
call XftFontOpenName canAWS
Are 'proxy XftFont* XftFont_seal' and 'XftFont' funtionally equivalent?
When would you use one over the other?
I'm using 'string' in the definition. Other templates use 'string_null'
and 'string_len_null'. What's the difference?
For this definition to work I needed to have an 'xlib xftFont' object in
the world. I struggled to find out how to create one of these that
worked but eventually I found that I needed to:
1) Create an object that is a 'copy down' parent of 'proxy' using
'deadCopy' as the selector and ommitting 'parent'. This can be done by
changing the attributes of an object or using 'Subclass Me' from the
middle click menu of 'proxy'.
2) Change the 'parent' slot of the object to be 'traits xftFont' I
created earlier.
If I didn't do (1) above and instead just 'copy' the 'proxy' object and
change the parent slot then the foreign function calls would fail with a
type error.
Once I did these steps and rebuilt the VM plus world then calling the
function gave me an XftFont object I could inspect, success!
I notice that most of the slots in 'xlib' have 'dead 'or 'alive' in the
name. My 'xlib xftFont' object didn't have this until I set 'Complete'
to 'Yes' in the attributes. What does 'Complete' mean?
Does the above sound right for integrating a new foreign object and
functions into the VM?
--
http://www.bluishcoder.co.nz
I tried the Self download for OS X on selflanguage.org but hit some
problems and am wondering if I'm doing something wrong.
The download page [1] mentions a 'Self' script being installed in
/usr/bin but I don't see it after installing. I also needed to download
and install XQuartz as OS X 10.8 doesn't include the X11 app.
Once XQuartz was installed the Self snapshot ran. Love the look and the
fonts compared to the Linux version! The two finger scrolling on the
trackpad for vertically and horizontally scrolling the world is also
fantastic.
I tried dragging a label morph from the morph factory to the main self
window and I couldn't drag it outside the bounds of the morph factory
window. Is this broken in the latest version?
[1] http://selflanguage.org/download/index.html
--
http://www.bluishcoder.co.nz
I've done a pull request to fix an issue with requesting a property
sheet from a labelMorph on Linux giving an error:
<https://github.com/russellallen/self/pull/17>
This relates to issue 4 but I think that issue is actually a Mac OS X
backend problem. Can anyone confirm if on Mac OS X that the scalableFont
slot doesn't exist? I'm guessing the Mac backend doesn't use x11Globals?
--
http://www.bluishcoder.co.nz
I've implemented the ability to switch to fullscreen mode in X11
backends. I've tested on Ubuntu 12.10 and it seems to work fine. The
pull request is here:
<https://github.com/russellallen/self/pull/16>
This provides a 'toggleFullscreen' method on the xWindowCanvas. Sending
this message will enter or exit fullscreen mode. In fullscreen mode the
window decorations are removed and the window takes up the entire screen
area, covering any window manager panels, etc.
A followup from this would be to find the right place to put
'fullscreen' in the right place for the non-platform dependent backends
and implement it for the Mac OS X backend.
To enter fullscreen mode froma desktop in X11 you can do:
desktop w winCanvases first toggleFullscreen
Calling it again will exit. Fullscreen mode removes window decorations,
expands the window to the maximum size of the screen and displays on top
of any panels, docks, etc provided by the OS. It's a good mode for
kiosk applications or maxiimising the screen real estate.
Anyone want to tackle the Mac OS X side of it? Where would be a good
place in th UI2 hierarchy to place a generic 'fullscreen' method?
--
http://www.bluishcoder.co.nz
I've done a pull request with some bitrot fixes for 'applications/pep':
<https://github.com/russellallen/self/pull/14>
These changes allow loading some Java class files that have been
compiled with recent JVM's. Simple test cases work but I've been unable
to get java.lang.System.out to work. This seems to require calling
'initializeSystemClass' and I've added this where I think it should go
but I get an infinite loop when using it. I'm still debugging this but
thought I'd make what works at the moment available.
When testing, ensure that before starting Self you have your CLASSPATH
environment variable set to the location of the Java class library
.class files and the 'objects/applications/pep' directory. Something
like:
export CLASSPATH=/home/me/self/objects/applications/pep:/home/me/jvm/classes'
I obtained the Java library classes by extracting the contents of
'rt.jar' from a local java installation.
To test 'SimpleTest1' and 'SimpleTest2' make sure they're compiled:
cd objects/applications/pep
javac SimpleTest1
javac SimpleTest2
To load 'pep' in self:
bootstrap read: 'pep' From: 'applications/pep'
To test SimpleTest1 and SimpleTest2:
pep tests testSimpleTest1
pep tests testSimpleTest1
To test an arbitary Java class file:
pep tests testClassNamed: 'Foo'
To view loaded classes and drill down to see their methods and converted Self code, etc:
pep loadedClasses class_java_lang_System
Chris.
--
http://www.bluishcoder.co.nz
I'm having issues with debugging and wonder if anyone as any tips. When
running code that uses error blocks, like this:
doSomething: 'something' IfFail: [|:e| error: e ]
If the method has an error and calls the error block in IfFail then the
debugger pops up with a stack that stops at the line where the error
blocks is created (ie. the one above). It doesn't show a stack inside
'doSomething:IfFail:' where the error actually occured.
Is there a way to recover this information? At the moment if I run some
Self code that deep inside internals it does an [|:e| error: e] block
then I lose the context of where the error actually occured and only get
the context of where it is handled.
--
http://www.bluishcoder.co.nz
I've created a pull request that gets javaClient and javaServer working
for me:
<https://github.com/russellallen/self/pull/12>
It fixes minor bitrot. I've described how to get it working, with a
screencast, here:
<http://bluishcoder.co.nz/2013/09/16/multiple-users-in-a-self-world.html>
I'd really like to see an HTML/JavaScript version of the Java client to
move away from applets. It'd make a fun project and demo I think.
It would also help reduce the reliance on X11 for screen sharing so if a
move is made towards doing a non-X11 backend that functionality is still
possible.
With regards to a non-X11 backend I was wondering if SDL2 would be a
good option. It provides hardware acceleration cross platform and works
on Android as well as Windows.
Chris.
--
http://www.bluishcoder.co.nz
Sometimes I do something silly like expand the 'indexable' slot in an
outliner on a vector of thousands of elements. This locks up the UI and
the console for quite a long time as it builds the outliner for all the
elements in the vector.
Is there a way to cancel or interrupt this operation? Or a way to make
it not blocking?
--
http://www.bluishcoder.co.nz
Bignum performance in Self seems to be quite slow. Executing 1000
factorial on my laptop gives the following:
[ 1000 factorial ] time
=> 2228
On similar JIT'd languages that support bignums I get subsecond
results. Implementing similar to factorial to use '+' instead of '*' to
ensure that no bignums are created I get:
[ 1000 foo ] time
=> 0
Where 'foo' is a method on 'traits integer':
<= 1 ifTrue: 1 False: [ + predecessor foo ]
Has anyone got ideas on what the performance hit might be caused by?
Chris.
--
http://www.bluishcoder.co.nz