<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Rivulus Blog</title>
	<atom:link href="http://blog.rivulus-sw.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://blog.rivulus-sw.com</link>
	<description>A blog by the folks at Rivulus Software.</description>
	<lastBuildDate>Tue, 30 Mar 2010 18:01:16 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Nu Blocks and Objective-C Blocks, Part 2</title>
		<link>http://blog.rivulus-sw.com/?p=54</link>
		<comments>http://blog.rivulus-sw.com/?p=54#comments</comments>
		<pubDate>Tue, 30 Mar 2010 17:29:28 +0000</pubDate>
		<dc:creator>Philip</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Nu Blocks]]></category>

		<guid isPermaLink="false">http://blog.rivulus-sw.com/?p=54</guid>
		<description><![CDATA[OK, at last I&#8217;m finally writing part two. Boy it&#8217;s surprisingly difficult to update one&#8217;s blog regularly…
So in Part 1 I showed how you can write over the function pointer of a block with another function pointer and the block will still work. It&#8217;s probably also possible to construct a block from scratch, but I [...]]]></description>
			<content:encoded><![CDATA[<p>OK, at last I&#8217;m finally writing part two. Boy it&#8217;s surprisingly difficult to update one&#8217;s blog regularly…</p>
<p>So <a href="?p=22">in Part 1</a> I showed how you can write over the function pointer of a block with another function pointer and the block will still work. It&#8217;s probably also possible to construct a block from scratch, but I don&#8217;t really see any benefit to that.</p>
<p>So, how to make a C block that will call a Nu block?<span id="more-54"></span> Fortunately most of the work is already done; if you look into the <a href="http://github.com/timburks/nu">Nu source code</a> in the objc/bridge.m file you can see how Nu is rigged it up so that Objective-C code can call methods implemented in Nu. The magic happens with the help of libffi (Foreign Function Interface) a library that, among other things, allows one to construct C functions at runtime with arbitrary names and argument signatures. When one of these constructed functions gets called, libffi in turn calls a callback that had been specified earlier. This is that callback in Nu; all message sends from Objective-C to Nu pass through this function: </p>
<pre>static void objc_calling_nu_method_handler(ffi_cif* cif, void* returnvalue, void** args, void* userdata)</pre>
<p>The first argument is a libffi struct previously generated by the user (in Nu this happens in <em>construct_method_handler()</em>) that contains information about the function that libffi was to generate: return type, argument count and types, etc. The second argument is a pointer to where the return value should be written so that libffi can return it to the original caller. The third argument is an array of the argument values and the fourth is user-defined info. In Nu this fourth argument points to an array of pointers where the first element is the Objective-C type encoding of the return value (a c string), the second is the Nu implementation of the method (as a NuBlock) and the remaining elements are the Objective-C type encodings of the arguments (more c strings).<br />
In short, all of the information that the Nu runtime needs to pass control to the Nu method are there.</p>
<p>So what I did was copy all of this code and tweak it a little bit. Instead of having libffi make a function fit to serve as an Objective-C method (i.e. with an argument list like this: &#8220;id sender, SEL __cmd, …&#8221; (where the first two arguments are the message recipient and the selector of the message being sent, respectively) I had it make one like this: &#8220;id block, …&#8221; (recall from part 1 of this post that block <em>functions</em> take as a first, hidden argument a pointer to the associated block <em>object</em>). So in my code all calls to Objective-C blocks implemented in Nu pass through this function:</p>
<pre>static void objc_calling_nu_block_handler(ffi_cif* cif, void* returnvalue, void** args, void* userdata)</pre>
<p>This function in turns just calls the appropriate NuBlock (stored in element two of <em>userdata</em>).<br />
So all that&#8217;s left is to make a dummy Objective-C block and write the pointer to the libffi generated function into it. Here is the code that does that:</p>
<pre>
static id make_cblock (NuBlock *nuBlock, NSString *signature)
{
	void *funcptr = construct_block_handler(nuBlock, [signature UTF8String]);
	int i = 0xFFFF;
	void(^cBlock)(void)=[^(void){printf("%i",i);} copy];
	#ifdef __x86_64__
	//2*(sizeof(void*)) = 0x10
	*((void **)(id)cBlock + 2) = (void *)funcptr;
	#else
	//3*(sizeof(void*)) = 0xc
	*((void **)(id)cBlock + 3) = (void *)funcptr;
	#endif
	return cBlock;
}</pre>
<p>Why that variable <em>i</em> and why the <em>printf()</em>? All that jazz does is make sure the compiler generates a distinct block object every time that code is executed. If it thinks it can get away with it, it will reuse previously created blocks just like it may reuse string literals (try running this code: <em>id a=@&#8221;Hi&#8221;, b=@&#8221;Hi&#8221;;printf(&#8220;%lx,%lx&#8221;,a,b);</em>)<br />Well the printf doesn&#8217;t do anything and will never get called; it&#8217;s just an arbitrary expression using the <em>i</em> variable. What&#8217;s important is for the block to reference something from the surrounding context, something mutable that will be copied by value. If it does not reference a variable from the surrounding context, or if that variable has the <em>__block</em> qualifier (meaning that it should not be <em>copied</em>), then the compiler will reuse the same block object over and over again.</p>
<p>So that&#8217;s how it works. But wait, there is a hitch. The problem is that there appears to be a bug in the Objective-C runtime. Nu uses the runtime functions <em>method_getNumberOfArguments()</em> and <em>method_getArgumentType()</em> in the code that handles message sends from Nu to Objective-C. But these functions (at least as of 10.6.2) return incorrect values for any method expecting a block argument. The encoding type for blocks appears to be &#8220;@?&#8221; but those runtime functions (which I believe call <em>method_getTypeEncoding</em> and parse the string returned by that) treat that encoding as two separate encodings. Unless this gets fixed in 10.6.3 (my bug report has gone unanswered so far) I&#8217;m going to have to write some substitutes for those functions or make a patched version of libobjc.A.dylib. Well, I&#8217;m hoping I&#8217;ll have time to finish this up soon, and then maybe see if Tim Burks is interested in merging this into the main Nu branch.</p>
<p>For the time being, the version of Nu at my github repository (see sidebar) replaces the above-mentioned runtime functions with calls to similar NSMethodSignature methods. Unfortunately, this seems to raise other more mysterious problems in Nu. But it is useable enough to screw around with.</p>
<p>An Objective-C block can be created by sending the following message to the class NuBridgedBlock:</p>
<pre>+(id)cBlockWithNuBlock:(NuBlock*)nb signature:(NSString*)sig</pre>
<p>where <em>sig</em> is a string containing the Objective-C type encodings for the return value and arguments. This is a little cumbersome and I plan to implement a convenience macro, maybe something like this:</p>
<pre>(cblock int ((id) arg1 (NSRect) arg2) (--nu code here--))</pre>
<p>
Anyway, I have successfully called various Cocoa methods that expect blocks as well as libdispatch functions from Nu. I just need to work out the kinks and I think it might be pretty useful!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rivulus-sw.com/?feed=rss2&amp;p=54</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arcade Typing Tutor 2.0 Released!</title>
		<link>http://blog.rivulus-sw.com/?p=49</link>
		<comments>http://blog.rivulus-sw.com/?p=49#comments</comments>
		<pubDate>Mon, 15 Mar 2010 23:46:06 +0000</pubDate>
		<dc:creator>Philip</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Arcade Typing Tutor]]></category>
		<category><![CDATA[wxWidgets]]></category>

		<guid isPermaLink="false">http://blog.rivulus-sw.com/?p=49</guid>
		<description><![CDATA[The first version of Arcade Typing Tutor since I took over development from my brother is out. This version features prettier text,  bug fixes and a smattering of user-settable options. Click here to download the latest version or here to visit the ATT webpage.
When my brother wrote ATT he was pretty good about not using Cocoa [...]]]></description>
			<content:encoded><![CDATA[<p>The first version of Arcade Typing Tutor since I took over development from my brother is out. This version features prettier text,  bug fixes and a smattering of user-settable options. Click <a href="http://www.rivulus-sw.com/download/ArcadeTypingTutor.zip ">here</a> to download the latest version or <a href="http://www.rivulus-sw.com/Rivulus/Arcade_Typing_Tutor.html">here</a> to visit the ATT webpage.</p>
<p>When my brother wrote ATT he was pretty good about not using Cocoa where he didn&#8217;t need to meaning that the code base looks to be pretty portable. I&#8217;m considering creating a version of it using <a href="http://www.wxWidgets.org/">wxWidgets</a> for the UI bits. Then I could release a version for Windows and possibly FreeBSD/Linux, though I&#8217;m not sure how well shareware does on the free *nixes. Most likely I&#8217;ll continue using Cocoa for the Mac OS X interface, just to make sure it always looks 100% native.</p>
<p>I&#8217;ll do some posting on wxWidgets as I get into. It should be interesting, especially since I haven&#8217;t done much in the way of C++ programming since my teens.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rivulus-sw.com/?feed=rss2&amp;p=49</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Arcade Typing Tutor is changing management…</title>
		<link>http://blog.rivulus-sw.com/?p=43</link>
		<comments>http://blog.rivulus-sw.com/?p=43#comments</comments>
		<pubDate>Tue, 09 Mar 2010 16:41:42 +0000</pubDate>
		<dc:creator>Philip</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Arcade Typing Tutor]]></category>

		<guid isPermaLink="false">http://blog.rivulus-sw.com/?p=43</guid>
		<description><![CDATA[Perhaps some of you have noticed that Arcade Typing Tutor was not quite one with the other Rivulus products. Well that&#8217;s because I had just been hosting the webpage for ATT on the Rivulus website. ATT was actually made by my brother and other than the management of the webpage, he had been handling all [...]]]></description>
			<content:encoded><![CDATA[<p>Perhaps some of you have noticed that Arcade Typing Tutor was not quite one with the other Rivulus products. Well that&#8217;s because I had just been hosting the webpage for ATT on the Rivulus website. ATT was actually made by my brother and other than the management of the webpage, he had been handling all aspects of it. Well, he is a medical intern now and is finding that he doesn&#8217;t have a lot of time to fix bugs and respond to customers, so he has handed over the reins to us. <span id="more-43"></span></p>
<p>Top priority is making ATT 100% Snow Leopard compatible. It works on Snow Leopard, but the text does not highlight to show you where you are in a word. Fixing that, plus a little spit and polish, and it&#8217;ll be ready for a new release.</p>
<p>We also have big plans for expanding ATT; things my brother has wanted to do for years but hasn&#8217;t had the time. Here&#8217;s a peek: options for different keys (right hand/left hand/home keys/etc…), more advanced logging of scores and maybe some others. Of course, ATT is a pretty awesome program and I don&#8217;t want to overwork it into something less awesome.</p>
<p>Please send suggestions if you have them!</p>
<p>Stay tuned: there may be a release as early as this weekend.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rivulus-sw.com/?feed=rss2&amp;p=43</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ssh over a High-Latency Connection</title>
		<link>http://blog.rivulus-sw.com/?p=39</link>
		<comments>http://blog.rivulus-sw.com/?p=39#comments</comments>
		<pubDate>Tue, 02 Mar 2010 19:32:26 +0000</pubDate>
		<dc:creator>Philip</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[FreeBSD]]></category>
		<category><![CDATA[PuTTY]]></category>
		<category><![CDATA[satellite]]></category>
		<category><![CDATA[ssh]]></category>

		<guid isPermaLink="false">http://blog.rivulus-sw.com/?p=39</guid>
		<description><![CDATA[I&#8217;m in the process of transferring this blog and the Rivulus website over to a RootBSD VPS. I like my current web host, Little Oak, and strongly recommend them to anyone who needs basic web hosting service: they are Mac-friendly and provide great customer service; but I really was starting to feel hindered by not [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m in the process of transferring this blog and the Rivulus website over to a <a href="http://www.rootbsd.net/">RootBSD</a> VPS. I like my current web host, <a href="http://www.littleoak.net/">Little Oak</a>, and strongly recommend them to anyone who needs basic web hosting service: they are Mac-friendly and provide great customer service; but I really was starting to feel hindered by not having full shell access. I mean, I really need the ability to trash my entire website with an errant &#8216;/&#8217;… <span id="more-39"></span></p>
<p>So anyway, I&#8217;m going to a VPS. And since Linux is just way too popular (and I have a mild philosophical disagreement with the GNU license), I decided that I had to have FreeBSD. RootBSD seems to be one of a handful of places offering FreeBSD VPSes. After about 24 hours, I am absolutely thrilled with what I&#8217;ve got.</p>
<p>Now, to the subject of this post. Living deep in the boonies, I use satellite for all my internet access. Overall I&#8217;m quite pleased with the service, though I wish it cost about a 1/3 of what it does. The major downside is the latency: pings to my VPS are running between 700 and 1110 ms. This makes ssh very difficult to use: press a key, it takes about a second for it register on the terminal. My solution has been to use putty (PuTTY, if you insist) with local echo and local line editing enabled. The local line editing tends to cause problems with anything other than the command line (emacs, ports install screens, etc.), so I&#8217;ve been keeping both putty and ssh from Terminal.app open whenever I&#8217;m working on the VPS. Together, they make for a useable setup.</p>
<p>So, if you&#8217;re in my boat, give putty a try. It kind of feels like a Windows 3.1 app and it never seems to save settings, but I can&#8217;t complain.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rivulus-sw.com/?feed=rss2&amp;p=39</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nu Blocks and Objective-C Blocks, Part 1</title>
		<link>http://blog.rivulus-sw.com/?p=22</link>
		<comments>http://blog.rivulus-sw.com/?p=22#comments</comments>
		<pubDate>Sat, 20 Feb 2010 23:57:25 +0000</pubDate>
		<dc:creator>Philip</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Blocks]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Nu]]></category>

		<guid isPermaLink="false">http://blog.rivulus-sw.com/?p=22</guid>
		<description><![CDATA[I hope to devote a fair amount of time on this blog to the Cocoa-based programming/scripting languages F-Script and Nu. So to get started, today&#8217;s entry is on a little bit of investigation I did into bridging Nu&#8217;s native blocks with the Objective-C blocks that Apple introduced with Snow Leopard.
A quick description of blocks for [...]]]></description>
			<content:encoded><![CDATA[<p>I hope to devote a fair amount of time on this blog to the Cocoa-based programming/scripting languages <a href="http://www.fscript.org/">F-Script</a> and <a href="http://programming.nu">Nu</a>. So to get started, today&#8217;s entry is on a little bit of investigation I did into bridging Nu&#8217;s native blocks with the Objective-C blocks that Apple introduced with Snow Leopard.</p>
<p>A quick description of blocks for those who don&#8217;t know what they are:<span id="more-22"></span> also called closures, anonymous functions or lambda functions, blocks are a means of creating a chunk of code inside of other code. The power of blocks is that they can reference context information (i.e. local variables) in the surrounding code.</p>
<p>Blocks are common in high-level languages but until now there had been no mainstream implementation of them in the C family of languages. Here is a simple example of an Objective-C block in action copied from one of my projects:</p>
<pre>NSMutableAttributedString *fixedText=[unfixedText mutableCopy];
__block id oldAttrName, newAttrName;
__block int checked,fixed;
id attrBlock = ^(id value, NSRange range, BOOL *stop)
{
	if (value == nil)
		return;
	checked++;

	NSRange goodRange = [plainText rangeOfComposedCharacterSequencesForRange:range];
	if (!NSEqualRanges(range, goodRange))
		fixed++;

	[fixedText removeAttribute:oldAttrName range:range];
	[fixedText addAttribute:newAttrName value:value range:goodRange];
};
//verse
oldAttrName = @"HebrewVerseAttribute",
newAttrName = @"HRVerse";
checked=0;
fixed=0;
[unfixedText enumerateAttribute:oldAttrName
			inRange:NSMakeRange(0, [unfixedText length])
			options:0
		    usingBlock:attrBlock];
printf("\nChecked %i verse attributes\nFixed %i\n",checked,fixed);

//segment/sentence
oldAttrName = @"HebrewSentenceAttribute",
newAttrName = @"HRSegment";
checked=0;
fixed=0;
[unfixedText enumerateAttribute:oldAttrName
			inRange:NSMakeRange(0, [unfixedText length])
			options:0
		    usingBlock:attrBlock];
printf("\nChecked %i sentence attributes\nFixed %i\n",checked,fixed);
</pre>
<p>I like this code snippet because it uses a Cocoa method that takes blocks and because it does something that would have been a bit more tedious without blocks. I&#8217;m not going to step through the whole thing but here are a few quick notes. Note the &#8216;__block&#8217; keyword. If you don&#8217;t use this keyword a block will still have access to that variable, but only via a copy of it. Hence any changes made to that variable after the block is created will not be reflected in the block. Also, the compiler will raise an error if code in the block tries to change the value of the variable.</p>
<p>Be aware that blocks are Objective-C objects; you might notice I use a variable of type &#8216;id&#8217; to store the block reference. This is convenient and fine for this situation but you should note that you cannot call a block unless it is specifically cast as a block type. So if I wanted to directly call that block above rather than just passing it on to Cocoa to call, I would have declared the variable like so:</p>
<pre>void(^attrBlock)(id,NSRange,BOOL*) = …</pre>
<p>You can see why I used &#8216;id&#8217;. It also happens to be the case that the compiler doesn&#8217;t like you casting a block to an arbitrary pointer type (e.g. void*, int*, etc), but it has no problem with you <em>first</em> casting it to &#8216;id&#8217; and <em>then</em> to some other pointer type; a useful thing to know if you want to hackishly write over parts of your block…</p>
<p>So what happens when you call a block? Here is the disassembly of a block call in some x86-64 code:</p>
<pre>mov    %rax,-0x18(%rbp)		 //the pointer to the block object is in rax
mov    -0x18(%rbp),%rax
mov    0x10(%rax),%rax		//the pointer to the block function is at +0x10 into the block object
mov    -0x18(%rbp),%rdi		//the first argument (this example has no others)
					//is always the pointer to the block object
callq  *%rax</pre>
<p>Ah! So the block contains a function pointer and when that function is called, the pointer to the block is passed as the first argument. So let&#8217;s run a little test:</p>
<pre>void foo(id block, int x)
{
	printf("thrice %i is %i\n",x, 3*x);
}

int main (int argc, const char * argv[])
{
	void(^b)(int) = ^(int x){printf("twice %i is %i\n",x,2*x);};
	b(5);
	*((void**)(id)b+2) = (void*)foo;
	b(5);
};</pre>
<p>Guess what this prints out? Cool, huh?</p>
<p>So what&#8217;s this *((void**)(id)b+2) monkey business? Well we are casting b to type &#8216;id&#8217; and then to type &#8216;void**&#8217;. We then offset the pointer by 2 units, remembering that in C when you add <em>n</em> to a pointer it actually adds <em>n</em> times the size of the type the pointer points to. A &#8216;void**&#8217; points to a &#8216;void*&#8217; which on x86-64 is 8 bytes long. Twice that is 16 or 0&#215;10 bytes, the correct offset to the function pointer inside of the block object. So I just took another function pointer, making sure it takes the correct arguments, and wrote that into the correct place in the block. And the block still works! Amazing!</p>
<p>So maybe you see where I&#8217;m going with this. At the beginning of this post I mentioned that I was trying to bridge Nu blocks and Obj-C blocks. What that means exactly is that I want to be able to use the new Cocoa methods that take Obj-C blocks and call them from Nu code, passing them Nu blocks. So I basically need to generate Obj-C blocks at runtime that will call Nu blocks. But it&#8217;s not as simple as it sounds at first. The generated Obj-C blocks need a signature (parameter list) that matches what the Nu blocks expect.</p>
<p>Next post I&#8217;ll show you how I did this, mainly by reusing Tim Burks&#8217; code that allows C code to call Nu methods.</p>
<p>Stay tuned for more!</p>
<p>UPDATE:<br />
<a href="http://blog.rivulus-sw.com/?p=54">Part 2!</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rivulus-sw.com/?feed=rss2&amp;p=22</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>USB Power Outlet</title>
		<link>http://blog.rivulus-sw.com/?p=14</link>
		<comments>http://blog.rivulus-sw.com/?p=14#comments</comments>
		<pubDate>Sun, 07 Feb 2010 04:13:11 +0000</pubDate>
		<dc:creator>Philip</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Outlet]]></category>
		<category><![CDATA[USB]]></category>

		<guid isPermaLink="false">http://blog.rivulus-sw.com/?p=14</guid>
		<description><![CDATA[So the latest (March &#8216;10) issue of Macworld has a highlight on FastMac&#8217;s new TruePower UCS Power Outlet, which is a regular duplex outlet plus two power-only usb ports. Here is a picture pulled off of FastMac&#8217;s website. 

Pretty slick, I thought to myself. Then I started thinking about how you would probably want it [...]]]></description>
			<content:encoded><![CDATA[<p>So the latest (March &#8216;10) issue of Macworld has a highlight on <a href="http://www.fastmac.com">FastMac&#8217;s</a> new TruePower UCS Power Outlet, which is a regular duplex outlet plus two power-only usb ports. Here is a picture pulled off of FastMac&#8217;s website.<span id="more-14"></span> </p>
<p><img src="http://blog.rivulus-sw.com/wp-content/uploads/2010/02/9CD0CD4F-7DD6-463B-A7D8-E67D2A0B1A74.jpg" alt="9CD0CD4F-7DD6-463B-A7D8-E67D2A0B1A74.jpg" border="0" width="160" height="213" /></p>
<p>Pretty slick, I thought to myself. Then I started thinking about how you would probably want it wired to a switch to prevent the power vampirism that afflicts most AC/DC converters. And then maybe you&#8217;d want to rig up a little LED in the outlet to help you remember if it&#8217;s on or not (this picture makes it look like it might have an LED in upper right corner). But no, according to FastMac&#8217;s <a href="http://store.fastmac.com/product_info.php?products_id=458">pre-order page</a> it is NOT a vampire and ensuring that it wasn&#8217;t was a high priority of theirs. </p>
<p>Kudos to FastMac for thinking it out and building what looks to be a solid product. By the way, it looks like it costs $19.95, though Macworld was reporting it at half that. Still not a bad price.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rivulus-sw.com/?feed=rss2&amp;p=14</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Attributes Affecting Text Layout</title>
		<link>http://blog.rivulus-sw.com/?p=7</link>
		<comments>http://blog.rivulus-sw.com/?p=7#comments</comments>
		<pubDate>Wed, 03 Feb 2010 20:07:36 +0000</pubDate>
		<dc:creator>Philip</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[Cocoa]]></category>
		<category><![CDATA[Hebrew]]></category>

		<guid isPermaLink="false">http://blog.rivulus-sw.com/?p=7</guid>
		<description><![CDATA[Yesterday I started a radical revamp of the Hebrew Reader code. I had previously noticed that occasionally a vowel marking (a niqqud) would appear a little shifted to one side or the other. Nothing drastic, but definitely noticeable and ugly.

I began to suspect that the problem was caused by some custom attributes I was assigning [...]]]></description>
			<content:encoded><![CDATA[<p>Yesterday I started a radical revamp of the Hebrew Reader code. I had previously noticed that occasionally a vowel marking (a niqqud) would appear a little shifted to one side or the other. Nothing drastic, but definitely noticeable and ugly.</p>
<p><img src="http://blog.rivulus-sw.com/wp-content/uploads/2010/02/shifted_shewa.tiff" border="0" alt="shifted_shewa.tiff" width="53" height="30" /></p>
<p>I began to suspect that the problem was caused by some custom attributes I was assigning to the text to mark verses and segments. In other words I was using NSMutableAttributedString&#8217;s addAttribute:value:range and the like to assign my own keys and values to bits of text.<span id="more-7"></span></p>
<p>Apple&#8217;s documentation says:<br />
<cite>You may assign any name/value pair you wish to a range of characters, in addition to the standard attributes described in the [Apple docs.]</cite></p>
<p>Nevertheless I suspected that my custom attributes were causing these layout problems. So I wrote a little test application that basically goes through all of the text displayed in an NSTextView and applies an arbitrary attribute to each uncomposed character. So vowel markings get their own attributes separate from the letters they are attached to.</p>
<style type="text/css">
    p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #7603a8}
    p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; min-height: 13.0px}
    p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo}
    p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Menlo; color: #450080}
    span.s1 {color: #000000}
    span.s2 {color: #528186}
    span.s3 {color: #450080}
    span.s4 {color: #7603a8}
    span.s5 {color: #4900d6}
    span.s6 {color: #bb00a2}
    span.s7 {color: #cd102a}
    span.Apple-tab-span {white-space:pre}
  </style>
<p><body></p>
<p class="p1"><span class="Apple-tab-span">	</span>NSTextStorage<span class="s1"> *ts = [</span><span class="s2">textView</span><span class="s1"> </span><span class="s3">textStorage</span><span class="s1">];</span></p>
<p class="p2"><span class="Apple-tab-span">	</span></p>
<p class="p3"><span class="Apple-tab-span">	</span><span class="s4">NSRange</span> r = {<span class="s5">0</span>,<span class="s5">1</span>};</p>
<p class="p3"><span class="Apple-tab-span">	</span><span class="s6">for</span> (;r.<span class="s4">location</span>+r.<span class="s4">length</span>&lt;=[ts <span class="s3">length</span>]; r.<span class="s4">location</span>++)</p>
<p class="p3"><span class="Apple-tab-span">	</span>{</p>
<p class="p4"><span class="s1"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span>[ts </span>addAttribute<span class="s1">:[</span><span class="s4">NSString</span><span class="s1"> </span>stringWithFormat<span class="s1">:</span><span class="s7">@"Nonsense%u"</span><span class="s1">,r.</span>location<span class="s1">]</span></p>
<p class="p4"><span class="s1"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span> <span class="Apple-converted-space">  </span></span>value<span class="s1">:[</span><span class="s4">NSString</span><span class="s1"> </span>stringWithFormat<span class="s1">:</span><span class="s7">@"Gibberish%u"</span><span class="s1">,r.</span>location<span class="s1">]</span></p>
<p class="p3"><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span><span class="Apple-tab-span">	</span> <span class="Apple-converted-space">  </span><span class="s3">range</span>:r];</p>
<p class="p3"><span class="Apple-tab-span">	</span>}</p>
<p></body><br />
This code converts this:</p>
<p><img src="http://www.rivulus-sw.com/junk/before.png" border="0" alt="before.png" /></p>
<p>into this:<br />
<img src="http://www.rivulus-sw.com/junk/after.png" border="0" alt="before.png" /></p>
<p>So I posted a question to the cocoa-dev mailing list and promptly got an answer back from Douglas Davidson, a developer at Apple whose name pops up a whole lot in connection with the Cocoa text system. He suggested I try applying the attributes to <em>composed</em> character ranges only. That is, making sure the ranges include both the characters and all of the markings that modify them.<br />
Apple supplies the following two NSString instance methods to help the developer find what the ranges of composed character sequences are:<br />
<cite>- (NSRange)rangeOfComposedCharacterSequenceAtIndex:(NSUInteger)anIndex</cite></p>
<p>- (NSRange)rangeOfComposedCharacterSequencesForRange:(NSRange)range</p>
<p>Sure enough, making sure that attribute ranges only contain whole composed character sequence ranges solves the problem. But is this correct behavior on the part of the text system? Probably not, especially for custom attributes that shouldn&#8217;t affect layout anyway (like my verse markings). In fact, Mr. Davidson suggested I file a bug report on this issue. (Which I will do soon…) But he also suggested that a good rule of thumb is to treat the composed character sequences as the actual characters, since that it was the user will perceive to be a single character.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rivulus-sw.com/?feed=rss2&amp;p=7</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Welcome to the new Rivulus Blog!</title>
		<link>http://blog.rivulus-sw.com/?p=4</link>
		<comments>http://blog.rivulus-sw.com/?p=4#comments</comments>
		<pubDate>Tue, 02 Feb 2010 19:35:55 +0000</pubDate>
		<dc:creator>Philip</dc:creator>
				<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.rivulus-sw.com/?p=4</guid>
		<description><![CDATA[Hi!
Welcome to the new Rivulus Software blog! Here we will be discussing programming topics (in particular Cocoa related), Mac OS X issues in general, and of course Rivulus news! I hope that users and developers will find some useful info on this blog and post some interesting comments too. Stay tuned!
]]></description>
			<content:encoded><![CDATA[<p>Hi!</p>
<p>Welcome to the new Rivulus Software blog! Here we will be discussing programming topics (in particular Cocoa related), Mac OS X issues in general, and of course Rivulus news! I hope that users and developers will find some useful info on this blog and post some interesting comments too. Stay tuned!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.rivulus-sw.com/?feed=rss2&amp;p=4</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
